From f508c4a4b5d79a8da6459a4eaf744c6afc6f2b4a Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Sat, 24 Apr 2021 00:28:43 -0700 Subject: [PATCH 001/225] Initial pointlight shadow work --- .../CoreLights/ViewSrg.azsli | 2 + .../RayTracingSceneSrg.azsli | 2 + .../Shaders/LightCulling/LightCulling.azsl | 2 + .../PointLightFeatureProcessorInterface.h | 3 + .../CoreLights/DiskLightFeatureProcessor.h | 2 +- .../CoreLights/PointLightFeatureProcessor.cpp | 87 +++++++++++++++++++ .../CoreLights/PointLightFeatureProcessor.h | 10 +++ 7 files changed, 107 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli index 5404cf8b69..c236730cc1 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli @@ -73,6 +73,8 @@ partial ShaderResourceGroup ViewSrg float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; + uint m_shadowIndex; + uint m_padding[3]; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli index 0aeb43bcf2..b306ae7e61 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli @@ -63,6 +63,8 @@ partial ShaderResourceGroup RayTracingSceneSrg float m_invAttenuationRadiusSquared; float3 m_rgbIntensity; float m_bulbRadius; + uint m_shadowIndex; + uint m_padding[3]; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl index 367720d13b..8672350d35 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl @@ -59,6 +59,8 @@ ShaderResourceGroup PassSrg : SRG_PerPass float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; + uint m_shadowIndex; + uint m_padding[3]; }; struct DiskLight diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h index 68e1a01e56..d55e50f012 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h @@ -14,6 +14,7 @@ #include #include +#include namespace AZ { @@ -48,6 +49,8 @@ namespace AZ virtual void SetAttenuationRadius(LightHandle handle, float attenuationRadius) = 0; //! Sets the bulb radius for the provided LightHandle. Values greater than zero effectively make it a spherical light. virtual void SetBulbRadius(LightHandle handle, float bulbRadius) = 0; + //! Sets if shadows are enabled + virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0; }; } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h index 446b008921..483f3cb711 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h @@ -84,7 +84,7 @@ namespace AZ template void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param); - ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor; + ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr; IndexedDataVector m_diskLightData; GpuBufferHandler m_lightBufferHandler; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 661a7d4bf4..21d01c642b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -54,6 +54,7 @@ namespace AZ desc.m_elementCountSrgName = "m_pointLightCount"; desc.m_elementSize = sizeof(PointLightData); desc.m_srgLayout = RPI::RPISystemInterface::Get()->GetViewSrgAsset()->GetLayout(); + m_shadowFeatureProcessor = GetParentScene()->GetFeatureProcessor(); m_lightBufferHandler = GpuBufferHandler(desc); } @@ -83,6 +84,11 @@ namespace AZ { if (handle.IsValid()) { + ShadowId shadowId = ShadowId(m_pointLightData.GetData(handle.GetIndex()).m_shadowIndex); + if (shadowId.IsValid()) + { + m_shadowFeatureProcessor->ReleaseShadow(shadowId); + } m_pointLightData.RemoveIndex(handle.GetIndex()); m_deviceBufferNeedsUpdate = true; handle.Reset(); @@ -177,5 +183,86 @@ namespace AZ return m_lightBufferHandler.GetElementCount(); } + void PointLightFeatureProcessor::SetShadowsEnabled(LightHandle handle, bool enabled) + { + auto& light = m_pointLightData.GetData(handle.GetIndex()); + ShadowId shadowId = ShadowId(light.m_shadowIndex); + if (shadowId.IsValid() && enabled == false) + { + // Disable shadows + m_shadowFeatureProcessor->ReleaseShadow(shadowId); + shadowId.Reset(); + light.m_shadowIndex = shadowId.GetIndex(); + m_deviceBufferNeedsUpdate = true; + } + else if (shadowId.IsNull() && enabled == true) + { + // Enable shadows + light.m_shadowIndex = m_shadowFeatureProcessor->AcquireShadow().GetIndex(); + + UpdateShadow(handle); + m_deviceBufferNeedsUpdate = true; + } + } + + void PointLightFeatureProcessor::UpdateShadow(LightHandle handle) + { + const auto& pointLight = m_pointLightData.GetData(handle.GetIndex()); + ShadowId shadowId = ShadowId(pointLight.m_shadowIndex); + if (shadowId.IsNull()) + { + // Early out if shadows are disabled. + return; + } + + ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = + m_shadowFeatureProcessor->GetShadowProperties(shadowId); + + Vector3 position = Vector3::CreateFromFloat3(pointLight.m_position.data()); + + constexpr float SmallAngle = 0.01f; + desc.m_fieldOfViewYRadians = 1.57f; + + // To handle bulb radius, set the position of the shadow caster behind the actual light depending on the radius of the bulb + // + // \ / + // \ / + // \_____/ <-- position of light itself (and forward plane of shadow casting view) + // . . + // . . + // * <-- position of shadow casting view + // + desc.m_transform = Transform::CreateLookAt(position, AZ::Vector3::CreateZero()); + + desc.m_aspectRatio = 1.0f; + desc.m_nearPlaneDistance = 0.1f; + + const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared; + if (invRadiusSquared <= 0.f) + { + AZ_Assert(false, "Attenuation radius have to be set before use the light."); + return; + } + const float attenuationRadius = sqrtf(1.f / invRadiusSquared); + desc.m_farPlaneDistance = attenuationRadius; + + m_shadowFeatureProcessor->SetShadowProperties(shadowId, desc); + } + + template + void PointLightFeatureProcessor::SetShadowSetting(LightHandle handle, Functor&& functor, ParamType&& param) + { + AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetShadowSetting()."); + + auto& light = m_pointLightData.GetData(handle.GetIndex()); + ShadowId shadowId = ShadowId(light.m_shadowIndex); + + AZ_Assert(shadowId.IsValid(), "Attempting to set a shadow property when shadows are not enabled."); + if (shadowId.IsValid()) + { + AZStd::invoke(AZStd::forward(functor), m_shadowFeatureProcessor, shadowId, AZStd::forward(param)); + } + } + } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h index 25b9bfa2cd..8f159ea455 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h @@ -16,6 +16,7 @@ #include #include #include +#include namespace AZ { @@ -31,6 +32,8 @@ namespace AZ float m_invAttenuationRadiusSquared = 0.0f; // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations. AZStd::array m_rgbIntensity = { { 0.0f, 0.0f, 0.0f } }; float m_bulbRadius = 0.0f; // Radius of spherical light in meters. + uint32_t m_shadowIndex; + uint32_t m_padding[3]; }; class PointLightFeatureProcessor final @@ -58,14 +61,21 @@ namespace AZ void SetPosition(LightHandle handle, const AZ::Vector3& lightPosition) override; void SetAttenuationRadius(LightHandle handle, float attenuationRadius) override; void SetBulbRadius(LightHandle handle, float bulbRadius) override; + void SetShadowsEnabled(LightHandle handle, bool enabled) override; const Data::Instance GetLightBuffer() const; uint32_t GetLightCount()const; private: PointLightFeatureProcessor(const PointLightFeatureProcessor&) = delete; + using ShadowId = ProjectedShadowFeatureProcessor::ShadowId; static constexpr const char* FeatureProcessorName = "PointLightFeatureProcessor"; + void UpdateShadow(LightHandle handle); + // Convenience function for forwarding requests to the ProjectedShadowFeatureProcessor + template + void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param); + ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr; IndexedDataVector m_pointLightData; GpuBufferHandler m_lightBufferHandler; From 569c831532fd364927a1c81c4ddd545b848c7aa9 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Mon, 26 Apr 2021 14:53:31 -0700 Subject: [PATCH 002/225] Working PLS --- .../Atom/Features/PBR/Lights/PointLight.azsli | 99 +++++++++++++- .../CoreLights/ViewSrg.azsli | 4 +- .../RayTracingSceneSrg.azsli | 4 +- .../Shaders/LightCulling/LightCulling.azsl | 4 +- .../PointLightFeatureProcessorInterface.h | 2 + .../CoreLights/PointLightFeatureProcessor.cpp | 124 ++++++++++-------- .../CoreLights/PointLightFeatureProcessor.h | 12 +- 7 files changed, 181 insertions(+), 68 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index a59eb89dc7..588f6419af 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -13,6 +13,67 @@ #pragma once #include +#include + +int GetShadowDirectionIndex(float3 targetPos, float3 lightPos) +{ + float3 toPoint = targetPos - lightPos; + toPoint = normalize(toPoint); + + const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y))); + if (toPoint.x == -maxElement) + { + return 5; + } + else if (toPoint.x == maxElement) + { + return 4; + } + else if (toPoint.y == -maxElement) + { + return 3; + } + else if (toPoint.y == maxElement) + { + return 2; + } + else if (toPoint.z == -maxElement) + { + return 1; + } + else + { + return 0; + } +} + +int GetShadowIndex(ViewSrg::PointLight light, int i) +{ + if (i == 0) + { + return light.m_shadowIndices[0] & 0xFFFF; + } + else if (i==1) + { + return (light.m_shadowIndices[0] >> 16) & 0xFFFF; + } + else if (i==2) + { + return (light.m_shadowIndices[1]) & 0xFFFF; + } + else if (i==3) + { + return (light.m_shadowIndices[1] >> 16) & 0xFFFF; + } + else if (i==4) + { + return (light.m_shadowIndices[2]) & 0xFFFF; + } + else + { + return (light.m_shadowIndices[2] >> 16) & 0xFFFF; + } +} void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData) { @@ -31,11 +92,45 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD d2 = max(0.001 * 0.001, d2); // clamp the light to at least 1mm away to avoid extreme values. float3 lightIntensity = (light.m_rgbIntensityCandelas / d2) * radiusAttenuation; + // shadow + float litRatio = 1.0; + + // How much is back face shadowed, it's set to the reverse of litRatio to share the same default value with thickness, which should be 0 if no shadow map available + float backShadowRatio = 0.0; + if (o_enableShadows) + { + const float3 Directions[6] = {float3(0,0,1), float3(0,0,-1), float3(0,1,0), float3(0,-1,0), float3(1,0,0), float3(-1,0,0)}; + const int shadowDirectionIndex = GetShadowDirectionIndex(surface.position, light.m_position); + + { + + litRatio *= ProjectedShadow::GetVisibility( + GetShadowIndex(light, shadowDirectionIndex), + light.m_position, + surface.position, + Directions[shadowDirectionIndex], + surface.normal); + + } + + + /* + // Use backShadowRatio to carry thickness from shadow map for thick mode + backShadowRatio = 1.0 - litRatio; + if (o_transmission_mode == TransmissionMode::ThickObject) + { + backShadowRatio = ProjectedShadow::GetThickness( + shadowIndex, + surface.position); + } */ + + } + // Diffuse contribution - lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)); + lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio; // Tranmission contribution - lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), 0.0); + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), 0.0) * litRatio; // Adjust the light direcion for specular based on bulb size diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli index c236730cc1..253fdfe974 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli @@ -73,8 +73,8 @@ partial ShaderResourceGroup ViewSrg float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; - uint m_shadowIndex; - uint m_padding[3]; + uint m_shadowIndices[3]; + uint m_padding; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli index b306ae7e61..ff7ef64277 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli @@ -63,8 +63,8 @@ partial ShaderResourceGroup RayTracingSceneSrg float m_invAttenuationRadiusSquared; float3 m_rgbIntensity; float m_bulbRadius; - uint m_shadowIndex; - uint m_padding[3]; + uint m_shadowIndices[3]; + uint m_padding; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl index 8672350d35..1f914ee1b9 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl @@ -59,8 +59,8 @@ ShaderResourceGroup PassSrg : SRG_PerPass float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; - uint m_shadowIndex; - uint m_padding[3]; + uint m_shadowIndices[3]; + uint m_padding; }; struct DiskLight diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h index d55e50f012..de3d00dbde 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h @@ -51,6 +51,8 @@ namespace AZ virtual void SetBulbRadius(LightHandle handle, float bulbRadius) = 0; //! Sets if shadows are enabled virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0; + //! Sets the shadowmap size (width and height) of the light. + virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0; }; } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 21d01c642b..fcc4acc246 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -44,6 +44,12 @@ namespace AZ PointLightFeatureProcessor::PointLightFeatureProcessor() : PointLightFeatureProcessorInterface() { + m_directions[0] = AZ::Vector3::CreateAxisZ(); + m_directions[1] = -AZ::Vector3::CreateAxisZ(); + m_directions[2] = AZ::Vector3::CreateAxisY(); + m_directions[3] = -AZ::Vector3::CreateAxisY(); + m_directions[4] = AZ::Vector3::CreateAxisX(); + m_directions[5] = -AZ::Vector3::CreateAxisX(); } void PointLightFeatureProcessor::Activate() @@ -84,11 +90,15 @@ namespace AZ { if (handle.IsValid()) { - ShadowId shadowId = ShadowId(m_pointLightData.GetData(handle.GetIndex()).m_shadowIndex); - if (shadowId.IsValid()) + for (int i = 0; i < PointLightData::NumShadowFaces; ++i) { - m_shadowFeatureProcessor->ReleaseShadow(shadowId); + ShadowId shadowId = ShadowId(m_pointLightData.GetData(handle.GetIndex()).m_shadowIndices[i]); + if (shadowId.IsValid()) + { + m_shadowFeatureProcessor->ReleaseShadow(shadowId); + } } + m_pointLightData.RemoveIndex(handle.GetIndex()); m_deviceBufferNeedsUpdate = true; handle.Reset(); @@ -154,6 +164,7 @@ namespace AZ lightPosition.StoreToFloat3(position.data()); m_deviceBufferNeedsUpdate = true; + UpdateShadow(handle); } void PointLightFeatureProcessor::SetAttenuationRadius(LightHandle handle, float attenuationRadius) @@ -186,76 +197,68 @@ namespace AZ void PointLightFeatureProcessor::SetShadowsEnabled(LightHandle handle, bool enabled) { auto& light = m_pointLightData.GetData(handle.GetIndex()); - ShadowId shadowId = ShadowId(light.m_shadowIndex); - if (shadowId.IsValid() && enabled == false) + for (int i = 0; i < PointLightData::NumShadowFaces; ++i) { - // Disable shadows - m_shadowFeatureProcessor->ReleaseShadow(shadowId); - shadowId.Reset(); - light.m_shadowIndex = shadowId.GetIndex(); - m_deviceBufferNeedsUpdate = true; - } - else if (shadowId.IsNull() && enabled == true) - { - // Enable shadows - light.m_shadowIndex = m_shadowFeatureProcessor->AcquireShadow().GetIndex(); + ShadowId shadowId = ShadowId(light.m_shadowIndices[i]); + if (shadowId.IsValid() && enabled == false) + { + // Disable shadows + m_shadowFeatureProcessor->ReleaseShadow(shadowId); + shadowId.Reset(); + light.m_shadowIndices[i] = shadowId.GetIndex(); + m_deviceBufferNeedsUpdate = true; + } + else if (shadowId.IsNull() && enabled == true) + { + // Enable shadows + light.m_shadowIndices[i] = m_shadowFeatureProcessor->AcquireShadow().GetIndex(); - UpdateShadow(handle); - m_deviceBufferNeedsUpdate = true; + UpdateShadow(handle); + m_deviceBufferNeedsUpdate = true; + } } } void PointLightFeatureProcessor::UpdateShadow(LightHandle handle) { - const auto& pointLight = m_pointLightData.GetData(handle.GetIndex()); - ShadowId shadowId = ShadowId(pointLight.m_shadowIndex); - if (shadowId.IsNull()) + for (int i = 0; i < PointLightData::NumShadowFaces; ++i) { - // Early out if shadows are disabled. - return; + const auto& pointLight = m_pointLightData.GetData(handle.GetIndex()); + ShadowId shadowId = ShadowId(pointLight.m_shadowIndices[i]); + if (shadowId.IsNull()) + { + // Early out if shadows are disabled. + return; + } + + ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = m_shadowFeatureProcessor->GetShadowProperties(shadowId); + Vector3 position = Vector3::CreateFromFloat3(pointLight.m_position.data()); + + desc.m_fieldOfViewYRadians = 1.58825f; + desc.m_transform = Transform::CreateLookAt(position, position + m_directions[i]); + desc.m_aspectRatio = 1.0f; + desc.m_nearPlaneDistance = 0.1f; + + const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared; + if (invRadiusSquared <= 0.f) + { + AZ_Assert(false, "Attenuation radius have to be set before use the light."); + return; + } + const float attenuationRadius = sqrtf(1.f / invRadiusSquared); + desc.m_farPlaneDistance = attenuationRadius; + + m_shadowFeatureProcessor->SetShadowProperties(shadowId, desc); } - - ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = - m_shadowFeatureProcessor->GetShadowProperties(shadowId); - - Vector3 position = Vector3::CreateFromFloat3(pointLight.m_position.data()); - - constexpr float SmallAngle = 0.01f; - desc.m_fieldOfViewYRadians = 1.57f; - - // To handle bulb radius, set the position of the shadow caster behind the actual light depending on the radius of the bulb - // - // \ / - // \ / - // \_____/ <-- position of light itself (and forward plane of shadow casting view) - // . . - // . . - // * <-- position of shadow casting view - // - desc.m_transform = Transform::CreateLookAt(position, AZ::Vector3::CreateZero()); - - desc.m_aspectRatio = 1.0f; - desc.m_nearPlaneDistance = 0.1f; - - const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared; - if (invRadiusSquared <= 0.f) - { - AZ_Assert(false, "Attenuation radius have to be set before use the light."); - return; - } - const float attenuationRadius = sqrtf(1.f / invRadiusSquared); - desc.m_farPlaneDistance = attenuationRadius; - - m_shadowFeatureProcessor->SetShadowProperties(shadowId, desc); } template - void PointLightFeatureProcessor::SetShadowSetting(LightHandle handle, Functor&& functor, ParamType&& param) + void PointLightFeatureProcessor::SetShadowSetting(LightHandle handle, Functor&& functor, ParamType&& param, const int lightIndex) { AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetShadowSetting()."); auto& light = m_pointLightData.GetData(handle.GetIndex()); - ShadowId shadowId = ShadowId(light.m_shadowIndex); + ShadowId shadowId = ShadowId(light.m_shadowIndices[lightIndex]); AZ_Assert(shadowId.IsValid(), "Attempting to set a shadow property when shadows are not enabled."); if (shadowId.IsValid()) @@ -264,5 +267,12 @@ namespace AZ } } + void PointLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) + { + for (int i = 0; i < PointLightData::NumShadowFaces; ++i) + { + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution, shadowmapSize, i); + } + } } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h index 8f159ea455..589da59955 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h @@ -32,8 +32,11 @@ namespace AZ float m_invAttenuationRadiusSquared = 0.0f; // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations. AZStd::array m_rgbIntensity = { { 0.0f, 0.0f, 0.0f } }; float m_bulbRadius = 0.0f; // Radius of spherical light in meters. - uint32_t m_shadowIndex; - uint32_t m_padding[3]; + + static const int NumShadowFaces = 6; + + AZStd::array m_shadowIndices = {{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}}; + uint32_t m_padding; }; class PointLightFeatureProcessor final @@ -62,6 +65,7 @@ namespace AZ void SetAttenuationRadius(LightHandle handle, float attenuationRadius) override; void SetBulbRadius(LightHandle handle, float bulbRadius) override; void SetShadowsEnabled(LightHandle handle, bool enabled) override; + void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override; const Data::Instance GetLightBuffer() const; uint32_t GetLightCount()const; @@ -74,12 +78,14 @@ namespace AZ void UpdateShadow(LightHandle handle); // Convenience function for forwarding requests to the ProjectedShadowFeatureProcessor template - void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param); + void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param, const int lightIndex); ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr; IndexedDataVector m_pointLightData; GpuBufferHandler m_lightBufferHandler; bool m_deviceBufferNeedsUpdate = false; + + AZStd::array m_directions; }; } // namespace Render } // namespace AZ From bbae3b6d48c3ab8e1c910e31edda2b671e9e4731 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Mon, 26 Apr 2021 16:16:05 -0700 Subject: [PATCH 003/225] Slight improvements --- .../Atom/Features/PBR/Lights/PointLight.azsli | 16 +++++----------- .../CoreLights/PointLightFeatureProcessor.cpp | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index 588f6419af..f803a5802c 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -101,20 +101,14 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD { const float3 Directions[6] = {float3(0,0,1), float3(0,0,-1), float3(0,1,0), float3(0,-1,0), float3(1,0,0), float3(-1,0,0)}; const int shadowDirectionIndex = GetShadowDirectionIndex(surface.position, light.m_position); - - { - - litRatio *= ProjectedShadow::GetVisibility( - GetShadowIndex(light, shadowDirectionIndex), + const int shadowIndex = GetShadowIndex(light, shadowDirectionIndex); + litRatio *= ProjectedShadow::GetVisibility( + shadowIndex, light.m_position, surface.position, Directions[shadowDirectionIndex], surface.normal); - - } - - - /* + // Use backShadowRatio to carry thickness from shadow map for thick mode backShadowRatio = 1.0 - litRatio; if (o_transmission_mode == TransmissionMode::ThickObject) @@ -122,7 +116,7 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD backShadowRatio = ProjectedShadow::GetThickness( shadowIndex, surface.position); - } */ + } } diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index fcc4acc246..62af94e548 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -234,7 +234,7 @@ namespace AZ ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = m_shadowFeatureProcessor->GetShadowProperties(shadowId); Vector3 position = Vector3::CreateFromFloat3(pointLight.m_position.data()); - desc.m_fieldOfViewYRadians = 1.58825f; + desc.m_fieldOfViewYRadians = DegToRad(90.5f); // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces desc.m_transform = Transform::CreateLookAt(position, position + m_directions[i]); desc.m_aspectRatio = 1.0f; desc.m_nearPlaneDistance = 0.1f; From 2eed8684b571944eaf5f1dc98ac73ff7f1420687 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Tue, 27 Apr 2021 14:08:54 -0700 Subject: [PATCH 004/225] Adding full shadowmap support --- .../PointLightFeatureProcessorInterface.h | 28 +++++++++ .../CoreLights/DiskLightFeatureProcessor.h | 2 +- .../CoreLights/PointLightFeatureProcessor.cpp | 59 +++++++++++++++---- .../CoreLights/PointLightFeatureProcessor.h | 22 +++---- 4 files changed, 83 insertions(+), 28 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h index de3d00dbde..20e6d366f5 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h @@ -23,6 +23,20 @@ namespace AZ namespace Render { + struct PointLightData + { + AZStd::array m_position = {{0.0f, 0.0f, 0.0f}}; + float m_invAttenuationRadiusSquared = + 0.0f; // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations. + AZStd::array m_rgbIntensity = {{0.0f, 0.0f, 0.0f}}; + float m_bulbRadius = 0.0f; // Radius of spherical light in meters. + + static const int NumShadowFaces = 6; + + AZStd::array m_shadowIndices = {{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}}; + uint32_t m_padding; + }; + //! PointLightFeatureProcessorInterface provides an interface to acquire, release, and update a point light. class PointLightFeatureProcessorInterface : public RPI::FeatureProcessor @@ -53,6 +67,20 @@ namespace AZ virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0; //! Sets the shadowmap size (width and height) of the light. virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0; + //! Specifies filter method of shadows. + virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0; + //! Specifies the width of boundary between shadowed area and lit area in radians. The degree ofshadowed gradually changes on + //! the boundary. 0 disables softening. + virtual void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) = 0; + //! Sets sample count to predict boundary of shadow (up to 16). It will be clamped to be less than or equal to the filtering + //! sample count. + virtual void SetPredictionSampleCount(LightHandle handle, uint16_t count) = 0; + //! Sets sample count for filtering of shadow boundary (up to 64) + virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0; + //! Sets the shadowmap Pcf (percentage closer filtering) method. + virtual void SetPcfMethod(LightHandle handle, PcfMethod method) = 0; + //! Sets all of the the point data for the provided LightHandle. + virtual void SetPointData(LightHandle handle, const PointLightData& data) = 0; }; } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h index 483f3cb711..8391506f63 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h @@ -59,7 +59,7 @@ namespace AZ void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override; void SetPredictionSampleCount(LightHandle handle, uint16_t count) override; void SetFilteringSampleCount(LightHandle handle, uint16_t count) override; - void SetPcfMethod(LightHandle handle, PcfMethod method); + void SetPcfMethod(LightHandle handle, PcfMethod method) override; void SetDiskData(LightHandle handle, const DiskLightData& data) override; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 62af94e548..94d5878e47 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -219,6 +219,15 @@ namespace AZ } } + void PointLightFeatureProcessor::SetPointData(LightHandle handle, const PointLightData& data) + { + AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetDiskData()."); + + m_pointLightData.GetData(handle.GetIndex()) = data; + m_deviceBufferNeedsUpdate = true; + UpdateShadow(handle); + } + void PointLightFeatureProcessor::UpdateShadow(LightHandle handle) { for (int i = 0; i < PointLightData::NumShadowFaces; ++i) @@ -237,7 +246,7 @@ namespace AZ desc.m_fieldOfViewYRadians = DegToRad(90.5f); // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces desc.m_transform = Transform::CreateLookAt(position, position + m_directions[i]); desc.m_aspectRatio = 1.0f; - desc.m_nearPlaneDistance = 0.1f; + desc.m_nearPlaneDistance = 0.0f; const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared; if (invRadiusSquared <= 0.f) @@ -246,33 +255,59 @@ namespace AZ return; } const float attenuationRadius = sqrtf(1.f / invRadiusSquared); - desc.m_farPlaneDistance = attenuationRadius; + desc.m_farPlaneDistance = attenuationRadius + pointLight.m_bulbRadius; m_shadowFeatureProcessor->SetShadowProperties(shadowId, desc); } } template - void PointLightFeatureProcessor::SetShadowSetting(LightHandle handle, Functor&& functor, ParamType&& param, const int lightIndex) + void PointLightFeatureProcessor::SetShadowSetting(LightHandle handle, Functor&& functor, ParamType&& param) { AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetShadowSetting()."); auto& light = m_pointLightData.GetData(handle.GetIndex()); - ShadowId shadowId = ShadowId(light.m_shadowIndices[lightIndex]); - - AZ_Assert(shadowId.IsValid(), "Attempting to set a shadow property when shadows are not enabled."); - if (shadowId.IsValid()) + for (int lightIndex = 0; lightIndex < PointLightData::NumShadowFaces; ++lightIndex) { - AZStd::invoke(AZStd::forward(functor), m_shadowFeatureProcessor, shadowId, AZStd::forward(param)); + ShadowId shadowId = ShadowId(light.m_shadowIndices[lightIndex]); + + AZ_Assert(shadowId.IsValid(), "Attempting to set a shadow property when shadows are not enabled."); + if (shadowId.IsValid()) + { + AZStd::invoke(AZStd::forward(functor), m_shadowFeatureProcessor, shadowId, AZStd::forward(param)); + } } } void PointLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) { - for (int i = 0; i < PointLightData::NumShadowFaces; ++i) - { - SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution, shadowmapSize, i); - } + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution, shadowmapSize); } + + void PointLightFeatureProcessor::SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) + { + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowFilterMethod, method); + } + + void PointLightFeatureProcessor::SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) + { + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle, boundaryWidthRadians); + } + + void PointLightFeatureProcessor::SetPredictionSampleCount(LightHandle handle, uint16_t count) + { + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetPredictionSampleCount, count); + } + + void PointLightFeatureProcessor::SetFilteringSampleCount(LightHandle handle, uint16_t count) + { + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetFilteringSampleCount, count); + } + + void PointLightFeatureProcessor::SetPcfMethod(LightHandle handle, PcfMethod method) + { + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetPcfMethod, method); + } + } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h index 589da59955..437ebc2f0a 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h @@ -25,20 +25,6 @@ namespace AZ namespace Render { - - struct PointLightData - { - AZStd::array m_position = { { 0.0f, 0.0f, 0.0f } }; - float m_invAttenuationRadiusSquared = 0.0f; // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations. - AZStd::array m_rgbIntensity = { { 0.0f, 0.0f, 0.0f } }; - float m_bulbRadius = 0.0f; // Radius of spherical light in meters. - - static const int NumShadowFaces = 6; - - AZStd::array m_shadowIndices = {{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}}; - uint32_t m_padding; - }; - class PointLightFeatureProcessor final : public PointLightFeatureProcessorInterface { @@ -66,6 +52,12 @@ namespace AZ void SetBulbRadius(LightHandle handle, float bulbRadius) override; void SetShadowsEnabled(LightHandle handle, bool enabled) override; void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override; + void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override; + void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override; + void SetPredictionSampleCount(LightHandle handle, uint16_t count) override; + void SetFilteringSampleCount(LightHandle handle, uint16_t count) override; + void SetPcfMethod(LightHandle handle, PcfMethod method) override; + void SetPointData(LightHandle handle, const PointLightData& data) override; const Data::Instance GetLightBuffer() const; uint32_t GetLightCount()const; @@ -78,7 +70,7 @@ namespace AZ void UpdateShadow(LightHandle handle); // Convenience function for forwarding requests to the ProjectedShadowFeatureProcessor template - void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param, const int lightIndex); + void SetShadowSetting(LightHandle handle, Functor&&, ParamType&& param); ProjectedShadowFeatureProcessor* m_shadowFeatureProcessor = nullptr; IndexedDataVector m_pointLightData; From 805eb1ba34c32be9ad4d10690ce6e441a5b58dd3 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Tue, 27 Apr 2021 15:14:59 -0700 Subject: [PATCH 005/225] Adding editor point light support --- .../CoreLights/AreaLightComponentConfig.cpp | 2 +- .../Source/CoreLights/SphereLightDelegate.cpp | 55 +++++++++++++++++++ .../Source/CoreLights/SphereLightDelegate.h | 9 +++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp index 2dc439b846..8f10204ae9 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp @@ -112,7 +112,7 @@ namespace AZ bool AreaLightComponentConfig::SupportsShadows() const { - return m_shapeType == AZ_CRC_CE("DiskShape"); + return m_lightType == LightType::SpotDisk || m_lightType == LightType::Sphere; } bool AreaLightComponentConfig::ShadowsDisabled() const diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp index de733e255b..7a74ad4c5c 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp @@ -63,5 +63,60 @@ namespace AZ debugDisplay.DrawWireSphere(transform.GetTranslation(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity)); } } + + void SphereLightDelegate::SetEnableShadow(bool enabled) + { + Base::SetEnableShadow(enabled); + GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled); + } + + void SphereLightDelegate::SetShadowmapMaxSize(ShadowmapSize size) + { + if (GetShadowsEnabled()) + { + GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size); + } + } + + void SphereLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method) + { + if (GetShadowsEnabled()) + { + GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method); + } + } + + void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees) + { + if (GetShadowsEnabled()) + { + GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees)); + } + } + + void SphereLightDelegate::SetPredictionSampleCount(uint32_t count) + { + if (GetShadowsEnabled()) + { + GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count); + } + } + + void SphereLightDelegate::SetFilteringSampleCount(uint32_t count) + { + if (GetShadowsEnabled()) + { + GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count); + } + } + + void SphereLightDelegate::SetPcfMethod(PcfMethod method) + { + if (GetShadowsEnabled()) + { + GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method); + } + } + } // namespace Render } // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.h index 7d790f2d6c..178540fd01 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.h @@ -24,6 +24,8 @@ namespace AZ class SphereLightDelegate final : public LightDelegateBase { + using Base = LightDelegateBase; + public: SphereLightDelegate(LmbrCentral::SphereShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible); @@ -32,6 +34,13 @@ namespace AZ void DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const override; float GetSurfaceArea() const override; float GetEffectiveSolidAngle() const override { return PhotometricValue::OmnidirectionalSteradians; } + void SetEnableShadow(bool enabled) override; + void SetShadowmapMaxSize(ShadowmapSize size) override; + void SetShadowFilterMethod(ShadowFilterMethod method) override; + void SetSofteningBoundaryWidthAngle(float widthInDegrees) override; + void SetPredictionSampleCount(uint32_t count) override; + void SetFilteringSampleCount(uint32_t count) override; + void SetPcfMethod(PcfMethod method) override; private: From c729c72034dbe5b2a01f094c0d37dcb0bba7336f Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Wed, 28 Apr 2021 09:35:56 -0700 Subject: [PATCH 006/225] Switching to XYZ instead of ZYX --- .../Atom/Features/PBR/Lights/PointLight.azsli | 14 +++++++------- .../CoreLights/PointLightFeatureProcessor.cpp | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index f803a5802c..dfd06a57ff 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -23,27 +23,27 @@ int GetShadowDirectionIndex(float3 targetPos, float3 lightPos) const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y))); if (toPoint.x == -maxElement) { - return 5; + return 0; } else if (toPoint.x == maxElement) { - return 4; + return 1; } else if (toPoint.y == -maxElement) { - return 3; + return 2; } else if (toPoint.y == maxElement) { - return 2; + return 3; } else if (toPoint.z == -maxElement) { - return 1; + return 4; } else { - return 0; + return 5; } } @@ -99,7 +99,7 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD float backShadowRatio = 0.0; if (o_enableShadows) { - const float3 Directions[6] = {float3(0,0,1), float3(0,0,-1), float3(0,1,0), float3(0,-1,0), float3(1,0,0), float3(-1,0,0)}; + const float3 Directions[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)}; const int shadowDirectionIndex = GetShadowDirectionIndex(surface.position, light.m_position); const int shadowIndex = GetShadowIndex(light, shadowDirectionIndex); litRatio *= ProjectedShadow::GetVisibility( diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 94d5878e47..8480bec2ce 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -44,12 +44,12 @@ namespace AZ PointLightFeatureProcessor::PointLightFeatureProcessor() : PointLightFeatureProcessorInterface() { - m_directions[0] = AZ::Vector3::CreateAxisZ(); - m_directions[1] = -AZ::Vector3::CreateAxisZ(); - m_directions[2] = AZ::Vector3::CreateAxisY(); - m_directions[3] = -AZ::Vector3::CreateAxisY(); - m_directions[4] = AZ::Vector3::CreateAxisX(); - m_directions[5] = -AZ::Vector3::CreateAxisX(); + m_directions[0] = -AZ::Vector3::CreateAxisX(); + m_directions[1] = AZ::Vector3::CreateAxisX(); + m_directions[2] = -AZ::Vector3::CreateAxisY(); + m_directions[3] = AZ::Vector3::CreateAxisY(); + m_directions[4] = -AZ::Vector3::CreateAxisZ(); + m_directions[5] = AZ::Vector3::CreateAxisZ(); } void PointLightFeatureProcessor::Activate() From 37fd8d43ed97ee244ab81c855e28c9332635f3d2 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Wed, 28 Apr 2021 10:40:31 -0700 Subject: [PATCH 007/225] Tabs to space and better naming and comments --- .../Atom/Features/PBR/Lights/PointLight.azsli | 132 +++++++++--------- .../CoreLights/PointLightFeatureProcessor.cpp | 18 +-- .../CoreLights/PointLightFeatureProcessor.h | 2 +- 3 files changed, 75 insertions(+), 77 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index dfd06a57ff..95482d432f 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -15,64 +15,62 @@ #include #include -int GetShadowDirectionIndex(float3 targetPos, float3 lightPos) +int GetShadowDirectionIndex(const float3 targetPos, const float3 lightPos) { - float3 toPoint = targetPos - lightPos; - toPoint = normalize(toPoint); - - const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y))); - if (toPoint.x == -maxElement) - { - return 0; - } - else if (toPoint.x == maxElement) - { - return 1; - } - else if (toPoint.y == -maxElement) - { - return 2; - } - else if (toPoint.y == maxElement) - { - return 3; - } - else if (toPoint.z == -maxElement) - { - return 4; - } - else - { - return 5; - } + const float3 toPoint = targetPos - lightPos; + const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y))); + if (toPoint.x == -maxElement) + { + return 0; + } + else if (toPoint.x == maxElement) + { + return 1; + } + else if (toPoint.y == -maxElement) + { + return 2; + } + else if (toPoint.y == maxElement) + { + return 3; + } + else if (toPoint.z == -maxElement) + { + return 4; + } + else + { + return 5; + } } -int GetShadowIndex(ViewSrg::PointLight light, int i) +int UnpackShadowIndex(const ViewSrg::PointLight light, const int i) { - if (i == 0) - { - return light.m_shadowIndices[0] & 0xFFFF; - } - else if (i==1) - { - return (light.m_shadowIndices[0] >> 16) & 0xFFFF; - } - else if (i==2) - { - return (light.m_shadowIndices[1]) & 0xFFFF; - } - else if (i==3) - { - return (light.m_shadowIndices[1] >> 16) & 0xFFFF; - } - else if (i==4) - { - return (light.m_shadowIndices[2]) & 0xFFFF; - } - else - { - return (light.m_shadowIndices[2] >> 16) & 0xFFFF; - } + if (i == 0) + { + return light.m_shadowIndices[0] & 0xFFFF; + } + else if (i==1) + { + return (light.m_shadowIndices[0] >> 16) & 0xFFFF; + } + else if (i==2) + { + return (light.m_shadowIndices[1]) & 0xFFFF; + } + else if (i==3) + { + return (light.m_shadowIndices[1] >> 16) & 0xFFFF; + } + else if (i==4) + { + return (light.m_shadowIndices[2]) & 0xFFFF; + } + else + { + return (light.m_shadowIndices[2] >> 16) & 0xFFFF; + } } void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData) @@ -99,16 +97,17 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD float backShadowRatio = 0.0; if (o_enableShadows) { - const float3 Directions[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)}; - const int shadowDirectionIndex = GetShadowDirectionIndex(surface.position, light.m_position); - const int shadowIndex = GetShadowIndex(light, shadowDirectionIndex); - litRatio *= ProjectedShadow::GetVisibility( - shadowIndex, - light.m_position, - surface.position, - Directions[shadowDirectionIndex], - surface.normal); - + // The order should match m_pointShadowTransforms in PointLightFeatureProcessor.h/.cpp + const float3 PointShadowDirections[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)}; + const int shadowDirectionIndex = GetShadowDirectionIndex(surface.position, light.m_position); + const int shadowIndex = UnpackShadowIndex(light, shadowDirectionIndex); + litRatio *= ProjectedShadow::GetVisibility( + shadowIndex, + light.m_position, + surface.position, + PointShadowDirections[shadowDirectionIndex], + surface.normal); + // Use backShadowRatio to carry thickness from shadow map for thick mode backShadowRatio = 1.0 - litRatio; if (o_transmission_mode == TransmissionMode::ThickObject) @@ -116,9 +115,8 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD backShadowRatio = ProjectedShadow::GetThickness( shadowIndex, surface.position); - } - - } + } + } // Diffuse contribution lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 8480bec2ce..9a940ea7b0 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -44,12 +44,13 @@ namespace AZ PointLightFeatureProcessor::PointLightFeatureProcessor() : PointLightFeatureProcessorInterface() { - m_directions[0] = -AZ::Vector3::CreateAxisX(); - m_directions[1] = AZ::Vector3::CreateAxisX(); - m_directions[2] = -AZ::Vector3::CreateAxisY(); - m_directions[3] = AZ::Vector3::CreateAxisY(); - m_directions[4] = -AZ::Vector3::CreateAxisZ(); - m_directions[5] = AZ::Vector3::CreateAxisZ(); + // Note must match PointShadowDirections in PointLight.azsli + m_pointShadowTransforms[0] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisX()); + m_pointShadowTransforms[1] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisX()); + m_pointShadowTransforms[2] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisY()); + m_pointShadowTransforms[3] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisY()); + m_pointShadowTransforms[4] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), -AZ::Vector3::CreateAxisZ()); + m_pointShadowTransforms[5] = AZ::Transform::CreateLookAt(AZ::Vector3::CreateZero(), AZ::Vector3::CreateAxisZ()); } void PointLightFeatureProcessor::Activate() @@ -241,10 +242,9 @@ namespace AZ } ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = m_shadowFeatureProcessor->GetShadowProperties(shadowId); - Vector3 position = Vector3::CreateFromFloat3(pointLight.m_position.data()); - desc.m_fieldOfViewYRadians = DegToRad(90.5f); // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces - desc.m_transform = Transform::CreateLookAt(position, position + m_directions[i]); + desc.m_transform = m_pointShadowTransforms[i]; + desc.m_transform.SetTranslation(pointLight.m_position[0], pointLight.m_position[1], pointLight.m_position[2]); desc.m_aspectRatio = 1.0f; desc.m_nearPlaneDistance = 0.0f; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h index 437ebc2f0a..c0c377e960 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h @@ -77,7 +77,7 @@ namespace AZ GpuBufferHandler m_lightBufferHandler; bool m_deviceBufferNeedsUpdate = false; - AZStd::array m_directions; + AZStd::array m_pointShadowTransforms; }; } // namespace Render } // namespace AZ From 66d36137b7522ad94853543a502b07dca98a0995 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Wed, 28 Apr 2021 10:53:52 -0700 Subject: [PATCH 008/225] Tabs to spaces --- .../Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli | 4 ++-- .../Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli | 4 ++-- .../Common/Assets/Shaders/LightCulling/LightCulling.azsl | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli index 253fdfe974..6c4a6d2a36 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli @@ -73,8 +73,8 @@ partial ShaderResourceGroup ViewSrg float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; - uint m_shadowIndices[3]; - uint m_padding; + uint m_shadowIndices[3]; + uint m_padding; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli index ff7ef64277..b392e07e06 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli @@ -63,8 +63,8 @@ partial ShaderResourceGroup RayTracingSceneSrg float m_invAttenuationRadiusSquared; float3 m_rgbIntensity; float m_bulbRadius; - uint m_shadowIndices[3]; - uint m_padding; + uint m_shadowIndices[3]; + uint m_padding; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl index 1f914ee1b9..398103a93f 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl @@ -59,8 +59,8 @@ ShaderResourceGroup PassSrg : SRG_PerPass float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; - uint m_shadowIndices[3]; - uint m_padding; + uint m_shadowIndices[3]; + uint m_padding; }; struct DiskLight From ce2af6be152a6ba43681a5a8b34381c849c7e552 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Wed, 28 Apr 2021 11:53:27 -0700 Subject: [PATCH 009/225] Tabs to spaces --- .../PointLightFeatureProcessorInterface.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h index 20e6d366f5..aaffac6d5a 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h @@ -1,20 +1,20 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once -#include #include #include +#include namespace AZ { @@ -38,8 +38,7 @@ namespace AZ }; //! PointLightFeatureProcessorInterface provides an interface to acquire, release, and update a point light. - class PointLightFeatureProcessorInterface - : public RPI::FeatureProcessor + class PointLightFeatureProcessorInterface : public RPI::FeatureProcessor { public: AZ_RTTI(AZ::Render::PointLightFeatureProcessorInterface, "{D3E0B016-F3C6-4C7A-A29E-0B3A4FA87806}", AZ::RPI::FeatureProcessor); @@ -48,7 +47,8 @@ namespace AZ using LightHandle = RHI::Handle; static constexpr PhotometricUnit PhotometricUnitType = PhotometricUnit::Candela; - //! Creates a new point light which can be referenced by the returned LightHandle. Must be released via ReleaseLight() when no longer needed. + //! Creates a new point light which can be referenced by the returned LightHandle. Must be released via ReleaseLight() when no + //! longer needed. virtual LightHandle AcquireLight() = 0; //! Releases a LightHandle which removes the point light. virtual bool ReleaseLight(LightHandle& handle) = 0; @@ -65,7 +65,7 @@ namespace AZ virtual void SetBulbRadius(LightHandle handle, float bulbRadius) = 0; //! Sets if shadows are enabled virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0; - //! Sets the shadowmap size (width and height) of the light. + //! Sets the shadowmap size (width and height) of the light. virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0; //! Specifies filter method of shadows. virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0; From 3b49b59c328b8f2f69a4b1b90857a0b2269f7929 Mon Sep 17 00:00:00 2001 From: sconel Date: Wed, 28 Apr 2021 12:03:09 -0700 Subject: [PATCH 010/225] Added AddProductDependency calls to PrefabProcessorContext --- .../Spawnable/PrefabCatchmentProcessor.cpp | 2 - .../Spawnable/PrefabProcessorContext.cpp | 53 ++++++++++--------- .../Prefab/Spawnable/PrefabProcessorContext.h | 12 +++-- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp index 5d8f1f35e3..6f2a5d517c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp @@ -84,8 +84,6 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils } SpawnableUtils::SortEntitiesByTransformHierarchy(*spawnable); context.GetProcessedObjects().push_back(AZStd::move(object)); - - context.RemovePrefab(prefabName); } else { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index eb206349d0..0d5f06d837 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -10,6 +10,8 @@ * */ +#include + #include namespace AzToolsFramework::Prefab::PrefabConversionUtils @@ -24,37 +26,14 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return result.second; } - bool PrefabProcessorContext::RemovePrefab(AZStd::string_view prefabName) - { - if (!m_isIterating) - { - return m_prefabs.erase(prefabName) > 0; - } - else - { - m_delayedDelete.emplace_back(prefabName); - } - return false; - } - void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) { m_isIterating = true; for (auto& it : m_prefabs) { - if (AZStd::find(m_delayedDelete.begin(), m_delayedDelete.end(), it.first) == m_delayedDelete.end()) - { - callback(it.first, it.second); - } + callback(it.first, it.second); } m_isIterating = false; - - // Clear out any prefabs that have been deleted. - for (AZStd::string& deleted : m_delayedDelete) - { - m_prefabs.erase(deleted); - } - m_delayedDelete.clear(); } void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) const @@ -70,6 +49,32 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return !m_prefabs.empty(); } + void PrefabProcessorContext::RegisterProductDependency(AZStd::string& prefabName, AZStd::string& dependentPrefabName) + { + using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; + + uint32_t prefabSubId = ConversionUtils::BuildSubId(prefabName + + AzFramework::Spawnable::DotFileExtension); + + uint32_t dependentPrefabSubId = ConversionUtils::BuildSubId(dependentPrefabName + + AzFramework::Spawnable::DotFileExtension); + + RegisterProductDependency(prefabSubId, dependentPrefabSubId); + } + + void PrefabProcessorContext::RegisterProductDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId) + { + AZ::Data::AssetId spawnableAssetId(GetSourceUuid(), spawnableAssetSubId); + AZ::Data::AssetId dependentSpawnableAssetId(GetSourceUuid(), dependentSpawnableAssetSubId); + + RegisterProductDependency(spawnableAssetId, dependentSpawnableAssetId); + } + + void PrefabProcessorContext::RegisterProductDependency(AZ::Data::AssetId& assetId, AZ::Data::AssetId& dependentAssetId) + { + m_registeredProductDependencies[assetId].emplace(dependentAssetId); + } + PrefabProcessorContext::ProcessedObjectStoreContainer& PrefabProcessorContext::GetProcessedObjects() { return m_products; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index 66368f335b..b98ce9c12b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -37,11 +37,14 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils virtual ~PrefabProcessorContext() = default; virtual bool AddPrefab(AZStd::string prefabName, PrefabDom prefab); - virtual bool RemovePrefab(AZStd::string_view prefabName); virtual void ListPrefabs(const AZStd::function& callback); virtual void ListPrefabs(const AZStd::function& callback) const; virtual bool HasPrefabs() const; + virtual void RegisterProductDependency(AZStd::string& prefabName, AZStd::string& dependentPrefabName); + virtual void RegisterProductDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId); + virtual void RegisterProductDependency(AZ::Data::AssetId& assetId, AZ::Data::AssetId& dependentAssetId); + virtual ProcessedObjectStoreContainer& GetProcessedObjects(); virtual const ProcessedObjectStoreContainer& GetProcessedObjects() const; @@ -54,10 +57,13 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils protected: using NamedPrefabContainer = AZStd::unordered_map; - + using ProductDependencyContainer = + AZStd::unordered_map>; + NamedPrefabContainer m_prefabs; ProcessedObjectStoreContainer m_products; - AZStd::vector m_delayedDelete; + ProductDependencyContainer m_registeredProductDependencies; + AZ::PlatformTagSet m_platformTags; AZ::Uuid m_sourceUuid; bool m_isIterating{ false }; From 48c34628f60c1475a4f2d377604a83a3ef6a43d2 Mon Sep 17 00:00:00 2001 From: daimini Date: Wed, 28 Apr 2021 13:34:02 -0700 Subject: [PATCH 011/225] Exclude the Level root prefab container when creating prefabs. --- .../Prefab/PrefabPublicHandler.cpp | 22 +++++++--- .../UI/Prefab/PrefabIntegrationManager.cpp | 42 ++++++++++--------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 1e9cc35230..46c3eaefe4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -89,7 +89,7 @@ namespace AzToolsFramework if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances)) { return AZ::Failure( - AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root.")); + AZStd::string("Could not create a new prefab out of the entities provided - invalid selection.")); } // When we create a prefab with other prefab instances, we have to remove the existing links between the source and @@ -142,9 +142,13 @@ namespace AzToolsFramework // Mark them as dirty so this change is correctly applied to the template for (AZ::Entity* topLevelEntity : topLevelEntities) { - m_prefabUndoCache.UpdateCache(topLevelEntity->GetId()); - undoBatch.MarkEntityDirty(topLevelEntity->GetId()); - AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); + AZ::EntityId topLevelEntityId = topLevelEntity->GetId(); + if (topLevelEntityId.IsValid() && !IsLevelInstanceContainerEntity(topLevelEntityId)) + { + m_prefabUndoCache.UpdateCache(topLevelEntityId); + undoBatch.MarkEntityDirty(topLevelEntityId); + AZ::TransformBus::Event(topLevelEntityId, &AZ::TransformBus::Events::SetParent, containerEntityId); + } } // Select Container Entity @@ -223,6 +227,14 @@ namespace AzToolsFramework // Retrieve entityList from entityIds inputEntityList = EntityIdListToEntityList(entityIds); + // Remove Level Container Entity if it's part of the list + AZ::Entity* levelEntity = GetEntityById(GetLevelInstanceContainerEntityId()); + auto levelEntityIter = AZStd::find(inputEntityList.begin(), inputEntityList.end(), levelEntity); + if (levelEntityIter != inputEntityList.end()) + { + inputEntityList.erase(levelEntityIter); + } + // Find common root and top level entities bool entitiesHaveCommonRoot = false; @@ -840,7 +852,7 @@ namespace AzToolsFramework outInstances.push_back(AZStd::move(commonRootEntityOwningInstance.DetachNestedInstance(instancePtr->GetInstanceAlias()))); } - return true; + return (outEntities.size() + outInstances.size()) > 0; } bool PrefabPublicHandler::EntitiesBelongToSameInstance(const EntityIdList& entityIds) const diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp index 6ce3fdc755..71354b8a1b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp @@ -151,32 +151,36 @@ namespace AzToolsFramework { if (!selectedEntities.empty()) { - bool layerInSelection = false; - - for (AZ::EntityId entityId : selectedEntities) + // Hide if the only selected entity is the Level Container + if (selectedEntities.size() > 1 || !s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntities[0])) { - if (!layerInSelection) - { - AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult( - layerInSelection, entityId, - &AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::HasLayer); + bool layerInSelection = false; - if (layerInSelection) + for (AZ::EntityId entityId : selectedEntities) + { + if (!layerInSelection) { - break; + AzToolsFramework::Layers::EditorLayerComponentRequestBus::EventResult( + layerInSelection, entityId, + &AzToolsFramework::Layers::EditorLayerComponentRequestBus::Events::HasLayer); + + if (layerInSelection) + { + break; + } } } - } - // Layers can't be in prefabs. - if (!layerInSelection) - { - QAction* createAction = menu->addAction(QObject::tr("Create Prefab...")); - createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities.")); + // Layers can't be in prefabs. + if (!layerInSelection) + { + QAction* createAction = menu->addAction(QObject::tr("Create Prefab...")); + createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities.")); - QObject::connect(createAction, &QAction::triggered, createAction, [this, selectedEntities] { - ContextMenu_CreatePrefab(selectedEntities); - }); + QObject::connect(createAction, &QAction::triggered, createAction, [this, selectedEntities] { + ContextMenu_CreatePrefab(selectedEntities); + }); + } } } } From 9dd3fe49df16f403076b097cb21e9d96b97f48a6 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Wed, 28 Apr 2021 17:27:20 -0700 Subject: [PATCH 012/225] fixing spelling and increasing angle so that the borders are not visible at 256 res --- .../Code/Source/CoreLights/DiskLightFeatureProcessor.cpp | 2 +- .../Code/Source/CoreLights/PointLightFeatureProcessor.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp index 58bbed699a..d0fb702d5a 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp @@ -380,7 +380,7 @@ namespace AZ const float invRadiusSquared = diskLight.m_invAttenuationRadiusSquared; if (invRadiusSquared <= 0.f) { - AZ_Assert(false, "Attenuation radius have to be set before use the light."); + AZ_Assert(false, "Attenuation radius must be set before using the light."); return; } const float attenuationRadius = sqrtf(1.f / invRadiusSquared); diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 9a940ea7b0..5110674492 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -222,7 +222,7 @@ namespace AZ void PointLightFeatureProcessor::SetPointData(LightHandle handle, const PointLightData& data) { - AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetDiskData()."); + AZ_Assert(handle.IsValid(), "Invalid LightHandle passed to PointLightFeatureProcessor::SetPointData()."); m_pointLightData.GetData(handle.GetIndex()) = data; m_deviceBufferNeedsUpdate = true; @@ -231,9 +231,9 @@ namespace AZ void PointLightFeatureProcessor::UpdateShadow(LightHandle handle) { + const auto& pointLight = m_pointLightData.GetData(handle.GetIndex()); for (int i = 0; i < PointLightData::NumShadowFaces; ++i) { - const auto& pointLight = m_pointLightData.GetData(handle.GetIndex()); ShadowId shadowId = ShadowId(pointLight.m_shadowIndices[i]); if (shadowId.IsNull()) { @@ -242,7 +242,7 @@ namespace AZ } ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = m_shadowFeatureProcessor->GetShadowProperties(shadowId); - desc.m_fieldOfViewYRadians = DegToRad(90.5f); // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces + desc.m_fieldOfViewYRadians = DegToRad(91.0f); // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces desc.m_transform = m_pointShadowTransforms[i]; desc.m_transform.SetTranslation(pointLight.m_position[0], pointLight.m_position[1], pointLight.m_position[2]); desc.m_aspectRatio = 1.0f; @@ -251,7 +251,7 @@ namespace AZ const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared; if (invRadiusSquared <= 0.f) { - AZ_Assert(false, "Attenuation radius have to be set before use the light."); + AZ_Assert(false, "Attenuation radius must be set before using the light."); return; } const float attenuationRadius = sqrtf(1.f / invRadiusSquared); From 815c02fb576cbded9c0cd2b8d7407bc3d9788d93 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Wed, 28 Apr 2021 17:45:17 -0700 Subject: [PATCH 013/225] better var names --- .../Atom/Features/PBR/Lights/PointLight.azsli | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index 95482d432f..42eb4b81da 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -15,7 +15,10 @@ #include #include -int GetShadowDirectionIndex(const float3 targetPos, const float3 lightPos) +// The order should match m_pointShadowTransforms in PointLightFeatureProcessor.h/.cpp +static const float3 PointLightShadowCubemapDirections[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)}; + +int GetPointLightShadowCubemapFace(const float3 targetPos, const float3 lightPos) { const float3 toPoint = targetPos - lightPos; const float maxElement = max(abs(toPoint.z), max(abs(toPoint.x), abs(toPoint.y))); @@ -45,7 +48,7 @@ int GetShadowDirectionIndex(const float3 targetPos, const float3 lightPos) } } -int UnpackShadowIndex(const ViewSrg::PointLight light, const int i) +int UnpackPointLightShadowIndex(const ViewSrg::PointLight light, const int i) { if (i == 0) { @@ -97,15 +100,14 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD float backShadowRatio = 0.0; if (o_enableShadows) { - // The order should match m_pointShadowTransforms in PointLightFeatureProcessor.h/.cpp - const float3 PointShadowDirections[6] = {float3(-1,0,0), float3(1,0,0), float3(0,-1,0), float3(0,1,0), float3(0,0,-1), float3(0,0,1)}; - const int shadowDirectionIndex = GetShadowDirectionIndex(surface.position, light.m_position); - const int shadowIndex = UnpackShadowIndex(light, shadowDirectionIndex); + const int shadowCubemapFace = GetPointLightShadowCubemapFace(surface.position, light.m_position); + const int shadowIndex = UnpackPointLightShadowIndex(light, shadowCubemapFace); + litRatio *= ProjectedShadow::GetVisibility( shadowIndex, light.m_position, surface.position, - PointShadowDirections[shadowDirectionIndex], + PointLightShadowCubemapDirections[shadowCubemapFace], surface.normal); // Use backShadowRatio to carry thickness from shadow map for thick mode From 59077f068c54c74ea1b6de64dc9ea2b4fc4c0c71 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Wed, 28 Apr 2021 18:09:37 -0700 Subject: [PATCH 014/225] bit shifts instead of if else also comments --- .../Atom/Features/PBR/Lights/PointLight.azsli | 33 ++++--------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index 42eb4b81da..853d77e372 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -48,33 +48,14 @@ int GetPointLightShadowCubemapFace(const float3 targetPos, const float3 lightPos } } -int UnpackPointLightShadowIndex(const ViewSrg::PointLight light, const int i) +// PointLight::m_shadowIndices actually consists of uint16_t x 6 on the CPU, but visible as a uint32_t x 3 on the GPU. +// This function returns the proper uint16_t value given an input face in the range 0-5 +int UnpackPointLightShadowIndex(const ViewSrg::PointLight light, const int face) { - if (i == 0) - { - return light.m_shadowIndices[0] & 0xFFFF; - } - else if (i==1) - { - return (light.m_shadowIndices[0] >> 16) & 0xFFFF; - } - else if (i==2) - { - return (light.m_shadowIndices[1]) & 0xFFFF; - } - else if (i==3) - { - return (light.m_shadowIndices[1] >> 16) & 0xFFFF; - } - else if (i==4) - { - return (light.m_shadowIndices[2]) & 0xFFFF; - } - else - { - return (light.m_shadowIndices[2] >> 16) & 0xFFFF; - } -} + const int index = face >> 1; + const int shiftAmount = (face & 1) * 16; + return (light.m_shadowIndices[index] >> shiftAmount) & 0xFFFF; +} void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingData lightingData) { From 6271aaa77ff3beee79c183ecd7baf3bf38544b5b Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 29 Apr 2021 11:07:15 -0700 Subject: [PATCH 015/225] Exclude level container entity from prefab external reference gathering code --- .../UI/Prefab/PrefabIntegrationManager.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp index 71354b8a1b..7f28080e9e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp @@ -276,6 +276,15 @@ namespace AzToolsFramework QWidget* activeWindow = QApplication::activeWindow(); const AZStd::string prefabFilesPath = "@devassets@/Prefabs"; + // Remove Level entity if it's part of the list + + auto levelContainerIter = + AZStd::find(selectedEntities.begin(), selectedEntities.end(), s_prefabPublicInterface->GetLevelInstanceContainerEntityId()); + if (levelContainerIter != selectedEntities.end()) + { + selectedEntities.erase(levelContainerIter); + } + // Set default folder for prefabs AZ::IO::FileIOBase* fileIoBaseInstance = AZ::IO::FileIOBase::GetInstance(); From 845b74806103e27b7c927867778cbe93403b6f66 Mon Sep 17 00:00:00 2001 From: sconel Date: Thu, 29 Apr 2021 14:15:48 -0700 Subject: [PATCH 016/225] Updated PrefabBuilder to include product dependencies defined in AddProductDependency --- .../Spawnable/PrefabProcessorContext.cpp | 38 +++++++++++++++---- .../Prefab/Spawnable/PrefabProcessorContext.h | 14 ++++--- .../PrefabBuilder/PrefabBuilderComponent.cpp | 16 +++++++- .../PrefabBuilder/PrefabBuilderComponent.h | 1 + 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index 0d5f06d837..a17222cc1a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -49,30 +49,42 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return !m_prefabs.empty(); } - void PrefabProcessorContext::RegisterProductDependency(AZStd::string& prefabName, AZStd::string& dependentPrefabName) + bool PrefabProcessorContext::RegisterProductDependency(const AZStd::string& prefabName, const AZStd::string& dependentPrefabName) { using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; - uint32_t prefabSubId = ConversionUtils::BuildSubId(prefabName + + uint32_t spawnableSubId = ConversionUtils::BuildSubId(prefabName + AzFramework::Spawnable::DotFileExtension); - uint32_t dependentPrefabSubId = ConversionUtils::BuildSubId(dependentPrefabName + + uint32_t spawnablePrefabSubId = ConversionUtils::BuildSubId(dependentPrefabName + AzFramework::Spawnable::DotFileExtension); - RegisterProductDependency(prefabSubId, dependentPrefabSubId); + return RegisterProductDependency(spawnableSubId, spawnablePrefabSubId); } - void PrefabProcessorContext::RegisterProductDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId) + bool PrefabProcessorContext::RegisterProductDependency(const AZStd::string& prefabName, const AZ::Data::AssetId& dependentAssetId) + { + using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; + + uint32_t spawnableSubId = ConversionUtils::BuildSubId(prefabName + + AzFramework::Spawnable::DotFileExtension); + + AZ::Data::AssetId spawnableAssetId(GetSourceUuid(), spawnableSubId); + + return RegisterProductDependency(spawnableAssetId, dependentAssetId); + } + + bool PrefabProcessorContext::RegisterProductDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId) { AZ::Data::AssetId spawnableAssetId(GetSourceUuid(), spawnableAssetSubId); AZ::Data::AssetId dependentSpawnableAssetId(GetSourceUuid(), dependentSpawnableAssetSubId); - RegisterProductDependency(spawnableAssetId, dependentSpawnableAssetId); + return RegisterProductDependency(spawnableAssetId, dependentSpawnableAssetId); } - void PrefabProcessorContext::RegisterProductDependency(AZ::Data::AssetId& assetId, AZ::Data::AssetId& dependentAssetId) + bool PrefabProcessorContext::RegisterProductDependency(const AZ::Data::AssetId& assetId, const AZ::Data::AssetId& dependentAssetId) { - m_registeredProductDependencies[assetId].emplace(dependentAssetId); + return m_registeredProductDependencies[assetId].emplace(dependentAssetId).second; } PrefabProcessorContext::ProcessedObjectStoreContainer& PrefabProcessorContext::GetProcessedObjects() @@ -85,6 +97,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return m_products; } + PrefabProcessorContext::ProductDependencyContainer& PrefabProcessorContext::GetRegisteredProductDependencies() + { + return m_registeredProductDependencies; + } + + const PrefabProcessorContext::ProductDependencyContainer& PrefabProcessorContext::GetRegisteredProductDependencies() const + { + return m_registeredProductDependencies; + } + void PrefabProcessorContext::SetPlatformTags(AZ::PlatformTagSet tags) { m_platformTags = AZStd::move(tags); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index b98ce9c12b..141b0b04cb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -29,6 +29,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { public: using ProcessedObjectStoreContainer = AZStd::vector; + using ProductDependencyContainer = + AZStd::unordered_map>; AZ_CLASS_ALLOCATOR(PrefabProcessorContext, AZ::SystemAllocator, 0); AZ_RTTI(PrefabProcessorContext, "{C7D77E3A-C544-486B-B774-7C82C38FE22F}"); @@ -41,13 +43,17 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils virtual void ListPrefabs(const AZStd::function& callback) const; virtual bool HasPrefabs() const; - virtual void RegisterProductDependency(AZStd::string& prefabName, AZStd::string& dependentPrefabName); - virtual void RegisterProductDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId); - virtual void RegisterProductDependency(AZ::Data::AssetId& assetId, AZ::Data::AssetId& dependentAssetId); + virtual bool RegisterProductDependency(const AZStd::string& prefabName, const AZStd::string& dependentPrefabName); + virtual bool RegisterProductDependency(const AZStd::string& prefabName, const AZ::Data::AssetId& dependentAssetId); + virtual bool RegisterProductDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId); + virtual bool RegisterProductDependency(const AZ::Data::AssetId& assetId, const AZ::Data::AssetId& dependentAssetId); virtual ProcessedObjectStoreContainer& GetProcessedObjects(); virtual const ProcessedObjectStoreContainer& GetProcessedObjects() const; + virtual ProductDependencyContainer& GetRegisteredProductDependencies(); + virtual const ProductDependencyContainer& GetRegisteredProductDependencies() const; + virtual void SetPlatformTags(AZ::PlatformTagSet tags); virtual const AZ::PlatformTagSet& GetPlatformTags() const; virtual const AZ::Uuid& GetSourceUuid() const; @@ -57,8 +63,6 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils protected: using NamedPrefabContainer = AZStd::unordered_map; - using ProductDependencyContainer = - AZStd::unordered_map>; NamedPrefabContainer m_prefabs; ProcessedObjectStoreContainer m_products; diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp index 84a4cd5cc6..c640f21000 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp @@ -176,6 +176,7 @@ namespace AZ::Prefab bool PrefabBuilderComponent::StoreProducts( AZ::IO::PathView tempDirPath, const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store, + const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductDependencyContainer& registeredDependencies, AZStd::vector& outputProducts) const { outputProducts.reserve(store.size()); @@ -214,6 +215,18 @@ namespace AZ::Prefab if (AssetBuilderSDK::OutputObject(&object.GetAsset(), object.GetAssetType(), productPath.String(), object.GetAssetType(), object.GetAsset().GetId().m_subId, product)) { + auto findRegisteredDependencies = registeredDependencies.find(object.GetAsset().GetId()); + if (findRegisteredDependencies != registeredDependencies.end()) + { + AZStd::transform(findRegisteredDependencies->second.begin(), findRegisteredDependencies->second.end(), + AZStd::back_inserter(product.m_dependencies), + [](const AZ::Data::AssetId& productId) -> AssetBuilderSDK::ProductDependency + { + return AssetBuilderSDK::ProductDependency(productId, + AZ::Data::ProductDependencyInfo::CreateFlags(AZ::Data::AssetLoadBehavior::NoLoad)); + }); + } + outputProducts.push_back(AZStd::move(product)); } @@ -250,7 +263,8 @@ namespace AZ::Prefab AZ_TracePrintf("Prefab Builder", "Finalizing products.\n"); if (!context.HasPrefabs()) { - if (StoreProducts(tempDirPath, context.GetProcessedObjects(), jobProducts)) + if (StoreProducts(tempDirPath, context.GetProcessedObjects(), + context.GetRegisteredProductDependencies(), jobProducts)) { return true; } diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h index 7fbd0b4be0..6aaae10d5b 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h @@ -69,6 +69,7 @@ namespace AZ::Prefab bool StoreProducts( AZ::IO::PathView tempDirPath, const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store, + const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductDependencyContainer& registeredDependencies, AZStd::vector& outputProducts) const; void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response); From 15b1ae4b2d62418899d9bd543d54f5395717db57 Mon Sep 17 00:00:00 2001 From: sconel Date: Thu, 29 Apr 2021 14:24:09 -0700 Subject: [PATCH 017/225] Removed excess whitespace --- .../AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index 141b0b04cb..a9488e2730 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -63,7 +63,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils protected: using NamedPrefabContainer = AZStd::unordered_map; - + NamedPrefabContainer m_prefabs; ProcessedObjectStoreContainer m_products; ProductDependencyContainer m_registeredProductDependencies; From e22398700dc45d2f5be50c8e23f6d4fb89323698 Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 29 Apr 2021 16:19:58 -0700 Subject: [PATCH 018/225] Simplified some checks, added early outs. --- .../Prefab/PrefabPublicHandler.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 46c3eaefe4..da4eee2263 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -143,7 +143,7 @@ namespace AzToolsFramework for (AZ::Entity* topLevelEntity : topLevelEntities) { AZ::EntityId topLevelEntityId = topLevelEntity->GetId(); - if (topLevelEntityId.IsValid() && !IsLevelInstanceContainerEntity(topLevelEntityId)) + if (topLevelEntityId.IsValid()) { m_prefabUndoCache.UpdateCache(topLevelEntityId); undoBatch.MarkEntityDirty(topLevelEntityId); @@ -228,11 +228,18 @@ namespace AzToolsFramework inputEntityList = EntityIdListToEntityList(entityIds); // Remove Level Container Entity if it's part of the list - AZ::Entity* levelEntity = GetEntityById(GetLevelInstanceContainerEntityId()); - auto levelEntityIter = AZStd::find(inputEntityList.begin(), inputEntityList.end(), levelEntity); - if (levelEntityIter != inputEntityList.end()) + AZ::EntityId levelEntityId = GetLevelInstanceContainerEntityId(); + if (levelEntityId.IsValid()) { - inputEntityList.erase(levelEntityIter); + AZ::Entity* levelEntity = GetEntityById(levelEntityId); + if (levelEntity) + { + auto levelEntityIter = AZStd::find(inputEntityList.begin(), inputEntityList.end(), levelEntity); + if (levelEntityIter != inputEntityList.end()) + { + inputEntityList.erase(levelEntityIter); + } + } } // Find common root and top level entities @@ -765,6 +772,11 @@ namespace AzToolsFramework const EntityList& inputEntities, Instance& commonRootEntityOwningInstance, EntityList& outEntities, AZStd::vector>& outInstances) const { + if (inputEntities.size() == 0) + { + return false; + } + AZStd::queue entityQueue; for (auto inputEntity : inputEntities) From a9de24ef7df0725fc06905f5fbfc781bbc9f9c7c Mon Sep 17 00:00:00 2001 From: sconel Date: Thu, 29 Apr 2021 18:09:38 -0700 Subject: [PATCH 019/225] Addressed PR feedback on function args and names --- .../Spawnable/PrefabProcessorContext.cpp | 36 +++++++++---------- .../Prefab/Spawnable/PrefabProcessorContext.h | 16 ++++----- .../PrefabBuilder/PrefabBuilderComponent.cpp | 4 +-- .../PrefabBuilder/PrefabBuilderComponent.h | 2 +- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index a17222cc1a..ca790ee35a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -49,42 +49,42 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return !m_prefabs.empty(); } - bool PrefabProcessorContext::RegisterProductDependency(const AZStd::string& prefabName, const AZStd::string& dependentPrefabName) + bool PrefabProcessorContext::RegisterSpawnableProductAssetDependency(AZStd::string prefabName, AZStd::string dependentPrefabName) { using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; - uint32_t spawnableSubId = ConversionUtils::BuildSubId(prefabName + - AzFramework::Spawnable::DotFileExtension); + uint32_t spawnableSubId = ConversionUtils::BuildSubId(AZStd::move(prefabName + + AzFramework::Spawnable::DotFileExtension)); - uint32_t spawnablePrefabSubId = ConversionUtils::BuildSubId(dependentPrefabName + - AzFramework::Spawnable::DotFileExtension); + uint32_t spawnablePrefabSubId = ConversionUtils::BuildSubId(AZStd::move(dependentPrefabName + + AzFramework::Spawnable::DotFileExtension)); - return RegisterProductDependency(spawnableSubId, spawnablePrefabSubId); + return RegisterSpawnableProductAssetDependency(spawnableSubId, spawnablePrefabSubId); } - bool PrefabProcessorContext::RegisterProductDependency(const AZStd::string& prefabName, const AZ::Data::AssetId& dependentAssetId) + bool PrefabProcessorContext::RegisterSpawnableProductAssetDependency(AZStd::string prefabName, const AZ::Data::AssetId& dependentAssetId) { using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; - uint32_t spawnableSubId = ConversionUtils::BuildSubId(prefabName + - AzFramework::Spawnable::DotFileExtension); + uint32_t spawnableSubId = ConversionUtils::BuildSubId(AZStd::move(prefabName + + AzFramework::Spawnable::DotFileExtension)); AZ::Data::AssetId spawnableAssetId(GetSourceUuid(), spawnableSubId); - return RegisterProductDependency(spawnableAssetId, dependentAssetId); + return RegisterProductAssetDependency(spawnableAssetId, dependentAssetId); } - bool PrefabProcessorContext::RegisterProductDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId) + bool PrefabProcessorContext::RegisterSpawnableProductAssetDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId) { AZ::Data::AssetId spawnableAssetId(GetSourceUuid(), spawnableAssetSubId); AZ::Data::AssetId dependentSpawnableAssetId(GetSourceUuid(), dependentSpawnableAssetSubId); - return RegisterProductDependency(spawnableAssetId, dependentSpawnableAssetId); + return RegisterProductAssetDependency(spawnableAssetId, dependentSpawnableAssetId); } - bool PrefabProcessorContext::RegisterProductDependency(const AZ::Data::AssetId& assetId, const AZ::Data::AssetId& dependentAssetId) + bool PrefabProcessorContext::RegisterProductAssetDependency(const AZ::Data::AssetId& assetId, const AZ::Data::AssetId& dependentAssetId) { - return m_registeredProductDependencies[assetId].emplace(dependentAssetId).second; + return m_registeredProductAssetDependencies[assetId].emplace(dependentAssetId).second; } PrefabProcessorContext::ProcessedObjectStoreContainer& PrefabProcessorContext::GetProcessedObjects() @@ -97,14 +97,14 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return m_products; } - PrefabProcessorContext::ProductDependencyContainer& PrefabProcessorContext::GetRegisteredProductDependencies() + PrefabProcessorContext::ProductAssetDependencyContainer& PrefabProcessorContext::GetRegisteredProductAssetDependencies() { - return m_registeredProductDependencies; + return m_registeredProductAssetDependencies; } - const PrefabProcessorContext::ProductDependencyContainer& PrefabProcessorContext::GetRegisteredProductDependencies() const + const PrefabProcessorContext::ProductAssetDependencyContainer& PrefabProcessorContext::GetRegisteredProductAssetDependencies() const { - return m_registeredProductDependencies; + return m_registeredProductAssetDependencies; } void PrefabProcessorContext::SetPlatformTags(AZ::PlatformTagSet tags) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index a9488e2730..3dc8c99bf3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -29,7 +29,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { public: using ProcessedObjectStoreContainer = AZStd::vector; - using ProductDependencyContainer = + using ProductAssetDependencyContainer = AZStd::unordered_map>; AZ_CLASS_ALLOCATOR(PrefabProcessorContext, AZ::SystemAllocator, 0); @@ -43,16 +43,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils virtual void ListPrefabs(const AZStd::function& callback) const; virtual bool HasPrefabs() const; - virtual bool RegisterProductDependency(const AZStd::string& prefabName, const AZStd::string& dependentPrefabName); - virtual bool RegisterProductDependency(const AZStd::string& prefabName, const AZ::Data::AssetId& dependentAssetId); - virtual bool RegisterProductDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId); - virtual bool RegisterProductDependency(const AZ::Data::AssetId& assetId, const AZ::Data::AssetId& dependentAssetId); + virtual bool RegisterSpawnableProductAssetDependency(AZStd::string prefabName, AZStd::string dependentPrefabName); + virtual bool RegisterSpawnableProductAssetDependency(AZStd::string prefabName, const AZ::Data::AssetId& dependentAssetId); + virtual bool RegisterSpawnableProductAssetDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId); + virtual bool RegisterProductAssetDependency(const AZ::Data::AssetId& assetId, const AZ::Data::AssetId& dependentAssetId); virtual ProcessedObjectStoreContainer& GetProcessedObjects(); virtual const ProcessedObjectStoreContainer& GetProcessedObjects() const; - virtual ProductDependencyContainer& GetRegisteredProductDependencies(); - virtual const ProductDependencyContainer& GetRegisteredProductDependencies() const; + virtual ProductAssetDependencyContainer& GetRegisteredProductAssetDependencies(); + virtual const ProductAssetDependencyContainer& GetRegisteredProductAssetDependencies() const; virtual void SetPlatformTags(AZ::PlatformTagSet tags); virtual const AZ::PlatformTagSet& GetPlatformTags() const; @@ -66,7 +66,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils NamedPrefabContainer m_prefabs; ProcessedObjectStoreContainer m_products; - ProductDependencyContainer m_registeredProductDependencies; + ProductAssetDependencyContainer m_registeredProductAssetDependencies; AZ::PlatformTagSet m_platformTags; AZ::Uuid m_sourceUuid; diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp index c640f21000..2b97b8a63d 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp @@ -176,7 +176,7 @@ namespace AZ::Prefab bool PrefabBuilderComponent::StoreProducts( AZ::IO::PathView tempDirPath, const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store, - const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductDependencyContainer& registeredDependencies, + const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductAssetDependencyContainer& registeredDependencies, AZStd::vector& outputProducts) const { outputProducts.reserve(store.size()); @@ -264,7 +264,7 @@ namespace AZ::Prefab if (!context.HasPrefabs()) { if (StoreProducts(tempDirPath, context.GetProcessedObjects(), - context.GetRegisteredProductDependencies(), jobProducts)) + context.GetRegisteredProductAssetDependencies(), jobProducts)) { return true; } diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h index 6aaae10d5b..f78e2cb889 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h @@ -69,7 +69,7 @@ namespace AZ::Prefab bool StoreProducts( AZ::IO::PathView tempDirPath, const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store, - const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductDependencyContainer& registeredDependencies, + const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductAssetDependencyContainer& registeredDependencies, AZStd::vector& outputProducts) const; void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response); From 6e8b1d10004a01d9ff3db0023a48763f9f348191 Mon Sep 17 00:00:00 2001 From: sconel Date: Thu, 29 Apr 2021 18:28:07 -0700 Subject: [PATCH 020/225] Update on how we move string values in AddProductDependency --- .../Prefab/Spawnable/PrefabProcessorContext.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index ca790ee35a..38f58503ed 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -53,11 +53,11 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; - uint32_t spawnableSubId = ConversionUtils::BuildSubId(AZStd::move(prefabName + - AzFramework::Spawnable::DotFileExtension)); + prefabName += AzFramework::Spawnable::DotFileExtension; + uint32_t spawnableSubId = ConversionUtils::BuildSubId(AZStd::move(prefabName)); - uint32_t spawnablePrefabSubId = ConversionUtils::BuildSubId(AZStd::move(dependentPrefabName + - AzFramework::Spawnable::DotFileExtension)); + dependentPrefabName += AzFramework::Spawnable::DotFileExtension; + uint32_t spawnablePrefabSubId = ConversionUtils::BuildSubId(AZStd::move(dependentPrefabName)); return RegisterSpawnableProductAssetDependency(spawnableSubId, spawnablePrefabSubId); } @@ -66,8 +66,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; - uint32_t spawnableSubId = ConversionUtils::BuildSubId(AZStd::move(prefabName + - AzFramework::Spawnable::DotFileExtension)); + prefabName += AzFramework::Spawnable::DotFileExtension; + uint32_t spawnableSubId = ConversionUtils::BuildSubId(AZStd::move(prefabName)); AZ::Data::AssetId spawnableAssetId(GetSourceUuid(), spawnableSubId); From 738883a9b07b855d4e0f7ed81a433b2601e8e83f Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Fri, 30 Apr 2021 11:43:32 -0700 Subject: [PATCH 021/225] Kens feedback --- .../CoreLights/PointLightFeatureProcessor.cpp | 4 +++- .../Source/CoreLights/SphereLightDelegate.cpp | 18 +++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 5110674492..82f41afbee 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -231,6 +231,8 @@ namespace AZ void PointLightFeatureProcessor::UpdateShadow(LightHandle handle) { + constexpr float SqrtHalf = 0.707106781187f; // sqrt(0.5); + const auto& pointLight = m_pointLightData.GetData(handle.GetIndex()); for (int i = 0; i < PointLightData::NumShadowFaces; ++i) { @@ -246,7 +248,7 @@ namespace AZ desc.m_transform = m_pointShadowTransforms[i]; desc.m_transform.SetTranslation(pointLight.m_position[0], pointLight.m_position[1], pointLight.m_position[2]); desc.m_aspectRatio = 1.0f; - desc.m_nearPlaneDistance = 0.0f; + desc.m_nearPlaneDistance = SqrtHalf * pointLight.m_bulbRadius; const float invRadiusSquared = pointLight.m_invAttenuationRadiusSquared; if (invRadiusSquared <= 0.f) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp index 7a74ad4c5c..e3cf1fac78 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp @@ -67,12 +67,16 @@ namespace AZ void SphereLightDelegate::SetEnableShadow(bool enabled) { Base::SetEnableShadow(enabled); - GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled); + + if (GetLightHandle().IsValid()) + { + GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled); + } } void SphereLightDelegate::SetShadowmapMaxSize(ShadowmapSize size) { - if (GetShadowsEnabled()) + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size); } @@ -80,7 +84,7 @@ namespace AZ void SphereLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method) { - if (GetShadowsEnabled()) + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method); } @@ -88,7 +92,7 @@ namespace AZ void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees) { - if (GetShadowsEnabled()) + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees)); } @@ -96,7 +100,7 @@ namespace AZ void SphereLightDelegate::SetPredictionSampleCount(uint32_t count) { - if (GetShadowsEnabled()) + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count); } @@ -104,7 +108,7 @@ namespace AZ void SphereLightDelegate::SetFilteringSampleCount(uint32_t count) { - if (GetShadowsEnabled()) + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count); } @@ -112,7 +116,7 @@ namespace AZ void SphereLightDelegate::SetPcfMethod(PcfMethod method) { - if (GetShadowsEnabled()) + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method); } From 2e1c4e52d38020f81354c134b778d9adab6d6b55 Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Sat, 1 May 2021 01:51:13 -0700 Subject: [PATCH 022/225] Improvements to reflection probe scaling --- .../ReflectionProbe/ReflectionProbe.cpp | 28 +++++++++++++------ .../Source/ReflectionProbe/ReflectionProbe.h | 4 +-- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp index cfce718146..e30fd8663f 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp @@ -120,13 +120,13 @@ namespace AZ { // stencil Srg // Note: the stencil pass uses a slightly reduced inner AABB to avoid seams - Vector3 innerExtentsReduced = m_innerExtents * m_transform.GetScale() - Vector3(0.1f, 0.1f, 0.1f); + Vector3 innerExtentsReduced = m_innerExtents - Vector3(0.1f, 0.1f, 0.1f); Matrix3x4 modelToWorldStencil = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(innerExtentsReduced); m_stencilSrg->SetConstant(m_reflectionRenderData->m_modelToWorldStencilConstantIndex, modelToWorldStencil); m_stencilSrg->Compile(); // blend weight Srg - Matrix3x4 modelToWorldOuter = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_outerExtents * m_transform.GetScale()); + Matrix3x4 modelToWorldOuter = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_outerExtents); m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_modelToWorldRenderConstantIndex, modelToWorldOuter); m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_aabbPosRenderConstantIndex, m_outerAabbWs.GetCenter()); m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_outerAabbMinRenderConstantIndex, m_outerAabbWs.GetMin()); @@ -149,7 +149,7 @@ namespace AZ m_renderOuterSrg->Compile(); // render inner Srg - Matrix3x4 modelToWorldInner = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_innerExtents * m_transform.GetScale()); + Matrix3x4 modelToWorldInner = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_innerExtents); m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_modelToWorldRenderConstantIndex, modelToWorldInner); m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_aabbPosRenderConstantIndex, m_outerAabbWs.GetCenter()); m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_outerAabbMinRenderConstantIndex, m_outerAabbWs.GetMin()); @@ -208,6 +208,12 @@ namespace AZ void ReflectionProbe::SetTransform(const AZ::Transform& transform) { + // retrieve previous scale and revert the scale on the inner/outer extents + AZ::Vector3 previousScale = m_transform.GetScale(); + m_outerExtents /= previousScale; + m_innerExtents /= previousScale; + + // store new transform m_transform = transform; // avoid scaling the visualization sphere @@ -215,22 +221,26 @@ namespace AZ visualizationTransform.ExtractScale(); m_meshFeatureProcessor->SetTransform(m_visualizationMeshHandle, visualizationTransform); - m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents * m_transform.GetScale() / 2.0f); - m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents * m_transform.GetScale() / 2.0f); + // update the inner/outer extents with the new scale + m_outerExtents *= m_transform.GetScale(); + m_innerExtents *= m_transform.GetScale(); + + m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents / 2.0f); + m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents / 2.0f); m_updateSrg = true; } void ReflectionProbe::SetOuterExtents(const AZ::Vector3& outerExtents) { - m_outerExtents = outerExtents; - m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents * m_transform.GetScale() / 2.0f); + m_outerExtents = outerExtents * m_transform.GetScale(); + m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents / 2.0f); m_updateSrg = true; } void ReflectionProbe::SetInnerExtents(const AZ::Vector3& innerExtents) { - m_innerExtents = innerExtents; - m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents * m_transform.GetScale() / 2.0f); + m_innerExtents = innerExtents * m_transform.GetScale(); + m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents / 2.0f); m_updateSrg = true; } diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h index 42b3ff5c5a..56826a8ba3 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h @@ -78,10 +78,10 @@ namespace AZ const Vector3& GetPosition() const { return m_transform.GetTranslation(); } void SetTransform(const AZ::Transform& transform); - AZ::Vector3 GetOuterExtents() const { return m_outerExtents * m_transform.GetScale(); } + const AZ::Vector3& GetOuterExtents() const { return m_outerExtents; } void SetOuterExtents(const AZ::Vector3& outerExtents); - AZ::Vector3 GetInnerExtents() const { return m_innerExtents * m_transform.GetScale(); } + const AZ::Vector3& GetInnerExtents() const { return m_innerExtents; } void SetInnerExtents(const AZ::Vector3& innerExtents); const Aabb& GetOuterAabbWs() const { return m_outerAabbWs; } From cc15e0d489f5768bc681fd19958456d52c8e8b39 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Mon, 3 May 2021 13:19:53 -0700 Subject: [PATCH 023/225] Avoid alignment issue if it ever went to cbuffer --- .../Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli | 3 +-- .../Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli | 3 +-- .../Common/Assets/Shaders/LightCulling/LightCulling.azsl | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli index 6c4a6d2a36..aeb57259e7 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli @@ -73,8 +73,7 @@ partial ShaderResourceGroup ViewSrg float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; - uint m_shadowIndices[3]; - uint m_padding; + uint4 m_shadowIndices; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli index b392e07e06..2bccee4902 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli @@ -63,8 +63,7 @@ partial ShaderResourceGroup RayTracingSceneSrg float m_invAttenuationRadiusSquared; float3 m_rgbIntensity; float m_bulbRadius; - uint m_shadowIndices[3]; - uint m_padding; + uint4 m_shadowIndices; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl index 398103a93f..41b42ca68b 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl @@ -59,8 +59,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; - uint m_shadowIndices[3]; - uint m_padding; + uint4 m_shadowIndices; }; struct DiskLight From b5d62b9cf69b2c287396ffc56ed78d5eeeec45a4 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Tue, 4 May 2021 10:36:57 -0700 Subject: [PATCH 024/225] Better variables --- .../Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli | 3 ++- .../Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli | 3 ++- .../Common/Assets/Shaders/LightCulling/LightCulling.azsl | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli index aeb57259e7..7a51d4c629 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/CoreLights/ViewSrg.azsli @@ -73,7 +73,8 @@ partial ShaderResourceGroup ViewSrg float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; - uint4 m_shadowIndices; + uint3 m_shadowIndices; + uint m_padding; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli index 2bccee4902..2ae74466d6 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/RayTracingSceneSrg.azsli @@ -63,7 +63,8 @@ partial ShaderResourceGroup RayTracingSceneSrg float m_invAttenuationRadiusSquared; float3 m_rgbIntensity; float m_bulbRadius; - uint4 m_shadowIndices; + uint3 m_shadowIndices; + uint m_padding; }; StructuredBuffer m_pointLights; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl index 41b42ca68b..0327a723d6 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl @@ -59,7 +59,8 @@ ShaderResourceGroup PassSrg : SRG_PerPass float m_invAttenuationRadiusSquared; // For a radius at which this light no longer has an effect, 1 / radius^2. float3 m_rgbIntensityCandelas; float m_bulbRadius; - uint4 m_shadowIndices; + uint3 m_shadowIndices; + uint m_padding; }; struct DiskLight From a2d2a372202590f736de47e533fc013cb4c1e9db Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Tue, 4 May 2021 10:38:21 -0700 Subject: [PATCH 025/225] Better commenting and readability fixes --- .../CoreLights/PointLightFeatureProcessorInterface.h | 11 +++++++---- .../Source/CoreLights/PointLightFeatureProcessor.cpp | 7 ++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h index aaffac6d5a..30d88cb839 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h @@ -26,13 +26,16 @@ namespace AZ struct PointLightData { AZStd::array m_position = {{0.0f, 0.0f, 0.0f}}; - float m_invAttenuationRadiusSquared = - 0.0f; // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations. + + // Inverse of the distance at which this light no longer has an effect, squared. Also used for falloff calculations. + float m_invAttenuationRadiusSquared = 0.0f; + AZStd::array m_rgbIntensity = {{0.0f, 0.0f, 0.0f}}; - float m_bulbRadius = 0.0f; // Radius of spherical light in meters. + + // Radius of spherical light in meters. + float m_bulbRadius = 0.0f; static const int NumShadowFaces = 6; - AZStd::array m_shadowIndices = {{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}}; uint32_t m_padding; }; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 82f41afbee..bb81c52b15 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -201,7 +201,7 @@ namespace AZ for (int i = 0; i < PointLightData::NumShadowFaces; ++i) { ShadowId shadowId = ShadowId(light.m_shadowIndices[i]); - if (shadowId.IsValid() && enabled == false) + if (shadowId.IsValid() && !enabled) { // Disable shadows m_shadowFeatureProcessor->ReleaseShadow(shadowId); @@ -209,7 +209,7 @@ namespace AZ light.m_shadowIndices[i] = shadowId.GetIndex(); m_deviceBufferNeedsUpdate = true; } - else if (shadowId.IsNull() && enabled == true) + else if (shadowId.IsNull() && enabled) { // Enable shadows light.m_shadowIndices[i] = m_shadowFeatureProcessor->AcquireShadow().GetIndex(); @@ -244,7 +244,8 @@ namespace AZ } ProjectedShadowFeatureProcessorInterface::ProjectedShadowDescriptor desc = m_shadowFeatureProcessor->GetShadowProperties(shadowId); - desc.m_fieldOfViewYRadians = DegToRad(91.0f); // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces + // Make it slightly larger than 90 degrees to avoid artifacts on the boundary between 2 cubemap faces + desc.m_fieldOfViewYRadians = DegToRad(91.0f); desc.m_transform = m_pointShadowTransforms[i]; desc.m_transform.SetTranslation(pointLight.m_position[0], pointLight.m_position[1], pointLight.m_position[2]); desc.m_aspectRatio = 1.0f; From c51e90d2243a69f096174fa18896f35b3880c918 Mon Sep 17 00:00:00 2001 From: Michael Riegger Date: Tue, 4 May 2021 12:12:27 -0700 Subject: [PATCH 026/225] Fix unused variable --- .../Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli index 853d77e372..b28f0f1708 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PointLight.azsli @@ -105,7 +105,7 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, lightIntensity, normalize(posToLight)) * litRatio; // Tranmission contribution - lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), 0.0) * litRatio; + lightingData.translucentBackLighting += GetBackLighting(surface, lightingData, lightIntensity, normalize(posToLight), backShadowRatio); // Adjust the light direcion for specular based on bulb size From 71eccf3a6abc4f0c92d645b4cdbd1e30eaf44878 Mon Sep 17 00:00:00 2001 From: darapan Date: Wed, 5 May 2021 04:16:48 -0700 Subject: [PATCH 027/225] "Adding New Test" --- .../PythonTests/scripting/TestSuite_Active.py | 4 + .../scripting/Unpin_VariableManager.py | 133 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index 8c34f29ebf..da67f21db1 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -31,3 +31,7 @@ class TestAutomation(TestAutomationBase): def test_Resizing_Pane(self, request, workspace, editor, launcher_platform): from . import Resizing_Pane as test_module self._run_test(request, workspace, editor, test_module) + + def test_Unpin_VariableManager(self, request, workspace, editor, launcher_platform): + from . import Unpin_VariableManager as test_module + self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py b/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py new file mode 100644 index 0000000000..e88236d13e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py @@ -0,0 +1,133 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +https://testrail.agscollab.com/index.php?/tests/view/92568973 +""" + + +# fmt: off +class Tests(): + open_sc_window = ("Script Canvas window is opened", "Failed to open Script Canvas window") + variable_manager_opened = ("VariableManager is opened successfully", "Failed to open VariableManager") + boolean_pinned = ("Boolean is pinned", "Boolean is not pinned, But it should be unpinned") + boolean_unpinned = ("Boolean is unpinned", "Boolean is not unpinned, But it should be pinned") + boolean_unpinned_after_reopen = ("Boolean is unpinned after reopening create variable menu", "Boolean is not unpinned after reopening create variable menu") +# fmt: on + + +def Unpin_VariableManager(): + """ + Summary: + Unpin variable types in create variable menu. + + Expected Behavior: + The variable unpinned in create variable menu remains unpinned after reopening create variable menu. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Variable Manager in Script Canvas window + 4) Create new graph + 5) Click on the Create Variable button in the Variable Manager + 6) Unpin Boolean by clicking the "Pin" icon on its left side + 7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu + 8) Restore default layout and close SC window + + Note: + - This test file must be called from the Lumberyard Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from PySide2 import QtWidgets + import azlmbr.legacy.general as general + + import pyside_utils + from utils import TestHelper as helper + from utils import Report + from PySide2.QtCore import Qt + + GENERAL_WAIT = 5.0 # seconds + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + is_sc_visible = helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 15.0) + Report.result(Tests.open_sc_window, is_sc_visible) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + sc_main = sc.findChild(QtWidgets.QMainWindow) + + # 3) Open Variable Manager in Script Canvas window + pane = find_pane(sc, "VariableManager") + if not pane.isVisible(): + click_menu_option(sc, "Variable Manager") + pane = find_pane(sc, "VariableManager") + Report.result(Tests.variable_manager_opened, pane.isVisible()) + + # 4) Create new graph + create_new_graph = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} + ) + create_new_graph.trigger() + + # 5) Click on the Create Variable button in the Variable Manager + variable_manager = sc_main.findChild(QtWidgets.QDockWidget, "VariableManager") + button = variable_manager.findChild(QtWidgets.QPushButton, "addButton") + button.click() + + # 6) Unpin Boolean by clicking the "Pin" icon on its left side + table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") + model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") + # Make sure Boolean is pinned + result = helper.wait_for_condition( + lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is not None, GENERAL_WAIT + ) + Report.result(Tests.boolean_pinned, result) + # Unpin Boolean and make sure Boolean is unpinned. + pyside_utils.item_view_index_mouse_click(table_view, model_index.siblingAtColumn(0)) + result = helper.wait_for_condition( + lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is None, GENERAL_WAIT + ) + Report.result(Tests.boolean_unpinned, result) + + # 7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu + button.click() + button.click() + general.idle_wait(1.0) + result = helper.wait_for_condition( + lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is None, GENERAL_WAIT + ) + Report.result(Tests.boolean_unpinned_after_reopen, result) + + # 8) Restore default layout and close SC window + click_menu_option(sc, "Restore Default Layout") + sc.close() + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + + from utils import Report + + Report.start_test(Unpin_VariableManager) From c90be6effae4ce570c930c45272d6d3a7b811003 Mon Sep 17 00:00:00 2001 From: darapan Date: Wed, 5 May 2021 04:22:52 -0700 Subject: [PATCH 028/225] "Ran fixup" --- .../Gem/PythonTests/scripting/Unpin_VariableManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py b/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py index e88236d13e..682084ff68 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py @@ -97,7 +97,7 @@ def Unpin_VariableManager(): # 6) Unpin Boolean by clicking the "Pin" icon on its left side table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") - # Make sure Boolean is pinned + # Make sure Boolean is pinned result = helper.wait_for_condition( lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is not None, GENERAL_WAIT ) From 6dcc75ed78a6478796888c273f0ddb15fe8fb3ac Mon Sep 17 00:00:00 2001 From: Aristo7 <5432499+Aristo7@users.noreply.github.com> Date: Wed, 5 May 2021 14:43:41 -0500 Subject: [PATCH 029/225] AtomBridge contains all runtime deps now --- .../Platform/Mac/runtime_dependencies.cmake | 2 -- .../Code/Platform/Mac/tool_dependencies.cmake | 4 --- .../Windows/runtime_dependencies.cmake | 3 -- .../Platform/Windows/tool_dependencies.cmake | 7 ---- .../Gem/Code/runtime_dependencies.cmake | 10 ------ .../Gem/Code/tool_dependencies.cmake | 15 --------- .../AtomBridge/Code/CMakeLists.txt | 33 +++++++++++++++++++ .../additional_windows_runtime_deps.cmake | 14 ++++++++ .../additional_windows_tool_deps.cmake | 13 ++++++++ .../additional_windows_runtime_deps.cmake | 14 ++++++++ .../Linux/additional_windows_tool_deps.cmake | 15 +++++++++ .../Mac/additional_windows_runtime_deps.cmake | 14 ++++++++ .../Mac/additional_windows_tool_deps.cmake | 19 +++++++++++ .../additional_windows_runtime_deps.cmake | 16 +++++++++ .../additional_windows_tool_deps.cmake | 20 +++++++++++ .../iOS/additional_windows_runtime_deps.cmake | 14 ++++++++ .../iOS/additional_windows_tool_deps.cmake | 13 ++++++++ 17 files changed, 185 insertions(+), 41 deletions(-) create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_runtime_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_tool_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_runtime_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_tool_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_runtime_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_tool_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_runtime_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_runtime_deps.cmake create mode 100644 Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_tool_deps.cmake diff --git a/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake index f9d1e60dda..ffcaf7293a 100644 --- a/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake @@ -10,6 +10,4 @@ # set(GEM_DEPENDENCIES - Gem::Atom_RHI_Metal.Private - Gem::Atom_RHI_Null.Private ) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake index ee7be9ac6d..ffcaf7293a 100644 --- a/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake @@ -10,8 +10,4 @@ # set(GEM_DEPENDENCIES - Gem::Atom_RHI_Null.Private - Gem::Atom_RHI_Null.Builders - Gem::Atom_RHI_Metal.Private - Gem::Atom_RHI_Metal.Builders ) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake index 0a1541bcfc..ffcaf7293a 100644 --- a/AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake @@ -10,7 +10,4 @@ # set(GEM_DEPENDENCIES - Gem::Atom_RHI_Vulkan.Private - Gem::Atom_RHI_DX12.Private - Gem::Atom_RHI_Null.Private ) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake index ddd3bfa6a7..933dd7927b 100644 --- a/AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake @@ -11,11 +11,4 @@ set(GEM_DEPENDENCIES Gem::QtForPython.Editor - Gem::Atom_RHI_Vulkan.Private - Gem::Atom_RHI_Vulkan.Builders - Gem::Atom_RHI_DX12.Private - Gem::Atom_RHI_DX12.Builders - Gem::Atom_RHI_Null.Private - Gem::Atom_RHI_Null.Builders - Gem::Atom_RHI_Metal.Builders ) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake index c8e66740e4..da0a70b9cd 100644 --- a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake @@ -42,16 +42,6 @@ set(GEM_DEPENDENCIES Gem::SurfaceData Gem::GradientSignal Gem::Vegetation - Gem::Atom_RHI.Private - Gem::Atom_RPI.Private - Gem::Atom_Feature_Common - Gem::Atom_Bootstrap - Gem::Atom_Component_DebugCamera - Gem::AtomImGuiTools - Gem::AtomLyIntegration_CommonFeatures - Gem::EMotionFX_Atom - Gem::ImguiAtom Gem::Atom_AtomBridge - Gem::AtomFont Gem::Blast ) diff --git a/AutomatedTesting/Gem/Code/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/tool_dependencies.cmake index 8c5da63f42..f0e73e8a11 100644 --- a/AutomatedTesting/Gem/Code/tool_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/tool_dependencies.cmake @@ -50,23 +50,8 @@ set(GEM_DEPENDENCIES Gem::Vegetation.Editor Gem::GraphModel.Editor Gem::LandscapeCanvas.Editor - Gem::Atom_RHI.Private Gem::EMotionFX.Editor - Gem::Atom_RPI.Builders - Gem::Atom_RPI.Editor - Gem::Atom_Feature_Common.Builders - Gem::Atom_Feature_Common.Editor Gem::ImGui.Editor - Gem::Atom_Bootstrap - Gem::Atom_Asset_Shader.Builders - Gem::Atom_Component_DebugCamera - Gem::AtomImGuiTools - Gem::AtomLyIntegration_CommonFeatures.Editor - Gem::EMotionFX_Atom.Editor - Gem::ImageProcessingAtom.Editor Gem::Atom_AtomBridge.Editor - Gem::ImguiAtom - Gem::AtomFont - Gem::AtomToolsFramework.Editor Gem::Blast.Editor ) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt index b684e445b3..30861a6feb 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt @@ -9,6 +9,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) + ly_add_target( NAME Atom_AtomBridge.Static STATIC NAMESPACE Gem @@ -41,12 +43,25 @@ ly_add_target( Source PUBLIC Include + PLATFORM_INCLUDE_FILES + ${pal_dir}/additional_${PAL_PLATFORM_NAME_LOWERCASE}_runtime_deps.cmake COMPILE_DEFINITIONS PRIVATE ENABLE_ATOM_DEBUG_DISPLAY=1 BUILD_DEPENDENCIES PRIVATE Gem::Atom_AtomBridge.Static + RUNTIME_DEPENDENCIES + Gem::Atom_RHI.Private + Gem::Atom_RPI.Private + Gem::Atom_Feature_Common + Gem::Atom_Bootstrap + Gem::Atom_Component_DebugCamera + Gem::AtomImGuiTools + Gem::AtomLyIntegration_CommonFeatures + Gem::EMotionFX_Atom + Gem::ImguiAtom + Gem::AtomFont ) if(PAL_TRAIT_BUILD_HOST_TOOLS) @@ -60,6 +75,8 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) Source PUBLIC Include + PLATFORM_INCLUDE_FILES + ${pal_dir}/additional_${PAL_PLATFORM_NAME_LOWERCASE}_tool_deps.cmake COMPILE_DEFINITIONS PRIVATE EDITOR @@ -68,5 +85,21 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AssetBuilderSDK Gem::Atom_Utils.Static Gem::Atom_AtomBridge.Static + RUNTIME_DEPENDENCIES + Gem::Atom_RHI.Private + Gem::Atom_RPI.Builders + Gem::Atom_RPI.Editor + Gem::Atom_Feature_Common.Builders + Gem::Atom_Feature_Common.Editor + Gem::Atom_Bootstrap + Gem::Atom_Asset_Shader.Builders + Gem::Atom_Component_DebugCamera + Gem::AtomImGuiTools + Gem::AtomLyIntegration_CommonFeatures.Editor + Gem::EMotionFX_Atom.Editor + Gem::ImageProcessingAtom.Editor + Gem::ImguiAtom + Gem::AtomFont + Gem::AtomToolsFramework.Editor ) endif() diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_runtime_deps.cmake new file mode 100644 index 0000000000..31c0cab74b --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_runtime_deps.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_tool_deps.cmake new file mode 100644 index 0000000000..99eec9a733 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_tool_deps.cmake @@ -0,0 +1,13 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_runtime_deps.cmake new file mode 100644 index 0000000000..31c0cab74b --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_runtime_deps.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_tool_deps.cmake new file mode 100644 index 0000000000..8fb58f5e56 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_tool_deps.cmake @@ -0,0 +1,15 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_Vulkan.Builders +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_runtime_deps.cmake new file mode 100644 index 0000000000..a0aa67c703 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_runtime_deps.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Metal.Private +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_tool_deps.cmake new file mode 100644 index 0000000000..0b601adf8d --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_tool_deps.cmake @@ -0,0 +1,19 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Metal.Private + Gem::Atom_RHI_Metal.Builders + Gem::Atom_RHI_Vulkan.Builders + Gem::Atom_RHI_DX12.Builders + Gem::Atom_RHI_Null.Private + Gem::Atom_RHI_Null.Builders +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_runtime_deps.cmake new file mode 100644 index 0000000000..dfd0319c05 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_runtime_deps.cmake @@ -0,0 +1,16 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_Null.Private +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake new file mode 100644 index 0000000000..e30a9737ac --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake @@ -0,0 +1,20 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_Vulkan.Builders + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_DX12.Builders + Gem::Atom_RHI_Null.Private + Gem::Atom_RHI_Null.Builders + Gem::Atom_RHI_Metal.Builders +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_runtime_deps.cmake new file mode 100644 index 0000000000..a0aa67c703 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_runtime_deps.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Metal.Private +) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_tool_deps.cmake new file mode 100644 index 0000000000..99eec9a733 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_tool_deps.cmake @@ -0,0 +1,13 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES +) From 6a3e89202016cc21b0b489fdea2c85fbdd6a28ba Mon Sep 17 00:00:00 2001 From: Aristo7 <5432499+Aristo7@users.noreply.github.com> Date: Wed, 5 May 2021 15:42:57 -0500 Subject: [PATCH 030/225] Fixed up pal file names --- ...s_runtime_deps.cmake => additional_android_runtime_deps.cmake} | 0 ...windows_tool_deps.cmake => additional_android_tool_deps.cmake} | 0 ...ows_runtime_deps.cmake => additional_linux_runtime_deps.cmake} | 0 ...l_windows_tool_deps.cmake => additional_linux_tool_deps.cmake} | 0 ...ndows_runtime_deps.cmake => additional_mac_runtime_deps.cmake} | 0 ...nal_windows_tool_deps.cmake => additional_mac_tool_deps.cmake} | 0 ...ndows_runtime_deps.cmake => additional_ios_runtime_deps.cmake} | 0 ...nal_windows_tool_deps.cmake => additional_ios_tool_deps.cmake} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/{additional_windows_runtime_deps.cmake => additional_android_runtime_deps.cmake} (100%) rename Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/{additional_windows_tool_deps.cmake => additional_android_tool_deps.cmake} (100%) rename Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/{additional_windows_runtime_deps.cmake => additional_linux_runtime_deps.cmake} (100%) rename Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/{additional_windows_tool_deps.cmake => additional_linux_tool_deps.cmake} (100%) rename Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/{additional_windows_runtime_deps.cmake => additional_mac_runtime_deps.cmake} (100%) rename Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/{additional_windows_tool_deps.cmake => additional_mac_tool_deps.cmake} (100%) rename Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/{additional_windows_runtime_deps.cmake => additional_ios_runtime_deps.cmake} (100%) rename Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/{additional_windows_tool_deps.cmake => additional_ios_tool_deps.cmake} (100%) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_android_runtime_deps.cmake similarity index 100% rename from Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_runtime_deps.cmake rename to Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_android_runtime_deps.cmake diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_android_tool_deps.cmake similarity index 100% rename from Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_windows_tool_deps.cmake rename to Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Android/additional_android_tool_deps.cmake diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_runtime_deps.cmake similarity index 100% rename from Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_runtime_deps.cmake rename to Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_runtime_deps.cmake diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake similarity index 100% rename from Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_windows_tool_deps.cmake rename to Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_runtime_deps.cmake similarity index 100% rename from Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_runtime_deps.cmake rename to Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_runtime_deps.cmake diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake similarity index 100% rename from Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_windows_tool_deps.cmake rename to Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_runtime_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_ios_runtime_deps.cmake similarity index 100% rename from Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_runtime_deps.cmake rename to Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_ios_runtime_deps.cmake diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_ios_tool_deps.cmake similarity index 100% rename from Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_windows_tool_deps.cmake rename to Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/iOS/additional_ios_tool_deps.cmake From e80de63d55586dfc6ddf0bbd74b5fdfcc8c2c446 Mon Sep 17 00:00:00 2001 From: guthadam Date: Wed, 5 May 2021 23:31:17 -0500 Subject: [PATCH 031/225] ATOM-15486 Saving material editor user settings https://jira.agscollab.com/browse/ATOM-15486 --- .../Atom/Document/MaterialDocumentSettings.h | 34 ++++++++ .../Atom/Document/MaterialEditorSettingsBus.h | 49 ----------- .../MaterialViewportNotificationBus.h | 1 - .../Atom/Viewport/MaterialViewportSettings.h | 41 +++++++++ .../Window/MaterialEditorWindowSettings.h | 37 ++++++++ .../Document/MaterialDocumentSettings.cpp | 51 +++++++++++ .../MaterialDocumentSystemComponent.cpp | 59 +++++++------ .../MaterialDocumentSystemComponent.h | 8 +- .../Document/MaterialEditorSettings.cpp | 73 ---------------- .../Source/Document/MaterialEditorSettings.h | 45 ---------- .../Code/Source/MaterialEditorApplication.cpp | 5 +- .../Viewport/MaterialViewportComponent.cpp | 42 +++++---- .../Viewport/MaterialViewportComponent.h | 13 +-- .../Viewport/MaterialViewportRenderer.cpp | 18 ++-- .../Viewport/MaterialViewportSettings.cpp | 72 +++++++++++++++ .../Source/Window/MaterialEditorWindow.cpp | 25 ++++-- .../Window/MaterialEditorWindowComponent.cpp | 19 ++-- .../Window/MaterialEditorWindowSettings.cpp | 62 +++++++++++++ .../Window/ToolBar/MaterialEditorToolBar.cpp | 51 ++++++----- .../ViewportSettingsInspector.cpp | 87 ++++--------------- .../ViewportSettingsInspector.h | 20 +---- .../Code/materialeditor_files.cmake | 2 - .../Code/materialeditordocument_files.cmake | 6 +- .../Code/materialeditorviewport_files.cmake | 2 + .../Code/materialeditorwindow_files.cmake | 2 + 25 files changed, 463 insertions(+), 361 deletions(-) create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialEditorSettingsBus.h create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportSettings.h create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialEditorSettings.cpp delete mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialEditorSettings.h create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.cpp create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h new file mode 100644 index 0000000000..37d6a8c2d8 --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h @@ -0,0 +1,34 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#include +#endif + +namespace MaterialEditor +{ + struct MaterialDocumentSettings + : public AZ::UserSettings + { + AZ_RTTI(MaterialDocumentSettings, "{FA4F4BF3-BF39-4753-AAF7-AF383B868881}", AZ::UserSettings); + AZ_CLASS_ALLOCATOR(MaterialDocumentSettings, AZ::SystemAllocator, 0); + + static void Reflect(AZ::ReflectContext* context); + + bool m_showReloadDocumentPrompt = true; + }; +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialEditorSettingsBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialEditorSettingsBus.h deleted file mode 100644 index 3ddfdf44d4..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialEditorSettingsBus.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -namespace MaterialEditor -{ - class MaterialEditorSettingsRequests - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - virtual AZ::Outcome GetProperty(AZStd::string_view name) const = 0; - virtual AZ::Outcome GetStringProperty(AZStd::string_view name) const = 0; - virtual AZ::Outcome GetBoolProperty(AZStd::string_view name) const = 0; - - virtual void SetProperty(AZStd::string_view name, const AZStd::any& value) = 0; - virtual void SetStringProperty(AZStd::string_view name, AZStd::string_view stringValue) = 0; - virtual void SetBoolProperty(AZStd::string_view name, bool boolValue) = 0; - }; - using MaterialEditorSettingsRequestBus = AZ::EBus; - - class MaterialEditorSettingsNotifications - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - virtual void OnPropertyChanged(AZStd::string_view name, const AZStd::any& value) = 0; - }; - using MaterialEditorSettingsNotificationBus = AZ::EBus; - -} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportNotificationBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportNotificationBus.h index 0727547b13..af85dcc1db 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportNotificationBus.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportNotificationBus.h @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportSettings.h new file mode 100644 index 0000000000..7af6b307df --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/MaterialViewportSettings.h @@ -0,0 +1,41 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#include +#include +#endif + +namespace MaterialEditor +{ + struct MaterialViewportSettings + : public AZ::UserSettings + { + AZ_RTTI(MaterialViewportSettings, "{16150503-A314-4765-82A3-172670C9EA90}", AZ::UserSettings); + AZ_CLASS_ALLOCATOR(MaterialViewportSettings, AZ::SystemAllocator, 0); + + static void Reflect(AZ::ReflectContext* context); + + bool m_enableGrid = true; + bool m_enableShadowCatcher = true; + bool m_enableAlternateSkybox = false; + float m_fieldOfView = 90.0f; + AZ::Render::DisplayMapperOperationType m_displayMapperOperationType = AZ::Render::DisplayMapperOperationType::Aces; + AZStd::string m_selectedModelPresetName = "Shader Ball"; + AZStd::string m_selectedLightingPresetName = "Neutral Urban"; + }; +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h new file mode 100644 index 0000000000..bf572b070a --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h @@ -0,0 +1,37 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#include +#endif + +namespace MaterialEditor +{ + struct MaterialEditorWindowSettings + : public AZ::UserSettings + { + AZ_RTTI(MaterialEditorWindowSettings, "{BB9DEB77-B7BE-4DF5-9FDD-6D9F3136C4EA}", AZ::UserSettings); + AZ_CLASS_ALLOCATOR(MaterialEditorWindowSettings, AZ::SystemAllocator, 0); + + static void Reflect(AZ::ReflectContext* context); + + bool m_enableGrid = true; + bool m_enableShadowCatcher = true; + bool m_enableAlternateSkybox = false; + float m_fieldOfView = 90.0f; + }; +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp new file mode 100644 index 0000000000..a64b6584c1 --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp @@ -0,0 +1,51 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include +#include + +namespace MaterialEditor +{ + void MaterialDocumentSettings::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(1) + ->Field("showReloadDocumentPrompt", &MaterialDocumentSettings::m_showReloadDocumentPrompt) + ; + + if (auto editContext = serializeContext->GetEditContext()) + { + editContext->Class( + "MaterialDocumentSettings", "") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialDocumentSettings::m_showReloadDocumentPrompt, "Show Reload Document Prompt", "") + ; + } + } + + if (auto behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("MaterialDocumentSettings") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Category, "Editor") + ->Attribute(AZ::Script::Attributes::Module, "render") + ->Constructor() + ->Constructor() + ->Property("showReloadDocumentPrompt", BehaviorValueProperty(&MaterialDocumentSettings::m_showReloadDocumentPrompt)) + ; + } + } +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.cpp index dbb1d18e49..d0a904d522 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -40,12 +41,13 @@ AZ_POP_DISABLE_WARNING namespace MaterialEditor { MaterialDocumentSystemComponent::MaterialDocumentSystemComponent() - : m_settings(aznew MaterialEditorSettings) { } void MaterialDocumentSystemComponent::Reflect(AZ::ReflectContext* context) { + MaterialDocumentSettings::Reflect(context); + if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() @@ -132,6 +134,7 @@ namespace MaterialEditor void MaterialDocumentSystemComponent::Activate() { m_documentMap.clear(); + m_settings = AZ::UserSettings::CreateFind(AZ::Crc32("MaterialDocumentSettings"), AZ::UserSettings::CT_GLOBAL); MaterialDocumentSystemRequestBus::Handler::BusConnect(); MaterialDocumentNotificationBus::Handler::BusConnect(); } @@ -188,22 +191,25 @@ namespace MaterialEditor AZStd::string documentPath; MaterialDocumentRequestBus::EventResult(documentPath, documentId, &MaterialDocumentRequestBus::Events::GetAbsolutePath); - if (QMessageBox::question(QApplication::activeWindow(), + if (m_settings->m_showReloadDocumentPrompt && + (QMessageBox::question(QApplication::activeWindow(), QString("Material document was externally modified"), QString("Would you like to reopen the document:\n%1?").arg(documentPath.c_str()), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) + QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)) { - AtomToolsFramework::TraceRecorder traceRecorder(m_maxMessageBoxLineCount); + continue; + } - bool openResult = false; - MaterialDocumentRequestBus::EventResult(openResult, documentId, &MaterialDocumentRequestBus::Events::Open, documentPath); - if (!openResult) - { - QMessageBox::critical( - QApplication::activeWindow(), QString("Material document could not be opened"), - QString("Failed to open: \n%1\n\n%2").arg(documentPath.c_str()).arg(traceRecorder.GetDump().c_str())); - MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::CloseDocument, documentId); - } + AtomToolsFramework::TraceRecorder traceRecorder(m_maxMessageBoxLineCount); + + bool openResult = false; + MaterialDocumentRequestBus::EventResult(openResult, documentId, &MaterialDocumentRequestBus::Events::Open, documentPath); + if (!openResult) + { + QMessageBox::critical( + QApplication::activeWindow(), QString("Material document could not be opened"), + QString("Failed to open: \n%1\n\n%2").arg(documentPath.c_str()).arg(traceRecorder.GetDump().c_str())); + MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::CloseDocument, documentId); } } @@ -212,22 +218,25 @@ namespace MaterialEditor AZStd::string documentPath; MaterialDocumentRequestBus::EventResult(documentPath, documentId, &MaterialDocumentRequestBus::Events::GetAbsolutePath); - if (QMessageBox::question(QApplication::activeWindow(), + if (m_settings->m_showReloadDocumentPrompt && + (QMessageBox::question(QApplication::activeWindow(), QString("Material document dependencies have changed"), QString("Would you like to update the document with these changes:\n%1?").arg(documentPath.c_str()), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) + QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)) { - AtomToolsFramework::TraceRecorder traceRecorder(m_maxMessageBoxLineCount); + continue; + } - bool openResult = false; - MaterialDocumentRequestBus::EventResult(openResult, documentId, &MaterialDocumentRequestBus::Events::Rebuild); - if (!openResult) - { - QMessageBox::critical( - QApplication::activeWindow(), QString("Material document could not be opened"), - QString("Failed to open: \n%1\n\n%2").arg(documentPath.c_str()).arg(traceRecorder.GetDump().c_str())); - MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::CloseDocument, documentId); - } + AtomToolsFramework::TraceRecorder traceRecorder(m_maxMessageBoxLineCount); + + bool openResult = false; + MaterialDocumentRequestBus::EventResult(openResult, documentId, &MaterialDocumentRequestBus::Events::Rebuild); + if (!openResult) + { + QMessageBox::critical( + QApplication::activeWindow(), QString("Material document could not be opened"), + QString("Failed to open: \n%1\n\n%2").arg(documentPath.c_str()).arg(traceRecorder.GetDump().c_str())); + MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::CloseDocument, documentId); } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.h index 4b0ee424a7..617937ad1a 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSystemComponent.h @@ -18,10 +18,10 @@ #include #include +#include #include #include #include -#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include @@ -43,7 +43,7 @@ namespace MaterialEditor MaterialDocumentSystemComponent(); ~MaterialDocumentSystemComponent() = default; MaterialDocumentSystemComponent(const MaterialDocumentSystemComponent&) = delete; - MaterialDocumentSystemComponent& operator =(const MaterialDocumentSystemComponent&) = delete; + MaterialDocumentSystemComponent& operator=(const MaterialDocumentSystemComponent&) = delete; static void Reflect(AZ::ReflectContext* context); @@ -87,10 +87,10 @@ namespace MaterialEditor AZ::Uuid OpenDocumentImpl(AZStd::string_view sourcePath, bool checkIfAlreadyOpen); + AZStd::intrusive_ptr m_settings; AZStd::unordered_map> m_documentMap; AZStd::unordered_set m_documentIdsToRebuild; AZStd::unordered_set m_documentIdsToReopen; - AZStd::unique_ptr m_settings; const size_t m_maxMessageBoxLineCount = 15; }; -} +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialEditorSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialEditorSettings.cpp deleted file mode 100644 index fc0ed84bfa..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialEditorSettings.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -namespace MaterialEditor -{ - MaterialEditorSettings::MaterialEditorSettings() - { - MaterialEditorSettingsRequestBus::Handler::BusConnect(); - } - - MaterialEditorSettings::~MaterialEditorSettings() - { - MaterialEditorSettingsRequestBus::Handler::BusDisconnect(); - } - - AZ::Outcome MaterialEditorSettings::GetProperty(AZStd::string_view name) const - { - const auto it = m_propertyMap.find(name); - if (it != m_propertyMap.end()) - { - return AZ::Success(it->second); - } - AZ_Warning("MaterialEditorSettings", false, "Failed to find property [%s].", name.data()); - return AZ::Failure(); - } - - AZ::Outcome MaterialEditorSettings::GetStringProperty(AZStd::string_view name) const - { - AZ::Outcome outcome = GetProperty(name); - if (!outcome || !outcome.GetValue().is()) - { - return AZ::Failure(); - } - return AZ::Success(AZStd::any_cast(outcome.GetValue())); - } - - AZ::Outcome MaterialEditorSettings::GetBoolProperty(AZStd::string_view name) const - { - AZ::Outcome outcome = GetProperty(name); - if (!outcome || !outcome.GetValue().is()) - { - return AZ::Failure(); - } - return AZ::Success(AZStd::any_cast(outcome.GetValue())); - } - - void MaterialEditorSettings::SetProperty(AZStd::string_view name, const AZStd::any& value) - { - m_propertyMap[name] = value; - MaterialEditorSettingsNotificationBus::Broadcast(&MaterialEditorSettingsNotifications::OnPropertyChanged, name, value); - } - - void MaterialEditorSettings::SetStringProperty(AZStd::string_view name, AZStd::string_view stringValue) - { - SetProperty(name, AZStd::any(AZStd::string(stringValue))); - } - - void MaterialEditorSettings::SetBoolProperty(AZStd::string_view name, bool boolValue) - { - SetProperty(name, AZStd::any(boolValue)); - } -} diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialEditorSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialEditorSettings.h deleted file mode 100644 index f3a948ed80..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialEditorSettings.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -#include - -namespace MaterialEditor -{ - class MaterialEditorSettings - : public MaterialEditorSettingsRequestBus::Handler - { - public: - AZ_RTTI(MaterialEditorSettings, "{9C6B6E20-A28E-45DD-85BE-68CA35E9305E}"); - AZ_CLASS_ALLOCATOR(MaterialEditorSettings, AZ::SystemAllocator, 0); - - MaterialEditorSettings(); - ~MaterialEditorSettings(); - - AZ::Outcome GetProperty(AZStd::string_view name) const override; - AZ::Outcome GetStringProperty(AZStd::string_view name) const override; - AZ::Outcome GetBoolProperty(AZStd::string_view name) const override; - - void SetProperty(AZStd::string_view name, const AZStd::any& value) override; - void SetStringProperty(AZStd::string_view name, AZStd::string_view stringValue) override; - void SetBoolProperty(AZStd::string_view name, bool boolValue) override; - - private: - AZStd::unordered_map m_propertyMap; - }; - -} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 1f32c2a66b..55710efb66 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -284,7 +284,7 @@ namespace MaterialEditor AZ_Assert(context, "No serialize context"); char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZ::IO::FileIOBase::GetInstance()->ResolvePath("@user@/EditorUserSettings.xml", resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); + AZ::IO::FileIOBase::GetInstance()->ResolvePath("@user@/MaterialEditorUserSettings.xml", resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); m_localUserSettings.Save(resolvedPath, context); } } @@ -546,6 +546,9 @@ namespace MaterialEditor void MaterialEditorApplication::Stop() { + MaterialEditor::MaterialEditorWindowFactoryRequestBus::Broadcast( + &MaterialEditor::MaterialEditorWindowFactoryRequestBus::Handler::DestroyMaterialEditorWindow); + UnloadSettings(); AzFramework::Application::Stop(); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp index abaf50804f..948a23d509 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -70,6 +71,8 @@ namespace MaterialEditor void MaterialViewportComponent::Reflect(AZ::ReflectContext* context) { + MaterialViewportSettings::Reflect(context); + if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() @@ -160,6 +163,9 @@ namespace MaterialEditor void MaterialViewportComponent::Activate() { + m_viewportSettings = + AZ::UserSettings::CreateFind(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL); + m_lightingPresetPreviewImageDefault = QImage(180, 90, QImage::Format::Format_RGBA8888); m_lightingPresetPreviewImageDefault.fill(Qt::GlobalColor::black); @@ -192,13 +198,14 @@ namespace MaterialEditor MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnBeginReloadContent); - const AZStd::string prevLightingPresetSelectionName = m_lightingPresetSelection ? m_lightingPresetSelection->m_displayName : ""; - const AZStd::string prevModelPresetSelectionName = m_modelPresetSelection ? m_modelPresetSelection->m_displayName : ""; + const AZStd::string selectedLightingPresetNameOld = m_viewportSettings->m_selectedLightingPresetName; m_lightingPresetVector.clear(); m_lightingPresetLastSavePathMap.clear(); m_lightingPresetSelection.reset(); + const AZStd::string selectedModelPresetNameOld = m_viewportSettings->m_selectedModelPresetName; + m_modelPresetVector.clear(); m_modelPresetLastSavePathMap.clear(); m_modelPresetSelection.reset(); @@ -263,8 +270,8 @@ namespace MaterialEditor // If there was a prior selection, this will keep the same configuration selected. // Otherwise, these strings are empty and the operation will be ignored. - SelectLightingPresetByName(prevLightingPresetSelectionName); - SelectModelPresetByName(prevModelPresetSelectionName); + SelectLightingPresetByName(selectedLightingPresetNameOld); + SelectModelPresetByName(selectedModelPresetNameOld); MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnEndReloadContent); @@ -327,6 +334,7 @@ namespace MaterialEditor if (preset) { m_lightingPresetSelection = preset; + m_viewportSettings->m_selectedLightingPresetName = preset->m_displayName; MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnLightingPresetSelected, m_lightingPresetSelection); } } @@ -422,6 +430,7 @@ namespace MaterialEditor if (preset) { m_modelPresetSelection = preset; + m_viewportSettings->m_selectedModelPresetName = preset->m_displayName; MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnModelPresetSelected, m_modelPresetSelection); } } @@ -463,71 +472,66 @@ namespace MaterialEditor void MaterialViewportComponent::SetShadowCatcherEnabled(bool enable) { - m_shadowCatcherEnabled = enable; + m_viewportSettings->m_enableShadowCatcher = enable; MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnShadowCatcherEnabledChanged, enable); } bool MaterialViewportComponent::GetShadowCatcherEnabled() const { - return m_shadowCatcherEnabled; + return m_viewportSettings->m_enableShadowCatcher; } void MaterialViewportComponent::SetGridEnabled(bool enable) { - m_gridEnabled = enable; + m_viewportSettings->m_enableGrid = enable; MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnGridEnabledChanged, enable); } bool MaterialViewportComponent::GetGridEnabled() const { - return m_gridEnabled; + return m_viewportSettings->m_enableGrid; } void MaterialViewportComponent::SetAlternateSkyboxEnabled(bool enable) { - m_alternateSkyboxEnabled = enable; + m_viewportSettings->m_enableAlternateSkybox = enable; MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnAlternateSkyboxEnabledChanged, enable); } bool MaterialViewportComponent::GetAlternateSkyboxEnabled() const { - return m_alternateSkyboxEnabled; + return m_viewportSettings->m_enableAlternateSkybox; } void MaterialViewportComponent::SetFieldOfView(float fieldOfView) { - m_fieldOfView = fieldOfView; + m_viewportSettings->m_fieldOfView = fieldOfView; MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnFieldOfViewChanged, fieldOfView); } float MaterialViewportComponent::GetFieldOfView() const { - return m_fieldOfView; + return m_viewportSettings->m_fieldOfView; } void MaterialViewportComponent::SetDisplayMapperOperationType(AZ::Render::DisplayMapperOperationType operationType) { - m_displayMapperOperationType = operationType; + m_viewportSettings->m_displayMapperOperationType = operationType; MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnDisplayMapperOperationTypeChanged, operationType); } AZ::Render::DisplayMapperOperationType MaterialViewportComponent::GetDisplayMapperOperationType() const { - return m_displayMapperOperationType; + return m_viewportSettings->m_displayMapperOperationType; } void MaterialViewportComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile) { AZ::TickBus::QueueFunction([this]() { ReloadContent(); - - // Automatically select preferred default presets if they exist - // We will later data drive this with editor settings - SelectLightingPresetByName("Neutral Urban"); - SelectModelPresetByName("Shader Ball"); }); } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h index 8332cb862c..ad35a86cf2 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h @@ -13,13 +13,12 @@ #pragma once #include - -#include -#include - #include #include #include +#include +#include +#include namespace MaterialEditor { @@ -111,10 +110,6 @@ namespace MaterialEditor mutable AZStd::map m_lightingPresetLastSavePathMap; mutable AZStd::map m_modelPresetLastSavePathMap; - bool m_shadowCatcherEnabled = true; - bool m_gridEnabled = true; - bool m_alternateSkyboxEnabled = false; - float m_fieldOfView = 90.0f; - AZ::Render::DisplayMapperOperationType m_displayMapperOperationType = AZ::Render::DisplayMapperOperationType::Aces; + AZStd::intrusive_ptr m_viewportSettings; }; } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp index 5939a40db6..f009cc1f9b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -92,6 +93,7 @@ namespace MaterialEditor auto sceneSystem = AzFramework::SceneSystemInterface::Get(); AZ_Assert(sceneSystem, "MaterialViewportRenderer was unable to get the scene system during construction."); AZStd::shared_ptr mainScene = sceneSystem->GetScene(AzFramework::Scene::MainSceneName); + // This should never happen unless scene creation has changed. AZ_Assert(mainScene, "Main scenes missing during system component initialization"); mainScene->SetSubsystem(m_scene); @@ -138,7 +140,6 @@ namespace MaterialEditor m_renderPipeline->SetDefaultViewFromEntity(m_cameraEntity->GetId()); // Configure tone mapper - AzFramework::EntityContextRequestBus::EventResult(m_postProcessEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "postProcessEntity"); AZ_Assert(m_postProcessEntity != nullptr, "Failed to create post process entity."); @@ -154,13 +155,11 @@ namespace MaterialEditor m_displayMapperFeatureProcessor = m_scene->GetFeatureProcessor(); // Init Skybox - m_skyboxFeatureProcessor = m_scene->GetFeatureProcessor(); m_skyboxFeatureProcessor->Enable(true); m_skyboxFeatureProcessor->SetSkyboxMode(AZ::Render::SkyBoxMode::Cubemap); // Create IBL - AzFramework::EntityContextRequestBus::EventResult(m_iblEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "IblEntity"); AZ_Assert(m_iblEntity != nullptr, "Failed to create ibl entity."); @@ -176,8 +175,8 @@ namespace MaterialEditor m_modelEntity->CreateComponent(AZ::Render::MaterialComponentTypeId); m_modelEntity->CreateComponent(azrtti_typeid()); m_modelEntity->Activate(); - // Create shadow catcher + // Create shadow catcher AzFramework::EntityContextRequestBus::EventResult(m_shadowCatcherEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "ViewportShadowCatcher"); AZ_Assert(m_shadowCatcherEntity != nullptr, "Failed to create shadow catcher entity."); m_shadowCatcherEntity->CreateComponent(AZ::Render::MeshComponentTypeId); @@ -208,7 +207,6 @@ namespace MaterialEditor } // Create grid - AzFramework::EntityContextRequestBus::EventResult(m_gridEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "ViewportGrid"); AZ_Assert(m_gridEntity != nullptr, "Failed to create grid entity."); @@ -235,6 +233,16 @@ namespace MaterialEditor MaterialViewportRequestBus::BroadcastResult(modelPreset, &MaterialViewportRequestBus::Events::GetModelPresetSelection); OnModelPresetSelected(modelPreset); + // Apply user settinngs restored since last run + AZStd::intrusive_ptr viewportSettings = + AZ::UserSettings::CreateFind(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL); + + OnGridEnabledChanged(viewportSettings->m_enableGrid); + OnShadowCatcherEnabledChanged(viewportSettings->m_enableShadowCatcher); + OnAlternateSkyboxEnabledChanged(viewportSettings->m_enableAlternateSkybox); + OnFieldOfViewChanged(viewportSettings->m_fieldOfView); + OnDisplayMapperOperationTypeChanged(viewportSettings->m_displayMapperOperationType); + MaterialDocumentNotificationBus::Handler::BusConnect(); MaterialViewportNotificationBus::Handler::BusConnect(); AZ::TickBus::Handler::BusConnect(); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.cpp new file mode 100644 index 0000000000..fd64f3073d --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportSettings.cpp @@ -0,0 +1,72 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include +#include + +namespace MaterialEditor +{ + void MaterialViewportSettings::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(1) + ->Field("enableGrid", &MaterialViewportSettings::m_enableGrid) + ->Field("enableShadowCatcher", &MaterialViewportSettings::m_enableShadowCatcher) + ->Field("enableAlternateSkybox", &MaterialViewportSettings::m_enableAlternateSkybox) + ->Field("fieldOfView", &MaterialViewportSettings::m_fieldOfView) + ->Field("displayMapperOperationType", &MaterialViewportSettings::m_displayMapperOperationType) + ->Field("selectedModelPresetName", &MaterialViewportSettings::m_selectedModelPresetName) + ->Field("selectedLightingPresetName", &MaterialViewportSettings::m_selectedLightingPresetName) + ; + + if (auto editContext = serializeContext->GetEditContext()) + { + editContext->Class( + "MaterialViewportSettings", "") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialViewportSettings::m_enableGrid, "Enable Grid", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialViewportSettings::m_enableShadowCatcher, "Enable Shadow Catcher", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialViewportSettings::m_enableAlternateSkybox, "Enable Alternate Skybox", "") + ->DataElement(AZ::Edit::UIHandlers::Slider, &MaterialViewportSettings::m_fieldOfView, "Field Of View", "") + ->Attribute(AZ::Edit::Attributes::Min, 60.0f) + ->Attribute(AZ::Edit::Attributes::Max, 120.0f) + ->DataElement(AZ::Edit::UIHandlers::ComboBox, &MaterialViewportSettings::m_displayMapperOperationType, "Display Mapper Type", "") + ->EnumAttribute(AZ::Render::DisplayMapperOperationType::Aces, "Aces") + ->EnumAttribute(AZ::Render::DisplayMapperOperationType::AcesLut, "AcesLut") + ->EnumAttribute(AZ::Render::DisplayMapperOperationType::Passthrough, "Passthrough") + ->EnumAttribute(AZ::Render::DisplayMapperOperationType::GammaSRGB, "GammaSRGB") + ->EnumAttribute(AZ::Render::DisplayMapperOperationType::Reinhard, "Reinhard") + ; + } + } + + if (auto behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("MaterialViewportSettings") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Category, "Editor") + ->Attribute(AZ::Script::Attributes::Module, "render") + ->Constructor() + ->Constructor() + ->Property("enableGrid", BehaviorValueProperty(&MaterialViewportSettings::m_enableGrid)) + ->Property("enableShadowCatcher", BehaviorValueProperty(&MaterialViewportSettings::m_enableShadowCatcher)) + ->Property("enableAlternateSkybox", BehaviorValueProperty(&MaterialViewportSettings::m_enableAlternateSkybox)) + ->Property("fieldOfView", BehaviorValueProperty(&MaterialViewportSettings::m_fieldOfView)) + ->Property("displayMapperOperationType", BehaviorValueProperty(&MaterialViewportSettings::m_displayMapperOperationType)) + ; + } + } +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index 6e47de189c..12e75f8fcf 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -10,14 +10,15 @@ * */ -#include #include -#include -#include -#include -#include +#include #include #include +#include +#include +#include +#include +#include #include @@ -121,10 +122,24 @@ namespace MaterialEditor MaterialEditorWindowRequestBus::Handler::BusConnect(); MaterialDocumentNotificationBus::Handler::BusConnect(); OnDocumentOpened(AZ::Uuid::CreateNull()); + + auto windowState = AZ::UserSettings::Find( + AZ::Crc32("MaterialEditorWindowState"), AZ::UserSettings::CT_GLOBAL); + if (windowState) + { + windowState->RestoreGeometry(this); + } } MaterialEditorWindow::~MaterialEditorWindow() { + auto windowState = AZ::UserSettings::CreateFind( + AZ::Crc32("MaterialEditorWindowState"), AZ::UserSettings::CT_GLOBAL); + if (windowState) + { + windowState->CaptureGeometry(this); + } + MaterialDocumentNotificationBus::Handler::BusDisconnect(); MaterialEditorWindowRequestBus::Handler::BusDisconnect(); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp index 820cee30f9..3d796a21ad 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp @@ -10,25 +10,24 @@ * */ -#include -#include +#include +#include #include - -#include +#include +#include #include #include +#include #include - -#include -#include -#include -#include +#include +#include +#include namespace MaterialEditor { void MaterialEditorWindowComponent::Reflect(AZ::ReflectContext* context) { - GeneralViewportSettings::Reflect(context); + MaterialEditorWindowSettings::Reflect(context); if (AZ::SerializeContext* serialize = azrtti_cast(context)) { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp new file mode 100644 index 0000000000..a9c928df10 --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp @@ -0,0 +1,62 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include +#include + +namespace MaterialEditor +{ + void MaterialEditorWindowSettings::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(1) + ->Field("enableGrid", &MaterialEditorWindowSettings::m_enableGrid) + ->Field("enableShadowCatcher", &MaterialEditorWindowSettings::m_enableShadowCatcher) + ->Field("enableAlternateSkybox", &MaterialEditorWindowSettings::m_enableAlternateSkybox) + ->Field("fieldOfView", &MaterialEditorWindowSettings::m_fieldOfView) + ; + + if (auto editContext = serializeContext->GetEditContext()) + { + editContext->Class( + "MaterialEditorWindowSettings", "") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableGrid, "Enable Grid", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableShadowCatcher, "Enable Shadow Catcher", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableAlternateSkybox, "Enable Alternate Skybox", "") + ->DataElement(AZ::Edit::UIHandlers::Slider, &MaterialEditorWindowSettings::m_fieldOfView, "Field Of View", "") + ->Attribute(AZ::Edit::Attributes::Min, 60.0f) + ->Attribute(AZ::Edit::Attributes::Max, 120.0f) + ; + } + } + + if (auto behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("MaterialEditorWindowSettings") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Category, "Editor") + ->Attribute(AZ::Script::Attributes::Module, "render") + ->Constructor() + ->Constructor() + ->Property("enableGrid", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableGrid)) + ->Property("enableShadowCatcher", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableShadowCatcher)) + ->Property("enableAlternateSkybox", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableAlternateSkybox)) + ->Property("fieldOfView", BehaviorValueProperty(&MaterialEditorWindowSettings::m_fieldOfView)) + ; + } + } +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.cpp index 2af73bf436..8da7c903a2 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ToolBar/MaterialEditorToolBar.cpp @@ -10,13 +10,13 @@ * */ -#include #include #include +#include #include -#include -#include -#include +#include +#include +#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include @@ -33,15 +33,16 @@ namespace MaterialEditor { AzQtComponents::ToolBar::addMainToolBarStyle(this); + AZStd::intrusive_ptr viewportSettings = + AZ::UserSettings::CreateFind(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL); + // Add toggle grid button m_toggleGrid = addAction(QIcon(":/Icons/grid.svg"), "Toggle Grid"); m_toggleGrid->setCheckable(true); connect(m_toggleGrid, &QAction::triggered, [this]() { MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SetGridEnabled, m_toggleGrid->isChecked()); - }); - bool enableGrid = false; - MaterialViewportRequestBus::BroadcastResult(enableGrid, &MaterialViewportRequestBus::Events::GetGridEnabled); - m_toggleGrid->setChecked(enableGrid); + }); + m_toggleGrid->setChecked(viewportSettings->m_enableGrid); // Add toggle shadow catcher button m_toggleShadowCatcher = addAction(QIcon(":/Icons/shadow.svg"), "Toggle Shadow Catcher"); @@ -49,34 +50,32 @@ namespace MaterialEditor connect(m_toggleShadowCatcher, &QAction::triggered, [this]() { MaterialViewportRequestBus::Broadcast( &MaterialViewportRequestBus::Events::SetShadowCatcherEnabled, m_toggleShadowCatcher->isChecked()); - }); - bool enableShadowCatcher = false; - MaterialViewportRequestBus::BroadcastResult(enableShadowCatcher, &MaterialViewportRequestBus::Events::GetShadowCatcherEnabled); - m_toggleShadowCatcher->setChecked(enableShadowCatcher); + }); + m_toggleShadowCatcher->setChecked(viewportSettings->m_enableShadowCatcher); // Add mapping selection button - + QToolButton* toneMappingButton = new QToolButton(this); QMenu* toneMappingMenu = new QMenu(toneMappingButton); - m_operationNames = - { - { AZ::Render::DisplayMapperOperationType::Reinhard, "Reinhard" }, - { AZ::Render::DisplayMapperOperationType::GammaSRGB, "GammaSRGB" }, - { AZ::Render::DisplayMapperOperationType::Passthrough, "Passthrough" }, - { AZ::Render::DisplayMapperOperationType::AcesLut, "AcesLut" }, - { AZ::Render::DisplayMapperOperationType::Aces, "Aces" } - }; + m_operationNames = { + {AZ::Render::DisplayMapperOperationType::Reinhard, "Reinhard"}, + {AZ::Render::DisplayMapperOperationType::GammaSRGB, "GammaSRGB"}, + {AZ::Render::DisplayMapperOperationType::Passthrough, "Passthrough"}, + {AZ::Render::DisplayMapperOperationType::AcesLut, "AcesLut"}, + {AZ::Render::DisplayMapperOperationType::Aces, "Aces"}}; + for (auto operationNamePair : m_operationNames) { m_operationActions[operationNamePair.first] = toneMappingMenu->addAction(operationNamePair.second, [operationNamePair]() { MaterialViewportRequestBus::Broadcast( - &MaterialViewportRequestBus::Events::SetDisplayMapperOperationType, - operationNamePair.first); - }); + &MaterialViewportRequestBus::Events::SetDisplayMapperOperationType, operationNamePair.first); + }); m_operationActions[operationNamePair.first]->setCheckable(true); + m_operationActions[operationNamePair.first]->setChecked( + operationNamePair.first == viewportSettings->m_displayMapperOperationType); } - m_operationActions[AZ::Render::DisplayMapperOperationType::Aces]->setChecked(true); + toneMappingButton->setMenu(toneMappingMenu); toneMappingButton->setText("Tone Mapping"); toneMappingButton->setIcon(QIcon(":/Icons/toneMapping.svg")); @@ -122,4 +121,4 @@ namespace MaterialEditor } // namespace MaterialEditor -#include +#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp index fd50ace918..22e752dddd 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp @@ -26,61 +26,12 @@ namespace MaterialEditor { - void GeneralViewportSettings::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("enableGrid", &GeneralViewportSettings::m_enableGrid) - ->Field("enableShadowCatcher", &GeneralViewportSettings::m_enableShadowCatcher) - ->Field("enableAlternateSkybox", &GeneralViewportSettings::m_enableAlternateSkybox) - ->Field("fieldOfView", &GeneralViewportSettings::m_fieldOfView) - ->Field("displayMapperOperationType", &GeneralViewportSettings::m_displayMapperOperationType) - ; - - if (auto editContext = serializeContext->GetEditContext()) - { - editContext->Class( - "GeneralViewportSettings", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->DataElement(AZ::Edit::UIHandlers::Default, &GeneralViewportSettings::m_enableGrid, "Enable Grid", "") - ->DataElement(AZ::Edit::UIHandlers::Default, &GeneralViewportSettings::m_enableShadowCatcher, "Enable Shadow Catcher", "") - ->DataElement(AZ::Edit::UIHandlers::Default, &GeneralViewportSettings::m_enableAlternateSkybox, "Enable Alternate Skybox", "") - ->DataElement(AZ::Edit::UIHandlers::Slider, &GeneralViewportSettings::m_fieldOfView, "Field Of View", "") - ->Attribute(AZ::Edit::Attributes::Min, 60.0f) - ->Attribute(AZ::Edit::Attributes::Max, 120.0f) - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &GeneralViewportSettings::m_displayMapperOperationType, "Display Mapper Type", "") - ->EnumAttribute(AZ::Render::DisplayMapperOperationType::Aces, "Aces") - ->EnumAttribute(AZ::Render::DisplayMapperOperationType::AcesLut, "AcesLut") - ->EnumAttribute(AZ::Render::DisplayMapperOperationType::Passthrough, "Passthrough") - ->EnumAttribute(AZ::Render::DisplayMapperOperationType::GammaSRGB, "GammaSRGB") - ->EnumAttribute(AZ::Render::DisplayMapperOperationType::Reinhard, "Reinhard") - ; - } - } - - if (auto behaviorContext = azrtti_cast(context)) - { - behaviorContext->Class("GeneralViewportSettings") - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) - ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, "render") - ->Constructor() - ->Constructor() - ->Property("enableGrid", BehaviorValueProperty(&GeneralViewportSettings::m_enableGrid)) - ->Property("enableShadowCatcher", BehaviorValueProperty(&GeneralViewportSettings::m_enableShadowCatcher)) - ->Property("enableAlternateSkybox", BehaviorValueProperty(&GeneralViewportSettings::m_enableAlternateSkybox)) - ->Property("fieldOfView", BehaviorValueProperty(&GeneralViewportSettings::m_fieldOfView)) - ->Property("displayMapperOperationType", BehaviorValueProperty(&GeneralViewportSettings::m_displayMapperOperationType)) - ; - } - } - ViewportSettingsInspector::ViewportSettingsInspector(QWidget* parent) : AtomToolsFramework::InspectorWidget(parent) { + m_viewportSettings = + AZ::UserSettings::CreateFind(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL); + MaterialViewportNotificationBus::Handler::BusConnect(); } @@ -109,7 +60,7 @@ namespace MaterialEditor AddGroup( groupNameId, groupDisplayName, groupDescription, - new AtomToolsFramework::InspectorPropertyGroupWidget(&m_generalSettings, nullptr, m_generalSettings.TYPEINFO_Uuid(), this)); + new AtomToolsFramework::InspectorPropertyGroupWidget(m_viewportSettings.get(), nullptr, m_viewportSettings->TYPEINFO_Uuid(), this)); } void ViewportSettingsInspector::AddModelGroup() @@ -300,13 +251,13 @@ namespace MaterialEditor m_lightingPreset.reset(); MaterialViewportRequestBus::BroadcastResult(m_lightingPreset, &MaterialViewportRequestBus::Events::GetLightingPresetSelection); - MaterialViewportRequestBus::BroadcastResult(m_generalSettings.m_enableGrid, &MaterialViewportRequestBus::Events::GetGridEnabled); + MaterialViewportRequestBus::BroadcastResult(m_viewportSettings->m_enableGrid, &MaterialViewportRequestBus::Events::GetGridEnabled); MaterialViewportRequestBus::BroadcastResult( - m_generalSettings.m_enableShadowCatcher, &MaterialViewportRequestBus::Events::GetShadowCatcherEnabled); + m_viewportSettings->m_enableShadowCatcher, &MaterialViewportRequestBus::Events::GetShadowCatcherEnabled); MaterialViewportRequestBus::BroadcastResult( - m_generalSettings.m_enableAlternateSkybox, &MaterialViewportRequestBus::Events::GetAlternateSkyboxEnabled); - MaterialViewportRequestBus::BroadcastResult(m_generalSettings.m_fieldOfView, &MaterialViewportRequestBus::Handler::GetFieldOfView); - MaterialViewportRequestBus::BroadcastResult(m_generalSettings.m_displayMapperOperationType, &MaterialViewportRequestBus::Handler::GetDisplayMapperOperationType); + m_viewportSettings->m_enableAlternateSkybox, &MaterialViewportRequestBus::Events::GetAlternateSkyboxEnabled); + MaterialViewportRequestBus::BroadcastResult(m_viewportSettings->m_fieldOfView, &MaterialViewportRequestBus::Handler::GetFieldOfView); + MaterialViewportRequestBus::BroadcastResult(m_viewportSettings->m_displayMapperOperationType, &MaterialViewportRequestBus::Handler::GetDisplayMapperOperationType); AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect(); AtomToolsFramework::InspectorWidget::Reset(); @@ -330,31 +281,31 @@ namespace MaterialEditor void ViewportSettingsInspector::OnShadowCatcherEnabledChanged(bool enable) { - m_generalSettings.m_enableShadowCatcher = enable; + m_viewportSettings->m_enableShadowCatcher = enable; RefreshGroup("general"); } void ViewportSettingsInspector::OnGridEnabledChanged(bool enable) { - m_generalSettings.m_enableGrid = enable; + m_viewportSettings->m_enableGrid = enable; RefreshGroup("general"); } void ViewportSettingsInspector::OnAlternateSkyboxEnabledChanged(bool enable) { - m_generalSettings.m_enableAlternateSkybox = enable; + m_viewportSettings->m_enableAlternateSkybox = enable; RefreshGroup("general"); } void ViewportSettingsInspector::OnFieldOfViewChanged(float fieldOfView) { - m_generalSettings.m_fieldOfView = fieldOfView; + m_viewportSettings->m_fieldOfView = fieldOfView; RefreshGroup("general"); } void ViewportSettingsInspector::OnDisplayMapperOperationTypeChanged(AZ::Render::DisplayMapperOperationType operationType) { - m_generalSettings.m_displayMapperOperationType = operationType; + m_viewportSettings->m_displayMapperOperationType = operationType; RefreshGroup("general"); } @@ -379,13 +330,13 @@ namespace MaterialEditor { MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnLightingPresetChanged, m_lightingPreset); MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnModelPresetChanged, m_modelPreset); - MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SetGridEnabled, m_generalSettings.m_enableGrid); + MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SetGridEnabled, m_viewportSettings->m_enableGrid); MaterialViewportRequestBus::Broadcast( - &MaterialViewportRequestBus::Events::SetShadowCatcherEnabled, m_generalSettings.m_enableShadowCatcher); + &MaterialViewportRequestBus::Events::SetShadowCatcherEnabled, m_viewportSettings->m_enableShadowCatcher); MaterialViewportRequestBus::Broadcast( - &MaterialViewportRequestBus::Events::SetAlternateSkyboxEnabled, m_generalSettings.m_enableAlternateSkybox); - MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Handler::SetFieldOfView, m_generalSettings.m_fieldOfView); - MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Handler::SetDisplayMapperOperationType, m_generalSettings.m_displayMapperOperationType); + &MaterialViewportRequestBus::Events::SetAlternateSkyboxEnabled, m_viewportSettings->m_enableAlternateSkybox); + MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Handler::SetFieldOfView, m_viewportSettings->m_fieldOfView); + MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Handler::SetDisplayMapperOperationType, m_viewportSettings->m_displayMapperOperationType); } AZStd::string ViewportSettingsInspector::GetDefaultUniqueSaveFilePath(const AZStd::string& baseName) const diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h index c61acb2e4c..fdfdec1458 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h @@ -14,28 +14,16 @@ #if !defined(Q_MOC_RUN) #include -#include #include #include -#include +#include +#include #include +#include #endif namespace MaterialEditor { - struct GeneralViewportSettings - { - AZ_TYPE_INFO(GeneralViewportSettings, "{16150503-A314-4765-82A3-172670C9EA90}"); - AZ_CLASS_ALLOCATOR(GeneralViewportSettings, AZ::SystemAllocator, 0); - static void Reflect(AZ::ReflectContext* context); - - bool m_enableGrid = true; - bool m_enableShadowCatcher = true; - bool m_enableAlternateSkybox = false; - float m_fieldOfView = 90.0f; - AZ::Render::DisplayMapperOperationType m_displayMapperOperationType = AZ::Render::DisplayMapperOperationType::Aces; - }; - //! Provides controls for viewing and editing a material document settings. //! The settings can be divided into cards, with each one showing a subset of properties. class ViewportSettingsInspector @@ -90,7 +78,7 @@ namespace MaterialEditor AZStd::string GetDefaultUniqueSaveFilePath(const AZStd::string& baseName) const; - GeneralViewportSettings m_generalSettings; + AZStd::intrusive_ptr m_viewportSettings; AZ::Render::ModelPresetPtr m_modelPreset; AZ::Render::LightingPresetPtr m_lightingPreset; }; diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditor_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditor_files.cmake index 845ff70cd1..e85a028005 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditor_files.cmake +++ b/Gems/Atom/Tools/MaterialEditor/Code/materialeditor_files.cmake @@ -13,7 +13,5 @@ set(FILES Source/main.cpp Source/MaterialEditorApplication.cpp Source/MaterialEditorApplication.h - Include/Atom/Document/MaterialDocumentModule.h - Source/Document/MaterialDocumentModule.cpp tool_dependencies.cmake ) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditordocument_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditordocument_files.cmake index ff781e6664..cf951cf0b2 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditordocument_files.cmake +++ b/Gems/Atom/Tools/MaterialEditor/Code/materialeditordocument_files.cmake @@ -14,11 +14,11 @@ set(FILES Include/Atom/Document/MaterialDocumentSystemRequestBus.h Include/Atom/Document/MaterialDocumentNotificationBus.h Include/Atom/Document/MaterialDocumentRequestBus.h - Include/Atom/Document/MaterialEditorSettingsBus.h + Include/Atom/Document/MaterialDocumentSettings.h + Source/Document/MaterialDocumentModule.cpp Source/Document/MaterialDocumentSystemComponent.cpp Source/Document/MaterialDocumentSystemComponent.h Source/Document/MaterialDocument.cpp Source/Document/MaterialDocument.h - Source/Document/MaterialEditorSettings.cpp - Source/Document/MaterialEditorSettings.h + Source/Document/MaterialDocumentSettings.cpp ) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorviewport_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorviewport_files.cmake index e8a65c8084..6ad602e167 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorviewport_files.cmake +++ b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorviewport_files.cmake @@ -12,6 +12,7 @@ set(FILES Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h Include/Atom/Viewport/MaterialViewportModule.h + Include/Atom/Viewport/MaterialViewportSettings.h Include/Atom/Viewport/MaterialViewportRequestBus.h Include/Atom/Viewport/MaterialViewportNotificationBus.h Include/Atom/Viewport/PerformanceMetrics.h @@ -35,6 +36,7 @@ set(FILES Source/Viewport/InputController/RotateModelBehavior.cpp Source/Viewport/InputController/RotateModelBehavior.h Source/Viewport/MaterialViewportModule.cpp + Source/Viewport/MaterialViewportSettings.cpp Source/Viewport/MaterialViewportComponent.cpp Source/Viewport/MaterialViewportComponent.h Source/Viewport/MaterialViewportWidget.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake index 1547dbf48f..52022e6e87 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake +++ b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake @@ -11,6 +11,7 @@ set(FILES Include/Atom/Window/MaterialEditorWindowModule.h + Include/Atom/Window/MaterialEditorWindowSettings.h Include/Atom/Window/MaterialEditorWindowNotificationBus.h Include/Atom/Window/MaterialEditorWindowRequestBus.h Include/Atom/Window/MaterialEditorWindowFactoryRequestBus.h @@ -19,6 +20,7 @@ set(FILES Source/Window/MaterialEditorWindow.h Source/Window/MaterialEditorWindow.cpp Source/Window/MaterialEditorWindowModule.cpp + Source/Window/MaterialEditorWindowSettings.cpp Source/Window/MaterialBrowserWidget.h Source/Window/MaterialBrowserWidget.cpp Source/Window/MaterialBrowserWidget.ui From 460863be0aade63c3fa43b35419566309ba8cd2e Mon Sep 17 00:00:00 2001 From: darapan Date: Thu, 6 May 2021 05:06:14 -0700 Subject: [PATCH 032/225] "Resolving merge conflicts" --- .../PythonTests/scripting/TestSuite_Active.py | 229 +++++++++++++++++- 1 file changed, 223 insertions(+), 6 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index da67f21db1..d87f2986bf 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -12,26 +12,243 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import pytest import os import sys +sys.path.append(os.path.dirname(__file__)) +import ImportPathHelper as imports +imports.init() + +import hydra_test_utils as hydra +import ly_test_tools.environment.file_system as file_system from ly_test_tools import LAUNCHERS - -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') - from base import TestAutomationBase +TEST_DIRECTORY = os.path.dirname(__file__) + + @pytest.mark.SUITE_periodic @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(TestAutomationBase): - + @pytest.mark.test_case_id("C1702834", "C1702823") + def test_Opening_Closing_Pane(self, request, workspace, editor, launcher_platform): + from . import Opening_Closing_Pane as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("C1702824") def test_Docking_Pane(self, request, workspace, editor, launcher_platform): from . import Docking_Pane as test_module self._run_test(request, workspace, editor, test_module) + @pytest.mark.test_case_id("C1702829") def test_Resizing_Pane(self, request, workspace, editor, launcher_platform): from . import Resizing_Pane as test_module self._run_test(request, workspace, editor, test_module) - def test_Unpin_VariableManager(self, request, workspace, editor, launcher_platform): - from . import Unpin_VariableManager as test_module + @pytest.mark.test_case_id("T92563190") + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptCanvas_TwoComponents(self, request, workspace, editor, launcher_platform, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptCanvas_TwoComponents as test_module self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92562986") + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptCanvas_ChangingAssets(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptCanvas_ChangingAssets as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92569079", "T92569081") + def test_Graph_ZoomInZoomOut(self, request, workspace, editor, launcher_platform): + from . import Graph_ZoomInZoomOut as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92568940") + def test_NodePalette_SelectNode(self, request, workspace, editor, launcher_platform): + from . import NodePalette_SelectNode as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92569253") + @pytest.mark.test_case_id("T92569254") + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import OnEntityActivatedDeactivated_PrintMessage as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92562993") + def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project): + from . import NodePalette_ClearSelection as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92563191") + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptCanvas_TwoEntities(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptCanvas_TwoEntities as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92569013") + def test_AssetEditor_CreateScriptEventFile(self, request, workspace, editor, launcher_platform, project): + def teardown(): + file_system.delete( + [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True + ) + request.addfinalizer(teardown) + file_system.delete( + [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True + ) + from . import AssetEditor_CreateScriptEventFile as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92569165", "T92569167", "T92569168", "T92569170") + def test_Toggle_ScriptCanvasTools(self, request, workspace, editor, launcher_platform): + from . import Toggle_ScriptCanvasTools as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92568982") + def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project): + from . import NodeInspector_RenameVariable as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92569137") + def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): + from . import Debugging_TargetMultipleGraphs as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92568856") + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_Debugging_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import Debugging_TargetMultipleEntities as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92569049", "T92569051") + def test_EditMenu_UndoRedo(self, request, workspace, editor, launcher_platform, project): + from . import EditMenu_UndoRedo as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("C1702825", "C1702831") + def test_UnDockedPane_CloseSCWindow(self, request, workspace, editor, launcher_platform): + from . import UnDockedPane_CloseSCWindow as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92562978") + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_Entity_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import Entity_AddScriptCanvasComponent as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("C1702821", "C1702832") + def test_Pane_RetainOnSCRestart(self, request, workspace, editor, launcher_platform): + from . import Pane_RetainOnSCRestart as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92567321") + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptEvents_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptEvents_SendReceiveAcrossMultiple as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.test_case_id("T92567320") + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptEvents_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptEvents_SendReceiveSuccessfully as test_module + self._run_test(request, workspace, editor, test_module) + +# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method +# fails because of pyside_utils import +@pytest.mark.SUITE_periodic +@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestScriptCanvasTests(object): + """ + The following tests use hydra_test_utils.py to launch the editor and validate the results. + """ + + @pytest.mark.test_case_id("T92569037", "T92569039") + def test_FileMenu_New_Open(self, request, editor, launcher_platform): + expected_lines = [ + "File->New action working as expected: True", + "File->Open action working as expected: True", + ] + hydra.launch_and_validate_results( + request, TEST_DIRECTORY, editor, "FileMenu_New_Open.py", expected_lines, auto_test_mode=False, timeout=60, + ) + + @pytest.mark.test_case_id("T92568942") + def test_AssetEditor_NewScriptEvent(self, request, editor, launcher_platform): + expected_lines = [ + "New Script event action found: True", + "Asset Editor opened: True", + "Asset Editor created with new asset: True", + "New Script event created in Asset Editor: True", + ] + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "AssetEditor_NewScriptEvent.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) + + @pytest.mark.test_case_id("T92563068", "T92563070") + def test_GraphClose_SavePrompt(self, request, editor, launcher_platform): + expected_lines = [ + "New graph created: True", + "Save prompt opened as expected: True", + "Close button worked as expected: True", + ] + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "GraphClose_SavePrompt.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) + + @pytest.mark.test_case_id("T92564789", "T92568873") + def test_VariableManager_CreateDeleteVars(self, request, editor, launcher_platform): + var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"] + expected_lines = [f"Success: {var_type} variable is created" for var_type in var_types] + expected_lines.extend([f"Success: {var_type} variable is deleted" for var_type in var_types]) + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "VariableManager_CreateDeleteVars.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) \ No newline at end of file From 409500635fc8a6b82beca4ae5db88a88a8b1434f Mon Sep 17 00:00:00 2001 From: darapan Date: Thu, 6 May 2021 05:40:11 -0700 Subject: [PATCH 033/225] "Fixing review comments" --- .../PythonTests/scripting/TestSuite_Active.py | 5 +++ ...y => VariableManager_UnpinVariableType.py} | 34 +++++++++---------- 2 files changed, 22 insertions(+), 17 deletions(-) rename AutomatedTesting/Gem/PythonTests/scripting/{Unpin_VariableManager.py => VariableManager_UnpinVariableType.py} (75%) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index d87f2986bf..7c218b5fa9 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -183,6 +183,11 @@ class TestAutomation(TestAutomationBase): from . import ScriptEvents_SendReceiveSuccessfully as test_module self._run_test(request, workspace, editor, test_module) + @pytest.mark.test_case_id("T92568973") + def test_VariableManager_UnpinVariableType(self, request, workspace, editor, launcher_platform): + from . import VariableManager_UnpinVariableType as test_module + self._run_test(request, workspace, editor, test_module) + # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method # fails because of pyside_utils import @pytest.mark.SUITE_periodic diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py similarity index 75% rename from AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py rename to AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py index 682084ff68..f9fe45dd86 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Unpin_VariableManager.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py @@ -8,21 +8,22 @@ or, if provided, by the license below or the license accompanying this file. Do remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -https://testrail.agscollab.com/index.php?/tests/view/92568973 +Test case ID: T92568973 +Test Case Title: Unpin Variable types in Variable Manager +URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568973 """ # fmt: off class Tests(): - open_sc_window = ("Script Canvas window is opened", "Failed to open Script Canvas window") - variable_manager_opened = ("VariableManager is opened successfully", "Failed to open VariableManager") - boolean_pinned = ("Boolean is pinned", "Boolean is not pinned, But it should be unpinned") - boolean_unpinned = ("Boolean is unpinned", "Boolean is not unpinned, But it should be pinned") - boolean_unpinned_after_reopen = ("Boolean is unpinned after reopening create variable menu", "Boolean is not unpinned after reopening create variable menu") + variable_manager_opened = ("VariableManager is opened successfully", "Failed to open VariableManager") + variable_pinned = ("Variable is pinned", "Variable is not pinned, But it should be unpinned") + variable_unpinned = ("Variable is unpinned", "Variable is not unpinned, But it should be pinned") + variable_unpinned_after_reopen = ("Variable is unpinned after reopening create variable menu", "Variable is not unpinned after reopening create variable menu") # fmt: on -def Unpin_VariableManager(): +def VariableManager_UnpinVariableType(): """ Summary: Unpin variable types in create variable menu. @@ -41,7 +42,7 @@ def Unpin_VariableManager(): 8) Restore default layout and close SC window Note: - - This test file must be called from the Lumberyard Editor command terminal + - This test file must be called from the Open 3D Engine Editor command terminal - Any passed and failed tests are written to the Editor.log file. Parsing the file or running a log_monitor are required to observe the test results. @@ -56,7 +57,7 @@ def Unpin_VariableManager(): from utils import Report from PySide2.QtCore import Qt - GENERAL_WAIT = 5.0 # seconds + GENERAL_WAIT = 1.0 # seconds def find_pane(window, pane_name): return window.findChild(QtWidgets.QDockWidget, pane_name) @@ -68,8 +69,7 @@ def Unpin_VariableManager(): # 1) Open Script Canvas window (Tools > Script Canvas) general.idle_enable(True) general.open_pane("Script Canvas") - is_sc_visible = helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 15.0) - Report.result(Tests.open_sc_window, is_sc_visible) + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 6.0) # 2) Get the SC window object editor_window = pyside_utils.get_editor_main_window() @@ -101,26 +101,26 @@ def Unpin_VariableManager(): result = helper.wait_for_condition( lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is not None, GENERAL_WAIT ) - Report.result(Tests.boolean_pinned, result) + Report.result(Tests.variable_pinned, result) # Unpin Boolean and make sure Boolean is unpinned. pyside_utils.item_view_index_mouse_click(table_view, model_index.siblingAtColumn(0)) result = helper.wait_for_condition( lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is None, GENERAL_WAIT ) - Report.result(Tests.boolean_unpinned, result) + Report.result(Tests.variable_unpinned, result) # 7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu button.click() button.click() - general.idle_wait(1.0) + model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") result = helper.wait_for_condition( lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is None, GENERAL_WAIT ) - Report.result(Tests.boolean_unpinned_after_reopen, result) + Report.result(Tests.variable_unpinned_after_reopen, result) # 8) Restore default layout and close SC window click_menu_option(sc, "Restore Default Layout") - sc.close() + general.close_pane("Script Canvas") if __name__ == "__main__": @@ -130,4 +130,4 @@ if __name__ == "__main__": from utils import Report - Report.start_test(Unpin_VariableManager) + Report.start_test(VariableManager_UnpinVariableType) From 076371b026e3288a39e1ed858d315a40895a6ca2 Mon Sep 17 00:00:00 2001 From: zsolleci Date: Thu, 6 May 2021 14:20:07 -0500 Subject: [PATCH 034/225] Removed references to JIRA/TestRail; fixed typos and formatting mistakes --- .../Gem/PythonTests/CMakeLists.txt | 2 +- .../AssetEditor_CreateScriptEventFile.py | 5 -- .../scripting/AssetEditor_NewScriptEvent.py | 11 +--- .../Debugging_TargetMultipleEntities.py | 10 +--- .../Debugging_TargetMultipleGraphs.py | 11 +--- .../Gem/PythonTests/scripting/Docking_Pane.py | 19 ++---- .../scripting/EditMenu_UndoRedo.py | 20 ++----- .../Entity_AddScriptCanvasComponent.py | 9 +-- .../scripting/FileMenu_New_Open.py | 18 ++---- .../scripting/GraphClose_SavePrompt.py | 18 ++---- .../scripting/Graph_ZoomInZoomOut.py | 13 +---- .../PythonTests/scripting/ImportPathHelper.py | 7 ++- .../scripting/NodeInspector_RenameVariable.py | 14 ++--- .../scripting/NodePalette_ClearSelection.py | 14 ++--- .../scripting/NodePalette_SelectNode.py | 16 ++--- ...EntityActivatedDeactivated_PrintMessage.py | 58 +++++++++++-------- .../scripting/Opening_Closing_Pane.py | 10 +--- .../scripting/Pane_RetainOnSCRestart.py | 39 +++++-------- .../PythonTests/scripting/Resizing_Pane.py | 15 ++--- .../scripting/ScriptCanvas_ChangingAssets.py | 7 --- .../scripting/ScriptCanvas_TwoComponents.py | 6 +- .../scripting/ScriptCanvas_TwoEntities.py | 11 ++-- .../ScriptEvents_SendReceiveAcrossMultiple.py | 22 +++---- .../ScriptEvents_SendReceiveSuccessfully.py | 5 -- .../PythonTests/scripting/TestSuite_Active.py | 26 --------- .../scripting/Toggle_ScriptCanvasTools.py | 17 +----- .../scripting/UnDockedPane_CloseSCWindow.py | 11 +--- .../VariableManager_CreateDeleteVars.py | 13 +---- 28 files changed, 124 insertions(+), 303 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 31afab87ed..2423bd5b06 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -68,7 +68,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Active.py - TIMEOUT 3000 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py index dcbbf47f0c..72144ebc0e 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92569013 -Test Case Title: Script Event file can be created -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569013 """ @@ -118,7 +114,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(CreateScriptEventFile) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py index 1f801d4eeb..acc0880a73 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py @@ -7,12 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - -Test case ID: T92568942 -Test Case Title: Clicking the "+" button and selecting "New Script Event" opens the -Asset Editor with a new Script Event asset -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568942 """ from PySide2 import QtWidgets @@ -36,11 +30,10 @@ GENERAL_WAIT = 0.5 # seconds class TestAssetEditor_NewScriptEvent: """ Summary: - Clicking the "+" button in Node Palette and creating New Script Event opens Asset Editor + Verifying logic flow of the "+" button on the Script Canvas pane's Node Palette is as expected Expected Behavior: - Clicking the "+" button and selecting "New Script Event" opens the Asset Editor with a - new Script Event asset + Clicking the "+" button and selecting "New Script Event" opens the Asset Editor with a new Script Event asset Test Steps: 1) Open Script Canvas window (Tools > Script Canvas) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py index a26cb4f923..71e24139f4 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py @@ -7,11 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - -Test case ID: T92568856 -Test Case Title: Multiple Entities can be targeted in the Debugger tool -URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568856 """ @@ -32,14 +27,14 @@ def Debugging_TargetMultipleEntities(): Multiple Entities can be targeted in the Debugger tool Expected Behavior: - Selected files can be checked for logging. + Multiple selected files can be checked for logging. Upon checking, checkboxes of the parent folders change to either full or partial check. Test Steps: 1) Create temp level 2) Create two entities with scriptcanvas components 3) Set values for scriptcanvas - 4) Open Script Canvas window and get sc opbject + 4) Open Script Canvas window and get sc object 5) Open Debugging(Logging) window 6) Click on Entities tab in logging window 7) Verify if the scriptcanvas exist under entities @@ -54,7 +49,6 @@ def Debugging_TargetMultipleEntities(): :return: None """ - from PySide2 import QtWidgets from PySide2.QtCore import Qt import azlmbr.legacy.general as general diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py index 4aa5c822a7..342f8f3cd4 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py @@ -7,17 +7,12 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - -Test case ID: T92569137 -Test Case Title: Multiple Graphs can be targeted in the Debugger tool -URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569137 """ # fmt: off class Tests(): - select_multiple_targets = ("Multiple targets are selected", "Multiple targets are not selected") + select_multiple_targets = ("Multiple targets are selected", "Multiple targets are not selected") # fmt: on @@ -30,7 +25,7 @@ def Debugging_TargetMultipleGraphs(): Multiple Graphs can be targeted in the Debugger tool Expected Behavior: - Selected files can be checked for logging. + Multiple elected files can be checked for logging. Upon checking, checkboxes of the parent folders change to either full or partial check. Test Steps: @@ -50,7 +45,6 @@ def Debugging_TargetMultipleGraphs(): :return: None """ - from PySide2 import QtWidgets from PySide2.QtCore import Qt import azlmbr.legacy.general as general @@ -107,7 +101,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(Debugging_TargetMultipleGraphs) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py index 4fa1e1257f..da9dc125bc 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py @@ -7,25 +7,21 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: C1702824 -Test Case Title: Docking -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702824 """ # fmt: off class Tests(): - pane_opened = ("Pane is opened successfully", "Failed to open pane") - dock_pane = ("Pane is docked successfully", "Failed to dock Pane into one or more allowed area") + pane_opened = ("Pane is opened successfully", "Failed to open pane") + dock_pane = ("Pane is docked successfully", "Failed to dock Pane into one or more allowed area") # fmt: on def Docking_Pane(): """ Summary: - The Script Canvas window is opened to verify if Script canvas panes can be docked into - every possible area of Script Canvas main window. + The Script Canvas window is opened to verify if Script canvas panes can be docked into every + possible area of Script Canvas main window. (top, bottom, right and left sides of the window) Expected Behavior: The pane docks successfully. @@ -44,12 +40,6 @@ def Docking_Pane(): :return: None """ - - # Helper imports - import ImportPathHelper as imports - - imports.init() - from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper import editor_python_test_tools.pyside_utils as pyside_utils @@ -111,7 +101,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from editor_python_test_tools.utils import Report Report.start_test(Docking_Pane) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py index a87d9e9be9..246a8894ba 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py @@ -7,14 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - -Test case ID: T92569049 -Test Case Title: Edit > Undo undoes the last action -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569049 -Test case ID: T92569051 -Test Case Title: Edit > Redo redoes the last undone action -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569051 """ @@ -35,8 +27,8 @@ def EditMenu_UndoRedo(): redo it and verify if the variable is created again. Expected Behavior: - The last action is undone. - The last undone action is redone. + The last action is undone upon selecting Undo. + The last undone action is redone upon selecting Redo. Test Steps: 1) Open Script Canvas window (Tools > Script Canvas) @@ -46,7 +38,7 @@ def EditMenu_UndoRedo(): 5) Create new variable 6) Verify if the variable is created initially 7) Trigger Undo action and verify if variable is removed in Variable Manager - 8) Trigger Redo action and verify if variable is readded in Variable Manager + 8) Trigger Redo action and verify if variable is re-added in Variable Manager 9) Close SC window Note: @@ -56,13 +48,12 @@ def EditMenu_UndoRedo(): :return: None """ - from PySide2 import QtWidgets, QtCore - import azlmbr.legacy.general as general - import pyside_utils + import azlmbr.legacy.general as general + # 1) Open Script Canvas window general.idle_enable(True) general.open_pane("Script Canvas") @@ -117,7 +108,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(EditMenu_UndoRedo) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py b/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py index fd8e9b1173..4e8576d892 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92562978 -Test Case Title: Script Canvas Component can be added to an entity -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562978 """ @@ -27,10 +23,10 @@ class Tests(): def Entity_AddScriptCanvasComponent(): """ Summary: - verify if Script Canvas component can be added to Entity without any issue + Script Canvas Component can be added to an entity Expected Behavior: - Script Canvas Component is added to the entity successfully without issue. + Script Canvas Component is added to the entity successfully without issue Test Steps: 1) Create temp level @@ -47,7 +43,6 @@ def Entity_AddScriptCanvasComponent(): :return: None """ - from utils import TestHelper as helper from utils import Tracer from editor_entity_utils import EditorEntity diff --git a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py index f72ac8ea01..094598e51d 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py @@ -7,24 +7,15 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - -Test case ID: T92569037 -Test Case Title: File > New Script creates a new script -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569037 -Test case ID: T92569039 -Test Case Title: File > Open opens the Open... dialog -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569039 """ - -import os -import sys from PySide2 import QtWidgets -import azlmbr.legacy.general as general import editor_python_test_tools.pyside_utils as pyside_utils from editor_python_test_tools.utils import Report +import azlmbr.legacy.general as general + + # fmt: off class Tests(): new_action = "File->New action working as expected" @@ -38,7 +29,8 @@ GENERAL_WAIT = 0.5 # seconds class TestFileMenuNewOpen: """ Summary: - When clicked on File->New, new script opens and File->Open should open the FileBrowser + When clicked on File->New, new script opens + File->Open should open the FileBrowser Expected Behavior: New and Open actions should work as expected. diff --git a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py index ce610b159b..b2a4b22056 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py @@ -7,26 +7,17 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - -Test case ID: T92563070 -Test Case Title: Graphs can be closed by clicking X on the Graph name tab -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563070 -Test case ID: T92563068 -Test Case Title: Save Prompt: User is prompted to save a graph on close after -creating a new graph -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563068 """ -import os -import sys from PySide2 import QtWidgets -import azlmbr.legacy.general as general import editor_python_test_tools.pyside_utils as pyside_utils from editor_python_test_tools.utils import TestHelper as helper from editor_python_test_tools.utils import Report +import azlmbr.legacy.general as general + + # fmt: off class Tests(): new_graph = "New graph created" @@ -45,7 +36,8 @@ class TestGraphCloseSavePrompt: Save Prompt is opened before closing. Expected Behavior: - New and Open actions should work as expected. + The Graph is closed. + Upon closing the graph, User is prompted whether or not to save changes. Test Steps: 1) Open Script Canvas window (Tools > Script Canvas) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py b/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py index a93b6e61d1..754a0ae686 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py @@ -7,14 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - -Test case ID: T92569079 -Test Case Title: View > Zoom In zooms the graph in -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569079 -Test case ID: T92569081 -Test Case Title: View > Zoom In zooms the graph out -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569081 """ @@ -93,7 +85,7 @@ def Graph_ZoomInZoomOut(): zin = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_ZoomIn", "type": QtWidgets.QAction}) zin.trigger() result = helper.wait_for_condition( - lambda: curr_m11 < graphics_view.transform().m11() and curr_m22 < graphics_view.transform().m22(), GENERAL_WAIT, + lambda: curr_m11 < graphics_view.transform().m11() and curr_m22 < graphics_view.transform().m22(), GENERAL_WAIT ) Report.result(Tests.zoom_in, result) @@ -102,7 +94,7 @@ def Graph_ZoomInZoomOut(): zout = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_ZoomOut", "type": QtWidgets.QAction}) zout.trigger() result = helper.wait_for_condition( - lambda: curr_m11 > graphics_view.transform().m11() and curr_m22 > graphics_view.transform().m22(), GENERAL_WAIT, + lambda: curr_m11 > graphics_view.transform().m11() and curr_m22 > graphics_view.transform().m22(), GENERAL_WAIT ) Report.result(Tests.zoom_out, result) @@ -114,7 +106,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(Graph_ZoomInZoomOut) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ImportPathHelper.py b/AutomatedTesting/Gem/PythonTests/scripting/ImportPathHelper.py index a45024cebf..ef794433f0 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/ImportPathHelper.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ImportPathHelper.py @@ -9,9 +9,10 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """ + def init(): import os import sys - sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') - sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../EditorPythonTestTools/editor_python_test_tools') - \ No newline at end of file + + sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../automatedtesting_shared") + sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../EditorPythonTestTools/editor_python_test_tools") diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py index 33d3f4137a..7351e45212 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92568982 -Test Case Title: Renaming variables in the Node Inspector -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568982 """ @@ -51,16 +47,16 @@ def NodeInspector_RenameVariable(): :return: None """ - - TEST_NAME = "test name" - from PySide2 import QtWidgets, QtCore, QtTest from PySide2.QtCore import Qt - import azlmbr.legacy.general as general import pyside_utils from utils import TestHelper as helper + import azlmbr.legacy.general as general + + TEST_NAME = "test name" + def open_tool(sc, dock_widget_name, pane_name): if sc.findChild(QtWidgets.QDockWidget, dock_widget_name) is None: action = pyside_utils.find_child_by_pattern(sc, {"text": pane_name, "type": QtWidgets.QAction}) @@ -121,12 +117,10 @@ def NodeInspector_RenameVariable(): general.close_pane("Script Canvas") - if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(NodeInspector_RenameVariable) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py index de30e46767..87a08346d0 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92562993 -Test Case Title: Clicking the X button on the Search Box clears the currently entered string -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562993 """ @@ -24,11 +20,11 @@ class Tests(): def NodePalette_ClearSelection(): """ Summary: - We enter some string in the Node Palette Search box, and click on the X button to verify if the - search string got cleared. + Clicking the X button on the Search Box clears the currently entered string Expected Behavior: - Clicking the X button on the Search Box clears the currently entered string + After entering a string value into the Node Palette's search box and click on + the X button, the search box should be cleared Test Steps: 1) Open Script Canvas window (Tools > Script Canvas) @@ -45,15 +41,13 @@ def NodePalette_ClearSelection(): :return: None """ - from PySide2 import QtWidgets + import pyside_utils from utils import TestHelper as helper import azlmbr.legacy.general as general - import pyside_utils - TEST_STRING = "Test String" # 1) Open Script Canvas window (Tools > Script Canvas) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py index 2ab76071a6..dfe1064a92 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py @@ -7,18 +7,13 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - -Test case ID: T92568940 -Test Case Title: Categories and Nodes can be selected -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568940 """ # fmt: off class Tests(): - category_selected = ("Category can be selected", "Category cannot be selected") - node_selected = ("Node can be selected", "Node cannot be selected") + category_selected = ("Category can be selected", "Category cannot be selected") + node_selected = ("Node can be selected", "Node cannot be selected") # fmt: on @@ -31,7 +26,8 @@ def NodePalette_SelectNode(): Categories and Nodes can be selected Expected Behavior: - When clicked on Node Palette, nodes and categories can be selected. + A category can be selected inside the Node Palette + A Node can be selected inside the Node Palette Test Steps: 1) Open Script Canvas window (Tools > Script Canvas) @@ -54,11 +50,12 @@ def NodePalette_SelectNode(): NODE = "Find Path To Entity" from PySide2 import QtWidgets - import azlmbr.legacy.general as general import pyside_utils from utils import TestHelper as helper + import azlmbr.legacy.general as general + # 1) Open Script Canvas window (Tools > Script Canvas) general.idle_enable(True) general.open_pane("Script Canvas") @@ -98,7 +95,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(NodePalette_SelectNode) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py b/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py index 51b63c4268..c331157e82 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py @@ -7,30 +7,26 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92569253 // T92569254 -Test Case Title: On Entity Activated // On Entity Deactivated -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569253 // https://testrail.agscollab.com/index.php?/tests/view/92569254 """ # fmt: off class Tests(): - level_created = ("Successfully created temp level", "Failed to create temp level") - controller_exists = ("Successfully found controller entity", "Failed to find controller entity") - activated_exists = ("Successfully found activated entity", "Failed to find activated entity") - deactivated_exists = ("Successfully found deactivated entity","Failed to find deactivated entity") - start_states_correct = ("Start states set up successfully", "Start states set up incorrectly") - game_mode_entered = ("Successfully entered game mode" "Failed to enter game mode") - lines_found = ("Successfully found expected prints", "Failed to find expected prints") - game_mode_exited = ("Successfully exited game mode" "Failed to exit game mode") + level_created = ("Successfully created temp level", "Failed to create temp level") + controller_exists = ("Successfully found controller entity", "Failed to find controller entity") + activated_exists = ("Successfully found activated entity", "Failed to find activated entity") + deactivated_exists = ("Successfully found deactivated entity", "Failed to find deactivated entity") + start_states_correct = ("Start states set up successfully", "Start states set up incorrectly") + game_mode_entered = ("Successfully entered game mode" "Failed to enter game mode") + lines_found = ("Successfully found expected prints", "Failed to find expected prints") + game_mode_exited = ("Successfully exited game mode" "Failed to exit game mode") # fmt: on def OnEntityActivatedDeactivated_PrintMessage(): """ Summary: - Verify that the On Entity Activation node is working as expected + Verify that the On Entity Activated/On Entity Deactivated nodes are working as expected Expected Behavior: Upon entering game mode, the Controller entity will wait 1 second and then activate the ActivationTest @@ -55,9 +51,9 @@ def OnEntityActivatedDeactivated_PrintMessage(): """ import os - from utils import TestHelper as helper from editor_entity_utils import EditorEntity as Entity from utils import Report + from utils import TestHelper as helper from utils import Tracer import azlmbr.legacy.general as general @@ -69,33 +65,45 @@ def OnEntityActivatedDeactivated_PrintMessage(): controller_dict = { "name": "Controller", "status": "active", - "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "controller.scriptcanvas") + "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "controller.scriptcanvas"), } activated_dict = { "name": "ActivationTest", "status": "inactive", - "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "activator.scriptcanvas") + "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "activator.scriptcanvas"), } deactivated_dict = { "name": "DeactivationTest", "status": "active", - "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "deactivator.scriptcanvas") + "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "deactivator.scriptcanvas"), } def get_asset(asset_path): - return azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False) + return azlmbr.asset.AssetCatalogRequestBus( + azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False + ) def setup_level(): - def create_editor_entity(entity_dict:dict, entity_to_activate:EditorEntity=None, entity_to_deactivate:EditorEntity=None) -> EditorEntity: + def create_editor_entity( + entity_dict: dict, entity_to_activate: EditorEntity = None, entity_to_deactivate: EditorEntity = None + ) -> EditorEntity: entity = Entity.create_editor_entity(entity_dict["name"]) entity.set_start_status(entity_dict["status"]) sc_component = entity.add_component("Script Canvas") - sc_component.set_component_property_value("Script Canvas Asset|Script Canvas Asset", get_asset(entity_dict["path"])) + sc_component.set_component_property_value( + "Script Canvas Asset|Script Canvas Asset", get_asset(entity_dict["path"]) + ) if entity_dict["name"] == "Controller": sc_component.get_property_tree() - sc_component.set_component_property_value("Properties|Variable Fields|Variables|[0]|Name,Value|Datum|Datum|EntityToActivate", entity_to_activate.id) - sc_component.set_component_property_value("Properties|Variable Fields|Variables|[1]|Name,Value|Datum|Datum|EntityToDeactivate", entity_to_deactivate.id) + sc_component.set_component_property_value( + "Properties|Variable Fields|Variables|[0]|Name,Value|Datum|Datum|EntityToActivate", + entity_to_activate.id, + ) + sc_component.set_component_property_value( + "Properties|Variable Fields|Variables|[1]|Name,Value|Datum|Datum|EntityToDeactivate", + entity_to_deactivate.id, + ) return entity activated = create_editor_entity(activated_dict) @@ -111,7 +119,7 @@ def OnEntityActivatedDeactivated_PrintMessage(): Report.critical_result(test_tuple, entity.id.IsValid()) return entity - def validate_start_state(entity:EditorEntity, expected_state:str): + def validate_start_state(entity: EditorEntity, expected_state: str): """ Validate that the starting state of the entity is correct, if it isn't then attempt to rectify and recheck. :return: bool: Whether state is set as expected @@ -177,8 +185,8 @@ def OnEntityActivatedDeactivated_PrintMessage(): if __name__ == "__main__": import ImportPathHelper as imports - imports.init() + imports.init() from utils import Report - + Report.start_test(OnEntityActivatedDeactivated_PrintMessage) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py index 666f052240..a72a302760 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py @@ -7,11 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: C1702834 // C1702823 -Test Case Title: Opening pane // Closing pane -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702834 and - https://testrail.agscollab.com/index.php?/cases/view/1702823 """ @@ -26,10 +21,10 @@ class Tests(): def Opening_Closing_Pane(): """ Summary: - The Script Canvas window is opened to verify if Script canvas panes can be opened and closed. + The Script Canvas window is opened to verify if Script Canvas panes can be opened and closed. Expected Behavior: - The pane opens and closes successfully. + The panes open and close successfully. Test Steps: 1) Open Script Canvas window (Tools > Script Canvas) @@ -115,7 +110,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from editor_python_test_tools.utils import Report Report.start_test(Opening_Closing_Pane) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py index fa5e9e6068..746efa500c 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py @@ -7,24 +7,19 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: C1702821 // C1702832 -Test Case Title: Retain visibility, size and location upon Script Canvas restart -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702821 and - https://testrail.agscollab.com/index.php?/cases/view/1702832 """ # fmt: off class Tests(): - relaunch_sc = ("Script Canvas window is relaunched", "Failed to relaunch Script Canvas window") - test_panes_visible = ("All the test panes are opened", "Failed to open one or more test panes") - close_pane_1 = ("Test pane 1 is closed", "Failed to close test pane 1") - visiblity_retained = ("Test pane retained its visiblity on SC restart", "Failed to retain visiblity of test pane on SC restart") - resize_pane_3 = ("Test pane 3 resized successfully", "Failed to resize Test pane 3") - size_retained = ("Test pane retained its size on SC restart", "Failed to retain size of test pane on SC restart") - location_changed = ("Location of test pane 2 changed successfully", "Failed to change locatio of test pane 2") - location_retained = ("Test pane retained its location on SC restart", "Failed to retain location of test pane on SC restart") + relaunch_sc = ("Script Canvas window is relaunched", "Failed to relaunch Script Canvas window") + test_panes_visible = ("All the test panes are opened", "Failed to open one or more test panes") + close_pane_1 = ("Test pane 1 is closed", "Failed to close test pane 1") + visibility_retained = ("Test pane retained its visibility on SC restart", "Failed to retain visibility of test pane on SC restart") + resize_pane_3 = ("Test pane 3 resized successfully", "Failed to resize Test pane 3") + size_retained = ("Test pane retained its size on SC restart", "Failed to retain size of test pane on SC restart") + location_changed = ("Location of test pane 2 changed successfully", "Failed to change location of test pane 2") + location_retained = ("Test pane retained its location on SC restart", "Failed to retain location of test pane on SC restart") # fmt: on @@ -35,7 +30,7 @@ def Pane_RetainOnSCRestart(): upon ScriptCanvas restart. Expected Behavior: - The ScriptCanvas pane retain it's visiblity, size and location upon ScriptCanvas restart. + The ScriptCanvas pane retain it's visibility, size and location upon ScriptCanvas restart. Test Steps: 1) Open Script Canvas window (Tools > Script Canvas) @@ -44,7 +39,7 @@ def Pane_RetainOnSCRestart(): 4) Change dock location of test pane 2 5) Resize test pane 3 6) Relaunch Script Canvas - 7) Verify if test pane 1 retain its visiblity + 7) Verify if test pane 1 retain its visibility 8) Verify if location of test pane 2 is retained 9) Verify if size of test pane 3 is retained 10) Restore default layout and close SC window @@ -57,6 +52,10 @@ def Pane_RetainOnSCRestart(): :return: None """ + # Pyside imports + from PySide2 import QtCore, QtWidgets + from PySide2.QtCore import Qt + # Helper imports from utils import Report from utils import TestHelper as helper @@ -65,11 +64,6 @@ def Pane_RetainOnSCRestart(): # Open 3D Engine Imports import azlmbr.legacy.general as general - # Pyside imports - from PySide2 import QtCore, QtWidgets - from PySide2.QtCore import Qt - - # Constants TEST_PANE_1 = "NodePalette" # test visibility TEST_PANE_2 = "VariableManager" # test location TEST_PANE_3 = "NodeInspector" # test size @@ -130,10 +124,10 @@ def Pane_RetainOnSCRestart(): sc_visible = helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) Report.result(Tests.relaunch_sc, sc_visible) - # 7) Verify if test pane 1 retain its visiblity + # 7) Verify if test pane 1 retain its visibility editor_window = pyside_utils.get_editor_main_window() sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - Report.result(Tests.visiblity_retained, not find_pane(sc, TEST_PANE_1).isVisible()) + Report.result(Tests.visibility_retained, not find_pane(sc, TEST_PANE_1).isVisible()) # 8) Verify if location of test pane 2 is retained sc_main = sc.findChild(QtWidgets.QMainWindow) @@ -158,7 +152,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(Pane_RetainOnSCRestart) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py index 180f577953..a870bea86f 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: C1702829 -Test Case Title: Resizing pane -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702829 """ @@ -24,7 +20,7 @@ class Tests(): def Resizing_Pane(): """ Summary: - The Script Canvas window is opened to verify if Script canvas panes can be resized and scaled + The Script Canvas window is opened to verify if Script Canvas panes can be resized and scaled Expected Behavior: The pane is resized and scaled appropriately. @@ -33,7 +29,7 @@ def Resizing_Pane(): 1) Open Script Canvas window (Tools > Script Canvas) 2) Restore default layout 3) Make sure pane is opened - 4) Resize pane + 4) Resize pane and verify change 5) Restore default layout 6) Close Script Canvas window @@ -45,6 +41,8 @@ def Resizing_Pane(): :return: None """ + from PySide2 import QtWidgets + from editor_python_test_tools.utils import Report from editor_python_test_tools.utils import TestHelper as helper import editor_python_test_tools.pyside_utils as pyside_utils @@ -52,9 +50,6 @@ def Resizing_Pane(): # Open 3D Engine imports import azlmbr.legacy.general as general - # Pyside imports - from PySide2 import QtWidgets - PANE_WIDGET = "NodePalette" SCALE_INT = 10 @@ -87,7 +82,7 @@ def Resizing_Pane(): Report.result(Tests.open_pane, pane.isVisible()) - # 4) Resize pane + # 4) Resize pane and verify change initial_size = pane.frameSize() pane.resize(initial_size.width() + SCALE_INT, initial_size.height() + SCALE_INT) new_size = pane.frameSize() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py index 38d60ad871..a1e177f5ec 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py @@ -7,11 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92562986 -Test Case Title: Changing the assigned Script Canvas Asset on an entity properly updates -level functionality -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562986 """ @@ -58,7 +53,6 @@ def ScriptCanvas_ChangingAssets(): import azlmbr.math as math import azlmbr.asset as asset import azlmbr.bus as bus - import azlmbr.paths as paths LEVEL_NAME = "tmp_level" ASSET_1 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents0.scriptcanvas") @@ -84,7 +78,6 @@ def ScriptCanvas_ChangingAssets(): Report.result(Tests.found_lines, find_expected_line(EXP_LINE)) helper.exit_game_mode(Tests.game_mode_exited) - # 1) Create temp level general.idle_enable(True) result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py index 896bee96e5..5117069b64 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92563190 -Test Case Title: A single Entity with two Script Canvas components works properly -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563190 """ @@ -58,6 +54,7 @@ def ScriptCanvas_TwoComponents(): import hydra_editor_utils as hydra from utils import Report from utils import Tracer + import azlmbr.legacy.general as general import azlmbr.math as math import azlmbr.asset as asset @@ -112,7 +109,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(ScriptCanvas_TwoComponents) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py index 401e6c0271..53b3951c1a 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py @@ -7,16 +7,12 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92563191 -Test Case Title: Two Entities can use the same Graph asset successfully at RunTime -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563191 """ # fmt: off class Tests(): - level_created = ("New level created", "New level not created") + level_created = ("New level created successfully", "New level failed to create") game_mode_entered = ("Game Mode successfully entered", "Game mode failed to enter") game_mode_exited = ("Game Mode successfully exited", "Game mode failed to exited") found_lines = ("Expected log lines were found", "Expected log lines were not found") @@ -27,7 +23,7 @@ def ScriptCanvas_TwoEntities(): """ Summary: Two Entities can use the same Graph asset successfully at RunTime. The script canvas asset - attached to the enties will print the respective entity names. + attached to the entities will print the respective entity names. Expected Behavior: When game mode is entered, respective strings of different entities should be printed. @@ -49,9 +45,10 @@ def ScriptCanvas_TwoEntities(): import os + import hydra_editor_utils as hydra from utils import TestHelper as helper from utils import Tracer - import hydra_editor_utils as hydra + import azlmbr.legacy.general as general import azlmbr.math as math import azlmbr.asset as asset diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py index d671229cdf..f58d6007a1 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92567321 -Test Case Title: Script Events: Can send and receive a script event across multiple entities successfully -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567321 """ @@ -28,7 +24,8 @@ class Tests(): def ScriptEvents_SendReceiveAcrossMultiple(): """ Summary: - EntityA and EntityB will be created in a level. Attached to both will be a Script Canvas component. The Script Event created for the test will be sent from EntityA to EntityB. + EntityA and EntityB will be created in a level. Attached to both will be a Script Canvas component. + The Script Event created for the test will be sent from EntityA to EntityB. Expected Behavior: The output of the Script Event should be printed to the console @@ -50,7 +47,7 @@ def ScriptEvents_SendReceiveAcrossMultiple(): :return: None """ import os - + from editor_entity_utils import EditorEntity as Entity from utils import Report from utils import TestHelper as helper @@ -66,20 +63,19 @@ def ScriptEvents_SendReceiveAcrossMultiple(): "assetA": os.path.join("ScriptCanvas", f"{ASSET_PREFIX}A.scriptcanvas"), "assetB": os.path.join("ScriptCanvas", f"{ASSET_PREFIX}B.scriptcanvas"), } - sc_for_entities = { - "EntityA": asset_paths["assetA"], - "EntityB": asset_paths["assetB"] - } + sc_for_entities = {"EntityA": asset_paths["assetA"], "EntityB": asset_paths["assetB"]} EXPECTED_LINES = ["Incoming Message Received"] def get_asset(asset_path): - return azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False) + return azlmbr.asset.AssetCatalogRequestBus( + azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False + ) def create_editor_entity(name, sc_asset): entity = Entity.create_editor_entity(name) sc_comp = entity.add_component("Script Canvas") sc_comp.set_component_property_value("Script Canvas Asset|Script Canvas Asset", get_asset(sc_asset)) - Report.critical_result(Tests.__dict__[name.lower()+"_created"], entity.id.isValid()) + Report.critical_result(Tests.__dict__[name.lower() + "_created"], entity.id.isValid()) def locate_expected_lines(line_list: list): found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] @@ -113,8 +109,8 @@ def ScriptEvents_SendReceiveAcrossMultiple(): if __name__ == "__main__": import ImportPathHelper as imports - imports.init() + imports.init() from utils import Report Report.start_test(ScriptEvents_SendReceiveAcrossMultiple) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py index b5e26d14ae..3f343221b0 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92567320 -Test Case Title: Script Events: Can send and receive a script event successfully -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567320 """ @@ -104,7 +100,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(ScriptEvents_SendReceiveSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index d87f2986bf..24e8eeda11 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -29,22 +29,18 @@ TEST_DIRECTORY = os.path.dirname(__file__) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(TestAutomationBase): - @pytest.mark.test_case_id("C1702834", "C1702823") def test_Opening_Closing_Pane(self, request, workspace, editor, launcher_platform): from . import Opening_Closing_Pane as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("C1702824") def test_Docking_Pane(self, request, workspace, editor, launcher_platform): from . import Docking_Pane as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("C1702829") def test_Resizing_Pane(self, request, workspace, editor, launcher_platform): from . import Resizing_Pane as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92563190") @pytest.mark.parametrize("level", ["tmp_level"]) def test_ScriptCanvas_TwoComponents(self, request, workspace, editor, launcher_platform, level): def teardown(): @@ -54,7 +50,6 @@ class TestAutomation(TestAutomationBase): from . import ScriptCanvas_TwoComponents as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92562986") @pytest.mark.parametrize("level", ["tmp_level"]) def test_ScriptCanvas_ChangingAssets(self, request, workspace, editor, launcher_platform, project, level): def teardown(): @@ -64,18 +59,14 @@ class TestAutomation(TestAutomationBase): from . import ScriptCanvas_ChangingAssets as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92569079", "T92569081") def test_Graph_ZoomInZoomOut(self, request, workspace, editor, launcher_platform): from . import Graph_ZoomInZoomOut as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92568940") def test_NodePalette_SelectNode(self, request, workspace, editor, launcher_platform): from . import NodePalette_SelectNode as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92569253") - @pytest.mark.test_case_id("T92569254") @pytest.mark.parametrize("level", ["tmp_level"]) def test_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): def teardown(): @@ -85,12 +76,10 @@ class TestAutomation(TestAutomationBase): from . import OnEntityActivatedDeactivated_PrintMessage as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92562993") def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project): from . import NodePalette_ClearSelection as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92563191") @pytest.mark.parametrize("level", ["tmp_level"]) def test_ScriptCanvas_TwoEntities(self, request, workspace, editor, launcher_platform, project, level): def teardown(): @@ -100,7 +89,6 @@ class TestAutomation(TestAutomationBase): from . import ScriptCanvas_TwoEntities as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92569013") def test_AssetEditor_CreateScriptEventFile(self, request, workspace, editor, launcher_platform, project): def teardown(): file_system.delete( @@ -113,22 +101,18 @@ class TestAutomation(TestAutomationBase): from . import AssetEditor_CreateScriptEventFile as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92569165", "T92569167", "T92569168", "T92569170") def test_Toggle_ScriptCanvasTools(self, request, workspace, editor, launcher_platform): from . import Toggle_ScriptCanvasTools as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92568982") def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project): from . import NodeInspector_RenameVariable as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92569137") def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): from . import Debugging_TargetMultipleGraphs as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92568856") @pytest.mark.parametrize("level", ["tmp_level"]) def test_Debugging_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level): def teardown(): @@ -138,17 +122,14 @@ class TestAutomation(TestAutomationBase): from . import Debugging_TargetMultipleEntities as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92569049", "T92569051") def test_EditMenu_UndoRedo(self, request, workspace, editor, launcher_platform, project): from . import EditMenu_UndoRedo as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("C1702825", "C1702831") def test_UnDockedPane_CloseSCWindow(self, request, workspace, editor, launcher_platform): from . import UnDockedPane_CloseSCWindow as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92562978") @pytest.mark.parametrize("level", ["tmp_level"]) def test_Entity_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level): def teardown(): @@ -158,12 +139,10 @@ class TestAutomation(TestAutomationBase): from . import Entity_AddScriptCanvasComponent as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("C1702821", "C1702832") def test_Pane_RetainOnSCRestart(self, request, workspace, editor, launcher_platform): from . import Pane_RetainOnSCRestart as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92567321") @pytest.mark.parametrize("level", ["tmp_level"]) def test_ScriptEvents_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level): def teardown(): @@ -173,7 +152,6 @@ class TestAutomation(TestAutomationBase): from . import ScriptEvents_SendReceiveAcrossMultiple as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92567320") @pytest.mark.parametrize("level", ["tmp_level"]) def test_ScriptEvents_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level): def teardown(): @@ -193,7 +171,6 @@ class TestScriptCanvasTests(object): The following tests use hydra_test_utils.py to launch the editor and validate the results. """ - @pytest.mark.test_case_id("T92569037", "T92569039") def test_FileMenu_New_Open(self, request, editor, launcher_platform): expected_lines = [ "File->New action working as expected: True", @@ -203,7 +180,6 @@ class TestScriptCanvasTests(object): request, TEST_DIRECTORY, editor, "FileMenu_New_Open.py", expected_lines, auto_test_mode=False, timeout=60, ) - @pytest.mark.test_case_id("T92568942") def test_AssetEditor_NewScriptEvent(self, request, editor, launcher_platform): expected_lines = [ "New Script event action found: True", @@ -221,7 +197,6 @@ class TestScriptCanvasTests(object): timeout=60, ) - @pytest.mark.test_case_id("T92563068", "T92563070") def test_GraphClose_SavePrompt(self, request, editor, launcher_platform): expected_lines = [ "New graph created: True", @@ -238,7 +213,6 @@ class TestScriptCanvasTests(object): timeout=60, ) - @pytest.mark.test_case_id("T92564789", "T92568873") def test_VariableManager_CreateDeleteVars(self, request, editor, launcher_platform): var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"] expected_lines = [f"Success: {var_type} variable is created" for var_type in var_types] diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py b/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py index 4024e28277..2b935a74b3 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py @@ -7,17 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: C92569165, C92569167, C92569168, C92569170 -Test Case Title: Tools > Node Palette toggles the Node Palette - Tools > Node Inspector toggles the Node Inspector - Tools > Bookmarks toggles the Bookmarks - Tools > Variable Manager toggles the Variable Manager - -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/92569165 - https://testrail.agscollab.com/index.php?/cases/view/92569167 - https://testrail.agscollab.com/index.php?/cases/view/92569168 - https://testrail.agscollab.com/index.php?/cases/view/92569170 """ @@ -63,6 +52,8 @@ def Toggle_ScriptCanvasTools(): :return: None """ + from PySide2 import QtWidgets + from utils import Report from utils import TestHelper as helper import pyside_utils @@ -70,9 +61,6 @@ def Toggle_ScriptCanvasTools(): # Open 3D Engine imports import azlmbr.legacy.general as general - # Pyside imports - from PySide2 import QtWidgets - def click_menu_option(window, option_text): action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) action.trigger() @@ -131,7 +119,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(Toggle_ScriptCanvasTools) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py b/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py index 875f28ec95..fbdba8fb38 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py @@ -7,11 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: C1702825 // C1702831 -Test Case Title: Undocking // Closing script canvas with the pane floating -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702825 & - https://testrail.agscollab.com/index.php?/cases/view/1702831 """ @@ -47,6 +42,8 @@ def UnDockedPane_CloseSCWindow(): :return: None """ + from PySide2 import QtWidgets + # Helper imports from utils import Report from utils import TestHelper as helper @@ -55,9 +52,6 @@ def UnDockedPane_CloseSCWindow(): # Open 3D Engine imports import azlmbr.legacy.general as general - # Pyside imports - from PySide2 import QtWidgets - TEST_PANE = "NodePalette" # Chosen most commonly used pane def click_menu_option(window, option_text): @@ -122,7 +116,6 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report Report.start_test(UnDockedPane_CloseSCWindow) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py index 6facc324d4..8f7557c01e 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py @@ -7,20 +7,13 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92564789 -Test Case Title: Each Variable type can be created -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92564789 -Test case ID: T92568873 -Test Case Title: Each Variable type can be deleted -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568873 """ def VariableManager_CreateDeleteVars(): """ Summary: - Each variable type can be created and deleted in variable manager. + Creating and deleting each type of variable in the Variable Manager pane Expected Behavior: Each variable type can be created and deleted in variable manager. @@ -43,15 +36,13 @@ def VariableManager_CreateDeleteVars(): """ from PySide2 import QtWidgets, QtCore, QtTest - from PySide2.QtCore import Qt from utils import TestHelper as helper + import pyside_utils import azlmbr.legacy.general as general - import pyside_utils - def generate_test_tuple(var_type, action): return (f"{var_type} variable is {action}d", f"{var_type} variable is not {action}d") From 6f3b46dc29fd54bf781c05024263e38e6c5596ea Mon Sep 17 00:00:00 2001 From: Peng Date: Thu, 6 May 2021 16:36:13 -0700 Subject: [PATCH 035/225] ATOM-15266 [RHI][Vulkan][Android] Use warning on fragment pool error due to recreation of the memory pool in subsequent step JIRA: https://jira.agscollab.com/browse/ATOM-15266 --- .../Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp | 11 ++++++++++- Gems/Atom/RHI/Vulkan/Code/Source/RHI/Vulkan.cpp | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp index 8eee7ef726..8769aaa1f9 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp @@ -239,7 +239,16 @@ namespace AZ allocInfo.pSetLayouts = &nativeLayout; VkResult result = vkAllocateDescriptorSets(descriptor.m_device->GetNativeDevice(), &allocInfo, &m_nativeDescriptorSet); - AssertSuccess(result); + if (result == VK_ERROR_FRAGMENTED_POOL) + { + // fragmented pool will be re-created subsequently, so warning only + AZ_Warning("Vulkan RHI", false, "Fragmented pool"); + } + else + { + AssertSuccess(result); + } + if (result != VK_SUCCESS) { return result; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Vulkan.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Vulkan.cpp index 90a4c2f9c2..311d3436de 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Vulkan.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Vulkan.cpp @@ -96,6 +96,8 @@ namespace AZ return "Validation failed"; case VK_ERROR_OUT_OF_POOL_MEMORY: return "Pool is out of memory"; + case VK_ERROR_FRAGMENTED_POOL: + return "Fragmented pool"; default: return "Unknown error"; } From 972f4b3c2876b2a039eb735d9d3e971f703854eb Mon Sep 17 00:00:00 2001 From: darapan Date: Thu, 6 May 2021 23:30:54 -0700 Subject: [PATCH 036/225] "Following rules in SPEC-6690" --- .../PythonTests/scripting/TestSuite_Active.py | 51 ++++++++++++++++--- .../VariableManager_UnpinVariableType.py | 4 -- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index 7c218b5fa9..36dd4f21e3 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -12,9 +12,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import pytest import os import sys + sys.path.append(os.path.dirname(__file__)) import ImportPathHelper as imports + imports.init() import hydra_test_utils as hydra @@ -26,22 +28,25 @@ TEST_DIRECTORY = os.path.dirname(__file__) @pytest.mark.SUITE_periodic -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(TestAutomationBase): @pytest.mark.test_case_id("C1702834", "C1702823") def test_Opening_Closing_Pane(self, request, workspace, editor, launcher_platform): from . import Opening_Closing_Pane as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("C1702824") def test_Docking_Pane(self, request, workspace, editor, launcher_platform): from . import Docking_Pane as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("C1702829") def test_Resizing_Pane(self, request, workspace, editor, launcher_platform): from . import Resizing_Pane as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92563190") @@ -49,9 +54,11 @@ class TestAutomation(TestAutomationBase): def test_ScriptCanvas_TwoComponents(self, request, workspace, editor, launcher_platform, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptCanvas_TwoComponents as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92562986") @@ -59,35 +66,44 @@ class TestAutomation(TestAutomationBase): def test_ScriptCanvas_ChangingAssets(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptCanvas_ChangingAssets as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569079", "T92569081") def test_Graph_ZoomInZoomOut(self, request, workspace, editor, launcher_platform): from . import Graph_ZoomInZoomOut as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92568940") def test_NodePalette_SelectNode(self, request, workspace, editor, launcher_platform): from . import NodePalette_SelectNode as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569253") @pytest.mark.test_case_id("T92569254") @pytest.mark.parametrize("level", ["tmp_level"]) - def test_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): + def test_OnEntityActivatedDeactivated_PrintMessage( + self, request, workspace, editor, launcher_platform, project, level + ): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import OnEntityActivatedDeactivated_PrintMessage as test_module + self._run_test(request, workspace, editor, test_module) - + @pytest.mark.test_case_id("T92562993") def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project): from . import NodePalette_ClearSelection as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92563191") @@ -95,9 +111,11 @@ class TestAutomation(TestAutomationBase): def test_ScriptCanvas_TwoEntities(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptCanvas_TwoEntities as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569013") @@ -106,26 +124,31 @@ class TestAutomation(TestAutomationBase): file_system.delete( [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True ) + request.addfinalizer(teardown) file_system.delete( [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True ) from . import AssetEditor_CreateScriptEventFile as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569165", "T92569167", "T92569168", "T92569170") def test_Toggle_ScriptCanvasTools(self, request, workspace, editor, launcher_platform): from . import Toggle_ScriptCanvasTools as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92568982") def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project): from . import NodeInspector_RenameVariable as test_module + self._run_test(request, workspace, editor, test_module) - + @pytest.mark.test_case_id("T92569137") def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): from . import Debugging_TargetMultipleGraphs as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92568856") @@ -133,19 +156,23 @@ class TestAutomation(TestAutomationBase): def test_Debugging_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import Debugging_TargetMultipleEntities as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569049", "T92569051") def test_EditMenu_UndoRedo(self, request, workspace, editor, launcher_platform, project): from . import EditMenu_UndoRedo as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("C1702825", "C1702831") def test_UnDockedPane_CloseSCWindow(self, request, workspace, editor, launcher_platform): from . import UnDockedPane_CloseSCWindow as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92562978") @@ -153,24 +180,31 @@ class TestAutomation(TestAutomationBase): def test_Entity_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import Entity_AddScriptCanvasComponent as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("C1702821", "C1702832") def test_Pane_RetainOnSCRestart(self, request, workspace, editor, launcher_platform): from . import Pane_RetainOnSCRestart as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92567321") @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptEvents_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level): + def test_ScriptEvents_SendReceiveAcrossMultiple( + self, request, workspace, editor, launcher_platform, project, level + ): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptEvents_SendReceiveAcrossMultiple as test_module + self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92567320") @@ -178,16 +212,19 @@ class TestAutomation(TestAutomationBase): def test_ScriptEvents_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptEvents_SendReceiveSuccessfully as test_module + self._run_test(request, workspace, editor, test_module) - @pytest.mark.test_case_id("T92568973") def test_VariableManager_UnpinVariableType(self, request, workspace, editor, launcher_platform): from . import VariableManager_UnpinVariableType as test_module + self._run_test(request, workspace, editor, test_module) + # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method # fails because of pyside_utils import @pytest.mark.SUITE_periodic @@ -256,4 +293,4 @@ class TestScriptCanvasTests(object): expected_lines, auto_test_mode=False, timeout=60, - ) \ No newline at end of file + ) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py index f9fe45dd86..5d097de2f8 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py @@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - -Test case ID: T92568973 -Test Case Title: Unpin Variable types in Variable Manager -URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568973 """ From 786cd9fcb78a474221f2dbc49e765ea02afc7f10 Mon Sep 17 00:00:00 2001 From: darapan Date: Thu, 6 May 2021 23:35:19 -0700 Subject: [PATCH 037/225] "" --- .../PythonTests/scripting/TestSuite_Active.py | 52 +++---------------- 1 file changed, 7 insertions(+), 45 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index 36dd4f21e3..7bfcca97df 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -12,11 +12,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import pytest import os import sys - sys.path.append(os.path.dirname(__file__)) import ImportPathHelper as imports - imports.init() import hydra_test_utils as hydra @@ -28,25 +26,22 @@ TEST_DIRECTORY = os.path.dirname(__file__) @pytest.mark.SUITE_periodic -@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(TestAutomationBase): @pytest.mark.test_case_id("C1702834", "C1702823") def test_Opening_Closing_Pane(self, request, workspace, editor, launcher_platform): from . import Opening_Closing_Pane as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("C1702824") def test_Docking_Pane(self, request, workspace, editor, launcher_platform): from . import Docking_Pane as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("C1702829") def test_Resizing_Pane(self, request, workspace, editor, launcher_platform): from . import Resizing_Pane as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92563190") @@ -54,11 +49,9 @@ class TestAutomation(TestAutomationBase): def test_ScriptCanvas_TwoComponents(self, request, workspace, editor, launcher_platform, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptCanvas_TwoComponents as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92562986") @@ -66,44 +59,35 @@ class TestAutomation(TestAutomationBase): def test_ScriptCanvas_ChangingAssets(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptCanvas_ChangingAssets as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569079", "T92569081") def test_Graph_ZoomInZoomOut(self, request, workspace, editor, launcher_platform): from . import Graph_ZoomInZoomOut as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92568940") def test_NodePalette_SelectNode(self, request, workspace, editor, launcher_platform): from . import NodePalette_SelectNode as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569253") @pytest.mark.test_case_id("T92569254") @pytest.mark.parametrize("level", ["tmp_level"]) - def test_OnEntityActivatedDeactivated_PrintMessage( - self, request, workspace, editor, launcher_platform, project, level - ): + def test_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import OnEntityActivatedDeactivated_PrintMessage as test_module - self._run_test(request, workspace, editor, test_module) - + @pytest.mark.test_case_id("T92562993") def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project): from . import NodePalette_ClearSelection as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92563191") @@ -111,11 +95,9 @@ class TestAutomation(TestAutomationBase): def test_ScriptCanvas_TwoEntities(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptCanvas_TwoEntities as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569013") @@ -124,31 +106,26 @@ class TestAutomation(TestAutomationBase): file_system.delete( [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True ) - request.addfinalizer(teardown) file_system.delete( [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True ) from . import AssetEditor_CreateScriptEventFile as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569165", "T92569167", "T92569168", "T92569170") def test_Toggle_ScriptCanvasTools(self, request, workspace, editor, launcher_platform): from . import Toggle_ScriptCanvasTools as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92568982") def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project): from . import NodeInspector_RenameVariable as test_module - self._run_test(request, workspace, editor, test_module) - + @pytest.mark.test_case_id("T92569137") def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): from . import Debugging_TargetMultipleGraphs as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92568856") @@ -156,23 +133,19 @@ class TestAutomation(TestAutomationBase): def test_Debugging_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import Debugging_TargetMultipleEntities as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92569049", "T92569051") def test_EditMenu_UndoRedo(self, request, workspace, editor, launcher_platform, project): from . import EditMenu_UndoRedo as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("C1702825", "C1702831") def test_UnDockedPane_CloseSCWindow(self, request, workspace, editor, launcher_platform): from . import UnDockedPane_CloseSCWindow as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92562978") @@ -180,31 +153,24 @@ class TestAutomation(TestAutomationBase): def test_Entity_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import Entity_AddScriptCanvasComponent as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("C1702821", "C1702832") def test_Pane_RetainOnSCRestart(self, request, workspace, editor, launcher_platform): from . import Pane_RetainOnSCRestart as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92567321") @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptEvents_SendReceiveAcrossMultiple( - self, request, workspace, editor, launcher_platform, project, level - ): + def test_ScriptEvents_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptEvents_SendReceiveAcrossMultiple as test_module - self._run_test(request, workspace, editor, test_module) @pytest.mark.test_case_id("T92567320") @@ -212,19 +178,15 @@ class TestAutomation(TestAutomationBase): def test_ScriptEvents_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptEvents_SendReceiveSuccessfully as test_module - self._run_test(request, workspace, editor, test_module) - + def test_VariableManager_UnpinVariableType(self, request, workspace, editor, launcher_platform): from . import VariableManager_UnpinVariableType as test_module - self._run_test(request, workspace, editor, test_module) - # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method # fails because of pyside_utils import @pytest.mark.SUITE_periodic @@ -293,4 +255,4 @@ class TestScriptCanvasTests(object): expected_lines, auto_test_mode=False, timeout=60, - ) + ) \ No newline at end of file From 132ee9d852d2b6e30e699e7a7ace67a46ac97759 Mon Sep 17 00:00:00 2001 From: balibhan Date: Fri, 7 May 2021 14:50:06 +0530 Subject: [PATCH 038/225] Node palette search box text deletion --- .../NodePalette_SearchText_Deletion.py | 91 +++++++++++++++++++ .../PythonTests/scripting/TestSuite_Active.py | 4 + 2 files changed, 95 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SearchText_Deletion.py diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SearchText_Deletion.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SearchText_Deletion.py new file mode 100644 index 0000000000..0739a8e637 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SearchText_Deletion.py @@ -0,0 +1,91 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + set_search_string = ("Search string is set", "Search string is not set") + search_string_deleted = ("Search string deleted as expected", "Search string not deleted") +# fmt: on + + +def NodePalette_SearchText_Deletion(): + """ + Summary: + We enter some string in the Node Palette Search box, select that text and delete it. + + Expected Behavior: + After RightClick->Delete the text in the Searchbox should be deleted. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Node Manager if not opened already + 4) Set some string in the Search box + 5) Verify if the test string is set + 6) Delete search string using right click and verify if it is cleared + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from PySide2 import QtWidgets, QtTest, QtCore + + from utils import TestHelper as helper + + import azlmbr.legacy.general as general + + import pyside_utils + + TEST_STRING = "TestString" + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 3.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + + # 3) Open Node Manager if not opened already + if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) + action.trigger() + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame") + + # 4) Set some string in the Search box + search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter") + search_box.setText(TEST_STRING) + + # 5) Verify if the test string is set + result = helper.wait_for_condition(lambda: search_box.text() == TEST_STRING, 1.0) + Report.result(Tests.set_search_string, result) + + # 6) Delete search string using right click and verify if it is cleared + QtTest.QTest.keyClick(search_box, QtCore.Qt.Key_A, QtCore.Qt.ControlModifier) + pyside_utils.trigger_context_menu_entry(search_box, "Delete") + result = helper.wait_for_condition(lambda: search_box.text() == "", 2.0) + Report.result(Tests.search_string_deleted, result) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(NodePalette_SearchText_Deletion) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index d87f2986bf..e34774ebd4 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -183,6 +183,10 @@ class TestAutomation(TestAutomationBase): from . import ScriptEvents_SendReceiveSuccessfully as test_module self._run_test(request, workspace, editor, test_module) + def test_NodePalette_SearchText_Deletion(self, request, workspace, editor, launcher_platform): + from . import NodePalette_SearchText_Deletion as test_module + self._run_test(request, workspace, editor, test_module) + # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method # fails because of pyside_utils import @pytest.mark.SUITE_periodic From be0f69d081a5643a7c298f84eb4f256709c05092 Mon Sep 17 00:00:00 2001 From: zsolleci Date: Fri, 7 May 2021 11:47:39 -0500 Subject: [PATCH 039/225] updated files to fit name convention --- ...ugger_HappyPath_TargetMultipleEntities.py} | 4 +- ...ebugger_HappyPath_TargetMultipleGraphs.py} | 4 +- ...doRedo.py => EditMenu_Default_UndoRedo.py} | 4 +- ...ity_HappyPath_AddScriptCanvasComponent.py} | 4 +- ...Open.py => FileMenu_Default_NewAndOpen.py} | 4 +- ...pt.py => GraphClose_Default_SavePrompt.py} | 4 +- ...ut.py => Graph_HappyPath_ZoomInZoomOut.py} | 4 +- ...entButton_HappyPath_ContainsSCCategory.py} | 0 ...odeInspector_HappyPath_VariableRenames.py} | 4 +- ...=> NodePalette_HappyPath_CanSelectNode.py} | 4 +- ...> NodePalette_HappyPath_ClearSelection.py} | 4 +- ...atedDeactivated_HappyPath_PrintMessage.py} | 4 +- ...t.py => Pane_Default_RetainOnSCRestart.py} | 4 +- ...ane.py => Pane_HappyPath_DocksProperly.py} | 4 +- ...> Pane_HappyPath_OpenCloseSuccessfully.py} | 4 +- ...e.py => Pane_HappyPath_ResizesProperly.py} | 4 +- ...py => Pane_Undocked_ClosesSuccessfully.py} | 4 +- ...iptCanvasTools_Toggle_OpenCloseSuccess.py} | 4 +- ...tCanvas_ChangingAssets_ComponentStable.py} | 4 +- ...vas_TwoComponents_InteractSuccessfully.py} | 4 +- ...ptCanvas_TwoEntities_UseSimultaneously.py} | 4 +- ...iptEvent_HappyPath_CreatedWithoutError.py} | 0 ...Events_Default_SendReceiveSuccessfully.py} | 4 +- ...ts_HappyPath_SendReceiveAcrossMultiple.py} | 4 +- .../PythonTests/scripting/TestSuite_Active.py | 104 +++++++++--------- ...riableManager_Default_CreateDeleteVars.py} | 4 +- 26 files changed, 98 insertions(+), 98 deletions(-) rename AutomatedTesting/Gem/PythonTests/scripting/{Debugging_TargetMultipleEntities.py => Debugger_HappyPath_TargetMultipleEntities.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{Debugging_TargetMultipleGraphs.py => Debugger_HappyPath_TargetMultipleGraphs.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{EditMenu_UndoRedo.py => EditMenu_Default_UndoRedo.py} (98%) rename AutomatedTesting/Gem/PythonTests/scripting/{Entity_AddScriptCanvasComponent.py => Entity_HappyPath_AddScriptCanvasComponent.py} (96%) rename AutomatedTesting/Gem/PythonTests/scripting/{FileMenu_New_Open.py => FileMenu_Default_NewAndOpen.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{GraphClose_SavePrompt.py => GraphClose_Default_SavePrompt.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{Graph_ZoomInZoomOut.py => Graph_HappyPath_ZoomInZoomOut.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{AssetEditor_NewScriptEvent.py => NewScriptEventButton_HappyPath_ContainsSCCategory.py} (100%) rename AutomatedTesting/Gem/PythonTests/scripting/{NodeInspector_RenameVariable.py => NodeInspector_HappyPath_VariableRenames.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{NodePalette_SelectNode.py => NodePalette_HappyPath_CanSelectNode.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{NodePalette_ClearSelection.py => NodePalette_HappyPath_ClearSelection.py} (96%) rename AutomatedTesting/Gem/PythonTests/scripting/{OnEntityActivatedDeactivated_PrintMessage.py => OnEntityActivatedDeactivated_HappyPath_PrintMessage.py} (98%) rename AutomatedTesting/Gem/PythonTests/scripting/{Pane_RetainOnSCRestart.py => Pane_Default_RetainOnSCRestart.py} (98%) rename AutomatedTesting/Gem/PythonTests/scripting/{Docking_Pane.py => Pane_HappyPath_DocksProperly.py} (97%) mode change 100755 => 100644 rename AutomatedTesting/Gem/PythonTests/scripting/{Opening_Closing_Pane.py => Pane_HappyPath_OpenCloseSuccessfully.py} (97%) mode change 100755 => 100644 rename AutomatedTesting/Gem/PythonTests/scripting/{Resizing_Pane.py => Pane_HappyPath_ResizesProperly.py} (97%) mode change 100755 => 100644 rename AutomatedTesting/Gem/PythonTests/scripting/{UnDockedPane_CloseSCWindow.py => Pane_Undocked_ClosesSuccessfully.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{Toggle_ScriptCanvasTools.py => ScriptCanvasTools_Toggle_OpenCloseSuccess.py} (98%) rename AutomatedTesting/Gem/PythonTests/scripting/{ScriptCanvas_ChangingAssets.py => ScriptCanvas_ChangingAssets_ComponentStable.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{ScriptCanvas_TwoComponents.py => ScriptCanvas_TwoComponents_InteractSuccessfully.py} (96%) rename AutomatedTesting/Gem/PythonTests/scripting/{ScriptCanvas_TwoEntities.py => ScriptCanvas_TwoEntities_UseSimultaneously.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{AssetEditor_CreateScriptEventFile.py => ScriptEvent_HappyPath_CreatedWithoutError.py} (100%) rename AutomatedTesting/Gem/PythonTests/scripting/{ScriptEvents_SendReceiveSuccessfully.py => ScriptEvents_Default_SendReceiveSuccessfully.py} (96%) rename AutomatedTesting/Gem/PythonTests/scripting/{ScriptEvents_SendReceiveAcrossMultiple.py => ScriptEvents_HappyPath_SendReceiveAcrossMultiple.py} (97%) rename AutomatedTesting/Gem/PythonTests/scripting/{VariableManager_CreateDeleteVars.py => VariableManager_Default_CreateDeleteVars.py} (97%) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleEntities.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py rename to AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleEntities.py index 71e24139f4..2c36062acf 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleEntities.py @@ -21,7 +21,7 @@ class Tests(): GENERAL_WAIT = 0.5 # seconds -def Debugging_TargetMultipleEntities(): +def Debugger_HappyPath_TargetMultipleEntities(): """ Summary: Multiple Entities can be targeted in the Debugger tool @@ -135,4 +135,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(Debugging_TargetMultipleEntities) + Report.start_test(Debugger_HappyPath_TargetMultipleEntities) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleGraphs.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py rename to AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleGraphs.py index 342f8f3cd4..906c198d43 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleGraphs.py @@ -19,7 +19,7 @@ class Tests(): GENERAL_WAIT = 0.5 # seconds -def Debugging_TargetMultipleGraphs(): +def Debugger_HappyPath_TargetMultipleGraphs(): """ Summary: Multiple Graphs can be targeted in the Debugger tool @@ -103,4 +103,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(Debugging_TargetMultipleGraphs) + Report.start_test(Debugger_HappyPath_TargetMultipleGraphs) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_Default_UndoRedo.py similarity index 98% rename from AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py rename to AutomatedTesting/Gem/PythonTests/scripting/EditMenu_Default_UndoRedo.py index 246a8894ba..34345cf36b 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_Default_UndoRedo.py @@ -18,7 +18,7 @@ class Tests(): # fmt: on -def EditMenu_UndoRedo(): +def EditMenu_Default_UndoRedo(): """ Summary: Edit > Undo undoes the last action @@ -110,4 +110,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(EditMenu_UndoRedo) + Report.start_test(EditMenu_Default_UndoRedo) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py b/AutomatedTesting/Gem/PythonTests/scripting/Entity_HappyPath_AddScriptCanvasComponent.py similarity index 96% rename from AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py rename to AutomatedTesting/Gem/PythonTests/scripting/Entity_HappyPath_AddScriptCanvasComponent.py index 4e8576d892..22530c90c1 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Entity_HappyPath_AddScriptCanvasComponent.py @@ -20,7 +20,7 @@ class Tests(): # fmt: on -def Entity_AddScriptCanvasComponent(): +def Entity_HappyPath_AddScriptCanvasComponent(): """ Summary: Script Canvas Component can be added to an entity @@ -80,4 +80,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(Entity_AddScriptCanvasComponent) + Report.start_test(Entity_HappyPath_AddScriptCanvasComponent) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py rename to AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py index 094598e51d..4771a95ab7 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py @@ -26,7 +26,7 @@ class Tests(): GENERAL_WAIT = 0.5 # seconds -class TestFileMenuNewOpen: +class TestFileMenuDefaultNewOpen: """ Summary: When clicked on File->New, new script opens @@ -86,5 +86,5 @@ class TestFileMenuNewOpen: general.close_pane("Script Canvas") -test = TestFileMenuNewOpen() +test = TestFileMenuDefaultNewOpen() test.run_test() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_Default_SavePrompt.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py rename to AutomatedTesting/Gem/PythonTests/scripting/GraphClose_Default_SavePrompt.py index b2a4b22056..9720c846c7 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_Default_SavePrompt.py @@ -29,7 +29,7 @@ class Tests(): GENERAL_WAIT = 0.5 # seconds -class TestGraphCloseSavePrompt: +class TestGraphClose_Default_SavePrompt: """ Summary: The graph is closed when x button is clicked. @@ -98,5 +98,5 @@ class TestGraphCloseSavePrompt: general.close_pane("Script Canvas") -test = TestGraphCloseSavePrompt() +test = TestGraphClose_Default_SavePrompt() test.run_test() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py b/AutomatedTesting/Gem/PythonTests/scripting/Graph_HappyPath_ZoomInZoomOut.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py rename to AutomatedTesting/Gem/PythonTests/scripting/Graph_HappyPath_ZoomInZoomOut.py index 754a0ae686..11c83bb779 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Graph_HappyPath_ZoomInZoomOut.py @@ -20,7 +20,7 @@ class Tests(): GENERAL_WAIT = 0.5 # seconds -def Graph_ZoomInZoomOut(): +def Graph_HappyPath_ZoomInZoomOut(): """ Summary: The graph can be zoomed in and zoomed out. @@ -108,4 +108,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(Graph_ZoomInZoomOut) + Report.start_test(Graph_HappyPath_ZoomInZoomOut) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py b/AutomatedTesting/Gem/PythonTests/scripting/NewScriptEventButton_HappyPath_ContainsSCCategory.py similarity index 100% rename from AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py rename to AutomatedTesting/Gem/PythonTests/scripting/NewScriptEventButton_HappyPath_ContainsSCCategory.py diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_HappyPath_VariableRenames.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py rename to AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_HappyPath_VariableRenames.py index 7351e45212..c235db6256 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_HappyPath_VariableRenames.py @@ -21,7 +21,7 @@ class Tests(): GENERAL_WAIT = 0.5 # seconds -def NodeInspector_RenameVariable(): +def NodeInspector_HappyPath_VariableRenames(): """ Summary: Renaming variables in the Node Inspector, renames the actual variable. @@ -123,4 +123,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(NodeInspector_RenameVariable) + Report.start_test(NodeInspector_HappyPath_VariableRenames) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_CanSelectNode.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py rename to AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_CanSelectNode.py index dfe1064a92..2fb1830b8f 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_CanSelectNode.py @@ -20,7 +20,7 @@ class Tests(): GENERAL_WAIT = 0.5 # seconds -def NodePalette_SelectNode(): +def NodePalette_HappyPath_CanSelectNode(): """ Summary: Categories and Nodes can be selected @@ -97,4 +97,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(NodePalette_SelectNode) + Report.start_test(NodePalette_HappyPath_CanSelectNode) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_ClearSelection.py similarity index 96% rename from AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py rename to AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_ClearSelection.py index 87a08346d0..93254dd377 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_ClearSelection.py @@ -17,7 +17,7 @@ class Tests(): # fmt: on -def NodePalette_ClearSelection(): +def NodePalette_HappyPath_ClearSelection(): """ Summary: Clicking the X button on the Search Box clears the currently entered string @@ -85,4 +85,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(NodePalette_ClearSelection) + Report.start_test(NodePalette_HappyPath_ClearSelection) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py b/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_HappyPath_PrintMessage.py similarity index 98% rename from AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py rename to AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_HappyPath_PrintMessage.py index c331157e82..721ab53d8e 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_HappyPath_PrintMessage.py @@ -23,7 +23,7 @@ class Tests(): # fmt: on -def OnEntityActivatedDeactivated_PrintMessage(): +def OnEntityActivatedDeactivated_HappyPath_PrintMessage(): """ Summary: Verify that the On Entity Activated/On Entity Deactivated nodes are working as expected @@ -189,4 +189,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(OnEntityActivatedDeactivated_PrintMessage) + Report.start_test(OnEntityActivatedDeactivated_HappyPath_PrintMessage) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_Default_RetainOnSCRestart.py similarity index 98% rename from AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py rename to AutomatedTesting/Gem/PythonTests/scripting/Pane_Default_RetainOnSCRestart.py index 746efa500c..626b1cf0bd 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_Default_RetainOnSCRestart.py @@ -23,7 +23,7 @@ class Tests(): # fmt: on -def Pane_RetainOnSCRestart(): +def Pane_Default_RetainOnSCRestart(): """ Summary: The Script Canvas window is opened to verify if Script canvas panes can retain its visibility, size and location @@ -154,4 +154,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(Pane_RetainOnSCRestart) + Report.start_test(Pane_Default_RetainOnSCRestart) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_DocksProperly.py old mode 100755 new mode 100644 similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py rename to AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_DocksProperly.py index da9dc125bc..2186a8a54a --- a/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_DocksProperly.py @@ -17,7 +17,7 @@ class Tests(): # fmt: on -def Docking_Pane(): +def Pane_HappyPath_DocksProperly(): """ Summary: The Script Canvas window is opened to verify if Script canvas panes can be docked into every @@ -103,4 +103,4 @@ if __name__ == "__main__": imports.init() from editor_python_test_tools.utils import Report - Report.start_test(Docking_Pane) + Report.start_test(Pane_HappyPath_DocksProperly) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_OpenCloseSuccessfully.py old mode 100755 new mode 100644 similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py rename to AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_OpenCloseSuccessfully.py index a72a302760..cedd68cd87 --- a/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_OpenCloseSuccessfully.py @@ -18,7 +18,7 @@ class Tests(): # fmt: on -def Opening_Closing_Pane(): +def Pane_HappyPath_OpenCloseSuccessfully(): """ Summary: The Script Canvas window is opened to verify if Script Canvas panes can be opened and closed. @@ -112,4 +112,4 @@ if __name__ == "__main__": imports.init() from editor_python_test_tools.utils import Report - Report.start_test(Opening_Closing_Pane) + Report.start_test(Pane_HappyPath_OpenCloseSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_ResizesProperly.py old mode 100755 new mode 100644 similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py rename to AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_ResizesProperly.py index a870bea86f..36d734049d --- a/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_ResizesProperly.py @@ -17,7 +17,7 @@ class Tests(): # fmt: on -def Resizing_Pane(): +def Pane_HappyPath_ResizesProperly(): """ Summary: The Script Canvas window is opened to verify if Script Canvas panes can be resized and scaled @@ -105,4 +105,4 @@ if __name__ == "__main__": imports.init() from editor_python_test_tools.utils import Report - Report.start_test(Resizing_Pane) + Report.start_test(Pane_HappyPath_ResizesProperly) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_Undocked_ClosesSuccessfully.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py rename to AutomatedTesting/Gem/PythonTests/scripting/Pane_Undocked_ClosesSuccessfully.py index fbdba8fb38..0ddbe7e34f 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_Undocked_ClosesSuccessfully.py @@ -18,7 +18,7 @@ class Tests(): # fmt: on -def UnDockedPane_CloseSCWindow(): +def Pane_Undocked_ClosesSuccessfully(): """ Summary: The Script Canvas window is opened with one of the pane undocked. @@ -118,4 +118,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(UnDockedPane_CloseSCWindow) + Report.start_test(Pane_Undocked_ClosesSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasTools_Toggle_OpenCloseSuccess.py similarity index 98% rename from AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py rename to AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasTools_Toggle_OpenCloseSuccess.py index 2b935a74b3..a105f1ef18 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasTools_Toggle_OpenCloseSuccess.py @@ -27,7 +27,7 @@ class Tests(): # fmt: on -def Toggle_ScriptCanvasTools(): +def ScriptCanvasTools_Toggle_OpenCloseSuccess(): """ Summary: Toggle Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas. @@ -121,4 +121,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(Toggle_ScriptCanvasTools) + Report.start_test(ScriptCanvasTools_Toggle_OpenCloseSuccess) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets_ComponentStable.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py rename to AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets_ComponentStable.py index a1e177f5ec..d39c3d2590 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets_ComponentStable.py @@ -20,7 +20,7 @@ class Tests(): # fmt: on -def ScriptCanvas_ChangingAssets(): +def ScriptCanvas_ChangingAssets_ComponentStable(): """ Summary: Changing the assigned Script Canvas Asset on an entity properly updates level functionality @@ -106,4 +106,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(ScriptCanvas_ChangingAssets) + Report.start_test(ScriptCanvas_ChangingAssets_ComponentStable) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents_InteractSuccessfully.py similarity index 96% rename from AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py rename to AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents_InteractSuccessfully.py index 5117069b64..9bbda9bdbd 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents_InteractSuccessfully.py @@ -23,7 +23,7 @@ class LogLines: expected_lines = ["Greetings from the first script", "Greetings from the second script"] -def ScriptCanvas_TwoComponents(): +def ScriptCanvas_TwoComponents_InteractSuccessfully(): """ Summary: A test entity contains two Script Canvas components with different unique script canvas files. @@ -111,4 +111,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(ScriptCanvas_TwoComponents) + Report.start_test(ScriptCanvas_TwoComponents_InteractSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities_UseSimultaneously.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py rename to AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities_UseSimultaneously.py index 53b3951c1a..d25ef64c4a 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities_UseSimultaneously.py @@ -19,7 +19,7 @@ class Tests(): # fmt: on -def ScriptCanvas_TwoEntities(): +def ScriptCanvas_TwoEntities_UseSimultaneously(): """ Summary: Two Entities can use the same Graph asset successfully at RunTime. The script canvas asset @@ -101,4 +101,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(ScriptCanvas_TwoEntities) + Report.start_test(ScriptCanvas_TwoEntities_UseSimultaneously) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_HappyPath_CreatedWithoutError.py similarity index 100% rename from AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py rename to AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_HappyPath_CreatedWithoutError.py diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_Default_SendReceiveSuccessfully.py similarity index 96% rename from AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py rename to AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_Default_SendReceiveSuccessfully.py index 3f343221b0..e0730b284c 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_Default_SendReceiveSuccessfully.py @@ -20,7 +20,7 @@ class Tests(): # fmt: on -def ScriptEvents_SendReceiveSuccessfully(): +def ScriptEvents_Default_SendReceiveSuccessfully(): """ Summary: An entity exists in the level that contains a Script Canvas component. In the graph is both a Send Event @@ -102,4 +102,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(ScriptEvents_SendReceiveSuccessfully) + Report.start_test(ScriptEvents_Default_SendReceiveSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_HappyPath_SendReceiveAcrossMultiple.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py rename to AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_HappyPath_SendReceiveAcrossMultiple.py index f58d6007a1..be2665899f 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_HappyPath_SendReceiveAcrossMultiple.py @@ -21,7 +21,7 @@ class Tests(): # fmt: on -def ScriptEvents_SendReceiveAcrossMultiple(): +def ScriptEvents_HappyPath_SendReceiveAcrossMultiple(): """ Summary: EntityA and EntityB will be created in a level. Attached to both will be a Script Canvas component. @@ -113,4 +113,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(ScriptEvents_SendReceiveAcrossMultiple) + Report.start_test(ScriptEvents_HappyPath_SendReceiveAcrossMultiple) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index 24e8eeda11..a225ebd845 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -29,67 +29,67 @@ TEST_DIRECTORY = os.path.dirname(__file__) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(TestAutomationBase): - def test_Opening_Closing_Pane(self, request, workspace, editor, launcher_platform): - from . import Opening_Closing_Pane as test_module + def test_Pane_HappyPath_OpenCloseSuccessfully(self, request, workspace, editor, launcher_platform): + from . import Pane_HappyPath_OpenCloseSuccessfully as test_module self._run_test(request, workspace, editor, test_module) - def test_Docking_Pane(self, request, workspace, editor, launcher_platform): - from . import Docking_Pane as test_module + def test_Pane_HappyPath_DocksProperly(self, request, workspace, editor, launcher_platform): + from . import Pane_HappyPath_DocksProperly as test_module self._run_test(request, workspace, editor, test_module) - def test_Resizing_Pane(self, request, workspace, editor, launcher_platform): - from . import Resizing_Pane as test_module + def test_Pane_HappyPath_ResizesProperly(self, request, workspace, editor, launcher_platform): + from . import Pane_HappyPath_ResizesProperly as test_module self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptCanvas_TwoComponents(self, request, workspace, editor, launcher_platform, level): + def test_ScriptCanvas_TwoComponents_InteractSuccessfully(self, request, workspace, editor, launcher_platform, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptCanvas_TwoComponents as test_module + from . import ScriptCanvas_TwoComponents_InteractSuccessfully as test_module self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptCanvas_ChangingAssets(self, request, workspace, editor, launcher_platform, project, level): + def test_ScriptCanvas_ChangingAssets_ComponentStable(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptCanvas_ChangingAssets as test_module + from . import ScriptCanvas_ChangingAssets_ComponentStable as test_module self._run_test(request, workspace, editor, test_module) - def test_Graph_ZoomInZoomOut(self, request, workspace, editor, launcher_platform): - from . import Graph_ZoomInZoomOut as test_module + def test_Graph_HappyPath_ZoomInZoomOut(self, request, workspace, editor, launcher_platform): + from . import Graph_HappyPath_ZoomInZoomOut as test_module self._run_test(request, workspace, editor, test_module) - def test_NodePalette_SelectNode(self, request, workspace, editor, launcher_platform): - from . import NodePalette_SelectNode as test_module + def test_NodePalette_HappyPath_CanSelectNode(self, request, workspace, editor, launcher_platform): + from . import NodePalette_HappyPath_CanSelectNode as test_module self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): + def test_OnEntityActivatedDeactivated_HappyPath_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import OnEntityActivatedDeactivated_PrintMessage as test_module + from . import OnEntityActivatedDeactivated_HappyPath_PrintMessage as test_module self._run_test(request, workspace, editor, test_module) - - def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project): - from . import NodePalette_ClearSelection as test_module + + def test_NodePalette_HappyPath_ClearSelection(self, request, workspace, editor, launcher_platform, project): + from . import NodePalette_HappyPath_ClearSelection as test_module self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptCanvas_TwoEntities(self, request, workspace, editor, launcher_platform, project, level): + def test_ScriptCanvas_TwoEntities_UseSimultaneously(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptCanvas_TwoEntities as test_module + from . import ScriptCanvas_TwoEntities_UseSimultaneously as test_module self._run_test(request, workspace, editor, test_module) - def test_AssetEditor_CreateScriptEventFile(self, request, workspace, editor, launcher_platform, project): + def test_ScriptEvent_HappyPath_CreatedWithoutError(self, request, workspace, editor, launcher_platform, project): def teardown(): file_system.delete( [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True @@ -98,67 +98,67 @@ class TestAutomation(TestAutomationBase): file_system.delete( [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True ) - from . import AssetEditor_CreateScriptEventFile as test_module + from . import ScriptEvent_HappyPath_CreatedWithoutError as test_module self._run_test(request, workspace, editor, test_module) - def test_Toggle_ScriptCanvasTools(self, request, workspace, editor, launcher_platform): - from . import Toggle_ScriptCanvasTools as test_module + def test_ScriptCanvasTools_Toggle_OpenCloseSuccess(self, request, workspace, editor, launcher_platform): + from . import ScriptCanvasTools_Toggle_OpenCloseSuccess as test_module self._run_test(request, workspace, editor, test_module) - def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project): - from . import NodeInspector_RenameVariable as test_module + def test_NodeInspector_HappyPath_VariableRenames(self, request, workspace, editor, launcher_platform, project): + from . import NodeInspector_HappyPath_VariableRenames as test_module self._run_test(request, workspace, editor, test_module) - - def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): - from . import Debugging_TargetMultipleGraphs as test_module + + def test_Debugger_HappyPath_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): + from . import Debugger_HappyPath_TargetMultipleGraphs as test_module self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_Debugging_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level): + def test_Debugger_HappyPath_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import Debugging_TargetMultipleEntities as test_module + from . import Debugger_HappyPath_TargetMultipleEntities as test_module self._run_test(request, workspace, editor, test_module) - def test_EditMenu_UndoRedo(self, request, workspace, editor, launcher_platform, project): - from . import EditMenu_UndoRedo as test_module + def test_EditMenu_Default_UndoRedo(self, request, workspace, editor, launcher_platform, project): + from . import EditMenu_Default_UndoRedo as test_module self._run_test(request, workspace, editor, test_module) - def test_UnDockedPane_CloseSCWindow(self, request, workspace, editor, launcher_platform): - from . import UnDockedPane_CloseSCWindow as test_module + def test_Pane_Undocked_ClosesSuccessfully(self, request, workspace, editor, launcher_platform): + from . import Pane_Undocked_ClosesSuccessfully as test_module self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_Entity_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level): + def test_Entity_HappyPath_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import Entity_AddScriptCanvasComponent as test_module + from . import Entity_HappyPath_AddScriptCanvasComponent as test_module self._run_test(request, workspace, editor, test_module) - def test_Pane_RetainOnSCRestart(self, request, workspace, editor, launcher_platform): - from . import Pane_RetainOnSCRestart as test_module + def test_Pane_Default_RetainOnSCRestart(self, request, workspace, editor, launcher_platform): + from . import Pane_Default_RetainOnSCRestart as test_module self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptEvents_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level): + def test_ScriptEvents_HappyPath_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptEvents_SendReceiveAcrossMultiple as test_module + from . import ScriptEvents_HappyPath_SendReceiveAcrossMultiple as test_module self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptEvents_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level): + def test_ScriptEvents_Default_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptEvents_SendReceiveSuccessfully as test_module + from . import ScriptEvents_Default_SendReceiveSuccessfully as test_module self._run_test(request, workspace, editor, test_module) # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method @@ -171,16 +171,16 @@ class TestScriptCanvasTests(object): The following tests use hydra_test_utils.py to launch the editor and validate the results. """ - def test_FileMenu_New_Open(self, request, editor, launcher_platform): + def test_FileMenu_Default_NewAndOpen(self, request, editor, launcher_platform): expected_lines = [ "File->New action working as expected: True", "File->Open action working as expected: True", ] hydra.launch_and_validate_results( - request, TEST_DIRECTORY, editor, "FileMenu_New_Open.py", expected_lines, auto_test_mode=False, timeout=60, + request, TEST_DIRECTORY, editor, "FileMenu_Default_NewAndOpen.py", expected_lines, auto_test_mode=False, timeout=60, ) - def test_AssetEditor_NewScriptEvent(self, request, editor, launcher_platform): + def test_NewScriptEventButton_HappyPath_ContainsSCCategory(self, request, editor, launcher_platform): expected_lines = [ "New Script event action found: True", "Asset Editor opened: True", @@ -191,13 +191,13 @@ class TestScriptCanvasTests(object): request, TEST_DIRECTORY, editor, - "AssetEditor_NewScriptEvent.py", + "NewScriptEventButton_HappyPath_ContainsSCCategory.py", expected_lines, auto_test_mode=False, timeout=60, ) - def test_GraphClose_SavePrompt(self, request, editor, launcher_platform): + def test_GraphClose_Default_SavePrompt(self, request, editor, launcher_platform): expected_lines = [ "New graph created: True", "Save prompt opened as expected: True", @@ -207,13 +207,13 @@ class TestScriptCanvasTests(object): request, TEST_DIRECTORY, editor, - "GraphClose_SavePrompt.py", + "GraphClose_Default_SavePrompt.py", expected_lines, auto_test_mode=False, timeout=60, ) - def test_VariableManager_CreateDeleteVars(self, request, editor, launcher_platform): + def test_VariableManager_Default_CreateDeleteVars(self, request, editor, launcher_platform): var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"] expected_lines = [f"Success: {var_type} variable is created" for var_type in var_types] expected_lines.extend([f"Success: {var_type} variable is deleted" for var_type in var_types]) @@ -221,7 +221,7 @@ class TestScriptCanvasTests(object): request, TEST_DIRECTORY, editor, - "VariableManager_CreateDeleteVars.py", + "VariableManager_Default_CreateDeleteVars.py", expected_lines, auto_test_mode=False, timeout=60, diff --git a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_Default_CreateDeleteVars.py similarity index 97% rename from AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py rename to AutomatedTesting/Gem/PythonTests/scripting/VariableManager_Default_CreateDeleteVars.py index 8f7557c01e..e53939172e 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_Default_CreateDeleteVars.py @@ -10,7 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """ -def VariableManager_CreateDeleteVars(): +def VariableManager_Default_CreateDeleteVars(): """ Summary: Creating and deleting each type of variable in the Variable Manager pane @@ -111,4 +111,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(VariableManager_CreateDeleteVars) + Report.start_test(VariableManager_Default_CreateDeleteVars) From 85a25d3bc1ad282bb294e261a73529d4fc18c0da Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Fri, 7 May 2021 14:32:14 -0500 Subject: [PATCH 040/225] - Removing Debugger refreshes from DistanceBetweenFilter tests --- ...tweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py | 7 ------- ...istanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py | 6 ------ 2 files changed, 13 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py index 1ccfc43585..85a16056f5 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py @@ -82,15 +82,11 @@ class TestDistanceBetweenFilterComponentOverrides(EditorTestHelper): editor.EditorComponentAPIBus(bus.Broadcast, "SetComponentProperty", veg_system_settings_component, 'Configuration|Area System Settings|Sector Point Density', 16) - # Add a Vegetation Debugger component to allow area refreshes - hydra.add_level_component("Vegetation Debugger") - # 5) Add a Vegetation Distance Between Filter, toggle overrides on both the component and descriptor, # and verify initial instance counts are accurate spawner_entity.add_component("Vegetation Distance Between Filter") spawner_entity.get_set_test(3, "Configuration|Allow Per-Item Overrides", True) spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Override Enabled", True) - general.run_console('veg_debugClearAllAreas') self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 2), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 2), 5.0) and \ @@ -98,7 +94,6 @@ class TestDistanceBetweenFilterComponentOverrides(EditorTestHelper): # 6) Change Radius Min to 1.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 1.0) - general.run_console('veg_debugClearAllAreas') self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) and \ @@ -106,7 +101,6 @@ class TestDistanceBetweenFilterComponentOverrides(EditorTestHelper): # 7) Change Radius Min to 2.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 2.0) - general.run_console('veg_debugClearAllAreas') self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) and \ @@ -114,7 +108,6 @@ class TestDistanceBetweenFilterComponentOverrides(EditorTestHelper): # 8) Change Radius Min to 16.0, refresh, and verify instance counts are accurate, only a single instance should plant spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 16.0) - general.run_console('veg_debugClearAllAreas') num_expected_instances = 1 final_check_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected_instances), 5.0) self.test_success = final_check_success and self.test_success diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py index 09c5fd63cf..59fbca205f 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py @@ -80,9 +80,6 @@ class TestDistanceBetweenFilterComponent(EditorTestHelper): editor.EditorComponentAPIBus(bus.Broadcast, "SetComponentProperty", veg_system_settings_component, 'Configuration|Area System Settings|Sector Point Density', 16) - # Add a Vegetation Debugger component to allow area refreshes - hydra.add_level_component("Vegetation Debugger") - # 5) Add a Vegetation Distance Between Filter and verify initial instance counts are accurate spawner_entity.add_component("Vegetation Distance Between Filter") self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ @@ -92,7 +89,6 @@ class TestDistanceBetweenFilterComponent(EditorTestHelper): # 6) Change Radius Min to 1.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 1.0) - general.run_console('veg_debugClearAllAreas') self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) and \ @@ -100,7 +96,6 @@ class TestDistanceBetweenFilterComponent(EditorTestHelper): # 7) Change Radius Min to 2.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 2.0) - general.run_console('veg_debugClearAllAreas') self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) and \ @@ -108,7 +103,6 @@ class TestDistanceBetweenFilterComponent(EditorTestHelper): # 8) Change Radius Min to 16.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 16.0) - general.run_console('veg_debugClearAllAreas') num_expected_instances = 1 final_check_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected_instances), 5.0) self.test_success = final_check_success and self.test_success From eb8084d3f6c0e6973a8a250aeee9c231218c0691 Mon Sep 17 00:00:00 2001 From: srikappa Date: Fri, 7 May 2021 16:21:23 -0700 Subject: [PATCH 041/225] Initial draft for getting instantiation to work immediately after creation is undone --- .../PrefabEditorEntityOwnershipService.cpp | 4 +- .../Instance/InstanceToTemplatePropagator.cpp | 14 +++++- .../AzToolsFramework/Prefab/Link/Link.cpp | 3 ++ .../AzToolsFramework/Prefab/PrefabDomTypes.h | 1 + .../Prefab/PrefabPublicHandler.cpp | 47 +++++++++++++++---- .../Prefab/PrefabPublicHandler.h | 2 +- .../Prefab/PrefabSystemComponent.cpp | 6 +-- .../Prefab/PrefabSystemComponent.h | 2 +- .../Prefab/PrefabSystemComponentInterface.h | 2 +- .../AzToolsFramework/Prefab/PrefabUndo.cpp | 23 +++++---- .../AzToolsFramework/Prefab/PrefabUndo.h | 2 +- .../Prefab/PrefabUndoHelpers.cpp | 8 ++-- .../Prefab/PrefabUndoHelpers.h | 4 +- .../Tests/Prefab/PrefabUndoLinkTests.cpp | 4 +- 14 files changed, 88 insertions(+), 34 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 81233069a9..58aa245397 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -281,13 +281,15 @@ namespace AzToolsFramework containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent()); HandleEntitiesAdded({containerEntity}); HandleEntitiesAdded(entities); - + + /* // Update the template of the instance since we modified the entities of the instance by calling HandleEntitiesAdded. Prefab::PrefabDom serializedInstance; if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(addedInstance, serializedInstance)) { m_prefabSystemComponent->UpdatePrefabTemplate(addedInstance.GetTemplateId(), serializedInstance); } + */ return addedInstance; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp index b1c5f64ef9..d298e1e2b2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp @@ -176,10 +176,15 @@ namespace AzToolsFramework { PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId); + PrefabDomUtils::PrintPrefabDomValue("patch is ", providedPatch); + PrefabDomUtils::PrintPrefabDomValue("template dom before is ", templateDomReference); + //apply patch to template AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference, templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch); + PrefabDomUtils::PrintPrefabDomValue("template dom after is ", templateDomReference); + //trigger propagation if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success) { @@ -270,7 +275,7 @@ namespace AzToolsFramework return parentInstance; } - void InstanceToTemplatePropagator::AddPatchesToLink(PrefabDom& patches, Link& link) + void InstanceToTemplatePropagator::AddPatchesToLink(const PrefabDom& patches, Link& link) { PrefabDom& linkDom = link.GetLinkDom(); PrefabDomValueReference linkPatchesReference = @@ -279,7 +284,12 @@ namespace AzToolsFramework // This logic only covers addition of patches. If patches already exists, the given list of patches must be appended to them. if (!linkPatchesReference.has_value()) { - linkDom.AddMember(rapidjson::StringRef(PrefabDomUtils::PatchesName), patches, linkDom.GetAllocator()); + // If the original allocator the patches were created with gets destroyed, then the patches would become garbage in the + // linkDom. Since we cannot guarantee the lifecycle of the patch allocators, we are doing a copy of the patches here to + // associate them with the linkDom's allocator. This is a limitation with rapidjson. + PrefabDom patchesCopy; + patchesCopy.CopyFrom(patches, linkDom.GetAllocator()); + linkDom.AddMember(rapidjson::StringRef(PrefabDomUtils::PatchesName), patchesCopy, linkDom.GetAllocator()); } } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp index e0834ed53b..e421e55a11 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp @@ -181,6 +181,8 @@ namespace AzToolsFramework } else { + PrefabDomUtils::PrintPrefabDomValue("Patches are : ", m_linkDom); + PrefabDomUtils::PrintPrefabDomValue("Linked instance dom before is : ", linkedInstanceDom); AZ::JsonSerializationResult::ResultCode applyPatchResult = AZ::JsonSerialization::ApplyPatch( linkedInstanceDom, targetTemplatePrefabDom.GetAllocator(), @@ -193,6 +195,7 @@ namespace AzToolsFramework "Link::UpdateTarget - " "ApplyPatches failed for Prefab DOM from source Template '%u' and target Template '%u'.", m_sourceTemplateId, m_targetTemplateId); + PrefabDomUtils::PrintPrefabDomValue("Linked instance dom after is : ", linkedInstanceDom); return false; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomTypes.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomTypes.h index e32f817227..e897630a91 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomTypes.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomTypes.h @@ -27,6 +27,7 @@ namespace AzToolsFramework using PrefabDomList = AZStd::vector; using PrefabDomReference = AZStd::optional>; + using PrefabDomConstReference = AZStd::optional>; using PrefabDomValueReference = AZStd::optional>; using PrefabDomValueConstReference = AZStd::optional>; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 475510c52f..80e1b558e7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -122,6 +122,24 @@ namespace AzToolsFramework AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId(); + // Change top level entities to be parented to the container entity + // Mark them as dirty so this change is correctly applied to the template + for (AZ::Entity* topLevelEntity : entities) + { + //m_prefabUndoCache.UpdateCache(topLevelEntity->GetId()); + // undoBatch.MarkEntityDirty(topLevelEntity->GetId()); + AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); + //ToolsApplicationRequests::Bus::Broadcast( + // &ToolsApplicationRequests::Bus::Events::RemoveDirtyEntity, topLevelEntity->GetId()); + } + + // Update the template of the instance since we modified the entities of the instance by calling HandleEntitiesAdded. + Prefab::PrefabDom serializedInstance; + if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(instanceToCreate->get(), serializedInstance)) + { + m_prefabSystemComponentInterface->UpdatePrefabTemplate(instanceToCreate->get().GetTemplateId(), serializedInstance); + } + instanceToCreate->get().GetNestedInstances([&](AZStd::unique_ptr& nestedInstance) { AZ_Assert(nestedInstance, "Invalid nested instance found in the new prefab created."); EntityOptionalReference nestedInstanceContainerEntity = nestedInstance->GetContainerEntity(); @@ -129,7 +147,7 @@ namespace AzToolsFramework nestedInstanceContainerEntity, "Invalid container entity found for the nested instance used in prefab creation."); CreateLink( {&nestedInstanceContainerEntity->get()}, *nestedInstance, instanceToCreate->get().GetTemplateId(), - undoBatch.GetUndoBatch(), containerEntityId); + undoBatch.GetUndoBatch(), containerEntityId, false); }); CreateLink( @@ -141,10 +159,13 @@ namespace AzToolsFramework for (AZ::Entity* topLevelEntity : topLevelEntities) { m_prefabUndoCache.UpdateCache(topLevelEntity->GetId()); - undoBatch.MarkEntityDirty(topLevelEntity->GetId()); - AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); + //undoBatch.MarkEntityDirty(topLevelEntity->GetId()); + //AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); + ToolsApplicationRequests::Bus::Broadcast( + &ToolsApplicationRequests::Bus::Events::RemoveDirtyEntity, topLevelEntity->GetId()); } + // Select Container Entity { auto selectionUndo = aznew SelectionCommand({containerEntityId}, "Select Prefab Container Entity"); @@ -244,7 +265,7 @@ namespace AzToolsFramework void PrefabPublicHandler::CreateLink( const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId, - UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId) + UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool IsUndoRedoSupportNeeded) { AZ::EntityId containerEntityId = sourceInstance.GetContainerEntityId(); AZ::Entity* containerEntity = GetEntityById(containerEntityId); @@ -270,9 +291,19 @@ namespace AzToolsFramework m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter); m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId); - LinkId linkId = PrefabUndoHelpers::CreateLink( - sourceInstance.GetTemplateId(), targetTemplateId, patch, sourceInstance.GetInstanceAlias(), - undoBatch); + LinkId linkId; + if (IsUndoRedoSupportNeeded) + { + linkId = PrefabUndoHelpers::CreateLink( + sourceInstance.GetTemplateId(), targetTemplateId, AZStd::move(patch), sourceInstance.GetInstanceAlias(), undoBatch); + } + else + { + linkId = m_prefabSystemComponentInterface->CreateLink( + targetTemplateId, sourceInstance.GetTemplateId(), sourceInstance.GetInstanceAlias(), AZStd::move(patch), + InvalidLinkId); + m_prefabSystemComponentInterface->PropagateTemplateChanges(targetTemplateId); + } sourceInstance.SetLinkId(linkId); @@ -305,7 +336,7 @@ namespace AzToolsFramework patchesCopyForUndoSupport.CopyFrom(nestedInstanceLinkPatches->get(), patchesCopyForUndoSupport.GetAllocator()); PrefabUndoHelpers::RemoveLink( sourceInstance->GetTemplateId(), targetTemplateId, sourceInstance->GetInstanceAlias(), sourceInstance->GetLinkId(), - patchesCopyForUndoSupport, undoBatch); + AZStd::move(patchesCopyForUndoSupport), undoBatch); } PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 5ade666a40..0e15fd9a15 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -80,7 +80,7 @@ namespace AzToolsFramework */ void CreateLink( const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId, - UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId); + UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool IsUndoRedoSupportNeeded = true); /** * Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index c6a95b01fe..0b447ef786 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -583,7 +583,7 @@ namespace AzToolsFramework const TemplateId& linkTargetId, const TemplateId& linkSourceId, const InstanceAlias& instanceAlias, - const PrefabDomReference linkPatch, + PrefabDom linkPatch, const LinkId& linkId) { if (linkTargetId == InvalidTemplateId) @@ -667,9 +667,9 @@ namespace AzToolsFramework rapidjson::StringRef(PrefabDomUtils::SourceName), rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()), newLink.GetLinkDom().GetAllocator()); - if (linkPatch && linkPatch->get().IsArray() && !(linkPatch->get().Empty())) + if (linkPatch.IsArray() && !(linkPatch.Empty())) { - m_instanceToTemplatePropagator.AddPatchesToLink(linkPatch.value(), newLink); + m_instanceToTemplatePropagator.AddPatchesToLink(AZStd::move(linkPatch), newLink); } //update the target template dom to have the proper values for the source template dom diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h index 30d03ba2ef..b5f499296d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h @@ -156,7 +156,7 @@ namespace AzToolsFramework const TemplateId& linkTargetId, const TemplateId& linkSourceId, const InstanceAlias& instanceAlias, - const PrefabDomReference linkPatch, + PrefabDom linkPatch, const LinkId& linkId = InvalidLinkId) override; /** diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h index 6491d67401..347b48a648 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h @@ -44,7 +44,7 @@ namespace AzToolsFramework //creates a new Link virtual LinkId CreateLink(const TemplateId& linkTargetId, const TemplateId& linkSourceId, - const InstanceAlias& instanceAlias, const PrefabDomReference linkPatch, + const InstanceAlias& instanceAlias, PrefabDom linkPatch, const LinkId& linkId = InvalidLinkId) = 0; virtual void RemoveLink(const LinkId& linkId) = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp index ad0cdc166a..e82e9da90a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp @@ -124,7 +124,7 @@ namespace AzToolsFramework const TemplateId& targetId, const TemplateId& sourceId, const InstanceAlias& instanceAlias, - PrefabDomReference linkPatches, + PrefabDom linkPatches, const LinkId linkId) { m_targetId = targetId; @@ -132,10 +132,7 @@ namespace AzToolsFramework m_instanceAlias = instanceAlias; m_linkId = linkId; - if (linkPatches.has_value()) - { - m_linkPatches = AZStd::move(linkPatches->get()); - } + m_linkPatches = AZStd::move(linkPatches); //if linkId is invalid, set as ADD if (m_linkId == InvalidLinkId) @@ -193,7 +190,9 @@ namespace AzToolsFramework void PrefabUndoInstanceLink::AddLink() { - m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkPatches, m_linkId); + PrefabDom linkPatchesCopy; + linkPatchesCopy.CopyFrom(m_linkPatches, linkPatchesCopy.GetAllocator()); + m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, AZStd::move(linkPatchesCopy), m_linkId); } void PrefabUndoInstanceLink::RemoveLink() @@ -228,9 +227,12 @@ namespace AzToolsFramework if (link.has_value()) { - m_linkDomPrevious = AZStd::move(link->get().GetLinkDom()); + m_linkDomPrevious.CopyFrom(link->get().GetLinkDom(), m_linkDomPrevious.GetAllocator()); } + PrefabDomUtils::PrintPrefabDomValue("m_linkDomPrevious is : ", m_linkDomPrevious); + PrefabDomUtils::PrintPrefabDomValue("link->get().GetLinkDom() is : ", link->get().GetLinkDom()); + //get source templateDom TemplateReference sourceTemplate = m_prefabSystemComponentInterface->FindTemplate(link->get().GetSourceTemplateId()); @@ -275,7 +277,7 @@ namespace AzToolsFramework if (patchesIter == m_linkDomNext.MemberEnd()) { m_linkDomNext.AddMember( - rapidjson::GenericStringRef(PrefabDomUtils::PatchesName), patchLinkCopy, m_linkDomNext.GetAllocator()); + rapidjson::GenericStringRef(PrefabDomUtils::PatchesName), AZStd::move(patchLinkCopy), m_linkDomNext.GetAllocator()); } else { @@ -303,9 +305,14 @@ namespace AzToolsFramework return; } + /* PrefabDom moveLink; moveLink.CopyFrom(linkDom, linkDom.GetAllocator()); link->get().GetLinkDom() = AZStd::move(moveLink); + */ + link->get().SetLinkDom(linkDom); + + PrefabDomUtils::PrintPrefabDomValue("dom after updating link is : ", link->get().GetLinkDom()); //propagate the link changes link->get().UpdateTarget(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.h index 49bae4eda0..33d9e5ad33 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.h @@ -101,7 +101,7 @@ namespace AzToolsFramework const TemplateId& targetId, const TemplateId& sourceId, const InstanceAlias& instanceAlias, - PrefabDomReference linkPatches = PrefabDomReference(), + PrefabDom linkPatches = PrefabDom(), const LinkId linkId = InvalidLinkId); void Undo() override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp index 24eb71e055..5ba8d3c940 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp @@ -34,11 +34,11 @@ namespace AzToolsFramework } LinkId CreateLink( - TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch, + TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDom patch, const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch) { auto linkAddUndo = aznew PrefabUndoInstanceLink("Create Link"); - linkAddUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, patch, InvalidLinkId); + linkAddUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, AZStd::move(patch), InvalidLinkId); linkAddUndo->SetParent(undoBatch); linkAddUndo->Redo(); @@ -47,10 +47,10 @@ namespace AzToolsFramework void RemoveLink( TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId, - PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch) + PrefabDom linkPatches, UndoSystem::URSequencePoint* undoBatch) { auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link"); - linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, linkPatches, linkId); + linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, AZStd::move(linkPatches), linkId); linkRemoveUndo->SetParent(undoBatch); linkRemoveUndo->Redo(); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.h index 6429df3b04..17cf7f52c1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.h @@ -22,11 +22,11 @@ namespace AzToolsFramework const Instance& instance, AZStd::string_view undoMessage, const PrefabDom& instanceDomBeforeUpdate, UndoSystem::URSequencePoint* undoBatch); LinkId CreateLink( - TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch, + TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDom patch, const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch); void RemoveLink( TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId, - PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch); + PrefabDom linkPatches, UndoSystem::URSequencePoint* undoBatch); } } // namespace Prefab } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp index 2122b116d8..3d540a7a95 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp @@ -120,7 +120,7 @@ namespace UnitTest //create an undo node to apply the patch and prep for undo PrefabUndoInstanceLink undoInstanceLinkNode("Undo Link Patch"); - undoInstanceLinkNode.Capture(rootTemplateId, nestedTemplateId, aliases[0], patch, InvalidLinkId); + undoInstanceLinkNode.Capture(rootTemplateId, nestedTemplateId, aliases[0], AZStd::move(patch), InvalidLinkId); undoInstanceLinkNode.Redo(); m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue(); @@ -196,7 +196,7 @@ namespace UnitTest //create an undo node to apply the patch and prep for undo PrefabUndoInstanceLink undoInstanceLinkNode("Undo Link Patch"); - undoInstanceLinkNode.Capture(rootTemplateId, nestedTemplateId, aliases[0], linkPatch, InvalidLinkId); + undoInstanceLinkNode.Capture(rootTemplateId, nestedTemplateId, aliases[0], AZStd::move(linkPatch), InvalidLinkId); undoInstanceLinkNode.Redo(); m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue(); From 1c04160966bf3d358f07192ec81cf2247d26e1e3 Mon Sep 17 00:00:00 2001 From: srikappa Date: Fri, 7 May 2021 16:23:14 -0700 Subject: [PATCH 042/225] Added a missing header --- .../Prefab/Instance/InstanceToTemplatePropagator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h index ca1f3a7c91..9a6aad8ac1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h @@ -41,7 +41,7 @@ namespace AzToolsFramework void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) override; - void AddPatchesToLink(PrefabDom& patches, Link& link); + void AddPatchesToLink(const PrefabDom& patches, Link& link); private: From e9165ed91116d98b507e050e99902a1510e59fb7 Mon Sep 17 00:00:00 2001 From: guthadam Date: Fri, 7 May 2021 20:16:05 -0500 Subject: [PATCH 043/225] Added save state keys to most of the RPEs in the material editor and component to save expand/collapse state Saving main window fancy docking state so all of the dock widgets save/restore visibly and positioning Added window decoration wrapper inside material editor main window for saving/restoring window position, size, state Added object names to several QT widgets so that their state could be captured and restored --- .../Inspector/InspectorPropertyGroupWidget.h | 1 + .../InspectorPropertyGroupWidget.cpp | 2 + .../Window/MaterialEditorWindowSettings.h | 5 +- .../Source/Window/MaterialEditorWindow.cpp | 117 +++++++++++------- .../Window/MaterialEditorWindowComponent.cpp | 1 - .../Window/MaterialEditorWindowSettings.cpp | 17 +-- .../MaterialInspector/MaterialInspector.cpp | 18 ++- .../MaterialInspector/MaterialInspector.h | 1 + .../ViewportSettingsInspector.cpp | 10 +- .../EditorMaterialComponentInspector.cpp | 12 +- 10 files changed, 111 insertions(+), 73 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h index 71ca975f58..60eae524a5 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h @@ -44,6 +44,7 @@ namespace AtomToolsFramework const AZ::Uuid& instanceClassId, AzToolsFramework::IPropertyEditorNotify* instanceNotificationHandler = {}, QWidget* parent = {}, + const AZ::u32 saveStateKey = {}, const AzToolsFramework::InstanceDataHierarchy::ValueComparisonFunction& valueComparisonFunction = {}); void Refresh() override; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorPropertyGroupWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorPropertyGroupWidget.cpp index c4d78d1acb..b850b4a488 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorPropertyGroupWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorPropertyGroupWidget.cpp @@ -22,6 +22,7 @@ namespace AtomToolsFramework const AZ::Uuid& instanceClassId, AzToolsFramework::IPropertyEditorNotify* instanceNotificationHandler, QWidget* parent, + const AZ::u32 saveStateKey, const AzToolsFramework::InstanceDataHierarchy::ValueComparisonFunction& valueComparisonFunction) : InspectorGroupWidget(parent) { @@ -37,6 +38,7 @@ namespace AtomToolsFramework m_propertyEditor->SetHideRootProperties(true); m_propertyEditor->SetAutoResizeLabels(true); m_propertyEditor->SetValueComparisonFunction(valueComparisonFunction); + m_propertyEditor->SetSavedStateKey(saveStateKey); m_propertyEditor->Setup(context, instanceNotificationHandler, false); m_propertyEditor->AddInstance(instance, instanceClassId, nullptr, instanceToCompare); m_propertyEditor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h index bf572b070a..b28d4d662b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h @@ -29,9 +29,6 @@ namespace MaterialEditor static void Reflect(AZ::ReflectContext* context); - bool m_enableGrid = true; - bool m_enableShadowCatcher = true; - bool m_enableAlternateSkybox = false; - float m_fieldOfView = 90.0f; + AZStd::vector m_mainWindowState; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index 12e75f8fcf..e62dae2986 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -10,46 +10,50 @@ * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - #include - #include #include #include #include #include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + #include -#include -#include -#include +#include #include #include +#include #include +#include #include -#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT +#include +#include #include -#include +#include #include -#include #include +#include +#include AZ_POP_DISABLE_WARNING namespace MaterialEditor @@ -57,6 +61,15 @@ namespace MaterialEditor MaterialEditorWindow::MaterialEditorWindow(QWidget* parent /* = 0 */) : AzQtComponents::DockMainWindow(parent) { + resize(1280, 1024); + + // Among other things, we need the window wrapper to save the main window size, position, and state + auto mainWindowWrapper = + new AzQtComponents::WindowDecorationWrapper(AzQtComponents::WindowDecorationWrapper::OptionAutoTitleBarButtons); + mainWindowWrapper->setGuest(this); + mainWindowWrapper->enableSaveRestoreGeometry("amazon", "MaterialEditor", "mainWindowGeometry"); + + // set the style sheet for RPE highlighting and other styling AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral(":/MaterialEditor.qss")); QApplication::setWindowIcon(QIcon(":/Icons/materialtype.svg")); @@ -75,6 +88,7 @@ namespace MaterialEditor m_advancedDockManager = new AzQtComponents::FancyDocking(this); + setObjectName("MaterialEditorWindow"); setDockNestingEnabled(true); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); @@ -82,17 +96,21 @@ namespace MaterialEditor setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); m_menuBar = new QMenuBar(this); + m_menuBar->setObjectName("MenuBar"); setMenuBar(m_menuBar); m_toolBar = new MaterialEditorToolBar(this); + m_toolBar->setObjectName("ToolBar"); addToolBar(m_toolBar); m_centralWidget = new QWidget(this); m_tabWidget = new AzQtComponents::TabWidget(m_centralWidget); + m_tabWidget->setObjectName("TabWidget"); m_tabWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); m_tabWidget->setContentsMargins(0, 0, 0, 0); m_materialViewport = new MaterialViewportWidget(m_centralWidget); + m_materialViewport->setObjectName("Viewport"); m_materialViewport->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); QVBoxLayout* vl = new QVBoxLayout(m_centralWidget); @@ -104,7 +122,8 @@ namespace MaterialEditor setCentralWidget(m_centralWidget); m_statusBar = new StatusBarWidget(this); - this->statusBar()->addPermanentWidget(m_statusBar, 1); + m_statusBar->setObjectName("StatusBar"); + statusBar()->addPermanentWidget(m_statusBar, 1); SetupMenu(); SetupTabs(); @@ -119,27 +138,26 @@ namespace MaterialEditor SetDockWidgetVisible("Performance Monitor", false); SetDockWidgetVisible("Python Terminal", false); + // Restore geometry and show the window + mainWindowWrapper->showFromSettings(); + + // Restore additional state for docked windows + auto windowSettings = AZ::UserSettings::CreateFind( + AZ::Crc32("MaterialEditorwindowSettings"), AZ::UserSettings::CT_GLOBAL); + + if (!windowSettings->m_mainWindowState.empty()) + { + QByteArray windowState(windowSettings->m_mainWindowState.data(), windowSettings->m_mainWindowState.size()); + m_advancedDockManager->restoreState(windowState); + } + MaterialEditorWindowRequestBus::Handler::BusConnect(); MaterialDocumentNotificationBus::Handler::BusConnect(); OnDocumentOpened(AZ::Uuid::CreateNull()); - - auto windowState = AZ::UserSettings::Find( - AZ::Crc32("MaterialEditorWindowState"), AZ::UserSettings::CT_GLOBAL); - if (windowState) - { - windowState->RestoreGeometry(this); - } } MaterialEditorWindow::~MaterialEditorWindow() { - auto windowState = AZ::UserSettings::CreateFind( - AZ::Crc32("MaterialEditorWindowState"), AZ::UserSettings::CT_GLOBAL); - if (windowState) - { - windowState->CaptureGeometry(this); - } - MaterialDocumentNotificationBus::Handler::BusDisconnect(); MaterialEditorWindowRequestBus::Handler::BusDisconnect(); } @@ -159,8 +177,9 @@ namespace MaterialEditor } auto dockWidget = new AzQtComponents::StyledDockWidget(name.c_str()); - dockWidget->setObjectName(name.c_str()); + dockWidget->setObjectName(QString("%1_DockWidget").arg(name.c_str())); dockWidget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable); + widget->setObjectName(name.c_str()); widget->setParent(dockWidget); widget->setMinimumSize(QSize(300, 300)); dockWidget->setWidget(widget); @@ -218,15 +237,16 @@ namespace MaterialEditor QSize requestedWindowSize = size() + offset; resize(requestedWindowSize); - AZ_Assert(m_materialViewport->size() == requestedViewportSize, + AZ_Assert( + m_materialViewport->size() == requestedViewportSize, "Resizing the window did not give the expected viewport size. Requested %d x %d but got %d x %d.", - requestedViewportSize.width(), requestedViewportSize.height(), - m_materialViewport->size().width(), m_materialViewport->size().height()); + requestedViewportSize.width(), requestedViewportSize.height(), m_materialViewport->size().width(), + m_materialViewport->size().height()); QSize newDeviceSize = m_materialViewport->size(); - AZ_Warning("Material Editor", newDeviceSize.width() == width && newDeviceSize.height() == height, - "Resizing the window did not give the expected frame size. Requested %d x %d but got %d x %d.", - width, height, + AZ_Warning( + "Material Editor", newDeviceSize.width() == width && newDeviceSize.height() == height, + "Resizing the window did not give the expected frame size. Requested %d x %d but got %d x %d.", width, height, newDeviceSize.width(), newDeviceSize.height()); } @@ -250,6 +270,13 @@ namespace MaterialEditor return; } + // Capture docking state before shutdown + auto windowSettings = AZ::UserSettings::CreateFind( + AZ::Crc32("MaterialEditorwindowSettings"), AZ::UserSettings::CT_GLOBAL); + + QByteArray windowState = m_advancedDockManager->saveState(); + windowSettings->m_mainWindowState.assign(windowState.begin(), windowState.end()); + MaterialEditorWindowNotificationBus::Broadcast(&MaterialEditorWindowNotifications::OnMaterialEditorWindowClosing); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp index 3d796a21ad..b0e8533ba4 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowComponent.cpp @@ -101,7 +101,6 @@ namespace MaterialEditor m_materialEditorBrowserInteractions.reset(aznew MaterialEditorBrowserInteractions); m_window.reset(aznew MaterialEditorWindow); - m_window->show(); } void MaterialEditorWindowComponent::DestroyMaterialEditorWindow() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp index a9c928df10..5ea23de8c6 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp @@ -22,11 +22,8 @@ namespace MaterialEditor { serializeContext->Class() ->Version(1) - ->Field("enableGrid", &MaterialEditorWindowSettings::m_enableGrid) - ->Field("enableShadowCatcher", &MaterialEditorWindowSettings::m_enableShadowCatcher) - ->Field("enableAlternateSkybox", &MaterialEditorWindowSettings::m_enableAlternateSkybox) - ->Field("fieldOfView", &MaterialEditorWindowSettings::m_fieldOfView) - ; + ->Field("mainWindowState", &MaterialEditorWindowSettings::m_mainWindowState) + ; if (auto editContext = serializeContext->GetEditContext()) { @@ -34,12 +31,6 @@ namespace MaterialEditor "MaterialEditorWindowSettings", "") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableGrid, "Enable Grid", "") - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableShadowCatcher, "Enable Shadow Catcher", "") - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialEditorWindowSettings::m_enableAlternateSkybox, "Enable Alternate Skybox", "") - ->DataElement(AZ::Edit::UIHandlers::Slider, &MaterialEditorWindowSettings::m_fieldOfView, "Field Of View", "") - ->Attribute(AZ::Edit::Attributes::Min, 60.0f) - ->Attribute(AZ::Edit::Attributes::Max, 120.0f) ; } } @@ -52,10 +43,6 @@ namespace MaterialEditor ->Attribute(AZ::Script::Attributes::Module, "render") ->Constructor() ->Constructor() - ->Property("enableGrid", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableGrid)) - ->Property("enableShadowCatcher", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableShadowCatcher)) - ->Property("enableAlternateSkybox", BehaviorValueProperty(&MaterialEditorWindowSettings::m_enableAlternateSkybox)) - ->Property("fieldOfView", BehaviorValueProperty(&MaterialEditorWindowSettings::m_fieldOfView)) ; } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp index b066c3c7dd..dffbd43702 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp @@ -39,6 +39,7 @@ namespace MaterialEditor void MaterialInspector::Reset() { + m_documentPath.clear(); m_documentId = AZ::Uuid::CreateNull(); m_groups = {}; @@ -55,6 +56,8 @@ namespace MaterialEditor bool isOpen = false; MaterialDocumentRequestBus::EventResult(isOpen, m_documentId, &MaterialDocumentRequestBus::Events::IsOpen); + MaterialDocumentRequestBus::EventResult(m_documentPath, m_documentId, &MaterialDocumentRequestBus::Events::GetAbsolutePath); + if (!m_documentId.IsNull() && isOpen) { // Create the top group for displaying details about the material @@ -89,7 +92,10 @@ namespace MaterialEditor group.m_properties.push_back(property); // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey( + AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); @@ -121,7 +127,10 @@ namespace MaterialEditor } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey( + AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); @@ -156,7 +165,10 @@ namespace MaterialEditor } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey( + AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h index efe979e5ea..a7a4dddbaa 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h @@ -64,6 +64,7 @@ namespace MaterialEditor const AtomToolsFramework::DynamicProperty* m_activeProperty = nullptr; AZ::Uuid m_documentId = AZ::Uuid::CreateNull(); + AZStd::string m_documentPath; AZStd::unordered_map m_groups; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp index 22e752dddd..384644f79c 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp @@ -58,9 +58,11 @@ namespace MaterialEditor const AZStd::string groupDisplayName = "General"; const AZStd::string groupDescription = "General"; + const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::GeneralGroup")); AddGroup( groupNameId, groupDisplayName, groupDescription, - new AtomToolsFramework::InspectorPropertyGroupWidget(m_viewportSettings.get(), nullptr, m_viewportSettings->TYPEINFO_Uuid(), this)); + new AtomToolsFramework::InspectorPropertyGroupWidget( + m_viewportSettings.get(), nullptr, m_viewportSettings->TYPEINFO_Uuid(), this, this, saveStateKey)); } void ViewportSettingsInspector::AddModelGroup() @@ -92,8 +94,9 @@ namespace MaterialEditor if (m_modelPreset) { + const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::ModelGroup")); auto inspectorWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - m_modelPreset.get(), nullptr, m_modelPreset.get()->TYPEINFO_Uuid(), this, groupWidget); + m_modelPreset.get(), nullptr, m_modelPreset.get()->TYPEINFO_Uuid(), this, groupWidget, saveStateKey); groupWidget->layout()->addWidget(inspectorWidget); } @@ -179,8 +182,9 @@ namespace MaterialEditor if (m_lightingPreset) { + const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::LightingGroup")); auto inspectorWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - m_lightingPreset.get(), nullptr, m_lightingPreset.get()->TYPEINFO_Uuid(), this, groupWidget); + m_lightingPreset.get(), nullptr, m_lightingPreset.get()->TYPEINFO_Uuid(), this, groupWidget, saveStateKey); groupWidget->layout()->addWidget(inspectorWidget); } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp index 03533e142f..1ae0610169 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp @@ -213,7 +213,11 @@ namespace AZ } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey(AZStd::string::format( + "MaterialPropertyInspector::PropertyGroup::%s::%s", m_materialAssetId.ToString().c_str(), + groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); @@ -262,7 +266,11 @@ namespace AZ } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(&group, &group, group.TYPEINFO_Uuid(), this, this, + const AZ::Crc32 saveStateKey(AZStd::string::format( + "MaterialPropertyInspector::PropertyGroup::%s::%s", m_materialAssetId.ToString().c_str(), + groupDisplayName.c_str())); + auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( + &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { AZ_UNUSED(source); const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); From 1dda6dabe4db1f1b166b3fe0e656f15915efc2d9 Mon Sep 17 00:00:00 2001 From: guthadam Date: Sat, 8 May 2021 00:57:16 -0500 Subject: [PATCH 044/225] Added support for expanding/collapsing material inspector groups by name Saving/restoring material inspector group expansion state --- .../Inspector/InspectorGroupHeaderWidget.h | 4 +- .../Inspector/InspectorRequestBus.h | 9 ++ .../Inspector/InspectorWidget.h | 15 ++- .../Inspector/InspectorGroupHeaderWidget.cpp | 17 ++- .../Code/Source/Inspector/InspectorWidget.cpp | 102 +++++++++++++----- .../Window/MaterialEditorWindowSettings.h | 1 + .../Source/Window/MaterialEditorWindow.cpp | 4 +- .../Window/MaterialEditorWindowSettings.cpp | 1 + .../MaterialInspector/MaterialInspector.cpp | 68 +++++++----- .../MaterialInspector/MaterialInspector.h | 10 ++ .../EditorMaterialComponentInspector.cpp | 4 +- 11 files changed, 169 insertions(+), 66 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorGroupHeaderWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorGroupHeaderWidget.h index bba299187b..931f88d0eb 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorGroupHeaderWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorGroupHeaderWidget.h @@ -29,11 +29,13 @@ namespace AtomToolsFramework AZ_CLASS_ALLOCATOR(InspectorGroupHeaderWidget, AZ::SystemAllocator, 0); explicit InspectorGroupHeaderWidget(QWidget* parent = nullptr); - void SetExpanded(bool expanded); + void SetExpanded(bool expand); bool IsExpanded() const; Q_SIGNALS: void clicked(QMouseEvent* event); + void expanded(); + void collapsed(); protected: void mousePressEvent(QMouseEvent* event) override; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorRequestBus.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorRequestBus.h index 81b512faf2..e76837137a 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorRequestBus.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorRequestBus.h @@ -56,6 +56,15 @@ namespace AtomToolsFramework //! Calls Rebuild for all InspectorGroupWidget, allowing for destructive UI changes virtual void RebuildAll() = 0; + //! Expands a specific group + virtual void ExpandGroup(const AZStd::string& groupNameId) = 0; + + //! Collapses a specific group + virtual void CollapseGroup(const AZStd::string& groupNameId) = 0; + + //! Checks the expansion state of a specific group + virtual bool IsGroupExpanded(const AZStd::string& groupNameId) const = 0; + //! Expands all groups and headers virtual void ExpandAll() = 0; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorWidget.h index b0932b3b04..5fb0b731d6 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Inspector/InspectorWidget.h @@ -63,15 +63,22 @@ namespace AtomToolsFramework void RefreshAll() override; void RebuildAll() override; + void ExpandGroup(const AZStd::string& groupNameId) override; + void CollapseGroup(const AZStd::string& groupNameId) override; + bool IsGroupExpanded(const AZStd::string& groupNameId) const override; + void ExpandAll() override; void CollapseAll() override; - private: - void OnHeaderClicked(QMouseEvent* event, InspectorGroupHeaderWidget* groupHeader, QWidget* groupWidget); + protected: + virtual bool ShouldGroupAutoExpanded(const AZStd::string& groupNameId) const; + virtual void OnGroupExpanded(const AZStd::string& groupNameId); + virtual void OnGroupCollapsed(const AZStd::string& groupNameId); + virtual void OnHeaderClicked(const AZStd::string& groupNameId, QMouseEvent* event); + private: QVBoxLayout* m_layout = nullptr; QScopedPointer m_ui; - AZStd::vector m_headers; - AZStd::vector m_groups; + AZStd::unordered_map> m_groups; }; } // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorGroupHeaderWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorGroupHeaderWidget.cpp index 41cc1e4a50..666f8f6c93 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorGroupHeaderWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorGroupHeaderWidget.cpp @@ -33,10 +33,21 @@ namespace AtomToolsFramework setMargin(0); } - void InspectorGroupHeaderWidget::SetExpanded(bool expanded) + void InspectorGroupHeaderWidget::SetExpanded(bool expand) { - m_expanded = expanded; - update(); + if (m_expanded != expand) + { + m_expanded = expand; + if (m_expanded) + { + emit expanded(); + } + else + { + emit collapsed(); + } + update(); + } } bool InspectorGroupHeaderWidget::IsExpanded() const diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorWidget.cpp index ec5f9893bd..0259120d9b 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Inspector/InspectorWidget.cpp @@ -39,7 +39,6 @@ namespace AtomToolsFramework m_layout = new QVBoxLayout(m_ui->m_propertyContent); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setSpacing(0); - m_headers.clear(); m_groups.clear(); } @@ -70,16 +69,27 @@ namespace AtomToolsFramework groupHeader->setText(groupDisplayName.c_str()); groupHeader->setToolTip(groupDescription.c_str()); m_layout->addWidget(groupHeader); - m_headers.push_back(groupHeader); groupWidget->setObjectName(groupNameId.c_str()); groupWidget->setParent(m_ui->m_propertyContent); m_layout->addWidget(groupWidget); - m_groups.push_back(groupWidget); - connect(groupHeader, &InspectorGroupHeaderWidget::clicked, this, [this, groupHeader, groupWidget](QMouseEvent* event) { - OnHeaderClicked(event, groupHeader, groupWidget); + m_groups[groupNameId] = AZStd::make_pair(groupHeader, groupWidget); + + connect(groupHeader, &InspectorGroupHeaderWidget::clicked, this, [this, groupNameId](QMouseEvent* event) { + OnHeaderClicked(groupNameId, event); }); + connect(groupHeader, &InspectorGroupHeaderWidget::expanded, this, [this, groupNameId]() { OnGroupExpanded(groupNameId); }); + connect(groupHeader, &InspectorGroupHeaderWidget::collapsed, this, [this, groupNameId]() { OnGroupCollapsed(groupNameId); }); + + if (ShouldGroupAutoExpanded(groupNameId)) + { + ExpandGroup(groupNameId); + } + else + { + CollapseGroup(groupNameId); + } } void InspectorWidget::RefreshGroup(const AZStd::string& groupNameId) @@ -114,50 +124,86 @@ namespace AtomToolsFramework } } + void InspectorWidget::ExpandGroup(const AZStd::string& groupNameId) + { + auto groupItr = m_groups.find(groupNameId); + if (groupItr != m_groups.end()) + { + groupItr->second.first->SetExpanded(true); + groupItr->second.second->setVisible(true); + } + } + + void InspectorWidget::CollapseGroup(const AZStd::string& groupNameId) + { + auto groupItr = m_groups.find(groupNameId); + if (groupItr != m_groups.end()) + { + groupItr->second.first->SetExpanded(false); + groupItr->second.second->setVisible(false); + } + } + + bool InspectorWidget::IsGroupExpanded(const AZStd::string& groupNameId) const + { + auto groupItr = m_groups.find(groupNameId); + return groupItr != m_groups.end() ? groupItr->second.first->IsExpanded() : false; + } + void InspectorWidget::ExpandAll() { - for (auto headerWidget : m_headers) + for (auto& groupPair : m_groups) { - headerWidget->SetExpanded(true); - } - for (auto groupWidget : m_groups) - { - groupWidget->setVisible(true); + groupPair.second.first->SetExpanded(true); + groupPair.second.second->setVisible(true); } } void InspectorWidget::CollapseAll() { - for (auto headerWidget : m_headers) + for (auto& groupPair : m_groups) { - headerWidget->SetExpanded(false); - } - for (auto groupWidget : m_groups) - { - groupWidget->setVisible(false); + groupPair.second.first->SetExpanded(false); + groupPair.second.second->setVisible(false); } } - void InspectorWidget::OnHeaderClicked(QMouseEvent* event, InspectorGroupHeaderWidget* groupHeader, QWidget* groupWidget) + bool InspectorWidget::ShouldGroupAutoExpanded(const AZStd::string& groupNameId) const + { + AZ_UNUSED(groupNameId); + return true; + } + + void InspectorWidget::OnGroupExpanded(const AZStd::string& groupNameId) + { + AZ_UNUSED(groupNameId); + } + + void InspectorWidget::OnGroupCollapsed(const AZStd::string& groupNameId) + { + AZ_UNUSED(groupNameId); + } + + void InspectorWidget::OnHeaderClicked(const AZStd::string& groupNameId, QMouseEvent* event) { if (event->button() == Qt::MouseButton::LeftButton) { - groupHeader->SetExpanded(!groupHeader->IsExpanded()); - groupWidget->setVisible(groupHeader->IsExpanded()); + if (!IsGroupExpanded(groupNameId)) + { + ExpandGroup(groupNameId); + } + else + { + CollapseGroup(groupNameId); + } return; } if (event->button() == Qt::MouseButton::RightButton) { QMenu menu; - menu.addAction("Expand", [groupHeader, groupWidget]() { - groupHeader->SetExpanded(true); - groupWidget->setVisible(true); - })->setEnabled(!groupHeader->IsExpanded()); - menu.addAction("Collapse", [groupHeader, groupWidget]() { - groupHeader->SetExpanded(false); - groupWidget->setVisible(false); - })->setEnabled(groupHeader->IsExpanded()); + menu.addAction("Expand", [this, groupNameId]() { ExpandGroup(groupNameId); })->setEnabled(!IsGroupExpanded(groupNameId)); + menu.addAction("Collapse", [this, groupNameId]() { CollapseGroup(groupNameId); })->setEnabled(IsGroupExpanded(groupNameId)); menu.addAction("Expand All", [this]() { ExpandAll(); }); menu.addAction("Collapse All", [this]() { CollapseAll(); }); menu.exec(event->globalPos()); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h index b28d4d662b..9ff03038f7 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Window/MaterialEditorWindowSettings.h @@ -30,5 +30,6 @@ namespace MaterialEditor static void Reflect(AZ::ReflectContext* context); AZStd::vector m_mainWindowState; + AZStd::unordered_set m_inspectorCollapsedGroups; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index e62dae2986..075a58c532 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -143,7 +143,7 @@ namespace MaterialEditor // Restore additional state for docked windows auto windowSettings = AZ::UserSettings::CreateFind( - AZ::Crc32("MaterialEditorwindowSettings"), AZ::UserSettings::CT_GLOBAL); + AZ::Crc32("MaterialEditorWindowSettings"), AZ::UserSettings::CT_GLOBAL); if (!windowSettings->m_mainWindowState.empty()) { @@ -272,7 +272,7 @@ namespace MaterialEditor // Capture docking state before shutdown auto windowSettings = AZ::UserSettings::CreateFind( - AZ::Crc32("MaterialEditorwindowSettings"), AZ::UserSettings::CT_GLOBAL); + AZ::Crc32("MaterialEditorWindowSettings"), AZ::UserSettings::CT_GLOBAL); QByteArray windowState = m_advancedDockManager->saveState(); windowSettings->m_mainWindowState.assign(windowState.begin(), windowState.end()); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp index 5ea23de8c6..da04e2ea20 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindowSettings.cpp @@ -23,6 +23,7 @@ namespace MaterialEditor serializeContext->Class() ->Version(1) ->Field("mainWindowState", &MaterialEditorWindowSettings::m_mainWindowState) + ->Field("inspectorCollapsedGroups", &MaterialEditorWindowSettings::m_inspectorCollapsedGroups) ; if (auto editContext = serializeContext->GetEditContext()) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp index dffbd43702..2c334ad3b7 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp @@ -21,13 +21,17 @@ #include #include -#include +#include +#include namespace MaterialEditor { MaterialInspector::MaterialInspector(QWidget* parent) : AtomToolsFramework::InspectorWidget(parent) { + m_windowSettings = AZ::UserSettings::CreateFind( + AZ::Crc32("MaterialEditorWindowSettings"), AZ::UserSettings::CT_GLOBAL); + MaterialDocumentNotificationBus::Handler::BusConnect(); } @@ -47,6 +51,22 @@ namespace MaterialEditor AtomToolsFramework::InspectorWidget::Reset(); } + bool MaterialInspector::ShouldGroupAutoExpanded(const AZStd::string& groupNameId) const + { + auto stateItr = m_windowSettings->m_inspectorCollapsedGroups.find(GetGroupSaveStateKey(groupNameId)); + return stateItr == m_windowSettings->m_inspectorCollapsedGroups.end(); + } + + void MaterialInspector::OnGroupExpanded(const AZStd::string& groupNameId) + { + m_windowSettings->m_inspectorCollapsedGroups.erase(GetGroupSaveStateKey(groupNameId)); + } + + void MaterialInspector::OnGroupCollapsed(const AZStd::string& groupNameId) + { + m_windowSettings->m_inspectorCollapsedGroups.insert(GetGroupSaveStateKey(groupNameId)); + } + void MaterialInspector::OnDocumentOpened(const AZ::Uuid& documentId) { AddGroupsBegin(); @@ -73,6 +93,20 @@ namespace MaterialEditor AddGroupsEnd(); } + AZ::Crc32 MaterialInspector::GetGroupSaveStateKey(const AZStd::string& groupNameId) const + { + return AZ::Crc32( + AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupNameId.c_str())); + } + + bool MaterialInspector::CompareInstanceNodeProperties( + const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) const + { + AZ_UNUSED(source); + const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); + return property && AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue); + } + void MaterialInspector::AddDetailsGroup() { const AZ::RPI::MaterialTypeSourceData* materialTypeSourceData = nullptr; @@ -92,15 +126,9 @@ namespace MaterialEditor group.m_properties.push_back(property); // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - const AZ::Crc32 saveStateKey( - AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, - [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { - AZ_UNUSED(source); - const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); - return property && AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue); - }); + &group, &group, group.TYPEINFO_Uuid(), this, this, GetGroupSaveStateKey(groupNameId), + [this](const auto source, const auto target) { return CompareInstanceNodeProperties(source, target); }); AddGroup(groupNameId, groupDisplayName, groupDescription, propertyGroupWidget); } @@ -127,15 +155,9 @@ namespace MaterialEditor } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - const AZ::Crc32 saveStateKey( - AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, - [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { - AZ_UNUSED(source); - const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); - return property && AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue); - }); + &group, &group, group.TYPEINFO_Uuid(), this, this, GetGroupSaveStateKey(groupNameId), + [this](const auto source, const auto target) { return CompareInstanceNodeProperties(source, target); }); AddGroup(groupNameId, groupDisplayName, groupDescription, propertyGroupWidget); } @@ -165,15 +187,9 @@ namespace MaterialEditor } // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties - const AZ::Crc32 saveStateKey( - AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupDisplayName.c_str())); auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, - [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { - AZ_UNUSED(source); - const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target); - return property && AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue); - }); + &group, &group, group.TYPEINFO_Uuid(), this, this, GetGroupSaveStateKey(groupNameId), + [this](const auto source, const auto target) { return CompareInstanceNodeProperties(source, target); }); AddGroup(groupNameId, groupDisplayName, groupDescription, propertyGroupWidget); } } @@ -270,4 +286,4 @@ namespace MaterialEditor } } // namespace MaterialEditor -#include +#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h index a7a4dddbaa..b2900b979c 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h @@ -41,7 +41,16 @@ namespace MaterialEditor // AtomToolsFramework::InspectorRequestBus::Handler overrides... void Reset() override; + protected: + bool ShouldGroupAutoExpanded(const AZStd::string& groupNameId) const override; + void OnGroupExpanded(const AZStd::string& groupNameId) override; + void OnGroupCollapsed(const AZStd::string& groupNameId) override; + private: + AZ::Crc32 GetGroupSaveStateKey(const AZStd::string& groupNameId) const; + bool CompareInstanceNodeProperties( + const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) const; + void AddDetailsGroup(); void AddUvNamesGroup(); void AddPropertiesGroup(); @@ -66,5 +75,6 @@ namespace MaterialEditor AZ::Uuid m_documentId = AZ::Uuid::CreateNull(); AZStd::string m_documentPath; AZStd::unordered_map m_groups; + AZStd::intrusive_ptr m_windowSettings; }; } // namespace MaterialEditor diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp index 1ae0610169..7f54e386fc 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentInspector.cpp @@ -215,7 +215,7 @@ namespace AZ // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties const AZ::Crc32 saveStateKey(AZStd::string::format( "MaterialPropertyInspector::PropertyGroup::%s::%s", m_materialAssetId.ToString().c_str(), - groupDisplayName.c_str())); + groupNameId.c_str())); auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { @@ -268,7 +268,7 @@ namespace AZ // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties const AZ::Crc32 saveStateKey(AZStd::string::format( "MaterialPropertyInspector::PropertyGroup::%s::%s", m_materialAssetId.ToString().c_str(), - groupDisplayName.c_str())); + groupNameId.c_str())); auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( &group, &group, group.TYPEINFO_Uuid(), this, this, saveStateKey, [this](const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) { From 1e860e7c82cb60948cc0b865314c183148a19d8c Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Sat, 8 May 2021 19:56:40 -0700 Subject: [PATCH 045/225] Change BindlessPrototype to use an unbounded array --- .../ShaderResourceGroups/BindlessPrototypeSrg.azsli | 7 +++---- .../Atom/RPI.Public/Shader/ShaderResourceGroup.h | 3 +++ .../Source/RPI.Public/Shader/ShaderResourceGroup.cpp | 10 ++++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli index c955c5d2f8..7304af9e1e 100644 --- a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli +++ b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli @@ -31,10 +31,6 @@ ShaderResourceGroupSemantic FloatBufferSemanticId ShaderResourceGroup ImageSrg : FrequencyPerScene { - // Array of textures - // NOTE: The size of the texture array has to match the number of textures in the example - Texture2D m_textureArray[8]; - Sampler m_sampler { MaxAnisotropy = 16; @@ -42,6 +38,9 @@ ShaderResourceGroup ImageSrg : FrequencyPerScene AddressV = Wrap; AddressW = Wrap; }; + + // Array of textures + Texture2D m_textureArray[]; } ShaderResourceGroup FloatBufferSrg : FloatBufferSemanticId diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderResourceGroup.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderResourceGroup.h index 8c53ed2eb2..6d99d287f3 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderResourceGroup.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderResourceGroup.h @@ -75,6 +75,9 @@ namespace AZ RHI::ShaderInputSamplerIndex FindShaderInputSamplerIndex(const Name& name) const; RHI::ShaderInputConstantIndex FindShaderInputConstantIndex(const Name& name) const; + RHI::ShaderInputBufferUnboundedArrayIndex FindShaderInputBufferUnboundedArrayIndex(const Name& name) const; + RHI::ShaderInputImageUnboundedArrayIndex FindShaderInputImageUnboundedArrayIndex(const Name& name) const; + /// Returns the parent shader resource group asset. const Data::Asset& GetAsset() const; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroup.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroup.cpp index 28ba48c370..77ea0b9494 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroup.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroup.cpp @@ -118,6 +118,16 @@ namespace AZ return m_layout->FindShaderInputConstantIndex(name); } + RHI::ShaderInputBufferUnboundedArrayIndex ShaderResourceGroup::FindShaderInputBufferUnboundedArrayIndex(const Name& name) const + { + return m_layout->FindShaderInputBufferUnboundedArrayIndex(name); + } + + RHI::ShaderInputImageUnboundedArrayIndex ShaderResourceGroup::FindShaderInputImageUnboundedArrayIndex(const Name& name) const + { + return m_layout->FindShaderInputImageUnboundedArrayIndex(name); + } + const Data::Asset& ShaderResourceGroup::GetAsset() const { return m_asset; From 543784339045b2b8b1ea53fe7312c8cdfd0e0dab Mon Sep 17 00:00:00 2001 From: guthadam Date: Sun, 9 May 2021 12:34:55 -0500 Subject: [PATCH 046/225] Created material editor settings dialog Activated settings menu option Moved viewport camera controller initialization before viewport settings restoration --- .../Atom/Document/MaterialDocumentSettings.h | 1 + .../Document/MaterialDocumentSettings.cpp | 3 + .../Viewport/MaterialViewportRenderer.cpp | 4 +- .../CreateMaterialDialog.cpp | 9 ++- .../Source/Window/MaterialEditorWindow.cpp | 13 ++-- .../Code/Source/Window/MaterialEditorWindow.h | 2 +- .../Window/SettingsDialog/SettingsDialog.cpp | 43 +++++++++++ .../Window/SettingsDialog/SettingsDialog.h | 27 +++++++ .../Window/SettingsDialog/SettingsWidget.cpp | 72 +++++++++++++++++++ .../Window/SettingsDialog/SettingsWidget.h | 54 ++++++++++++++ .../ViewportSettingsInspector.cpp | 6 +- .../ViewportSettingsInspector.h | 2 +- .../Code/materialeditorwindow_files.cmake | 4 ++ 13 files changed, 226 insertions(+), 14 deletions(-) create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsDialog.cpp create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsDialog.h create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.cpp create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h index 37d6a8c2d8..86c913d271 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Document/MaterialDocumentSettings.h @@ -30,5 +30,6 @@ namespace MaterialEditor static void Reflect(AZ::ReflectContext* context); bool m_showReloadDocumentPrompt = true; + AZStd::string m_defaultMaterialTypeName = "StandardPBR"; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp index a64b6584c1..0dab7ea9f6 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocumentSettings.cpp @@ -23,6 +23,7 @@ namespace MaterialEditor serializeContext->Class() ->Version(1) ->Field("showReloadDocumentPrompt", &MaterialDocumentSettings::m_showReloadDocumentPrompt) + ->Field("defaultMaterialTypeName", &MaterialDocumentSettings::m_defaultMaterialTypeName) ; if (auto editContext = serializeContext->GetEditContext()) @@ -32,6 +33,7 @@ namespace MaterialEditor ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialDocumentSettings::m_showReloadDocumentPrompt, "Show Reload Document Prompt", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialDocumentSettings::m_defaultMaterialTypeName, "Default Material Type Name", "") ; } } @@ -45,6 +47,7 @@ namespace MaterialEditor ->Constructor() ->Constructor() ->Property("showReloadDocumentPrompt", BehaviorValueProperty(&MaterialDocumentSettings::m_showReloadDocumentPrompt)) + ->Property("defaultMaterialTypeName", BehaviorValueProperty(&MaterialDocumentSettings::m_defaultMaterialTypeName)) ; } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp index f009cc1f9b..c7265e0039 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportRenderer.cpp @@ -233,6 +233,8 @@ namespace MaterialEditor MaterialViewportRequestBus::BroadcastResult(modelPreset, &MaterialViewportRequestBus::Events::GetModelPresetSelection); OnModelPresetSelected(modelPreset); + m_viewportController->Init(m_cameraEntity->GetId(), m_modelEntity->GetId(), m_iblEntity->GetId()); + // Apply user settinngs restored since last run AZStd::intrusive_ptr viewportSettings = AZ::UserSettings::CreateFind(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL); @@ -248,8 +250,6 @@ namespace MaterialEditor AZ::TickBus::Handler::BusConnect(); AZ::TransformNotificationBus::MultiHandler::BusConnect(m_cameraEntity->GetId()); AzFramework::WindowSystemRequestBus::Handler::BusConnect(); - - m_viewportController->Init(m_cameraEntity->GetId(), m_modelEntity->GetId(), m_iblEntity->GetId()); } MaterialViewportRenderer::~MaterialViewportRenderer() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp index 6c30540392..6a4bb8c0f4 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp @@ -21,6 +21,8 @@ #include #include +#include + #include namespace MaterialEditor @@ -69,8 +71,11 @@ namespace MaterialEditor QObject::connect(m_ui->m_materialTypeComboBox, static_cast(&QComboBox::currentIndexChanged), this, [this]() { UpdateMaterialTypeSelection(); }); QObject::connect(m_ui->m_materialTypeComboBox, &QComboBox::currentTextChanged, this, [this]() { UpdateMaterialTypeSelection(); }); - // Select StandardPBR by default but we will later data drive this with editor settings - const int index = m_ui->m_materialTypeComboBox->findText("StandardPBR"); + // Select the default material type from settings + auto settings = + AZ::UserSettings::CreateFind(AZ::Crc32("MaterialDocumentSettings"), AZ::UserSettings::CT_GLOBAL); + + const int index = m_ui->m_materialTypeComboBox->findText(settings->m_defaultMaterialTypeName.c_str()); if (index >= 0) { m_ui->m_materialTypeComboBox->setCurrentIndex(index); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index 075a58c532..d0470c476f 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -314,7 +315,7 @@ namespace MaterialEditor m_actionUndo->setEnabled(canUndo); m_actionRedo->setEnabled(canRedo); - m_actionPreferences->setEnabled(false); + m_actionSettings->setEnabled(true); m_actionAssetBrowser->setEnabled(true); m_actionInspector->setEnabled(true); @@ -507,9 +508,11 @@ namespace MaterialEditor m_menuEdit->addSeparator(); - m_actionPreferences = m_menuEdit->addAction("&Preferences...", [this]() { + m_actionSettings = m_menuEdit->addAction("&Settings...", [this]() { + SettingsDialog dialog(this); + dialog.exec(); }, QKeySequence::Preferences); - m_actionPreferences->setEnabled(false); + m_actionSettings->setEnabled(true); m_menuView = m_menuBar->addMenu("&View"); @@ -554,8 +557,8 @@ namespace MaterialEditor m_menuHelp = m_menuBar->addMenu("&Help"); m_actionHelp = m_menuHelp->addAction("&Help...", [this]() { - HelpDialog dlg(this); - dlg.exec(); + HelpDialog dialog(this); + dialog.exec(); }); m_actionAbout = m_menuHelp->addAction("&About...", [this]() { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.h index 778e11275f..aa95e5ad8c 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.h @@ -119,7 +119,7 @@ namespace MaterialEditor QMenu* m_menuEdit = {}; QAction* m_actionUndo = {}; QAction* m_actionRedo = {}; - QAction* m_actionPreferences = {}; + QAction* m_actionSettings = {}; QMenu* m_menuView = {}; QAction* m_actionAssetBrowser = {}; diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsDialog.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsDialog.cpp new file mode 100644 index 0000000000..75bc78db12 --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsDialog.cpp @@ -0,0 +1,43 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include + +#include +#include + +namespace MaterialEditor +{ + SettingsDialog::SettingsDialog(QWidget* parent) + : QDialog(parent) + { + setWindowTitle("Material Editor Settings"); + setFixedSize(600, 300); + setLayout(new QVBoxLayout(this)); + + auto settingsWidget = new SettingsWidget(this); + settingsWidget->Populate(); + layout()->addWidget(settingsWidget); + + // Create the bottom row of the dialog with action buttons + auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok, this); + layout()->addWidget(buttonBox); + + QObject::connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + QObject::connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + + setModal(true); + } +} // namespace MaterialEditor + +//#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsDialog.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsDialog.h new file mode 100644 index 0000000000..a5ad35c4a3 --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsDialog.h @@ -0,0 +1,27 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#include + +namespace MaterialEditor +{ + class SettingsDialog + : public QDialog + { + Q_OBJECT + public: + SettingsDialog(QWidget* parent = nullptr); + ~SettingsDialog() = default; + }; +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.cpp new file mode 100644 index 0000000000..2cb07b6770 --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.cpp @@ -0,0 +1,72 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include + +namespace MaterialEditor +{ + SettingsWidget::SettingsWidget(QWidget* parent) + : AtomToolsFramework::InspectorWidget(parent) + { + m_documentSettings = + AZ::UserSettings::CreateFind(AZ::Crc32("MaterialDocumentSettings"), AZ::UserSettings::CT_GLOBAL); + } + + SettingsWidget::~SettingsWidget() + { + AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect(); + } + + void SettingsWidget::Populate() + { + AddGroupsBegin(); + AddDocumentGroup(); + AddGroupsEnd(); + } + + void SettingsWidget::AddDocumentGroup() + { + const AZStd::string groupNameId = "documentSettings"; + const AZStd::string groupDisplayName = "Document Settings"; + const AZStd::string groupDescription = "Document Settings"; + + const AZ::Crc32 saveStateKey(AZStd::string::format("SettingsWidget::DocumentGroup")); + AddGroup( + groupNameId, groupDisplayName, groupDescription, + new AtomToolsFramework::InspectorPropertyGroupWidget( + m_documentSettings.get(), nullptr, m_documentSettings->TYPEINFO_Uuid(), this, this, saveStateKey)); + } + + void SettingsWidget::Reset() + { + AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect(); + AtomToolsFramework::InspectorWidget::Reset(); + } + + void SettingsWidget::BeforePropertyModified(AzToolsFramework::InstanceDataNode* pNode) + { + AZ_UNUSED(pNode); + } + + void SettingsWidget::AfterPropertyModified(AzToolsFramework::InstanceDataNode* pNode) + { + AZ_UNUSED(pNode); + } + + void SettingsWidget::SetPropertyEditingComplete(AzToolsFramework::InstanceDataNode* pNode) + { + AZ_UNUSED(pNode); + } +} // namespace MaterialEditor + +//#include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h new file mode 100644 index 0000000000..33d831f3d1 --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/SettingsDialog/SettingsWidget.h @@ -0,0 +1,54 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#endif + +namespace MaterialEditor +{ + //! Provides controls for viewing and editing settings. + class SettingsWidget + : public AtomToolsFramework::InspectorWidget + , private AzToolsFramework::IPropertyEditorNotify + { + Q_OBJECT + public: + AZ_CLASS_ALLOCATOR(SettingsWidget, AZ::SystemAllocator, 0); + + explicit SettingsWidget(QWidget* parent = nullptr); + ~SettingsWidget() override; + + void Populate(); + + private: + void AddDocumentGroup(); + + // AtomToolsFramework::InspectorRequestBus::Handler overrides... + void Reset() override; + + // AzToolsFramework::IPropertyEditorNotify overrides... + void BeforePropertyModified(AzToolsFramework::InstanceDataNode* pNode) override; + void AfterPropertyModified(AzToolsFramework::InstanceDataNode* pNode) override; + void SetPropertyEditingActive([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {} + void SetPropertyEditingComplete(AzToolsFramework::InstanceDataNode* pNode) override; + void SealUndoStack() override {} + void RequestPropertyContextMenu(AzToolsFramework::InstanceDataNode*, const QPoint&) override {} + void PropertySelectionChanged(AzToolsFramework::InstanceDataNode*, bool) override {} + + AZStd::intrusive_ptr m_documentSettings; + }; +} // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp index 384644f79c..49bd31ee31 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp @@ -43,7 +43,7 @@ namespace MaterialEditor AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect(); } - void ViewportSettingsInspector::Popuate() + void ViewportSettingsInspector::Populate() { AddGroupsBegin(); AddGeneralGroup(); @@ -271,7 +271,7 @@ namespace MaterialEditor { if (m_lightingPreset != preset) { - Popuate(); + Populate(); } } @@ -279,7 +279,7 @@ namespace MaterialEditor { if (m_modelPreset != preset) { - Popuate(); + Populate(); } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h index fdfdec1458..ac9927e069 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h @@ -39,7 +39,7 @@ namespace MaterialEditor ~ViewportSettingsInspector() override; private: - void Popuate(); + void Populate(); void AddGeneralGroup(); void AddModelGroup(); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake index 52022e6e87..7a1aa8c735 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake +++ b/Gems/Atom/Tools/MaterialEditor/Code/materialeditorwindow_files.cmake @@ -28,6 +28,10 @@ set(FILES Source/Window/MaterialEditor.qss Source/Window/MaterialEditorWindowComponent.h Source/Window/MaterialEditorWindowComponent.cpp + Source/Window/SettingsDialog/SettingsDialog.cpp + Source/Window/SettingsDialog/SettingsDialog.h + Source/Window/SettingsDialog/SettingsWidget.cpp + Source/Window/SettingsDialog/SettingsWidget.h Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp Source/Window/CreateMaterialDialog/CreateMaterialDialog.h Source/Window/CreateMaterialDialog/CreateMaterialDialog.ui From 23194376271a4f486495e890aa048e41836dac51 Mon Sep 17 00:00:00 2001 From: zsolleci Date: Mon, 10 May 2021 10:17:05 -0500 Subject: [PATCH 047/225] changed file name per review feedback --- ...vasComponent_OnEntityActivatedDeactivated_PrintMessage.py} | 4 ++-- .../Gem/PythonTests/scripting/TestSuite_Active.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename AutomatedTesting/Gem/PythonTests/scripting/{OnEntityActivatedDeactivated_HappyPath_PrintMessage.py => ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage.py} (98%) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_HappyPath_PrintMessage.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage.py similarity index 98% rename from AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_HappyPath_PrintMessage.py rename to AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage.py index 721ab53d8e..14e0c849e3 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_HappyPath_PrintMessage.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage.py @@ -23,7 +23,7 @@ class Tests(): # fmt: on -def OnEntityActivatedDeactivated_HappyPath_PrintMessage(): +def ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage(): """ Summary: Verify that the On Entity Activated/On Entity Deactivated nodes are working as expected @@ -189,4 +189,4 @@ if __name__ == "__main__": imports.init() from utils import Report - Report.start_test(OnEntityActivatedDeactivated_HappyPath_PrintMessage) + Report.start_test(ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index a225ebd845..1c52aa18fe 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -68,12 +68,12 @@ class TestAutomation(TestAutomationBase): self._run_test(request, workspace, editor, test_module) @pytest.mark.parametrize("level", ["tmp_level"]) - def test_OnEntityActivatedDeactivated_HappyPath_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): + def test_ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): def teardown(): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) request.addfinalizer(teardown) file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import OnEntityActivatedDeactivated_HappyPath_PrintMessage as test_module + from . import ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage as test_module self._run_test(request, workspace, editor, test_module) def test_NodePalette_HappyPath_ClearSelection(self, request, workspace, editor, launcher_platform, project): From 521a486ee45f373a4cf7d0f9fece8ac54086e02f Mon Sep 17 00:00:00 2001 From: moudgils Date: Mon, 10 May 2021 09:13:15 -0700 Subject: [PATCH 048/225] Fixes to ios build --- .../Code/Source/ImageBuilderComponent.cpp | 2 +- .../Source/Processing/ImageAssetProducer.cpp | 12 ++++-------- .../Atom/RHI.Reflect/ImageSubresource.h | 11 ++++++++++- .../Source/RHI.Reflect/ImageSubresource.cpp | 12 ++++++++++-- .../Code/Source/RHI/AsyncUploadQueue.cpp | 14 +++++++++++--- .../Shader/ShaderVariantTreeAsset.cpp | 19 ++++++++----------- 6 files changed, 44 insertions(+), 26 deletions(-) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp index ccba00f15f..59c799a601 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp @@ -79,7 +79,7 @@ namespace ImageProcessingAtom builderDescriptor.m_busId = azrtti_typeid(); builderDescriptor.m_createJobFunction = AZStd::bind(&ImageBuilderWorker::CreateJobs, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); builderDescriptor.m_processJobFunction = AZStd::bind(&ImageBuilderWorker::ProcessJob, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - builderDescriptor.m_version = 22; // [ATOM-14765] + builderDescriptor.m_version = 23; // [ATOM-14022] builderDescriptor.m_analysisFingerprint = ImageProcessingAtom::BuilderSettingManager::Instance()->GetAnalysisFingerprint(); m_imageBuilder.BusConnect(builderDescriptor.m_busId); AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor); diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp index 9c02894b7c..2448f501af 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -238,14 +239,9 @@ namespace ImageProcessingAtom uint8_t* mipBuffer; uint32_t pitch; m_imageObject->GetImagePointer(mip, mipBuffer, pitch); - uint32_t mipBufferSize = m_imageObject->GetMipBufSize(mip); - - RHI::ImageSubresourceLayout layout; - layout.m_bytesPerImage = mipBufferSize / arraySize; - layout.m_rowCount = layout.m_bytesPerImage / pitch; - layout.m_size = RHI::Size(m_imageObject->GetWidth(mip), m_imageObject->GetHeight(mip) / arraySize, 1); - layout.m_bytesPerRow = pitch; - + RHI::Format format = Utils::PixelFormatToRHIFormat(m_imageObject->GetPixelFormat(), m_imageObject->HasImageFlags(EIF_SRGBRead)); + + RHI::ImageSubresourceLayout layout = RHI::GetImageSubresourceLayout(RHI::Size(m_imageObject->GetWidth(mip), m_imageObject->GetHeight(mip) / arraySize, 1), format); builder.BeginMip(layout); for (uint32_t arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h index b536ed5524..d81ffc006c 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h @@ -100,7 +100,9 @@ namespace AZ Size size, uint32_t rowCount, uint32_t bytesPerRow, - uint32_t bytesPerImage); + uint32_t bytesPerImage, + uint32_t numBlocksWidth, + uint32_t numBlocksHeight); /// The size of the image subresource in pixels. Certain formats have alignment requirements. /// Block compressed formats are 4 pixel aligned. Other non-standard formats may be 2 pixel aligned. @@ -114,6 +116,13 @@ namespace AZ /// The number of bytes in a single image slice. 3D textures are comprised of m_size.m_depth image slices. uint32_t m_bytesPerImage = 0; + + /// The number of blocks in width based on the texture fomat + uint32_t m_numBlocksWidth = 1; + + /// The number of blocks in height based on the texture fomat + uint32_t m_numBlocksHeight = 1; + }; struct ImageSubresourceLayoutPlaced : ImageSubresourceLayout diff --git a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp index 4e34fe2b32..a956a13d1b 100644 --- a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp @@ -102,11 +102,13 @@ namespace AZ if (auto* serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(0) + ->Version(1) ->Field("m_size", &ImageSubresourceLayout::m_size) ->Field("m_rowCount", &ImageSubresourceLayout::m_rowCount) ->Field("m_bytesPerRow", &ImageSubresourceLayout::m_bytesPerRow) ->Field("m_bytesPerImage", &ImageSubresourceLayout::m_bytesPerImage) + ->Field("m_numBlocksWidth", &ImageSubresourceLayout::m_numBlocksWidth) + ->Field("m_numBlocksHeight", &ImageSubresourceLayout::m_numBlocksHeight) ; } } @@ -115,11 +117,15 @@ namespace AZ Size size, uint32_t rowCount, uint32_t bytesPerRow, - uint32_t bytesPerImage) + uint32_t bytesPerImage, + uint32_t numBlocksWidth, + uint32_t numBlocksHeight) : m_size{size} , m_rowCount{rowCount} , m_bytesPerRow{bytesPerRow} , m_bytesPerImage{bytesPerImage} + , m_numBlocksWidth{numBlocksWidth} + , m_numBlocksHeight{numBlocksHeight} {} ImageSubresourceLayoutPlaced::ImageSubresourceLayoutPlaced(const ImageSubresourceLayout& subresourceLayout, size_t offset) @@ -316,6 +322,8 @@ namespace AZ subresourceLayout.m_rowCount = numBlocksHigh; subresourceLayout.m_size.m_width = imageSize.m_width; subresourceLayout.m_size.m_height = imageSize.m_height; + subresourceLayout.m_numBlocksWidth = numBlocks; + subresourceLayout.m_numBlocksHeight = numBlocks; } else if (isPacked) { diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp index 891f9ea2f3..d9a8f8aa3b 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp @@ -190,8 +190,8 @@ namespace AZ const uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, bufferOffsetAlign); const uint32_t stagingSlicePitch = RHI::AlignUp(subresourceLayout.m_rowCount * stagingRowPitch, bufferOffsetAlign); const uint32_t rowsPerSplit = static_cast(m_descriptor.m_stagingSizeInBytes) / stagingRowPitch; - const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount; - + const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_numBlocksHeight; + // ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression. // Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images. if (subresourceLayout.m_size.m_height < subresourceLayout.m_rowCount) @@ -281,7 +281,7 @@ namespace AZ const uint32_t endRow = AZStd::min(startRow + rowsPerSplit, subresourceLayout.m_rowCount); // Calculate the blocksize for BC formatted images; the copy command works in texels. - const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; + uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; // Copy subresource data to staging memory. uint8_t* stagingDataStart = framePacket->m_stagingResourceData + framePacket->m_dataOffset; @@ -293,6 +293,14 @@ namespace AZ const uint32_t bytesCopied = (endRow - startRow) * stagingRowPitch; Platform::SynchronizeBufferOnCPU(framePacket->m_stagingResource, framePacket->m_dataOffset, bytesCopied); + //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over + //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight + if(destHeight+heightToCopy > subresourceLayout.m_size.m_height) + { + uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height; + heightToCopy -= HeightDiff; + } + const RHI::Size sourceSize = RHI::Size(subresourceLayout.m_size.m_width, heightToCopy, 1); const RHI::Origin sourceOrigin = RHI::Origin(0, destHeight, depth); CopyBufferToImage(framePacket, image, stagingRowPitch, bytesCopied, diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp index 25ba5aa837..f550a6f2ca 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -40,15 +41,12 @@ namespace AZ Data::AssetId ShaderVariantTreeAsset::GetShaderVariantTreeAssetIdFromShaderAssetId(const Data::AssetId& shaderAssetId) { //From the shaderAssetId We can deduce the path of the shader asset, and from the path of the shader asset we can deduce the path of the ShaderVariantTreeAsset. - AZStd::string shaderAssetPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderAssetPath - , &AZ::Data::AssetCatalogRequests::GetAssetPathById - , shaderAssetId); - - AZStd::string shaderAssetPathRoot; - AZStd::string shaderAssetPathName; - AzFramework::StringFunc::Path::Split(shaderAssetPath.c_str(), nullptr /*drive*/, &shaderAssetPathRoot, &shaderAssetPathName, nullptr /*extension*/); - + AZ::IO::FixedMaxPath shaderAssetPath; + AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderAssetPath.Native(), &AZ::Data::AssetCatalogRequests::GetAssetPathById + , shaderAssetId); + AZ::IO::FixedMaxPath shaderAssetPathRoot = shaderAssetPath.ParentPath(); + AZ::IO::FixedMaxPath shaderAssetPathName = shaderAssetPath.Stem(); + AZStd::string shaderVariantTreeAssetDir; AzFramework::StringFunc::Path::Join(ShaderVariantTreeAsset::CommonSubFolderLowerCase, shaderAssetPathRoot.c_str(), shaderVariantTreeAssetDir); AZStd::string shaderVariantTreeAssetFilename = AZStd::string::format("%s.%s", shaderAssetPathName.c_str(), ShaderVariantTreeAsset::Extension); @@ -63,8 +61,7 @@ namespace AZ { // If the game project did not customize the shadervariantlist, let's see if the original author of the .shader file // provided a shadervariantlist. - shaderVariantTreeAssetDir = shaderAssetPathRoot; - AzFramework::StringFunc::Path::Join(shaderVariantTreeAssetDir.c_str(), shaderVariantTreeAssetFilename.c_str(), shaderVariantTreeAssetPath); + AzFramework::StringFunc::Path::Join(shaderAssetPathRoot.c_str(), shaderVariantTreeAssetFilename.c_str(), shaderVariantTreeAssetPath); AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderVariantTreeAssetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath , shaderVariantTreeAssetPath.c_str(), AZ::Data::s_invalidAssetType, false); } From 9725c9beab757fbaeea629257b16ff24b10290f0 Mon Sep 17 00:00:00 2001 From: guthadam Date: Mon, 10 May 2021 12:05:15 -0500 Subject: [PATCH 049/225] Recording/restoring viewport settings group expansion --- .../MaterialInspector/MaterialInspector.cpp | 75 +++++++++------ .../MaterialInspector/MaterialInspector.h | 1 + .../ViewportSettingsInspector.cpp | 94 ++++++++++++------- .../ViewportSettingsInspector.h | 9 +- 4 files changed, 113 insertions(+), 66 deletions(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp index 2c334ad3b7..55e098962a 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.cpp @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #include #include @@ -21,7 +21,6 @@ #include #include -#include #include namespace MaterialEditor @@ -95,8 +94,7 @@ namespace MaterialEditor AZ::Crc32 MaterialInspector::GetGroupSaveStateKey(const AZStd::string& groupNameId) const { - return AZ::Crc32( - AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupNameId.c_str())); + return AZ::Crc32(AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupNameId.c_str())); } bool MaterialInspector::CompareInstanceNodeProperties( @@ -110,7 +108,8 @@ namespace MaterialEditor void MaterialInspector::AddDetailsGroup() { const AZ::RPI::MaterialTypeSourceData* materialTypeSourceData = nullptr; - MaterialDocumentRequestBus::EventResult(materialTypeSourceData, m_documentId, &MaterialDocumentRequestBus::Events::GetMaterialTypeSourceData); + MaterialDocumentRequestBus::EventResult( + materialTypeSourceData, m_documentId, &MaterialDocumentRequestBus::Events::GetMaterialTypeSourceData); const AZStd::string groupNameId = "details"; const AZStd::string groupDisplayName = "Details"; @@ -118,11 +117,13 @@ namespace MaterialEditor auto& group = m_groups[groupNameId]; AtomToolsFramework::DynamicProperty property; - MaterialDocumentRequestBus::EventResult(property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::Name("details.materialType")); + MaterialDocumentRequestBus::EventResult( + property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::Name("details.materialType")); group.m_properties.push_back(property); property = {}; - MaterialDocumentRequestBus::EventResult(property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::Name("details.parentMaterial")); + MaterialDocumentRequestBus::EventResult( + property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::Name("details.parentMaterial")); group.m_properties.push_back(property); // Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties @@ -148,7 +149,9 @@ namespace MaterialEditor for (const auto& uvNamePair : uvNameMap) { AtomToolsFramework::DynamicProperty property; - MaterialDocumentRequestBus::EventResult(property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::RPI::MaterialPropertyId(groupNameId, uvNamePair.m_shaderInput.ToString()).GetFullName()); + MaterialDocumentRequestBus::EventResult( + property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, + AZ::RPI::MaterialPropertyId(groupNameId, uvNamePair.m_shaderInput.ToString()).GetFullName()); group.m_properties.push_back(property); property.SetValue(property.GetConfig().m_parentValue); @@ -164,13 +167,15 @@ namespace MaterialEditor void MaterialInspector::AddPropertiesGroup() { const AZ::RPI::MaterialTypeSourceData* materialTypeSourceData = nullptr; - MaterialDocumentRequestBus::EventResult(materialTypeSourceData, m_documentId, &MaterialDocumentRequestBus::Events::GetMaterialTypeSourceData); + MaterialDocumentRequestBus::EventResult( + materialTypeSourceData, m_documentId, &MaterialDocumentRequestBus::Events::GetMaterialTypeSourceData); for (const auto& groupDefinition : materialTypeSourceData->GetGroupDefinitionsInDisplayOrder()) { const AZStd::string& groupNameId = groupDefinition.m_nameId; const AZStd::string& groupDisplayName = !groupDefinition.m_displayName.empty() ? groupDefinition.m_displayName : groupNameId; - const AZStd::string& groupDescription = !groupDefinition.m_description.empty() ? groupDefinition.m_description : groupDisplayName; + const AZStd::string& groupDescription = + !groupDefinition.m_description.empty() ? groupDefinition.m_description : groupDisplayName; auto& group = m_groups[groupNameId]; const auto& propertyLayout = materialTypeSourceData->m_propertyLayout; @@ -181,7 +186,9 @@ namespace MaterialEditor for (const auto& propertyDefinition : propertyListItr->second) { AtomToolsFramework::DynamicProperty property; - MaterialDocumentRequestBus::EventResult(property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::RPI::MaterialPropertyId(groupNameId, propertyDefinition.m_nameId).GetFullName()); + MaterialDocumentRequestBus::EventResult( + property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, + AZ::RPI::MaterialPropertyId(groupNameId, propertyDefinition.m_nameId).GetFullName()); group.m_properties.push_back(property); } } @@ -205,7 +212,8 @@ namespace MaterialEditor if (!AtomToolsFramework::ArePropertyValuesEqual(reflectedProperty.GetValue(), property.GetValue())) { reflectedProperty.SetValue(property.GetValue()); - AtomToolsFramework::InspectorRequestBus::Event(documentId, &AtomToolsFramework::InspectorRequestBus::Events::RefreshGroup, groupPair.first); + AtomToolsFramework::InspectorRequestBus::Event( + documentId, &AtomToolsFramework::InspectorRequestBus::Events::RefreshGroup, groupPair.first); } return; } @@ -213,7 +221,8 @@ namespace MaterialEditor } } - void MaterialInspector::OnDocumentPropertyConfigModified(const AZ::Uuid& documentId, const AtomToolsFramework::DynamicProperty& property) + void MaterialInspector::OnDocumentPropertyConfigModified( + const AZ::Uuid& documentId, const AtomToolsFramework::DynamicProperty& property) { for (auto& groupPair : m_groups) { @@ -225,12 +234,14 @@ namespace MaterialEditor if (reflectedProperty.GetVisibility() != property.GetVisibility()) { reflectedProperty.SetConfig(property.GetConfig()); - AtomToolsFramework::InspectorRequestBus::Event(documentId, &AtomToolsFramework::InspectorRequestBus::Events::RebuildGroup, groupPair.first); + AtomToolsFramework::InspectorRequestBus::Event( + documentId, &AtomToolsFramework::InspectorRequestBus::Events::RebuildGroup, groupPair.first); } else { reflectedProperty.SetConfig(property.GetConfig()); - AtomToolsFramework::InspectorRequestBus::Event(documentId, &AtomToolsFramework::InspectorRequestBus::Events::RefreshGroup, groupPair.first); + AtomToolsFramework::InspectorRequestBus::Event( + documentId, &AtomToolsFramework::InspectorRequestBus::Events::RefreshGroup, groupPair.first); } return; } @@ -242,7 +253,8 @@ namespace MaterialEditor { // For some reason the reflected property editor notifications are not symmetrical // This function is called continuously anytime a property changes until the edit has completed - // Because of that, we have to track whether or not we are continuing to edit the same property to know when editing has started and ended + // Because of that, we have to track whether or not we are continuing to edit the same property to know when editing has started and + // ended const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode); if (property) { @@ -261,23 +273,24 @@ namespace MaterialEditor { if (m_activeProperty == property) { - MaterialDocumentRequestBus::Event(m_documentId, &MaterialDocumentRequestBus::Events::SetPropertyValue, - property->GetId(), property->GetValue()); + MaterialDocumentRequestBus::Event( + m_documentId, &MaterialDocumentRequestBus::Events::SetPropertyValue, property->GetId(), property->GetValue()); } } } void MaterialInspector::SetPropertyEditingComplete(AzToolsFramework::InstanceDataNode* pNode) { - // As above, there are symmetrical functions on the notification interface for when editing begins and ends and has been completed but they are not being called following that pattern. - // when this function executes the changes to the property are ready to be committed or reverted + // As above, there are symmetrical functions on the notification interface for when editing begins and ends and has been completed + // but they are not being called following that pattern. when this function executes the changes to the property are ready to be + // committed or reverted const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode); if (property) { if (m_activeProperty == property) { - MaterialDocumentRequestBus::Event(m_documentId, &MaterialDocumentRequestBus::Events::SetPropertyValue, - property->GetId(), property->GetValue()); + MaterialDocumentRequestBus::Event( + m_documentId, &MaterialDocumentRequestBus::Events::SetPropertyValue, property->GetId(), property->GetValue()); MaterialDocumentRequestBus::Event(m_documentId, &MaterialDocumentRequestBus::Events::EndEdit); m_activeProperty = nullptr; diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h index b2900b979c..f53e93a2f9 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialInspector/MaterialInspector.h @@ -20,6 +20,7 @@ #include #include +#include #endif namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp index 49bd31ee31..ebce4849e0 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp @@ -1,27 +1,27 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ -#include #include #include #include #include #include +#include +#include #include +#include #include #include -#include -#include #include namespace MaterialEditor @@ -32,6 +32,9 @@ namespace MaterialEditor m_viewportSettings = AZ::UserSettings::CreateFind(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL); + m_windowSettings = AZ::UserSettings::CreateFind( + AZ::Crc32("MaterialEditorWindowSettings"), AZ::UserSettings::CT_GLOBAL); + MaterialViewportNotificationBus::Handler::BusConnect(); } @@ -54,22 +57,21 @@ namespace MaterialEditor void ViewportSettingsInspector::AddGeneralGroup() { - const AZStd::string groupNameId = "general"; - const AZStd::string groupDisplayName = "General"; - const AZStd::string groupDescription = "General"; + const AZStd::string groupNameId = "generalSettings"; + const AZStd::string groupDisplayName = "General Settings"; + const AZStd::string groupDescription = "General Settings"; - const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::GeneralGroup")); AddGroup( groupNameId, groupDisplayName, groupDescription, new AtomToolsFramework::InspectorPropertyGroupWidget( - m_viewportSettings.get(), nullptr, m_viewportSettings->TYPEINFO_Uuid(), this, this, saveStateKey)); + m_viewportSettings.get(), nullptr, m_viewportSettings->TYPEINFO_Uuid(), this, this, GetGroupSaveStateKey(groupNameId))); } void ViewportSettingsInspector::AddModelGroup() { - const AZStd::string groupNameId = "model"; - const AZStd::string groupDisplayName = "Model"; - const AZStd::string groupDescription = "Model"; + const AZStd::string groupNameId = "modelSettings"; + const AZStd::string groupDisplayName = "Model Settings"; + const AZStd::string groupDescription = "Model Settings"; auto groupWidget = new QWidget(this); auto buttonGroupWidget = new QWidget(groupWidget); @@ -94,9 +96,8 @@ namespace MaterialEditor if (m_modelPreset) { - const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::ModelGroup")); auto inspectorWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - m_modelPreset.get(), nullptr, m_modelPreset.get()->TYPEINFO_Uuid(), this, groupWidget, saveStateKey); + m_modelPreset.get(), nullptr, m_modelPreset.get()->TYPEINFO_Uuid(), this, groupWidget, GetGroupSaveStateKey(groupNameId)); groupWidget->layout()->addWidget(inspectorWidget); } @@ -155,9 +156,9 @@ namespace MaterialEditor void ViewportSettingsInspector::AddLightingGroup() { - const AZStd::string groupNameId = "lighting"; - const AZStd::string groupDisplayName = "Lighting"; - const AZStd::string groupDescription = "Lighting"; + const AZStd::string groupNameId = "lightingSettings"; + const AZStd::string groupDisplayName = "Lighting Settings"; + const AZStd::string groupDescription = "Lighting Settings"; auto groupWidget = new QWidget(this); auto buttonGroupWidget = new QWidget(groupWidget); @@ -182,9 +183,9 @@ namespace MaterialEditor if (m_lightingPreset) { - const AZ::Crc32 saveStateKey(AZStd::string::format("ViewportSettingsInspector::LightingGroup")); auto inspectorWidget = new AtomToolsFramework::InspectorPropertyGroupWidget( - m_lightingPreset.get(), nullptr, m_lightingPreset.get()->TYPEINFO_Uuid(), this, groupWidget, saveStateKey); + m_lightingPreset.get(), nullptr, m_lightingPreset.get()->TYPEINFO_Uuid(), this, groupWidget, + GetGroupSaveStateKey(groupNameId)); groupWidget->layout()->addWidget(inspectorWidget); } @@ -202,8 +203,7 @@ namespace MaterialEditor AZ::Render::LightingPresetPtr preset; MaterialViewportRequestBus::BroadcastResult( preset, &MaterialViewportRequestBus::Events::AddLightingPreset, AZ::Render::LightingPreset()); - MaterialViewportRequestBus::Broadcast( - &MaterialViewportRequestBus::Events::SaveLightingPreset, preset, savePath); + MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SaveLightingPreset, preset, savePath); MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectLightingPreset, preset); } } @@ -227,7 +227,8 @@ namespace MaterialEditor MaterialViewportRequestBus::BroadcastResult(preset, &MaterialViewportRequestBus::Events::GetLightingPresetSelection); AZStd::string defaultPath; - MaterialViewportRequestBus::BroadcastResult(defaultPath, &MaterialViewportRequestBus::Events::GetLightingPresetLastSavePath, preset); + MaterialViewportRequestBus::BroadcastResult( + defaultPath, &MaterialViewportRequestBus::Events::GetLightingPresetLastSavePath, preset); if (defaultPath.empty()) { @@ -260,8 +261,10 @@ namespace MaterialEditor m_viewportSettings->m_enableShadowCatcher, &MaterialViewportRequestBus::Events::GetShadowCatcherEnabled); MaterialViewportRequestBus::BroadcastResult( m_viewportSettings->m_enableAlternateSkybox, &MaterialViewportRequestBus::Events::GetAlternateSkyboxEnabled); - MaterialViewportRequestBus::BroadcastResult(m_viewportSettings->m_fieldOfView, &MaterialViewportRequestBus::Handler::GetFieldOfView); - MaterialViewportRequestBus::BroadcastResult(m_viewportSettings->m_displayMapperOperationType, &MaterialViewportRequestBus::Handler::GetDisplayMapperOperationType); + MaterialViewportRequestBus::BroadcastResult( + m_viewportSettings->m_fieldOfView, &MaterialViewportRequestBus::Handler::GetFieldOfView); + MaterialViewportRequestBus::BroadcastResult( + m_viewportSettings->m_displayMapperOperationType, &MaterialViewportRequestBus::Handler::GetDisplayMapperOperationType); AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect(); AtomToolsFramework::InspectorWidget::Reset(); @@ -340,7 +343,8 @@ namespace MaterialEditor MaterialViewportRequestBus::Broadcast( &MaterialViewportRequestBus::Events::SetAlternateSkyboxEnabled, m_viewportSettings->m_enableAlternateSkybox); MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Handler::SetFieldOfView, m_viewportSettings->m_fieldOfView); - MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Handler::SetDisplayMapperOperationType, m_viewportSettings->m_displayMapperOperationType); + MaterialViewportRequestBus::Broadcast( + &MaterialViewportRequestBus::Handler::SetDisplayMapperOperationType, m_viewportSettings->m_displayMapperOperationType); } AZStd::string ViewportSettingsInspector::GetDefaultUniqueSaveFilePath(const AZStd::string& baseName) const @@ -353,6 +357,28 @@ namespace MaterialEditor savePath = AtomToolsFramework::GetUniqueFileInfo(savePath.c_str()).absoluteFilePath().toUtf8().constData(); return savePath; } + + AZ::Crc32 ViewportSettingsInspector::GetGroupSaveStateKey(const AZStd::string& groupNameId) const + { + return AZ::Crc32(AZStd::string::format("ViewportSettingsInspector::PropertyGroup::%s", groupNameId.c_str())); + } + + bool ViewportSettingsInspector::ShouldGroupAutoExpanded(const AZStd::string& groupNameId) const + { + auto stateItr = m_windowSettings->m_inspectorCollapsedGroups.find(GetGroupSaveStateKey(groupNameId)); + return stateItr == m_windowSettings->m_inspectorCollapsedGroups.end(); + } + + void ViewportSettingsInspector::OnGroupExpanded(const AZStd::string& groupNameId) + { + m_windowSettings->m_inspectorCollapsedGroups.erase(GetGroupSaveStateKey(groupNameId)); + } + + void ViewportSettingsInspector::OnGroupCollapsed(const AZStd::string& groupNameId) + { + m_windowSettings->m_inspectorCollapsedGroups.insert(GetGroupSaveStateKey(groupNameId)); + } + } // namespace MaterialEditor #include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h index ac9927e069..23bad988f0 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #endif @@ -78,8 +79,14 @@ namespace MaterialEditor AZStd::string GetDefaultUniqueSaveFilePath(const AZStd::string& baseName) const; - AZStd::intrusive_ptr m_viewportSettings; + AZ::Crc32 GetGroupSaveStateKey(const AZStd::string& groupNameId) const; + bool ShouldGroupAutoExpanded(const AZStd::string& groupNameId) const override; + void OnGroupExpanded(const AZStd::string& groupNameId) override; + void OnGroupCollapsed(const AZStd::string& groupNameId) override; + AZ::Render::ModelPresetPtr m_modelPreset; AZ::Render::LightingPresetPtr m_lightingPreset; + AZStd::intrusive_ptr m_viewportSettings; + AZStd::intrusive_ptr m_windowSettings; }; } // namespace MaterialEditor From e0e2600b62841ed7da484daa203b2483d07bd6c4 Mon Sep 17 00:00:00 2001 From: jromnoa Date: Mon, 10 May 2021 11:43:12 -0700 Subject: [PATCH 050/225] increase test timeout so the nightly debug jobs can pass (profile passes without issue) --- .../Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py index f84e367d1d..0b75760e05 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py @@ -18,7 +18,7 @@ import pytest import editor_python_test_tools.hydra_test_utils as hydra logger = logging.getLogger(__name__) -EDITOR_TIMEOUT = 120 +EDITOR_TIMEOUT = 300 TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") From 0da6e450a68ad2a20a8962a42ed52a58f34d2885 Mon Sep 17 00:00:00 2001 From: srikappa Date: Mon, 10 May 2021 11:43:32 -0700 Subject: [PATCH 051/225] Improved comments --- .../PrefabEditorEntityOwnershipService.cpp | 10 ------- .../Instance/InstanceToTemplatePropagator.cpp | 13 ++++----- .../AzToolsFramework/Prefab/Link/Link.cpp | 3 --- .../Prefab/PrefabPublicHandler.cpp | 27 +++++++++---------- .../Prefab/PrefabPublicHandler.h | 1 + 5 files changed, 19 insertions(+), 35 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 58aa245397..59e50fdf65 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -281,16 +281,6 @@ namespace AzToolsFramework containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent()); HandleEntitiesAdded({containerEntity}); HandleEntitiesAdded(entities); - - /* - // Update the template of the instance since we modified the entities of the instance by calling HandleEntitiesAdded. - Prefab::PrefabDom serializedInstance; - if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(addedInstance, serializedInstance)) - { - m_prefabSystemComponent->UpdatePrefabTemplate(addedInstance.GetTemplateId(), serializedInstance); - } - */ - return addedInstance; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp index d298e1e2b2..6f812df89b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp @@ -176,15 +176,10 @@ namespace AzToolsFramework { PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId); - PrefabDomUtils::PrintPrefabDomValue("patch is ", providedPatch); - PrefabDomUtils::PrintPrefabDomValue("template dom before is ", templateDomReference); - //apply patch to template AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference, templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch); - PrefabDomUtils::PrintPrefabDomValue("template dom after is ", templateDomReference); - //trigger propagation if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success) { @@ -284,9 +279,11 @@ namespace AzToolsFramework // This logic only covers addition of patches. If patches already exists, the given list of patches must be appended to them. if (!linkPatchesReference.has_value()) { - // If the original allocator the patches were created with gets destroyed, then the patches would become garbage in the - // linkDom. Since we cannot guarantee the lifecycle of the patch allocators, we are doing a copy of the patches here to - // associate them with the linkDom's allocator. This is a limitation with rapidjson. + /* + If the original allocator the patches were created with gets destroyed, then the patches would become garbage in the + linkDom. Since we cannot guarantee the lifecycle of the patch allocators, we are doing a copy of the patches here to + associate them with the linkDom's allocator. This is a limitation with rapidjson. + */ PrefabDom patchesCopy; patchesCopy.CopyFrom(patches, linkDom.GetAllocator()); linkDom.AddMember(rapidjson::StringRef(PrefabDomUtils::PatchesName), patchesCopy, linkDom.GetAllocator()); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp index e421e55a11..e0834ed53b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp @@ -181,8 +181,6 @@ namespace AzToolsFramework } else { - PrefabDomUtils::PrintPrefabDomValue("Patches are : ", m_linkDom); - PrefabDomUtils::PrintPrefabDomValue("Linked instance dom before is : ", linkedInstanceDom); AZ::JsonSerializationResult::ResultCode applyPatchResult = AZ::JsonSerialization::ApplyPatch( linkedInstanceDom, targetTemplatePrefabDom.GetAllocator(), @@ -195,7 +193,6 @@ namespace AzToolsFramework "Link::UpdateTarget - " "ApplyPatches failed for Prefab DOM from source Template '%u' and target Template '%u'.", m_sourceTemplateId, m_targetTemplateId); - PrefabDomUtils::PrintPrefabDomValue("Linked instance dom after is : ", linkedInstanceDom); return false; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 80e1b558e7..9959ae18fa 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -122,18 +122,14 @@ namespace AzToolsFramework AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId(); - // Change top level entities to be parented to the container entity - // Mark them as dirty so this change is correctly applied to the template + // Parent the entities to the container entity. Parenting the container entities of the instances passed to createPrefab + // will be done during the creation of links below. for (AZ::Entity* topLevelEntity : entities) { - //m_prefabUndoCache.UpdateCache(topLevelEntity->GetId()); - // undoBatch.MarkEntityDirty(topLevelEntity->GetId()); AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); - //ToolsApplicationRequests::Bus::Broadcast( - // &ToolsApplicationRequests::Bus::Events::RemoveDirtyEntity, topLevelEntity->GetId()); } - // Update the template of the instance since we modified the entities of the instance by calling HandleEntitiesAdded. + // Update the template of the instance since the entities are modified since the template creation. Prefab::PrefabDom serializedInstance; if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(instanceToCreate->get(), serializedInstance)) { @@ -145,27 +141,28 @@ namespace AzToolsFramework EntityOptionalReference nestedInstanceContainerEntity = nestedInstance->GetContainerEntity(); AZ_Assert( nestedInstanceContainerEntity, "Invalid container entity found for the nested instance used in prefab creation."); + + // These link creations shouldn't be undone because that would put the template in a non-usable state if a user + // chooses to instantiate the template after undoing the creation. CreateLink( {&nestedInstanceContainerEntity->get()}, *nestedInstance, instanceToCreate->get().GetTemplateId(), undoBatch.GetUndoBatch(), containerEntityId, false); }); CreateLink( - topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(), - commonRootEntityId); + topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), + undoBatch.GetUndoBatch(), commonRootEntityId); - // Change top level entities to be parented to the container entity - // Mark them as dirty so this change is correctly applied to the template for (AZ::Entity* topLevelEntity : topLevelEntities) { m_prefabUndoCache.UpdateCache(topLevelEntity->GetId()); - //undoBatch.MarkEntityDirty(topLevelEntity->GetId()); - //AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId); + + // Parenting entities would mark entities as dirty. But we want to unmark the top level entities as dirty because + // if we don't, the template created would be updated and cause issues with undo operation followed by instantiation. ToolsApplicationRequests::Bus::Broadcast( &ToolsApplicationRequests::Bus::Events::RemoveDirtyEntity, topLevelEntity->GetId()); } - // Select Container Entity { auto selectionUndo = aznew SelectionCommand({containerEntityId}, "Select Prefab Container Entity"); @@ -442,6 +439,8 @@ namespace AzToolsFramework PrefabDom patch; m_instanceToTemplateInterface->GeneratePatch(patch, beforeState, afterState); + PrefabDomUtils::PrintPrefabDomValue(entity->GetName(), patch); + if (patch.IsArray() && !patch.Empty() && beforeState.IsObject()) { if (IsInstanceContainerEntity(entityId) && !IsLevelInstanceContainerEntity(entityId)) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 0e15fd9a15..771f73a815 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -77,6 +77,7 @@ namespace AzToolsFramework * \param targetInstance The id of the target template. * \param undoBatch The undo batch to set as parent for this create link action. * \param commonRootEntityId The id of the entity that the source instance should be parented under. + * \param IsUndoRedoSupportNeeded The flag indicating whether the link should be created with undo/redo support or not. */ void CreateLink( const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId, From b04bfc459ff57c10ab21a4668c63586fcb67148a Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 11:46:58 -0700 Subject: [PATCH 052/225] Asset Preload fix for json serialization and prefab game mode --- .../Registry/editorpreferences.setreg | 3 +- .../AzCore/AzCore/Asset/AssetCommon.h | 18 ++++---- .../AzCore/Asset/AssetJsonSerializer.cpp | 33 ++++++++++++- .../AzCore/Asset/AssetManagerComponent.cpp | 9 +++- .../AzCore/Serialization/SerializeContext.h | 2 - .../AzCore/AzCore/azcore_files.cmake | 2 + .../PrefabEditorEntityOwnershipService.cpp | 46 ++++++++++++++++++- .../Prefab/PrefabDomUtils.cpp | 45 ++++++++++++++++++ .../AzToolsFramework/Prefab/PrefabDomUtils.h | 11 +++++ .../Spawnable/PrefabCatchmentProcessor.cpp | 5 +- .../Prefab/Spawnable/ProcesedObjectStore.cpp | 10 ++++ .../Prefab/Spawnable/ProcesedObjectStore.h | 5 ++ .../Prefab/Spawnable/SpawnableUtils.cpp | 7 +-- .../Prefab/Spawnable/SpawnableUtils.h | 2 +- 14 files changed, 178 insertions(+), 20 deletions(-) diff --git a/AutomatedTesting/Registry/editorpreferences.setreg b/AutomatedTesting/Registry/editorpreferences.setreg index b338d6acad..d7afc9e0ae 100644 --- a/AutomatedTesting/Registry/editorpreferences.setreg +++ b/AutomatedTesting/Registry/editorpreferences.setreg @@ -1,7 +1,8 @@ { "Amazon": { "Preferences": { - "EnablePrefabSystem": false + "EnablePrefabSystem": true, + "EnablePrefabSystemWipFeatures": true } } } \ No newline at end of file diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h index c8a245af68..c5cdbbf331 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -216,16 +217,14 @@ namespace AZ /** * Setting for each reference (Asset) to control loading of referenced assets during serialization. */ - enum class AssetLoadBehavior : u8 - { - PreLoad = 0, ///< Serializer will "Pre load" dependencies, asset containers may load in parallel but will not signal AssetReady - QueueLoad = 1, ///< Serializer will queue an asynchronous load of the referenced asset and return the object to the user. User code should use the \ref AZ::Data::AssetBus to monitor for when it's ready. - NoLoad = 2, ///< Serializer will load reference information, but asset loading will be left to the user. User code should call Asset::QueueLoad and use the \ref AZ::Data::AssetBus to monitor for when it's ready. - ///< AssetContainers will skip NoLoad dependencies - + AZ_ENUM_WITH_UNDERLYING_TYPE(AssetLoadBehavior, u8, + (PreLoad, 0), ///< Serializer will "Pre load" dependencies, asset containers may load in parallel but will not signal AssetReady + (QueueLoad, 1), ///< Serializer will queue an asynchronous load of the referenced asset and return the object to the user. User code should use the \ref AZ::Data::AssetBus to monitor for when it's ready. + (NoLoad, 2), ///< Serializer will load reference information, but asset loading will be left to the user. User code should call Asset::QueueLoad and use the \ref AZ::Data::AssetBus to monitor for when it's ready. + ///< AssetContainers will skip NoLoad dependencies Count, - Default = QueueLoad, - }; + (Default, QueueLoad) + ); struct AssetFilterInfo { @@ -1222,6 +1221,7 @@ namespace AZ } // namespace ProductDependencyInfo } // namespace Data + AZ_TYPE_INFO_SPECIALIZE(Data::AssetLoadBehavior, "{DAF9ECED-FEF3-4D7A-A220-8CFD6A5E6DA1}"); AZ_TYPE_INFO_TEMPLATE_WITH_NAME(AZ::Data::Asset, "Asset", "{C891BF19-B60C-45E2-BFD0-027D15DDC939}", AZ_TYPE_INFO_CLASS); } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp index 767dadedf8..6968b51025 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -70,6 +71,17 @@ namespace AZ } } + { + const AZ::Data::AssetLoadBehavior autoLoadBehavior = instance->GetAutoLoadBehavior(); + const AZ::Data::AssetLoadBehavior defaultAutoLoadBehavior = defaultInstance ? + defaultInstance->GetAutoLoadBehavior() : AZ::Data::AssetLoadBehavior::Default; + + result.Combine( + ContinueStoringToJsonObjectField(outputValue, "loadBehavior", + &autoLoadBehavior, &defaultAutoLoadBehavior, + azrtti_typeid(), context)); + } + { ScopedContextPath subPathHint(context, "m_assetHint"); const AZStd::string* hint = &instance->GetHint(); @@ -100,6 +112,20 @@ namespace AZ AssetId id; JSR::ResultCode result(JSR::Tasks::ReadField); + SerializedAssetTracker** assetIdTracker = + context.GetMetadata().Find(); + + { + Data::AssetLoadBehavior loadBehavior = instance->GetAutoLoadBehavior(); + + result.Combine( + ContinueLoadingFromJsonObjectField(&loadBehavior, + azrtti_typeid(), + inputValue, "loadBehavior", context)); + + instance->SetAutoLoadBehavior(loadBehavior); + } + auto it = inputValue.FindMember("assetId"); if (it != inputValue.MemberEnd()) { @@ -107,7 +133,7 @@ namespace AZ result = ContinueLoading(&id, azrtti_typeid(), it->value, context); if (!id.m_guid.IsNull()) { - *instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), AssetLoadBehavior::NoLoad); + *instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), instance->GetAutoLoadBehavior()); result.Combine(context.Report(result, "Successfully created Asset with id.")); @@ -142,6 +168,11 @@ namespace AZ "The asset hint is missing for Asset, so it will be left empty.")); } + if (assetIdTracker && *assetIdTracker) + { + (*assetIdTracker)->AddAsset(*instance); + } + bool success = result.GetOutcome() <= JSR::Outcomes::PartialSkip; bool defaulted = result.GetOutcome() == JSR::Outcomes::DefaultsUsed || result.GetOutcome() == JSR::Outcomes::PartialDefaults; AZStd::string_view message = diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp index d861614309..1075c6a931 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,6 +24,11 @@ namespace AZ { + namespace Data + { + AZ_ENUM_DEFINE_REFLECT_UTILITIES(AssetLoadBehavior); + } + //========================================================================= // AssetDatabaseComponent // [6/25/2012] @@ -99,6 +104,8 @@ namespace AZ if (SerializeContext* serializeContext = azrtti_cast(context)) { + AZ::Data::AssetLoadBehaviorReflect(*serializeContext); + serializeContext->RegisterGenericType>(); serializeContext->Class() diff --git a/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h b/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h index e5bc76cd19..6806232337 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h +++ b/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h @@ -14,8 +14,6 @@ #include -#include - #include #include diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index 5357ed66a6..c6ad90200b 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -35,6 +35,8 @@ set(FILES Asset/AssetSerializer.h Asset/AssetTypeInfoBus.h Asset/AssetInternal/WeakAsset.h + Asset/SerializedAssetTracker.cpp + Asset/SerializedAssetTracker.h Casting/lossy_cast.h Casting/numeric_cast.h Component/Component.cpp diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 81233069a9..a4e9d207be 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -342,6 +343,45 @@ namespace AzToolsFramework m_validateEntitiesCallback = AZStd::move(validateEntitiesCallback); } + void LoadReferencedAssets(AZStd::vector>& referencedAssets) + { + for (AZ::Data::Asset& asset : referencedAssets) + { + if (!asset.GetId().IsValid()) + { + continue; + } + + const AZ::Data::AssetLoadBehavior loadBehavior = asset.GetAutoLoadBehavior(); + + if (loadBehavior == AZ::Data::AssetLoadBehavior::NoLoad) + { + continue; + } + + AZ::Data::AssetId assetId = asset.GetId(); + AZ::Data::AssetType assetType = asset.GetType(); + const bool blockingLoad = loadBehavior == AZ::Data::AssetLoadBehavior::PreLoad; + + asset = AZ::Data::AssetManager::Instance().GetAsset(assetId, assetType, loadBehavior); + + if (!asset.GetId().IsValid()) + { + continue; + } + + if (blockingLoad) + { + asset.BlockUntilLoadComplete(); + + if (asset.IsError()) + { + continue; + } + } + } + } + void PrefabEditorEntityOwnershipService::StartPlayInEditor() { // This is a workaround until the replacement for GameEntityContext is done @@ -381,13 +421,15 @@ namespace AzToolsFramework rootSpawnableIndex = m_playInEditorData.m_assets.size(); } + LoadReferencedAssets(product.GetReferencedAssets()); + AZ::Data::AssetInfo info; info.m_assetId = product.GetAsset().GetId(); info.m_assetType = product.GetAssetType(); info.m_relativePath = product.GetId(); AZ::Data::AssetCatalogRequestBus::Broadcast( - &AZ::Data::AssetCatalogRequestBus::Events::RegisterAsset, product.GetAsset().GetId(), info); + &AZ::Data::AssetCatalogRequestBus::Events::RegisterAsset, info.m_assetId, info); m_playInEditorData.m_assets.emplace_back(product.ReleaseAsset().release(), AZ::Data::AssetLoadBehavior::Default); } @@ -398,6 +440,8 @@ namespace AzToolsFramework m_playInEditorData.m_entities.SpawnAllEntities(); } + AZ::Data::AssetManager::Instance().DispatchEvents(); + // This is a workaround until the replacement for GameEntityContext is done AzFramework::GameEntityContextEventBus::Broadcast( &AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesStarted); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index d53aeaa241..ae1737f907 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -11,8 +11,10 @@ */ #include +#include #include #include + #include #include #include @@ -115,6 +117,49 @@ namespace AzToolsFramework return true; } + bool LoadInstanceFromPrefabDom( + Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& loadedAssets, LoadInstanceFlags flags) + { + // When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will + // be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload + // is avoided. + AZ::Data::AssetManager::Instance().SuspendAssetRelease(); + + InstanceEntityIdMapper entityIdMapper; + entityIdMapper.SetLoadingInstance(instance); + if ((flags & LoadInstanceFlags::AssignRandomEntityId) == LoadInstanceFlags::AssignRandomEntityId) + { + entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random); + } + + AZ::Data::SerializedAssetTracker assetTracker; + + AZ::JsonDeserializerSettings settings; + // The InstanceEntityIdMapper is registered twice because it's used in several places during deserialization where one is + // specific for the InstanceEntityIdMapper and once for the generic JsonEntityIdMapper. Because the Json Serializer's meta + // data has strict typing and doesn't look for inheritance both have to be explicitly added so they're found both locations. + settings.m_metadata.Add(static_cast(&entityIdMapper)); + settings.m_metadata.Add(&entityIdMapper); + settings.m_metadata.Add(&assetTracker); + + AZ::JsonSerializationResult::ResultCode result = + AZ::JsonSerialization::Load(instance, prefabDom, settings); + + AZ::Data::AssetManager::Instance().ResumeAssetRelease(); + + if (result.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted) + { + AZ_Error("Prefab", false, + "Failed to de-serialize Prefab Instance from Prefab DOM. " + "Unable to proceed."); + + return false; + } + + loadedAssets = assetTracker.GetTrackedAssets(); + return true; + } + bool LoadInstanceFromPrefabDom( Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadInstanceFlags flags) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index c4b988e36f..1f000c2f70 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -13,6 +13,7 @@ #pragma once #include +#include #include #include @@ -67,6 +68,16 @@ namespace AzToolsFramework bool LoadInstanceFromPrefabDom( Instance& instance, const PrefabDom& prefabDom, LoadInstanceFlags flags = LoadInstanceFlags::None); + /** + * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. + * @param instance The Instance to load. + * @param prefabDom the prefabDom that will be used to load the Instance data. + * @param shouldClearContainers whether to clear containers in Instance while loading. + * @return bool on whether the operation succeeded. + */ + bool LoadInstanceFromPrefabDom( + Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& loadedAssets, LoadInstanceFlags flags = LoadInstanceFlags::None); + /** * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. * @param instance The Instance to load. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp index 5d8f1f35e3..9ae795dbf1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp @@ -20,6 +20,8 @@ #include #include +#include + namespace AzToolsFramework::Prefab::PrefabConversionUtils { void PrefabCatchmentProcessor::Process(PrefabProcessorContext& context) @@ -63,7 +65,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AZStd::move(uniqueName), context.GetSourceUuid(), AZStd::move(serializer)); AZ_Assert(spawnable, "Failed to create a new spawnable."); - bool result = SpawnableUtils::CreateSpawnable(*spawnable, prefab); + Prefab::PrefabDomUtils::PrintPrefabDomValue("Prefab used for spawnable", prefab); + bool result = SpawnableUtils::CreateSpawnable(*spawnable, prefab, object.GetReferencedAssets()); if (result) { AzFramework::Spawnable::EntityList& entities = spawnable->GetEntities(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.cpp index ee45c258ff..78d1332a71 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.cpp @@ -56,6 +56,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return *m_asset; } + AZStd::vector>& ProcessedObjectStore::GetReferencedAssets() + { + return m_referencedAssets; + } + + const AZStd::vector>& ProcessedObjectStore::GetReferencedAssets() const + { + return m_referencedAssets; + } + AZStd::unique_ptr ProcessedObjectStore::ReleaseAsset() { return AZStd::move(m_asset); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h index a24d1f24c5..48e0007516 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h @@ -48,6 +48,10 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AZ::Data::AssetData& GetAsset(); AZStd::unique_ptr ReleaseAsset(); + AZStd::vector>& GetReferencedAssets(); + const AZStd::vector>& GetReferencedAssets() const; + + const AZStd::string& GetId() const; private: @@ -55,6 +59,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils SerializerFunction m_assetSerializer; AZStd::unique_ptr m_asset; + AZStd::vector> m_referencedAssets; AZStd::string m_uniqueId; }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp index 713a5d8205..085758cda9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp @@ -28,16 +28,17 @@ namespace AzToolsFramework::Prefab::SpawnableUtils AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom) { AzFramework::Spawnable spawnable; - [[maybe_unused]] bool result = CreateSpawnable(spawnable, prefabDom); + AZStd::vector> referencedAssets; + [[maybe_unused]] bool result = CreateSpawnable(spawnable, prefabDom, referencedAssets); AZ_Assert(result, "Failed to Load Prefab Instance from given Prefab DOM while Spawnable creation."); return spawnable; } - bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom) + bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets) { Instance instance; - if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(instance, prefabDom, + if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(instance, prefabDom, referencedAssets, Prefab::PrefabDomUtils::LoadInstanceFlags::AssignRandomEntityId)) // Always assign random entity ids because the spawnable is // going to be used to create clones of the entities. { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h index 74cbbcb1e4..c30e5ea77a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h @@ -18,7 +18,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils { AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom); - bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom); + bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets); void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable); } // namespace AzToolsFramework::Prefab::SpawnableUtils From 49941036276264c3248b42cf2fdba9fe8469f386 Mon Sep 17 00:00:00 2001 From: srikappa Date: Mon, 10 May 2021 11:58:54 -0700 Subject: [PATCH 053/225] Add const ref function parameters as needed --- .../Prefab/PrefabSystemComponent.cpp | 6 +++--- .../Prefab/PrefabSystemComponent.h | 2 +- .../Prefab/PrefabSystemComponentInterface.h | 6 +++--- .../AzToolsFramework/Prefab/PrefabUndo.cpp | 14 +------------- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index 0b447ef786..985d2333bc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -583,7 +583,7 @@ namespace AzToolsFramework const TemplateId& linkTargetId, const TemplateId& linkSourceId, const InstanceAlias& instanceAlias, - PrefabDom linkPatch, + const PrefabDomConstReference linkPatches, const LinkId& linkId) { if (linkTargetId == InvalidTemplateId) @@ -667,9 +667,9 @@ namespace AzToolsFramework rapidjson::StringRef(PrefabDomUtils::SourceName), rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()), newLink.GetLinkDom().GetAllocator()); - if (linkPatch.IsArray() && !(linkPatch.Empty())) + if (linkPatches && linkPatches->get().IsArray() && !(linkPatches->get().Empty())) { - m_instanceToTemplatePropagator.AddPatchesToLink(AZStd::move(linkPatch), newLink); + m_instanceToTemplatePropagator.AddPatchesToLink(linkPatches.value(), newLink); } //update the target template dom to have the proper values for the source template dom diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h index b5f499296d..0a9a450f64 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h @@ -156,7 +156,7 @@ namespace AzToolsFramework const TemplateId& linkTargetId, const TemplateId& linkSourceId, const InstanceAlias& instanceAlias, - PrefabDom linkPatch, + const PrefabDomConstReference linkPatches, const LinkId& linkId = InvalidLinkId) override; /** diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h index 347b48a648..f47941254a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h @@ -43,9 +43,9 @@ namespace AzToolsFramework PrefabDomValue::MemberIterator& instanceIterator, InstanceOptionalReference instance) = 0; //creates a new Link - virtual LinkId CreateLink(const TemplateId& linkTargetId, const TemplateId& linkSourceId, - const InstanceAlias& instanceAlias, PrefabDom linkPatch, - const LinkId& linkId = InvalidLinkId) = 0; + virtual LinkId CreateLink( + const TemplateId& linkTargetId, const TemplateId& linkSourceId, const InstanceAlias& instanceAlias, + const PrefabDomConstReference linkPatches, const LinkId& linkId = InvalidLinkId) = 0; virtual void RemoveLink(const LinkId& linkId) = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp index e82e9da90a..aadcdcdea0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp @@ -190,9 +190,7 @@ namespace AzToolsFramework void PrefabUndoInstanceLink::AddLink() { - PrefabDom linkPatchesCopy; - linkPatchesCopy.CopyFrom(m_linkPatches, linkPatchesCopy.GetAllocator()); - m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, AZStd::move(linkPatchesCopy), m_linkId); + m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkPatches, m_linkId); } void PrefabUndoInstanceLink::RemoveLink() @@ -230,9 +228,6 @@ namespace AzToolsFramework m_linkDomPrevious.CopyFrom(link->get().GetLinkDom(), m_linkDomPrevious.GetAllocator()); } - PrefabDomUtils::PrintPrefabDomValue("m_linkDomPrevious is : ", m_linkDomPrevious); - PrefabDomUtils::PrintPrefabDomValue("link->get().GetLinkDom() is : ", link->get().GetLinkDom()); - //get source templateDom TemplateReference sourceTemplate = m_prefabSystemComponentInterface->FindTemplate(link->get().GetSourceTemplateId()); @@ -305,15 +300,8 @@ namespace AzToolsFramework return; } - /* - PrefabDom moveLink; - moveLink.CopyFrom(linkDom, linkDom.GetAllocator()); - link->get().GetLinkDom() = AZStd::move(moveLink); - */ link->get().SetLinkDom(linkDom); - PrefabDomUtils::PrintPrefabDomValue("dom after updating link is : ", link->get().GetLinkDom()); - //propagate the link changes link->get().UpdateTarget(); m_prefabSystemComponentInterface->PropagateTemplateChanges(link->get().GetTargetTemplateId()); From 2e9ae76596c87ff5b3f7d2b62a4892922090a2ca Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 12:11:53 -0700 Subject: [PATCH 054/225] Removed print statement, adding in new files that were missed --- .../Registry/editorpreferences.setreg | 3 +- .../AzCore/Asset/SerializedAssetTracker.cpp | 29 ++++++++++++++++ .../AzCore/Asset/SerializedAssetTracker.h | 33 +++++++++++++++++++ .../Prefab/PrefabDomUtils.cpp | 4 +-- .../AzToolsFramework/Prefab/PrefabDomUtils.h | 3 +- .../Spawnable/PrefabCatchmentProcessor.cpp | 3 -- 6 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp create mode 100644 Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h diff --git a/AutomatedTesting/Registry/editorpreferences.setreg b/AutomatedTesting/Registry/editorpreferences.setreg index d7afc9e0ae..b338d6acad 100644 --- a/AutomatedTesting/Registry/editorpreferences.setreg +++ b/AutomatedTesting/Registry/editorpreferences.setreg @@ -1,8 +1,7 @@ { "Amazon": { "Preferences": { - "EnablePrefabSystem": true, - "EnablePrefabSystemWipFeatures": true + "EnablePrefabSystem": false } } } \ No newline at end of file diff --git a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp new file mode 100644 index 0000000000..b3fad2431f --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp @@ -0,0 +1,29 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include + +namespace AZ +{ + namespace Data + { + void SerializedAssetTracker::AddAsset(Asset& asset) + { + m_serializedAssets.emplace_back(asset); + } + + const AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() const + { + return m_serializedAssets; + } + } +} diff --git a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h new file mode 100644 index 0000000000..e1b0af72e1 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h @@ -0,0 +1,33 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#include +#include +namespace AZ +{ + namespace Data + { + class SerializedAssetTracker + { + public: + AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}"); + + void AddAsset(Asset& asset); + const AZStd::vector>& GetTrackedAssets() const; + + private: + AZStd::vector> m_serializedAssets; + }; + } +} diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index ae1737f907..9163b681de 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -118,7 +118,7 @@ namespace AzToolsFramework } bool LoadInstanceFromPrefabDom( - Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& loadedAssets, LoadInstanceFlags flags) + Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets, LoadInstanceFlags flags) { // When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will // be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload @@ -156,7 +156,7 @@ namespace AzToolsFramework return false; } - loadedAssets = assetTracker.GetTrackedAssets(); + referencedAssets = AZStd::move(assetTracker.GetTrackedAssets()); return true; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index 1f000c2f70..c0992abda9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -76,7 +76,8 @@ namespace AzToolsFramework * @return bool on whether the operation succeeded. */ bool LoadInstanceFromPrefabDom( - Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& loadedAssets, LoadInstanceFlags flags = LoadInstanceFlags::None); + Instance& instance, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets, + LoadInstanceFlags flags = LoadInstanceFlags::None); /** * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp index 9ae795dbf1..a89b364471 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp @@ -20,8 +20,6 @@ #include #include -#include - namespace AzToolsFramework::Prefab::PrefabConversionUtils { void PrefabCatchmentProcessor::Process(PrefabProcessorContext& context) @@ -65,7 +63,6 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils AZStd::move(uniqueName), context.GetSourceUuid(), AZStd::move(serializer)); AZ_Assert(spawnable, "Failed to create a new spawnable."); - Prefab::PrefabDomUtils::PrintPrefabDomValue("Prefab used for spawnable", prefab); bool result = SpawnableUtils::CreateSpawnable(*spawnable, prefab, object.GetReferencedAssets()); if (result) { From b57dd02d90139ce33928d2d5cba1d569c8b8e7dd Mon Sep 17 00:00:00 2001 From: srikappa Date: Mon, 10 May 2021 12:28:33 -0700 Subject: [PATCH 055/225] Removed a debug print command --- .../AzToolsFramework/Prefab/PrefabPublicHandler.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 9959ae18fa..4d1a657245 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -297,7 +297,7 @@ namespace AzToolsFramework else { linkId = m_prefabSystemComponentInterface->CreateLink( - targetTemplateId, sourceInstance.GetTemplateId(), sourceInstance.GetInstanceAlias(), AZStd::move(patch), + targetTemplateId, sourceInstance.GetTemplateId(), sourceInstance.GetInstanceAlias(), patch, InvalidLinkId); m_prefabSystemComponentInterface->PropagateTemplateChanges(targetTemplateId); } @@ -439,8 +439,6 @@ namespace AzToolsFramework PrefabDom patch; m_instanceToTemplateInterface->GeneratePatch(patch, beforeState, afterState); - PrefabDomUtils::PrintPrefabDomValue(entity->GetName(), patch); - if (patch.IsArray() && !patch.Empty() && beforeState.IsObject()) { if (IsInstanceContainerEntity(entityId) && !IsLevelInstanceContainerEntity(entityId)) From 1e232294d564f0fa80190549ee77850807b1b9d1 Mon Sep 17 00:00:00 2001 From: Aristo7 <5432499+Aristo7@users.noreply.github.com> Date: Mon, 10 May 2021 14:36:32 -0500 Subject: [PATCH 056/225] Added Null RHI to all targets --- Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt index 30861a6feb..33873e0dfa 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt @@ -54,6 +54,7 @@ ly_add_target( RUNTIME_DEPENDENCIES Gem::Atom_RHI.Private Gem::Atom_RPI.Private + Gem::Atom_RHI_Null.Private Gem::Atom_Feature_Common Gem::Atom_Bootstrap Gem::Atom_Component_DebugCamera @@ -89,6 +90,8 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) Gem::Atom_RHI.Private Gem::Atom_RPI.Builders Gem::Atom_RPI.Editor + Gem::Atom_RHI_Null.Private + Gem::Atom_RHI_Null.Builders Gem::Atom_Feature_Common.Builders Gem::Atom_Feature_Common.Editor Gem::Atom_Bootstrap From 4c0fdf78bcfe5918d4ac69a93db44d5f401b3e58 Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 12:56:54 -0700 Subject: [PATCH 057/225] Added error messaging, cleaned up LoadReferencedAssets --- .../Entity/PrefabEditorEntityOwnershipService.cpp | 7 ++++++- .../Entity/PrefabEditorEntityOwnershipService.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index a4e9d207be..0206875418 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -343,12 +343,13 @@ namespace AzToolsFramework m_validateEntitiesCallback = AZStd::move(validateEntitiesCallback); } - void LoadReferencedAssets(AZStd::vector>& referencedAssets) + void PrefabEditorEntityOwnershipService::LoadReferencedAssets(AZStd::vector>& referencedAssets) { for (AZ::Data::Asset& asset : referencedAssets) { if (!asset.GetId().IsValid()) { + AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode"); continue; } @@ -367,6 +368,7 @@ namespace AzToolsFramework if (!asset.GetId().IsValid()) { + AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode"); continue; } @@ -376,6 +378,9 @@ namespace AzToolsFramework if (asset.IsError()) { + AZ_Error("Prefab", false, "Asset with id %s failed to preload while entering game mode", + asset.GetId().ToString().c_str()); + continue; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h index 9c483e61c5..48e07df091 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h @@ -199,6 +199,8 @@ namespace AzToolsFramework void OnEntityRemoved(AZ::EntityId entityId); + void LoadReferencedAssets(AZStd::vector>& referencedAssets); + OnEntitiesAddedCallback m_entitiesAddedCallback; OnEntitiesRemovedCallback m_entitiesRemovedCallback; ValidateEntitiesCallback m_validateEntitiesCallback; From 17ccf904801e1d0480670f6ef79277c03748d6b4 Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 12:59:16 -0700 Subject: [PATCH 058/225] Updated function header comment --- .../AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index c0992abda9..6778c236ee 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -71,6 +71,7 @@ namespace AzToolsFramework /** * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. * @param instance The Instance to load. + * @param referencedAssets AZ::Assets discovered during json load are added to this list * @param prefabDom the prefabDom that will be used to load the Instance data. * @param shouldClearContainers whether to clear containers in Instance while loading. * @return bool on whether the operation succeeded. From 9255e4c1917c91396e678f8d3b9e54df842aeaab Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 13:05:29 -0700 Subject: [PATCH 059/225] Added non const getter to SerializedAssetTracker --- .../Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp | 5 +++++ Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h | 1 + 2 files changed, 6 insertions(+) diff --git a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp index b3fad2431f..bdd89683f6 100644 --- a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp @@ -25,5 +25,10 @@ namespace AZ { return m_serializedAssets; } + + AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() + { + return m_serializedAssets; + } } } diff --git a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h index e1b0af72e1..ad80a077fe 100644 --- a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h +++ b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h @@ -24,6 +24,7 @@ namespace AZ AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}"); void AddAsset(Asset& asset); + AZStd::vector>& GetTrackedAssets(); const AZStd::vector>& GetTrackedAssets() const; private: From 3b55d56593095bedc622c4d72102efeffe9d6ff8 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 10 May 2021 15:10:32 -0500 Subject: [PATCH 060/225] Updating test asset for DistanceBetweenFilter tests --- AutomatedTesting/Slices/1m_Cube.slice | 49 +++++++++++---------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/AutomatedTesting/Slices/1m_Cube.slice b/AutomatedTesting/Slices/1m_Cube.slice index 5ace34bd10..b31869c7fa 100644 --- a/AutomatedTesting/Slices/1m_Cube.slice +++ b/AutomatedTesting/Slices/1m_Cube.slice @@ -39,6 +39,7 @@ + @@ -61,7 +62,7 @@ - + @@ -122,38 +123,26 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + From a768c28b31339dfaf01844dc92054bd9f631b8f7 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 10 May 2021 15:11:28 -0500 Subject: [PATCH 061/225] Adding Qtest as a dependency of Editor automated tests --- AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 3124f1048a..11ee414b36 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -366,6 +366,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ Legacy::Editor AZ::AssetProcessor AutomatedTesting.Assets + 3rdParty::Qt::Test COMPONENT Editor ) From ed8d79d1f5ed89d78cc86e5a88b4be8719b0726c Mon Sep 17 00:00:00 2001 From: karlberg Date: Mon, 10 May 2021 13:11:36 -0700 Subject: [PATCH 062/225] Potential fix for build failures in main --- .../Code/Tests/ImageProcessing_Test.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Tests/ImageProcessing_Test.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Tests/ImageProcessing_Test.cpp index c94978c63d..540178f4d9 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Tests/ImageProcessing_Test.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Tests/ImageProcessing_Test.cpp @@ -95,32 +95,32 @@ namespace UnitTest class ImageProcessingTest : public ::testing::Test , public AllocatorsBase - , public ComponentApplicationBus::Handler + , public AZ::ComponentApplicationBus::Handler { public: ////////////////////////////////////////////////////////////////////////// // ComponentApplicationMessages. - ComponentApplication* GetApplication() override { return nullptr; } - void RegisterComponentDescriptor(const ComponentDescriptor*) override { } - void UnregisterComponentDescriptor(const ComponentDescriptor*) override { } - void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler&) override { } - void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler&) override { } - void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler&) override { } - void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler&) override { } - void SignalEntityActivated(Entity*) override { } - void SignalEntityDeactivated(Entity*) override { } - bool AddEntity(Entity*) override { return false; } - bool RemoveEntity(Entity*) override { return false; } - bool DeleteEntity(const EntityId&) override { return false; } - Entity* FindEntity(const EntityId&) override { return nullptr; } - SerializeContext* GetSerializeContext() override { return m_context.get(); } - BehaviorContext* GetBehaviorContext() override { return nullptr; } + AZ::ComponentApplication* GetApplication() override { return nullptr; } + void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override { } + void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override { } + void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override { } + void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override { } + void RegisterEntityActivatedEventHandler(AZ::EntityActivatedEvent::Handler&) override { } + void RegisterEntityDeactivatedEventHandler(AZ::EntityDeactivatedEvent::Handler&) override { } + void SignalEntityActivated(AZ::Entity*) override { } + void SignalEntityDeactivated(AZ::Entity*) override { } + bool AddEntity(AZ::Entity*) override { return false; } + bool RemoveEntity(AZ::Entity*) override { return false; } + bool DeleteEntity(const AZ::EntityId&) override { return false; } + Entity* FindEntity(const AZ::EntityId&) override { return nullptr; } + AZ::SerializeContext* GetSerializeContext() override { return m_context.get(); } + AZ::BehaviorContext* GetBehaviorContext() override { return nullptr; } AZ::JsonRegistrationContext* GetJsonRegistrationContext() override { return m_jsonRegistrationContext.get(); } const char* GetAppRoot() const override { return nullptr; } const char* GetEngineRoot() const override { return nullptr; } const char* GetExecutableFolder() const override { return nullptr; } - Debug::DrillerManager* GetDrillerManager() override { return nullptr; } - void EnumerateEntities(const EntityCallback& /*callback*/) override {} + AZ::Debug::DrillerManager* GetDrillerManager() override { return nullptr; } + void EnumerateEntities(const AZ::ComponentApplicationRequests::EntityCallback& /*callback*/) override {} void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override {} ////////////////////////////////////////////////////////////////////////// From fc03734b41f5b96e19b7c17b65104ebf2b339044 Mon Sep 17 00:00:00 2001 From: evanchia Date: Mon, 10 May 2021 13:16:06 -0700 Subject: [PATCH 063/225] Fixes dedicated servers in LyTestTools --- .../pytest_plugin/test_tools_fixtures.py | 4 +-- .../ly_test_tools/launchers/platforms/base.py | 12 ++++---- .../launchers/platforms/win/launcher.py | 29 ++++++++++++++++--- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py index c4249441b0..e09b1ab54c 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py @@ -29,7 +29,7 @@ import ly_test_tools.environment.file_system import ly_test_tools.launchers.launcher_helper import ly_test_tools.launchers.platforms.base import ly_test_tools.environment.watchdog -from ly_test_tools import ALL_PLATFORM_OPTIONS, HOST_OS_PLATFORM +from ly_test_tools import ALL_PLATFORM_OPTIONS, HOST_OS_PLATFORM, HOST_OS_DEDICATED_SERVER logger = logging.getLogger(__name__) @@ -260,7 +260,7 @@ def dedicated_launcher(request, workspace, crash_log_watchdog): return _dedicated_launcher( request=request, workspace=workspace, - launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_PLATFORM), + launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_DEDICATED_SERVER), level=get_fixture_argument(request, 'level', '')) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py index 6b53c1f8f3..36746b510f 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py @@ -70,7 +70,7 @@ class Launcher(object): return config_dict - def setup(self, backupFiles = True, launch_ap = True): + def setup(self, backupFiles=True, launch_ap=True): """ Perform setup of this launcher, must be called before launching. Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files @@ -193,7 +193,7 @@ class Launcher(object): """ raise NotImplementedError("There is no binary file for this launcher") - def start(self, backupFiles = True, launch_ap = True): + def start(self, backupFiles=True, launch_ap=None): """ Automatically prepare and launch the application When called using "with launcher.start():" it will automatically call stop() when block exits @@ -203,14 +203,14 @@ class Launcher(object): """ return _Application(self, backupFiles, launch_ap=launch_ap) - def _start_impl(self, backupFiles = True, launch_ap=True): + def _start_impl(self, backupFiles = True, launch_ap=None): """ Implementation of start(), intended to be called via context manager in _Application :param backupFiles: Bool to backup settings files :return None: """ - self.setup(backupFiles, launch_ap=launch_ap) + self.setup(backupFiles=backupFiles, launch_ap=launch_ap) self.launch() def stop(self): @@ -326,7 +326,7 @@ class _Application(object): """ Context-manager for opening an application, enables using both "launcher.start()" and "with launcher.start()" """ - def __init__(self, launcher, backupFiles = True, launch_ap = True): + def __init__(self, launcher, backupFiles = True, launch_ap=None): """ Called during both "launcher.start()" and "with launcher.start()" @@ -334,7 +334,7 @@ class _Application(object): :return None: """ self.launcher = launcher - launcher._start_impl(backupFiles, launch_ap=launch_ap) + launcher._start_impl(backupFiles, launch_ap) def __enter__(self): """ diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py index 800771c9bc..47c24098ed 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py @@ -42,21 +42,26 @@ class WinLauncher(Launcher): assert self.workspace.project is not None return os.path.join(self.workspace.paths.build_directory(), f"{self.workspace.project}.GameLauncher.exe") - def setup(self, backupFiles = True, launch_ap = True): + def setup(self, backupFiles=True, launch_ap=True): """ Perform setup of this launcher, must be called before launching. Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files :param backupFiles: Bool to backup setup files + :param lauch_ap: Bool to lauch the asset processor :return: None """ # Backup if backupFiles: self.backup_settings() + # Base setup defaults to None + if launch_ap is None: + launch_ap = True + # Modify and re-configure self.configure_settings() - super(WinLauncher, self).setup(launch_ap=launch_ap) + super(WinLauncher, self).setup(backupFiles, launch_ap) def launch(self): """ @@ -177,6 +182,21 @@ class WinLauncher(Launcher): class DedicatedWinLauncher(WinLauncher): + def setup(self, backupFiles=True, launch_ap=False): + """ + Perform setup of this launcher, must be called before launching. + Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files + + :param backupFiles: Bool to backup setup files + :param lauch_ap: Bool to lauch the asset processor + :return: None + """ + # Base setup defaults to None + if launch_ap is None: + launch_ap = False + + super(DedicatedWinLauncher, self).setup(backupFiles, launch_ap) + def binary_path(self): """ Return full path to the dedicated server launcher for the build directory. @@ -185,8 +205,9 @@ class DedicatedWinLauncher(WinLauncher): """ assert self.workspace.project is not None, ( 'Project cannot be NoneType - please specify a project name string.') - return os.path.join(f"{self.workspace.paths.build_directory()}", - f"{self.workspace.project}.ServerLauncher.exe") + return "C:\Program Files\Sublime Text 3\sublime_text.exe" + # return os.path.join(f"{self.workspace.paths.build_directory()}", + # f"{self.workspace.project}.ServerLauncher.exe") class WinEditor(WinLauncher): From f7ea02afdcd554eac29a0d3b6101071bbeccd24d Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 13:21:13 -0700 Subject: [PATCH 064/225] Fix for NetworkingProcessor using CreateSpawnable without ReferencedAssets arg --- .../AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp | 6 ++++++ .../AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h | 1 + 2 files changed, 7 insertions(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp index 085758cda9..716c3098d9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.cpp @@ -35,6 +35,12 @@ namespace AzToolsFramework::Prefab::SpawnableUtils return spawnable; } + bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom) + { + AZStd::vector> referencedAssets; + return CreateSpawnable(spawnable, prefabDom, referencedAssets); + } + bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets) { Instance instance; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h index c30e5ea77a..3b5ea488cb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h @@ -18,6 +18,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils { AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom); + bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom); bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector>& referencedAssets); void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable); From e37b3989bedc1b4c3beec5bdd8268a9ff38fb624 Mon Sep 17 00:00:00 2001 From: pruiksma Date: Mon, 10 May 2021 15:31:33 -0500 Subject: [PATCH 065/225] ATOM-15515 Fixing nullptr reference in OnShapeChanged() when visibility is turned back on for shapeless punctual light types. --- .../Code/Source/CoreLights/LightDelegateBase.inl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateBase.inl b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateBase.inl index 406df42547..c255f02400 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateBase.inl +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateBase.inl @@ -101,6 +101,7 @@ namespace AZ template void LightDelegateBase::OnShapeChanged(ShapeChangeReasons changeReason) { + AZ_Assert(m_shapeBus, "OnShapeChanged called without a shape bus present."); if (changeReason == ShapeChangeReasons::TransformChanged) { AZ::Aabb aabb; // unused, but required for GetTransformAndLocalBounds() @@ -133,7 +134,11 @@ namespace AZ { // now visible, acquire light handle and update values. m_lightHandle = m_featureProcessor->AcquireLight(); - OnShapeChanged(ShapeChangeReasons::TransformChanged); + if (m_shapeBus) + { + // For lights that get their transform from the shape bus, force an OnShapeChanged to update the transform. + OnShapeChanged(ShapeChangeReasons::TransformChanged); + } } } From 8044760613db5be48e889aa7f45c4b2effab6dab Mon Sep 17 00:00:00 2001 From: Vicky <55564570+VickyAtAZ@users.noreply.github.com> Date: Mon, 10 May 2021 13:33:51 -0700 Subject: [PATCH 066/225] ATOM-15446 ImGui assert with Editor debug build (#622) Disable the assert as short term solution. A proper fix will be addressed in ATOM-15495 --- Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp b/Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp index 2555d1a6af..c2db0da54a 100644 --- a/Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp +++ b/Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp @@ -7118,7 +7118,9 @@ static void ImGui::ErrorCheckEndFrameSanityChecks() // We silently accommodate for this case by ignoring/ the case where all io.KeyXXX modifiers were released (aka key_mod_flags == 0), // while still correctly asserting on mid-frame key press events. const ImGuiKeyModFlags key_mod_flags = GetMergedKeyModFlags(); - IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); + + // [GFX TODO] Commented this line until Atom ImGuiPass is refactored (ATOM-15495). + // IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); IM_UNUSED(key_mod_flags); // Recover from errors From b6890eef5cc5e6070210c775c020ba407bc6f311 Mon Sep 17 00:00:00 2001 From: evanchia Date: Mon, 10 May 2021 13:36:05 -0700 Subject: [PATCH 067/225] removed debugging text --- .../ly_test_tools/launchers/platforms/win/launcher.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py index 47c24098ed..138d788b9f 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py @@ -205,9 +205,8 @@ class DedicatedWinLauncher(WinLauncher): """ assert self.workspace.project is not None, ( 'Project cannot be NoneType - please specify a project name string.') - return "C:\Program Files\Sublime Text 3\sublime_text.exe" - # return os.path.join(f"{self.workspace.paths.build_directory()}", - # f"{self.workspace.project}.ServerLauncher.exe") + return os.path.join(f"{self.workspace.paths.build_directory()}", + f"{self.workspace.project}.ServerLauncher.exe") class WinEditor(WinLauncher): From f856bd26b08cb63bf67e14800ff42d2a25f5f6cb Mon Sep 17 00:00:00 2001 From: moudgils Date: Mon, 10 May 2021 13:58:43 -0700 Subject: [PATCH 068/225] Propogated fixes to other RHI backends --- .../RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp | 12 ++++++++++-- .../RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp | 10 +++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp index f816a7ae04..ec18b985ff 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp @@ -267,7 +267,7 @@ namespace AZ // Staging sizes uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, DX12_TEXTURE_DATA_PITCH_ALIGNMENT); uint32_t stagingSlicePitch = RHI::AlignUp(subresourceLayout.m_rowCount*stagingRowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); - const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount; + const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_numBlocksHeight; // ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression. // Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images. @@ -382,7 +382,7 @@ namespace AZ const uint32_t numRowsToCopy = endRow - startRow; // Calculate the blocksize for BC formatted images; the copy command works in texels. - const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; + uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; // Copy subresource data to staging memory { @@ -398,6 +398,14 @@ namespace AZ } } + //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over + //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight + if(destHeight+heightToCopy > subresourceLayout.m_size.m_height) + { + uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height; + heightToCopy -= HeightDiff; + } + // Add copy command to copy image subresource from staging memory to image gpu resource // Source location diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp index a6e7ff082f..08d8fca9b3 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp @@ -214,7 +214,7 @@ namespace AZ const uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, bufferOffsetAlign); const uint32_t stagingSlicePitch = subresourceLayout.m_rowCount * stagingRowPitch; const uint32_t rowsPerSplit = static_cast(m_descriptor.m_stagingSizeInBytes) / stagingRowPitch; - const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount; + const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_numBlocksHeight; // ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression. // Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images. @@ -348,6 +348,14 @@ namespace AZ framePacket->m_stagingBuffer->GetBufferMemoryView()->Unmap(RHI::HostMemoryAccess::Write); } + //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over + //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight + if(destHeight+heightToCopy > subresourceLayout.m_size.m_height) + { + uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height; + heightToCopy -= HeightDiff; + } + // Add copy command to copy image subresource from staging memory to image GPU resource. copyDescriptor.m_destinationOrigin.m_top = destHeight; copyDescriptor.m_sourceSize.m_height = heightToCopy; From 45055ab3cc29bce1a2a31ee8847e3ddfb36fbee7 Mon Sep 17 00:00:00 2001 From: greerdv Date: Mon, 10 May 2021 22:01:41 +0100 Subject: [PATCH 069/225] applying debug draw transform stack to DrawLines and DrawTriangles --- .../AtomDebugDisplayViewportInterface.cpp | 31 +++++++++++++++---- .../AtomDebugDisplayViewportInterface.h | 6 ++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp index 8a063cd7a7..7a8d6b7494 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp @@ -506,9 +506,10 @@ namespace AZ::AtomBridge { if (m_auxGeomPtr) { + AZStd::vector transformedVertices = ToWorldSpacePosition(vertices); AZ::RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments drawArgs; - drawArgs.m_verts = vertices.data(); - drawArgs.m_vertCount = aznumeric_cast(vertices.size()); + drawArgs.m_verts = transformedVertices.data(); + drawArgs.m_vertCount = aznumeric_cast(transformedVertices.size()); drawArgs.m_colors = &color; drawArgs.m_colorCount = 1; drawArgs.m_opacityType = m_rendState.m_opacityType; @@ -526,9 +527,10 @@ namespace AZ::AtomBridge { if (m_auxGeomPtr) { + AZStd::vector transformedVertices = ToWorldSpacePosition(vertices); AZ::RPI::AuxGeomDraw::AuxGeomDynamicIndexedDrawArguments drawArgs; - drawArgs.m_verts = vertices.data(); - drawArgs.m_vertCount = aznumeric_cast(vertices.size()); + drawArgs.m_verts = transformedVertices.data(); + drawArgs.m_vertCount = aznumeric_cast(transformedVertices.size()); drawArgs.m_indices = indices.data(); drawArgs.m_indexCount = aznumeric_cast(indices.size()); drawArgs.m_colors = &color; @@ -659,9 +661,10 @@ namespace AZ::AtomBridge { if (m_auxGeomPtr) { + AZStd::vector transformedLines = ToWorldSpacePosition(lines); AZ::RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments drawArgs; - drawArgs.m_verts = lines.data(); - drawArgs.m_vertCount = aznumeric_cast(lines.size()); + drawArgs.m_verts = transformedLines.data(); + drawArgs.m_vertCount = aznumeric_cast(transformedLines.size()); drawArgs.m_colors = &color; drawArgs.m_colorCount = 1; drawArgs.m_size = m_rendState.m_lineWidth; @@ -1513,6 +1516,22 @@ namespace AZ::AtomBridge return m_rendState.m_transformStack[m_rendState.m_currentTransform]; } + AZStd::vector AtomDebugDisplayViewportInterface::ToWorldSpacePosition(const AZStd::vector& positions) const + { + AZStd::vector transformedPositions; + transformedPositions.resize_no_construct(positions.size()); + AZStd::transform(positions.begin(), positions.end(), transformedPositions.begin(), [this](const AZ::Vector3& position){ return ToWorldSpacePosition(position); }); + return transformedPositions; + } + + AZStd::vector AtomDebugDisplayViewportInterface::ToWorldSpaceVector(const AZStd::vector& vectors) const + { + AZStd::vector transformedVectors; + transformedVectors.resize_no_construct(vectors.size()); + AZStd::transform(vectors.begin(), vectors.end(), transformedVectors.begin(), [this](const AZ::Vector3& vector) { return ToWorldSpaceVector(vector); }); + return transformedVectors; + } + AZ::RPI::ViewportContextPtr AtomDebugDisplayViewportInterface::GetViewportContext() const { auto viewContextManager = AZ::Interface::Get(); diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h index c872e2b81e..5edd1f0a02 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h @@ -249,6 +249,12 @@ namespace AZ::AtomBridge //! Convert direction to world space (translation is not considered) AZ::Vector3 ToWorldSpaceVector(const AZ::Vector3& v) const { return m_rendState.m_transformStack[m_rendState.m_currentTransform].Multiply3x3(v); } + //! Convert position to world space. + AZStd::vector ToWorldSpacePosition(const AZStd::vector& positions) const; + + //! Convert direction to world space (translation is not considered) + AZStd::vector ToWorldSpaceVector(const AZStd::vector& vectors) const; + void CalcBasisVectors(const AZ::Vector3& n, AZ::Vector3& b1, AZ::Vector3& b2) const; const AZ::Matrix3x4& GetCurrentTransform() const; From 93974dd1c51cfcde72fe187a2072f6ffeb499da7 Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 14:22:48 -0700 Subject: [PATCH 070/225] Seperated queue load and blocking load calls so queue loads aren't interrupted. Added comment about asset dispatch events --- .../PrefabEditorEntityOwnershipService.cpp | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 0206875418..6b6f1475bb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -345,6 +345,7 @@ namespace AzToolsFramework void PrefabEditorEntityOwnershipService::LoadReferencedAssets(AZStd::vector>& referencedAssets) { + // Start our loads on all assets by calling GetAsset from the AssetManager for (AZ::Data::Asset& asset : referencedAssets) { if (!asset.GetId().IsValid()) @@ -362,7 +363,6 @@ namespace AzToolsFramework AZ::Data::AssetId assetId = asset.GetId(); AZ::Data::AssetType assetType = asset.GetType(); - const bool blockingLoad = loadBehavior == AZ::Data::AssetLoadBehavior::PreLoad; asset = AZ::Data::AssetManager::Instance().GetAsset(assetId, assetType, loadBehavior); @@ -371,18 +371,33 @@ namespace AzToolsFramework AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode"); continue; } + } - if (blockingLoad) + // For all Preload assets we block until they're ready + // We do this as a seperate pass so that we don't interrupt queuing up all other asset loads + for (AZ::Data::Asset& asset : referencedAssets) + { + if (!asset.GetId().IsValid()) { - asset.BlockUntilLoadComplete(); + AZ_Error("Prefab", false, "Invalid asset found referenced in scene while entering game mode"); + continue; + } - if (asset.IsError()) - { - AZ_Error("Prefab", false, "Asset with id %s failed to preload while entering game mode", - asset.GetId().ToString().c_str()); + const AZ::Data::AssetLoadBehavior loadBehavior = asset.GetAutoLoadBehavior(); - continue; - } + if (loadBehavior != AZ::Data::AssetLoadBehavior::PreLoad) + { + continue; + } + + asset.BlockUntilLoadComplete(); + + if (asset.IsError()) + { + AZ_Error("Prefab", false, "Asset with id %s failed to preload while entering game mode", + asset.GetId().ToString().c_str()); + + continue; } } } @@ -438,6 +453,9 @@ namespace AzToolsFramework m_playInEditorData.m_assets.emplace_back(product.ReleaseAsset().release(), AZ::Data::AssetLoadBehavior::Default); } + // make sure that PRE_NOTIFY assets get their notify before we activate, so that we can preserve the order of + // (load asset) -> (notify) -> (init) -> (activate) + AZ::Data::AssetManager::Instance().DispatchEvents(); if (rootSpawnableIndex != NoRootSpawnable) { @@ -445,8 +463,6 @@ namespace AzToolsFramework m_playInEditorData.m_entities.SpawnAllEntities(); } - AZ::Data::AssetManager::Instance().DispatchEvents(); - // This is a workaround until the replacement for GameEntityContext is done AzFramework::GameEntityContextEventBus::Broadcast( &AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesStarted); From 63b3dbefa82e6937b2a0eede1002a9a1fc520d03 Mon Sep 17 00:00:00 2001 From: mnaumov Date: Mon, 10 May 2021 14:24:45 -0700 Subject: [PATCH 071/225] Fixing parallax artifacts --- .../Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl | 2 +- Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl | 2 +- .../Materials/Types/StandardMultilayerPBR_ForwardPass.azsl | 2 +- .../Assets/Materials/Types/StandardPBR_ForwardPass.azsl | 4 ++-- .../Features/LightCulling/LightCullingTileIterator.azsli | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index 23e28e8742..367b2e379c 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -268,7 +268,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float LightingData lightingData; // Light iterator - lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.tileIterator.Init(IN.m_position.xy, IN.m_position.z, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); // Directional light shadow coordinates diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl index 84095ac163..c81d96d552 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl @@ -324,7 +324,7 @@ PbrLightingOutput SkinPS_Common(VSOutput IN) LightingData lightingData; // Light iterator - lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.tileIterator.Init(IN.m_position.xy, IN.m_position.z, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); // Directional light shadow coordinates diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl index a83ea629e4..5c527998c1 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl @@ -303,7 +303,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float LightingData lightingData; // Light iterator - lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.tileIterator.Init(IN.m_position.xy, IN.m_position.z, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); // Directional light shadow coordinates diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl index 22751b49bc..dc20f89a75 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl @@ -125,7 +125,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // ------- Depth & Parallax ------- - depth = IN.m_position.z; + depth = IN.m_position.w; bool displacementIsClipped = false; @@ -210,7 +210,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float LightingData lightingData; // Light iterator - lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.tileIterator.Init(IN.m_position.xy, IN.m_position.z, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); // Directional light shadow coordinates diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli index 001f672631..314a8951a4 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli @@ -17,13 +17,13 @@ // This class is used by forward shaders to iterate through lights (and decals) that are visible at this pixel position class LightCullingTileIterator { - void Init(float4 svPosition, StructuredBuffer lightListRemapped, Texture2D tileLightDataTex) + void Init(float2 screenPos, float depth, StructuredBuffer lightListRemapped, Texture2D tileLightDataTex) { m_lightListRemapped = lightListRemapped; - uint2 tileId = ComputeTileId(svPosition.xy); + uint2 tileId = ComputeTileId(screenPos); - float viewz = abs(svPosition.w); + float viewz = abs(depth); // https://jira.agscollab.com/browse/ATOM-4198 // Replace GetDimensions() with a cbuffer uint read. Reading it from a cbuffer should be faster From 8766790f48dae79da59fd60c73b124d0e9b191a2 Mon Sep 17 00:00:00 2001 From: jromnoa Date: Mon, 10 May 2021 14:28:02 -0700 Subject: [PATCH 072/225] re-add WinGenericLauncher for custom .exe launchers instead of the hard-coded ones (i.e. able to use 'MaterialEditor.exe' instead of 'Editor.exe' for a WinLauncher class) --- Tools/LyTestTools/ly_test_tools/__init__.py | 6 ++++-- .../pytest_plugin/test_tools_fixtures.py | 15 +++++++++++++++ .../ly_test_tools/launchers/launcher_helper.py | 16 ++++++++++++++++ .../launchers/platforms/win/launcher.py | 16 ++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/__init__.py b/Tools/LyTestTools/ly_test_tools/__init__.py index 1c78176b87..febb89b541 100755 --- a/Tools/LyTestTools/ly_test_tools/__init__.py +++ b/Tools/LyTestTools/ly_test_tools/__init__.py @@ -17,7 +17,7 @@ logger = logging.getLogger(__name__) # Supported platforms. ALL_PLATFORM_OPTIONS = ['android', 'ios', 'linux', 'mac', 'windows'] -ALL_LAUNCHER_OPTIONS = ['android', 'base', 'mac', 'windows', 'windows_editor', 'windows_dedicated'] +ALL_LAUNCHER_OPTIONS = ['android', 'base', 'mac', 'windows', 'windows_editor', 'windows_dedicated', 'windows_generic'] ANDROID = False IOS = False # Not implemented - see SPEC-2505 LINUX = sys.platform.startswith('linux') # Not implemented - see SPEC-2501 @@ -38,11 +38,13 @@ if WINDOWS: HOST_OS_EDITOR = 'windows_editor' HOST_OS_DEDICATED_SERVER = 'windows_dedicated' import ly_test_tools.mobile.android - from ly_test_tools.launchers import AndroidLauncher, WinLauncher, DedicatedWinLauncher, WinEditor + from ly_test_tools.launchers import ( + AndroidLauncher, WinLauncher, DedicatedWinLauncher, WinEditor, WinGenericLauncher) ANDROID = ly_test_tools.mobile.android.can_run_android() LAUNCHERS['windows'] = WinLauncher LAUNCHERS['windows_editor'] = WinEditor LAUNCHERS['windows_dedicated'] = DedicatedWinLauncher + LAUNCHERS['windows_generic'] = WinGenericLauncher LAUNCHERS['android'] = AndroidLauncher elif MAC: HOST_OS_PLATFORM = 'mac' diff --git a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py index c4249441b0..02b574ddf9 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py @@ -281,6 +281,21 @@ def _dedicated_launcher(request, workspace, launcher_platform, level=""): return launcher + +@pytest.fixture(scope="function") +def generic_launcher(workspace, request, crash_log_watchdog): + # type: (...) -> ly_test_tools.launchers.platforms.base.Launcher + return _generic_launcher( + workspace=workspace, + launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_PLATFORM), + exe_file_name=get_fixture_argument(request, 'exe_file_name', '')) + + +def _generic_launcher(workspace, launcher_platform, exe_file_name): + """Separate implementation to call directly during unit tests""" + return ly_test_tools.launchers.launcher_helper.create_generic_launcher(workspace, launcher_platform, exe_file_name) + + @pytest.fixture def automatic_process_killer(request): # type: (_pytest.fixtures.SubRequest) -> ly_process_killer diff --git a/Tools/LyTestTools/ly_test_tools/launchers/launcher_helper.py b/Tools/LyTestTools/ly_test_tools/launchers/launcher_helper.py index 4ed4c43dee..63b1eac1d3 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/launcher_helper.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/launcher_helper.py @@ -61,3 +61,19 @@ def create_editor(workspace, launcher_platform=ly_test_tools.HOST_OS_EDITOR, arg """ launcher_class = ly_test_tools.LAUNCHERS.get(launcher_platform, ly_test_tools.HOST_OS_EDITOR) return launcher_class(workspace, args) + + +def create_generic_launcher(workspace, launcher_platform, exe_file_name, args=None): + # type: (ly_test_tools.managers.workspace.WorkspaceManager, str, str, List[str]) -> Launcher + """ + Create a generic launcher compatible with the specified workspace. + Allows custom .exe files to serve as the launcher instead of ones listed in the ly_test_tools.LAUNCHERS constant + + :param workspace: lumberyard workspace to use + :param launcher_platform: the platform to target for a launcher (i.e. 'windows' for WinLauncher) + :param exe_file_name: .exe file name which has to be launched for this launcher (i.e. 'MaterialEditor.exe') + :param args: List of arguments to pass to the launcher's 'args' argument during construction + :return: Launcher instance. + """ + launcher_class = ly_test_tools.LAUNCHERS.get(launcher_platform, ly_test_tools.HOST_OS_PLATFORM) + return launcher_class(workspace, exe_file_name, args) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py index 800771c9bc..492af0e612 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py @@ -203,3 +203,19 @@ class WinEditor(WinLauncher): """ assert self.workspace.project is not None return os.path.join(self.workspace.paths.build_directory(), "Editor.exe") + + +class WinGenericLauncher(WinLauncher): + + def __init__(self, build, exe_file_name, args=None): + super(WinGenericLauncher, self).__init__(build, args) + self.exe_file_name = exe_file_name + + def binary_path(self): + """ + Return full path to the .exe file for this build's configuration and project + + :return: full path to the given exe file + """ + assert self.workspace.project is not None + return os.path.join(self.workspace.paths.build_directory(), f"{self.exe_file_name}.exe") From 58858994970fb1ce004215f055202d6251c12e92 Mon Sep 17 00:00:00 2001 From: jromnoa Date: Mon, 10 May 2021 14:44:47 -0700 Subject: [PATCH 073/225] fix tabbing, add WinGenericLauncher class import to ly_test_tools.launchers.__init__ --- .../_internal/pytest_plugin/test_tools_fixtures.py | 4 ++-- Tools/LyTestTools/ly_test_tools/launchers/__init__.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py index 02b574ddf9..c3a9ffdc22 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py @@ -287,8 +287,8 @@ def generic_launcher(workspace, request, crash_log_watchdog): # type: (...) -> ly_test_tools.launchers.platforms.base.Launcher return _generic_launcher( workspace=workspace, - launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_PLATFORM), - exe_file_name=get_fixture_argument(request, 'exe_file_name', '')) + launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_PLATFORM), + exe_file_name=get_fixture_argument(request, 'exe_file_name', '')) def _generic_launcher(workspace, launcher_platform, exe_file_name): diff --git a/Tools/LyTestTools/ly_test_tools/launchers/__init__.py b/Tools/LyTestTools/ly_test_tools/launchers/__init__.py index 2203d2eb39..5f7a391afb 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/__init__.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/__init__.py @@ -11,5 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. from ly_test_tools.launchers.platforms.base import Launcher from ly_test_tools.launchers.platforms.mac.launcher import MacLauncher -from ly_test_tools.launchers.platforms.win.launcher import WinLauncher, DedicatedWinLauncher, WinEditor +from ly_test_tools.launchers.platforms.win.launcher import ( + WinLauncher, DedicatedWinLauncher, WinEditor, WinGenericLauncher) from ly_test_tools.launchers.platforms.android.launcher import AndroidLauncher From 3c315df36f5bc086806efda05b8cdec0131ecbd6 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Wed, 5 May 2021 16:47:44 -0700 Subject: [PATCH 074/225] Fix Camera transform property notifications. Moves transform notification logic from CComponentEntityObject::InvalidateTM (which will eventually go away) to AzToolsFramework::TransformComponent::OnTransformChanged. We also specifically make sure PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged fires, which is used by Track View to detect camera position changes. --- .../ToolsComponents/TransformComponent.cpp | 19 ++++++++++++++++++- .../Objects/ComponentEntityObject.cpp | 8 -------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index f8d02b6581..6ce797c3ee 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -253,7 +253,7 @@ namespace AzToolsFramework m_localTransformDirty = true; m_worldTransformDirty = true; - if (GetEntity()) + if (const AZ::Entity* entity = GetEntity()) { SetDirty(); @@ -265,6 +265,23 @@ namespace AzToolsFramework AZ::TransformNotificationBus::Event( GetEntityId(), &TransformNotification::OnTransformChanged, localTM, worldTM); + + // Fire a property changed notification for this component + if (const AZ::Component* component = entity->FindComponent()) + { + PropertyEditorEntityChangeNotificationBus::Event( + GetEntityId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged, component->GetId()); + } + + // Refresh the property editor if we're selected + bool selected = false; + ToolsApplicationRequestBus::BroadcastResult( + selected, &AzToolsFramework::ToolsApplicationRequests::IsSelected, GetEntityId()); + if (selected) + { + ToolsApplicationEvents::Bus::Broadcast( + &ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values); + } } } diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp index c85ed1248f..20ae0a74cd 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp @@ -609,14 +609,6 @@ void CComponentEntityObject::InvalidateTM(int nWhyFlags) { Matrix34 worldTransform = GetWorldTM(); EBUS_EVENT_ID(m_entityId, AZ::TransformBus, SetWorldTM, LYTransformToAZTransform(worldTransform)); - - // When transformed via the editor, make sure the entity is marked dirty for undo capture. - EBUS_EVENT(AzToolsFramework::ToolsApplicationRequests::Bus, AddDirtyEntity, m_entityId); - - if (CheckFlags(OBJFLAG_SELECTED)) - { - EBUS_EVENT(AzToolsFramework::ToolsApplicationEvents::Bus, InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values); - } } } } From dca2294b362538a03f4566dd9e4d76634d16c9b1 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Wed, 5 May 2021 16:51:49 -0700 Subject: [PATCH 075/225] Move GetCameraTransform into RPI::View. --- Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h | 2 ++ Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp | 9 +++++++++ Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp | 7 +------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h index d6146d3760..aad099dc23 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h @@ -91,6 +91,8 @@ namespace AZ const AZ::Matrix4x4& GetViewToWorldMatrix() const; const AZ::Matrix4x4& GetViewToClipMatrix() const; const AZ::Matrix4x4& GetWorldToClipMatrix() const; + //! Get the camera's world transform, converted from the viewToWorld matrix's native y-up to z-up + AZ::Transform GetCameraTransform() const; //! Finalize draw lists in this view. This function should only be called when all //! draw packets for current frame are added. diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp index e3f41cbda9..85216707a8 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp @@ -110,6 +110,15 @@ namespace AZ InvalidateSrg(); } + AZ::Transform View::GetCameraTransform() const + { + const Quaternion zUpToYUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi); + return AZ::Transform::CreateFromQuaternionAndTranslation( + Quaternion::CreateFromMatrix4x4(m_worldToViewMatrix) * zUpToYUp, + m_worldToViewMatrix.GetTranslation() + ).GetOrthogonalized(); + } + void View::SetCameraTransform(const AZ::Matrix3x4& cameraTransform) { m_position = cameraTransform.GetTranslation(); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp index b5d3f815fe..b2f9acb855 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp @@ -192,12 +192,7 @@ namespace AZ AZ::Transform ViewportContext::GetCameraTransform() const { - const Matrix4x4& worldToViewMatrix = GetDefaultView()->GetViewToWorldMatrix(); - const Quaternion zUpToYUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi); - return AZ::Transform::CreateFromQuaternionAndTranslation( - Quaternion::CreateFromMatrix4x4(worldToViewMatrix) * zUpToYUp, - worldToViewMatrix.GetTranslation() - ).GetOrthogonalized(); + return GetDefaultView()->GetCameraTransform(); } void ViewportContext::SetCameraTransform(const AZ::Transform& transform) From 5d9c99436a81cabeff5758a22f86522acfc63265 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Wed, 5 May 2021 16:54:31 -0700 Subject: [PATCH 076/225] Ensure CameraComponentController entities get synced with Atom camera changes. This ensures the camera entity's transform gets correctly set if the RPI::View (or ViewportContext) is directly used instead of adjusting the entity transform, for e.g. camera controllers. --- .../Code/Source/CameraComponentController.cpp | 18 ++++++++++++++++++ .../Code/Source/CameraComponentController.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/Gems/Camera/Code/Source/CameraComponentController.cpp b/Gems/Camera/Code/Source/CameraComponentController.cpp index 2799d897d6..3dcee68169 100644 --- a/Gems/Camera/Code/Source/CameraComponentController.cpp +++ b/Gems/Camera/Code/Source/CameraComponentController.cpp @@ -160,6 +160,17 @@ namespace Camera incompatible.push_back(AZ_CRC("CameraService", 0x1dd1caa4)); } + void CameraComponentController::Init() + { + m_onViewMatrixChanged = AZ::Event::Handler([this](const AZ::Matrix4x4&) + { + if (!m_updatingTransformFromEntity) + { + AZ::TransformBus::Event(m_entityId, &AZ::TransformInterface::SetWorldTM, m_atomCamera->GetCameraTransform()); + } + }); + } + void CameraComponentController::Activate(AZ::EntityId entityId) { m_entityId = entityId; @@ -218,6 +229,8 @@ namespace Camera } } AZ::RPI::ViewProviderBus::Handler::BusConnect(m_entityId); + + m_atomCamera->ConnectWorldToViewMatrixChangedHandler(m_onViewMatrixChanged); } UpdateCamera(); @@ -258,6 +271,7 @@ namespace Camera if (atomViewportRequests) { AZ::RPI::ViewProviderBus::Handler::BusDisconnect(m_entityId); + m_onViewMatrixChanged.Disconnect(); } DeactivateAtomView(); @@ -376,7 +390,9 @@ namespace Camera if (m_atomCamera) { + m_updatingTransformFromEntity = true; m_atomCamera->SetCameraTransform(AZ::Matrix3x4::CreateFromTransform(world.GetOrthogonalized())); + m_updatingTransformFromEntity = false; } } @@ -425,7 +441,9 @@ namespace Camera m_config.m_nearClipDistance, m_config.m_farClipDistance, true); + m_updatingTransformFromEntity = true; m_atomCamera->SetViewToClipMatrix(viewToClipMatrix); + m_updatingTransformFromEntity = false; } } diff --git a/Gems/Camera/Code/Source/CameraComponentController.h b/Gems/Camera/Code/Source/CameraComponentController.h index 92e1354f17..cae6ad4663 100644 --- a/Gems/Camera/Code/Source/CameraComponentController.h +++ b/Gems/Camera/Code/Source/CameraComponentController.h @@ -77,6 +77,7 @@ namespace Camera static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + void Init(); void Activate(AZ::EntityId entityId); void Deactivate(); void SetConfiguration(const CameraComponentConfig& config); @@ -121,6 +122,8 @@ namespace Camera // Atom integration AZ::RPI::ViewPtr m_atomCamera; AZ::RPI::AuxGeomDrawPtr m_atomAuxGeom; + AZ::Event::Handler m_onViewMatrixChanged; + bool m_updatingTransformFromEntity = false; // Cry view integration IView* m_view = nullptr; From 7fd356751b78a4ba540128d55f83674ff4ccc156 Mon Sep 17 00:00:00 2001 From: bosnichd Date: Mon, 10 May 2021 16:17:24 -0600 Subject: [PATCH 077/225] Remove the ImageProcessing Gem. (#677) Remove the ImageProcessing Gem. This was supposed to have happened as part of [21d96e7], but looks like I only removed it from the CMakeLists.txt file and forgot to delete the actual folder! --- .../AssetProcessorGemConfig.setreg | 7 - .../Assets/Editor/Backward.png | 3 - .../ImageProcessing/Assets/Editor/Forward.png | 3 - .../Assets/Editor/Resources.qrc | 11 - Gems/ImageProcessing/Assets/Editor/info.png | 3 - .../Assets/Editor/refresh-active.png | 3 - .../ImageProcessing/Assets/Editor/refresh.png | 3 - Gems/ImageProcessing/Assets/Editor/reset.png | 3 - .../ImageProcessing/Assets/Editor/warning.png | 3 - Gems/ImageProcessing/CMakeLists.txt | 12 - Gems/ImageProcessing/Code/CMakeLists.txt | 147 - .../Include/ImageProcessing/ImageObject.h | 147 - .../ImageProcessing/ImageProcessingBus.h | 37 - .../ImageProcessingEditorBus.h | 36 - .../Include/ImageProcessing/PixelFormats.h | 107 - .../AtlasBuilder/AtlasBuilderComponent.cpp | 99 - .../AtlasBuilder/AtlasBuilderComponent.h | 44 - .../AtlasBuilder/AtlasBuilderWorker.cpp | 1494 --- .../Source/AtlasBuilder/AtlasBuilderWorker.h | 221 - .../BuilderSettings/BuilderSettingManager.cpp | 1114 --- .../BuilderSettings/BuilderSettingManager.h | 192 - .../BuilderSettings/BuilderSettings.cpp | 32 - .../Source/BuilderSettings/BuilderSettings.h | 33 - .../BuilderSettings/CubemapSettings.cpp | 52 - .../Source/BuilderSettings/CubemapSettings.h | 52 - .../BuilderSettings/ImageProcessingDefines.h | 108 - .../Source/BuilderSettings/MipmapSettings.cpp | 66 - .../Source/BuilderSettings/MipmapSettings.h | 39 - .../Source/BuilderSettings/PlatformSettings.h | 34 - .../Source/BuilderSettings/PresetSettings.cpp | 213 - .../Source/BuilderSettings/PresetSettings.h | 120 - .../BuilderSettings/TextureSettings.cpp | 589 -- .../Source/BuilderSettings/TextureSettings.h | 171 - .../Code/Source/Compressors/CTSquisher.cpp | 387 - .../Code/Source/Compressors/CTSquisher.h | 38 - .../Code/Source/Compressors/Compressor.cpp | 58 - .../Code/Source/Compressors/Compressor.h | 56 - .../CryTextureSquisher/ColorBlockRGBA4x4c.cpp | 297 - .../CryTextureSquisher/ColorBlockRGBA4x4c.h | 62 - .../CryTextureSquisher/ColorBlockRGBA4x4f.cpp | 282 - .../CryTextureSquisher/ColorBlockRGBA4x4f.h | 59 - .../CryTextureSquisher/ColorBlockRGBA4x4s.cpp | 297 - .../CryTextureSquisher/ColorBlockRGBA4x4s.h | 62 - .../CryTextureSquisher/ColorTypes.h | 228 - .../CryTextureSquisher/CryTextureSquisher.cpp | 657 -- .../CryTextureSquisher/CryTextureSquisher.h | 132 - .../Code/Source/Compressors/ETC2.cpp | 229 - .../Code/Source/Compressors/ETC2.h | 32 - .../Code/Source/Compressors/PVRTC.cpp | 389 - .../Code/Source/Compressors/PVRTC.h | 32 - .../Code/Source/Converters/AlphaCoverage.cpp | 121 - .../Code/Source/Converters/ColorChart.cpp | 314 - .../Source/Converters/ConvertPixelFormat.cpp | 170 - .../Code/Source/Converters/Cubemap.cpp | 620 -- .../Code/Source/Converters/Cubemap.h | 118 - .../Code/Source/Converters/FIR-Filter.cpp | 1285 --- .../Code/Source/Converters/FIR-Weights.cpp | 329 - .../Code/Source/Converters/FIR-Weights.h | 83 - .../Code/Source/Converters/FIR-Windows.h | 1283 --- .../Code/Source/Converters/Gamma.cpp | 260 - .../Code/Source/Converters/HighPass.cpp | 110 - .../Code/Source/Converters/Histogram.cpp | 81 - .../Code/Source/Converters/Histogram.h | 84 - .../Code/Source/Converters/Normalize.cpp | 420 - .../Code/Source/Converters/PixelOperation.cpp | 487 - .../Code/Source/Converters/PixelOperation.h | 31 - .../Code/Source/Editor/EditorCommon.cpp | 386 - .../Code/Source/Editor/EditorCommon.h | 105 - .../Code/Source/Editor/ImagePopup.cpp | 49 - .../Code/Source/Editor/ImagePopup.h | 44 - .../Code/Source/Editor/ImagePopup.ui | 43 - .../Source/Editor/MipmapSettingWidget.cpp | 122 - .../Code/Source/Editor/MipmapSettingWidget.h | 62 - .../Code/Source/Editor/MipmapSettingWidget.ui | 89 - .../Code/Source/Editor/PresetInfoPopup.cpp | 120 - .../Code/Source/Editor/PresetInfoPopup.h | 49 - .../Code/Source/Editor/PresetInfoPopup.ui | 83 - .../Editor/ResolutionSettingItemWidget.cpp | 145 - .../Editor/ResolutionSettingItemWidget.h | 81 - .../Editor/ResolutionSettingItemWidget.ui | 205 - .../Source/Editor/ResolutionSettingWidget.cpp | 58 - .../Source/Editor/ResolutionSettingWidget.h | 44 - .../Source/Editor/ResolutionSettingWidget.ui | 177 - .../Editor/TexturePresetSelectionWidget.cpp | 199 - .../Editor/TexturePresetSelectionWidget.h | 65 - .../Editor/TexturePresetSelectionWidget.ui | 91 - .../Source/Editor/TexturePreviewWidget.cpp | 639 -- .../Code/Source/Editor/TexturePreviewWidget.h | 121 - .../Source/Editor/TexturePreviewWidget.ui | 371 - .../Source/Editor/TexturePropertyEditor.cpp | 217 - .../Source/Editor/TexturePropertyEditor.h | 74 - .../Source/Editor/TexturePropertyEditor.ui | 120 - .../Code/Source/ImageBuilderBaseType.h | 29 - .../Code/Source/ImageBuilderComponent.cpp | 346 - .../Code/Source/ImageBuilderComponent.h | 80 - .../ImageBuilderDefaultPresets.settings | 8051 ----------------- .../Code/Source/ImageLoader/BTImageLoader.cpp | 227 - .../Code/Source/ImageLoader/ImageLoaders.cpp | 72 - .../Code/Source/ImageLoader/ImageLoaders.h | 51 - .../Code/Source/ImageLoader/QtImageLoader.cpp | 76 - .../Code/Source/ImageLoader/TIFFLoader.cpp | 660 -- .../Code/Source/ImageProcessingModule.cpp | 53 - .../Source/ImageProcessingSystemComponent.cpp | 196 - .../Source/ImageProcessingSystemComponent.h | 77 - .../Source/ImageProcessing_precompiled.cpp | 13 - .../Code/Source/ImageProcessing_precompiled.h | 33 - .../Android/ImageProcessing_Traits_Android.h | 20 - .../Android/ImageProcessing_Traits_Platform.h | 14 - .../Platform/Android/platform_android.cmake | 16 - .../Android/platform_android_files.cmake | 15 - .../Linux/ImageProcessing_Traits_Linux.h | 20 - .../Linux/ImageProcessing_Traits_Platform.h | 14 - .../Platform/Linux/platform_linux.cmake | 16 - .../Platform/Linux/platform_linux_files.cmake | 15 - .../Platform/Mac/ImageProcessing_Traits_Mac.h | 20 - .../Mac/ImageProcessing_Traits_Platform.h | 14 - .../Source/Platform/Mac/platform_mac.cmake | 10 - .../Platform/Mac/platform_mac_files.cmake | 15 - .../Windows/ImageProcessing_Traits_Platform.h | 14 - .../Windows/ImageProcessing_Traits_Windows.h | 20 - .../Platform/Windows/platform_windows.cmake | 16 - .../Windows/platform_windows_files.cmake | 15 - .../iOS/ImageProcessing_Traits_Platform.h | 14 - .../Platform/iOS/ImageProcessing_Traits_iOS.h | 20 - .../Source/Platform/iOS/platform_ios.cmake | 16 - .../Platform/iOS/platform_ios_files.cmake | 15 - .../Code/Source/Processing/DDSHeader.h | 230 - .../Code/Source/Processing/ImageConvert.cpp | 1014 --- .../Code/Source/Processing/ImageConvert.h | 182 - .../Source/Processing/ImageConvertJob.cpp | 148 - .../Code/Source/Processing/ImageConvertJob.h | 74 - .../Code/Source/Processing/ImageFlags.h | 43 - .../Source/Processing/ImageObjectImpl.cpp | 1417 --- .../Code/Source/Processing/ImageObjectImpl.h | 199 - .../Code/Source/Processing/ImagePreview.cpp | 206 - .../Code/Source/Processing/ImagePreview.h | 59 - .../Code/Source/Processing/ImageToProcess.h | 114 - .../Source/Processing/PixelFormatInfo.cpp | 430 - .../Code/Source/Processing/PixelFormatInfo.h | 222 - .../Code/Tests/AtlasBuilderTest.cpp | 186 - .../Code/Tests/ImageProcessing_Test.cpp | 1544 ---- .../Code/Tests/TestAssets/1024x1024_24bit.tif | 3 - .../1024x1024_24bit.tif.exportsettings | 1 - .../Code/Tests/TestAssets/128x128_RGBA8.tga | 3 - .../Code/Tests/TestAssets/200x200_24bit.jpg | 3 - .../Code/Tests/TestAssets/20x16_32bit.png | 3 - .../Code/Tests/TestAssets/237x177_RGB.jpg | 3 - .../Code/Tests/TestAssets/32x32_16bit_f.tif | 3 - .../Code/Tests/TestAssets/32x32_32bit_f.tif | 3 - .../Code/Tests/TestAssets/512x288_24bit.tga | 3 - .../Code/Tests/TestAssets/512x512_RGB_N.tga | 3 - .../Code/Tests/TestAssets/BlackWhite.png | 3 - .../TestAssets/Lenstexture_dirtyglass.tif | 3 - .../Code/Tests/TestAssets/TerrainHeightmap.bt | Bin 65792 -> 0 bytes .../TestAssets/TextureAtlasTest.texatlas | 50 - .../TextureAtlasTest/CircleFrame.tif | 3 - .../TextureAtlasTest/CircleGradient.png | 3 - .../TextureAtlasTest/CircleMask.tif | 3 - .../TextureAtlasTest/Circle_Shadow.tif | 3 - .../TextureAtlasTest/ParticleGlow.tif | 3 - .../TestAssets/TextureAtlasTest/button.tif | 3 - .../TextureAtlasTest/buttonPressed.tif | 3 - .../TextureAtlasTest/buttonSlider.tif | 3 - .../TextureAtlasTest/checkbox_spritesheet.tif | 3 - .../TextureAtlasTest/checkered3.tif | 3 - .../TextureAtlasTest/empty_icon.tif | 3 - .../TextureAtlasTest/fixed_image.tif | 3 - .../TextureAtlasTest/flipbook_walking.tif | 3 - .../imagesequence/flipbook_walking_00.png | 3 - .../imagesequence/flipbook_walking_01.png | 3 - .../imagesequence/flipbook_walking_02.png | 3 - .../imagesequence/flipbook_walking_03.png | 3 - .../imagesequence/flipbook_walking_04.png | 3 - .../imagesequence/flipbook_walking_05.png | 3 - .../imagesequence/flipbook_walking_06.png | 3 - .../imagesequence/flipbook_walking_07.png | 3 - .../imagesequence/flipbook_walking_08.png | 3 - .../imagesequence/flipbook_walking_09.png | 3 - .../imagesequence/flipbook_walking_10.png | 3 - .../imagesequence/flipbook_walking_11.png | 3 - .../TestAssets/TextureAtlasTest/mask.tif | 3 - .../TestAssets/TextureAtlasTest/outline.tif | 3 - .../TextureAtlasTest/outlineRounded.tif | 3 - .../TestAssets/TextureAtlasTest/panelBkgd.tif | 3 - .../TestAssets/TextureAtlasTest/pattern02.tif | 3 - .../TextureAtlasTest/pattern02_big.tif | 3 - .../TextureAtlasTest/pattern02vertical.tif | 3 - .../pattern02vertical_big.tif | 3 - .../TestAssets/TextureAtlasTest/pattern03.tif | 3 - .../TextureAtlasTest/pattern03_big.tif | 3 - .../TextureAtlasTest/scroll_box_icon_1.tif | 3 - .../TextureAtlasTest/scroll_box_icon_10.tif | 3 - .../TextureAtlasTest/scroll_box_icon_2.tif | 3 - .../TextureAtlasTest/scroll_box_icon_3.tif | 3 - .../TextureAtlasTest/scroll_box_icon_4.tif | 3 - .../TextureAtlasTest/scroll_box_icon_5.tif | 3 - .../TextureAtlasTest/scroll_box_icon_6.tif | 3 - .../TextureAtlasTest/scroll_box_icon_7.tif | 3 - .../TextureAtlasTest/scroll_box_icon_8.tif | 3 - .../TextureAtlasTest/scroll_box_icon_9.tif | 3 - .../TextureAtlasTest/scroll_box_map.tif | 3 - .../TestAssets/TextureAtlasTest/selected.tif | 3 - .../TextureAtlasTest/shadowInside2.tif | 3 - .../TextureAtlasTest/shadowInsideSquare.tif | 3 - .../Code/Tests/TestAssets/greyscale.png | 3 - .../Code/Tests/TestAssets/noon_cm.tif | 3 - .../TestAssets/normalSmoothness_ddna.tif | 3 - .../Code/Tests/TestAssets/red.png | 3 - .../Code/Tests/TestAssets/uppercase.TGA | 3 - .../Code/imageprocessing_files.cmake | 18 - .../Code/imageprocessing_headers_files.cmake | 13 - .../Code/imageprocessing_static_files.cmake | 133 - .../Code/imageprocessing_tests_files.cmake | 15 - .../External/CubeMapGen/CBBoxInt32.cpp | 129 - .../External/CubeMapGen/CBBoxInt32.h | 32 - .../External/CubeMapGen/CCubeMapProcessor.cpp | 2237 ----- .../External/CubeMapGen/CCubeMapProcessor.h | 595 -- .../External/CubeMapGen/CImageSurface.cpp | 695 -- .../External/CubeMapGen/CImageSurface.h | 94 - .../External/CubeMapGen/ReadMe_CubeGen.doc | Bin 435200 -> 0 bytes .../External/CubeMapGen/VectorMacros.h | 176 - .../External/CubeMapGen/license.txt | 19 - .../External/CubeMapGen/readme.txt | 5 - Gems/ImageProcessing/gem.json | 27 - Gems/ImageProcessing/preview.png | 3 - 225 files changed, 38838 deletions(-) delete mode 100644 Gems/ImageProcessing/AssetProcessorGemConfig.setreg delete mode 100644 Gems/ImageProcessing/Assets/Editor/Backward.png delete mode 100644 Gems/ImageProcessing/Assets/Editor/Forward.png delete mode 100644 Gems/ImageProcessing/Assets/Editor/Resources.qrc delete mode 100644 Gems/ImageProcessing/Assets/Editor/info.png delete mode 100644 Gems/ImageProcessing/Assets/Editor/refresh-active.png delete mode 100644 Gems/ImageProcessing/Assets/Editor/refresh.png delete mode 100644 Gems/ImageProcessing/Assets/Editor/reset.png delete mode 100644 Gems/ImageProcessing/Assets/Editor/warning.png delete mode 100644 Gems/ImageProcessing/CMakeLists.txt delete mode 100644 Gems/ImageProcessing/Code/CMakeLists.txt delete mode 100644 Gems/ImageProcessing/Code/Include/ImageProcessing/ImageObject.h delete mode 100644 Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingBus.h delete mode 100644 Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingEditorBus.h delete mode 100644 Gems/ImageProcessing/Code/Include/ImageProcessing/PixelFormats.h delete mode 100644 Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.h delete mode 100644 Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.h delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.h delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.h delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.h delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/ImageProcessingDefines.h delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.h delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/PlatformSettings.h delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.h delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/Compressor.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/Compressor.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/ETC2.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/ETC2.h delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Compressors/PVRTC.h delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/AlphaCoverage.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/ColorChart.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/ConvertPixelFormat.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/Cubemap.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/Cubemap.h delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/FIR-Filter.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.h delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/FIR-Windows.h delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/Gamma.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/HighPass.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/Histogram.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/Histogram.h delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/Normalize.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/PixelOperation.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Converters/PixelOperation.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/EditorCommon.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/EditorCommon.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ImagePopup.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ImagePopup.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ImagePopup.ui delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.ui delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.ui delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.ui delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.ui delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.ui delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.ui delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.h delete mode 100644 Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.ui delete mode 100644 Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h delete mode 100644 Gems/ImageProcessing/Code/Source/ImageBuilderComponent.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/ImageBuilderComponent.h delete mode 100644 Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings delete mode 100644 Gems/ImageProcessing/Code/Source/ImageLoader/BTImageLoader.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.h delete mode 100644 Gems/ImageProcessing/Code/Source/ImageLoader/QtImageLoader.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/ImageProcessingModule.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.h delete mode 100644 Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Android.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Platform.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Android/platform_android.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Android/platform_android_files.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Linux.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Platform.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux_files.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Mac.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Platform.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac_files.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Platform.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Windows.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows_files.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_Platform.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_iOS.h delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios_files.cmake delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/DDSHeader.h delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImageConvert.h delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.h delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImageFlags.h delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.h delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImagePreview.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImagePreview.h delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/ImageToProcess.h delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.cpp delete mode 100644 Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.h delete mode 100644 Gems/ImageProcessing/Code/Tests/AtlasBuilderTest.cpp delete mode 100644 Gems/ImageProcessing/Code/Tests/ImageProcessing_Test.cpp delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif.exportsettings delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/128x128_RGBA8.tga delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/200x200_24bit.jpg delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/20x16_32bit.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/237x177_RGB.jpg delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/32x32_16bit_f.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/32x32_32bit_f.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/512x288_24bit.tga delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/512x512_RGB_N.tga delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/BlackWhite.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TerrainHeightmap.bt delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest.texatlas delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleFrame.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleGradient.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleMask.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/Circle_Shadow.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/ParticleGlow.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/button.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonPressed.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonSlider.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkbox_spritesheet.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkered3.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/empty_icon.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/fixed_image.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/flipbook_walking.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_00.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_01.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_02.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_03.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_04.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_05.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_06.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_07.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_08.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_09.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_10.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_11.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/mask.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outline.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outlineRounded.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/panelBkgd.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02_big.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical_big.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03_big.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_1.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_10.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_2.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_3.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_4.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_5.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_6.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_7.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_8.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_9.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_map.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/selected.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInside2.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInsideSquare.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/greyscale.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/red.png delete mode 100644 Gems/ImageProcessing/Code/Tests/TestAssets/uppercase.TGA delete mode 100644 Gems/ImageProcessing/Code/imageprocessing_files.cmake delete mode 100644 Gems/ImageProcessing/Code/imageprocessing_headers_files.cmake delete mode 100644 Gems/ImageProcessing/Code/imageprocessing_static_files.cmake delete mode 100644 Gems/ImageProcessing/Code/imageprocessing_tests_files.cmake delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.cpp delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.h delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/CCubeMapProcessor.cpp delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/CCubeMapProcessor.h delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/CImageSurface.cpp delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/CImageSurface.h delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/ReadMe_CubeGen.doc delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/VectorMacros.h delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/license.txt delete mode 100644 Gems/ImageProcessing/External/CubeMapGen/readme.txt delete mode 100644 Gems/ImageProcessing/gem.json delete mode 100644 Gems/ImageProcessing/preview.png diff --git a/Gems/ImageProcessing/AssetProcessorGemConfig.setreg b/Gems/ImageProcessing/AssetProcessorGemConfig.setreg deleted file mode 100644 index 17d9887fe8..0000000000 --- a/Gems/ImageProcessing/AssetProcessorGemConfig.setreg +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Amazon": { - "AssetProcessor": { - "Settings": {} - } - } -} diff --git a/Gems/ImageProcessing/Assets/Editor/Backward.png b/Gems/ImageProcessing/Assets/Editor/Backward.png deleted file mode 100644 index 82b3eafbd9..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/Backward.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1a1623477f4e2e5ef0440ecfc0c08e775d9b5f12d8ebc6b434e8212bf3445bcd -size 224 diff --git a/Gems/ImageProcessing/Assets/Editor/Forward.png b/Gems/ImageProcessing/Assets/Editor/Forward.png deleted file mode 100644 index a7a29a4c25..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/Forward.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:31b247223c1116d4fc014189a9d8d86d4458b792c1120442673631136fd89520 -size 222 diff --git a/Gems/ImageProcessing/Assets/Editor/Resources.qrc b/Gems/ImageProcessing/Assets/Editor/Resources.qrc deleted file mode 100644 index c309d19053..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/Resources.qrc +++ /dev/null @@ -1,11 +0,0 @@ - - - refresh-active.png - warning.png - refresh.png - info.png - Backward.png - Forward.png - reset.png - - diff --git a/Gems/ImageProcessing/Assets/Editor/info.png b/Gems/ImageProcessing/Assets/Editor/info.png deleted file mode 100644 index 002cf9c775..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/info.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3fec3caae92b9c9290c4157b3aeca29dcb366edd12719355e1d93dfb9d80cfed -size 825 diff --git a/Gems/ImageProcessing/Assets/Editor/refresh-active.png b/Gems/ImageProcessing/Assets/Editor/refresh-active.png deleted file mode 100644 index 33bc1c592a..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/refresh-active.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d29af2b69b74815c88352f85a7131384482e4f2d26ecf36581b46dede542fccb -size 2973 diff --git a/Gems/ImageProcessing/Assets/Editor/refresh.png b/Gems/ImageProcessing/Assets/Editor/refresh.png deleted file mode 100644 index fc9ef09987..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/refresh.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:36591b457ee3519b16405d281674fcdd18645e3570bfc960a22b8f142ee99a14 -size 436 diff --git a/Gems/ImageProcessing/Assets/Editor/reset.png b/Gems/ImageProcessing/Assets/Editor/reset.png deleted file mode 100644 index ed9c2f016d..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/reset.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0362da38d3804e2911130d138be4fd73040d66c8ac7d1b5f9f60c70037e8ca93 -size 1292 diff --git a/Gems/ImageProcessing/Assets/Editor/warning.png b/Gems/ImageProcessing/Assets/Editor/warning.png deleted file mode 100644 index 6020245f86..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/warning.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cf5e987ea92164dcaa6deb88989aaac962bc092f5745274017f71224f48dbf7a -size 651 diff --git a/Gems/ImageProcessing/CMakeLists.txt b/Gems/ImageProcessing/CMakeLists.txt deleted file mode 100644 index 20a680bce9..0000000000 --- a/Gems/ImageProcessing/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -add_subdirectory(Code) diff --git a/Gems/ImageProcessing/Code/CMakeLists.txt b/Gems/ImageProcessing/Code/CMakeLists.txt deleted file mode 100644 index a5cb6f6cb9..0000000000 --- a/Gems/ImageProcessing/Code/CMakeLists.txt +++ /dev/null @@ -1,147 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -ly_add_target( - NAME ImageProcessing.Headers HEADERONLY - NAMESPACE Gem - FILES_CMAKE - imageprocessing_headers_files.cmake - INCLUDE_DIRECTORIES - INTERFACE - Include -) - -if (NOT PAL_TRAIT_BUILD_HOST_TOOLS) - return() -endif() - -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) - -set(platform_tools_files) -set(pal_tools_include_files) -set(pal_tools_dirs) -foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED}) - string(TOLOWER ${enabled_platform} enabled_platform_lowercase) - ly_get_list_relative_pal_filename(pal_tools_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${enabled_platform}) - list(APPEND platform_tools_files ${pal_tools_dir}/pal_tools_${enabled_platform_lowercase}.cmake) - list(APPEND pal_tools_include_files ${pal_tools_dir}/pal_tools_${enabled_platform_lowercase}_files.cmake) - list(APPEND pal_tools_dirs ${pal_tools_dir}) -endforeach() - -ly_add_target( - NAME ImageProcessing.Static STATIC - NAMESPACE Gem - AUTOMOC - AUTOUIC - FILES_CMAKE - imageprocessing_static_files.cmake - ${pal_tools_include_files} - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - ${platform_tools_files} - INCLUDE_DIRECTORIES - PRIVATE - . - Source - ../External - ${pal_dir} - ${pal_tools_dirs} - PUBLIC - Include - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Core - 3rdParty::Qt::Widgets - 3rdParty::etc2comp - 3rdParty::PVRTexTool - 3rdParty::squish-ccr - 3rdParty::zlib - 3rdParty::tiff - Legacy::CryCommon - AZ::AzCore - AZ::AssetBuilderSDK - Gem::TextureAtlas -) -ly_add_source_properties( - SOURCES - Source/BuilderSettings/BuilderSettingManager.cpp - Source/Processing/ImageConvert.cpp - PROPERTY COMPILE_DEFINITIONS - VALUES ${LY_PAL_TOOLS_DEFINES} -) - -ly_add_target( - NAME ImageProcessing.Editor GEM_MODULE - - NAMESPACE Gem - AUTOMOC - AUTORCC - FILES_CMAKE - imageprocessing_files.cmake - PLATFORM_INCLUDE_FILES - ${platform_tools_files} - INCLUDE_DIRECTORIES - PRIVATE - . - Source - ${pal_dir} - PUBLIC - Include - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Widgets - 3rdParty::PVRTexTool - 3rdParty::squish-ccr - Legacy::CryCommon - AZ::AzCore - AZ::AzToolsFramework - AZ::AssetBuilderSDK - Gem::ImageProcessing.Static - Gem::TextureAtlas - RUNTIME_DEPENDENCIES - 3rdParty::ASTCEncoder - Gem::TextureAtlas -) - -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - ly_add_target( - NAME ImageProcessing.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Gem - FILES_CMAKE - imageprocessing_tests_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - Tests - . - Source - ${pal_dir} - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - 3rdParty::Qt::Widgets - Legacy::CryCommon - AZ::AssetBuilderSDK - Gem::ImageProcessing.Static - Gem::ImageProcessing.Editor - Gem::TextureAtlas - ) - ly_add_googletest( - NAME Gem::ImageProcessing.Tests - ) - - ly_add_source_properties( - SOURCES Tests/ImageProcessing_Test.cpp - PROPERTY COMPILE_DEFINITIONS - VALUES ${LY_PAL_TOOLS_DEFINES} - ) - -endif() diff --git a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageObject.h b/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageObject.h deleted file mode 100644 index baa6613daf..0000000000 --- a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageObject.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace AZ -{ - namespace IO - { - class SystemFileStream; - } -} - -namespace ImageProcessing -{ - class IImageObject; - class TextureSettings; - typedef AZStd::shared_ptr IImageObjectPtr; - - enum class EAlphaContent - { - eAlphaContent_Indeterminate, // the format may have alpha, but can't be calculated - eAlphaContent_Absent, // the format has no alpha - eAlphaContent_OnlyWhite, // alpha contains just white - eAlphaContent_OnlyBlack, // alpha contains just black - eAlphaContent_OnlyBlackAndWhite, // alpha contains just black and white - eAlphaContent_Greyscale // alpha contains grey tones - }; - - //interface for image object. The image object may have mipmaps. - class IImageObject - { - public: - //static functions - static IImageObject* CreateImage(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat); - - virtual ~IImageObject() {}; - public: - //creating new image object outof this image object - virtual IImageObject* Clone() const = 0; - // allocate an empty image object with requested format and same properties with current image - virtual IImageObject* AllocateImage(EPixelFormat pixelFormat) const = 0; - virtual IImageObject* AllocateImage() const = 0; - - //get pixel format - virtual EPixelFormat GetPixelFormat() const = 0; - - virtual AZ::u32 GetPixelCount(AZ::u32 mip) const = 0; - virtual AZ::u32 GetWidth(AZ::u32 mip) const = 0; - virtual AZ::u32 GetHeight(AZ::u32 mip) const = 0; - virtual bool IsCubemap() const = 0; - virtual AZ::u32 GetMipCount() const = 0; - - //get pixel data buffer - virtual void GetImagePointer(AZ::u32 mip, AZ::u8*& pMem, AZ::u32& pitch) const = 0; - virtual AZ::u32 GetMipBufSize(AZ::u32 mip) const = 0; - virtual void SetMipData(AZ::u32 mip, AZ::u8* mipBuf, AZ::u32 bufSize, AZ::u32 pitch) = 0; - - //get/set image flags - virtual AZ::u32 GetImageFlags() const = 0; - virtual void SetImageFlags(AZ::u32 imageFlags) = 0; - virtual void AddImageFlags(AZ::u32 imageFlags) = 0; - virtual void RemoveImageFlags(AZ::u32 imageFlags) = 0; - virtual bool HasImageFlags(AZ::u32 imageFlags) const = 0; - - // image data operations and calculation - // Calculates "(pixel.rgba * scale) + bias" - virtual void ScaleAndBiasChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& scale, const AZ::Vector4& bias) = 0; - // Calculates "clamp(pixel.rgba, min, max)" - virtual void ClampChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& min, const AZ::Vector4& max) = 0; - - //transfer alpha coverage from source image - virtual void TransferAlphaCoverage(const TextureSettings* textureSetting, const IImageObjectPtr srcImg) = 0; - // Routines to measure and manipulate alpha coverage - virtual float ComputeAlphaCoverageScaleFactor(AZ::u32 mip, float fDesiredCoverage, float fAlphaRef) const = 0; - virtual float ComputeAlphaCoverage(AZ::u32 mip, float fAlphaRef) const = 0; - - //helper functions - //compare whether two images are same. return true if they are same. - virtual bool CompareImage(const IImageObjectPtr otherImage) const = 0; - - // Writes this image to file used for runtime, overwrites any existing file. - // It may write alpha image as attached image into the same file - // outFilePaths will save filenames finally saved to since the image might be split and saved to multiple files - virtual bool SaveImage(const char* filename, IImageObjectPtr alphaImage, AZStd::vector& outFilePaths) const = 0; - virtual bool SaveImage(AZ::IO::SystemFileStream& out) const = 0; - virtual bool SaveMipToFile(AZ::u32 mip, const AZStd::string& filename) const = 0; - - //get total image data size in memory of all mipmaps. Not includs header and flags. - virtual AZ::u32 GetTextureMemory() const = 0; - - //identify content of the alpha channel - virtual EAlphaContent GetAlphaContent() const = 0; - - //normalize rgb channel for specified mips - virtual void NormalizeVectors(AZ::u32 firstMip, AZ::u32 maxMipCount) = 0; - - // use when you convert an image to another one - virtual void CopyPropertiesFrom(const IImageObjectPtr src) = 0; - - //swizzle data for source channels to dest channels - virtual void Swizzle(const char channels[4]) = 0; - - //get/set properties of the image object - virtual void GetColorRange(AZ::Color& minColor, AZ::Color& maxColor) const = 0; - virtual void SetColorRange(const AZ::Color& minColor, const AZ::Color& maxColor) = 0; - virtual AZ::u32 GetNumPersistentMips() const = 0; - virtual void SetNumPersistentMips(AZ::u32 nMips) = 0; - virtual float GetAverageBrightness() const = 0; - virtual void SetAverageBrightness(float avgBrightness) = 0; - - // Derive new roughness from normal variance to preserve the bumpiness of normal map mips and to reduce specular aliasing. - // The derived roughness is combined with the artist authored roughness stored in the alpha channel of the normal map. - // The algorithm is based on the Frequency Domain Normal Mapping implementation presented by Neubelt and Pettineo at Siggraph 2013. - virtual void GlossFromNormals(bool hasAuthoredGloss) = 0; - - //convert gloss map from legacy distribution to new one. New World is still using legacy gloss map. - virtual void ConvertLegacyGloss() = 0; - - //clear image with color - virtual void ClearColor(float r, float g, float b, float a) = 0; - - virtual bool HasPowerOfTwoSizes() const = 0; - }; - - //loading function to load output dds file to a IImageObject - IImageObject* LoadImageFromDdsFile(const AZStd::string& filename); - IImageObject* LoadImageFromDdsFile(AZ::IO::SystemFileStream& fileLoadStream); - IImageObject* LoadAttachedImageFromDdsFile(const AZStd::string& filename, IImageObjectPtr originImage); - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingBus.h b/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingBus.h deleted file mode 100644 index 8b127b3f6e..0000000000 --- a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingBus.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace ImageProcessing -{ - class ImageProcessingRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - // Loads an image from a source file path - virtual IImageObjectPtr LoadImage(const AZStd::string& filePath) = 0; - - // Loads an image from a source file path and converts it to a format suitable for previewing in tools - virtual IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) = 0; - }; - using ImageProcessingRequestBus = AZ::EBus; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingEditorBus.h b/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingEditorBus.h deleted file mode 100644 index eae1fdeb6d..0000000000 --- a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingEditorBus.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include - -class QString; - -namespace ImageProcessingEditor -{ - class ImageProcessingEditorRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ///////////////////////////////////////////////////////////////////////// - - //! Open single texture file - virtual void OpenSourceTextureFile(const AZ::Uuid& textureSourceID) = 0; - }; - - using ImageProcessingEditorRequestBus = AZ::EBus; -}//namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Include/ImageProcessing/PixelFormats.h b/Gems/ImageProcessing/Code/Include/ImageProcessing/PixelFormats.h deleted file mode 100644 index 2ceb889ac9..0000000000 --- a/Gems/ImageProcessing/Code/Include/ImageProcessing/PixelFormats.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -namespace ImageProcessing -{ - enum EPixelFormat : int - { - //unsigned formats - ePixelFormat_R8G8B8A8 = 0, - ePixelFormat_R8G8B8X8, - ePixelFormat_R8G8, - ePixelFormat_R8, - ePixelFormat_A8, - ePixelFormat_R16G16B16A16, - ePixelFormat_R16G16, - ePixelFormat_R16, - - //Custom FourCC Formats - // Data in these FourCC formats is custom compressed data and only decodable by certain hardware. - //ASTC formats supported by ios devices with A8 processor. Also supported by Android Extension Pack. - ePixelFormat_ASTC_4x4, - ePixelFormat_ASTC_5x4, - ePixelFormat_ASTC_5x5, - ePixelFormat_ASTC_6x5, - ePixelFormat_ASTC_6x6, - ePixelFormat_ASTC_8x5, - ePixelFormat_ASTC_8x6, - ePixelFormat_ASTC_8x8, - ePixelFormat_ASTC_10x5, - ePixelFormat_ASTC_10x6, - ePixelFormat_ASTC_10x8, - ePixelFormat_ASTC_10x10, - ePixelFormat_ASTC_12x10, - ePixelFormat_ASTC_12x12, - //Formats supported by PowerVR GPU. Mainly for ios devices. - ePixelFormat_PVRTC2, //2bpp - ePixelFormat_PVRTC4, //4bpp - //formats for opengl and opengles 3.0 (android devices) - ePixelFormat_EAC_R11, //one channel unsigned data - ePixelFormat_EAC_RG11, //two channel unsigned data - ePixelFormat_ETC2, //Compresses RGB888 data, it taks 4x4 groups of pixel data and compresses each into a 64-bit - ePixelFormat_ETC2a, //Compresses RGBA8888 data with full alpha support - - // Standardized Compressed DXGI Formats (DX10+) - // Data in these compressed formats is hardware decodable on all DX10 chips, and manageable with the DX10-API. - ePixelFormat_BC1, // RGB without alpha, 0.5 byte/px - ePixelFormat_BC1a, // RGB with 1 bit of alpha, 0.5 byte/px. - ePixelFormat_BC3, // RGBA 1 byte/px, color maps with full alpha. - ePixelFormat_BC3t, // BC3 with alpha weighted color - ePixelFormat_BC4, // One color channel, 0.5 byte/px, unsigned - ePixelFormat_BC4s, // BC4, signed - ePixelFormat_BC5, // Two color channels, 1 byte/px, unsigned. Usually use for tangent-space normal maps - ePixelFormat_BC5s, // BC5, signed - ePixelFormat_BC6UH, // RGB, floating-point. Used for HDR images. Decompress to RGB in half floating point - ePixelFormat_BC7, // RGB or RGBA. 1 byte/px. Three color channels (4 to 7 bits per channel) with 0 to 8 bits of alpha - ePixelFormat_BC7t, // BC& with alpha weighted color - - // Float formats - // Data in a Float format is floating point data. - ePixelFormat_R9G9B9E5, - ePixelFormat_R32G32B32A32F, - ePixelFormat_R32G32F, - ePixelFormat_R32F, - ePixelFormat_R16G16B16A16F, - ePixelFormat_R16G16F, - ePixelFormat_R16F, - - //legacy format. Only used to load old converted dds files. - ePixelFormat_B8G8R8A8, //32bits rgba format - - ePixelFormat_R32, - - ePixelFormat_Count, - ePixelFormat_Unknown = ePixelFormat_Count - }; - - inline bool IsASTCFormat(EPixelFormat fmt) - { - return fmt == ePixelFormat_ASTC_4x4 || fmt == ePixelFormat_ASTC_5x4 || fmt == ePixelFormat_ASTC_5x5 || - fmt == ePixelFormat_ASTC_6x5 || fmt == ePixelFormat_ASTC_6x6 || fmt == ePixelFormat_ASTC_8x5 || - fmt == ePixelFormat_ASTC_8x6 || fmt == ePixelFormat_ASTC_8x8 || fmt == ePixelFormat_ASTC_10x5 || - fmt == ePixelFormat_ASTC_10x6 || fmt == ePixelFormat_ASTC_10x8 || fmt == ePixelFormat_ASTC_10x10 || - fmt == ePixelFormat_ASTC_12x10 || fmt == ePixelFormat_ASTC_12x12; - } - - inline bool IsETCFormat(EPixelFormat fmt) - { - return fmt == ePixelFormat_ETC2 || fmt == ePixelFormat_ETC2a || fmt == ePixelFormat_EAC_R11 || - fmt == ePixelFormat_EAC_RG11; - } - - inline bool IsPVRTCFormat(EPixelFormat fmt) - { - return fmt == ePixelFormat_PVRTC2 || fmt == ePixelFormat_PVRTC4; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.cpp b/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.cpp deleted file mode 100644 index e8d4948cc9..0000000000 --- a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include "AtlasBuilderComponent.h" - -#include - -namespace TextureAtlasBuilder -{ - // AZ Components should only initialize their members to null and empty in constructor - // Allocation of data should occur in Init(), once we can guarantee reflection and registration of types - AtlasBuilderComponent::AtlasBuilderComponent() - { - } - - // Handle deallocation of your memory allocated in Init() - AtlasBuilderComponent::~AtlasBuilderComponent() - { - } - - // Init is where you'll actually allocate memory or create objects - // This ensures that any dependency components will have been been created and serialized - void AtlasBuilderComponent::Init() - { - } - - // Activate is where you'd perform registration with other objects and systems. - // All builder classes owned by this component should be registered here - // Any EBuses for the builder classes should also be connected at this point - void AtlasBuilderComponent::Activate() - { - AssetBuilderSDK::AssetBuilderDesc builderDescriptor; - builderDescriptor.m_name = "Atlas Worker Builder"; - builderDescriptor.m_version = 1; - builderDescriptor.m_patterns.emplace_back(AssetBuilderSDK::AssetBuilderPattern("*.texatlas", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_busId = azrtti_typeid(); - builderDescriptor.m_createJobFunction = AZStd::bind(&AtlasBuilderWorker::CreateJobs, &m_atlasBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - builderDescriptor.m_processJobFunction = AZStd::bind(&AtlasBuilderWorker::ProcessJob, &m_atlasBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - - m_atlasBuilder.BusConnect(builderDescriptor.m_busId); - - AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor); - } - - // Disconnects from any EBuses we connected to in Activate() - // Unregisters from objects and systems we register with in Activate() - void AtlasBuilderComponent::Deactivate() - { - m_atlasBuilder.BusDisconnect(); - - // We don't need to unregister the builder - the AP will handle this for us, because it is managing the lifecycle of this component - } - - // Reflect the input and output formats for the serializer - void AtlasBuilderComponent::Reflect(AZ::ReflectContext* context) - { - // components also get Reflect called automatically - // this is your opportunity to perform static reflection or type registration of any types you want the serializer to know about - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(0) - ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })) - ; - } - - AtlasBuilderInput::Reflect(context); - } - - void AtlasBuilderComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("Atlas Builder Plugin Service", 0x35974d0d)); - } - - void AtlasBuilderComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("Atlas Builder Plugin Service", 0x35974d0d)); - } - - void AtlasBuilderComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - AZ_UNUSED(required); - } - - void AtlasBuilderComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) - { - AZ_UNUSED(dependent); - } -} diff --git a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.h b/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.h deleted file mode 100644 index eb8b85dfcf..0000000000 --- a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ - -#pragma once - -#include -#include -#include "AtlasBuilderWorker.h" - -namespace TextureAtlasBuilder -{ - class AtlasBuilderComponent : public AZ::Component - { - public: - AZ_COMPONENT(AtlasBuilderComponent, "{F49987FB-3375-4417-AB83-97B44C78B335}"); - - AtlasBuilderComponent(); - ~AtlasBuilderComponent() override; - - void Init() override; - void Activate() override; - void Deactivate() override; - - //! Reflect formats for input and output - static void Reflect(AZ::ReflectContext* context); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - - private: - AtlasBuilderWorker m_atlasBuilder; - }; -} // namespace TextureAtlasBuilder diff --git a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.cpp b/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.cpp deleted file mode 100644 index 95cc9b851f..0000000000 --- a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.cpp +++ /dev/null @@ -1,1494 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include "AtlasBuilderWorker.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -namespace TextureAtlasBuilder -{ - //! Counts leading zeros - uint32 CountLeadingZeros32(uint32 x) - { - return x == 0 ? 32 : az_clz_u32(x); - } - - //! Integer log2 - uint32 IntegerLog2(uint32 x) - { - return 31 - CountLeadingZeros32(x); - } - - bool IsFolderPath(const AZStd::string& path) - { - bool hasExtension = AzFramework::StringFunc::Path::HasExtension(path.c_str()); - return !hasExtension; - } - - bool HasTrailingSlash(const AZStd::string& path) - { - size_t pathLength = path.size(); - return (pathLength > 0 && (path.at(pathLength - 1) == '/' || path.at(pathLength - 1) == '\\')); - } - - bool ResolveRelativePath(const AZStd::string& relativePath, const AZStd::string& watchDirectory, AZStd::string& resolvedFullPathOut) - { - // Get full path by appending the relative path to the watch directory - AZ::IO::FixedMaxPath resolvedPath; - AZ::IO::FileIOBase::GetInstance()->ReplaceAlias(resolvedPath, AZ::IO::PathView{relativePath}); - - resolvedPath = (AZ::IO::FixedMaxPath{watchDirectory} / resolvedPath).LexicallyNormal(); - resolvedFullPathOut = resolvedPath.String(); - - return true; - } - - bool GetAbsoluteSourcePathFromRelativePath(const AZStd::string& relativeSourcePath, AZStd::string& absoluteSourcePathOut) - { - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, relativeSourcePath.c_str(), info, watchFolder); - if (result) - { - absoluteSourcePathOut = AZStd::string::format("%s/%s", watchFolder.c_str(), info.m_relativePath.c_str()); - - // Normalize path - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePathKeepCase, absoluteSourcePathOut); - } - return result; - } - - const ImageProcessing::PresetSettings* GetImageProcessPresetSettings(const AZStd::string& presetName, const AZStd::string& platformIdentifier) - { - // Get the specified presetId - AZ::Uuid presetId = ImageProcessing::BuilderSettingManager::Instance()->GetPresetIdFromName(presetName); - if (presetId.IsNull()) - { - AZ_Error("Texture Editor", false, "Texture Preset %s has no associated UUID.", presetName.c_str()); - return nullptr; - } - - // Get the preset settings for the platform this job is building for - const ImageProcessing::PresetSettings* presetSettings = ImageProcessing::BuilderSettingManager::Instance()->GetPreset( - presetId, platformIdentifier); - - return presetSettings; - } - - // Reflect the input parameters - void AtlasBuilderInput::Reflect(AZ::ReflectContext* context) - { - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(1) - ->Field("Force Square", &AtlasBuilderInput::m_forceSquare) - ->Field("Force Power of Two", &AtlasBuilderInput::m_forcePowerOf2) - ->Field("Include White Texture", &AtlasBuilderInput::m_includeWhiteTexture) - ->Field("Maximum Dimension", &AtlasBuilderInput::m_maxDimension) - ->Field("Padding", &AtlasBuilderInput::m_padding) - ->Field("UnusedColor", &AtlasBuilderInput::m_unusedColor) - ->Field("PresetName", &AtlasBuilderInput::m_presetName) - ->Field("Textures to Add", &AtlasBuilderInput::m_filePaths); - } - } - - // Supports a custom parser format - AtlasBuilderInput AtlasBuilderInput::ReadFromFile(const AZStd::string& path, const AZStd::string& directory, bool& valid) - { - // Open the file - AZ::IO::FileIOBase* input = AZ::IO::FileIOBase::GetInstance(); - AZ::IO::HandleType handle; - input->Open(path.c_str(), AZ::IO::OpenMode::ModeRead, handle); - - // Read the file - AZ::u64 size; - input->Size(handle, size); - char* buffer = new char[size + 1]; - input->Read(handle, buffer, size); - buffer[size] = 0; - - // Close the file - input->Close(handle); - - // Prepare the output - AtlasBuilderInput data; - - // Parse the input into lines - AZStd::vector lines; - AzFramework::StringFunc::Tokenize(buffer, lines, "\n\t"); - delete[] buffer; - - // Parse the individual lines - for (auto line : lines) - { - line = AzFramework::StringFunc::TrimWhiteSpace(line, true, true); - // Check for comments and empty lines - if ((line.length() >= 2 && line[0] == '/' && line[1] == '/') || line.length() < 1) - { - continue; - } - else if (line.find('=') != -1) - { - AZStd::vector args; - AzFramework::StringFunc::Tokenize(line.c_str(), args, '=', true, true); - - if (args.size() > 2) - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to parse line: Excessive '=' symbols were found: \"%s\"", line.c_str()).c_str()); - valid = false; - } - - // Trim whitespace - args[0] = AzFramework::StringFunc::TrimWhiteSpace(args[0], true, true); - args[1] = AzFramework::StringFunc::TrimWhiteSpace(args[1], true, true); - - // No case sensitivity for property names - AZStd::to_lower(args[0].begin(), args[0].end()); - - // Keep track of if the value is rejected - bool accepted = false; - - if (args[0] == "square") - { - accepted = AzFramework::StringFunc::LooksLikeBool(args[1].c_str()); - if (accepted) - { - data.m_forceSquare = AzFramework::StringFunc::ToBool(args[1].c_str()); - } - } - else if (args[0] == "poweroftwo") - { - accepted = AzFramework::StringFunc::LooksLikeBool(args[1].c_str()); - if (accepted) - { - data.m_forcePowerOf2 = AzFramework::StringFunc::ToBool(args[1].c_str()); - } - } - else if (args[0] == "whitetexture") - { - accepted = AzFramework::StringFunc::LooksLikeBool(args[1].c_str()); - if (accepted) - { - data.m_includeWhiteTexture = AzFramework::StringFunc::ToBool(args[1].c_str()); - } - } - else if (args[0] == "maxdimension") - { - accepted = AzFramework::StringFunc::LooksLikeInt(args[1].c_str()); - if (accepted) - { - data.m_maxDimension = AzFramework::StringFunc::ToInt(args[1].c_str()); - } - } - else if (args[0] == "padding") - { - accepted = AzFramework::StringFunc::LooksLikeInt(args[1].c_str()); - if (accepted) - { - data.m_padding = AzFramework::StringFunc::ToInt(args[1].c_str()); - } - } - else if (args[0] == "unusedcolor") - { - accepted = args[1].at(0) == '#' && args[1].length() == 9; - if (accepted) - { - AZStd::string color = AZStd::string::format("%s%s%s%s", args[1].substr(7).c_str(), args[1].substr(5, 2).c_str(), - args[1].substr(3, 2).c_str(), args[1].substr(1, 2).c_str()); - data.m_unusedColor.FromU32(AZStd::stoul(color, nullptr, 16)); - } - } - else if (args[0] == "presetname") - { - accepted = true; - data.m_presetName = args[1]; - } - else - { - // Supress accepted error because this error superceeds it - accepted = true; - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to parse line: Unrecognized property: \"%s\"", args[0].c_str()).c_str()); - } - - // If the property is recognized but the value is rejected, fail the job - if (!accepted) - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to parse line: Invalid value assigned to property: Property: \"%s\" Value: \"%s\"", args[0].c_str(), args[1].c_str()).c_str()); - } - } - else if ((line[0] == '-')) - { - // Remove image files - AZStd::string remove = line.substr(1); - remove = AzFramework::StringFunc::TrimWhiteSpace(remove, true, true); - if (remove.find('*') != -1) - { - AZStd::string resolvedAbsolutePath; - bool resolved = ResolveRelativePath(remove, directory, resolvedAbsolutePath); - if (resolved) - { - RemoveFilesUsingWildCard(data.m_filePaths, resolvedAbsolutePath); - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to resolve relative path: %s", remove.c_str()).c_str()); - } - } - else if (IsFolderPath(remove)) - { - AZStd::string resolvedAbsolutePath; - bool resolved = ResolveRelativePath(remove, directory, resolvedAbsolutePath); - if (resolved) - { - RemoveFolderContents(data.m_filePaths, resolvedAbsolutePath); - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to resolve relative path: %s", remove.c_str()).c_str()); - } - } - else - { - // Get the full path to the source image from the relative source path - AZStd::string fullSourceAssetPathName; - bool fullPathFound = GetAbsoluteSourcePathFromRelativePath(remove, fullSourceAssetPathName); - - if (!fullPathFound) - { - // Try to resolve relative path as it might be using "./" or "../" - fullPathFound = ResolveRelativePath(remove, directory, fullSourceAssetPathName); - } - - if (fullPathFound) - { - for (size_t i = 0; i < data.m_filePaths.size(); ++i) - { - if (data.m_filePaths[i] == fullSourceAssetPathName) - { - data.m_filePaths.erase(data.m_filePaths.begin() + i); - } - } - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to get source asset path for image: %s", remove.c_str()).c_str()); - } - } - } - else - { - // Add image files - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePathKeepCase, line); - bool duplicate = false; - if (line.find('*') != -1) - { - AZStd::string resolvedAbsolutePath; - bool resolved = ResolveRelativePath(line, directory, resolvedAbsolutePath); - if (resolved) - { - AddFilesUsingWildCard(data.m_filePaths, resolvedAbsolutePath); - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to resolve relative path: %s", line.c_str()).c_str()); - } - } - else if (IsFolderPath(line)) - { - AZStd::string resolvedAbsolutePath; - bool resolved = ResolveRelativePath(line, directory, resolvedAbsolutePath); - if (resolved) - { - AddFolderContents(data.m_filePaths, resolvedAbsolutePath, valid); - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to resolve relative path: %s", line.c_str()).c_str()); - } - } - else - { - // Get the full path to the source image from the relative source path - AZStd::string fullSourceAssetPathName; - bool fullPathFound = GetAbsoluteSourcePathFromRelativePath(line, fullSourceAssetPathName); - - if (!fullPathFound) - { - // Try to resolve relative path as it might be using "./" or "../" - fullPathFound = ResolveRelativePath(line, directory, fullSourceAssetPathName); - } - - if (fullPathFound) - { - // Prevent duplicates - for (size_t i = 0; i < data.m_filePaths.size() && !duplicate; ++i) - { - duplicate = data.m_filePaths[i] == fullSourceAssetPathName; - } - if (!duplicate) - { - data.m_filePaths.push_back(fullSourceAssetPathName); - } - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to get source asset path for image: %s", line.c_str()).c_str()); - } - } - } - } - - return data; - } - - void AtlasBuilderInput::AddFilesUsingWildCard(AZStd::vector& paths, const AZStd::string& insert) - { - AZ::IO::PathView fullPathView(insert); - - // Find first path element with a wild card in it - AZ::IO::Path staticPath; - auto wildCardPathElementIter = fullPathView.begin(); - for (; wildCardPathElementIter != fullPathView.end(); ++wildCardPathElementIter) - { - if (wildCardPathElementIter->Native().contains('*')) - { - break; - } - staticPath /= *wildCardPathElementIter; - } - - // The remaining path segments are part of the wild card path - - AZStd::vector candidates{ AZStd::move(staticPath) }; - for(; wildCardPathElementIter != fullPathView.end() && !candidates.empty(); ++wildCardPathElementIter) - { - AZStd::vector nextCandidates; - for (const AZ::IO::Path& candidate : candidates) - { - if (QDir inputFolder(QString::fromUtf8(candidate.c_str(), aznumeric_cast(candidate.Native().size()))); - inputFolder.exists()) - { - QFileInfoList entries = inputFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files); - for (const QFileInfo& entry : entries) - { - AZ::IO::Path filenameEntry(entry.fileName().toUtf8().data()); - if (filenameEntry.Match(wildCardPathElementIter->Native())) - { - nextCandidates.push_back(entry.filePath().toUtf8().data()); - } - } - } - } - candidates = nextCandidates; - } - - for (const AZ::IO::Path& candidate : candidates) - { - QFileInfo fileInfo(QString::fromUtf8(candidate.c_str(), aznumeric_cast(candidate.Native().size()))); - if (fileInfo.isFile()) - { - AZStd::string ext = fileInfo.suffix().toUtf8().data(); - if (ImageProcessing::IsExtensionSupported(ext.c_str()) && ext != "dds") - { - auto FindExistingPath = [&candidate](const AZStd::string& path) - { - return candidate == AZ::IO::PathView(path); - }; - if (auto foundIt = AZStd::find_if(paths.begin(), paths.end(), FindExistingPath); - foundIt == paths.end()) - { - AZStd::string normalizedPath = AZ::IO::Path(candidate.Native(), AZ::IO::PosixPathSeparator).LexicallyNormal().Native(); - paths.push_back(AZStd::move(normalizedPath)); - } - } - } - else if (fileInfo.isDir()) - { - bool waste = true; - AddFolderContents(paths, candidate.Native(), waste); - } - } - } - - void AtlasBuilderInput::RemoveFilesUsingWildCard(AZStd::vector& paths, const AZStd::string& remove) - { - auto RemoveWildCardPath = [&remove](const AZStd::string& subPath) - { - return AZ::IO::PathView(subPath).Match(remove); - }; - AZStd::erase_if(paths, RemoveWildCardPath); - } - - // Replaces all folder paths with the files they contain - void AtlasBuilderInput::AddFolderContents(AZStd::vector& paths, const AZStd::string& insert, bool& valid) - { - if (QDir inputFolder(insert.c_str()); inputFolder.exists()) - { - QFileInfoList entries = inputFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files); - for (const QFileInfo& entry : entries) - { - AZ::IO::Path child = entry.filePath().toUtf8().data(); - AZStd::string ext = entry.suffix().toUtf8().data(); - const bool isDir = entry.isDir(); - if (isDir) - { - AddFolderContents(paths, child.Native(), valid); - } - else if (ImageProcessing::IsExtensionSupported(ext.c_str()) && ext != "dds") - { - auto FindExistingPath = [&child](const AZStd::string& path) - { - return child == AZ::IO::PathView(path); - }; - if (auto foundIter = AZStd::find_if(paths.begin(), paths.end(), FindExistingPath); - foundIter == paths.end()) - { - // Normalize the path to have posix slashes - AZStd::string normalizedPath = AZ::IO::Path(child.Native(), AZ::IO::PosixPathSeparator).LexicallyNormal().Native(); - paths.push_back(AZStd::move(normalizedPath)); - } - } - } - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to find requested directory: %s", insert.c_str()).c_str()); - } - } - - // Removes all of the contents of a folder - void AtlasBuilderInput::RemoveFolderContents(AZStd::vector& paths, const AZStd::string& remove) - { - auto RemoveSubPath = [folder = AZ::IO::PathView(remove)](const AZStd::string& subPath) - { - return AZ::IO::PathView(subPath).IsRelativeTo(folder); - }; - AZStd::erase_if(paths, RemoveSubPath); - } - - // Note - Shutdown will be called on a different thread than your process job thread - void AtlasBuilderWorker::ShutDown() { m_isShuttingDown = true; } - - void AtlasBuilderWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, - AssetBuilderSDK::CreateJobsResponse& response) - { - // Read in settings/filepaths to set dependencies - AZStd::string fullPath; - AzFramework::StringFunc::Path::Join( - request.m_watchFolder.c_str(), request.m_sourceFile.c_str(), fullPath, true, true); - // Check if input is valid - bool valid = true; - AtlasBuilderInput input = AtlasBuilderInput::ReadFromFile(fullPath, request.m_watchFolder, valid); - - // Set dependencies - for (int i = 0; i < input.m_filePaths.size(); ++i) - { - AssetBuilderSDK::SourceFileDependency dependency; - dependency.m_sourceFileDependencyPath = input.m_filePaths[i].c_str(); - response.m_sourceFileDependencyList.push_back(dependency); - } - - // We process the same file for all platforms - for (const AssetBuilderSDK::PlatformInfo& info : request.m_enabledPlatforms) - { - if (ImageProcessing::BuilderSettingManager::Instance()->DoesSupportPlatform(info.m_identifier)) - { - AssetBuilderSDK::JobDescriptor descriptor = GetJobDescriptor(request.m_sourceFile, input); - descriptor.SetPlatformIdentifier(info.m_identifier.c_str()); - response.m_createJobOutputs.push_back(descriptor); - } - } - - if (valid) - { - response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; - } - - return; - } - - AssetBuilderSDK::JobDescriptor AtlasBuilderWorker::GetJobDescriptor(const AZStd::string& sourceFile, const AtlasBuilderInput& input) - { - // Get the extension of the file - AZStd::string ext; - AzFramework::StringFunc::Path::GetExtension(sourceFile.c_str(), ext, false); - AZStd::to_upper(ext.begin(), ext.end()); - - AssetBuilderSDK::JobDescriptor descriptor; - descriptor.m_jobKey = ext + " Atlas"; - descriptor.m_critical = false; - descriptor.m_jobParameters[AZ_CRC("forceSquare")] = input.m_forceSquare ? "true" : "false"; - descriptor.m_jobParameters[AZ_CRC("forcePowerOf2")] = input.m_forcePowerOf2 ? "true" : "false"; - descriptor.m_jobParameters[AZ_CRC("includeWhiteTexture")] = input.m_includeWhiteTexture ? "true" : "false"; - descriptor.m_jobParameters[AZ_CRC("padding")] = AZStd::to_string(input.m_padding); - descriptor.m_jobParameters[AZ_CRC("maxDimension")] = AZStd::to_string(input.m_maxDimension); - descriptor.m_jobParameters[AZ_CRC("filePaths")] = AZStd::to_string(input.m_filePaths.size()); - - AZ::u32 col = input.m_unusedColor.ToU32(); - descriptor.m_jobParameters[AZ_CRC("unusedColor")] = AZStd::to_string(*reinterpret_cast(&col)); - descriptor.m_jobParameters[AZ_CRC("presetName")] = input.m_presetName; - - // The starting point for the list - const int start = static_cast(descriptor.m_jobParameters.size()) + 1; - descriptor.m_jobParameters[AZ_CRC("startPoint")] = AZStd::to_string(start); - - for (int i = 0; i < input.m_filePaths.size(); ++i) - { - descriptor.m_jobParameters[start + i] = input.m_filePaths[i]; - } - - return descriptor; - } - - void AtlasBuilderWorker::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, - AssetBuilderSDK::ProcessJobResponse& response) - { - // Before we begin, let's make sure we are not meant to abort. - AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId); - - AZStd::vector productFilepaths; - - const AZStd::string path = request.m_fullPath; - - bool imageProcessingSuccessful = false; - - // read in settings/filepaths - AtlasBuilderInput input; - input.m_forceSquare = AzFramework::StringFunc::ToBool(request.m_jobDescription.m_jobParameters.find(AZ_CRC("forceSquare"))->second.c_str()); - input.m_forcePowerOf2 = AzFramework::StringFunc::ToBool(request.m_jobDescription.m_jobParameters.find(AZ_CRC("forcePowerOf2"))->second.c_str()); - input.m_includeWhiteTexture = AzFramework::StringFunc::ToBool(request.m_jobDescription.m_jobParameters.find(AZ_CRC("includeWhiteTexture"))->second.c_str()); - input.m_padding = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("padding"))->second.c_str()); - input.m_maxDimension = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("maxDimension"))->second.c_str()); - int startAsInt = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("startPoint"))->second.c_str()); - int sizeAsInt = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("filePaths"))->second.c_str()); - AZ::u32 start = static_cast(AZStd::max(0, startAsInt)); - AZ::u32 size = static_cast(AZStd::max(0, sizeAsInt)); - - int col = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("unusedColor"))->second.c_str()); - input.m_unusedColor.FromU32(*reinterpret_cast(&col)); - - input.m_presetName = request.m_jobDescription.m_jobParameters.find(AZ_CRC("presetName"))->second; - - for (AZ::u32 i = 0; i < size; ++i) - { - input.m_filePaths.push_back(request.m_jobDescription.m_jobParameters.find(start + i)->second); - } - - if (input.m_filePaths.empty()) - { - AZ_Error("AtlasBuilder", false, "No image files specified. Cannot create an empty atlas."); - return; - } - - // Don't allow padding to be less than zero - if (input.m_padding < 0) - { - input.m_padding = 0; - } - - if (input.m_presetName.empty()) - { - // Default to the TextureAtlas preset which is currently set to use compression for all platforms except for iOS. - // Currently the only fully supported compression for iOS is PVRTC which requires the texture to be square and a power of 2. - // Due to this limitation, we default to using no compression for iOS until ASTC is fully supported - const AZStd::string defaultPresetName = "TextureAtlas"; - input.m_presetName = defaultPresetName; - } - - // Get a preset to use for the output image - const ImageProcessing::PresetSettings* preset = GetImageProcessPresetSettings(input.m_presetName, request.m_platformInfo.m_identifier); - if (preset) - { - // Check the preset's pixel format requirements - const ImageProcessing::PixelFormatInfo* pixelFormatInfo = ImageProcessing::CPixelFormats::GetInstance().GetPixelFormatInfo(preset->m_pixelFormat); - if (pixelFormatInfo && pixelFormatInfo->bSquarePow2) - { - // Override the user config settings to force square and power of 2. - // Otherwise the image conversion process will stretch the image to satisfy these requirements - input.m_forceSquare = true; - input.m_forcePowerOf2 = true; - } - } - else - { - AZ_Error("AtlasBuilder", false, "Could not find a preset setting for the output image."); - return; - } - - // Read in images - AZStd::vector images; - AZ::u64 totalArea = 0; - int maxArea = input.m_maxDimension * input.m_maxDimension; - bool sizeFailure = false; - for (int i = 0; i < input.m_filePaths.size() && !jobCancelListener.IsCancelled(); ++i) - { - ImageProcessing::IImageObject* inputImage = ImageProcessing::LoadImageFromFile(input.m_filePaths[i]); - // Check if we were able to load the image - if (inputImage) - { - ImageProcessing::IImageObjectPtr image = ImageProcessing::IImageObjectPtr(inputImage); - images.push_back(image); - totalArea += inputImage->GetWidth(0) * inputImage->GetHeight(0); - } - else - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to load file: %s", input.m_filePaths[i].c_str()).c_str()); - return; - } - if (maxArea < totalArea) - { - sizeFailure = true; - } - } - // If we get cancelled, return - if (jobCancelListener.IsCancelled()) - { - return; - } - - if (sizeFailure) - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Total image area exceeds maximum alotted area. %llu > %d", totalArea, maxArea).c_str()); - return; - } - - // Convert all image paths to their output format referenced at runtime - for (auto& filePath : input.m_filePaths) - { - // Get path relative to the watch folder - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, filePath.c_str(), info, watchFolder); - if (!result) - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to get relative source path for image: %s", filePath.c_str()).c_str()); - return; - } - - // Remove extension - filePath = info.m_relativePath.substr(0, info.m_relativePath.find_last_of('.')); - - // Normalize path - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePathKeepCase, filePath); - } - - // Add white texture if we need to - if (input.m_includeWhiteTexture) - { - ImageProcessing::IImageObjectPtr texture(ImageProcessing::IImageObject::CreateImage( - cellSize, cellSize, 1, ImageProcessing::EPixelFormat::ePixelFormat_R8G8B8A8)); - - // Make the texture white - texture->ClearColor(1, 1, 1, 1); - images.push_back(texture); - input.m_filePaths.push_back("WhiteTexture"); - } - - // Generate algorithm inputs - ImageDimensionData data; - for (int i = 0; i < images.size(); ++i) - { - data.push_back(IndexImageDimension(i, - ImageDimension(images[i]->GetWidth(0), - images[i]->GetHeight(0)))); - } - AZStd::sort(data.begin(), data.end()); - - // Run algorithm - - // Variables that keep track of the optimal solution - int resultWidth = -1; - int resultHeight = -1; - - // Check that the max dimension is not large enough for the area to loop past the maximum integer - // This is important because we do not want the area to be calculated negative - if (input.m_maxDimension > 65535) - { - input.m_maxDimension = 65535; - } - - // Get the optimal mappings based on the input settings - AZStd::vector paddedMap; - size_t amountFit = 0; - if (!TryTightening( - input, data, GetWidest(data), GetTallest(data), aznumeric_cast(totalArea), input.m_padding, resultWidth, resultHeight, amountFit, paddedMap)) - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Cannot fit images into given maximum atlas size (%dx%d). Only %zu out of %zu images fit.", input.m_maxDimension, input.m_maxDimension, amountFit, input.m_filePaths.size()).c_str()); - // For some reason, failing the assert isn't enough to stop the Asset builder. It will still fail further - // down when it tries to assemble the atlas, but returning here is cleaner. - return; - } - - // Move coordinates from algorithm space to padded result space - TextureAtlasNamespace::AtlasCoordinateSets output; - resultWidth = 0; - resultHeight = 0; - AZStd::vector map; - for (int i = 0; i < paddedMap.size(); ++i) - { - map.push_back(AtlasCoordinates(paddedMap[i].GetLeft(), paddedMap[i].GetLeft() + images[data[i].first]->GetWidth(0), paddedMap[i].GetTop(), paddedMap[i].GetTop() + images[data[i].first]->GetHeight(0))); - resultHeight = resultHeight > map[i].GetBottom() ? resultHeight : map[i].GetBottom(); - resultWidth = resultWidth > map[i].GetRight() ? resultWidth : map[i].GetRight(); - - const AZStd::string& outputFilePath = input.m_filePaths[data[i].first]; - output.push_back(AZStd::pair(outputFilePath, map[i])); - } - if (input.m_forcePowerOf2) - { - resultWidth = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(resultWidth - 1)))); - resultHeight = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(resultHeight - 1)))); - } - else - { - resultWidth = (resultWidth + (cellSize - 1)) / cellSize * cellSize; - resultHeight = (resultHeight + (cellSize - 1)) / cellSize * cellSize; - } - if (input.m_forceSquare) - { - if (resultWidth > resultHeight) - { - resultHeight = resultWidth; - } - else - { - resultWidth = resultHeight; - } - } - - // Process texture sheet - ImageProcessing::IImageObjectPtr outImage(ImageProcessing::IImageObject::CreateImage( - resultWidth, resultHeight, 1, ImageProcessing::EPixelFormat::ePixelFormat_R8G8B8A8)); - - // Clear the sheet - outImage->ClearColor(input.m_unusedColor.GetR(), input.m_unusedColor.GetG(), input.m_unusedColor.GetB(), input.m_unusedColor.GetA()); - - AZ::u8* outBuffer = nullptr; - AZ::u32 outPitch; - outImage->GetImagePointer(0, outBuffer, outPitch); - - // Copy images over - for (int i = 0; i < map.size() && !jobCancelListener.IsCancelled(); ++i) - { - AZ::u8* inBuffer = nullptr; - AZ::u32 inPitch; - images[data[i].first]->GetImagePointer(0, inBuffer, inPitch); - int j = 0; - - // The padding calculated here is the amount of excess horizontal space measured in bytes that are in each - // row of the destination space AFTER the placement of the source row. - int rightPadding = (paddedMap[i].GetRight() - map[i].GetRight() - input.m_padding); - if (map[i].GetRight() + rightPadding > resultWidth) - { - rightPadding = resultWidth - map[i].GetRight(); - } - rightPadding *= bytesPerPixel; - int bottomPadding = (paddedMap[i].GetBottom() - map[i].GetBottom() - input.m_padding); - if (map[i].GetBottom() + bottomPadding > resultHeight) - { - bottomPadding = resultHeight - map[i].GetBottom(); - } - - int leftPadding = 0; - if (map[i].GetLeft() - input.m_padding >= 0) - { - leftPadding = input.m_padding * bytesPerPixel; - } - - int topPadding = 0; - if (map[i].GetTop() - input.m_padding >= 0) - { - topPadding = input.m_padding; - } - - for (j = 0; j < map[i].GetHeight(); ++j) - { - // When we multiply `map[i].GetLeft()` by 4, we are changing the measure from atlas space, to byte array - // space. The number is 4 because in this format, each pixel is 4 bytes long. - memcpy(outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel), - inBuffer + inPitch * j, - inPitch); - // Fill in the last bit of the row in the destination space with the same colors - SetPixels(outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel) + inPitch, - outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel) + inPitch - bytesPerPixel, - rightPadding); - // Fill in the first bit of the row in the destination space with the same colors - SetPixels(outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel), - leftPadding); - } - // Fill in the last few rows of the buffer with the same colors - for (; j < map[i].GetHeight() + bottomPadding; ++j) - { - memcpy(outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - outBuffer + (map[i].GetBottom() - 1) * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - inPitch + leftPadding + rightPadding); - } - for (j = 1; j <= topPadding; ++j) - { - memcpy(outBuffer + (map[i].GetTop() - j) * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - outBuffer + map[i].GetTop() * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - inPitch + rightPadding + leftPadding); - } - } - - // If we get cancelled, return - if (jobCancelListener.IsCancelled()) - { - return; - } - - // Output Atlas Coordinates - AZStd::string fileName; - AZStd::string outputPath; - AzFramework::StringFunc::Path::GetFullFileName(request.m_sourceFile.c_str(), fileName); - fileName = fileName.append("idx"); - AzFramework::StringFunc::Path::Join( - request.m_tempDirPath.c_str(), fileName.c_str(), outputPath, true, true); - - // Output texture sheet - AZStd::string imageFileName, imageOutputPath; - AzFramework::StringFunc::Path::GetFileName(request.m_sourceFile.c_str(), imageFileName); - imageFileName += ".dds"; - AzFramework::StringFunc::Path::Join( - request.m_tempDirPath.c_str(), imageFileName.c_str(), imageOutputPath, true, true); - - // Let the ImageProcessor do the rest of the work. - ImageProcessing::TextureSettings textureSettings; - textureSettings.m_preset = preset->m_uuid; - - // Mipmaps for the texture atlas would require more work than the Image Processor does. This is because if we - // let the Image Processor make mipmaps, it might bleed the textures in the atlas together. - textureSettings.m_enableMipmap = false; - - // Check if the ImageBuilder wants to enable streaming - bool isStreaming = ImageProcessing::BuilderSettingManager::Instance() - ->GetBuilderSetting(request.m_platformInfo.m_identifier) - ->m_enableStreaming; - - bool canOverridePreset = false; - ImageProcessing::ImageConvertProcess* process = - new ImageProcessing::ImageConvertProcess(outImage, - textureSettings, - *preset, - false, - isStreaming, - canOverridePreset, - imageOutputPath, - request.m_platformInfo.m_identifier); - - if (process != nullptr) - { - // the process can be stopped if the job is cancelled or the worker is shutting down - while (!process->IsFinished() && !m_isShuttingDown && !jobCancelListener.IsCancelled()) - { - process->UpdateProcess(); - } - - // get process result - imageProcessingSuccessful = process->IsSucceed(); - process->GetAppendOutputFilePaths(productFilepaths); - - delete process; - } - else - { - imageProcessingSuccessful = false; - } - - if (imageProcessingSuccessful) - { - TextureAtlasNamespace::TextureAtlasRequestBus::Broadcast( - &TextureAtlasNamespace::TextureAtlasRequests::SaveAtlasToFile, outputPath, output, resultWidth, resultHeight); - response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(outputPath)); - response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_productAssetType = azrtti_typeid(); - response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_productSubID = 0; - - // The Image Processing Gem can produce multiple output files under certain - // circumstances, but the texture atlas is not expected to produce such output - if (productFilepaths.size() > 1) - { - AZ_Error("AtlasBuilder", false, "Image processing resulted in multiple output files. Texture atlas is expected to produce one output."); - response.m_outputProducts.clear(); - return; - } - - if (productFilepaths.size() > 0) - { - response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(productFilepaths[0])); - response.m_outputProducts.back().m_productAssetType = azrtti_typeid(); - response.m_outputProducts.back().m_productSubID = 1; - - // The texatlasidx file is a data file that indicates where the original parts are inside the atlas, - // and this would usually imply that it refers to its dds file in some way or needs it to function. - // The texatlasidx file should be the one that depends on the DDS because its possible to use the DDS - // without the texatlasid, but not the other way around - AZ::Data::AssetId productAssetId(request.m_sourceFileUUID, response.m_outputProducts.back().m_productSubID); - response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependencies.push_back(AssetBuilderSDK::ProductDependency(productAssetId, 0)); - response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependenciesHandled = true; // We've populated the dependencies immediately above so it's OK to tell the AP we've handled dependencies - } - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; - } - } - - bool AtlasBuilderWorker::TryPack(const ImageDimensionData& images, - int targetWidth, - int targetHeight, - int padding, - size_t& amountFit, - AZStd::vector& out) - { - // Start with one open slot and initialize a vector to store the closed products - AZStd::vector open; - AZStd::vector closed; - open.push_back(AtlasCoordinates(0, targetWidth, 0, targetHeight)); - bool slotNotFound = false; - for (size_t i = 0; i < images.size() && !slotNotFound; ++i) - { - slotNotFound = true; - // Try to place the image in every open slot - for (size_t j = 0; j < open.size(); ++j) - { - if (CanInsert(open[j], images[i].second, padding, targetWidth, targetHeight)) - { - // if it fits, subdivide the excess space in the slot, add it back to the open list and place the - // filled space into the closed vector - slotNotFound = false; - AtlasCoordinates spent(open[j].GetLeft(), - open[j].GetLeft() + images[i].second.m_width, - open[j].GetTop(), - open[j].GetTop() + images[i].second.m_height); - - // We are going to try pushing the object up / left to try to avoid creating tight open spaces. - bool needTrim = false; - AtlasCoordinates coords = spent; - // Modifying left will preserve width - coords.SetLeft(coords.GetLeft() - 1); - AddPadding(coords, padding, targetWidth, targetHeight); - while (spent.GetLeft() > 0 && !Collides(coords, closed)) - { - spent.SetLeft(coords.GetLeft()); - coords = spent; - coords.SetLeft(coords.GetLeft() - 1); - AddPadding(coords, padding, targetWidth, targetHeight); - needTrim = true; - } - // Refocus the search to see if we can push up - coords = spent; - coords.SetTop(coords.GetTop() - 1); - AddPadding(coords, padding, targetWidth, targetHeight); - while (spent.GetTop() > 0 && !Collides(coords, closed)) - { - spent.SetTop(coords.GetTop()); - coords = spent; - coords.SetTop(coords.GetTop() - 1); - AddPadding(coords, padding, targetWidth, targetHeight); - needTrim = true; - } - AddPadding(spent, padding, targetWidth, targetHeight); - if (needTrim) - { - TrimOverlap(open, spent); - closed.push_back(spent); - break; - } - AtlasCoordinates bigCoords; - AtlasCoordinates smallCoords; - - // Create the largest possible subdivision and another subdivision that uses the left over space - if (open[j].GetBottom() - spent.GetBottom() < open[j].GetRight() - spent.GetRight()) - { - smallCoords = AtlasCoordinates( - open[j].GetLeft(), spent.GetRight(), spent.GetBottom(), open[j].GetBottom()); - bigCoords = AtlasCoordinates(spent.GetRight(), open[j].GetRight(), open[j].GetTop(), smallCoords.GetBottom()); - } - else - { - bigCoords = AtlasCoordinates( - open[j].GetLeft(), open[j].GetRight(), spent.GetBottom(), open[j].GetBottom()); - smallCoords = AtlasCoordinates(spent.GetRight(), open[j].GetRight(), open[j].GetTop(), bigCoords.GetTop()); - } - - open.erase(open.begin() + j, open.begin() + j + 1); - if (bigCoords.GetHeight() > 0 && bigCoords.GetHeight() > 0) - { - InsertInOrder(open, bigCoords); - } - if (smallCoords.GetHeight() > 0 && smallCoords.GetHeight() > 0) - { - InsertInOrder(open, smallCoords); - } - - closed.push_back(spent); - break; - } - } - if (slotNotFound) - { - // If no single open slot can fit the object, do one last check to see if we can fit it in at any open - // corner. The reason we perform this check is in case the object can be fit across multiple different - // open spaces. If there is a space that an object can be fit in, it will probably involve the top left - // corner of that object in the top left corner of an open slot. This may miss some odd fits, but due to - // the nature of the packing algorithm, such solutions are highly unlikely to exist. If we wanted to - // expand the algorithm, we could theoretically base it on edges instead of corners to find all results, - // but it would not be time efficient. - for (size_t j = 0; j < open.size(); ++j) - { - AtlasCoordinates insert = AtlasCoordinates(open[j].GetLeft(), - open[j].GetLeft() + images[i].second.m_width, - open[j].GetTop(), - open[j].GetTop() + images[i].second.m_height); - AddPadding(insert, padding, targetWidth, targetHeight); - if (insert.GetRight() <= targetWidth && insert.GetBottom() <= targetHeight) - { - bool collision = Collides(insert, closed); - if (!collision) - { - closed.push_back(insert); - // Trim overlapping open slots - TrimOverlap(open, insert); - slotNotFound = false; - break; - } - } - } - } - } - // If we succeeded, update the output - if (!slotNotFound) - { - out = closed; - } - amountFit = amountFit > closed.size() ? amountFit : closed.size(); - return !slotNotFound; - } - - // Modifies slotList so that no items in slotList overlap with item - void AtlasBuilderWorker::TrimOverlap(AZStd::vector& slotList, AtlasCoordinates item) - { - for (size_t i = 0; i < slotList.size(); ++i) - { - if (Collides(slotList[i], item)) - { - // Subdivide the overlapping slot to seperate overlapping and non overlapping portions - AtlasCoordinates overlap = GetOverlap(item, slotList[i]); - AZStd::vector excess; - excess.push_back(AtlasCoordinates( - slotList[i].GetLeft(), overlap.GetRight(), slotList[i].GetTop(), overlap.GetTop())); - excess.push_back(AtlasCoordinates( - slotList[i].GetLeft(), overlap.GetLeft(), overlap.GetTop(), slotList[i].GetBottom())); - excess.push_back(AtlasCoordinates( - overlap.GetRight(), slotList[i].GetRight(), slotList[i].GetTop(), overlap.GetBottom())); - excess.push_back(AtlasCoordinates( - overlap.GetLeft(), slotList[i].GetRight(), overlap.GetBottom(), slotList[i].GetBottom())); - slotList.erase(slotList.begin() + i); - for (size_t j = 0; j < excess.size(); ++j) - { - if (excess[j].GetWidth() > 0 && excess[j].GetHeight() > 0) - { - InsertInOrder(slotList, excess[j]); - } - } - --i; - } - } - } - - // This function interprets input and performs the proper tightening option - bool AtlasBuilderWorker::TryTightening(AtlasBuilderInput input, - const ImageDimensionData& images, - int smallestWidth, - int smallestHeight, - int targetArea, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out) - { - if (input.m_forceSquare) - { - return TryTighteningSquare(images, - smallestWidth > smallestHeight ? smallestWidth : smallestHeight, - input.m_maxDimension, - targetArea, - input.m_forcePowerOf2, - padding, - resultWidth, - resultHeight, - amountFit, - out); - } - else - { - return TryTighteningOptimal(images, - smallestWidth, - smallestHeight, - input.m_maxDimension, - targetArea, - input.m_forcePowerOf2, - padding, - resultWidth, - resultHeight, - amountFit, - out); - } - } - - // Finds the optimal square solution by starting with the ideal solution and expanding the size of the space until everything fits - bool AtlasBuilderWorker::TryTighteningSquare(const ImageDimensionData& images, - int lowerBound, - int maxDimension, - int targetArea, - bool powerOfTwo, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out) - { - // Square solution cannot be smaller than the target area - int dimension = aznumeric_cast(sqrt(static_cast(targetArea))); - // Solution cannot be smaller than the smallest side - dimension = dimension > lowerBound ? dimension : lowerBound; - if (powerOfTwo) - { - // Starting dimension needs to be rounded up to the nearest power of two - dimension = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(dimension - 1)))); - } - - AZStd::vector track; - // Expand the square until the contents fit - while (!TryPack(images, dimension, dimension, padding, amountFit, track) && dimension <= maxDimension) - { - // Step to the next valid value - dimension = powerOfTwo ? dimension * 2 : dimension + cellSize; - } - // Make sure we found a solution - if (dimension > maxDimension) - { - return false; - } - - resultHeight = dimension; - resultWidth = dimension; - out = track; - return true; - } - - // Finds the optimal solution by starting with a somewhat optimal solution and searching for better solutions - bool AtlasBuilderWorker::TryTighteningOptimal(const ImageDimensionData& images, - int smallestWidth, - int smallestHeight, - int maxDimension, - int targetArea, - bool powerOfTwo, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out) - { - AZStd::vector track; - - // round max dimension down to a multiple of cellSize - AZ::u32 maxDimensionRounded = maxDimension - (maxDimension % cellSize); - - // The starting width is the larger of the widest individual texture and the width required - // to fit the total texture area given the max dimension - AZ::u32 smallestWidthDueToArea = targetArea / maxDimensionRounded; - AZ::u32 minWidth = AZStd::max(static_cast(smallestWidth), smallestWidthDueToArea); - - if (powerOfTwo) - { - // Starting dimension needs to be rounded up to the nearest power of two - minWidth = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(minWidth - 1)))); - } - - // Round min width up to the nearest compression unit - minWidth = (minWidth + (cellSize - 1)) / cellSize * cellSize; - - AZ::u32 height = 0; - // Finds the optimal thin solution - // This uses a standard binary search to find the smallest width that can pack everything - AZ::u32 lower = minWidth; - AZ::u32 upper = maxDimensionRounded; - AZ::u32 width = 0; - while (lower <= upper) - { - AZ::u32 testWidth = (lower + upper) / 2; // must be divisible by cellSize because lower and upper are - bool canPack = TryPack(images, testWidth, maxDimension, padding, amountFit, track); - if (canPack) - { - // it packed, continue looking for smaller widths that pack - width = testWidth; // best fit so far - upper = testWidth - cellSize; - } - else - { - // it failed to pack, don't try any widths smaller than this - lower = testWidth + cellSize; - } - } - // Make sure we found a solution - if (width == 0) - { - return false; - } - - // Find the height of the solution - for (int i = 0; i < track.size(); ++i) - { - uint32 bottom = static_cast(AZStd::max(0, track[i].GetBottom())); - if (height < bottom) - { - height = bottom; - } - } - - // Fix height for power of two when applicable - if (powerOfTwo) - { - // Starting dimensions need to be rounded up to the nearest power of two - height = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(height - 1)))); - } - - AZ::u32 resultArea = height * width; - // This for loop starts with the optimal thin width and makes it wider at each step. For each width, it - // calculates what height would be neccesary to have a more optimal solution than the stored solution. If the - // more optimal solution is valid, it tries shrinking the height until the solution fails. The loop ends when it - // is determined that a valid solution cannot exist at further steps - for (AZ::u32 testWidth = width; testWidth <= maxDimensionRounded && resultArea / testWidth >= static_cast(smallestHeight); - testWidth = powerOfTwo ? testWidth * 2 : testWidth + cellSize) - { - // The area of test height and width should be equal or less than resultArea - // Note: We don't need to force powers of two here because the Area and the width are already powers of two - int testHeight = resultArea / testWidth * cellSize / cellSize; - // Try the tighter pack - while (TryPack(images, static_cast(testWidth), testHeight, padding, amountFit, track)) - { - // Loop and continue to shrink the height until you cannot do so any further - width = testWidth; - height = testHeight; - resultArea = height * width; - // Try to step down a level - testHeight = powerOfTwo ? testHeight / 2 : testHeight - cellSize; - } - } - // Output the results of the function - out = track; - resultHeight = height; - resultWidth = width; - return true; - } - - // Allows us to keep the list of open spaces in order from lowest to highest area - void AtlasBuilderWorker::InsertInOrder(AZStd::vector& slotList, AtlasCoordinates item) - { - int area = item.GetWidth() * item.GetHeight(); - for (size_t i = 0; i < slotList.size(); ++i) - { - if (area < slotList[i].GetWidth() * slotList[i].GetHeight()) - { - slotList.insert(slotList.begin() + i, item); - return; - } - } - slotList.push_back(item); - } - - // Defines priority so that sorting can be meaningful. It may seem odd that larger items are "less than" smaller - // ones, but as this is a deduction of priority, not value, it is correct. - static bool operator<(ImageDimension a, ImageDimension b) - { - // Prioritize first by longest size - if ((a.m_width > a.m_height ? a.m_width : a.m_height) != (b.m_width > b.m_height ? b.m_width : b.m_height)) - { - return (a.m_width > a.m_height ? a.m_width : a.m_height) > (b.m_width > b.m_height ? b.m_width : b.m_height); - } - // Prioritize second by the length of the smaller side - if (a.m_width * a.m_height != b.m_width * b.m_height) - { - return a.m_width * a.m_height > b.m_width * b.m_height; - } - // Prioritize wider objects over taller objects for objects of the same size - else - { - return a.m_width > b.m_width; - } - } - - // Exposes priority logic to the sorting algorithm - static bool operator<(IndexImageDimension a, IndexImageDimension b) { return a.second < b.second; } - - // Tests if two coordinate sets intersect - bool Collides(AtlasCoordinates a, AtlasCoordinates b) - { - return !((a.GetRight() <= b.GetLeft()) || (a.GetBottom() <= b.GetTop()) || (b.GetRight() <= a.GetLeft()) - || (b.GetBottom() <= a.GetTop())); - } - - // Tests if an item collides with any items in a list - bool Collides(AtlasCoordinates item, AZStd::vector list) - { - for (size_t i = 0; i < list.size(); ++i) - { - if (Collides(list[i], item)) - { - return true; - } - } - return false; - } - - // Returns the overlap of two intersecting coordinate sets - AtlasCoordinates GetOverlap(AtlasCoordinates a, AtlasCoordinates b) - { - return AtlasCoordinates(b.GetLeft() > a.GetLeft() ? b.GetLeft() : a.GetLeft(), - b.GetRight() < a.GetRight() ? b.GetRight() : a.GetRight(), - b.GetTop() > a.GetTop() ? b.GetTop() : a.GetTop(), - b.GetBottom() < a.GetBottom() ? b.GetBottom() : a.GetBottom()); - } - - // Returns the width of the widest element in imageList - int AtlasBuilderWorker::GetWidest(const ImageDimensionData& imageList) - { - int max = 0; - for (size_t i = 0; i < imageList.size(); ++i) - { - if (max < imageList[i].second.m_width) - { - max = imageList[i].second.m_width; - } - } - return max; - } - - // Returns the height of the tallest element in imageList - int AtlasBuilderWorker::GetTallest(const ImageDimensionData& imageList) - { - int max = 0; - for (size_t i = 0; i < imageList.size(); ++i) - { - if (max < imageList[i].second.m_height) - { - max = imageList[i].second.m_height; - } - } - return max; - } - - // Performs an operation that copies a pixel to the output - void SetPixels(AZ::u8* dest, const AZ::u8* source, int destBytes) - { - if (destBytes >= bytesPerPixel) - { - memcpy(dest, source, bytesPerPixel); - int bytesCopied = bytesPerPixel; - while (bytesCopied * 2 < destBytes) - { - memcpy(dest + bytesCopied, dest, bytesCopied); - bytesCopied *= 2; - } - memcpy(dest + bytesCopied, dest, destBytes - bytesCopied); - } - } - - // Checks if we can insert an image into a slot - bool CanInsert(AtlasCoordinates slot, ImageDimension image, int padding, int farRight, int farBot) - { - int right = slot.GetLeft() + image.m_width; - if (slot.GetRight() < farRight) - { - // Add padding for my right border - right += padding; - // Round up to the nearest compression unit - right = (right + (cellSize - 1)) / cellSize * cellSize; - // Add padding for an adjacent unit's left border - right += padding; - } - - int bot = slot.GetTop() + image.m_height; - if (slot.GetBottom() < farBot) - { - // Add padding for my right border - bot += padding; - // Round up to the nearest compression unit - bot = (bot + (cellSize - 1)) / cellSize * cellSize; - // Add padding for an adjacent unit's left border - bot += padding; - } - - return slot.GetRight() >= right && slot.GetBottom() >= bot; - } - - // Adds the necessary padding to an Atlas Coordinate - void AddPadding(AtlasCoordinates& slot, int padding, [[maybe_unused]] int farRight, [[maybe_unused]] int farBot) - { - // Add padding for my right border - int right = slot.GetRight() + padding; - // Round up to the nearest compression unit - right = (right + (cellSize - 1)) / cellSize * cellSize; - // Add padding for an adjacent unit's left border - right += padding; - - // Add padding for my right border - int bot = slot.GetBottom() + padding; - // Round up to the nearest compression unit - bot = (bot + (cellSize - 1)) / cellSize * cellSize; - // Add padding for an adjacent unit's left border - bot += padding; - - slot.SetRight(right); - slot.SetBottom(bot); - } - -} diff --git a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.h b/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.h deleted file mode 100644 index f28535998e..0000000000 --- a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.h +++ /dev/null @@ -1,221 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace TextureAtlasBuilder -{ - //! Struct that is used to communicate input commands - struct AtlasBuilderInput - { - AZ_CLASS_ALLOCATOR(AtlasBuilderInput, AZ::SystemAllocator, 0); - AZ_TYPE_INFO(AtlasBuilderInput, "{F54477F9-1BDE-4274-8CC0-8320A3EF4A42}"); - - bool m_forceSquare; - bool m_forcePowerOf2; - // Includes a white default texture for the UI to use under certain circumstances - bool m_includeWhiteTexture; - int m_maxDimension; - // At least this much padding will surround each texture except on the edges of the atlas - int m_padding; - // Color used in wasted space - AZ::Color m_unusedColor; - // A preset to use for the texture atlas image processing - AZStd::string m_presetName; - - AZStd::vector m_filePaths; - AtlasBuilderInput(): - m_forceSquare(false), - m_forcePowerOf2(false), - m_includeWhiteTexture(true), - m_maxDimension(4096), - m_padding(1), - // Default color should be a non-transparent color that isn't used often in uis - m_unusedColor(.235f, .702f, .443f, 1) - { - } - - static void Reflect(AZ::ReflectContext* context); - - //! Attempts to read the input from a .texatlas file. "valid" is for reporting exceptions and telling the asset - //! proccesor to fail the job. Supports parsing through a human readable custom parser. - static AtlasBuilderInput ReadFromFile(const AZStd::string& path, const AZStd::string& directory, bool& valid); - - //! Resolves any wild cards in paths - static void AddFilesUsingWildCard(AZStd::vector& paths, const AZStd::string& insert); - - //! Removes anything that matches the wildcard - static void RemoveFilesUsingWildCard(AZStd::vector& paths, const AZStd::string& remove); - - //! Resolves any folder paths into image file paths - static void AddFolderContents(AZStd::vector& paths, const AZStd::string& insert, bool& valid); - - //! Resolves remove commands for folders - static void RemoveFolderContents(AZStd::vector& paths, const AZStd::string& remove); - }; - - //! Struct that is used to represent an object with a width and height in pixels - struct ImageDimension - { - int m_width; - int m_height; - - ImageDimension(int width, int height) - { - m_width = width; - m_height = height; - } - }; - - //! Typedef for an ImageDimension paired with an integer - using IndexImageDimension = AZStd::pair; - - //! Typedef for a list of ImageDimensions paired with integers - using ImageDimensionData = AZStd::vector; - - //! Typedef to simplify references to TextureAtlas::AtlasCoordinates - using AtlasCoordinates = TextureAtlasNamespace::AtlasCoordinates; - - //! Number of bytes in a pixel - const int bytesPerPixel = 4; - - //! The size of the padded sorting units (important for compression) - const int cellSize = 4; - - //! Indexes of the products - enum class Product - { - TexatlasidxProduct = 0, - DdsProduct = 1 - }; - - //! An asset builder for texture atlases - class AtlasBuilderWorker : public AssetBuilderSDK::AssetBuilderCommandBus::Handler - { - public: - AZ_RTTI(AtlasBuilderWorker, "{79036188-E017-4575-9EC0-8D39CB560EA6}"); - - AtlasBuilderWorker() = default; - ~AtlasBuilderWorker() = default; - - //! Asset Builder Callback Functions - - //! Called by asset processor to gather information on a job for a ".texatlas" file - void CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, - AssetBuilderSDK::CreateJobsResponse& response); - //! Called by asset proccessor when it wants us to execute a job - void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, - AssetBuilderSDK::ProcessJobResponse& response); - - //! Returns the job related information used by the builder - static AssetBuilderSDK::JobDescriptor GetJobDescriptor(const AZStd::string& sourceFile, const AtlasBuilderInput& input); - - ////////////////////////////////////////////////////////////////////////// - //! AssetBuilderSDK::AssetBuilderCommandBus interface - void ShutDown() override; // if you get this you must fail all existing jobs and return. - ////////////////////////////////////////////////////////////////////////// - - private: - bool m_isShuttingDown = false; - - //! This is the main function that takes a set of inputs and attempts to pack them into an atlas of a given - //! size. Returns true if succesful, does not update out on failure. - static bool TryPack(const ImageDimensionData& images, - int targetWidth, - int targetHeight, - int padding, - size_t& amountFit, - AZStd::vector& out); - - //! Removes any overlap between slotList and the given item - static void TrimOverlap(AZStd::vector& slotList, AtlasCoordinates item); - - //! Uses the proper tightening method based on the input and returns the maximum number of items that were able to be fit - bool TryTightening(AtlasBuilderInput input, - const ImageDimensionData& images, - int smallestWidth, - int smallestHeight, - int targetArea, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out); - - //! Finds the tightest square fit achievable by expanding a square area until a valid fit is found - bool TryTighteningSquare(const ImageDimensionData& images, - int lowerBound, - int maxDimension, - int targetArea, - bool powerOfTwo, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out); - - //! Finds the tightest fit achievable by starting with the optimal thin solution and attempting to resize to be - //! a better shape - bool TryTighteningOptimal(const ImageDimensionData& images, - int smallestWidth, - int smallestHeight, - int maxDimension, - int targetArea, - bool powerOfTwo, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out); - - //! Sorting logic for adding a slot to a sorted list in order to maintain increasing order - static void InsertInOrder(AZStd::vector& slotList, AtlasCoordinates item); - - //! Misc Logic For Estimating Target Shape - - //! Returns the width of the widest element - static int GetWidest(const ImageDimensionData& imageList); - - //! Returns the height of the tallest area - static int GetTallest(const ImageDimensionData& imageList); - }; - - //! Used for sorting ImageDimensions - static bool operator<(ImageDimension a, ImageDimension b); - - //! Used to expose the ImageDimension in a pair to AZStd::Sort - static bool operator<(IndexImageDimension a, IndexImageDimension b); - - //! Returns true if two coordinate sets overlap - static bool Collides(AtlasCoordinates a, AtlasCoordinates b); - - //! Returns true if item collides with any object in list - static bool Collides(AtlasCoordinates item, AZStd::vector list); - - //! Returns the portion of the second item that overlaps with the first - static AtlasCoordinates GetOverlap(AtlasCoordinates a, AtlasCoordinates b); - - //! Performs an operation that copies a pixel to the output - static void SetPixels(AZ::u8* dest, const AZ::u8* source, int destBytes); - - //! Checks if we can insert an image into a slot - static bool CanInsert(AtlasCoordinates slot, ImageDimension image, int padding, int farRight, int farBot); - - //! Adds the necessary padding to an Atlas Coordinate - static void AddPadding(AtlasCoordinates& slot, int padding, int farRight, int farBot); -} diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.cpp deleted file mode 100644 index f8b0a1651b..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.cpp +++ /dev/null @@ -1,1114 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" - -#include "BuilderSettingManager.h" -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - namespace ImageProcess##PrivateName\ - {\ - bool DoesSupport(AZStd::string);\ - } -AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - - const char* BuilderSettingManager::s_environmentVariableName = "ImageBuilderSettingManager"; - AZ::EnvironmentVariable BuilderSettingManager::s_globalInstance = nullptr; - AZStd::mutex BuilderSettingManager::s_instanceMutex; - const PlatformName BuilderSettingManager::s_defaultPlatform = AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM; - - AZ::Outcome, AZStd::string> GetPlatformNamesFromRC(AZStd::string& filePath) - { - QFile inputFile(filePath.c_str()); - - if (inputFile.exists() == false) - { - return AZ::Failure(AZStd::string::format("'%s' does not exist", filePath.c_str())); - } - - AZStd::vector all_platforms; - if (inputFile.open(QIODevice::ReadOnly)) - { - QTextStream in(&inputFile); - while (!in.atEnd()) - { - if (in.readLine() == "[_platform]") - { - QString name_line = in.readLine(); - if (name_line.contains("name=")) - { - QString name_value = name_line.split("=")[1]; - // Remove name alias after ',' - AZStd::string az_name_value = name_value.split(",")[0].toUtf8().constData(); - all_platforms.push_back(az_name_value); - } - } - } - inputFile.close(); - } - return AZ::Success(all_platforms); - } - - StringOutcome ParseKeyToData(QString settingKey, const QSettings& rcINI, PresetSettings& presetSettings) - { - // We may be parsing platform-specific settings denoted by a colon and a platform (ex. mintexturesize:ios=35). - // We always extract the actual setting name to determine the setting we are parsing. We must reference the key - // as a whole to properly index into the rcINI file content. - QString key = settingKey.split(":")[0]; - - // There is no standard way to map an enum to string-- - // Also, can't seem to make this static because it allocates something that the destructor doesn't catch. - const AZStd::map colorSpaceMap{ - { "linear" , ColorSpace::linear }, - { "sRGB" , ColorSpace::sRGB }, - { "auto" , ColorSpace::autoSelect } - }; - - const AZStd::map rgbWeightMap{ - { "uniform" , RGBWeight::uniform }, - { "luminance" , RGBWeight::luminance }, - { "ciexyz" , RGBWeight::ciexyz } - }; - - //cm_ftype: gaussian, cone, disc, cosine, cosine_power, ggx - const AZStd::map cubemapFilterTypeMap{ - { "cone" , CubemapFilterType::cone }, - { "gaussian" , CubemapFilterType::gaussian }, - { "ggx" , CubemapFilterType::ggx }, - { "cosine" , CubemapFilterType::cosine }, - { "cosine_power" , CubemapFilterType::cosine_power } - }; - - // To avoid abusing '#define', we use lambda instead. - auto INI_VALUE = [&rcINI, &settingKey]() { return rcINI.value(settingKey); }; - auto INI_VALUE_QSTRING = [&rcINI, &settingKey]() { return rcINI.value(settingKey).toString(); }; - - /************************************************************************/ - /* GENERAL PRESET SETTINGS */ - /************************************************************************/ - if (key == "rgbweights") - { - auto rgbWeightStr = INI_VALUE_QSTRING().toUtf8(); - auto rgbWeightIter = rgbWeightMap.find(rgbWeightStr); - if (rgbWeightIter != rgbWeightMap.end()) - { - presetSettings.m_rgbWeight = rgbWeightIter->second; - } - else - { - return AZ::Failure(AZStd::string("Unmapped rgbweights enum detected.")); - } - } - else if (key == "powof2") - { - presetSettings.m_isPowerOf2 = INI_VALUE().toBool(); - } - else if (key == "discardalpha") - { - presetSettings.m_discardAlpha = INI_VALUE().toBool(); - } - else if (key == "reduce") - { - int reduce = INI_VALUE().toInt(); - if (reduce > 0) - { - presetSettings.m_sizeReduceLevel = reduce; - } - } - else if (key == "ser") - { - presetSettings.m_suppressEngineReduce = INI_VALUE().toBool(); - } - else if (key == "colorchart") - { - presetSettings.m_isColorChart = INI_VALUE().toBool(); - } - else if (key == "highpass") - { - presetSettings.m_highPassMip = INI_VALUE().toInt(); - } - else if (key == "glossfromnormals") - { - presetSettings.m_glossFromNormals = INI_VALUE().toBool(); - } - else if (key == "glosslegacydist") - { - presetSettings.m_isLegacyGloss = INI_VALUE().toBool(); - } - else if (key == "swizzle") - { - presetSettings.m_swizzle = INI_VALUE_QSTRING().toUtf8().constData(); - } - else if (key == "mipnormalize") - { - presetSettings.m_isMipRenormalize = INI_VALUE().toBool(); - } - else if (key == "numstreamablemips") - { - presetSettings.m_numStreamableMips = INI_VALUE().toInt(); - } - else if (key == "colorspace") - { - // By default, RC.ini contains data written in non-standard INI format inherited from CryEngine. - // We need to parse in the value as string list. - // Example: - // - // [MyValues] - // colorspace=src,dst - // - QVariant paramValue = rcINI.value(key, QString()); - if (paramValue.type() != QVariant::StringList) - { - return AZ::Failure(AZStd::string("Expect ColorSpace parameter to be a string list!")); - } - QStringList stringValueList = paramValue.toStringList(); // The order of values for this key is... (SRC, DST) - - if (stringValueList.size() != 2) - { - return AZ::Failure(AZStd::string("Expect ColorSpace parameter list size to be 2!")); - } - - auto srcColorSpaceIter = colorSpaceMap.find(stringValueList[0]); - if (srcColorSpaceIter != colorSpaceMap.end()) - { - presetSettings.m_srcColorSpace = srcColorSpaceIter->second; - } - else - { - return AZ::Failure(AZStd::string("Unmapped ColorSpace enum detected.")); - } - - auto dstColorSpaceIter = colorSpaceMap.find(stringValueList[1]); - if (dstColorSpaceIter != colorSpaceMap.end()) - { - presetSettings.m_destColorSpace = dstColorSpaceIter->second; - } - else - { - return AZ::Failure(AZStd::string("Unmapped ColorSpace enum detected.")); - } - } - else if (key == "filemasks") - { - QVariant iniVariant = rcINI.value(settingKey); - QStringList stringValueList = iniVariant.toStringList(); - for (QString value : stringValueList) - { - //remove stars. For example: "*_ddna*" => "_ddna" - QString suffix = value.mid(1, value.length()-2); - QByteArray suffixByteArray = suffix.toUtf8(); - presetSettings.m_fileMasks.emplace_back(suffixByteArray.constData()); - } - } - else if (key == "pixelformat") - { - auto pixelFormatQBytes = INI_VALUE_QSTRING().toUtf8(); - const char* pixelFormatString = pixelFormatQBytes.constData(); - - EPixelFormat pixelFormatEnum = CPixelFormats::GetInstance().FindPixelFormatByLegacyName(pixelFormatString); - if (pixelFormatEnum == EPixelFormat::ePixelFormat_Unknown) - { - return AZ::Failure(AZStd::string::format("Unsupported ePixelFormat detected: %s", pixelFormatString)); - } - - presetSettings.m_pixelFormat = pixelFormatEnum; - presetSettings.m_pixelFormatName = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormatEnum)->szName; - } - else if (key == "pixelformatalpha") - { - auto pixelFormatQBytes = INI_VALUE_QSTRING().toUtf8(); - const char* pixelFormatString = pixelFormatQBytes.constData(); - - EPixelFormat pixelFormatEnum = CPixelFormats::GetInstance().FindPixelFormatByLegacyName(pixelFormatString); - if (pixelFormatEnum == EPixelFormat::ePixelFormat_Unknown) - { - return AZ::Failure(AZStd::string::format("Unsupported ePixelFormat detected: %s", pixelFormatString)); - } - - presetSettings.m_pixelFormatAlpha = pixelFormatEnum; - presetSettings.m_pixelFormatAlphaName = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormatEnum)->szName; - } - else if (key == "maxtexturesize") - { - bool isOk = false; - auto maxTextureSize = INI_VALUE().toUInt(&isOk); - if (isOk) - { - presetSettings.m_maxTextureSize = maxTextureSize; - } - else - { - return AZ::Failure(AZStd::string::format("Invalid number for key 'maxtexturesize' for [%s]", presetSettings.m_name.c_str())); - } - } - else if (key == "mintexturesize") - { - bool isOk = false; - auto minTextureSize = INI_VALUE().toUInt(&isOk); - if (isOk) - { - presetSettings.m_minTextureSize = minTextureSize; - } - else - { - return AZ::Failure(AZStd::string::format("Invalid number for key 'mintexturesize' for [%s]", presetSettings.m_name.c_str())); - } - } - /************************************************************************/ - /* CUBEMAP PRESET SETTINGS */ - /************************************************************************/ - else if (key == "cm") - { - if (presetSettings.m_cubemapSetting == nullptr && INI_VALUE().toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - } - else - { - return AZ::Failure(AZStd::string("Multiple CubeMap settings detected. Reduce to a single settings entry.")); - } - } - else if (key == "cm_ftype") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - } - } - - if (presetSettings.m_cubemapSetting) - { - auto filterTypeStr = INI_VALUE_QSTRING().toUtf8(); - auto filterTypeIter = cubemapFilterTypeMap.find(filterTypeStr); - if (filterTypeIter != cubemapFilterTypeMap.end()) - { - presetSettings.m_cubemapSetting->m_filter = filterTypeIter->second; - } - else - { - return AZ::Failure(AZStd::string("Unmapped cubemap filter type enum detected.")); - } - } - } - else if (key == "cm_fangle") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_angle = INI_VALUE().toFloat(); - } - } - else - { - presetSettings.m_cubemapSetting->m_angle = INI_VALUE().toFloat(); - } - } - else if (key == "cm_fmipangle") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_mipAngle = INI_VALUE().toFloat(); - } - } - else - { - presetSettings.m_cubemapSetting->m_mipAngle = INI_VALUE().toFloat(); - } - } - else if (key == "cm_fmipslope") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_mipSlope = INI_VALUE().toFloat(); - } - } - else - { - presetSettings.m_cubemapSetting->m_mipSlope = INI_VALUE().toFloat(); - } - } - else if (key == "cm_edgefixup") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_edgeFixup = INI_VALUE().toFloat(); - } - } - else - { - presetSettings.m_cubemapSetting->m_edgeFixup = INI_VALUE().toFloat(); - } - } - else if (key == "cm_diff") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_generateDiff = INI_VALUE().toBool(); - } - } - else - { - presetSettings.m_cubemapSetting->m_generateDiff = INI_VALUE().toBool(); - } - } - else if (key == "cm_diffpreset") - { - QByteArray presetNameByteArray = INI_VALUE().toString().toUtf8(); - AZ::Uuid presetID = BuilderSettingManager::Instance()->GetPresetIdFromName(presetNameByteArray.constData()); - if (presetID.IsNull()) - { - return STRING_OUTCOME_ERROR(AZStd::string::format("Parsing error [cm_diffpreset]. Unable to find UUID for preset: %s", presetNameByteArray.constData())); - } - - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_diffuseGenPreset = presetID; - } - } - else - { - presetSettings.m_cubemapSetting->m_diffuseGenPreset = presetID; - } - } - /************************************************************************/ - /* MIPMAP PRESET SETTINGS */ - /************************************************************************/ - else if (key == "mipmaps") - { - // We convey whether 'mipmaps' is enabled/available by whether the pointer is valid or empty. - if (presetSettings.m_mipmapSetting == nullptr && INI_VALUE().toBool()) - { - presetSettings.m_mipmapSetting = AZStd::make_unique(); - } - } - else if (key == "mipgentype") - { - // We must handle parsing settings of missing/disabled parent settings ("mipmaps") - if (rcINI.value("mipmaps") == QVariant()) - { - return AZ::Failure(AZStd::string("'mipgentype' specified, but dependent 'mipmaps' setting is missing in rc.ini.")); - } - - // If we are missing the mipmap settings (possibly yet to be parsed)... - if (presetSettings.m_mipmapSetting == nullptr) - { - if (rcINI.value("mipmaps").toBool()) - { - presetSettings.m_mipmapSetting = AZStd::make_unique(); - } - else - { - return AZ::Failure(AZStd::string::format( - "Cannot assign 'mipgentype' because current Preset [%s] has 'mipmaps' disabled.", presetSettings.m_name.c_str())); - } - } - - presetSettings.m_mipmapSetting->m_type = MipGenType::blackmanHarris; - if ("average" == INI_VALUE_QSTRING().toUtf8()) - { - presetSettings.m_mipmapSetting->m_type = MipGenType::box; - } - } - else - { - QByteArray keyByteArray = key.toUtf8(); - return STRING_OUTCOME_WARNING(AZStd::string::format("Unsupported key parsed from RC.ini: %s", keyByteArray.constData())); - } - - return STRING_OUTCOME_SUCCESS; - } - - void LoadPresetAliasFromRC(QSettings& rcINI, AZStd::map & presetAliases) - { - rcINI.beginGroup("_presetAliases"); - - for (QString legacyPresetString : rcINI.childKeys()) - { - QString modernPresetString = rcINI.value(legacyPresetString).toString(); - - // We must store this intermediary data in order to convert to a c-string. - QByteArray legacyPresetUtf8 = legacyPresetString.toUtf8(); - QByteArray modernPresetUtf8 = modernPresetString.toUtf8(); - - PresetName legacyPresetName(legacyPresetUtf8.constData()); - PresetName modernPresetName(modernPresetUtf8.constData()); - - presetAliases.insert(AZStd::pair(legacyPresetName, modernPresetName)); - } - - rcINI.endGroup(); - } - - void BuilderSettingManager::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("BuildSettings", &BuilderSettingManager::m_builderSettings) - ->Field("PresetAliases", &BuilderSettingManager::m_presetAliases) - ->Field("DefaultPresetsByFileMask", &BuilderSettingManager::m_defaultPresetByFileMask) - ->Field("DefaultPreset", &BuilderSettingManager::m_defaultPreset) - ->Field("DefaultPresetAlpha", &BuilderSettingManager::m_defaultPresetAlpha) - ->Field("DefaultPresetNonePOT", &BuilderSettingManager::m_defaultPresetNonePOT); - } - } - - BuilderSettingManager* BuilderSettingManager::Instance() - { - AZStd::lock_guard lock(s_instanceMutex); - - if (!s_globalInstance) - { - s_globalInstance = AZ::Environment::FindVariable(s_environmentVariableName); - } - AZ_Assert(s_globalInstance, "BuilderSettingManager not created!"); - - return s_globalInstance.Get(); - } - - void BuilderSettingManager::CreateInstance() - { - AZStd::lock_guard lock(s_instanceMutex); - - if (s_globalInstance) - { - AZ_Assert(false, "BuilderSettingManager already created!"); - return; - } - - if (!s_globalInstance) - { - s_globalInstance = AZ::Environment::CreateVariable(s_environmentVariableName); - } - if (!s_globalInstance.Get()) - { - s_globalInstance.Set(aznew BuilderSettingManager()); - } - } - - void BuilderSettingManager::DestroyInstance() - { - AZStd::lock_guard lock(s_instanceMutex); - AZ_Assert(s_globalInstance, "Invalid call to DestroyInstance - no instance exists."); - AZ_Assert(s_globalInstance.Get(), "You can only call DestroyInstance if you have called CreateInstance."); - - delete s_globalInstance.Get(); - s_globalInstance.Reset(); - } - - const PresetSettings* BuilderSettingManager::GetPreset(const AZ::Uuid presetId, const PlatformName& platform) - { - AZStd::lock_guard lock(m_presetMapLock); - PlatformName platformName = platform; - if (platformName.empty()) - { - platformName = BuilderSettingManager::s_defaultPlatform; - } - - if (m_builderSettings.find(platformName) != m_builderSettings.end()) - { - const BuilderSettings& platformBuilderSetting = m_builderSettings[platformName]; - auto settingsIter = platformBuilderSetting.m_presets.find(presetId); - if (settingsIter != platformBuilderSetting.m_presets.end()) - { - return &settingsIter->second; - } - else - { - AZ_Error("Image Processing", false, "Cannot find preset settings on platform [%s] for preset id: %s", platformName.c_str(), presetId.ToString().c_str()); - } - } - else - { - AZ_Error("Image Processing", false, "Cannot find platform [%s]", platformName.c_str()); - } - - return nullptr; - } - - - const BuilderSettings* BuilderSettingManager::GetBuilderSetting(const PlatformName& platform) - { - if (m_builderSettings.find(platform) != m_builderSettings.end()) - { - return &m_builderSettings[platform]; - } - return nullptr; - } - - const PlatformNameList BuilderSettingManager::GetPlatformList() - { - PlatformNameList platforms; - - for(auto& builderSetting : m_builderSettings) - { - if (builderSetting.second.m_enablePlatform) - { - platforms.push_back(builderSetting.first); - } - } - - return platforms; - } - - const AZStd::map >& BuilderSettingManager::GetPresetFilterMap() - { - AZStd::lock_guard lock(m_presetMapLock); - return m_presetFilterMap; - } - - const AZ::Uuid BuilderSettingManager::GetPresetIdFromName(const PresetName& presetName) - { - AZStd::lock_guard lock(m_presetMapLock); - - // Each preset shares the same UUID across platforms, therefore, it's safe to pick a random - // platform to search for the preset UUID. We'll use PC, in this case. - const PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - if (m_builderSettings.find(defaultPlatform) != m_builderSettings.end()) - { - auto presets = m_builderSettings[defaultPlatform].m_presets; - - for (auto curIter : presets) - { - if (curIter.second.m_name == presetName) - { - return curIter.first; - } - } - } - - return AZ::Uuid::CreateNull(); - } - - const PresetName BuilderSettingManager::GetPresetNameFromId(const AZ::Uuid& presetId) - { - AZStd::lock_guard lock(m_presetMapLock); - const PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - if (m_builderSettings.find(defaultPlatform) != m_builderSettings.end()) - { - auto& presetMap = m_builderSettings[defaultPlatform].m_presets; - auto presetIter = presetMap.find(presetId); - if (presetIter != presetMap.end()) - { - return presetIter->second.m_name; - } - } - - return "Unknown"; - } - - void BuilderSettingManager::ClearSettings() - { - AZStd::lock_guard lock(m_presetMapLock); - m_presetFilterMap.clear(); - m_presetAliases.clear(); - m_builderSettings.clear(); - } - - StringOutcome BuilderSettingManager::LoadBuilderSettings() - { - StringOutcome outcome = STRING_OUTCOME_ERROR(""); - // Construct the project setting path that is used by the tool for loading setting file - const char* gameFolderPath = nullptr; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gameFolderPath, &AzToolsFramework::AssetSystemRequestBus::Events::GetAbsoluteDevGameFolderPath); - AZStd::string projectSettingPath = ""; - - if (gameFolderPath) - { - AzFramework::StringFunc::Path::Join(gameFolderPath, "Config/ImageBuilder/ImageBuilderPresets.settings", projectSettingPath); - outcome = LoadBuilderSettings(projectSettingPath); - } - - if (!outcome.IsSuccess()) - { - AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Failed to read project specific preset setting at [%s], will use default setting file.\n", projectSettingPath.c_str()); - // Construct the default setting path - const char* engineRoot = nullptr; - AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot); - - if (engineRoot) - { - AZStd::string defaultSettingPath = ""; - AzFramework::StringFunc::Path::Join(engineRoot, "Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings", defaultSettingPath); - outcome = LoadBuilderSettings(defaultSettingPath); - } - } - - return outcome; - } - - StringOutcome BuilderSettingManager::LoadBuilderSettings(AZStd::string filepath, AZ::SerializeContext* context) - { - // Ensure filepath exists. - AZ::IO::FileIOBase* fileReader = AZ::IO::FileIOBase::GetInstance(); - if(false == fileReader->Exists(filepath.c_str())) - { - return AZ::Failure(AZStd::string::format("Build settings file not found: %s", filepath.c_str())); - } - - AZ::IO::HandleType settingsFileHandle; - m_builderSettingsFileVersion = 0; - if (fileReader->Open(filepath.c_str(), AZ::IO::OpenMode::ModeRead | AZ::IO::OpenMode::ModeBinary, settingsFileHandle) == AZ::IO::ResultCode::Success) - { - // Read the contents of the file and hash it. The first u32 of the result of this will be used as a version - // number. Any changes to the builder settings file will then cause all textures to be reconverted to pick - // up that change. - AZStd::string settingsFileBuffer; - AZ::u64 settingsFileSize = 0; - fileReader->Size(settingsFileHandle, settingsFileSize); - settingsFileBuffer.resize_no_construct(settingsFileSize); - fileReader->Read(settingsFileHandle, settingsFileBuffer.data(), settingsFileSize); - fileReader->Close(settingsFileHandle); - - AZ::Sha1 block; - AZ::u32 hashDigest[5]; - block.ProcessBytes(settingsFileBuffer.data(), settingsFileSize); - block.GetDigest(hashDigest); - m_builderSettingsFileVersion = hashDigest[0]; - } - - auto loadedSettingsPtr = AZStd::unique_ptr(AZ::Utils::LoadObjectFromFile(filepath, context)); - - // Ensure file is loaded. - if (!loadedSettingsPtr) - { - return AZ::Failure(AZStd::string::format("Failed to read from file: %s", filepath.c_str())); - } - - m_presetMapLock.lock(); - // Normally, we would perform a deep-copy from the loaded settings onto 'this' via assignment operator overload. However, we have deleted our - // assignment operator overloads, because we intend for this class to be a singleton. Instead, we will manually perform a deep-copy - // in this function since it's the only time we require something akin to assignment operation. - m_builderSettings = loadedSettingsPtr->m_builderSettings; - m_presetAliases = loadedSettingsPtr->m_presetAliases; - m_defaultPresetByFileMask = loadedSettingsPtr->m_defaultPresetByFileMask; - m_defaultPreset = loadedSettingsPtr->m_defaultPreset; - m_defaultPresetAlpha = loadedSettingsPtr->m_defaultPresetAlpha; - m_defaultPresetNonePOT = loadedSettingsPtr->m_defaultPresetNonePOT; - - m_presetFilterMap.clear(); - - //enable builder settings for enabled restricted platforms. These settings should be disabled by default in the setting file -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - for (auto& buildSetting : m_builderSettings)\ - {\ - if (ImageProcess##PrivateName::DoesSupport(buildSetting.first))\ - {\ - buildSetting.second.m_enablePlatform = true;\ - break;\ - }\ - } - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - - //convert pixel format string to enum for each preset - for (auto& buildSetting : m_builderSettings) - { - for (auto& preset : buildSetting.second.m_presets) - { - preset.second.m_pixelFormat = CPixelFormats::GetInstance().FindPixelFormatByName(preset.second.m_pixelFormatName.c_str()); - preset.second.m_pixelFormatAlpha = CPixelFormats::GetInstance().FindPixelFormatByName(preset.second.m_pixelFormatAlphaName.c_str()); - } - } - m_presetMapLock.unlock(); - - RegenerateMappings(); - - return AZ::Success(AZStd::string()); - } - - StringOutcome BuilderSettingManager::WriteBuilderSettings(AZStd::string filepath, AZ::SerializeContext* context) - { - if( false == AZ::Utils::SaveObjectToFile(filepath, AZ::DataStream::StreamType::ST_XML, this, context)) - { - return STRING_OUTCOME_ERROR(AZStd::string::format("Failed to write file: %s", filepath.c_str())); - } - return STRING_OUTCOME_SUCCESS; - } - - const PresetName BuilderSettingManager::TranslateLegacyPresetName(const PresetName& legacyName) - { - auto iterResult = m_presetAliases.find(legacyName); - - if (iterResult == m_presetAliases.end()) - { - return legacyName; - } - - return iterResult->second; - } - - StringOutcome BuilderSettingManager::LoadBuilderSettingsFromRC(AZStd::string& filePath) - { - //Clear previous settings first - ClearSettings(); - - // Find all the platforms - auto outcome = GetPlatformNamesFromRC(filePath); - AZ_ENSURE_STRING_OUTCOME(outcome); - PlatformNameVector all_platforms = outcome.TakeValue(); - - m_presetMapLock.lock(); - // Register all the platforms with empty settings. - for (const AZStd::string& platformName : all_platforms) - { - auto newEntry = AZStd::pair(platformName, BuilderSettings()); - m_builderSettings.insert(newEntry); - } - - // Open settings for parsing - QSettings set(filePath.c_str(), QSettings::IniFormat); - - // Load the preset alias mapping - LoadPresetAliasFromRC(set, m_presetAliases); - - QStringList childGroups = set.childGroups(); - QStringList exemptGroups; - exemptGroups.append("_platform"); - exemptGroups.append("_presetAliases"); - - // We must generate new preset settings and UUID's prior to parsing the rest of the data, because - // some preset settings make references to other presets within RC.ini. We must make sure all presets - // are identified, before making references to them via their UUID. - for (QString groupName : childGroups) - { - auto newPresetUuid = AZ::Uuid::CreateRandom(); - PresetSettings newPresetSetting; - newPresetSetting.m_name = groupName.toUtf8().constData(); - newPresetSetting.m_uuid = newPresetUuid; - for (const PlatformName& platform : all_platforms) - { - m_builderSettings[platform].m_presets.insert(AZStd::make_pair(newPresetUuid, newPresetSetting)); - } - } - m_presetMapLock.unlock(); - - // Apply preset settings from file to the existing presets (process each platform). - for(QString groupName : childGroups) - { - // Only process Presets from here on out. - if (exemptGroups.contains(groupName)) - { - continue; - } - - auto outcome2 = ProcessPreset(groupName, set, all_platforms); - AZ_ENSURE_STRING_OUTCOME(outcome2); - } - - RegenerateMappings(); - - // The original rc.ini doesn't have the information below. Included here for GetSuggestedPreset() to work properly. - m_defaultPresetByFileMask["_diff"] = GetPresetIdFromName("Albedo"); - m_defaultPresetByFileMask["_spec"] = GetPresetIdFromName("Reflectance"); - m_defaultPresetByFileMask["_refl"] = GetPresetIdFromName("Reflectance"); - m_defaultPresetByFileMask["_ddn"] = GetPresetIdFromName("Normals"); - m_defaultPresetByFileMask["_ddna"] = GetPresetIdFromName("NormalsWithSmoothness"); - m_defaultPresetByFileMask["_cch"] = GetPresetIdFromName("ColorChart"); - m_defaultPresetByFileMask["_cm"] = GetPresetIdFromName("EnvironmentProbeHDR"); - - m_defaultPreset = GetPresetIdFromName("Albedo"); - m_defaultPresetAlpha = GetPresetIdFromName("AlbedoWithGenericAlpha"); - m_defaultPresetNonePOT = GetPresetIdFromName("ReferenceImage"); - - return STRING_OUTCOME_SUCCESS; - } - - AZ::u32 BuilderSettingManager::BuilderSettingsVersion() const - { - return m_builderSettingsFileVersion; - } - - void BuilderSettingManager::RegenerateMappings() - { - AZStd::lock_guard lock(m_presetMapLock); - - AZStd::string noFilter = AZStd::string(); - - m_presetFilterMap.clear(); - - for (auto& builderSettingIter : m_builderSettings) - { - const BuilderSettings& builderSetting = builderSettingIter.second; - for (auto& presetIter : builderSetting.m_presets) - { - //Put into no filter preset list - m_presetFilterMap[noFilter].insert(presetIter.second.m_name); - - //Put into file mask preset list if any - for (const PlatformName& filemask : presetIter.second.m_fileMasks) - { - m_presetFilterMap[filemask].insert(presetIter.second.m_name); - } - } - } - } - - StringOutcome BuilderSettingManager::ProcessPreset(QString& preset, QSettings& rcINI, PlatformNameVector& all_platforms) - { - // Early-out check. We should have the preset available before processing. - QByteArray presetByteArray = preset.toUtf8(); - AZ::Uuid parsingPresetUuid = GetPresetIdFromName(presetByteArray.constData()); - if (parsingPresetUuid.IsNull()) - { - return STRING_OUTCOME_ERROR(AZStd::string::format("Unable to find UUID for preset: %s", presetByteArray.constData())); - } - - rcINI.beginGroup(preset); - QStringList groupKeys = rcINI.allKeys(); - - // Build a list for common & platform-specific settings - QStringList commonPresetSettingKeys; - QStringList platformSpecificPresetSettingKeys; - for (QString key : groupKeys) - { - if (key.contains(":")) - { - platformSpecificPresetSettingKeys.append(key); - } - else - { - commonPresetSettingKeys.append(key); - } - } - - // Parse the common settings (retain preset name & uuid) - PresetSettings commonPresetSettings; - commonPresetSettings.m_name = presetByteArray.constData(); - commonPresetSettings.m_uuid = parsingPresetUuid; - for (QString settingKey : commonPresetSettingKeys) - { - AZ_ENSURE_STRING_OUTCOME(ParseKeyToData(settingKey, rcINI, commonPresetSettings)); - } - - // When loading a preset, the UUID is the same per-preset, regardless of the target-platform. - for (AZStd::string& platformId : all_platforms) - { - // Begin platform-specific settings loading with a copy of common Preset settings. - PresetSettings currentPlatformPresetSetting = commonPresetSettings; - - // Obtain platform-specific settings - QString platformFilter = QString(":%1").arg(platformId.c_str()); // Example results-> ":ios", ":osx", ":es3" - QStringList currentPlatformSettings = platformSpecificPresetSettingKeys.filter(platformFilter); - - // Overwrite values for platform-specific settings... - for (QString platformSetting : currentPlatformSettings) - { - AZ_ENSURE_STRING_OUTCOME(ParseKeyToData(platformSetting, rcINI, currentPlatformPresetSetting)); - } - - // Assign the overridden platform preset settings to the BuilderSettingManager. - m_builderSettings[platformId].m_presets[parsingPresetUuid] = currentPlatformPresetSetting; - } - - rcINI.endGroup(); - return STRING_OUTCOME_SUCCESS; - } - - void BuilderSettingManager::MetafilePathFromImagePath(const AZStd::string& imagePath, AZStd::string& metafilePath) - { - // Determine if we have a meta file (legacy or modern). - AZ::IO::LocalFileIO fileIO; - - AZStd::string modernMetaFilepath = imagePath + TextureSettings::modernExtensionName; - if (fileIO.Exists(modernMetaFilepath.c_str())) - { - metafilePath = modernMetaFilepath; - return; - } - - AZStd::string legacyMetaFilepath = imagePath + TextureSettings::legacyExtensionName; - if (fileIO.Exists(legacyMetaFilepath.c_str())) - { - metafilePath = legacyMetaFilepath; - return; - } - - // We found neither. - metafilePath = AZStd::string(); - } - - AZStd::string GetFileMask(const AZStd::string& imageFilePath) - { - //get file name - AZStd::string fileName; - QString lowerFileName = imageFilePath.c_str(); - lowerFileName = lowerFileName.toLower(); - AzFramework::StringFunc::Path::GetFileName(lowerFileName.toUtf8().constData(), fileName); - - //get the substring from last '_' - size_t lastUnderScore = fileName.find_last_of('_'); - if (lastUnderScore != AZStd::string::npos) - { - return fileName.substr(lastUnderScore); - } - - return AZStd::string(); - } - - AZ::Uuid BuilderSettingManager::GetSuggestedPreset(const AZStd::string& imageFilePath, IImageObjectPtr imageFromFile) - { - //load the image to get its size for later use - IImageObjectPtr image = imageFromFile; - //if the input image is empty we will try to load it from the path - if (imageFromFile == nullptr) - { - image = IImageObjectPtr(LoadImageFromFile(imageFilePath)); - } - - if (image == nullptr) - { - AZ_Error("Image Processing", image, "Cannot load image file [%s]. Invalid image format or corrupt data. Note that \"Indexed Color\" is not currently supported for .tga files.", imageFilePath.c_str()); - return AZ::Uuid::CreateNull(); - } - - //get file mask of this image file - AZStd::string fileMask = GetFileMask(imageFilePath); - - AZ::Uuid outPreset = AZ::Uuid::CreateNull(); - - if ("_diff" == fileMask && image->GetAlphaContent() != EAlphaContent::eAlphaContent_Absent) - { - outPreset = m_defaultPresetAlpha; - } - else - { - //check default presets for some file masks - if (m_defaultPresetByFileMask.find(fileMask) != m_defaultPresetByFileMask.end()) - { - outPreset = m_defaultPresetByFileMask[fileMask]; - } - } - - //use the preset filter map to find - if (outPreset.IsNull() && !fileMask.empty()) - { - auto& presetFilterMap = GetPresetFilterMap(); - if (presetFilterMap.find(fileMask) != presetFilterMap.end()) - { - AZStd::string presetName = *(presetFilterMap.find(fileMask)->second.begin()); - outPreset = GetPresetIdFromName(presetName); - } - } - - const PresetSettings* presetInfo = nullptr; - - if (!outPreset.IsNull()) - { - presetInfo = GetPreset(outPreset); - - //special case for cubemap - if (presetInfo && presetInfo->m_cubemapSetting) - { - if (CubemapLayout::GetCubemapLayoutInfo(image) == nullptr) - { - outPreset = AZ::Uuid::CreateNull(); - } - } - } - - if (outPreset.IsNull()) - { - if (!image->HasPowerOfTwoSizes()) - { - // The resource compiler used the non power of 2 preset if the width or the height is not power of 2 - // even if it would have been possible to compress the image, so this behavior is matched here. - return m_defaultPresetNonePOT; - } - else if (image->GetAlphaContent() == EAlphaContent::eAlphaContent_Absent) - { - outPreset = m_defaultPreset; - } - else - { - outPreset = m_defaultPresetAlpha; - } - } - - //get the pixel format for selected preset - presetInfo = GetPreset(outPreset); - - if (presetInfo) - { - //valid whether image size work with pixel format - if (CPixelFormats::GetInstance().IsImageSizeValid(presetInfo->m_pixelFormat, - image->GetWidth(0), image->GetHeight(0), false)) - { - return outPreset; - } - } - - //uncompressed one which could be used for almost everything - return m_defaultPresetNonePOT; - } - - bool BuilderSettingManager::DoesSupportPlatform(const AZStd::string& platformId) - { - bool rv = m_builderSettings.find(platformId) != m_builderSettings.end(); - return rv; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.h deleted file mode 100644 index c6d03eae54..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.h +++ /dev/null @@ -1,192 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -class QSettings; -class QString; - -namespace AZ -{ - template class EnvironmentVariable; - class SerializeContext; -} - -namespace ImageProcessing -{ - class BuilderSettingManager - { - public: - AZ_TYPE_INFO(CBuilderSettingManager, "{DAA55241-64FA-4A9B-A37F-C0A36B36D536}"); - AZ_CLASS_ALLOCATOR(BuilderSettingManager, AZ::SystemAllocator, 0); - //load builder settings for all platform - //contain builder setting for all platforms - //this manager should be able to get texture setting for a platform - - - static BuilderSettingManager* Instance(); - // life cycle management: - static void CreateInstance(); - static void DestroyInstance(); - static void Reflect(AZ::ReflectContext* context); - - const PresetSettings* GetPreset(const AZ::Uuid presetId, const PlatformName& platform = ""); - - const BuilderSettings* GetBuilderSetting(const PlatformName& platform); - - /** - * Attempts to translate a legacy preset name into Open 3D Engine preset name. - * @param legacy preset name string - * @return A translated preset name. If no translation is available, returns the same value as input argument. - */ - const PresetName TranslateLegacyPresetName(const PresetName& legacyName); - - /** - * @return A list of platform supported - */ - const PlatformNameList GetPlatformList(); - - /** - * @return A map of preset settings based on their filemasks. - * @key filemask string, empty string means no filemask - * @value set of preset setting names supporting the specified filemask - */ - const AZStd::map>& GetPresetFilterMap(); - - /** - * Find preset id list based on the preset name. - * @param preset name string - * @return a map of preset ids whose name are specified by the input on different platforms - * @key platform name string - * @value uuid of the preset setting - */ - const AZ::Uuid GetPresetIdFromName(const PresetName& presetName); - - /** - * Find preset name based on the preset id. - * @param uuid of the preset setting - * @return preset name string - */ - const PresetName GetPresetNameFromId(const AZ::Uuid& presetId); - - /** - * Writes preset data to file using AZ::Serialization format. - * @param filepath string to the build settings xml - */ - StringOutcome WriteBuilderSettings(AZStd::string filepath, AZ::SerializeContext* context = nullptr); - - /** - * Loads preset data from file using AZ::Serialization format. - * @param filepath string to the build settings xml - */ - StringOutcome LoadBuilderSettings(AZStd::string filepath, AZ::SerializeContext* context = nullptr); - - /** - * Overload function. Loads preset data from project setting file if any - * Otherwise, the function will load default setting file inside the gem - */ - StringOutcome LoadBuilderSettings(); - - /** - * Loads preset data from legacy format found in RC.ini. - * @param filepath string to RC.ini - */ - StringOutcome LoadBuilderSettingsFromRC(AZStd::string& filePath); - - /** - * Returns the first u32 generated from a hash of the builder settings - * file that can be used as a version to detect changes to the file. - */ - AZ::u32 BuilderSettingsVersion() const; - - /** - * Provides a full path to the adjacent metafile of a given texture/image file. - * @param Filepath string to the texture/image file. - * @param Output filepath string to the adjacent texture/image metafile. - * Will output whichever metafile is present, whether it is legacy or modern format. - * If both are present, modern format is returned. - * If none are present, an empty string is returned. - */ - void MetafilePathFromImagePath(const AZStd::string& imagePath, AZStd::string& metafilePath); - - /** - * Find a suitable preset a given image file. - * @param imageFilePath: Filepath string of the image file. The function may load the image from the path for better detection - * @param image: an optional image object which can be used for preset selection if there is no match based file mask. - * @return suggested preset uuid. - */ - AZ::Uuid GetSuggestedPreset(const AZStd::string& imageFilePath, IImageObjectPtr image = nullptr); - - bool DoesSupportPlatform(const AZStd::string& platformId); - - static const char* s_environmentVariableName; - static AZ::EnvironmentVariable s_globalInstance; - static AZStd::mutex s_instanceMutex; - static const PlatformName s_defaultPlatform; - - BuilderSettingManager(){} - - private: // functions - AZ_DISABLE_COPY_MOVE(BuilderSettingManager); - - StringOutcome ProcessPreset(QString& preset, QSettings& rcINI, PlatformNameVector& all_platforms); - - /** - * Clear Builder Settings and any cached maps/lists - */ - void ClearSettings(); - - /** - * Regenerate Builder Settings and any cached maps/lists - */ - void RegenerateMappings(); - - private: // variables - - //builder settings for each platform - AZStd::map m_builderSettings; - AZStd::map m_presetAliases; - - /** - * Cached list of presets mapped by their file masks. - * @Key file mask, use empty string to indicate all presets without filtering - * @Value set of preset names that matches the file mask - */ - AZStd::map > m_presetFilterMap; - - /** - * A mutex to protect when modifying any map in this manager - */ - AZStd::mutex m_presetMapLock; - - //default presets for certian file masks - AZStd::map m_defaultPresetByFileMask; - - //default preset for none power of two image - AZ::Uuid m_defaultPresetNonePOT; - - //default preset for power of two - AZ::Uuid m_defaultPreset; - - //default preset for power of two with alpha - AZ::Uuid m_defaultPresetAlpha; - - //generated from hashing the builder settings file - AZ::u32 m_builderSettingsFileVersion; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.cpp deleted file mode 100644 index 6f68ea7581..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "ImageProcessing_precompiled.h" -#include -#include - -namespace ImageProcessing -{ - void BuilderSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("GlossScale", &BuilderSettings::m_brdfGlossScale) - ->Field("GlossBias", &BuilderSettings::m_brdfGlossBias) - ->Field("Streaming", &BuilderSettings::m_enableStreaming) - ->Field("Enable", &BuilderSettings::m_enablePlatform) - ->Field("Presets", &BuilderSettings::m_presets); - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.h deleted file mode 100644 index 500b69f472..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - //builder setting for a platform - struct BuilderSettings - { - AZ_TYPE_INFO(BuilderSettings, "{4085AB56-934C-43A6-AF25-4443E1EEB71D}"); - AZ_CLASS_ALLOCATOR(BuilderSettings, AZ::SystemAllocator, 0); - static void Reflect(AZ::ReflectContext* context); - - //global settings - float m_brdfGlossScale = 16.0f; - float m_brdfGlossBias = 0.0f; - bool m_enableStreaming = true; - bool m_enablePlatform = true; - AZStd::map m_presets; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.cpp deleted file mode 100644 index 43f2a50535..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include - -namespace ImageProcessing -{ - - bool CubemapSettings::operator!=(const CubemapSettings& other) - { - return !(*this == other); - } - - bool CubemapSettings::operator==(const CubemapSettings& other) - { - return - m_angle == other.m_angle && - m_mipAngle == other.m_mipAngle && - m_mipSlope == other.m_mipSlope && - m_edgeFixup == other.m_edgeFixup && - m_generateDiff == other.m_generateDiff && - m_diffuseGenPreset == other.m_diffuseGenPreset; - } - - void CubemapSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("Filter", &CubemapSettings::m_filter) - ->Field("Angle", &CubemapSettings::m_angle) - ->Field("MipAngle", &CubemapSettings::m_mipAngle) - ->Field("MipSlope", &CubemapSettings::m_mipSlope) - ->Field("EdgeFixup", &CubemapSettings::m_edgeFixup) - ->Field("GenerateDiff", &CubemapSettings::m_generateDiff) - ->Field("DiffuseProbePreset", &CubemapSettings::m_diffuseGenPreset); - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.h deleted file mode 100644 index edfdde8cbe..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include - -namespace ImageProcessing -{ - //! settings related to cubemap. Part of texture preset setting. only useful when cubemap enabled - struct CubemapSettings - { - AZ_TYPE_INFO(CubemapSettings, "{C6BDEB7B-8E05-4B2D-8F39-8F6275BC84E8}"); - AZ_CLASS_ALLOCATOR(CubemapSettings, AZ::SystemAllocator, 0); - bool operator!=(const CubemapSettings& other); - bool operator==(const CubemapSettings& other); - static void Reflect(AZ::ReflectContext* context); - - // "cm_ftype", cubemap angular filter type: gaussian, cone, disc, cosine, cosine_power, ggx - CubemapFilterType m_filter; - - // "cm_fangle", base filter angle for cubemap filtering(degrees), 0 - disabled - float m_angle; - - // "cm_fmipangle", initial mip filter angle for cubemap filtering(degrees), 0 - disabled - float m_mipAngle; - - // "cm_fmipslope", mip filter angle multiplier for cubemap filtering, 1 - default" - float m_mipSlope; - - // "cm_edgefixup", cubemap edge fix-up width, 0 - disabled - float m_edgeFixup; - - // "cm_diff", generate a diffuse illumination light-probe in addition - bool m_generateDiff; - - // "cm_diffpreset", the name of the preset to be used for the diffuse probe - AZ::Uuid m_diffuseGenPreset; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/ImageProcessingDefines.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/ImageProcessingDefines.h deleted file mode 100644 index c9fa860240..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/ImageProcessingDefines.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include - -/** -* Shorthand for checking a condition, and failing if false. -* Works with any function that returns AZ::Outcome<..., AZStd::string>. -* Unlike assert, it is not removed in release builds. -* Ensure all strings are passed with c_str(), as they are passed to AZStd::string::format(). -*/ -#define AZ_ENSURE_STRING_OUTCOME_CONDITION(cond, ...) if (!(cond)) { return AZ::Failure(AZStd::string::format(__VA_ARGS__)); } - -// Similar to above macro, but ensures on an AZ::Outcome. Not removed in release builds. -#define AZ_ENSURE_STRING_OUTCOME(outcome) if (!(outcome.IsSuccess())) { return AZ::Failure(outcome.GetError()); } - -namespace ImageProcessing -{ - //! Common return type for operations that can fail. - // Empty success string == Success. - // Populated success string == Warning. - // Populated error string == Failure. - using StringOutcome = AZ::Outcome; -#define STRING_OUTCOME_SUCCESS AZ::Success(AZStd::string()) -#define STRING_OUTCOME_WARNING(warning) AZ::Success(AZStd::string(warning)) -#define STRING_OUTCOME_ERROR(error) AZ::Failure(AZStd::string(error)) - - // Common typedefs (with dependent forward-declarations) - typedef AZStd::string PlatformName, PresetName, FileMask; - typedef AZStd::vector PlatformNameVector; - typedef AZStd::list PlatformNameList; - - //! min and max reduce level - static const unsigned int s_MinReduceLevel = 0; - static const unsigned int s_MaxReduceLevel = 5; - - static const int s_TotalSupportedImageExtensions = 8; - static const char* s_SupportedImageExtensions[s_TotalSupportedImageExtensions] = { - "*.tif", - "*.tiff", - "*.png", - "*.bmp", - "*.jpg", - "*.jpeg", - "*.tga", - "*.gif" - }; - - enum class RGBWeight : AZ::u32 - { - uniform, // uniform weights (1.0, 1.0, 1.0) (default) - luminance, // luminance-based weights (0.3086, 0.6094, 0.0820) - ciexyz // ciexyz-based weights (0.2126, 0.7152, 0.0722) - }; - - enum class ColorSpace : AZ::u32 - { - linear, - sRGB, - autoSelect, - }; - - enum class MipGenType : AZ::u32 - { - point, //Also called nearest neighbor - box, //Also called 'average'. When shrinking images it will average, and merge the pixels together. - triangle, //Also called linear or Bartlett window - quadratic, //Also called bilinear or Welch window - gaussian, //It remove high frequency noise in a highly controllable way. - blackmanHarris, - kaiserSinc //Good for foliage and tree assets exported from Speedtree. - }; - - enum class MipGenEvalType : AZ::u32 - { - sum, - max, - min - }; - - //cubemap angular filter type. Only two filter types were used in rc.ini - enum class CubemapFilterType : AZ::u32 - { - disc = 0, // same as CP_FILTER_TYPE_DISC in CubemapGen - cone = 1, // same as CP_FILTER_TYPE_CONE - cosine = 2, // same as CP_FILTER_TYPE_COSINE. only used for [EnvironmentProbeHDR_Irradiance] - gaussian = 3, // same as CP_FILTER_TYPE_ANGULAR_GAUSSIAN - cosine_power = 4, // same as CP_FILTER_TYPE_COSINE_POWER - ggx = 5 // same as CP_FILTER_TYPE_GGX. only used for [EnvironmentProbeHDR] - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.cpp deleted file mode 100644 index 0285404f50..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include -#include - -namespace ImageProcessing -{ - bool MipmapSettings::operator!=(const MipmapSettings& other) const - { - return !(*this == other); - } - - bool MipmapSettings::operator==(const MipmapSettings& other) const - { - return - m_type == other.m_type && - m_borderColor == other.m_borderColor && - m_normalize == other.m_normalize && - m_streamableMips == other.m_streamableMips; - } - - void MipmapSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("MipGenType", &MipmapSettings::m_type) - ->Field("BorderColor", &MipmapSettings::m_borderColor) - ->Field("Normalize", &MipmapSettings::m_normalize) - ->Field("StreamableMips", &MipmapSettings::m_streamableMips); - - AZ::EditContext* editContext = serialize->GetEditContext(); - if (editContext) - { - editContext->Class("Mipmap Setting", "") - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &MipmapSettings::m_type, "Type", "") - ->EnumAttribute(MipGenType::point, "Point") - ->EnumAttribute(MipGenType::box, "Average") - ->EnumAttribute(MipGenType::triangle, "Linear") - ->EnumAttribute(MipGenType::quadratic, "Bilinear") - ->EnumAttribute(MipGenType::gaussian, "Gaussian") - ->EnumAttribute(MipGenType::blackmanHarris, "BlackmanHarris") - ->EnumAttribute(MipGenType::kaiserSinc, "KaiserSinc") - ->DataElement(AZ::Edit::UIHandlers::Color, &MipmapSettings::m_borderColor, "Color", "") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &MipmapSettings::m_normalize, "Normalized", "") - ->DataElement(AZ::Edit::UIHandlers::SpinBox, &MipmapSettings::m_streamableMips, "Streamable Mips", "") - ->Attribute(AZ::Edit::Attributes::Min, 0) - ; - } - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.h deleted file mode 100644 index 4a2864d2b7..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - struct MipmapSettings - { - AZ_TYPE_INFO(MipmapSettings, "{9239618E-23A6-43C8-9B87-50528CBFA6FF}"); - AZ_CLASS_ALLOCATOR(MipmapSettings, AZ::SystemAllocator, 0); - bool operator!=(const MipmapSettings& other) const; - bool operator==(const MipmapSettings& other) const; - - static void Reflect(AZ::ReflectContext* context); - - MipGenType m_type = MipGenType::blackmanHarris; - - //Unused or duplicated properties. We may want to move same properties from perset setting to here. - AZ::Color m_borderColor; - bool m_normalize; - AZ::u32 m_streamableMips; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/PlatformSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/PlatformSettings.h deleted file mode 100644 index 5cfc7757b2..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/PlatformSettings.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include - -namespace ImageProcessing -{ - //! default settings for platform - struct PlatformSetting - { - AZ_TYPE_INFO(PlatformSetting, "{19EF828B-DDFF-4591-AD5A-946801FCC98E}"); - AZ_CLASS_ALLOCATOR(PlatformSetting, AZ::SystemAllocator, 0); - - //! Platform's name - PlatformName m_name; - - //! pixel formats supported for the platform - AZStd::list m_availableFormat; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.cpp deleted file mode 100644 index 8f904058d3..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include - -namespace ImageProcessing -{ - PresetSettings::PresetSettings() - : m_uuid(0) - , m_rgbWeight(RGBWeight::uniform) - , m_srcColorSpace(ColorSpace::sRGB) - , m_destColorSpace(ColorSpace::autoSelect) - , m_suppressEngineReduce(false) - , m_pixelFormat(ePixelFormat_R8G8B8A8) - , m_pixelFormatName("R8G8B8A8") - , m_pixelFormatAlpha(ePixelFormat_Unknown) - , m_pixelFormatAlphaName("") - , m_discardAlpha(false) - , m_maxTextureSize(0) - , m_minTextureSize(0) - , m_isPowerOf2(false) - , m_sizeReduceLevel(0) - , m_isColorChart(0) - , m_highPassMip(0) - , m_glossFromNormals(false) - , m_isMipRenormalize(false) - , m_numStreamableMips(100) - , m_isLegacyGloss(false) - { - - } - - PresetSettings::PresetSettings(const PresetSettings& other) - { - DeepCopyMembers(other); - } - - void PresetSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("UUID", &PresetSettings::m_uuid) - ->Field("Name", &PresetSettings::m_name) - ->Field("Description", &PresetSettings::m_description) - ->Field("RGB_Weight", &PresetSettings::m_rgbWeight) - ->Field("SourceColor", &PresetSettings::m_srcColorSpace) - ->Field("DestColor", &PresetSettings::m_destColorSpace) - ->Field("FileMasks", &PresetSettings::m_fileMasks) - ->Field("SuppressEngineReduce", &PresetSettings::m_suppressEngineReduce) - ->Field("PixelFormat", &PresetSettings::m_pixelFormatName) - ->Field("PixelFormatAlpha", &PresetSettings::m_pixelFormatAlphaName) - ->Field("DiscardAlpha", &PresetSettings::m_discardAlpha) - ->Field("MaxTextureSize", &PresetSettings::m_maxTextureSize) - ->Field("MinTextureSize", &PresetSettings::m_minTextureSize) - ->Field("IsPowerOf2", &PresetSettings::m_isPowerOf2) - ->Field("SizeReduceLevel", &PresetSettings::m_sizeReduceLevel) - ->Field("IsColorChart", &PresetSettings::m_isColorChart) - ->Field("HighPassMip", &PresetSettings::m_highPassMip) - ->Field("GlossFromNormal", &PresetSettings::m_glossFromNormals) - ->Field("UseLegacyGloss", &PresetSettings::m_isLegacyGloss) - ->Field("MipRenormalize", &PresetSettings::m_isMipRenormalize) - ->Field("NumberStreamableMips", &PresetSettings::m_numStreamableMips) - ->Field("Swizzle", &PresetSettings::m_swizzle) - ->Field("CubemapSettings", &PresetSettings::m_cubemapSetting) - ->Field("MipMapSetting", &PresetSettings::m_mipmapSetting); - } - } - - PresetSettings& PresetSettings::operator= (const PresetSettings& other) - { - DeepCopyMembers(other); - return *this; - } - - bool PresetSettings::operator==(const PresetSettings& other) const - { - bool arePointersEqual = true; - - /////// - // MipMap Settings - ////// - // If both pointers are allocated... - if (m_mipmapSetting && other.m_mipmapSetting) - { - // If the allocated values are different... - if (*m_mipmapSetting != *other.m_mipmapSetting) - { - arePointersEqual = false; - } - } - // Otherwise, one or both pointers are un-allocated. - // If only one pointer is allocated (via unequivalency)... - else if (m_mipmapSetting != other.m_mipmapSetting) - { - arePointersEqual = false; - } - /////// - // CubeMap Settings - ////// - // If both pointers are allocated... - if (m_cubemapSetting && other.m_cubemapSetting) - { - // If the allocated values are different... - if (*m_cubemapSetting != *other.m_cubemapSetting) - { - arePointersEqual = false; - } - } - // Otherwise, one or both pointers are un-allocated. - // If only one pointer is allocated (via unequivalency)... - else if (m_cubemapSetting != other.m_cubemapSetting) - { - arePointersEqual = false; - } - return - arePointersEqual && - m_uuid == other.m_uuid && - m_name == other.m_name && - m_description == other.m_description && - m_rgbWeight == other.m_rgbWeight && - m_srcColorSpace == other.m_srcColorSpace && - m_destColorSpace == other.m_destColorSpace && - m_fileMasks == other.m_fileMasks && - m_suppressEngineReduce == other.m_suppressEngineReduce && - m_pixelFormat == other.m_pixelFormat && - m_pixelFormatName == other.m_pixelFormatName && - m_pixelFormatAlpha == other.m_pixelFormatAlpha && - m_pixelFormatAlphaName == other.m_pixelFormatAlphaName && - m_discardAlpha == other.m_discardAlpha && - m_minTextureSize == other.m_minTextureSize && - m_maxTextureSize == other.m_maxTextureSize && - m_isPowerOf2 == other.m_isPowerOf2 && - m_sizeReduceLevel == other.m_sizeReduceLevel && - m_isColorChart == other.m_isColorChart && - m_highPassMip == other.m_highPassMip && - m_glossFromNormals == other.m_glossFromNormals && - m_isLegacyGloss == other.m_isLegacyGloss && - m_swizzle == other.m_swizzle && - m_isMipRenormalize == other.m_isMipRenormalize && - m_numStreamableMips == other.m_numStreamableMips; - } - - void PresetSettings::DeepCopyMembers(const PresetSettings & other) - { - if (this != &other) - { - if(other.m_mipmapSetting) - { - m_mipmapSetting = AZStd::make_unique(*other.m_mipmapSetting); - } - - if(other.m_cubemapSetting) - { - m_cubemapSetting = AZStd::make_unique(*other.m_cubemapSetting); - } - - m_uuid = other.m_uuid; - m_name = other.m_name; - m_description = other.m_description; - m_rgbWeight = other.m_rgbWeight; - m_srcColorSpace = other.m_srcColorSpace; - m_destColorSpace = other.m_destColorSpace; - m_fileMasks = other.m_fileMasks; - m_suppressEngineReduce = other.m_suppressEngineReduce; - m_pixelFormat = other.m_pixelFormat; - m_pixelFormatAlpha = other.m_pixelFormatAlpha; - m_pixelFormatName = other.m_pixelFormatName; - m_pixelFormatAlphaName = other.m_pixelFormatAlphaName; - m_discardAlpha = other.m_discardAlpha; - m_minTextureSize = other.m_minTextureSize; - m_maxTextureSize = other.m_maxTextureSize; - m_isPowerOf2 = other.m_isPowerOf2; - m_sizeReduceLevel = other.m_sizeReduceLevel; - m_isColorChart = other.m_isColorChart; - m_highPassMip = other.m_highPassMip; - m_glossFromNormals = other.m_glossFromNormals; - m_isLegacyGloss = other.m_isLegacyGloss; - m_swizzle = other.m_swizzle; - m_isMipRenormalize = other.m_isMipRenormalize; - m_numStreamableMips = other.m_numStreamableMips; - } - } - - AZ::Vector3 PresetSettings::GetColorWeight() - { - switch (m_rgbWeight) - { - case RGBWeight::uniform: - return AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - case RGBWeight::ciexyz: - return AZ::Vector3(0.2126f, 0.7152f, 0.0722f); - case RGBWeight::luminance: - return AZ::Vector3(0.3086f, 0.6094f, 0.0820f); - default: - AZ_Assert(false, "color weight value need to be added to new rgbWeight enum"); - return AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.h deleted file mode 100644 index fa881e853b..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - //settings for texture process preset - class PresetSettings - { - public: - AZ_TYPE_INFO(PresetSettings, "{935BCE3F-9E76-494E-9408-47C5937D7288}"); - AZ_CLASS_ALLOCATOR(PresetSettings, AZ::SystemAllocator, 0); - - PresetSettings(); - PresetSettings(const PresetSettings& other); - PresetSettings& operator= (const PresetSettings& other); - bool operator== (const PresetSettings& other) const; - static void Reflect(AZ::ReflectContext* context); - - //unique id for the preset - AZ::Uuid m_uuid; - - PresetName m_name; - - //a brief description for the usage of this Preset - AZStd::string m_description; - - //misc options - // "rgbweights". specify preset for weighting of R,G,B channels (used by compressor) - RGBWeight m_rgbWeight; - ColorSpace m_srcColorSpace; - ColorSpace m_destColorSpace; - - // file masks used for helping select default preset and option preset list in texture property dialog - AZStd::vector m_fileMasks; - - // "ser". Whether to enable supress reduce resolution (m_sizeReduceLevel) during loading, 0(default) - bool m_suppressEngineReduce; - - //pixel format - EPixelFormat m_pixelFormat; - AZStd::string m_pixelFormatName; - //pixel format for image which only contains alpha channel. this is for if we need to save alpha channel into a seperate image - EPixelFormat m_pixelFormatAlpha; - AZStd::string m_pixelFormatAlphaName; - bool m_discardAlpha; - - // Resolution related settings - - // "maxtexturesize", upper limit of the resolution of generated textures. It should be a power-of-2 number larger than 1 - // resulting texture will be downscaled if its width or height larger than this value - // 0 - no upper resolution limit (default) - unsigned int m_maxTextureSize; - - // "mintexturesize", lower limit of the resolution of generated textures.It should be a power-of-2 number larger than 1 - // resulting texture will be upscaled if its width or height smaller than this value - // 0 - no lower resolution limit (default) - unsigned int m_minTextureSize; - - bool m_isPowerOf2; - - //"reduce", 0=no size reduce /1=half resolution /2=quarter resolution, etc" - unsigned int m_sizeReduceLevel; - - //settings for cubemap generation. it's null if this preset is not for cubemap. - //"cm" equals 1 to enable cubemap in rc.ini - AZStd::unique_ptr m_cubemapSetting; - - //settings for mipmap generation. it's null if this preset disable mipmap. - AZStd::unique_ptr m_mipmapSetting; - - //some specific settings - // "colorchart". This is to indicate if need to extract color chart from the image and output the color chart data. - // This is very specific usage for cryEngine. Check ColorChart.cpp for better explaination. - bool m_isColorChart; - - //"highpass". Defines which mip level is subtracted when applying the high pass filter - //this is only used for terrain asset. we might remove it later since it can be done with source image directly - AZ::u32 m_highPassMip; - - //"glossfromnormals". Bake normal variance into smoothness stored in alpha channel - AZ::u32 m_glossFromNormals; - - //"mipnormalize". need normalize the rgb - bool m_isMipRenormalize; - - //function to get color's rgb weight in vec3 based on m_rgbWeight enum - //this is useful for squisher compression - AZ::Vector3 GetColorWeight(); - - //numstreamablemips - AZ::u32 m_numStreamableMips; - - //legacy options might be removed later - //"glosslegacydist". If the gloss map use legacy distribution. NW is still using legacy dist - bool m_isLegacyGloss; - - //"swizzle". need to be 4 character and each character need to be one of "rgba01" - AZStd::string m_swizzle; - - private: - void DeepCopyMembers(const PresetSettings& other); - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.cpp deleted file mode 100644 index b465ec81f3..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -namespace ImageProcessing -{ - const char* TextureSettings::legacyExtensionName = ".exportsettings"; - const char* TextureSettings::modernExtensionName = ".imagesettings"; - - StringOutcome ParseLegacyTextureSettingString(AZStd::string& key, AZStd::string& value, TextureSettings& textureSettingOut) - { - // Parse only the settings we support for TextureSetting - if ("reduce" == key) // Example: reduce=0 - { - int reduce = AzFramework::StringFunc::ToInt(value.c_str()); - if (reduce >= 0) - { - textureSettingOut.m_sizeReduceLevel = reduce; - } - } - else if ("M" == key) // Example: M=50,50,0,50,50,50 - { - textureSettingOut.m_enableMipmap = true; - - AZStd::vector mipStringValues; - AzFramework::StringFunc::Tokenize(value.c_str(), mipStringValues, ','); - - for (size_t mipIndex = 0; mipIndex < mipStringValues.size(); ++mipIndex) - { - AZ::u32 mipValue = AzFramework::StringFunc::ToInt(mipStringValues[mipIndex].c_str()); - textureSettingOut.m_mipAlphaAdjust[mipIndex] = mipValue; - } - } - else if ("ser" == key) // Example: ser=1 - { - textureSettingOut.m_suppressEngineReduce = (value == "1"); - } - else if ("preset" == key) // Example: preset=NormalsWithSmoothness - { - AZ::Uuid presetUuid = BuilderSettingManager::Instance()->GetPresetIdFromName(value); - - // There's a chance the preset name still adheres to legacy preset naming convention (from CryEngine). - const PresetName translation = BuilderSettingManager::Instance()->TranslateLegacyPresetName(value); - AZ::Uuid translatedPresetUuid = BuilderSettingManager::Instance()->GetPresetIdFromName(translation); - - if (!presetUuid.IsNull()) - { - textureSettingOut.m_preset = presetUuid; - } - else if (!translatedPresetUuid.IsNull()) - { - textureSettingOut.m_preset = translatedPresetUuid; - } - else - { - AZ_Error("Image processing", false, "Can't find preset %s", value.c_str()); - } - } - else if ("mipgentype" == key) // Example: mipgentype=box - { - if ("box" == value || "average" == value) - { - textureSettingOut.m_mipGenType = MipGenType::box; - } - else if ("gauss" == value) - { - textureSettingOut.m_mipGenType = MipGenType::gaussian; - } - else if ("blackman-harris" == value) - { - textureSettingOut.m_mipGenType = MipGenType::blackmanHarris; - } - else if ("kaiser" == value) - { - textureSettingOut.m_mipGenType = MipGenType::kaiserSinc; - } - else if ("point" == value) - { - textureSettingOut.m_mipGenType = MipGenType::point; - } - else if ("quadric" == value) - { - textureSettingOut.m_mipGenType = MipGenType::quadratic; - } - else if ("triangle" == value) - { - textureSettingOut.m_mipGenType = MipGenType::triangle; - } - } - return STRING_OUTCOME_SUCCESS; - } - - TextureSettings::TextureSettings() - : m_preset(0) - , m_sizeReduceLevel(0) - , m_suppressEngineReduce(false) - , m_enableMipmap(true) - , m_maintainAlphaCoverage(false) - , m_mipGenEval(MipGenEvalType::sum) - , m_mipGenType(MipGenType::blackmanHarris) - { - const int defaultMipMapValue = 50; - - for (int i = 0; i < s_MaxMipMaps; ++i) - { - m_mipAlphaAdjust.push_back(defaultMipMapValue); - } - } - - void TextureSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("PresetID", &TextureSettings::m_preset) - ->Field("SizeReduceLevel", &TextureSettings::m_sizeReduceLevel) - ->Field("EngineReduce", &TextureSettings::m_suppressEngineReduce) - ->Field("EnableMipmap", &TextureSettings::m_enableMipmap) - ->Field("MaintainAlphaCoverage", &TextureSettings::m_maintainAlphaCoverage) - ->Field("MipMapAlphaAdjustments", &TextureSettings::m_mipAlphaAdjust) - ->Field("MipMapGenEval", &TextureSettings::m_mipGenEval) - ->Field("MipMapGenType", &TextureSettings::m_mipGenType) - ->Field("PlatformSpecificOverrides", &TextureSettings::m_platfromOverrides) - ->Field("OverridingPlatform", &TextureSettings::m_overridingPlatform); - - AZ::EditContext* edit = serialize->GetEditContext(); - if (edit) - { - edit->Class("Texture Setting", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->DataElement(AZ::Edit::UIHandlers::Default, &TextureSettings::m_mipAlphaAdjust, "Alpha Test Bias", "Multiplies the mipmap's alpha with a scale value that is based on alpha coverage. \ - Set the mip 0 to mip 5 values to offset the alpha test values and ensure the mipmap's alpha coverage matches the original image. Specify a value from 0 to 100.") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false) - ->ElementAttribute(AZ::Edit::UIHandlers::Handler, AZ::Edit::UIHandlers::Slider) - ->ElementAttribute(AZ::Edit::Attributes::Min, 0) - ->ElementAttribute(AZ::Edit::Attributes::Max, 100) - ->ElementAttribute(AZ::Edit::Attributes::Step, 1) - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &TextureSettings::m_mipGenType, "Filter Method", "") - ->EnumAttribute(MipGenType::point, "Point") - ->EnumAttribute(MipGenType::box, "Average") - ->EnumAttribute(MipGenType::triangle, "Linear") - ->EnumAttribute(MipGenType::quadratic, "Bilinear") - ->EnumAttribute(MipGenType::gaussian, "Gaussian") - ->EnumAttribute(MipGenType::blackmanHarris, "BlackmanHarris") - ->EnumAttribute(MipGenType::kaiserSinc, "KaiserSinc") - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &TextureSettings::m_mipGenEval, "Pixel Sampling Type", "") - ->EnumAttribute(MipGenEvalType::max, "Max") - ->EnumAttribute(MipGenEvalType::min, "Min") - ->EnumAttribute(MipGenEvalType::sum, "Sum") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &TextureSettings::m_maintainAlphaCoverage, "Maintain Alpha Coverage", "Select this option to manually adjust Alpha channel mipmaps.") - ; - } - } - - } - - bool TextureSettings::operator!=(const TextureSettings& other) const - { - return !(*this == other); - } - - bool TextureSettings::operator==(const TextureSettings& other) const - { - ///////////////////////////// - // Compare Alpha Adjust - ///////////////////////////// - bool matchingAlphaTestAdjust = true; - for (AZ::u8 curIndex = 0; curIndex < s_MaxMipMaps; ++curIndex) - { - if (m_mipAlphaAdjust[curIndex] != other.m_mipAlphaAdjust[curIndex]) - { - matchingAlphaTestAdjust = false; - break; - } - } - return - matchingAlphaTestAdjust && - m_preset == other.m_preset && - m_sizeReduceLevel == other.m_sizeReduceLevel && - m_suppressEngineReduce == other.m_suppressEngineReduce && - m_maintainAlphaCoverage == other.m_maintainAlphaCoverage && - m_mipGenEval == other.m_mipGenEval && - m_mipGenType == other.m_mipGenType; - } - - bool TextureSettings::Equals(const TextureSettings& other, AZ::SerializeContext* serializeContext) - { - ///////////////////////////// - // Compare Common Settings - ///////////////////////////// - if (*this != other) - { - return false; - } - - ///////////////////////////// - // Compare Overrides - ///////////////////////////// - const MultiplatformTextureSettings selfOverrides = GetMultiplatformTextureSetting(*this, serializeContext); - const MultiplatformTextureSettings otherOverrides = GetMultiplatformTextureSetting(other, serializeContext); - auto selfOverridesIter = selfOverrides.begin(); - auto otherOverridesIter = otherOverrides.begin(); - - while (selfOverridesIter != selfOverrides.end() && otherOverridesIter != otherOverrides.end()) - { - if (selfOverridesIter->second != otherOverridesIter->second) - { - return false; - } - otherOverridesIter++; - selfOverridesIter++; - } - - AZ_Assert(selfOverridesIter == selfOverrides.end() && otherOverridesIter == otherOverrides.end(), "Both iterators must be at the end by now.") - return true; - } - - float TextureSettings::ComputeMIPAlphaOffset(AZ::u32 mip) const - { - if (mip / 2 + 1 >= s_MaxMipMaps) - { - return 0; - } - - float fVal = static_cast(m_mipAlphaAdjust[s_MaxMipMaps - 1]); - if (mip / 2 + 1 < s_MaxMipMaps) - { - float fInterpolationSlider1 = static_cast(m_mipAlphaAdjust[mip / 2]); - float fInterpolationSlider2 = static_cast(m_mipAlphaAdjust[mip / 2 + 1]); - fVal = fInterpolationSlider1 + (fInterpolationSlider2 - fInterpolationSlider1) * (mip & 1) * 0.5f; - } - - return 0.5f - fVal / 100.0f; - } - - void TextureSettings::ApplyPreset(AZ::Uuid presetId) - { - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(presetId); - if (presetSetting != nullptr) - { - m_sizeReduceLevel = presetSetting->m_sizeReduceLevel; - m_suppressEngineReduce = presetSetting->m_suppressEngineReduce; - if (presetSetting->m_mipmapSetting) - { - m_mipGenType = presetSetting->m_mipmapSetting->m_type; - } - - m_preset = presetId; - } - else - { - AZ_Error("Image Processing", false, "Cannot set an invalid preset %s!", presetId.ToString().c_str()); - } - } - - StringOutcome TextureSettings::LoadTextureSetting(const AZStd::string& filepath, TextureSettings& textureSettingPtrOut, AZ::SerializeContext* serializeContext /*= nullptr*/) - { - auto loadedTextureSettingPtr = AZStd::unique_ptr(AZ::Utils::LoadObjectFromFile(filepath, serializeContext)); - - if (!loadedTextureSettingPtr) - { - return AZ::Failure(AZStd::string()); - } - - textureSettingPtrOut = *loadedTextureSettingPtr; - return AZ::Success(AZStd::string()); - } - - StringOutcome TextureSettings::WriteTextureSetting(const AZStd::string& filepath, TextureSettings& textureSetting, AZ::SerializeContext* serializeContext) - { - if(false == AZ::Utils::SaveObjectToFile(filepath, AZ::DataStream::StreamType::ST_XML, &textureSetting, serializeContext)) - { - return STRING_OUTCOME_ERROR("Failed to write to file: " + filepath); - } - - return STRING_OUTCOME_SUCCESS; - } - - StringOutcome TextureSettings::LoadLegacyTextureSetting(const AZStd::string& imagePath, const AZStd::string& contentString, TextureSettings& textureSettingOut, AZ::SerializeContext* serializeContext) - { - AZStd::string trimmedContent = contentString; - AzFramework::StringFunc::TrimWhiteSpace(trimmedContent, true /* leading */, true /* trailing */); - if (trimmedContent.empty()) - { - return STRING_OUTCOME_ERROR("Empty legacy texture setting!"); - } - - AZStd::vector settings; - AZStd::vector overrideSettings; - - // Each setting begins with a forward-slash. - AzFramework::StringFunc::Tokenize(trimmedContent.c_str(), settings, " /"); // requires space character. - - // For each setting pair (field & value)... - for (AZStd::string& settingPair : settings) - { - // Split setting pair into key & value. - AZStd::string key, value; - { - AZStd::vector key_value; - AzFramework::StringFunc::Tokenize(settingPair.c_str(), key_value, '='); - if (key_value.size() == 2) - { - key = key_value[0]; - value = key_value[1]; - } - else - { - return STRING_OUTCOME_ERROR("Invalid format found in legacy texture setting: " + settingPair); - } - } - - bool containsPlatformOverrides = !value.empty() && (value[0] == '"' && value[value.length() - 1] == '"'); - if (containsPlatformOverrides) - { - // Process platform-specific overrides on the next loop. - overrideSettings.push_back(&settingPair); - continue; - } - - // Parse the common settings. - ParseLegacyTextureSettingString(key, value, textureSettingOut); - } - - // Some setting file won't assign a proper preset for the image, need to assign a suggested one here - if (textureSettingOut.m_preset.IsNull()) - { - textureSettingOut.m_preset = BuilderSettingManager::Instance()->GetSuggestedPreset(imagePath); - } - - // Store a temporary settings of all platforms intended to have overrides within this preset. - // We will collate all overrides per-platform to generate PatchData at the end. - MultiplatformTextureSettings overrideCache; - - // For each platform-specific override setting pair - for (AZStd::string* overrideSettingPair : overrideSettings) - { - // Split setting pair into key & value. - AZStd::string key, value; - { - AZStd::vector key_value; - AzFramework::StringFunc::Tokenize(overrideSettingPair->c_str(), key_value, '='); - - if (key_value.size() == 2) - { - key = key_value[0]; - value = key_value[1]; - } - else - { - return STRING_OUTCOME_ERROR("Invalid format found in legacy texture setting: " + *overrideSettingPair); - } - } - - // Chop the surrounding quotation marks. - AzFramework::StringFunc::LChop(value, 1); - AzFramework::StringFunc::RChop(value, 1); - - // Split the collection of platforms overrides into entries in a vector. - // Layout: { [platform0],[value0],[platform1],[value1],[platform2],[value2] } - AZStd::vector override_platform_value; - AzFramework::StringFunc::Tokenize(value.c_str(), override_platform_value, ",:"); - - if (override_platform_value.size() % 2 != 0) - { - return STRING_OUTCOME_ERROR("Invalid format found in legacy texture setting: " + value); - } - - for (int platformIdx = 0, valueIdx = 1; - valueIdx < override_platform_value.size(); - platformIdx += 2, valueIdx = platformIdx + 1) - { - PlatformName& overridePlatform = override_platform_value[platformIdx]; - AZStd::string& overrideValue = override_platform_value[valueIdx]; - - // Insert a copy of the base settings we've parsed from the legacy metafile. - overrideCache.insert(AZStd::pair(overridePlatform, textureSettingOut)); - - ParseLegacyTextureSettingString(key, overrideValue, overrideCache[overridePlatform]); - overrideCache[overridePlatform].m_overridingPlatform = overridePlatform; - overrideCache[overridePlatform].m_platfromOverrides.clear(); - } - } - - // Store the final result in a temp variable to do a whole-sale copy at the end. - TextureSettings finalResult = textureSettingOut; - - // Use the override cache to generate a DataPatch per-platform. - for (auto& overridePair : overrideCache) - { - // Every DataPatch is only a diff between a vanilla common-settings (with no platform-specific overrides) and the specified platform's override. - AZ::DataPatch platformOverridePatch; - platformOverridePatch.Create(&textureSettingOut, &overridePair.second,AZ::DataPatch::FlagsMap(), AZ::DataPatch::FlagsMap(), serializeContext); - finalResult.m_platfromOverrides.insert(AZStd::pair(overridePair.first, platformOverridePatch)); - } - - // Fully overwrite output variable. The only difference should be properly filled-out overrides. - textureSettingOut = finalResult; - - return STRING_OUTCOME_SUCCESS; - } - - StringOutcome TextureSettings::LoadLegacyTextureSettingFromFile(const AZStd::string& imagePath, const AZStd::string& filepath, TextureSettings& textureSettingOut, AZ::SerializeContext* serializeContext) - { - AZStd::string fileContents; - - // Perform file I/O to read the contents of the metafile into the string above. - auto fileIoPtr = AZ::IO::FileIOBase::GetInstance(); - AZ::IO::HandleType fileHandle; - fileIoPtr->Open(filepath.c_str(), AZ::IO::OpenMode::ModeRead, fileHandle); - AZ::u64 fileSize = 0; - AZ::u64 bytesRead = 0; - fileIoPtr->Size(fileHandle, fileSize); - char* fileString = new char[fileSize + 1]; - fileIoPtr->Read(fileHandle, fileString, fileSize, false, &bytesRead); - fileIoPtr->Close(fileHandle); - fileString[bytesRead] = 0; - fileContents = fileString; - delete[] fileString; - - - return LoadLegacyTextureSetting(imagePath, fileContents, textureSettingOut, serializeContext); - } - - MultiplatformTextureSettings TextureSettings::GenerateDefaultMultiplatformTextureSettings(const AZStd::string& imageFilepath) - { - MultiplatformTextureSettings settings; - PlatformNameList platformsList = BuilderSettingManager::Instance()->GetPlatformList(); - AZ::Uuid suggestedPreset = BuilderSettingManager::Instance()->GetSuggestedPreset(imageFilepath); - if (!suggestedPreset.IsNull()) - { - for (PlatformName& platform : platformsList) - { - TextureSettings textureSettings; - textureSettings.ApplyPreset(suggestedPreset); - settings.insert(AZStd::pair(platform, textureSettings)); - } - } - return settings; - } - - StringOutcome TextureSettings::GetPlatformSpecificTextureSetting(const PlatformName& platformName, const TextureSettings& baseTextureSettings, - TextureSettings& textureSettingsOut, AZ::SerializeContext* serializeContext) - { - // Obtain the DataPatch (if platform exists) - auto overrideIter = baseTextureSettings.m_platfromOverrides.find(platformName); - if (overrideIter == baseTextureSettings.m_platfromOverrides.end()) - { - return STRING_OUTCOME_ERROR(AZStd::string::format("TextureSettings preset [%s] does not have override for platform [%s]", - baseTextureSettings.m_preset.ToString().c_str(), platformName.c_str())); - } - AZ::DataPatch& platformOverride = const_cast(overrideIter->second); - - // Update settings instance with override values. - if (platformOverride.IsData()) - { - // Apply the AZ::DataPatch to obtain a platform-overridden version of the TextureSettings. - AZStd::unique_ptr platformSpecificTextureSettings(platformOverride.Apply(&baseTextureSettings, serializeContext)); - AZ_Assert(platformSpecificTextureSettings->m_mipAlphaAdjust.size() == s_MaxMipMaps, "Unexpected m_mipAlphaAdjust size."); - - // Adjust overrides data to imply 'platformSpecificTextureSettings' *IS* the override. - platformSpecificTextureSettings->m_platfromOverrides.clear(); - platformSpecificTextureSettings->m_overridingPlatform = platformName; - textureSettingsOut = *platformSpecificTextureSettings; - } - else - { - textureSettingsOut = baseTextureSettings; - } - - return STRING_OUTCOME_SUCCESS; - } - - const MultiplatformTextureSettings TextureSettings::GetMultiplatformTextureSetting(const TextureSettings& textureSettings, AZ::SerializeContext* serializeContext) - { - MultiplatformTextureSettings loadedSettingsReturn; - PlatformNameList platformsList = BuilderSettingManager::Instance()->GetPlatformList(); - // Generate MultiplatformTextureSettings based on existing available overrides. - for (const PlatformName& curPlatformName : platformsList) - { - // Start with a copy of the base settings - TextureSettings curPlatformOverride = textureSettings; - if (!GetPlatformSpecificTextureSetting(curPlatformName, textureSettings, curPlatformOverride, serializeContext).IsSuccess()) - { - // We have failed to obtain an override. Maintain base settings to indicate zero overrides. - // We still want to designate these TextureSettings as an (empty) override. - curPlatformOverride.m_platfromOverrides.clear(); - curPlatformOverride.m_overridingPlatform = curPlatformName; - } - - // Add as an entry to the multiplatform texture settings - loadedSettingsReturn.insert(AZStd::pair(curPlatformName, curPlatformOverride)); - } - - // return a copy of the results - return loadedSettingsReturn; - } - - const MultiplatformTextureSettings TextureSettings::GetMultiplatformTextureSetting(const AZStd::string& imageFilepath, bool& canOverridePreset, AZ::SerializeContext* serializeContext) - { - TextureSettings loadedTextureSetting; - - // Attempt to get metadata filepath from image path. - AZStd::string legacyMetadataFilepath = imageFilepath + legacyExtensionName; - AZStd::string modernMetadataFilepath = imageFilepath + modernExtensionName; - bool hasLegacyMetafile = AZ::IO::SystemFile::Exists(legacyMetadataFilepath.c_str()); - bool hasModernMetafile = AZ::IO::SystemFile::Exists(modernMetadataFilepath.c_str()); - - // If the image has an accompanying metadata... - if(hasModernMetafile) - { - // Parse the metadata file. - if (!LoadTextureSetting(modernMetadataFilepath, loadedTextureSetting, serializeContext).IsSuccess()) - { - canOverridePreset = true; - return GenerateDefaultMultiplatformTextureSettings(imageFilepath); - } - } - else if (hasLegacyMetafile) - { - if (!LoadLegacyTextureSettingFromFile(imageFilepath, legacyMetadataFilepath, loadedTextureSetting, serializeContext).IsSuccess()) - { - canOverridePreset = true; - return GenerateDefaultMultiplatformTextureSettings(imageFilepath); - } - } - else - { - canOverridePreset = true; // RC could override settings if it was loaded from the image so this is set to - // true regardless of whether settings existed in the texture for compatibility. - // Try to load from image file if it has embedded setting file - AZStd::string embeddedString = LoadEmbeddedSettingFromFile(imageFilepath); - if (!LoadLegacyTextureSetting(imageFilepath, embeddedString, loadedTextureSetting, serializeContext).IsSuccess()) - { - // If the texture has neither of legacy/modern meta file nor embedded setting, generate data for a new metadata file. - return GenerateDefaultMultiplatformTextureSettings(imageFilepath); - } - } - - // Generate MultiplatformTextureSettings based on the loaded texture setting. - return GetMultiplatformTextureSetting(loadedTextureSetting, serializeContext); - } - - StringOutcome TextureSettings::ApplySettings(const TextureSettings& settings, const PlatformName& overridePlatform, AZ::SerializeContext* serializeContext) - { - if (overridePlatform.empty()) - { - *this = settings; - } - else - { - AZ::DataPatch newOverride; - if (false == newOverride.Create(this, &settings, AZ::DataPatch::FlagsMap(), AZ::DataPatch::FlagsMap(), serializeContext)) - { - return STRING_OUTCOME_ERROR("Failed to create TextureSettings platform override data. See AZ_Error log for details."); - } - - m_platfromOverrides[overridePlatform] = newOverride; - } - - return STRING_OUTCOME_SUCCESS; - } -} diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.h deleted file mode 100644 index 2ecc2c0a96..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.h +++ /dev/null @@ -1,171 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include - -namespace ImageProcessing -{ - class TextureSettings; - typedef AZStd::map MultiplatformTextureSettings; - - class TextureSettings - { - public: - AZ_TYPE_INFO(TextureSettings, "{CC3ED018-7FF7-4233-AAD8-6D3115FD844A}"); - AZ_CLASS_ALLOCATOR(TextureSettings, AZ::SystemAllocator, 0); - - TextureSettings(); - float ComputeMIPAlphaOffset(AZ::u32 mip) const; - void ApplyPreset(AZ::Uuid presetId); - - /** - * Performs a comprehensive comparison between two TextureSettings instances. - * @param Reference to the settings which will be compared. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return True, is both instances are equivalent. - */ - bool Equals(const TextureSettings& other, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Applies texture settings to the instance (including overrides). Common settings are applied, unless specific platform is specified. - * @param Reference to the settings which will be applied. - * @param Optional. Applies settings as a platform override if a platform is specified. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - StringOutcome ApplySettings(const TextureSettings& settings, const PlatformName& overridePlatform = PlatformName(), AZ::SerializeContext* serializeContext = nullptr); - - /** - * Gets platform-specific texture settings obtained from the base settings version of a pre-loaded TextureSettings instance. - * @param Name of platform to get the settings from. - * @param Base TextureSettings which we will get overrides from. - * @param Output TextureSettings which will contain the result of the function. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome GetPlatformSpecificTextureSetting(const PlatformName& platformName, const TextureSettings& baseTextureSettings, TextureSettings& textureSettingsOut, AZ::SerializeContext* serializeContext = nullptr); - - static void Reflect(AZ::ReflectContext* context); - - - /** - * Loads base texture settings obtained from ".exportsettings" file (legacy setting) - * @param ImagePath absolute/relative path of the image file. - * @param FilePath absolute/relative path of the ".exportsettings" file. - * @param Output TextureSettings which contain the result of the function, it may contains platform-specific overrides. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome LoadLegacyTextureSettingFromFile(const AZStd::string& imagePath, const AZStd::string& filepath, TextureSettings& textureSettingOut, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Loads base texture settings obtained from a legacy setting string - * @param ImagePath absolute/relative path of the image file. - * @param Content string of the legacy setting to be read. - * @param Output TextureSettings which contain the result of the function, it may contains platform-specific overrides. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome LoadLegacyTextureSetting(const AZStd::string& imagePath, const AZStd::string& contentString, TextureSettings& textureSettingOut, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Loads base texture settings obtained from ".imagesettings" file (modern setting) - * @param FilePath absolute/relative path of the ".imagesettings" file. - * @param Output TextureSettings which contain the result of the function, it may contains platform-specific overrides. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome LoadTextureSetting(const AZStd::string& filepath, TextureSettings& textureSettingPtrOut, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Writes base texture settings to a ".imagesettings" file (modern setting) - * @param FilePath absolute/relative path of the ".imagesettings" file. - * @param TextureSetting to be written on the disk, it may contains platform-specific overrides. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome WriteTextureSetting(const AZStd::string& filepath, TextureSettings& textureSetting, AZ::SerializeContext* serializeContext = nullptr); - - // Generates a MultiplatformTextureSettings collection with default texture settings for all - static MultiplatformTextureSettings GenerateDefaultMultiplatformTextureSettings(const AZStd::string& imageFilepath); - - /** - * Generates a TextureSetting instance of a particular image file for each supported platform. - * @param filepath - A path to the texture file. - * @param canOverridePreset - Returns whether the preset can be overriden. Will return false if the preset was selecting from a settings file created by the user. - * @param serializeContext - Optional. Serialize context used for reflection/serialization - * @return - The collection of TextureSetting instances. If error occurs, a default MultiplatformTextureSettings is returned (see GenerateDefaultMultiplatformTextureSettings()). - */ - static const MultiplatformTextureSettings GetMultiplatformTextureSetting(const AZStd::string& filepath, bool& canOverridePreset, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Generates a TextureSetting instance of a particular image file for each supported platform. - * @param textureSettings - A reference to an already-loaded texture settings. - * @param serializeContext - Optional. Serialize context used for reflection/serialization - * @return - The collection of TextureSetting instances. If error occurs, a default MultiplatformTextureSettings is returned (see GenerateDefaultMultiplatformTextureSettings()). - */ - static const MultiplatformTextureSettings GetMultiplatformTextureSetting(const TextureSettings& textureSettings, AZ::SerializeContext* serializeContext = nullptr); - - static const char* legacyExtensionName; - static const char* modernExtensionName; - static const size_t s_MaxMipMaps = 6; - - // uuid of selected preset for this texture - AZ::Uuid m_preset; - - // texture size reduce level. the value of this variable will override the same variable in PresetSettings - unsigned int m_sizeReduceLevel; - - // "ser". Whether to enable supress reduce resolution (m_sizeReduceLevel) during loading, 0(default) - // the value of this variable will override the same variable in PresetSettings - bool m_suppressEngineReduce; - - //enable generate mipmap or not - bool m_enableMipmap; - - //"mc". not used in rc.ini. experiemental - //maybe relate to http://the-witness.net/news/2010/09/computing-alpha-mipmaps/ - bool m_maintainAlphaCoverage; - - // "M", adjust mipalpha, 0..50=normal..100. associate with ComputeMIPAlphaOffset function - // only useful if m_maintainAlphaCoverage set to true. - // This data type MUST be an AZStd::vector, even though we treat is as a fixed array. This is due to a limitation - // during AZ::DataPatch serialization, where an element is allocated one by one while extending the container.. - AZStd::vector m_mipAlphaAdjust; - - MipGenEvalType m_mipGenEval; - - MipGenType m_mipGenType; - - private: - // Platform overrides in form of DataPatch. Each entry is a patch for a specified platform. - // This map is used to generate TextureSettings with overridden values. The map is empty if - // the instance is for platform-specific settings. - AZStd::map m_platfromOverrides; - - // The platform which these settings override. - // Blank if the instance is for common settings. - PlatformName m_overridingPlatform; - - // Comparison operators only compare the base settings, they do not compare overrides. - // For a comprehensive equality comparison, use Equals() function. - bool operator==(const TextureSettings& other) const; - bool operator!=(const TextureSettings& other) const; - - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.cpp deleted file mode 100644 index efb9d85cab..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include - -#include - -namespace ImageProcessing -{ - struct CrySquisherCallbackUserData - { - IImageObjectPtr m_pImageObject; - AZ::u8* m_dstMem; - AZ::u32 m_dstOffset; - }; - - // callbacks for the CryTextureSquisher - void CrySquisherOutputCallback(const CryTextureSquisher::CompressorParameters& compress, const void* data, AZ::u32 size, AZ::u32 oy, AZ::u32 ox) - { - CrySquisherCallbackUserData* const pUserData = (CrySquisherCallbackUserData*)compress.userPtr; - - AZ::u32 stride = (compress.width + 3) >> 2; - AZ::u32 blocks = (compress.height + 3) >> 2; - memcpy(pUserData->m_dstMem + size * (stride * oy + ox), data, size); - pUserData->m_dstOffset = size * (stride * blocks); - } - - void CrySquisherInputCallback(const CryTextureSquisher::DecompressorParameters& decompress, void* data, AZ::u32 size, AZ::u32 oy, AZ::u32 ox) - { - CrySquisherCallbackUserData* const pUserData = (CrySquisherCallbackUserData*)decompress.userPtr; - AZ::u32 stride = (decompress.width + 3) >> 2; - AZ::u32 blocks = (decompress.height + 3) >> 2; - - //assert(CPixelFormats::GetPixelFormatInfo(pUserData->m_pImageObject->GetPixelFormat())->bCompressed); - - memcpy(data, pUserData->m_dstMem + size * (stride * oy + ox), size); - - pUserData->m_dstOffset = size * (stride * blocks); - } - - - CryTextureSquisher::ECodingPreset CTSquisher::GetCompressPreset(EPixelFormat compressFmt, EPixelFormat uncompressFmt) - { - CryTextureSquisher::ECodingPreset preset = CryTextureSquisher::eCompressorPreset_Num; - switch (compressFmt) - { - case ePixelFormat_BC1: - preset = CryTextureSquisher::eCompressorPreset_BC1U; - break; - case ePixelFormat_BC1a: - preset = CryTextureSquisher::eCompressorPreset_BC1Ua; - break; - case ePixelFormat_BC3: - preset = CryTextureSquisher::eCompressorPreset_BC3U; - break; - case ePixelFormat_BC3t: - preset = CryTextureSquisher::eCompressorPreset_BC3Ut; - break; - case ePixelFormat_BC4: - preset = (CPixelFormats::GetInstance().IsFormatSingleChannel(uncompressFmt) - ? CryTextureSquisher::eCompressorPreset_BC4Ua // a-channel - : CryTextureSquisher::eCompressorPreset_BC4U); // r-channel - break; - case ePixelFormat_BC4s: - preset = (CPixelFormats::GetInstance().IsFormatSingleChannel(uncompressFmt) - ? CryTextureSquisher::eCompressorPreset_BC4Sa // a-channel - : CryTextureSquisher::eCompressorPreset_BC4S); // r-channel - break; - case ePixelFormat_BC5: - preset = CryTextureSquisher::eCompressorPreset_BC5Un; - break; - case ePixelFormat_BC5s: - preset = CryTextureSquisher::eCompressorPreset_BC5Sn; - break; - case ePixelFormat_BC6UH: - preset = CryTextureSquisher::eCompressorPreset_BC6UH; - break; - case ePixelFormat_BC7: - preset = CryTextureSquisher::eCompressorPreset_BC7U; - break; - case ePixelFormat_BC7t: - preset = CryTextureSquisher::eCompressorPreset_BC7Ut; - break; - default: - AZ_Assert(false, "%s: Unexpected pixel format (in compressing an image). Inform an RC programmer.", __FUNCTION__); - } - - return preset; - } - - bool CTSquisher::IsCompressedPixelFormatSupported(EPixelFormat fmt) - { - switch (fmt) - { - case ePixelFormat_BC1: - case ePixelFormat_BC1a: - case ePixelFormat_BC3: - case ePixelFormat_BC3t: - case ePixelFormat_BC4: - case ePixelFormat_BC4s: - case ePixelFormat_BC5: - case ePixelFormat_BC5s: - case ePixelFormat_BC6UH: - case ePixelFormat_BC7: - case ePixelFormat_BC7t: - return true; - default: - return false; - } - } - - bool CTSquisher::IsUncompressedPixelFormatSupported(EPixelFormat fmt) - { - switch (fmt) - { - case ePixelFormat_R8: - case ePixelFormat_A8: - case ePixelFormat_R8G8B8A8: - case ePixelFormat_R8G8B8X8: - case ePixelFormat_R32F: - case ePixelFormat_R32G32B32A32F: - return true; - default: - return false; - } - } - - bool CTSquisher::DoesSupportDecompress([[maybe_unused]] EPixelFormat fmtDst) - { - return true; - } - - EPixelFormat CTSquisher::GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) - { - //special cases - if (compressedfmt == ePixelFormat_BC6UH || compressedfmt == ePixelFormat_BC5 || compressedfmt == ePixelFormat_BC5s) - { - return ePixelFormat_R32G32B32A32F; - } - - if (IsUncompressedPixelFormatSupported(uncompressedfmt)) - { - return uncompressedfmt; - } - - //for fmt dont support, convert to supported uncompressed formats: ePixelFormat_A8, ePixelFormat_R8, ePixelFormat_A8R8G8B8, - // ePixelFormat_X8R8G8B8, ePixelFormat_R32F, ePixelFormat_A32B32G32R32F - - switch (uncompressedfmt) - { - case ePixelFormat_R8G8: - case ePixelFormat_R16G16: - return ePixelFormat_R8G8B8X8; - case ePixelFormat_R16: - return ePixelFormat_R8; - case ePixelFormat_R16G16B16A16: - case ePixelFormat_B8G8R8A8: - return ePixelFormat_R8G8B8A8; - case ePixelFormat_R9G9B9E5: - case ePixelFormat_R32G32F: - case ePixelFormat_R16G16B16A16F: - case ePixelFormat_R16G16F: - return ePixelFormat_R32G32B32A32F; - case ePixelFormat_R16F: - return ePixelFormat_R32F; - default: - //this shouldn't happen. but we could handle it with uncompressed data anyway - if (CPixelFormats::GetInstance().IsPixelFormatWithoutAlpha(uncompressedfmt)) - { - return ePixelFormat_R8G8B8X8; - } - else - { - return ePixelFormat_R8G8B8A8; - } - } - } - - IImageObjectPtr CTSquisher::DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) - { - // Decompressing - // the output pixel format could only have one channel or four channels. need to find out more - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); - - //src format need to be compressed and dst format need to uncompressed. - if (!IsCompressedPixelFormatSupported(fmtSrc) || !IsUncompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - //clear the dstImage to (0, 0, 0, 1) since some compression format only write to certain channels - dstImage->ClearColor(0, 0, 0, 1); - - //for each mipmap - const AZ::u32 mipCount = srcImage->GetMipCount(); - for (AZ::u32 dwMip = 0; dwMip < mipCount; ++dwMip) - { - const AZ::u32 dwLocalWidth = srcImage->GetWidth(dwMip); - const AZ::u32 dwLocalHeight = srcImage->GetHeight(dwMip); - - AZ::u8* pSrcMem; - AZ::u32 dwSrcPitch; - srcImage->GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - AZ::u8* pDstMem; - AZ::u32 dwDstPitch; - dstImage->GetImagePointer(dwMip, pDstMem, dwDstPitch); - - CrySquisherCallbackUserData userData; - userData.m_pImageObject = srcImage; - userData.m_dstOffset = 0; - userData.m_dstMem = pSrcMem; - - CryTextureSquisher::DecompressorParameters decompress; - - decompress.dstBuffer = pDstMem; - decompress.width = dwLocalWidth; - decompress.height = dwLocalHeight; - decompress.pitch = dwDstPitch; - - decompress.dstType = (CPixelFormats::GetInstance().IsFormatFloatingPoint(fmtDst, true) ? - CryTextureSquisher::eBufferType_ufloat : CryTextureSquisher::eBufferType_uint8); - - if (CPixelFormats::GetInstance().IsFormatSigned(fmtSrc)) - { - decompress.dstType = (decompress.dstType == CryTextureSquisher::eBufferType_ufloat ? - CryTextureSquisher::eBufferType_sfloat : CryTextureSquisher::eBufferType_sint8); - } - - decompress.userPtr = &userData; - decompress.userInputFunction = CrySquisherInputCallback; - decompress.preset = GetCompressPreset(fmtSrc, fmtDst); - - CryTextureSquisher::Decompress(decompress); - } - - // CTsquish operates on native normal vectors when floating-point - // buffers are used. Apply bias and scale when returning a normal-map. - if (fmtSrc == ePixelFormat_BC5 || fmtSrc == ePixelFormat_BC5s) - { - if (fmtDst == ePixelFormat_R32G32B32A32F) - { - //conver from [-1, 1] to [0, 1]. And set alpha to 1. - dstImage->ScaleAndBiasChannels(0, 100, - AZ::Vector4(0.5f, 0.5f, 0.5f, 0.0f), - AZ::Vector4(0.5f, 0.5f, 0.5f, 1.0f)); - } - } - - return dstImage; - } - - /////////////////////////////////////////////////////////////////////////////////// - IImageObjectPtr CTSquisher::CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, - const CompressOption *compressOption) - { - // Compressing - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); - - //src format need to be uncompressed and dst format need to compressed. - if (!IsUncompressedPixelFormatSupported(fmtSrc) || !IsCompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - //passing compress option - ICompressor::EQuality quality = ICompressor::eQuality_Normal; - AZ::Vector3 weights = AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - if (compressOption) - { - quality = compressOption->compressQuality; - weights = compressOption->rgbWeight; - } - - //do some clamp for float - if (fmtSrc == ePixelFormat_R32G32B32A32F) - { - const uint32 nMips = srcImage->GetMipCount(); - - // NOTES: - // - all incoming images are unsigned, even normal maps - // - all mipmaps of incoming images can contain out-of-range values from mipmap filtering - // - 3Dc/BC5 is synonymous with "is a normal map" because they are not tagged explicitly as such - if (fmtDst == ePixelFormat_BC5 || fmtDst == ePixelFormat_BC5s) - { - srcImage->ScaleAndBiasChannels(0, nMips, - AZ::Vector4(2.0f, 2.0f, 2.0f, 1.0f), - AZ::Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); - srcImage->ClampChannels(0, nMips, - AZ::Vector4(-1.0f, -1.0f, -1.0f, -1.0f), - AZ::Vector4(1.0f, 1.0f, 1.0f, 1.0f)); - } - else if (fmtDst == ePixelFormat_BC6UH) - { - srcImage->ClampChannels(0, nMips, - AZ::Vector4(0.0f, 0.0f, 0.0f, 0.0f), - AZ::Vector4(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX)); - } - else - { - srcImage->ClampChannels(0, nMips, - AZ::Vector4(0.0f, 0.0f, 0.0f, 0.0f), - AZ::Vector4(1.0f, 1.0f, 1.0f, 1.0f)); - } - } - - const uint32 mipCount = dstImage->GetMipCount(); - for (uint32 dwMip = 0; dwMip < mipCount; ++dwMip) - { - uint32 dwLocalWidth = srcImage->GetWidth(dwMip); - uint32 dwLocalHeight = srcImage->GetHeight(dwMip); - - uint8* pSrcMem; - uint32 dwSrcPitch; - srcImage->GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - uint8* pDstMem; - uint32 dwDstPitch; - dstImage->GetImagePointer(dwMip, pDstMem, dwDstPitch); - - { - CrySquisherCallbackUserData userData; - userData.m_pImageObject = dstImage; - userData.m_dstOffset = 0; - userData.m_dstMem = pDstMem; - - CryTextureSquisher::CompressorParameters compress; - - compress.srcBuffer = pSrcMem; - compress.width = dwLocalWidth; - compress.height = dwLocalHeight; - compress.pitch = dwSrcPitch; - - compress.srcType = (CPixelFormats::GetInstance().IsFormatFloatingPoint(fmtSrc, true) ? - CryTextureSquisher::eBufferType_ufloat : CryTextureSquisher::eBufferType_uint8); - if (CPixelFormats::GetInstance().IsFormatSigned(fmtDst)) - { - compress.srcType = (compress.srcType == CryTextureSquisher::eBufferType_ufloat ? - CryTextureSquisher::eBufferType_sfloat : CryTextureSquisher::eBufferType_sint8); - } - - const AZ::Vector3 uniform = AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - - compress.weights[0] = weights.GetX(); - compress.weights[1] = weights.GetY(); - compress.weights[2] = weights.GetZ(); - - compress.perceptual = - (compress.weights[0] != uniform.GetX()) || - (compress.weights[1] != uniform.GetY()) || - (compress.weights[2] != uniform.GetZ()); - - compress.quality = - (quality == eQuality_Preview ? CryTextureSquisher::eQualityProfile_Low : - (quality == eQuality_Fast ? CryTextureSquisher::eQualityProfile_Low : - (quality == eQuality_Slow ? CryTextureSquisher::eQualityProfile_High : - CryTextureSquisher::eQualityProfile_Medium))); - - compress.userPtr = &userData; - compress.userOutputFunction = CrySquisherOutputCallback; - compress.preset = GetCompressPreset(fmtDst, fmtSrc); - - CryTextureSquisher::Compress(compress); - } - } // for: all mips - - return dstImage; - } - -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.h b/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.h deleted file mode 100644 index 6cb08ac295..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace ImageProcessing -{ - //Cry Texture Squisher for all the BC compressions - class CTSquisher : public ICompressor - { - public: - static bool IsCompressedPixelFormatSupported(EPixelFormat fmt); - static bool IsUncompressedPixelFormatSupported(EPixelFormat fmt); - static bool DoesSupportDecompress(EPixelFormat fmtDst); - - IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption *compressOption) override; - IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) override; - - EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) override; - - - private: - static CryTextureSquisher::ECodingPreset GetCompressPreset(EPixelFormat compressFmt, EPixelFormat uncompressFmt); - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/Compressor.cpp b/Gems/ImageProcessing/Code/Source/Compressors/Compressor.cpp deleted file mode 100644 index fe151d8954..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/Compressor.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include - -namespace ImageProcessing -{ - ICompressorPtr ICompressor::FindCompressor(EPixelFormat fmt, bool isCompressing) - { - if (CTSquisher::IsCompressedPixelFormatSupported(fmt)) - { - if (isCompressing || (!isCompressing && CTSquisher::DoesSupportDecompress(fmt))) - { - return ICompressorPtr(new CTSquisher()); - } - } - - // Both ETC2Compressor and PVRTCCompressor can process ETC formats - // According to Mobile team, Etc2Com is faster than PVRTexLib, so we check with ETC2Compressor before PVRTCCompressor - // Note: with the test I have done, I found out it cost similar time for both Etc2Com and PVRTexLib to compress - // a 2048x2048 test texture to EAC_R11 and EAC_RG11. It was around 7 minutes for EAC_R11 and 14 minutes for EAC_RG11 - if (ETC2Compressor::IsCompressedPixelFormatSupported(fmt)) - { - if (isCompressing || (!isCompressing && ETC2Compressor::DoesSupportDecompress(fmt))) - { - return ICompressorPtr(new ETC2Compressor()); - } - } - - if (PVRTCCompressor::IsCompressedPixelFormatSupported(fmt)) - { - if (isCompressing || (!isCompressing && PVRTCCompressor::DoesSupportDecompress(fmt))) - { - return ICompressorPtr(new PVRTCCompressor()); - } - } - - return nullptr; - } - - ICompressor::~ICompressor() - { - - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/Compressor.h b/Gems/ImageProcessing/Code/Source/Compressors/Compressor.h deleted file mode 100644 index 14fb6d2b9a..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/Compressor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace ImageProcessing -{ - class ICompressor; - typedef AZStd::shared_ptr ICompressorPtr; - - //the interface base class for any compressors which can decompress/compress image with compressed pixel format - class ICompressor - { - public: - enum EQuality - { - eQuality_Preview, // for the 256x256 preview only - eQuality_Fast, - eQuality_Normal, - eQuality_Slow, - }; - - //some extra information required for different compressors. - //keep is a simple structure for now. - struct CompressOption - { - EQuality compressQuality = eQuality_Normal; - //required for CTSquisher - AZ::Vector3 rgbWeight = AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - }; - - public: - //compress the source image to desired compressed pixel format - virtual IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption *compressOption) = 0; - virtual IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) = 0; - virtual EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) = 0; - - //find compressor for specified compressed pixel format. isCompressing to indicate if it's for compressing or decompressing - static ICompressorPtr FindCompressor(EPixelFormat fmt, bool isCompressing); - - virtual ~ICompressor() = 0; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp deleted file mode 100644 index b436e7bbc2..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include - -#include "ColorBlockRGBA4x4c.h" - -namespace ImageProcessing -{ - static_assert(sizeof(int) == 4, "Expected size of int to be 4 bytes!"); - - void ColorBlockRGBA4x4c::setRGBA8(const void* imgBGRA8, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgBGRA8, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBA8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA8* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const uint8* const pSrc = ((const uint8*)imgBGRA8) + (pitch * (y + row)) + (x * sizeof(ColorRGBA8)); - - ColorRGBA8* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(&pSrc[0 * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - pDst[1].setRGBA(&pSrc[1 * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - pDst[2].setRGBA(&pSrc[2 * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - pDst[3].setRGBA(&pSrc[3 * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const uint8* const pSrc = ((const uint8*)imgBGRA8) + pitch * (y + by); - - ColorRGBA8* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(&pSrc[(x + bx) * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4c::getRGBA8(void* imgRGBA8, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgRGBA8, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBA8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA8* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - uint8* const pDst = ((uint8*)imgRGBA8) + (pitch * (y + row)) + (x * sizeof(ColorRGBA8)); - - const ColorRGBA8* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(&pDst[0 * sizeof(ColorRGBA8) / sizeof(*pDst)]); - pSrc[1].getRGBA(&pDst[1 * sizeof(ColorRGBA8) / sizeof(*pDst)]); - pSrc[2].getRGBA(&pDst[2 * sizeof(ColorRGBA8) / sizeof(*pDst)]); - pSrc[3].getRGBA(&pDst[3 * sizeof(ColorRGBA8) / sizeof(*pDst)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - uint8* const pDst = ((uint8*)imgRGBA8) + pitch * (y + by); - - const ColorRGBA8* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(&pDst[(x + bx) * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4c::setA8(const void* imgA8, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgA8, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(uint8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA8* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const uint8* const pSrc = ((const uint8*)imgA8) + (pitch * (y + row)) + (x * sizeof(uint8)); - - ColorRGBA8* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(0, 0, 0, pSrc[0]); - pDst[1].setRGBA(0, 0, 0, pSrc[1]); - pDst[2].setRGBA(0, 0, 0, pSrc[2]); - pDst[3].setRGBA(0, 0, 0, pSrc[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const uint8* const pSrc = ((const uint8*)imgA8) + pitch * (y + by); - - ColorRGBA8* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(0, 0, 0, pSrc[x + bx]); - } - } - } - } - - void ColorBlockRGBA4x4c::getA8(void* imgA8, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgA8, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(uint8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA8* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - uint8* const pDst = ((uint8*)imgA8) + (pitch * (y + row)) + (x * sizeof(uint8)); - uint8 r, g, b; - - const ColorRGBA8* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(r, g, b, pDst[0]); - pSrc[1].getRGBA(r, g, b, pDst[1]); - pSrc[2].getRGBA(r, g, b, pDst[2]); - pSrc[3].getRGBA(r, g, b, pDst[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - uint8* const pDst = ((uint8*)imgA8) + pitch * (y + by); - uint8 r, g, b; - - const ColorRGBA8* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(r, g, b, pDst[x + bx]); - } - } - } - } - - bool ColorBlockRGBA4x4c::isSingleColorIgnoringAlpha() const - { - for (unsigned int i = 1; i < COLOR_COUNT; ++i) - { - if ((m_color[0].b != m_color[i].b) || - (m_color[0].g != m_color[i].g) || - (m_color[0].r != m_color[i].r)) - { - return false; - } - } - - return true; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h deleted file mode 100644 index 06f0ac00ed..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - - -#include "ColorTypes.h" - -namespace ImageProcessing -{ - // Uncompressed 4x4 color block of 8bit integers. - struct ColorBlockRGBA4x4c - { - ColorBlockRGBA4x4c() - { - } - - void setRGBA8(const void* imgBGRA8, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getRGBA8(void* imgBGRA8, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - void setA8(const void* imgA8, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getA8(void* imgA8, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - bool isSingleColorIgnoringAlpha() const; - - const ColorRGBA8* colors() const - { - return m_color; - } - - ColorRGBA8* colors() - { - return m_color; - } - - ColorRGBA8 color(unsigned int i) const - { - return m_color[i]; - } - - ColorRGBA8& color(unsigned int i) - { - return m_color[i]; - } - - private: - static const unsigned int COLOR_COUNT = 4 * 4; - - ColorRGBA8 m_color[COLOR_COUNT]; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp deleted file mode 100644 index 20db26100a..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include - -#include "ColorBlockRGBA4x4f.h" - -namespace ImageProcessing -{ - static_assert(sizeof(int) == 4, "Expected size of int to be 4 bytes!"); - - void ColorBlockRGBA4x4f::setRGBAf(const void* imgRGBAf, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgRGBAf, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBAf), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorRGBAf* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const float* const pSrc = (const float*)(((const uint8*)imgRGBAf) + (pitch * (y + row)) + (x * sizeof(ColorRGBAf))); - - ColorRGBAf* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(&pSrc[0 * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - pDst[1].setRGBA(&pSrc[1 * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - pDst[2].setRGBA(&pSrc[2 * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - pDst[3].setRGBA(&pSrc[3 * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const float* const pSrc = (const float*)(((const uint8*)imgRGBAf) + pitch * (y + by)); - - ColorRGBAf* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(&pSrc[(x + bx) * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4f::getRGBAf(void* imgRGBAf, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgRGBAf, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBAf), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorRGBAf* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - float* const pDst = (float*)(((uint8*)imgRGBAf) + (pitch * (y + row)) + (x * sizeof(ColorRGBAf))); - - const ColorRGBAf* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(&pDst[0 * sizeof(ColorRGBAf) / sizeof(*pDst)]); - pSrc[1].getRGBA(&pDst[1 * sizeof(ColorRGBAf) / sizeof(*pDst)]); - pSrc[2].getRGBA(&pDst[2 * sizeof(ColorRGBAf) / sizeof(*pDst)]); - pSrc[3].getRGBA(&pDst[3 * sizeof(ColorRGBAf) / sizeof(*pDst)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - float* const pDst = (float*)(((uint8*)imgRGBAf) + pitch * (y + by)); - - const ColorRGBAf* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(&pDst[(x + bx) * sizeof(ColorRGBAf) / sizeof(*pDst)]); - } - } - } - } - - void ColorBlockRGBA4x4f::setAf(const void* imgAf, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgAf, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(float), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorRGBAf* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const float* const pSrc = (const float*)(((const uint8*)imgAf) + (pitch * (y + row)) + (x * sizeof(float))); - - ColorRGBAf* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(0, 0, 0, pSrc[0]); - pDst[1].setRGBA(0, 0, 0, pSrc[1]); - pDst[2].setRGBA(0, 0, 0, pSrc[2]); - pDst[3].setRGBA(0, 0, 0, pSrc[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const float* const pSrc = (const float*)(((const uint8*)imgAf) + (pitch * (y + by))); - - ColorRGBAf* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(0, 0, 0, pSrc[x + bx]); - } - } - } - } - - void ColorBlockRGBA4x4f::getAf(void* imgAf, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgAf, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(float), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorRGBAf* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - float* const pDst = (float*)(((uint8*)imgAf) + (pitch * (y + row)) + (x * sizeof(float))); - float r, g, b; - - const ColorRGBAf* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(r, g, b, pDst[0]); - pSrc[1].getRGBA(r, g, b, pDst[1]); - pSrc[2].getRGBA(r, g, b, pDst[2]); - pSrc[3].getRGBA(r, g, b, pDst[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - float* const pDst = (float*)(((uint8*)imgAf) + pitch * (y + by)); - float r, g, b; - - const ColorRGBAf* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(r, g, b, pDst[x + bx]); - } - } - } - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h deleted file mode 100644 index 0235dd18db..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "ColorTypes.h" - -namespace ImageProcessing -{ - // Uncompressed 4x4 color block of single precision floating points. - struct ColorBlockRGBA4x4f - { - ColorBlockRGBA4x4f() - { - } - - void setRGBAf(const void* imgARGBf, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getRGBAf(void* imgARGBf, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - void setAf(const void* imgAf, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getAf(void* imgAf, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - const ColorRGBAf* colors() const - { - return m_color; - } - - ColorRGBAf* colors() - { - return m_color; - } - - ColorRGBAf color(unsigned int i) const - { - return m_color[i]; - } - - ColorRGBAf& color(unsigned int i) - { - return m_color[i]; - } - - private: - static const unsigned int COLOR_COUNT = 4 * 4; - - ColorRGBAf m_color[COLOR_COUNT]; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp deleted file mode 100644 index 9e95a23f17..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include - -#include "ColorBlockRGBA4x4s.h" - -namespace ImageProcessing -{ - static_assert(sizeof(int) == 4, "Expected size of int to be 4 bytes!"); - - void ColorBlockRGBA4x4s::setRGBA16(const void* imgBGRA16, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgBGRA16, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBA16), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA16* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const uint16* const pSrc = (const uint16*)(((const uint8*)imgBGRA16) + (pitch * (y + row)) + (x * sizeof(ColorRGBA16))); - - ColorRGBA16* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(&pSrc[0 * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - pDst[1].setRGBA(&pSrc[1 * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - pDst[2].setRGBA(&pSrc[2 * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - pDst[3].setRGBA(&pSrc[3 * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const uint16* const pSrc = (const uint16*)(((const uint8*)imgBGRA16) + pitch * (y + by)); - - ColorRGBA16* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(&pSrc[(x + bx) * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4s::getRGBA16(void* imgBGRA16, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgBGRA16, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBA16), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA16* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - uint16* const pDst = (uint16*)(((uint8*)imgBGRA16) + (pitch * (y + row)) + (x * sizeof(ColorRGBA16))); - - const ColorRGBA16* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(&pDst[0 * sizeof(ColorRGBA16) / sizeof(*pDst)]); - pSrc[1].getRGBA(&pDst[1 * sizeof(ColorRGBA16) / sizeof(*pDst)]); - pSrc[2].getRGBA(&pDst[2 * sizeof(ColorRGBA16) / sizeof(*pDst)]); - pSrc[3].getRGBA(&pDst[3 * sizeof(ColorRGBA16) / sizeof(*pDst)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - uint16* const pDst = (uint16*)(((uint8*)imgBGRA16) + pitch * (y + by)); - - const ColorRGBA16* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(&pDst[(x + bx) * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4s::setA16(const void* imgA16, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgA16, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(uint8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA16* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const uint16* const pSrc = (const uint16*)(((const uint8*)imgA16) + (pitch * (y + row)) + (x * sizeof(uint16))); - - ColorRGBA16* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(0, 0, 0, pSrc[0]); - pDst[1].setRGBA(0, 0, 0, pSrc[1]); - pDst[2].setRGBA(0, 0, 0, pSrc[2]); - pDst[3].setRGBA(0, 0, 0, pSrc[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const uint16* const pSrc = (const uint16*)(((const uint8*)imgA16) + pitch * (y + by)); - - ColorRGBA16* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(0, 0, 0, pSrc[x + bx]); - } - } - } - } - - void ColorBlockRGBA4x4s::getA16(void* imgA16, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgA16, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(uint8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA16* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - uint16* const pDst = (uint16*)(((uint8*)imgA16) + (pitch * (y + row)) + (x * sizeof(uint16))); - uint16 r, g, b; - - const ColorRGBA16* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(r, g, b, pDst[0]); - pSrc[1].getRGBA(r, g, b, pDst[1]); - pSrc[2].getRGBA(r, g, b, pDst[2]); - pSrc[3].getRGBA(r, g, b, pDst[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - uint16* const pDst = (uint16*)(((uint8*)imgA16) + pitch * (y + by)); - uint16 r, g, b; - - const ColorRGBA16* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(r, g, b, pDst[x + bx]); - } - } - } - } - - bool ColorBlockRGBA4x4s::isSingleColorIgnoringAlpha() const - { - for (unsigned int i = 1; i < COLOR_COUNT; ++i) - { - if ((m_color[0].b != m_color[i].b) || - (m_color[0].g != m_color[i].g) || - (m_color[0].r != m_color[i].r)) - { - return false; - } - } - - return true; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h deleted file mode 100644 index 3c4b47cae7..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - - -#include "ColorTypes.h" - -namespace ImageProcessing -{ - // Uncompressed 4x4 color block of 16bit integers. - struct ColorBlockRGBA4x4s - { - ColorBlockRGBA4x4s() - { - } - - void setRGBA16(const void* imgRGBA16, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getRGBA16(void* imgRGBA16, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - void setA16(const void* imgA16, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getA16(void* imgA16, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - bool isSingleColorIgnoringAlpha() const; - - const ColorRGBA16* colors() const - { - return m_color; - } - - ColorRGBA16* colors() - { - return m_color; - } - - ColorRGBA16 color(unsigned int i) const - { - return m_color[i]; - } - - ColorRGBA16& color(unsigned int i) - { - return m_color[i]; - } - - private: - static const unsigned int COLOR_COUNT = 4 * 4; - - ColorRGBA16 m_color[COLOR_COUNT]; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h deleted file mode 100644 index 2d5c8eb1e3..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h +++ /dev/null @@ -1,228 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -namespace ImageProcessing -{ - // 32 bit 8888 RGBA color - struct ColorRGBA8 - { - ColorRGBA8() - { - } - - ColorRGBA8(const ColorRGBA8& a_c) - : u(a_c.u) - { - } - - ColorRGBA8(uint8 a_r, uint8 a_g, uint8 a_b, uint8 a_a) - : r(a_r) - , g(a_g) - , b(a_b) - , a(a_a) - { - } - - explicit ColorRGBA8(uint32 a_u) - : u(a_u) - { - } - - void setRGBA(uint8 a_r, uint8 a_g, uint8 a_b, uint8 a_a) - { - r = a_r; - g = a_g; - b = a_b; - a = a_a; - } - - void setRGBA(const uint8* a_pRGBA8) - { - r = a_pRGBA8[0]; - g = a_pRGBA8[1]; - b = a_pRGBA8[2]; - a = a_pRGBA8[3]; - } - - void getRGBA(uint8& a_r, uint8& a_g, uint8& a_b, uint8& a_a) const - { - a_r = r; - a_g = g; - a_b = b; - a_a = a; - } - - void getRGBA(uint8* a_pRGBA8) const - { - a_pRGBA8[0] = r; - a_pRGBA8[1] = g; - a_pRGBA8[2] = b; - a_pRGBA8[3] = a; - } - - union - { - struct - { - uint8 r; - uint8 g; - uint8 b; - uint8 a; - }; - uint32 u; - }; - }; - - // 64 bit 16161616 RGBA color - struct ColorRGBA16 - { - ColorRGBA16() - { - } - - ColorRGBA16(const ColorRGBA16& a_c) - : u(a_c.u) - { - } - - ColorRGBA16(uint16 a_r, uint16 a_g, uint16 a_b, uint16 a_a) - : r(a_r) - , g(a_g) - , b(a_b) - , a(a_a) - { - } - - explicit ColorRGBA16(AZ::u64 a_u) - : u(a_u) - { - } - - void setRGBA(uint16 a_r, uint16 a_g, uint16 a_b, uint16 a_a) - { - r = a_r; - g = a_g; - b = a_b; - a = a_a; - } - - void setRGBA(const uint16* a_pRGBA16) - { - r = a_pRGBA16[0]; - g = a_pRGBA16[1]; - b = a_pRGBA16[2]; - a = a_pRGBA16[3]; - } - - - void getRGBA(uint16& a_r, uint16& a_g, uint16& a_b, uint16& a_a) const - { - a_r = r; - a_g = g; - a_b = b; - a_a = a; - } - - void getRGBA(uint16* a_pRGBA16) const - { - a_pRGBA16[0] = r; - a_pRGBA16[1] = g; - a_pRGBA16[2] = b; - a_pRGBA16[3] = a; - } - - union - { - struct - { - uint16 r; - uint16 g; - uint16 b; - uint16 a; - }; - AZ::u64 u; - }; - }; - - // 128 bit (4 floats) RGBA color - struct ColorRGBAf - { - ColorRGBAf() - { - } - - ColorRGBAf(const ColorRGBAf& a_c) - : r(a_c.r) - , g(a_c.g) - , b(a_c.b) - , a(a_c.a) - { - } - - ColorRGBAf(float a_r, float a_g, float a_b, float a_a) - : r(a_r) - , g(a_g) - , b(a_b) - , a(a_a) - { - } - - void setRGBA(float a_r, float a_g, float a_b, float a_a) - { - r = a_r; - g = a_g; - b = a_b; - a = a_a; - } - - void setRGBA(const float* a_pRGBAf) - { - r = a_pRGBAf[0]; - g = a_pRGBAf[1]; - b = a_pRGBAf[2]; - a = a_pRGBAf[3]; - } - - void getRGBA(float& a_r, float& a_g, float& a_b, float& a_a) const - { - a_r = r; - a_g = g; - a_b = b; - a_a = a; - } - - void getRGBA(float* a_pRGBAf) const - { - a_pRGBAf[0] = r; - a_pRGBAf[1] = g; - a_pRGBAf[2] = b; - a_pRGBAf[3] = a; - } - - union - { - struct - { - float r; - float g; - float b; - float a; - }; - }; - }; - static_assert(sizeof(ColorRGBA8) == 4, "Expected size of ColorRGBA8 to be 4 bytes!"); - static_assert(sizeof(ColorRGBA16) == 8, "Expected size of ColorRGBA16 to be 4 bytes!"); - static_assert(sizeof(ColorRGBAf) == 16, "Expected size of ColorRGBAf to be 4 bytes!"); -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp deleted file mode 100644 index 27bb11a35b..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp +++ /dev/null @@ -1,657 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include -#include "ColorBlockRGBA4x4c.h" -#include "ColorBlockRGBA4x4s.h" -#include "ColorBlockRGBA4x4f.h" -#include "CryTextureSquisher.h" - -#include - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wnull-dereference" -# pragma clang diagnostic ignored "-Wsometimes-uninitialized" -# pragma clang diagnostic ignored "-Wshift-negative-value" -#endif - -#if AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL -#define __fastcall -#define _fastcall -#define __assume(x) -#endif - -#include - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif - -// number of bytes per block per type -#define BLOCKSIZE_BC1 8 -#define BLOCKSIZE_BC2 16 -#define BLOCKSIZE_BC3 16 -#define BLOCKSIZE_BC4 8 -#define BLOCKSIZE_BC5 16 -#define BLOCKSIZE_BC6 16 -#define BLOCKSIZE_BC7 16 -#define BLOCKSIZE_CTX1 8 -#define BLOCKSIZE_LIMIT 16 - -#define PTROFFSET_R 0 -#define PTROFFSET_G 1 -#define PTROFFSET_B 2 -#define PTROFFSET_A 3 - -namespace ImageProcessing -{ - AZStd::mutex s_squishLock; - - -/* ------------------------------------------------------------------------------------------------------------- - * internal presets - */ - static struct ParameterMatrix - { - int flagsBaseline; - int flagsUniform; - int flagsPerceptual; - int flagsQuality[CryTextureSquisher::EQualityProfile::eQualityProfile_Num]; - - size_t offset; - bool alphaOnly; - } P2P[] = - { - // eCompressorPreset_BC1U, - { - squish::kBtc1 + squish::kExcludeAlphaFromPalette, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_BC2U, - { - squish::kBtc2, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_BC3U, - { - squish::kBtc3, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit + squish::kAlphaIterativeFit, squish::kColourIterativeClusterFit + squish::kAlphaIterativeFit, squish::kColourIterativeClusterFit + squish::kAlphaIterativeFit }, - - 0, false - }, - // eCompressorPreset_BC4U, - { - squish::kBtc4, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_R, false - }, - // eCompressorPreset_BC5U, - { - squish::kBtc5, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_R, false - }, - // eCompressorPreset_BC6UH, - { - squish::kBtc6, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourRangeFit }, - - 0, false - }, - // eCompressorPreset_BC7U, - { - squish::kBtc7, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - - // eCompressorPreset_BC4S, - { - squish::kBtc4 + squish::kSignedInternal, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_R, false - }, - // eCompressorPreset_BC5S, - { - squish::kBtc5 + squish::kSignedInternal, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_R, false - }, - - // eCompressorPreset_BC1Un, - { - squish::kBtc1 + squish::kExcludeAlphaFromPalette, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit }, - - 0, false - }, - // eCompressorPreset_BC2Un, - { - squish::kBtc2, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit }, - - 0, false - }, - // eCompressorPreset_BC3Un, - { - squish::kBtc3, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit + squish::kAlphaIterativeFit, squish::kNormalRangeFit + squish::kAlphaIterativeFit, squish::kNormalRangeFit + squish::kAlphaIterativeFit }, - - 0, false - }, - // eCompressorPreset_BC4Un, - { - squish::kBtc4, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_B, false - }, - // eCompressorPreset_BC5Un, - { - squish::kBtc5, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { 0, 0, squish::kNormalIterativeFit, squish::kNormalIterativeFit }, - - PTROFFSET_R, false - }, - // eCompressorPreset_BC6UHn, - { - squish::kBtc6, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit }, - - 0, false - }, - // eCompressorPreset_BC7Un, - { - squish::kBtc7, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - - // eCompressorPreset_BC4Sn, - { - squish::kBtc4 + squish::kSignedInternal, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_B, false - }, - // eCompressorPreset_BC5Sn, - { - squish::kBtc5 + squish::kSignedInternal, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { 0, 0, squish::kNormalIterativeFit, squish::kNormalIterativeFit }, - - PTROFFSET_R, false - }, - - // eCompressorPreset_BC1Ua, - { - squish::kBtc1 + squish::kWeightColourByAlpha, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_BC2Ut, - { - squish::kBtc2 + squish::kWeightColourByAlpha, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_BC3Ut, - { - squish::kBtc3 + squish::kWeightColourByAlpha, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit + squish::kAlphaIterativeFit, squish::kColourIterativeClusterFit + squish::kAlphaIterativeFit, squish::kColourIterativeClusterFit + squish::kAlphaIterativeFit }, - - 0, false - }, - // eCompressorPreset_BC4Ua, - { - squish::kBtc4, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_A, true - }, - // eCompressorPreset_BC7Ut - { - squish::kBtc7 + squish::kWeightColourByAlpha, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - - // eCompressorPreset_BC4Sa, - { - squish::kBtc4 + squish::kSignedInternal, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_A, true - }, - - // eCompressorPreset_BC7Ug - { - squish::kBtc7, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourClusterFit * 15, squish::kColourClusterFit * 15 }, - - 0, false - }, - - // eCompressorPreset_CTX1U - { - squish::kCtx1, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_CTX1Un - { - squish::kCtx1, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit }, - - 0, false - }, - }; - - /* ------------------------------------------------------------------------------------------------------------- - * compression functions - */ - void CryTextureSquisher::Compress(const CryTextureSquisher::CompressorParameters& compress) - { - const unsigned int w = compress.width; - const unsigned int h = compress.height; - const size_t offset = P2P[compress.preset].offset; - int flags = P2P[compress.preset].flagsBaseline + P2P[compress.preset].flagsQuality[compress.quality] + - (!compress.perceptual ? P2P[compress.preset].flagsUniform : P2P[compress.preset].flagsPerceptual); - const bool bAlphaOnly = P2P[compress.preset].alphaOnly; - - squish::sqio::dtp datatype; - switch (compress.srcType) - { - case eBufferType_sint8: - flags += squish::kSignedExternal; - case eBufferType_uint8: - datatype = squish::sqio::dtp::DT_U8; - break; - case eBufferType_sint16: - flags += squish::kSignedExternal; - case eBufferType_uint16: - datatype = squish::sqio::dtp::DT_U16; - break; - case eBufferType_sfloat: - flags += squish::kSignedExternal; - case eBufferType_ufloat: - datatype = squish::sqio::dtp::DT_F23; - break; - default: - __assume(0); - break; - } - - if (compress.perceptual && (flags & squish::kColourMetricPerceptual)) - { - flags |= squish::kColourMetricCustom; - } - - const struct squish::sqio sqio = squish::GetSquishIO(w, h, datatype, flags); - - if (compress.perceptual && (flags & squish::kColourMetricPerceptual)) - { - s_squishLock.lock(); - } - if (compress.perceptual && (flags & squish::kColourMetricPerceptual)) - { - squish::SetWeights(sqio.flags, &compress.weights[0]); - } - - AZ_Assert(!(h & 3), "%s: Unexpected compress parameter of height", __FUNCTION__); - - switch (compress.srcType) - { - // compress an unsigned 8bit texture -------------------------------------------------- - // compress a signed 8bit texture ----------------------------------------------------- - case eBufferType_uint8: - case eBufferType_sint8: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - ColorBlockRGBA4x4c srcBlock; - uint8 dstBlock[BLOCKSIZE_LIMIT]; - - uint8* const targetBlock = dstBlock; - const uint8* const sourceRgba = (const uint8*)srcBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (!bAlphaOnly) - { - srcBlock.setRGBA8(compress.srcBuffer, w, h, compress.pitch, x, y); - } - else - { - srcBlock.setA8(compress.srcBuffer, w, h, compress.pitch, x, y); - } - - sqio.encoder(sourceRgba, 0xFFFF, targetBlock, sqio.flags); - - if (compress.userOutputFunction) - { - compress.userOutputFunction(compress, targetBlock, sqio.blocksize, y >> 2, x >> 2); - } - } - } - } - break; - // compress an unsigned 16bit texture ------------------------------------------------- - // compress a signed 16bit texture ---------------------------------------------------- - case eBufferType_uint16: - case eBufferType_sint16: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - ColorBlockRGBA4x4s srcBlock; - uint8 dstBlock[BLOCKSIZE_LIMIT]; - - uint8* const targetBlock = dstBlock; - const float* const sourceRgba = (const float*)srcBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (!bAlphaOnly) - { - srcBlock.setRGBA16(compress.srcBuffer, w, h, compress.pitch, x, y); - } - else - { - srcBlock.setA16(compress.srcBuffer, w, h, compress.pitch, x, y); - } - - sqio.encoder(sourceRgba, 0xFFFF, targetBlock, sqio.flags); - - if (compress.userOutputFunction) - { - compress.userOutputFunction(compress, targetBlock, sqio.blocksize, y >> 2, x >> 2); - } - } - } - } - break; - // compress an unsigned floating point texture ---------------------------------------- - // compress a signed floating point texture ------------------------------------------- - case eBufferType_ufloat: - case eBufferType_sfloat: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - ColorBlockRGBA4x4f srcBlock; - uint8 dstBlock[BLOCKSIZE_LIMIT]; - - uint8* const targetBlock = dstBlock; - const float* const sourceRgba = (const float*)srcBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (!bAlphaOnly) - { - srcBlock.setRGBAf(compress.srcBuffer, w, h, compress.pitch, x, y); - } - else - { - srcBlock.setAf(compress.srcBuffer, w, h, compress.pitch, x, y); - } - - sqio.encoder(sourceRgba, 0xFFFF, targetBlock, sqio.flags); - - if (compress.userOutputFunction) - { - compress.userOutputFunction(compress, targetBlock, sqio.blocksize, y >> 2, x >> 2); - } - } - } - } - break; - default: - AZ_Assert(false, "%s: Unexpected compress source type", __FUNCTION__); - break; - } - - if (compress.perceptual && (flags & squish::kColourMetricPerceptual)) - { - s_squishLock.unlock(); - } - } - - void CryTextureSquisher::Decompress(const DecompressorParameters& decompress) - { - const unsigned int w = decompress.width; - const unsigned int h = decompress.height; - const size_t offset = P2P[decompress.preset].offset; - int flags = P2P[decompress.preset].flagsBaseline + - P2P[decompress.preset].flagsUniform; - const bool bAlphaOnly = P2P[decompress.preset].alphaOnly; - - squish::sqio::dtp datatype; - switch (decompress.dstType) - { - case eBufferType_sint8: - flags += squish::kSignedExternal; - case eBufferType_uint8: - datatype = squish::sqio::dtp::DT_U8; - break; - case eBufferType_sint16: - flags += squish::kSignedExternal; - case eBufferType_uint16: - datatype = squish::sqio::dtp::DT_U16; - break; - case eBufferType_sfloat: - flags += squish::kSignedExternal; - case eBufferType_ufloat: - datatype = squish::sqio::dtp::DT_F23; - break; - default: - __assume(0); - break; - } - - const struct squish::sqio sqio = squish::GetSquishIO(w, h, datatype, flags); - - AZ_Assert(!(h & 3), "%s: Unexpected compress parameter of height", __FUNCTION__); - - switch (decompress.dstType) - { - // decompress an unsigned 8bit texture -------------------------------------------------- - // decompress a signed 8bit texture ----------------------------------------------------- - case eBufferType_uint8: - case eBufferType_sint8: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - uint8 srcBlock[BLOCKSIZE_LIMIT]; - ColorBlockRGBA4x4c dstBlock; - - uint8* const sourceBlock = srcBlock; - uint8* const targetRgba = (uint8*)dstBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (decompress.userInputFunction) - { - decompress.userInputFunction(decompress, sourceBlock, sqio.blocksize, y >> 2, x >> 2); - } - - if (!bAlphaOnly) - { - dstBlock.setRGBA8(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - - sqio.decoder(targetRgba, sourceBlock, sqio.flags); - - if (!bAlphaOnly) - { - dstBlock.getRGBA8(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - else - { - dstBlock.getA8(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - } - } - } - break; - // decompress an unsigned 16bit texture ------------------------------------------------- - // decompress a signed 16bit texture ---------------------------------------------------- - case eBufferType_uint16: - case eBufferType_sint16: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - uint8 srcBlock[BLOCKSIZE_LIMIT]; - ColorBlockRGBA4x4s dstBlock; - - uint8* const sourceBlock = srcBlock; - uint16* const targetRgba = (uint16*)dstBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (decompress.userInputFunction) - { - decompress.userInputFunction(decompress, sourceBlock, sqio.blocksize, y >> 2, x >> 2); - } - - if (!bAlphaOnly) - { - dstBlock.setRGBA16(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - - sqio.decoder(targetRgba, sourceBlock, sqio.flags); - - if (!bAlphaOnly) - { - dstBlock.setRGBA16(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - else - { - dstBlock.getA16(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - } - } - } - break; - // decompress an unsigned floating point texture ---------------------------------------- - // decompress a signed floating point texture ------------------------------------------- - case eBufferType_ufloat: - case eBufferType_sfloat: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - uint8 srcBlock[BLOCKSIZE_LIMIT]; - ColorBlockRGBA4x4f dstBlock; - - uint8* const sourceBlock = srcBlock; - float* const targetRgba = (float*)dstBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (decompress.userInputFunction) - { - decompress.userInputFunction(decompress, sourceBlock, sqio.blocksize, y >> 2, x >> 2); - } - - if (!bAlphaOnly) - { - dstBlock.setRGBAf(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - sqio.decoder(targetRgba, sourceBlock, sqio.flags); - - if (!bAlphaOnly) - { - dstBlock.getRGBAf(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - else - { - dstBlock.getAf(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - } - } - } - break; - default: - AZ_Assert(false, "%s: Unexpected compress destination type", __FUNCTION__); - break; - } - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.h deleted file mode 100644 index 2aa7117d46..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -namespace ImageProcessing -{ - class CryTextureSquisher - { - public: - enum EBufferType - { - eBufferType_uint8, // native support: BC1-5/7,CTX1 - eBufferType_sint8, // native support: BC4-5 - eBufferType_uint16, // native support: BC1-7,CTX1 - eBufferType_sint16, // native support: BC4-6 - eBufferType_ufloat, // native support: BC1-7,CTX1 - eBufferType_sfloat, // native support: BC4-6 - }; - - enum EQualityProfile - { - eQualityProfile_Low = 0,// as-fast-as-possible - eQualityProfile_Medium, // not so bad (nightly builds) - eQualityProfile_High, // relative good (weekly builds) - eQualityProfile_Best, // as-best-as-possible (final build for release) - - eQualityProfile_Num - }; - - enum ECodingPreset - { - eCompressorPreset_BC1U = 0, - eCompressorPreset_BC2U, - eCompressorPreset_BC3U, - eCompressorPreset_BC4U, // r-channel from RGBA - eCompressorPreset_BC5U, // rg-channels from RGBA - eCompressorPreset_BC6UH, - eCompressorPreset_BC7U, - - eCompressorPreset_BC4S, // r-channel from RGBA - eCompressorPreset_BC5S, // rg-channels from RGBA - - // normal vectors -> unit metric - eCompressorPreset_BC1Un, - eCompressorPreset_BC2Un, - eCompressorPreset_BC3Un, - eCompressorPreset_BC4Un, // z-channel from XYZD - eCompressorPreset_BC5Un, // xy-channels from XYZD, xyz must be a valid unit-vector - eCompressorPreset_BC6UHn, - eCompressorPreset_BC7Un, - - eCompressorPreset_BC4Sn, // z-channel from XYZD - eCompressorPreset_BC5Sn, // xy-channels from XYZD, xyz must be a valid unit-vector - - // transparency -> weighted alpha - eCompressorPreset_BC1Ua, - eCompressorPreset_BC2Ut, - eCompressorPreset_BC3Ut, - eCompressorPreset_BC4Ua, // a-channel from RGBA - eCompressorPreset_BC7Ut, - - eCompressorPreset_BC4Sa, // a-channel from RGBA - - // grey-scale -> 12+ bits of precision - eCompressorPreset_BC7Ug, - - // special ones - eCompressorPreset_CTX1U, // rg-channels from RGBA - eCompressorPreset_CTX1Un, // xy-channels from XYZD, xyz must be a valid unit-vector - - eCompressorPreset_Num - }; - - struct CompressorParameters - { - // source's parameters - EBufferType srcType; - const void* srcBuffer; - unsigned int width; - unsigned int height; - unsigned int pitch; - - // coding preset - ECodingPreset preset; - EQualityProfile quality; - - // either if "srgb==1" or if "rgbweights!=uniform" - bool perceptual; - float weights[4]; - - void* userPtr; - int userInt; - - void(*userOutputFunction)(const CompressorParameters& compress, const void* compressedData, unsigned int compressedSize, unsigned int oy, unsigned int ox); - }; - - struct DecompressorParameters - { - // destination's parameters - EBufferType dstType; - void* dstBuffer; - unsigned int width; - unsigned int height; - unsigned int pitch; - - // coding preset - ECodingPreset preset; - - void* userPtr; - int userInt; - - void(*userInputFunction)(const DecompressorParameters& decompress, void* compressedData, unsigned int compressedSize, unsigned int oy, unsigned int ox); - }; - - public: - static void Compress(const CompressorParameters& compress); - static void Decompress(const DecompressorParameters& decompress); - }; - -} //namespace ImageProcessing - diff --git a/Gems/ImageProcessing/Code/Source/Compressors/ETC2.cpp b/Gems/ImageProcessing/Code/Source/Compressors/ETC2.cpp deleted file mode 100644 index 3d43fe7dda..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/ETC2.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace ImageProcessing -{ - //limited to 1 thread because AP requires so. We may change to n when AP allocate n thread to a job in the furture - static const int MAX_COMP_JOBS = 1; - static const int MIN_COMP_JOBS = 1; - static const float ETC_LOW_EFFORT_LEVEL = 25.0f; - static const float ETC_MED_EFFORT_LEVEL = 40.0f; - static const float ETC_HIGH_EFFORT_LEVEL = 80.0f; - - //Grab the Etc2Comp specific pixel format enum - static Etc::Image::Format FindEtc2PixelFormat(EPixelFormat fmt) - { - switch (fmt) - { - case ePixelFormat_EAC_RG11: - return Etc::Image::Format::RG11; - case ePixelFormat_EAC_R11: - return Etc::Image::Format::R11; - case ePixelFormat_ETC2: - return Etc::Image::Format::RGB8; - case ePixelFormat_ETC2a: - return Etc::Image::Format::RGBA8; - default: - return Etc::Image::Format::FORMATS; - } - } - - //Get the errmetric required for the compression - static Etc::ErrorMetric FindErrMetric(Etc::Image::Format fmt) - { - switch (fmt) - { - case Etc::Image::Format::RG11: - return Etc::ErrorMetric::NORMALXYZ; - case Etc::Image::Format::R11: - return Etc::ErrorMetric::NUMERIC; - case Etc::Image::Format::RGB8: - return Etc::ErrorMetric::RGBX; - case Etc::Image::Format::RGBA8: - return Etc::ErrorMetric::RGBA; - default: - return Etc::ErrorMetric::ERROR_METRICS; - } - - } - - //Convert to sRGB format - static Etc::Image::Format FindGammaEtc2PixelFormat(Etc::Image::Format fmt) - { - switch (fmt) - { - case Etc::Image::Format::RGB8: - return Etc::Image::Format::SRGB8; - case Etc::Image::Format::RGBA8: - return Etc::Image::Format::SRGBA8; - case Etc::Image::Format::RGB8A1: - return Etc::Image::Format::SRGB8A1; - default: - return Etc::Image::Format::FORMATS; - } - } - - bool ETC2Compressor::IsCompressedPixelFormatSupported(EPixelFormat fmt) - { - return (FindEtc2PixelFormat(fmt) != Etc::Image::Format::FORMATS); - } - - bool ETC2Compressor::IsUncompressedPixelFormatSupported(EPixelFormat fmt) - { - //for uncompress format - if (fmt == ePixelFormat_R8G8B8A8) - { - return true; - } - return false; - } - - EPixelFormat ETC2Compressor::GetSuggestedUncompressedFormat([[maybe_unused]] EPixelFormat compressedfmt, [[maybe_unused]] EPixelFormat uncompressedfmt) - { - return ePixelFormat_R8G8B8A8; - } - - bool ETC2Compressor::DoesSupportDecompress([[maybe_unused]] EPixelFormat fmtDst) - { - return false; - } - - IImageObjectPtr ETC2Compressor::CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, - const CompressOption *compressOption) - { - const size_t srcPixelSize = 4; - - //validate input - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); - - //src format need to be uncompressed and dst format need to compressed. - if (!IsUncompressedPixelFormatSupported(fmtSrc) || !IsCompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - //determinate compression quality - ICompressor::EQuality quality = ICompressor::eQuality_Normal; - //get setting from compression option - if (compressOption) - { - quality = compressOption->compressQuality; - } - - float qualityEffort = 0.0f; - switch (quality) - { - case eQuality_Preview: - case eQuality_Fast: - { - qualityEffort = ETC_LOW_EFFORT_LEVEL; - break; - } - case eQuality_Normal: - { - qualityEffort = ETC_MED_EFFORT_LEVEL; - break; - } - default: - { - qualityEffort = ETC_HIGH_EFFORT_LEVEL; - } - } - - Etc::Image::Format dstEtc2Format = FindEtc2PixelFormat(fmtDst); - if (srcImage->GetImageFlags() & EIF_SRGBRead) - { - dstEtc2Format = FindGammaEtc2PixelFormat(dstEtc2Format); - } - - //use to read pixel data from src image - IPixelOperationPtr pixelOp = CreatePixelOperation(fmtSrc); - //get count of bytes per pixel for images - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtSrc)->bitsPerBlock / 8; - - const AZ::u32 mipCount = dstImage->GetMipCount(); - for (AZ::u32 mip = 0; mip < mipCount; ++mip) - { - const AZ::u32 width = srcImage->GetWidth(mip); - const AZ::u32 height = srcImage->GetHeight(mip); - - // Prepare source data - AZ::u8* srcMem; - AZ::u32 srcPitch; - srcImage->GetImagePointer(mip, srcMem, srcPitch); - const AZ::u32 pixelCount = srcImage->GetPixelCount(mip); - - Etc::ColorFloatRGBA* rgbaPixels = new Etc::ColorFloatRGBA[pixelCount]; - Etc::ColorFloatRGBA* rgbaPixelPtr = rgbaPixels; - float r, g, b, a; - for (AZ::u32 pixelIdx = 0; pixelIdx < pixelCount; pixelIdx++, srcMem += pixelBytes, rgbaPixelPtr++) - { - pixelOp->GetRGBA(srcMem, r, g, b, a); - rgbaPixelPtr->fA = a; - rgbaPixelPtr->fR = r; - rgbaPixelPtr->fG = g; - rgbaPixelPtr->fB = b; - } - - //Call into etc2Comp lib to compress. https://medium.com/@duhroach/building-a-blazing-fast-etc2-compressor-307f3e9aad99 - Etc::ErrorMetric errMetric = FindErrMetric(dstEtc2Format); - unsigned char* paucEncodingBits; - unsigned int uiEncodingBitsBytes; - unsigned int uiExtendedWidth; - unsigned int uiExtendedHeight; - int iEncodingTime_ms; - - Etc::Encode(reinterpret_cast(rgbaPixels), - width, height, - dstEtc2Format, - errMetric, - qualityEffort, - MIN_COMP_JOBS, - MAX_COMP_JOBS, - &paucEncodingBits, &uiEncodingBitsBytes, - &uiExtendedWidth, &uiExtendedHeight, - &iEncodingTime_ms); - - AZ::u8* dstMem; - AZ::u32 dstPitch; - dstImage->GetImagePointer(mip, dstMem, dstPitch); - - memcpy(dstMem, paucEncodingBits, uiEncodingBitsBytes); - delete[] rgbaPixels; - } - - return dstImage; - } - - IImageObjectPtr ETC2Compressor::DecompressImage(IImageObjectPtr srcImage, [[maybe_unused]] EPixelFormat fmtDst) - { - //etc2Comp doesn't support decompression - //Since PVRTexLib support ETC formats too. It may take over the decompression. - return nullptr; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/ETC2.h b/Gems/ImageProcessing/Code/Source/Compressors/ETC2.h deleted file mode 100644 index d862bead68..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/ETC2.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - class ETC2Compressor : public ICompressor - { - public: - static bool IsCompressedPixelFormatSupported(EPixelFormat fmt); - static bool IsUncompressedPixelFormatSupported(EPixelFormat fmt); - static bool DoesSupportDecompress(EPixelFormat fmtDst); - - IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption *compressOption) override; - IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) override; - - EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) override; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp b/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp deleted file mode 100644 index 64fee3b747..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include - -#if AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT -//_WINDLL_IMPORT need to be defined before including PVRTexLib header files to avoid linking error on windows. -#define _WINDLL_IMPORT -// NOMINMAX needs to be defined before including PVRTexLib header files (which include Windows.h) -// so that Windows.h doesn't define min/max. Otherwise, a compile error may arise in Uber builds -#ifndef NOMINMAX -#define NOMINMAX -#endif -#endif -#include -#include - - -namespace ImageProcessing -{ - // Note: PVRTexLib supports ASTC formats, ETC formats, PVRTC formats and BC formats - // We haven't tested the performace to compress BC formats compare to CTSquisher - // For PVRTC formats, we only added PVRTC 1 support for now - // The compression for ePVRTPF_EAC_R11 and ePVRTPF_EAC_RG11 are very slow. It takes 7 and 14 minutes for a 2048x2048 texture. - EPVRTPixelFormat FindPvrPixelFormat(EPixelFormat fmt) - { - switch (fmt) - { - case ePixelFormat_ASTC_4x4: - return ePVRTPF_ASTC_4x4; - case ePixelFormat_ASTC_5x4: - return ePVRTPF_ASTC_5x4; - case ePixelFormat_ASTC_5x5: - return ePVRTPF_ASTC_5x5; - case ePixelFormat_ASTC_6x5: - return ePVRTPF_ASTC_6x5; - case ePixelFormat_ASTC_6x6: - return ePVRTPF_ASTC_6x6; - case ePixelFormat_ASTC_8x5: - return ePVRTPF_ASTC_8x5; - case ePixelFormat_ASTC_8x6: - return ePVRTPF_ASTC_8x6; - case ePixelFormat_ASTC_8x8: - return ePVRTPF_ASTC_8x8; - case ePixelFormat_ASTC_10x5: - return ePVRTPF_ASTC_10x5; - case ePixelFormat_ASTC_10x6: - return ePVRTPF_ASTC_10x6; - case ePixelFormat_ASTC_10x8: - return ePVRTPF_ASTC_10x8; - case ePixelFormat_ASTC_10x10: - return ePVRTPF_ASTC_10x10; - case ePixelFormat_ASTC_12x10: - return ePVRTPF_ASTC_12x10; - case ePixelFormat_ASTC_12x12: - return ePVRTPF_ASTC_12x12; - case ePixelFormat_PVRTC2: - return ePVRTPF_PVRTCI_2bpp_RGBA; - case ePixelFormat_PVRTC4: - return ePVRTPF_PVRTCI_4bpp_RGBA; - case ePixelFormat_EAC_R11: - return ePVRTPF_EAC_R11; - case ePixelFormat_EAC_RG11: - return ePVRTPF_EAC_RG11; - case ePixelFormat_ETC2: - return ePVRTPF_ETC2_RGB; - case ePixelFormat_ETC2a: - return ePVRTPF_ETC2_RGBA; - default: - return ePVRTPF_NumCompressedPFs; - } - } - - bool PVRTCCompressor::IsCompressedPixelFormatSupported(EPixelFormat fmt) - { - return (FindPvrPixelFormat(fmt) != ePVRTPF_NumCompressedPFs); - } - - bool PVRTCCompressor::IsUncompressedPixelFormatSupported(EPixelFormat fmt) - { - //for uncompress format - if (fmt == ePixelFormat_R8G8B8A8) - { - return true; - } - return false; - } - - - EPixelFormat PVRTCCompressor::GetSuggestedUncompressedFormat([[maybe_unused]] EPixelFormat compressedfmt, [[maybe_unused]] EPixelFormat uncompressedfmt) - { - return ePixelFormat_R8G8B8A8; - } - - - bool PVRTCCompressor::DoesSupportDecompress([[maybe_unused]] EPixelFormat fmtDst) - { - return true; - } - - IImageObjectPtr PVRTCCompressor::CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, - const CompressOption *compressOption) - { - //validate input - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); - - //src format need to be uncompressed and dst format need to compressed. - if (!IsUncompressedPixelFormatSupported(fmtSrc) || !IsCompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - //determinate compression quality - pvrtexture::ECompressorQuality internalQuality = pvrtexture::eETCFast; - ICompressor::EQuality quality = ICompressor::eQuality_Normal; - AZ::Vector3 uniformWeights = AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - AZ::Vector3 weights = uniformWeights; - bool isUniform = true; - //get setting from compression option - if (compressOption) - { - quality = compressOption->compressQuality; - weights = compressOption->rgbWeight; - isUniform = (weights == uniformWeights); - } - - if (IsETCFormat(fmtDst)) - { - if ((quality <= eQuality_Normal) && isUniform) - { - internalQuality = pvrtexture::eETCFast; - } - else if (quality <= eQuality_Normal) - { - internalQuality = pvrtexture::eETCNormal; - } - else if (isUniform) - { - internalQuality = pvrtexture::eETCSlow; - } - else - { - internalQuality = pvrtexture::eETCSlow; - } - } - else if (IsASTCFormat(fmtDst)) - { - if (quality == eQuality_Preview) - { - internalQuality = pvrtexture::eASTCVeryFast; - } - else if (quality == eQuality_Fast) - { - internalQuality = pvrtexture::eASTCFast; - } - else if (quality == eQuality_Normal) - { - internalQuality = pvrtexture::eASTCMedium; - } - else - { - internalQuality = pvrtexture::eASTCThorough; - } - } - else - { - if (quality == eQuality_Preview) - { - internalQuality = pvrtexture::ePVRTCFastest; - } - else if (quality == eQuality_Fast) - { - internalQuality = pvrtexture::ePVRTCFast; - } - else if (quality == eQuality_Normal) - { - internalQuality = pvrtexture::ePVRTCNormal; - } - else - { - internalQuality = pvrtexture::ePVRTCHigh; - } - } - - // setup color space - EPVRTColourSpace cspace = ePVRTCSpacelRGB; - if (srcImage->GetImageFlags() & EIF_SRGBRead) - { - cspace = ePVRTCSpacesRGB; - } - - //setup src texture for compression - const pvrtexture::PixelType srcPixelType('r', 'g', 'b', 'a', 8, 8, 8, 8); - const AZ::u32 dstMips = dstImage->GetMipCount(); - for (AZ::u32 mip = 0; mip < dstMips; ++mip) - { - const AZ::u32 width = srcImage->GetWidth(mip); - const AZ::u32 height = srcImage->GetHeight(mip); - - // Prepare source data - AZ::u8* srcMem; - uint32 srcPitch; - srcImage->GetImagePointer(mip, srcMem, srcPitch); - - const pvrtexture::CPVRTextureHeader srcHeader( - srcPixelType.PixelTypeID, // AZ::u64 u64PixelFormat, - width, // uint32 u32Height=1, - height, // uint32 u32Width=1, - 1, // uint32 u32Depth=1, - 1, // uint32 u32NumMipMaps=1, - 1, // uint32 u32NumArrayMembers=1, - 1, // uint32 u32NumFaces=1, - cspace, // EPVRTColourSpace eColourSpace=ePVRTCSpacelRGB, - ePVRTVarTypeUnsignedByteNorm, // EPVRTVariableType eChannelType=ePVRTVarTypeUnsignedByteNorm, - false); // bool bPreMultiplied=false); - - pvrtexture::CPVRTexture compressTexture(srcHeader, srcMem); - - //compressing - bool isSuccess = false; -#if AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - try -#endif // AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - { - isSuccess = pvrtexture::Transcode( - compressTexture, - pvrtexture::PixelType(FindPvrPixelFormat(fmtDst)), - ePVRTVarTypeUnsignedByteNorm, - cspace, - internalQuality); - } -#if AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - catch (...) - { - AZ_Error("Image Processing", false, "Unknown exception in PVRTexLib"); - return nullptr; - } -#endif // AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - - if (!isSuccess) - { - AZ_Error("Image Processing", false, "Failed to compress image with PVRTexLib. You may not have astcenc.exe for compressing ASTC formates"); - return nullptr; - } - - // Getting compressed data - const void* const compressedData = compressTexture.getDataPtr(); - if (!compressedData) - { - AZ_Error("Image Processing", false, "Failed to obtain compressed image data by using PVRTexLib"); - return nullptr; - } - - const AZ::u32 compressedDataSize = compressTexture.getDataSize(); - if (dstImage->GetMipBufSize(mip) != compressedDataSize) - { - AZ_Error("Image Processing", false, "Compressed image data size mismatch while using PVRTexLib"); - return nullptr; - } - - //save compressed data to dst image - AZ::u8* dstMem; - AZ::u32 dstPitch; - dstImage->GetImagePointer(mip, dstMem, dstPitch); - memcpy(dstMem, compressedData, compressedDataSize); - } - - return dstImage; - } - - IImageObjectPtr PVRTCCompressor::DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) - { - //validate input - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); //compressed - - if (!IsCompressedPixelFormatSupported(fmtSrc) || !IsUncompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - EPVRTColourSpace colorSpace = ePVRTCSpacelRGB; - if (srcImage->GetImageFlags() & EIF_SRGBRead) - { - colorSpace = ePVRTCSpacesRGB; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - const AZ::u32 mipCount = dstImage->GetMipCount(); - for (AZ::u32 mip = 0; mip < mipCount; ++mip) - { - const AZ::u32 width = srcImage->GetWidth(mip); - const AZ::u32 height = srcImage->GetHeight(mip); - - // Preparing source compressed data - const pvrtexture::CPVRTextureHeader compressedHeader( - FindPvrPixelFormat(fmtSrc), // AZ::u64 u64PixelFormat, - width, // uint32 u32Height=1, - height, // uint32 u32Width=1, - 1, // uint32 u32Depth=1, - 1, // uint32 u32NumMipMaps=1, - 1, // uint32 u32NumArrayMembers=1, - 1, // uint32 u32NumFaces=1, - colorSpace, // EPVRTColourSpace eColourSpace=ePVRTCSpacelRGB, - ePVRTVarTypeUnsignedByteNorm, // EPVRTVariableType eChannelType=ePVRTVarTypeUnsignedByteNorm, - false); // bool bPreMultiplied=false); - - const AZ::u32 compressedDataSize = compressedHeader.getDataSize(); - if (srcImage->GetMipBufSize(mip) != compressedDataSize) - { - AZ_Error("Image Processing", false, "Decompressed image data size mismatch while using PVRTexLib"); - return nullptr; - } - - AZ::u8* srcMem; - AZ::u32 srcPitch; - srcImage->GetImagePointer(mip, srcMem, srcPitch); - pvrtexture::CPVRTexture cTexture(compressedHeader, srcMem); - - // Decompress - bool bOk = false; -#if AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - try - { -#endif // AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - bOk = pvrtexture::Transcode( - cTexture, - pvrtexture::PVRStandard8PixelType, - ePVRTVarTypeUnsignedByteNorm, - colorSpace, - pvrtexture::ePVRTCHigh); - -#if AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - } - catch (...) - { - AZ_Error("Image Processing", false, "Unknown exception in PVRTexLib when decompressing"); - return nullptr; - } -#endif // AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - - if (!bOk) - { - AZ_Error("Image Processing", false, "Failed to decompress an image by using PVRTexLib"); - return nullptr; - } - - // Getting decompressed data - const void* const pDecompressedData = cTexture.getDataPtr(); - if (!pDecompressedData) - { - AZ_Error("Image Processing", false, "Failed to obtain decompressed image data by using PVRTexLib"); - return nullptr; - } - - const AZ::u32 decompressedDataSize = cTexture.getDataSize(); - if (dstImage->GetMipBufSize(mip) != decompressedDataSize) - { - AZ_Error("Image Processing", false, "Decompressed image data size mismatch while using PVRTexLib"); - return nullptr; - } - - //save decompressed image to dst image - AZ::u8* dstMem; - AZ::u32 dstPitch; - dstImage->GetImagePointer(mip, dstMem, dstPitch); - memcpy(dstMem, pDecompressedData, decompressedDataSize); - } - - return dstImage; - } - -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.h b/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.h deleted file mode 100644 index 648990a819..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - class PVRTCCompressor : public ICompressor - { - public: - static bool IsCompressedPixelFormatSupported(EPixelFormat fmt); - static bool IsUncompressedPixelFormatSupported(EPixelFormat fmt); - static bool DoesSupportDecompress(EPixelFormat fmtDst); - - IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption *compressOption) override; - IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) override; - - EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) override; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/AlphaCoverage.cpp b/Gems/ImageProcessing/Code/Source/Converters/AlphaCoverage.cpp deleted file mode 100644 index 46444d8d87..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/AlphaCoverage.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include - -/////////////////////////////////////////////////////////////////////////////////// -//functions for maintaining alpha coverage. - -namespace ImageProcessing -{ - void CImageObject::TransferAlphaCoverage(const TextureSettings* textureSetting, const IImageObjectPtr srcImg) - { - EPixelFormat srcFmt = srcImg->GetPixelFormat(); - //both this image and src image need to be uncompressed - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat) - || !CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcFmt)) - { - AZ_Assert(false, "Both source image and dest image need to be uncompressed"); - return; - } - - const float fAlphaRef = 0.5f; // Seems to give good overall results - const float fDesiredAlphaCoverage = srcImg->ComputeAlphaCoverage(0, fAlphaRef); - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - for (uint32 mip = 0; mip < GetMipCount(); mip++) - { - const float fAlphaOffset = textureSetting->ComputeMIPAlphaOffset(mip); - const float fAlphaScale = ComputeAlphaCoverageScaleFactor(mip, fDesiredAlphaCoverage, fAlphaRef); - - AZ::u8* pixelBuf = m_mips[mip]->m_pData; - const AZ::u32 pixelCount = GetPixelCount(mip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - float r, g, b, a; - pixelOp->GetRGBA(pixelBuf, r, g, b, a); - a = AZ::GetMin(a * fAlphaScale + fAlphaOffset, 1.0f); - pixelOp->SetRGBA(pixelBuf, r, g, b, a); - } - } - } - - float CImageObject::ComputeAlphaCoverageScaleFactor(AZ::u32 mip, float fDesiredCoverage, float fAlphaRef) const - { - float minAlphaRef = 0.0f; - float maxAlphaRef = 1.0f; - float midAlphaRef = 0.5f; - - // Find best alpha test reference value using a binary search - for (int i = 0; i < 10; i++) - { - const float currentCoverage = ComputeAlphaCoverage(mip, midAlphaRef); - - if (currentCoverage > fDesiredCoverage) - { - minAlphaRef = midAlphaRef; - } - else if (currentCoverage < fDesiredCoverage) - { - maxAlphaRef = midAlphaRef; - } - else - { - break; - } - - midAlphaRef = (minAlphaRef + maxAlphaRef) * 0.5f; - } - - return fAlphaRef / midAlphaRef; - } - - float CImageObject::ComputeAlphaCoverage(AZ::u32 mip, float fAlphaRef) const - { - //This function only works with uncompressed image - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat)) - { - AZ_Assert(false, "This image need to be uncompressed"); - return 0; - } - - uint32 coverage = 0; - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - AZ::u8* pixelBuf = m_mips[mip]->m_pData; - const AZ::u32 pixelCount = GetPixelCount(mip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - float r, g, b, a; - pixelOp->GetRGBA(pixelBuf, r, g, b, a); - coverage += a > fAlphaRef; - } - - return (float)coverage / (float)(pixelCount); - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/ColorChart.cpp b/Gems/ImageProcessing/Code/Source/Converters/ColorChart.cpp deleted file mode 100644 index 63067a57b5..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/ColorChart.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include - -namespace ImageProcessing -{ - const int COLORCHART_IMAGE_WIDTH = 78; - const int COLORCHART_IMAGE_HEIGHT = 66; - - // color chart in cry engine is a special image data, with size 78x66, you may see in game screenshot which is defined by a rectangle - // area with a yellow-black dash line boarder - // Create color chart function is to read that block of image data and convert it to a color table then save it to another image - // with size 256x16. - - class C3dLutColorChart - { - public: - C3dLutColorChart() {} - ~C3dLutColorChart() {}; - - //generate default color chart data - void GenerateDefault(); - - //generate color chart data from input image - bool GenerateFromInput(IImageObjectPtr image); - - //ouput the color chart data to an image object - IImageObjectPtr GenerateChartImage(); - - protected: - //extract color chart data from specified location in an image - void ExtractFromImageAt(IImageObjectPtr pImg, AZ::u32 x, AZ::u32 y); - - //find color chart location in an image - static bool FindColorChart(const IImageObjectPtr pImg, AZ::u32& outLocX, AZ::u32& outLocY); - - //if there is a color chart at specified location - static bool IsColorChartAt(AZ::u32 x, AZ::u32 y, void* pData, AZ::u32 pitch); - - private: - enum EPrimaryShades - { - ePS_Red = 16, - ePS_Green = 16, - ePS_Blue = 16, - - ePS_NumColors = ePS_Red * ePS_Green * ePS_Blue - }; - - struct SColor - { - unsigned char r, g, b, _padding; - }; - - typedef AZStd::vector ColorMapping; - - ColorMapping m_mapping; - }; - - void C3dLutColorChart::GenerateDefault() - { - m_mapping.reserve(ePS_NumColors); - - for (int b = 0; b < ePS_Blue; ++b) - { - for (int g = 0; g < ePS_Green; ++g) - { - for (int r = 0; r < ePS_Red; ++r) - { - SColor col; - col.r = 255 * r / (ePS_Red); - col.g = 255 * g / (ePS_Green); - col.b = 255 * b / (ePS_Blue); - int l = 255 - (col.r * 3 + col.g * 6 + col.b) / 10; - col.r = col.g = col.b = (unsigned char)l; - m_mapping.push_back(col); - } - } - } - } - - //find color chart location in a image - bool C3dLutColorChart::FindColorChart(const IImageObjectPtr pImg, AZ::u32& outLocX, AZ::u32& outLocY) - { - const AZ::u32 width = pImg->GetWidth(0); - const AZ::u32 height = pImg->GetHeight(0); - - //the origin image is too small to have a color chart - if (width < COLORCHART_IMAGE_WIDTH || height < COLORCHART_IMAGE_HEIGHT) - { - return false; - } - - AZ::u8* pData; - AZ::u32 pitch; - pImg->GetImagePointer(0, pData, pitch); - - //check all the posible start location on whether there might be a color chart - for (AZ::u32 y = 0; y <= height - COLORCHART_IMAGE_HEIGHT; ++y) - { - for (AZ::u32 x = 0; x <= width - COLORCHART_IMAGE_WIDTH; ++x) - { - if (IsColorChartAt(x, y, pData, pitch)) - { - outLocX = x; - outLocY = y; - return true; - } - } - } - - return false; - } - - bool C3dLutColorChart::GenerateFromInput(IImageObjectPtr image) - { - AZ::u32 outLocX, outLocY; - if (FindColorChart(image, outLocX, outLocY)) - { - ExtractFromImageAt(image, outLocX, outLocY); - return true; - } - return false; - } - - IImageObjectPtr C3dLutColorChart::GenerateChartImage() - { - const AZ::u32 mipCount = 1; - IImageObjectPtr image( IImageObject::CreateImage(ePS_Red * ePS_Blue, ePS_Green, 1, ePixelFormat_R8G8B8A8)); - - { - AZ::u8* pData; - AZ::u32 pitch; - image->GetImagePointer(0, pData, pitch); - - size_t nSlicePitch = (pitch / ePS_Blue); - AZ::u32 src = 0; - for (int b = 0; b < ePS_Blue; ++b) - { - for (int g = 0; g < ePS_Green; ++g) - { - - AZ::u8* p = pData + g * pitch + b * nSlicePitch; - for (int r = 0; r < ePS_Red; ++r) - { - const SColor& c = m_mapping[src]; - p[0] = c.r; - p[1] = c.g; - p[2] = c.b; - p[3] = 255; - ++src; - p += 4; - } - } - } - } - - return image; - } - - void C3dLutColorChart::ExtractFromImageAt(IImageObjectPtr image, AZ::u32 x, AZ::u32 y) - { - int ox = x + 1; - int oy = y + 1; - - AZ::u8* pData; - AZ::u32 pitch; - image->GetImagePointer(0, pData, pitch); - - m_mapping.reserve(ePS_NumColors); - - for (int b = 0; b < ePS_Blue; ++b) - { - int px = ox + ePS_Red * (b % 4); - int py = oy + ePS_Green * (b / 4); - - for (int g = 0; g < ePS_Green; ++g) - { - for (int r = 0; r < ePS_Red; ++r) - { - AZ::u8* p = pData + pitch * (py + g) + (px + r) * 4; - - SColor col; - col.r = p[0]; - col.g = p[1]; - col.b = p[2]; - m_mapping.push_back(col); - } - } - } - } - - //check if image data at location x and y could be a color chart - //based on if the boarder is dash lines with two pixel each segement - //the idea and implementation are both coming from CryEngine. - bool C3dLutColorChart::IsColorChartAt(AZ::u32 x, AZ::u32 y, void* pData, AZ::u32 pitch) - { - struct Color - { - private: - int c[3]; - - public: - Color(AZ::u32 x, AZ::u32 y, void* pPixels, AZ::u32 pitch) - { - const uint8* p = (const uint8*)pPixels + pitch * y + x * 4; - c[0] = p[0]; - c[1] = p[1]; - c[2] = p[2]; - } - - bool isSimilar(const Color& a, int maxDiff) const - { - return - abs(a.c[0] - c[0]) <= maxDiff && - abs(a.c[1] - c[1]) <= maxDiff && - abs(a.c[2] - c[2]) <= maxDiff; - } - }; - - const Color colorRef[2] = - { - Color(x, y, pData, pitch), - Color(x + 2, y, pData, pitch) - }; - - // We require two colors of the border to be at least a bit different - if (colorRef[0].isSimilar(colorRef[1], 15)) - { - return false; - } - - static const int kMaxDiff = 3; - - int refIdx = 0; - //rectangle's top - for (int i = 0; i < COLORCHART_IMAGE_WIDTH; i += 2) - { - if (!colorRef[refIdx].isSimilar(Color(x + i, y, pData, pitch), kMaxDiff) || - !colorRef[refIdx].isSimilar(Color(x + i + 1, y, pData, pitch), kMaxDiff)) - { - return false; - } - refIdx ^= 1; - } - - refIdx = 0; - //left - for (int i = 0; i < COLORCHART_IMAGE_HEIGHT; i += 2) - { - if (!colorRef[refIdx].isSimilar(Color(x, y + i, pData, pitch), kMaxDiff) || - !colorRef[refIdx].isSimilar(Color(x, y + i + 1, pData, pitch), kMaxDiff)) - { - return false; - } - refIdx ^= 1; - } - - refIdx = 0; - //right - for (int i = 0; i < COLORCHART_IMAGE_HEIGHT; i += 2) - { - if (!colorRef[refIdx].isSimilar(Color(x + COLORCHART_IMAGE_WIDTH - 1, y + i, pData, pitch), kMaxDiff) || - !colorRef[refIdx].isSimilar(Color(x + COLORCHART_IMAGE_WIDTH - 1, y + i + 1, pData, pitch), kMaxDiff)) - { - return false; - } - refIdx ^= 1; - } - - refIdx = 0; - //bottom - for (int i = 0; i < COLORCHART_IMAGE_WIDTH; i += 2) - { - if (!colorRef[refIdx].isSimilar(Color(x + i, y + COLORCHART_IMAGE_HEIGHT - 1, pData, pitch), kMaxDiff) || - !colorRef[refIdx].isSimilar(Color(x + i + 1, y + COLORCHART_IMAGE_HEIGHT - 1, pData, pitch), kMaxDiff)) - { - return false; - } - refIdx ^= 1; - } - - return true; - } - - - void ImageToProcess::CreateColorChart() - { - C3dLutColorChart colorChart; - - //get color chart data from source image. - if (!colorChart.GenerateFromInput(m_img)) - { - //if load from image failed then generate default color data - colorChart.GenerateDefault(); - } - - //save color chart data to an image and save as current - m_img = colorChart.GenerateChartImage(); - } -} diff --git a/Gems/ImageProcessing/Code/Source/Converters/ConvertPixelFormat.cpp b/Gems/ImageProcessing/Code/Source/Converters/ConvertPixelFormat.cpp deleted file mode 100644 index 9a49bf9b63..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/ConvertPixelFormat.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include - -#include -#include - -/////////////////////////////////////////////////////////////////////////////////// -//functions for maintaining alpha coverage. - -namespace ImageProcessing -{ - void ImageToProcess::ConvertFormat(EPixelFormat fmtDst) - { - //pixel format before convertion - EPixelFormat fmtSrc = Get()->GetPixelFormat(); - - //return directly if the image already has the desired pixel format - if (fmtDst == fmtSrc) - { - return; - } - - uint32 dwWidth, dwHeight, dwMips; - dwWidth = Get()->GetWidth(0); - dwHeight = Get()->GetHeight(0); - dwMips = Get()->GetMipCount(); - - //if the output image size doesn't work the desired pixel format. set to fallback format - const PixelFormatInfo* dstFmtInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtDst); - if (!CPixelFormats::GetInstance().IsImageSizeValid(fmtDst, dwWidth, dwHeight, true)) - { - AZ_Warning("Image Processing", false, "Output pixel format %d doesn't work with output image size %d x %d", - fmtDst, dwWidth, dwHeight); - - //fall back to safe texture format - if (dstFmtInfo->nChannels == 1) - { - fmtDst = dstFmtInfo->bHasAlpha ? ePixelFormat_A8 : ePixelFormat_R8; - } - else if (dstFmtInfo->nChannels == 2) - { - fmtDst = ePixelFormat_R8G8; - } - else - { - fmtDst = dstFmtInfo->bHasAlpha ? ePixelFormat_R8G8B8A8 : ePixelFormat_R8G8B8X8; - } - } - - //convert src image to uncompressed formats if it's compressed format - bool isSrcUncompressed = CPixelFormats::GetInstance().IsPixelFormatUncompressed(fmtSrc); - bool isDstUncompressed = CPixelFormats::GetInstance().IsPixelFormatUncompressed(fmtDst); - - if (isSrcUncompressed && isDstUncompressed) - {//both are uncompressed - ConvertFormatUncompressed(fmtDst); - } - else if (!isSrcUncompressed && !isDstUncompressed) - { //both are compressed - AZ_Assert(false, "unusual user case. but we can still handle it"); - } - else - { //one fmt is compressed format - //use the compressed format to find right compressor - EPixelFormat compressedFmt = isSrcUncompressed ? fmtDst : fmtSrc; - EPixelFormat uncompressedFmt = isSrcUncompressed ? fmtSrc : fmtDst; - ICompressorPtr compressor = ICompressor::FindCompressor(compressedFmt, isSrcUncompressed); - - if (compressor == nullptr) - { - //no avaible compressor for compressed format - AZ_Warning("Image Processing", false, "No avaliable compressor for pixel format %d", compressedFmt); - return; - } - - //check if the uncompressed fmt also supported by the compressor - EPixelFormat desiredUncompressedFmt = compressor->GetSuggestedUncompressedFormat(compressedFmt, uncompressedFmt); - if (desiredUncompressedFmt != uncompressedFmt) - { - //we need to do intermedia convertion to convert to the temperory format - ConvertFormat(desiredUncompressedFmt); - ConvertFormat(fmtDst); - } - else - { - IImageObjectPtr dstImage = nullptr; - if (isSrcUncompressed) - { - dstImage = compressor->CompressImage(Get(), fmtDst, &m_compressOption); - } - else - { - dstImage = compressor->DecompressImage(Get(), fmtDst); - } - - Set(dstImage); - } - - if (Get() == nullptr) - { - AZ_Error("Image Processing", false, "The selected compressor failed to compress this image"); - } - } - } - - void ImageToProcess::ConvertFormatUncompressed(EPixelFormat fmtTo) - { - IImageObjectPtr srcImage = m_img; - EPixelFormat srcFmt = srcImage->GetPixelFormat(); - EPixelFormat dstFmt = fmtTo; - - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcFmt) - && CPixelFormats::GetInstance().IsPixelFormatUncompressed(dstFmt))) - { - AZ_Assert(false, "both source and dest images' pixel format need to be uncompressed"); - return; - } - - IImageObjectPtr dstImage(m_img->AllocateImage(fmtTo)); - - AZ_Assert(srcImage->GetPixelCount(0) == dstImage->GetPixelCount(0), "dest image has different size than source image"); - - //create pixel operation function for src and dst images - IPixelOperationPtr srcOp = CreatePixelOperation(srcFmt); - IPixelOperationPtr dstOp = CreatePixelOperation(dstFmt); - - //get count of bytes per pixel for both src and dst images - uint32 srcPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(srcFmt)->bitsPerBlock / 8; - uint32 dstPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->bitsPerBlock / 8; - - const uint32 dwMips = dstImage->GetMipCount(); - float r, g, b, a; - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* srcPixelBuf; - uint32 srcPitch; - srcImage->GetImagePointer(dwMip, srcPixelBuf, srcPitch); - uint8* dstPixelBuf; - uint32 dstPitch; - dstImage->GetImagePointer(dwMip, dstPixelBuf, dstPitch); - - const uint32 pixelCount = srcImage->GetPixelCount(dwMip); - - for (uint32 i = 0; i < pixelCount; ++i, srcPixelBuf += srcPixelBytes, dstPixelBuf += dstPixelBytes) - { - srcOp->GetRGBA(srcPixelBuf, r, g, b, a); - dstOp->SetRGBA(dstPixelBuf, r, g, b, a); - } - } - - m_img = dstImage; - } - - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/Cubemap.cpp b/Gems/ImageProcessing/Code/Source/Converters/Cubemap.cpp deleted file mode 100644 index 71e629b553..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Cubemap.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -namespace ImageProcessing -{ - CubemapLayoutInfo CubemapLayout::s_layoutList[CubemapLayoutTypeCount]; - - template - inline bool IsPowerOfTwo(TInteger x) - { - return (x & (x - 1)) == 0; - } - - CubemapLayoutInfo::CubemapLayoutInfo() - : m_type(CubemapLayoutNone) - , m_rows(0) - , m_columns(0) - { - - } - - void CubemapLayoutInfo::SetFaceInfo(CubemapFace face, AZ::u8 row, AZ::u8 col, CubemapFaceDirection dir) - { - m_faceInfos[face].row = row; - m_faceInfos[face].column = col; - m_faceInfos[face].direction = dir; - } - - void CubemapLayout::InitCubemapLayoutInfos() - { - //CubemapLayoutHorizontal - //left , right, front, back, top, bottom; - //NOTE: this layout is widely used in game projects by Jan 2018 since other layouts weren't supported correctly - //but the faces in one has unusual directions compare to other format. - //The direction matters when using it as input for Cubemap generation filter. - //Left: rotated left 90 degree. Right: rotated right 90 degree - //Front: rotated 180 degree. Back: no rotation - //Top: rotate 180 degree. Bottom: no rotation - CubemapLayoutInfo *info = &s_layoutList[CubemapLayoutHorizontal]; - info->m_rows = 1; - info->m_columns = 6; - info->m_type = CubemapLayoutHorizontal; - info->SetFaceInfo(FaceLeft, 0, 0, CubemapFaceDirection::DirRotateLeft90); - info->SetFaceInfo(FaceRight, 0, 1, CubemapFaceDirection::DirRotateRight90); - info->SetFaceInfo(FaceFront, 0, 2, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceBack, 0, 3, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceTop, 0, 4, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceBottom, 0, 5, CubemapFaceDirection::DirNoRotation); - - //CubemapLayoutHorizontalCross - // top - // left front right back - // bottom - info = &s_layoutList[CubemapLayoutHorizontalCross]; - info->m_rows = 3; - info->m_columns = 4; - info->m_type = CubemapLayoutHorizontalCross; - info->SetFaceInfo(FaceLeft, 1, 0, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceRight, 1, 2, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceFront, 1, 1, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceBack, 1, 3, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceTop, 0, 1, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceBottom, 2, 1, CubemapFaceDirection::DirNoRotation); - - //CubemapLayoutVerticalCross - // top - // left front right - // bottom - // back - info = &s_layoutList[CubemapLayoutVerticalCross]; - info->m_rows = 4; - info->m_columns = 3; - info->m_type = CubemapLayoutVerticalCross; - info->SetFaceInfo(FaceLeft, 1, 0, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceRight, 1, 2, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceFront, 1, 1, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceBack, 3, 1, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceTop, 0, 1, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceBottom, 2, 1, CubemapFaceDirection::DirNoRotation); - - //CubemapLayoutVertical - // left - // right - // front - // back - // top - // bottom - info = &s_layoutList[CubemapLayoutVertical]; - info->m_rows = 6; - info->m_columns = 1; - info->m_type = CubemapLayoutVertical; - info->SetFaceInfo(FaceLeft, 0, 0, CubemapFaceDirection::DirRotateLeft90); - info->SetFaceInfo(FaceRight, 1, 0, CubemapFaceDirection::DirRotateRight90); - info->SetFaceInfo(FaceFront, 2, 0, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceBack, 3, 0, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceTop, 4, 0, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceBottom, 5, 0, CubemapFaceDirection::DirNoRotation); - - //make sure all types were initialized - for (int i = 0; i < CubemapLayoutTypeCount; i++) - { - AZ_Assert(s_layoutList[i].m_type == i, "layout %d is not initialized", i); - } - } - - const float* GetTransformMatrix(CubemapFaceDirection dir, bool isInvert) - { - switch (dir) - { - case CubemapFaceDirection::DirNoRotation: - { - static const float mat[] = { 1, 0, 0, 1 }; - return mat; - } - case CubemapFaceDirection::DirRotateLeft90: - { - //thelta = 90 degree - //{cos, -sin, sin, cos} - if (isInvert) - { - return GetTransformMatrix(CubemapFaceDirection::DirRotateRight90, false); - } - static const float mat[] = { 0, -1, 1, 0 }; - return mat; - } - case CubemapFaceDirection::DirRotateRight90: - { - //thelta = -90 degree - if (isInvert) - { - return GetTransformMatrix(CubemapFaceDirection::DirRotateLeft90, false); - } - static const float mat[] = { 0, 1, -1, 0 }; - return mat; - } - case CubemapFaceDirection::DirRotate180: - { - //thelta = 180 degree - static const float mat[] = { -1, 0, 0, -1 }; - return mat; - } - case CubemapFaceDirection::DirMirrorHorizontal: - { - static const float mat[] = { 1, 0, 0, -1 }; - return mat; - } - default: - { - AZ_Assert(false, "unimplemented direction matrix"); - static const float mat[] = { 1, 0, 0, 1 }; - return mat; - } - } - } - - void TransformImage(CubemapFaceDirection srcDir, CubemapFaceDirection dstDir, const AZ::u8* srcImageBuf, - AZ::u8* dstImageBuf, AZ::u8 bytePerPixel, AZ::u32 rectSize) - { - //get final matrix to transform dst back to src - const float* m1 = GetTransformMatrix(dstDir, true); - const float* m2 = GetTransformMatrix(srcDir, false); - float mtx[4]; - mtx[0] = m1[0] * m2[0] + m1[1] * m2[2]; - mtx[1] = m1[0] * m2[1] + m1[1] * m2[3]; - mtx[2] = m1[2] * m2[0] + m1[3] * m2[2]; - mtx[3] = m1[2] * m2[1] + m1[3] * m2[3]; - - const float* noRotate = GetTransformMatrix(CubemapFaceDirection::DirNoRotation, false); - - if (memcmp(noRotate, mtx, 4 * sizeof(float)) == 0) - { - memcpy(dstImageBuf, srcImageBuf, rectSize*rectSize*bytePerPixel); - return; - } - - //for each pixel in dst image, find it's location in src and copy the data from there - float halfSize = rectSize / 2; - for (AZ::u32 row = 0; row < rectSize; row++) - { - for (AZ::u32 col = 0; col < rectSize; col++) - { - //coordinate in image center as origin and right as positive X, up as positive Y - float dstX = col + 0.5f - halfSize; - float dstY = halfSize - row - 0.5f; - float srcX = dstX * mtx[0] + dstY * mtx[1]; - float srcY = dstX * mtx[2] + dstY * mtx[3]; - AZ::u32 srcCol = srcX + halfSize; - AZ::u32 srcRow = halfSize - srcY; - - memcpy(&dstImageBuf[(row*rectSize + col)*bytePerPixel], - &srcImageBuf[(srcRow*rectSize + srcCol)*bytePerPixel], bytePerPixel); - } - } - } - - CubemapLayout::CubemapLayout() - : m_info(nullptr) - , m_image(nullptr) - , m_faceSize(256) - { - } - - CubemapLayout* CubemapLayout::CreateCubemapLayout(IImageObjectPtr image) - { - //only support uncompressed format. - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(image->GetPixelFormat())) - { - AZ_Assert(false, "CubemapLayout only support uncompressed image"); - return nullptr; - } - - CubemapLayout* layout = nullptr; - CubemapLayoutInfo* info = GetCubemapLayoutInfo(image); - if (info) - { - layout = new CubemapLayout(); - layout->m_info = GetCubemapLayoutInfo(image); - layout->m_image = image; - layout->m_faceSize = image->GetWidth(0)/layout->m_info->m_columns; - } - return layout; - } - - - CubemapLayoutInfo* CubemapLayout::GetCubemapLayoutInfo(CubemapLayoutType type) - { - if (type == CubemapLayoutNone) - { - return nullptr; - } - - //if it's never initialized - if (s_layoutList[0].m_type == CubemapLayoutNone) - { - InitCubemapLayoutInfos(); - } - - return &s_layoutList[type]; - } - - CubemapLayoutInfo* CubemapLayout::GetCubemapLayoutInfo(IImageObjectPtr image) - { - //if it's never initialized - if (s_layoutList[0].m_type == CubemapLayoutNone) - { - InitCubemapLayoutInfos(); - } - - if (image == nullptr) - { - return nullptr; - } - - uint32 width, height; - width = image->GetWidth(0); - height = image->GetHeight(0); - CubemapLayoutInfo* info = nullptr; - - for (int i = 0; i < CubemapLayoutTypeCount; i++) - { - if (width * s_layoutList[i].m_rows == height*s_layoutList[i].m_columns) - { - info = &s_layoutList[i]; - - //we require the face size need to be power of two - if (IsPowerOfTwo(width / info->m_columns)) - { - return info; - } - else - { - return nullptr; - } - } - } - return nullptr; - } - - //public functions to get faces information for associated image - AZ::u32 CubemapLayout::GetFaceSize() - { - return m_faceSize; - } - - CubemapLayoutInfo* CubemapLayout::GetLayoutInfo() - { - return m_info; - } - - CubemapFaceDirection CubemapLayout::GetFaceDirection(CubemapFace face) - { - return m_info->m_faceInfos[face].direction; - } - - void CubemapLayout::GetFaceData(CubemapFace face, void* outBuffer, AZ::u32& outSize) - { - //only valid for uncompressed - AZ::u32 sizePerPixel = CPixelFormats::GetInstance().GetPixelFormatInfo(m_image->GetPixelFormat())->bitsPerBlock / 8; - - AZ::u8* imageBuf; - AZ::u32 dwPitch; - m_image->GetImagePointer(0, imageBuf, dwPitch); - AZ::u8* dstBuf = (AZ::u8*)outBuffer; - - AZ::u32 startX = m_info->m_faceInfos[face].column * m_faceSize; - AZ::u32 startY = m_info->m_faceInfos[face].row * m_faceSize; - - //face size is same as rows for uncompressed format - for (AZ::u32 y = 0; y < m_faceSize; y++) - { - AZ::u32 scanlineSize = m_faceSize*sizePerPixel; - AZ::u8* srcBuf = &imageBuf[(startY + y) * dwPitch + startX*sizePerPixel]; - memcpy(dstBuf, srcBuf, scanlineSize); - dstBuf += scanlineSize; - } - - outSize = m_faceSize*m_faceSize*sizePerPixel; - - } - - void CubemapLayout::SetFaceData(CubemapFace face, void* dataBuffer, [[maybe_unused]] AZ::u32 dataSize) - { - //only valid for uncompressed - AZ::u32 sizePerPixel = CPixelFormats::GetInstance().GetPixelFormatInfo(m_image->GetPixelFormat())->bitsPerBlock / 8; - - AZ::u8* imageBuf; - AZ::u32 dwPitch; - m_image->GetImagePointer(0, imageBuf, dwPitch); - AZ::u8* srcBuf = (AZ::u8*)dataBuffer; - - AZ::u32 startX = m_info->m_faceInfos[face].column * m_faceSize; - AZ::u32 startY = m_info->m_faceInfos[face].row * m_faceSize; - - //face size is same as rows for uncompressed format - for (AZ::u32 y = 0; y < m_faceSize; y++) - { - AZ::u32 scanlineSize = m_faceSize*sizePerPixel; - AZ::u8* dstBuf = &imageBuf[(startY + y) * dwPitch + startX*sizePerPixel]; - memcpy(dstBuf, srcBuf, scanlineSize); - srcBuf += scanlineSize; - } - } - - void* CubemapLayout::GetFaceMemBuffer(AZ::u32 mip, CubemapFace face, AZ::u32& outPitch) - { - if (CubemapLayoutVertical != m_info->m_type) - { - AZ_Assert(false, "this should only be used for CubemapLayoutVertical which has continous memory for each face"); - return nullptr; - } - - AZ::u32 faceSize = m_faceSize >> mip; - AZ::u8* imageBuf; - m_image->GetImagePointer(mip, imageBuf, outPitch); - AZ::u32 startY = m_info->m_faceInfos[face].row * faceSize; - - //use startY is same as rows from m_image since the pixel format is uncompressed - return &imageBuf[startY * outPitch]; - } - - void CubemapLayout::SetToFaceMemBuffer(AZ::u32 mip, CubemapFace face, void* dataBuffer) - { - if (CubemapLayoutVertical != m_info->m_type) - { - AZ_Assert(false, "this should only be used for CubemapLayoutVertical which has continuous memory for each face"); - return; - } - - AZ::u32 faceSize = m_faceSize >> mip; - AZ::u32 pitch; - AZ::u8* imageBuf; - m_image->GetImagePointer(mip, imageBuf, pitch); - AZ::u32 startY = m_info->m_faceInfos[face].row * faceSize; - - //use startY is same as rows from m_image since the pixel format is uncompressed - memcpy(&imageBuf[startY * pitch], dataBuffer, faceSize*pitch); - } - - void CubemapLayout::GetRectForFace(AZ::u32 mip, CubemapFace face, QRect& outRect) - { - AZ::u32 faceSize = m_faceSize >> mip; - AZ::u32 startY = m_info->m_faceInfos[face].row * faceSize; - AZ::u32 startX = m_info->m_faceInfos[face].column * faceSize; - - outRect.setRect(startX, startY, faceSize, faceSize); - } - - bool ImageToProcess::ConvertCubemapLayout(CubemapLayoutType dstLayoutType) - { - const EPixelFormat srcPixelFormat = m_img->GetPixelFormat(); - - //it need to be uncompressed format - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcPixelFormat)) - { - AZ_Assert(false, "Please convert the image to uncompressed pixel format before calling ConvertCubemapLayout"); - return false; - } - - //check if it's valid cubemap size - CubemapLayoutInfo* layoutInfo = CubemapLayout::GetCubemapLayoutInfo(m_img); - if (layoutInfo == nullptr) - { - AZ_Error("Image Processing", false, "The original image doesn't have a valid size (layout) as cubemap"); - return false; - } - - //if the source is same as output layout, return directly - if (layoutInfo->m_type == dstLayoutType) - { - return true; - } - - CubemapLayoutInfo* dstLayoutInfo = CubemapLayout::GetCubemapLayoutInfo(dstLayoutType); - - //create cubemap layout for source image for later operation. - CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(m_img); - AZ::u32 faceSize = srcCubemap->GetFaceSize(); - - //create new image with same pixel format and copy prperties from source image - IImageObjectPtr newImage(IImageObject::CreateImage(faceSize * dstLayoutInfo->m_columns, - faceSize*dstLayoutInfo->m_rows, 1, srcPixelFormat)); - CubemapLayout *dstCubemap = CubemapLayout::CreateCubemapLayout(newImage); - newImage->CopyPropertiesFrom(newImage); - - //copy data from src cube to dst cube for each face - //temp buf for copy over data - AZ::u32 sizePerPixel = CPixelFormats::GetInstance().GetPixelFormatInfo(srcPixelFormat)->bitsPerBlock/8; //only valid for uncompressed - AZ::u8 *buf = new AZ::u8[faceSize*faceSize*sizePerPixel]; - AZ::u8 *tempBuf = new AZ::u8[faceSize*faceSize*sizePerPixel]; - - for (AZ::u32 faceIdx = 0; faceIdx < FaceCount; faceIdx++) - { - AZ::u32 outSize = 0; - CubemapFace face = (CubemapFace)faceIdx; - srcCubemap->GetFaceData(face, buf, outSize); - CubemapFaceDirection srcDir = srcCubemap->GetFaceDirection(face); - CubemapFaceDirection dstDir = dstCubemap->GetFaceDirection(face); - if (srcDir == dstDir) - { - dstCubemap->SetFaceData(face, buf, outSize); - } - else - { - //transform the image - TransformImage(srcDir, dstDir, buf, tempBuf, sizePerPixel, faceSize); - dstCubemap->SetFaceData(face, tempBuf, outSize); - } - } - - //clean up - delete[] buf; - delete[] tempBuf; - delete srcCubemap; - delete dstCubemap; - - newImage->AddImageFlags(EIF_Cubemap); - m_img = newImage; - return true; - } - - bool ImageConvertProcess::FillCubemapMipmaps() - { - //this function only works with pixel format rgba32f - const EPixelFormat srcPixelFormat = m_image->Get()->GetPixelFormat(); - if (srcPixelFormat != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s only works with pixel format rgba32f", __FUNCTION__); - return false; - } - - //only if the src image has one mip - if (m_image->Get()->GetMipCount() != 1) - { - AZ_Assert(false, "%s called for a mipmapped image. ", __FUNCTION__); - return false; - } - - CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(m_image->Get()); - - uint32 outWidth; - uint32 outHeight; - uint32 outReduce = 0; - AZ::u32 srcFaceSize = srcCubemap->GetFaceSize(); - //get output face size - GetOutputExtent(srcFaceSize, srcFaceSize, outWidth, outHeight, outReduce, &m_textureSetting, &m_presetSetting); - AZ_Assert(outWidth == outHeight, "something wrong with GetOutputExtent function"); - - //get final cubemap image size - outWidth *= srcCubemap->GetLayoutInfo()->m_columns; - outHeight *= srcCubemap->GetLayoutInfo()->m_rows; - - //max mipmap count - uint32 maxMipCount; - if (m_presetSetting.m_mipmapSetting == nullptr || !m_textureSetting.m_enableMipmap) - { - maxMipCount = 1; - } - else - { - //calculate based on face size, and use final export format which may save some low level mip calculation - maxMipCount = CPixelFormats::GetInstance().ComputeMaxMipCount(m_presetSetting.m_pixelFormat, srcFaceSize, srcFaceSize); - - //the FilterImage function won't do well with rect size 1. avoiding cubemap with face size 1 - if (srcFaceSize >> maxMipCount == 1 && maxMipCount > 1) - { - maxMipCount -= 1; - } - } - - //create new new output image with proper face - IImageObjectPtr outImage(IImageObject::CreateImage(outWidth, outHeight, maxMipCount, srcPixelFormat)); - outImage->CopyPropertiesFrom(m_image->Get()); - CubemapLayout *dstCubemap = CubemapLayout::CreateCubemapLayout(outImage); - AZ::u32 outFaceSize = dstCubemap->GetFaceSize(); - AZ::u32 dstMipCount = outImage->GetMipCount(); - - //filter the image for top mip first - for (int iSide = 0; iSide < 6; ++iSide) - { - QRect srcRect; - QRect dstRect; - - srcRect.setLeft(0); - srcRect.setRight(srcFaceSize); - srcRect.setTop(iSide * srcFaceSize); - srcRect.setBottom((iSide + 1) * srcFaceSize); - - dstRect.setLeft(0); - dstRect.setRight(outFaceSize); - dstRect.setTop(iSide * outFaceSize); - dstRect.setBottom((iSide + 1) * outFaceSize); - - FilterImage(m_textureSetting.m_mipGenType, m_textureSetting.m_mipGenEval, 0, 0, m_image->Get(), 0, - outImage, 0, &srcRect, &dstRect); - } - - - CCubeMapProcessor atiCubemanGen; - //ATI's cubemap generator to filter the image edges to avoid seam problem - // https://gpuopen.com/archive/gamescgi/cubemapgen/ - - //the thread support was done with windows thread function so it's removed for multi-dev platform support - atiCubemanGen.m_NumFilterThreads = 0; - - // input and output cubemap set to have save dimensions, - atiCubemanGen.Init(outFaceSize, outFaceSize, dstMipCount, 4); - - // Load the 6 faces of the input cubemap and copy them into the cubemap processor - void* pMem; - uint32 nPitch; - - for (int iFace = 0; iFace < 6; ++iFace) - { - pMem = dstCubemap->GetFaceMemBuffer(0, (CubemapFace)iFace, nPitch); - atiCubemanGen.SetInputFaceData( - iFace, // FaceIdx, - CP_VAL_FLOAT32, // SrcType, - 4, // SrcNumChannels, - nPitch, // SrcPitch, - pMem, // SrcDataPtr, - 1000000.0f, // MaxClamp, - 1.0f, // Degamma, - 1.0f); // Scale - } - - //Filter cubemap - atiCubemanGen.InitiateFiltering( - m_presetSetting.m_cubemapSetting->m_angle, //BaseFilterAngle, - m_presetSetting.m_cubemapSetting->m_mipAngle, //InitialMipAngle, - m_presetSetting.m_cubemapSetting->m_mipSlope, //MipAnglePerLevelScale, - (int)m_presetSetting.m_cubemapSetting->m_filter, //FilterType, CP_FILTER_TYPE_COSINE for diffuse cube - m_presetSetting.m_cubemapSetting->m_edgeFixup > 0? CP_FIXUP_PULL_LINEAR : CP_FIXUP_NONE, //FixupType, CP_FIXUP_PULL_LINEAR if FixupWidth> 0 - m_presetSetting.m_cubemapSetting->m_edgeFixup, //FixupWidth, - true, //bUseSolidAngle, - 16, //GlossScale, - 0, //GlossBias - 128); //SampleCountGGX - - // Download data into it - for (int iFace = 0; iFace < 6; ++iFace) - { - for (unsigned int dstMip = 0; dstMip < dstMipCount; ++dstMip) - { - pMem = dstCubemap->GetFaceMemBuffer(dstMip, (CubemapFace)iFace, nPitch); - atiCubemanGen.GetOutputFaceData(iFace, dstMip, CP_VAL_FLOAT32, 4, nPitch, pMem, 1.0f, 1.0f); - } - } - - delete srcCubemap; - delete dstCubemap; - - //set back to image - m_image->Set(outImage); - return true; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/Cubemap.h b/Gems/ImageProcessing/Code/Source/Converters/Cubemap.h deleted file mode 100644 index 76dd8d2c30..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Cubemap.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - // note: O3DE is right hand Z up coordinate - // please don't change the order of the enum since we are using it to match the face id defined in AMD's CubemapGen - // and they are using left hand Y up coordinate - enum CubemapFace - { - FaceLeft = 0, - FaceRight, - FaceFront, - FaceBack, - FaceTop, - FaceBottom, - FaceCount - }; - - //we are treating the orientation of faces in 4x3 layout as the original direction. - enum class CubemapFaceDirection - { - DirNoRotation = 0, - DirRotateLeft90, - DirRotateRight90, - DirRotate180, - DirMirrorHorizontal - }; - - //this class contains information to describe a cubemap layout - class CubemapLayoutInfo - { - public: - struct FaceInfo - { - AZ::u8 row; - AZ::u8 column; - CubemapFaceDirection direction; - }; - - //rows and columns of how cubemap's faces laid - AZ::u8 m_rows; - AZ::u8 m_columns; - - //the type of this layout info for - CubemapLayoutType m_type; - - //the index of row and column where all the faces located - FaceInfo m_faceInfos[FaceCount]; - - CubemapLayoutInfo(); - void SetFaceInfo(CubemapFace face, AZ::u8 row, AZ::u8 col, CubemapFaceDirection dir); - }; - - //class to help doing operations with faces for an image as cubemap - class CubemapLayout - { - public: - //create a cubemapLayout object for the image. It can be used later to get image information as a cubemap - static CubemapLayout* CreateCubemapLayout(IImageObjectPtr image); - - //get layout info for input layout type - static CubemapLayoutInfo* GetCubemapLayoutInfo(CubemapLayoutType type); - - //get layout info for input image based on its size - static CubemapLayoutInfo* GetCubemapLayoutInfo(IImageObjectPtr image); - - //public functions to get faces information for associated image - AZ::u32 GetFaceSize(); - - //get the rect where the face in the image - void GetRectForFace(AZ::u32 mip, CubemapFace face, QRect& outRect); - - CubemapLayoutInfo* GetLayoutInfo(); - - //set/get pixels' data from/to specific face. only works for mip 0 - void GetFaceData(CubemapFace face, void* outBuffer, AZ::u32& outSize); - void SetFaceData(CubemapFace face, void* dataBuffer, AZ::u32 dataSize); - - //get the face's direction - CubemapFaceDirection GetFaceDirection(CubemapFace face); - - //get memory for a face from Image data. only works for CubemapLayoutVertical since its memory for each face is continuous - void* GetFaceMemBuffer(AZ::u32 mip, CubemapFace face, AZ::u32& outPitch); - void SetToFaceMemBuffer(AZ::u32 mip, CubemapFace face, void* dataBuffer); - - private: - //information for all supported cubemap layouts - static CubemapLayoutInfo s_layoutList[CubemapLayoutTypeCount]; - - //the image associated for this CubemapLayout - IImageObjectPtr m_image; - //the layout information of m_image - CubemapLayoutInfo *m_info; - //the size of the cubemap's face (which is square and power of 2). - uint32 m_faceSize; - - //private constructor. User should always use CreateCubemapLayout create a layout for an image object - CubemapLayout(); - - //initialize information of all available cubemap layouts - static void InitCubemapLayoutInfos(); - }; - -}//end namspace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/FIR-Filter.cpp b/Gems/ImageProcessing/Code/Source/Converters/FIR-Filter.cpp deleted file mode 100644 index 8d1b8f2877..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/FIR-Filter.cpp +++ /dev/null @@ -1,1285 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* #################################################################################################################### - */ -#define mallocAligned(sze) _aligned_malloc(sze, 16) -#define freeAligned(ptr) _aligned_free(ptr) - -/* #################################################################################################################### - */ - -namespace ImageProcessing -{ - class Rect2D - { - public: - /* ================================================================================================================== - * Rect2D = ??? - */ - Rect2D() { } - Rect2D(const int x, const int y) { visual[0] = x; visual[1] = y; } - - private: - int visual[2]; - - public: - /* ================================================================================================================== - * Access operators - * M(i, j) == [row i][col j] - */ - inline int& operator () (int i) { return visual[i]; } - inline int operator () (int i) const { return visual[i]; } - - inline int& operator [] (int i) { return visual[i]; } - inline int operator [] (int i) const { return visual[i]; } - - /* ================================================================================================================== - * Logical operators - */ - inline bool operator == (const Rect2D& tht) - { - return (visual[0] == tht.visual[0]) && - (visual[1] == tht.visual[1]); - } - }; - - /* #################################################################################################################### - */ - template - class Plane2D - { - public: - /* ================================================================================================================== - * Plane2D = ??? - */ - Plane2D(const int x, const int y, const int p) { planes = p; allocatedC[0] = x; allocatedC[1] = y; used = allocatedC; aligned[0] = (allocatedC[0] + 15) & (~15); aligned[1] = allocatedC[1]; allocate(); } - Plane2D(const Rect2D& i, const int p) { planes = p; allocatedC = i; used = allocatedC; aligned[0] = (allocatedC[0] + 15) & (~15); aligned[1] = allocatedC[1]; allocate(); } - - ~Plane2D() { deallocate(); } - - /* ================================================================================================================== - * ??? = Plane2D - */ - inline operator Rect2D() const { return used; } - inline operator int () const { return planes; } - - inline operator DataType* () const { return buffers; } - inline operator DataType*** () const { return rows; } - inline operator const DataType* () const { return (const DataType*)buffers; } - inline operator const DataType*** () const { return (const DataType***)rows; } - - public: - inline void locate(Rect2D take) - { - taken = take; - - if ((taken[0] > aligned[0]) || - (taken[1] > abs(aligned[1]))) - { - abort(); - } - - /* align column#length */ - used[0] = (taken[0] + 15) & (~15); - used[1] = taken[1]; - - for (int p = 0; p < planes; p++) - { - /* we may need to replicate the row-unsigned __int64 over all rows only (y < 0) */ - const unsigned long int rowsize = (aligned[1] <= 0 ? 0 : aligned[0] * sizeof(DataType)); - int r; - char* buffer; - AZ_Assert((rowsize % 16) == 0, "%s: Unexpected row size!", __FUNCTION__); - - /* first block contains the row*-pointers */ - rows[p] = (DataType**)((char*)(rows + planes) + rowblocksize * p) + excess; - - /* "excess" empty pointers on negative offsets ----------------------------- */ - buffer = (char*)NULL; - AZ_Assert((reinterpret_cast(buffer) % 16) == 0, "%s: Unexpected buffer size!", __FUNCTION__); - - - for (r = -excess; r < 0; r++) - { - rows[p][r] = (DataType*)buffer; - } - - /* regular row-pointers ---------------------------------------------------- */ - buffer = (char*)buffers + (planesize * p); - AZ_Assert((reinterpret_cast(buffer) % 16) == 0, "%s: Unexpected buffer size!", __FUNCTION__); - - for (r = 0; r < abs(aligned[1]); r++, buffer += rowsize) - { - rows[p][r] = (DataType*)buffer; - } - - /* overhanging row-pointers show on the first valid row (loop) ------------- */ - buffer = (char*)buffers + (planesize * p); - AZ_Assert((reinterpret_cast(buffer) % 16) == 0, "%s: Unexpected buffer size!", __FUNCTION__); - - - for (r = abs(aligned[1]); r < abs(aligned[1]) + excess; r++, buffer += rowsize) - { - rows[p][r] = (DataType*)buffer; - } - } - } - - inline void clear() - { - memset(buffers, 0, planesize * planes); - } - - inline void delocate() - { - memset(buffers, 0, planesize * planes); - memset(rows, 0, sizeof(DataType * *) * planes + rowblocksize * planes); - } - - inline void relocate(Rect2D take) - { - delocate(); - locate(take); - } - - protected: - inline void allocate () - { - /* adjust rows */ - allocatedC[0] = allocatedC[0]; - allocatedC[1] = maximum(1, allocatedC[1]); - - /* if "(y < 0)", we allocate exactly 1 row and replicate it over "abs(y)" */ - planesize = sizeof(DataType) * aligned[0] * maximum(1, aligned[1]); - rowblocksize = sizeof(DataType*) * (abs(aligned[1]) + (2 * excess) + 16); - - /* all planes after each other: - * - * start -> plane0 -> plane1 -> ... - */ - buffers = (DataType* )AZ_OS_MALLOC(planesize * planes, 16); - /* all pointers after each other: - * - * start -> unsigned __int64 to planes -> unsigned __int64 to rows of planes - */ - rows = (DataType***)AZ_OS_MALLOC(sizeof(DataType * *) * planes + rowblocksize * planes, 16); - - /* ensure the blocks are aligned */ - AZ_Assert(((AZ::s64)buffers % 16) == 0, "%s: Expect blocks are aligned!", __FUNCTION__); - /* ensure the planes concat aligned */ - AZ_Assert((planesize % 16) == 0, "%s: Expect planes concat is aligned!", __FUNCTION__); - - locate(allocatedC); - } - - inline void deallocate() - { - AZ_OS_FREE(buffers); - AZ_OS_FREE(rows); - } - - Rect2D allocatedC, aligned; // real buffer sizes and its aligned counterpart - Rect2D taken, used; // actually taken sizes and its aligned counterpart - - int planes; - long int planesize, rowblocksize; - DataType* buffers; - DataType*** rows; - }; - - /* #################################################################################################################### \ - */ - #define filterTVariables(filterVxNNum, dtyp, wtyp, reps) \ - /* addition of c-pointers already takes care of datatype-sizes */ \ - const signed long int dy = /*parm->mirror ? -1 :*/ 1; \ - const unsigned int stridei = parm->incols * 1 * 1; \ - const unsigned int stridet = parm->subcols * 1 * 1; \ - const unsigned int strideo = parm->outcols * 1 * 1; \ - /* offset and shift calculations still require the unmodified values */ \ - const unsigned int strideiraw = parm->incols; \ - const unsigned int stridetraw = parm->subcols; \ - const unsigned int strideoraw = parm->outcols; \ - \ - class Plane2D tmp(tmpcols, tmprows, 4); \ - dtyp*** t = (dtyp***)tmp; \ - int srcPos, dstPos; \ - bool plusminush = false; const bool of = true; \ - bool plusminusv = false; const bool nc = false; \ - FilterWeights* fwh = calculateFilterWeights(parm->resample.colrem, parm->caged ? 0 : 0 - parm->region.subtop, parm->caged ? srccols : parm->subrows - parm->region.subtop, \ - parm->resample.colquo, 0, dstcols, reps, parm->resample.colblur, parm->resample.wf, parm->resample.operation != eWindowEvaluation_Sum, plusminush); \ - FilterWeights* fwv = calculateFilterWeights(parm->resample.rowrem, parm->caged ? 0 : 0 - parm->region.intop, parm->caged ? srcrows : parm->inrows - parm->region.intop, \ - parm->resample.rowquo, 0, dstrows, reps, parm->resample.rowblur, parm->resample.wf, parm->resample.operation != eWindowEvaluation_Sum, plusminusv); \ - - #define filterFTVariables(filterVxNNum) \ - filterTVariables(filterVxNNum, float, signed short, 1) - - /* #################################################################################################################### \ - */ - #define filterTCleanUp(filterVxNNum) \ - delete[] fwh; \ - delete[] fwv; - - /* #################################################################################################################### \ - */ - #define filterTInitLoop() - - /* ******************************************************************************************************************** \ - */ - #define filterTExitLoop() - - /* #################################################################################################################### \ - */ - #define filter4xNf(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, pm, hv, dtyp, atyp) \ - init(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); \ - \ - dstPos = 0; do { \ - FilterWeights& fw = *(hv + dstPos); \ - const signed short* w = fw.weights; \ - \ - next(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); \ - \ - atyp res0 = (op != eWindowEvaluation_Min ? 0 : 32768); \ - atyp res1 = (op != eWindowEvaluation_Min ? 0 : 32768); \ - atyp res2 = (op != eWindowEvaluation_Min ? 0 : 32768); \ - atyp res3 = (op != eWindowEvaluation_Min ? 0 : 32768); \ - \ - srcPos = fw.first; do { \ - /* get value */ \ - fetch(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); \ - \ - /* build result using sign inverted weights [32767,-32768] */ \ - if constexpr (op == eWindowEvaluation_Sum) { \ - res0 -= ((atyp)_0 * *w); \ - res1 -= ((atyp)_1 * *w); \ - res2 -= ((atyp)_2 * *w); \ - res3 -= ((atyp)_3 * *w++); \ - } \ - else if constexpr (op == eWindowEvaluation_Max) { \ - res0 = maximum(res0, -(atyp)_0 * *w); \ - res1 = maximum(res1, -(atyp)_1 * *w); \ - res2 = maximum(res2, -(atyp)_2 * *w); \ - res3 = maximum(res3, -(atyp)_3 * *w++); \ - } \ - else if constexpr (op == eWindowEvaluation_Min) { \ - res0 = (atyp)32768.0 - maximum((atyp)32768.0 - res0, -(atyp)(1.0f - _0) * *w); \ - res1 = (atyp)32768.0 - maximum((atyp)32768.0 - res1, -(atyp)(1.0f - _1) * *w); \ - res2 = (atyp)32768.0 - maximum((atyp)32768.0 - res2, -(atyp)(1.0f - _2) * *w); \ - res3 = (atyp)32768.0 - maximum((atyp)32768.0 - res3, -(atyp)(1.0f - _3) * *w++); \ - } \ - } while (++srcPos < fw.last); \ - \ - /* dtyp _0 = ldexp((dtyp)res0, -15); */ \ - /* dtyp _1 = ldexp((dtyp)res1, -15); */ \ - /* dtyp _2 = ldexp((dtyp)res2, -15); */ \ - /* dtyp _3 = ldexp((dtyp)res3, -15); */ \ - \ - dtyp _0 = (dtyp)res0 * (dtyp)(1.0 / 32768.0); \ - dtyp _1 = (dtyp)res1 * (dtyp)(1.0 / 32768.0); \ - dtyp _2 = (dtyp)res2 * (dtyp)(1.0 / 32768.0); \ - dtyp _3 = (dtyp)res3 * (dtyp)(1.0 / 32768.0); \ - \ - /* put value */ \ - store(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); \ - } while (++dstPos < (signed)dstSize); \ - \ - exit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); - - #define filterF4xNHor(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, pm) \ - filter4xNf(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, 0, fwh, float, float /*double*/) - - #define filterF4xNVer(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, pm) \ - filter4xNf(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, 0, fwv, float, float /*double*/) - - /* #################################################################################################################### \ - */ - #define resampleF4xNFromPlane(stride) \ - float _0, _1, _2, _3; \ - \ - _0 = (*i0)[ix], i0 += (stride) * dy; \ - _1 = (*i1)[ix], i1 += (stride) * dy; \ - _2 = (*i2)[ix], i2 += (stride) * dy; \ - _3 = (*i3)[ix], i3 += (stride) * dy; - - /* ******************************************************************************************************************** \ - */ - #define resampleF4xNFromStream(stride, instream) \ - float _0, _1, _2, _3; \ - \ - _0 = instream[0]; \ - _1 = instream[1]; \ - _2 = instream[2]; \ - _3 = instream[3], instream += (stride) * 4; - - /* ******************************************************************************************************************** \ - */ - #define resampleF4xNFromStreamSwapped(stride, instream) \ - float _0, _1, _2, _3; \ - \ - _3 = instream[0]; \ - _2 = instream[1]; \ - _1 = instream[2]; \ - _0 = instream[3], instream += (stride) * 4; - - /* #################################################################################################################### \ - */ - #define resampleF4xNToPlane(stride) \ - (*o0)[ox] = _0; \ - (*o1)[ox] = _1; \ - (*o2)[ox] = _2; \ - (*o3)[ox] = _3, ox += (1) * 1; - - /* ******************************************************************************************************************** \ - */ - #define resampleF4xNToStream(stride, outstream) \ - outstream[0] = _0; \ - outstream[1] = _1; \ - outstream[2] = _2; \ - outstream[3] = _3, outstream += (1) * 4; - - /* ******************************************************************************************************************** \ - */ - #define resampleF4xNToStreamSwapped(stride, outstream) \ - outstream[0] = _3; \ - outstream[1] = _2; \ - outstream[2] = _1; \ - outstream[3] = _0, outstream += (1) * 4; - - /* #################################################################################################################### \ - */ - #undef filterF4xNFromPlane - #define filterF4xNFromPlane(stride) \ - resampleF4xNFromPlane(stride) - - /* ******************************************************************************************************************** \ - */ - #undef filterF4xNFromStream - #define filterF4xNFromStream(stride, instream) \ - resampleF4xNFromStream(stride, instream) - - /* ******************************************************************************************************************** \ - */ - #undef filterF4xNFromStreamSwapped - #define filterF4xNFromStreamSwapped(stride, instream) \ - resampleF4xNFromStreamSwapped(stride, instream) - - /* #################################################################################################################### \ - */ - #undef filterF4xNToPlane - #define filterF4xNToPlane(stride) \ - resampleF4xNToPlane(stride) - - /* ******************************************************************************************************************** \ - */ - #undef filterF4xNToStream - #define filterF4xNToStream(stride, outstream) \ - resampleF4xNToStream(stride, outstream) - - /* ******************************************************************************************************************** \ - */ - #undef filterF4xNToStreamSwapped - #define filterF4xNToStreamSwapped(stride, outstream) \ - resampleF4xNToStreamSwapped(stride, outstream) - - /* #################################################################################################################### \ - */ - #define loopEnter(id, untill, advance) \ - unsigned int id; for (id = 0; id < untill; id += advance) { - #define loopLeave(id, untill, advance) \ - } - - /* #################################################################################################################### \ - */ - #define all4InitSwappablePlanePointers(left, top, row, rows, pp, swap, dtyp) \ - dtyp * pp##0, *pp##1, *pp##2, *pp##3; \ - \ - pp##0 = pp[0][/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)] + left; /* r */ \ - pp##1 = pp[1][/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)] + left; /* g */ \ - pp##2 = pp[2][/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)] + left; /* b */ \ - pp##3 = pp[3][/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)] + left; /* a */ - - #define allF4InitSwappablePlanePointers(left, top, row, rows, pp, swap) \ - all4InitSwappablePlanePointers(left, top, row, rows, pp, swap, float) - - /* #################################################################################################################### \ - */ - #define all4InitFixedPlanePointers(left, top, row, rows, pp, swap, dtyp) \ - dtyp * pp##0, *pp##1, *pp##2, *pp##3; \ - \ - pp##0 = pp[0][(row + top)] + left; /* r */ \ - pp##1 = pp[1][(row + top)] + left; /* g */ \ - pp##2 = pp[2][(row + top)] + left; /* b */ \ - pp##3 = pp[3][(row + top)] + left; /* a */ - - #define allF4InitFixedPlanePointers(left, top, row, rows, pp, swap) \ - all4InitFixedPlanePointers(left, top, row, rows, pp, swap, float) - - /* #################################################################################################################### \ - */ - #define all4InitSwappablePlaneReferences(left, offs, top, row, rows, pp, swap, dtyp) \ - unsigned long int pp##x = left + offs; \ - dtyp** pp##0; \ - dtyp** pp##1; \ - dtyp** pp##2; \ - dtyp** pp##3; \ - \ - pp##0 = pp[0] + (/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)); /* r */ \ - pp##1 = pp[1] + (/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)); /* g */ \ - pp##2 = pp[2] + (/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)); /* b */ \ - pp##3 = pp[3] + (/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)); /* a */ - - #define allF4InitSwappablePlaneReferences(left, offs, top, row, rows, pp, swap) \ - all4InitSwappablePlaneReferences(left, offs, top, row, rows, pp, swap, float) - - /* #################################################################################################################### \ - */ - #define all4InitFixedPlaneReferences(left, row, rows, pp, ps, dtyp) \ - unsigned long int pp##x = left; \ - dtyp** pp##0; \ - dtyp** pp##1; \ - dtyp** pp##2; \ - dtyp** pp##3; \ - \ - pp##0 = ps[0] + (row); /* r */ \ - pp##1 = ps[1] + (row); /* g */ \ - pp##2 = ps[2] + (row); /* b */ \ - pp##3 = ps[3] + (row); /* a */ - - #define allF4InitFixedPlaneReferences(left, row, rows, pp, ps) \ - all4InitFixedPlaneReferences(left, row, rows, pp, ps, float) - - /* #################################################################################################################### \ - */ - #define allF4AdvanceSwappablePlaneReferences(row, rows, pp) \ - pp##0 += (rows - row) * dy; /* r */ \ - pp##1 += (rows - row) * dy; /* g */ \ - pp##2 += (rows - row) * dy; /* b */ \ - pp##3 += (rows - row) * dy; /* a */ - - /* #################################################################################################################### \ - */ - #define allF4AdvanceFixedPlaneReferences(row, rows, pp) \ - allF4AdvanceSwappablePlaneReferences(row, rows, pp) - - /* #################################################################################################################### \ - */ - #define allF4AdvanceStreamPointer(left, col, cols, sp) \ - sp += ((cols) - (left + col)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvNMULStreamPointer(top, stride, sp) \ - sp -= ((stride) * (top)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvPMULStreamPointer(top, stride, sp) \ - sp += ((stride) * (top)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvSUBMStreamPointer(left, top, stride, sp) \ - sp -= (((stride) * (top)) - (left)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvADDMStreamPointer(left, top, stride, sp) \ - sp += ((left) + ((stride) * (top))) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvPADDStreamPointer(offs, sp) \ - sp += (offs) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvSSUBStreamPointer(top, shift, offs, sp) \ - sp += (((top) << (shift)) - (offs)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvNAMAStreamPointer(left, top, offs, stride, sp) \ - sp -= ((left) + (((top) + (offs)) * (stride))) * 4; - - /* ################################################################################################################### \ - */ - #undef comcpyFNum - #define comcpyFNum 1 - #undef orderedFNum - #define orderedFNum 1 - #undef orderedFShift - #define orderedFShift 0 - #undef interleavedFNum - #define interleavedFNum 1 - - /* #################################################################################################################### \ - */ - # define allTInitFixedOutPlaneReferences allF4InitFixedPlaneReferences - # define allTInitFixedInPlaneReferences allF4InitFixedPlaneReferences - # define allCInitSwappableInPlaneReferences /*allF4InitSwappablePlaneReferences*/ - # define allCInitSwappableOutPlaneReferences /*allF4InitSwappablePlaneReferences*/ - - # define allCAdvADDMInStreamPointer allF4AdvADDMStreamPointer - # define allCAdvPADDInStreamPointer allF4AdvPADDStreamPointer - # define allCAdvPMULInStreamPointer allF4AdvPMULStreamPointer - # define allCAdvNMULInStreamPointer allF4AdvNMULStreamPointer - # define allCAdvADDMOutStreamPointer allF4AdvADDMStreamPointer - # define allCAdvSSUBOutStreamPointer allF4AdvSSUBStreamPointer - - # define getCxNFromStreamSwapped /*filterF4xNFromStreamSwapped*/ - # define getCxNFromStream filterF4xNFromStream - # define getCxNFromPlane /*filterF4xNFromPlane*/ - # define getTxNFromPlane filterF4xNFromPlane - - # define filterHor filterF4xNHor - # define filterVer filterF4xNVer - - # define comcpyCCheckHiLo() /*orderedF4CheckHiLo*/ - # define comcpyCCoVar() /*orderedF4CoVar*/ - # define comcpyCHistogram() /*orderedF4Histogram*/ - - # define putCxNToStreamSwapped /*filterF4xNToStreamSwapped*/ - # define putCxNToStream filterF4xNToStream - # define putCxNToPlane /*filterF4xNToPlane*/ - # define putTxNToPlane filterF4xNToPlane - - # define orderedNum orderedFNum - # define orderedShift orderedFShift - - # define comcpyCMergeHiLo(orderedNum) /*comcpyFTMergeHiLo*/ - # define comcpyCCompleteCoVar(orderedNum) /*comcpyFTCompleteCoVar*/ - # define comcpyCCompleteHistogram(orderedNum) /*comcpyFTCompleteHistogram*/ - - # define hiloCVariables /*hiloFTVariables*/ - # define covarCVariables /*covarFTVariables*/ - # define histoCVariables /*histoFTVariables*/ - - # define filterCVariables filterFTVariables - - # define orderedTInitLoop() /*orderedTInitLoop*/ - # define hiloTInitLoop() /*hiloTInitLoop*/ - # define covarTInitLoop() /*covarTInitLoop*/ - # define histoTInitLoop() /*histoTInitLoop*/ - - # define orderedTExitLoop() /*orderedTExitLoop*/ - # define hiloTExitLoop() /*hiloTExitLoop*/ - # define covarTExitLoop() /*covarTExitLoop*/ - # define histoTExitLoop() /*histoTExitLoop*/ - - # define filterCCleanUp filterTCleanUp - - /* #################################################################################################################### \ - */ - - struct prcparm - { - /* configuration -------------------------------------------------------------------------------- */ - - /* dimensions of the source/destination image */ - int inrows, outrows, subrows; - int incols, outcols, subcols; - - /* region to process the stuff in */ - bool regional; - /* don't fetch data from outside the region */ - bool caged; - struct - { - /* offsets to the source/destination image-region */ - int intop, outtop, subtop; - int inleft, outleft, subleft; - - /* dimensions of the source/destination image-region */ - int inrows, outrows, subrows; - int incols, outcols, subcols; - } region; - - /* parameters ----------------------------------------------------------------------------------- */ - - /* parameters for resampling */ - struct - { - /* we don't give floating-point x/y-factor, it's not exact enough */ - unsigned int rowquo, rowrem; - unsigned int colquo, colrem; - - /* over/under-blurring (window minification/magnification) */ - float rowblur, colblur; - - /* the windowing-function for the filtering */ - IWindowFunction* wf; - - /* operation to perform the filter with */ - int operation; - } resample; - - /* private stuff -------------------------------------------------------------------------------- */ - - /* what really has do be done after choosing/recalculation */ - int dorows, docols; - }; - - static void CheckBoundaries(const void* i, void* o, struct prcparm* parm) - { - /* the parameter evaluation ----------------------------------------------- */ - const bool scaler = true; - - /* this is fairly straightforward */ - if (!parm->regional) - { - int rgrows = parm->inrows; - int rgcols = parm->incols; - - /* compare out-region against available out-size */ - if (o) - { - int dorows = parm->outrows; - int docols = parm->outcols; - - /* scale up */ - if (scaler) - { - dorows = dorows * parm->resample.rowrem / parm->resample.rowquo; - docols = docols * parm->resample.colrem / parm->resample.colquo; - } - - /* compare in scaled space */ - rgrows = maximum(rgrows, dorows); - rgcols = maximum(rgcols, docols); - - /* scale down */ - if (scaler) - { - rgrows = rgrows * parm->resample.rowquo / parm->resample.rowrem; - rgcols = rgcols * parm->resample.colquo / parm->resample.colrem; - } - } - - parm->dorows = rgrows; - parm->docols = rgcols; - } - /* this may need some adjustment */ - else - { - int rgrows = parm->region.inrows; - int rgcols = parm->region.incols; - - /* compare in/out-region against available out-size */ - if (o) - { - int dorows = parm->region.outrows; - int docols = parm->region.outcols; - - /* compare out-region against available in-size */ - if (dorows > parm->outrows - parm->region.outtop) - { - dorows = parm->outrows - parm->region.outtop; - } - if (docols > parm->outcols - parm->region.outleft) - { - docols = parm->outcols - parm->region.outleft; - } - - /* scale to in */ - if (scaler) - { - dorows = dorows * parm->resample.rowrem / parm->resample.rowquo; - docols = docols * parm->resample.colrem / parm->resample.colquo; - } - - /* compare in scaled space */ - rgrows = maximum(rgrows, dorows); - rgcols = maximum(rgcols, docols); - - /* compare in-region against available in-size */ - if (i) - { - if (rgrows > parm->inrows - parm->region.intop) - { - rgrows = parm->inrows - parm->region.intop; - } - if (rgcols > parm->incols - parm->region.inleft) - { - rgcols = parm->incols - parm->region.inleft; - } - } - - /* scale to out */ - if (scaler) - { - rgrows = rgrows * parm->resample.rowquo / parm->resample.rowrem; - rgcols = rgcols * parm->resample.colquo / parm->resample.colrem; - } - } - else - { - /* compare in-region against available in-size */ - if (i) - { - if (rgrows > parm->inrows - parm->region.intop) - { - rgrows = parm->inrows - parm->region.intop; - } - if (rgcols > parm->incols - parm->region.inleft) - { - rgcols = parm->incols - parm->region.inleft; - } - } - } - - parm->dorows = rgrows; - parm->docols = rgcols; - } - - AZ_Assert(parm->dorows > 0, "%s: Expect row count to be above zero!", __FUNCTION__); - AZ_Assert(parm->docols > 0, "%s: Expect column count to be above zero!", __FUNCTION__); - } - - /* #################################################################################################################### \ - * multi-threadable if needed - */ - static void RunAlgorithm(const float* i, float* o, struct prcparm* parm) - { - /* make these local, so no indirect access is needed */ - const unsigned int srcrows = parm->dorows * parm->resample.rowrem / parm->resample.rowquo; - const unsigned int srccols = parm->docols * parm->resample.colrem / parm->resample.colquo; - const unsigned int dstrows = parm->dorows; - const unsigned int dstcols = parm->docols; - const unsigned int cstZero = 0; - - /* temporary buffer region */ - parm->subrows = srccols; - parm->subcols = dstrows; - parm->region.subleft = 0; - parm->region.subtop = 0; - parm->region.subcols = parm->subcols; - parm->region.subrows = parm->subrows; - - if (!parm->caged) - { - int oleft; - int oright; - - /* check for out-of-region access rectangle */ - calculateFilterRange(srccols, oleft, oright, dstcols, 0, dstcols, parm->resample.colblur, parm->resample.wf); - - /* round down left, round up right */ - oleft = oleft & (~(orderedNum - 1)); - oright = (oright + (orderedNum - 1)) & (~(orderedNum - 1)); - - /* clamp to available image-rectangle */ - if ((oleft < (signed)parm->region.subtop) || - (oright > (signed)parm->subrows)) - { - oleft = maximum(oleft, -(signed)parm->region.inleft); - oright = minimum(oright, (signed)parm->incols); - } - - /* readjust temporary buffer region to include out-of-region accesses */ - parm->region.inleft += oleft; //rm->docols -= oleft; //rm->docols += (oright - srccols); - parm->region.subtop -= oleft; - parm->subrows -= oleft; - parm->subrows += (oright - srccols); - } - - const unsigned int tmprows = parm->subrows; - const unsigned int tmpcols = parm->subcols; - - /* -------------------------------------------------------------------------------------------- - * common resampling - */ - - /* init t */ - filterCVariables(orderedNum); - - filterTInitLoop(); - - /* -------------------------------------------------------------------------------------------- - * reading rows, writing cols (xy-flip) - * - * make srccol x inrow -> dstrow x srccol - * - * we are reading vertical, and writing horizontal - * in effect we can use fast parallel-reads, but need - * slow interleaved-writes - * as reads are slower (ask+receive) than writes (send) - * this should even be gracefully fast - */ - allCAdvADDMInStreamPointer(parm->region.inleft, parm->region.intop, parm->incols, i); - - #define filterRowInit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - allTInitFixedOutPlaneReferences(cstZero, srcOffs, -, o, t); - - #define filterRowNext(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* every in/out-put may swap */ \ - allCInitSwappableInPlaneReferences(parm->region.inleft, srcOffs, parm->region.intop, fw.first, parm->inrows, i, false); \ - /* because the filter moves back and forth, we always have to reposition from 0 */ \ - allCAdvPMULInStreamPointer(srcSkip##raw, fw.first, i); - - #define filterRowFetch(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* vertical stride, horizontal fetch */ \ - getCxNFromStreamSwapped(srcSkip, i); \ - getCxNFromStream(srcSkip, i); \ - getCxNFromPlane(1); \ - \ - /*srcPos++;*/ - - #define filterRowStore(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* because the filter moves back and forth, we always have to reposition to 0 */ \ - allCAdvNMULInStreamPointer(srcSkip##raw, fw.last, i); \ - \ - /* horizontal stride, vertical store */ \ - putTxNToPlane(1); \ - \ - /*dstPos++;*/ - - #define filterRowExit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - allCAdvPADDInStreamPointer(orderedNum, i); - - if (parm->resample.operation == eWindowEvaluation_Sum) - { - loopEnter(tmprow, tmprows, orderedNum); - - { - filterVer(tmprow, srcrows, stridei, - tmprow, dstrows, stridet, filterRowInit, filterRowNext, filterRowFetch, filterRowStore, filterRowExit, eWindowEvaluation_Sum, of); - } - - loopLeave(tmprow, tmprows, orderedNum); - } - else if (parm->resample.operation == eWindowEvaluation_Max) - { - loopEnter(tmprow, tmprows, orderedNum); - - { - filterVer(tmprow, srcrows, stridei, - tmprow, dstrows, stridet, filterRowInit, filterRowNext, filterRowFetch, filterRowStore, filterRowExit, eWindowEvaluation_Max, of); - } - - loopLeave(tmprow, tmprows, orderedNum); - } - else if (parm->resample.operation == eWindowEvaluation_Min) - { - loopEnter(tmprow, tmprows, orderedNum); - - { - filterVer(tmprow, srcrows, stridei, - tmprow, dstrows, stridet, filterRowInit, filterRowNext, filterRowFetch, filterRowStore, filterRowExit, eWindowEvaluation_Min, of); - } - - loopLeave(tmprow, tmprows, orderedNum); - } - - /* 1st resampling end - * -------------------------------------------------------------------------------------------- - */ - filterTExitLoop(); - - /* return collected min/max */ - hiloCVariables(orderedNum); - covarCVariables(orderedNum); - histoCVariables(orderedNum); - - /* --------------------------------------------------------------- */ - orderedTInitLoop(); - filterTInitLoop(); - - hiloTInitLoop(); - covarTInitLoop(); - histoTInitLoop(); - - /* -------------------------------------------------------------------------------------------- - * reading rows, writing cols (xy-flip) - * - * make dstrow x srccol -> outcol x dstrow - * - * we are reading vertical, and writing horizontal - * in effect we can use fast parallel-reads, but need - * slow interleaved-writes - * as reads are slower (ask+receive) than writes (send) - * this should even be gracefully fast - */ - allCAdvADDMOutStreamPointer(parm->region.outleft, parm->region.outtop, parm->outcols, o); - - #define filterColInit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - allCInitSwappableOutPlaneReferences(parm->region.outleft, cstZero, parm->region.outtop, srcOffs, parm->outrows, o, false); - - #define filterColNext(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* every in/out-put may swap */ \ - allTInitFixedInPlaneReferences(srcOffs, parm->region.subtop + fw.first, -, i, t); - - #define filterColFetch(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* vertical stride, horizontal fetch */ \ - getTxNFromPlane(1); \ - \ - /*srcPos++;*/ - - #define filterColStore(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - comcpyCCheckHiLo(); \ - comcpyCCoVar(); \ - comcpyCHistogram(); \ - \ - /* horizontal stride, vertical store */ \ - putCxNToStreamSwapped(dstSkip, o); \ - putCxNToStream(dstSkip, o); \ - putCxNToPlane(1); \ - \ - /*dstPos++;*/ - - #define filterColExit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - allCAdvSSUBOutStreamPointer(dstSkip##raw, orderedShift, dstPos, o); - - if (parm->resample.operation == eWindowEvaluation_Sum) - { - loopEnter(dstrow, dstrows, orderedNum); - - { - filterHor(dstrow, srccols, stridet, - dstrow, dstcols, strideo, filterColInit, filterColNext, filterColFetch, filterColStore, filterColExit, eWindowEvaluation_Sum, of); - } - - loopLeave(dstrow, dstrows, orderedNum); - } - else if (parm->resample.operation == eWindowEvaluation_Max) - { - loopEnter(dstrow, dstrows, orderedNum); - - { - filterHor(dstrow, srccols, stridet, - dstrow, dstcols, strideo, filterColInit, filterColNext, filterColFetch, filterColStore, filterColExit, eWindowEvaluation_Max, of); - } - - loopLeave(dstrow, dstrows, orderedNum); - } - else if (parm->resample.operation == eWindowEvaluation_Min) - { - loopEnter(dstrow, dstrows, orderedNum); - - { - filterHor(dstrow, srccols, stridet, - dstrow, dstcols, strideo, filterColInit, filterColNext, filterColFetch, filterColStore, filterColExit, eWindowEvaluation_Min, of); - } - - loopLeave(dstrow, dstrows, orderedNum); - } - - /* 2nd resampling end - * -------------------------------------------------------------------------------------------- - */ - histoTExitLoop(); - covarTExitLoop(); - hiloTExitLoop(); - - filterTExitLoop(); - orderedTExitLoop(); - /* --------------------------------------------------------------- */ - - /* return collected min/max */ - comcpyCMergeHiLo(orderedNum); - comcpyCCompleteCoVar(orderedNum); - comcpyCCompleteHistogram(orderedNum); - - /* exit t */ - filterCCleanUp(orderedNum); - } - - // TODO: not working yet, debug and enable - //static void SplitAlgorithm(const void* i, void* o, struct prcparm* templ, int threads = 8) - //{ - // struct prcparm fraction[32]; - // int t, istart = 0, sstart = 0, ostart = 0; - // const bool scaler = true; - - // int theight = 0; - - // /* prepare data to be emitted to the threads */ - // for (t = 0; t < threads; t++) - // { - // fraction[t] = *templ; - - // /* adjust the processing-region according to the available threads */ - // { - //#undef split /* only prefix-threads need aligned transpose (for not trashing suffix-thread data) */ - //#define split(rows) !scaler \ - // ? ((rows * (t + 1)) / threads) & (~(t != threads - 1 ? 15 : 0)) \ - // : ((rows * (t + 1)) / threads) & (~0) - - // /* area covered */ - // const int inrows = (fraction[t].regional ? fraction[t].region.inrows : fraction[t].inrows); - // const int incols = (fraction[t].regional ? fraction[t].region.incols : fraction[t].incols); - // const int subrows = (fraction[t].regional ? fraction[t].region.subrows : fraction[t].subrows); - // const int subcols = (fraction[t].regional ? fraction[t].region.subcols : fraction[t].subcols); - // const int outrows = (fraction[t].regional ? fraction[t].region.outrows : fraction[t].outrows); - // const int outcols = (fraction[t].regional ? fraction[t].region.outcols : fraction[t].outcols); - - // /* splitting blocks */ - // const int istop = split(inrows), sstop = split(subrows), ostop = split(outrows); - // const int irows = istop - istart, srows = sstop - sstart, orows = ostop - ostart; - // const int icols = incols, scols = subcols, ocols = outcols; - - // AZ_Assert(irows > 0, "%s: Expect row count to be above zero!", __FUNCTION__); - // AZ_Assert(orows > 0, "%s: Expect row count to be above zero!", __FUNCTION__); - // AZ_Assert(icols > 0, "%s: Expect column count to be above zero!", __FUNCTION__); - // AZ_Assert(ocols > 0, "%s: Expect column count to be above zero!", __FUNCTION__); - - // /* now we are regional */ - // fraction[t].regional = true; - - // /* take previous regionality into account */ - // fraction[t].region.intop += istart; - // fraction[t].region.subtop += sstart; - // fraction[t].region.outtop += ostart; - // fraction[t].region.inrows = irows; - // fraction[t].region.subrows = srows; - // fraction[t].region.outrows = orows; - - // /* take previous regionality into account */ - // fraction[t].region.inleft += 0; - // fraction[t].region.subleft += 0; - // fraction[t].region.outleft += 0; - // fraction[t].region.incols = icols; - // fraction[t].region.subcols = scols; - // fraction[t].region.outcols = ocols; - - // /* advance block */ - // istart = istop; - // sstart = sstop; - // ostart = ostop; - - // /* check */ - // theight += irows; - // } - - // // the algorithm supports "i" and "o" pointing to the same memory - // CheckBoundaries((float*)i, (float*)o, &fraction[t]); - // RunAlgorithm((float*)i, (float*)o, &fraction[t]); - // } - - // AZ_Assert(theight >= (templ->regional ? templ->region.inrows : templ->inrows), "%s: Invalid height!", __FUNCTION__); - //} - - /* #################################################################################################################### \ - */ - void FilterImage(int filterIndex, int filterOp, float blurH, float blurV, const IImageObjectPtr srcImg, int srcMip, - IImageObjectPtr dstImg, int dstMip, QRect* srcRect, QRect* dstRect) - { - //only support ePixelFormat_R32G32B32A32F - if (srcImg->GetPixelFormat() != ePixelFormat_R32G32B32A32F || dstImg->GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "FilterImage only support both source and dest image objects have pixel format R32G32B32A32F"); - return; - } - - uint32 srcWidth, srcHeight; - uint8* pSrcMem; - uint32 dwSrcPitch; - - srcImg->GetImagePointer(srcMip, pSrcMem, dwSrcPitch); - - srcWidth = srcImg->GetWidth(srcMip); - srcHeight = srcImg->GetHeight(srcMip); - - uint32 dstWidth, dstHeight; - uint8* pDestMem; - uint32 dwDestPitch; - - dstImg->GetImagePointer(dstMip, pDestMem, dwDestPitch); - - dstWidth = dstImg->GetWidth(dstMip); - dstHeight = dstImg->GetHeight(dstMip); - - { - struct prcparm parm; - memset(&parm, 0, sizeof(parm)); - - parm.incols = srcWidth; - parm.inrows = srcHeight; - parm.outcols = dstWidth; - parm.outrows = dstHeight; - parm.regional = false; - parm.caged = false; - - if (srcRect || dstRect) - { - parm.regional = true; - parm.caged = true; - - parm.region.inleft = (!srcRect ? 0 : srcRect->left()); - parm.region.intop = (!srcRect ? 0 : srcRect->top()); - parm.region.incols = (!srcRect ? parm.incols : srcRect->right() - srcRect->left()); - parm.region.inrows = (!srcRect ? parm.inrows : srcRect->bottom() - srcRect->top()); - - parm.region.outleft = (!dstRect ? 0 : dstRect->left()); - parm.region.outtop = (!dstRect ? 0 : dstRect->top()); - parm.region.outcols = (!dstRect ? parm.outcols : dstRect->right() - dstRect->left()); - parm.region.outrows = (!dstRect ? parm.outrows : dstRect->bottom() - dstRect->top()); - - if (!srcRect) - { - parm.region.inleft = parm.region.outleft * srcHeight / dstHeight; - parm.region.intop = parm.region.outtop * srcWidth / dstWidth; - } - - if (!dstRect) - { - parm.region.outleft = parm.region.inleft * dstHeight / srcHeight; - parm.region.outtop = parm.region.intop * dstWidth / srcWidth; - } - } - - parm.resample.colquo = dstWidth; - parm.resample.colrem = srcWidth; - parm.resample.rowquo = dstHeight; - parm.resample.rowrem = srcHeight; - parm.resample.rowblur = blurH; - parm.resample.colblur = blurV; - parm.resample.operation = filterOp; - - switch (filterIndex) - { - // case eWindowFunction_COMBINER : parm.resample.wf = new CombinerWindowFunction(..., ...); break; - case eWindowFunction_Point: - parm.resample.wf = new PointWindowFunction(); - break; - case eWindowFunction_Box: - parm.resample.wf = new BoxWindowFunction(); - break; - case eWindowFunction_Triangle: - parm.resample.wf = new TriangleWindowFunction(); - break; - case eWindowFunction_Quadric: - parm.resample.wf = new QuadricWindowFunction(); - break; - case eWindowFunction_Cubic: - parm.resample.wf = new CubicWindowFunction(); - break; - case eWindowFunction_Hermite: - parm.resample.wf = new HermiteWindowFunction(); - break; - case eWindowFunction_Catrom: - parm.resample.wf = new CatromWindowFunction(); - break; - case eWindowFunction_Sine: - parm.resample.wf = new SineWindowFunction(); - break; - case eWindowFunction_Sinc: - parm.resample.wf = new SincWindowFunction(); - break; - case eWindowFunction_Bessel: - parm.resample.wf = new BesselWindowFunction(); - break; - case eWindowFunction_Lanczos: - parm.resample.wf = new LanczosWindowFunction(); - break; - case eWindowFunction_Gaussian: - parm.resample.wf = new GaussianWindowFunction(); - break; - case eWindowFunction_Normal: - parm.resample.wf = new NormalWindowFunction(); - break; - case eWindowFunction_Mitchell: - parm.resample.wf = new MitchellWindowFunction(); - break; - case eWindowFunction_Hann: - parm.resample.wf = new HannWindowFunction(); - break; - case eWindowFunction_BartlettHann: - parm.resample.wf = new BartlettHannWindowFunction(); - break; - case eWindowFunction_Hamming: - parm.resample.wf = new HammingWindowFunction(); - break; - case eWindowFunction_Blackman: - parm.resample.wf = new BlackmanWindowFunction(); - break; - case eWindowFunction_BlackmanHarris: - parm.resample.wf = new BlackmanHarrisWindowFunction(); - break; - case eWindowFunction_BlackmanNuttall: - parm.resample.wf = new BlackmanNuttallWindowFunction(); - break; - case eWindowFunction_Flattop: - parm.resample.wf = new FlatTopWindowFunction(); - break; - case eWindowFunction_Kaiser: - parm.resample.wf = new KaiserWindowFunction(); - break; - - case eWindowFunction_SigmaSix: - parm.resample.wf = new SigmaSixWindowFunction(); - break; - case eWindowFunction_KaiserSinc: - parm.resample.wf = new CombinerWindowFunction(new SincWindowFunction(), new KaiserWindowFunction()); - break; - - default: - abort(); - break; - } - - // TODO: not working yet, debug and enable - // SplitAlgorithm(pSrcMem, pDestMem, &parm); - - // the algorithm supports "pSrcMem" and "pDestMem" pointing to the same memory - CheckBoundaries((float*)pSrcMem, (float*)pDestMem, &parm); - RunAlgorithm((float*)pSrcMem, (float*)pDestMem, &parm); - - delete parm.resample.wf; - } - } - - int MipGenTypeToFilterIndex(MipGenType filterType) - { - switch (filterType) - { - case MipGenType::point: - return eWindowFunction_Point; - case MipGenType::box: - return eWindowFunction_Box; - case MipGenType::triangle: - return eWindowFunction_Triangle; - case MipGenType::quadratic: - return eWindowFunction_Bilinear; - case MipGenType::gaussian: - return eWindowFunction_Gaussian; - case MipGenType::blackmanHarris: - return eWindowFunction_BlackmanHarris; - case MipGenType::kaiserSinc: - return eWindowFunction_KaiserSinc; - default: - AZ_Assert(false, "unable find filter type for mipmap gen type %d", filterType); - return eWindowFunction_BlackmanHarris; - } - } - - /* #################################################################################################################### \ - */ - void FilterImage(MipGenType filterType, MipGenEvalType evalType, float blurH, float blurV, const IImageObjectPtr srcImg, int srcMip, - IImageObjectPtr dstImg, int dstMip, QRect* srcRect, QRect* dstRect) - { - int filterIndex = MipGenTypeToFilterIndex(filterType); - int filterOp = static_cast(evalType); - FilterImage(filterIndex, filterOp, blurH, blurV, srcImg, srcMip, dstImg, dstMip, srcRect, dstRect); - } - -} diff --git a/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.cpp b/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.cpp deleted file mode 100644 index d5d9d617c4..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include -#include "FIR-Weights.h" - -/* #################################################################################################################### - */ - -namespace ImageProcessing -{ - void calculateFilterRange(unsigned int srcFactor, int& srcFirst, int& srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, - double blurFactor, class IWindowFunction* windowFunction) - { - double s, t, u, scaleFactor; /* scale factors */ - double srcRadius, srcCenter; /* window position and size */ - -#define s0 0 -#define s1 srcFactor -#define d0 0 -#define d1 dstFactor - - /* the mapping from discrete destination coordinates to continuous source coordinates: */ -#define MAP(b, scaleFactor, offset) ((b) + (offset)) / (scaleFactor) - - /* relation of dstFactor to srcFactor */ - s = (double)dstFactor / srcFactor; - t = d0 - s * (s0 - 0.5) - 0.5; - - /* compute offsets for MAP */ - u = d0 - s * (s0 - 0.5) - t; - - /* find scale of filter - * when minifying, scaleFactor = 1/s, but when magnifying, scaleFactor = 1 - */ - scaleFactor = (blurFactor == 0.0 ? 1.0 : (blurFactor > 0.0 ? (1.0 + blurFactor) : 1.0 / (1.0 - blurFactor))) * maximum(1., 1. / s); - - /* find support radius of scaled filter - * if the window's length is <= 0.5 then we've got point sampling. - */ - srcRadius = maximum(0.5, scaleFactor * windowFunction->getLength()); - - /* sample the continuous filter, scaled by scaleFactor and - * positioned at continuous source coordinate srcCenter - */ - { - srcCenter = MAP(dstFirst + 0, s, u); - - /* find the source coordinate range of this positioned filter window */ - srcFirst = int(floor(srcCenter - srcRadius + 0.5)); - } - - { - srcCenter = MAP(dstLast - 1, s, u); - - /* find the source coordinate range of this positioned filter window */ - srcLast = int(floor(srcCenter + srcRadius + 0.5)); - } - } - - template<> - FilterWeights* calculateFilterWeights(unsigned int srcFactor, int srcFirst, int srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, signed short int numRepetitions, - double blurFactor, class IWindowFunction* windowFunction, - bool peaknorm, bool& plusminus) - - { -#define WEIGHTBITS 15 -#define WEIGHTONE (1 << WEIGHTBITS) /* filter weight of one */ - - double s, t, u, scaleFactor; /* scale factors */ - double srcRadius, srcCenter; /* window position and size */ - double sumfWeights, neg, pos, nrmWeights, fWeight; /* window position and size */ - int i, i0, i1; /* window position and size */ - int dstPosition; - signed short int n; - bool trimZeros = true, stillzero; - int lastnonzero, hWeight, highest; - signed int sumiWeights, iWeight; - signed short int* weightsPtr, *weightsMem; - FilterWeights* weightsObjs; - bool pm, pma = false; - - /* pre-calculate filter window solutions for all rows - */ - weightsObjs = new FilterWeights[dstLast - dstFirst]; - -#define s0 0 -#define s1 srcFactor -#define d0 0 -#define d1 dstFactor - - /* relation of dstFactor to srcFactor */ - s = (double)dstFactor / srcFactor; - t = d0 - s * (s0 - 0.5) - 0.5; - - /* compute offsets for MAP */ - u = d0 - s * (s0 - 0.5) - t; - - /* find scale of filter - * when minifying, scaleFactor = 1/s, but when magnifying, scaleFactor = 1 - */ - scaleFactor = (blurFactor == 0.0 ? 1.0 : (blurFactor > 0.0 ? (1.0 + blurFactor) : 1.0 / (1.0 - blurFactor))) * maximum(1., 1. / s); - - /* find support radius of scaled filter - * if the window's length is <= 0.5 then we've got point sampling. - */ - srcRadius = maximum(0.5, scaleFactor * windowFunction->getLength()); - - /* sample the continuous filter, scaled by ap->scaleFactor and - * positioned at continuous source coordinate srcCenter, for source coordinates in - * the range [0..len-1], writing the weights into wtab. - * Scale the weights so they sum up to WEIGHTONE, and trim leading and trailing - * zeros if trimZeros is true. - */ -#undef NORMALIZE_SUMMED_PEAK -#define NORMALIZE_MAXXED_PEAK - for (dstPosition = dstFirst, pm = false; dstPosition < dstLast; dstPosition++) - { - srcCenter = MAP(dstPosition, s, u); - - /* find the source coordinate range of this positioned filter window */ - i0 = int(floor(srcCenter - srcRadius + 0.5)); - i1 = int(floor(srcCenter + srcRadius + 0.5)); - - /* clip against the source-range */ - if (i0 < srcFirst) - { - i0 = srcFirst; - } - if (i1 > srcLast) - { - i1 = srcLast; - } - - /* this is possible if we hit the final line */ - if (i1 <= i0) - { - if (i1 >= srcLast) - { - i0 = i1 - 1; - } - else - { - i1 = i0 + 1; - } - } - - AZ_Assert(i0 >= srcFirst, "%s: Invalid source coordinate range!", __FUNCTION__); - AZ_Assert(i1 <= srcLast, "%s: Invalid source coordinate range!", __FUNCTION__); - AZ_Assert(i0 < i1, "%s: Invalid source coordinate range!", __FUNCTION__); - - /* find maximum peak to normalize the filter */ - for (sumfWeights = 0, pos = 0, neg = 0, i = i0; i < i1; i++) - { - /* evaluate the filter function: */ - fWeight = (*windowFunction)((i + 0.5 - srcCenter) / scaleFactor); - -#if defined(NORMALIZE_SUMMED_PEAK) - /* get positive and negative summed peaks */ - if (fWeight >= 0) - { - pos += fWeight; - } - else - { - neg += fWeight; - } -#elif defined(NORMALIZE_MAXXED_PEAK) - /* get positive and negative maximum peaks */ - minmax(fWeight, neg, pos); -#endif - - sumfWeights += fWeight; - } - - /* the range of source samples to buffer: */ - weightsMem = new signed short int[(i1 - i0) * abs(numRepetitions)]; - - /* set nrmWeights so that sumWeights of windowFunction() is approximately WEIGHTONE - * this needs to be adjusted because the maximum weight-coefficient - * is NOT allowed to leave [-32768,32767] - * a case like {+1.25,-0.25} does produce a sumWeights of 1.0 BUT - * produced a weight much too high (-40000) - */ -#if defined(NORMALIZE_SUMMED_PEAK) - sumfWeights = maximum(-neg, pos); -#elif defined(NORMALIZE_MAXXED_PEAK) - sumfWeights = maximum(sumfWeights, maximum(-neg, pos)); -#endif - - if (!peaknorm) - { - nrmWeights = (sumfWeights == 0. ? WEIGHTONE : (-neg > pos ? WEIGHTONE - 1 : WEIGHTONE) / sumfWeights); - } - else - { - nrmWeights = (sumfWeights == 0. ? WEIGHTONE : (-neg > pos ? WEIGHTONE - 1 : WEIGHTONE) / maximum(-neg, pos)); - } - - /* compute the discrete, sampled filter coefficients */ - stillzero = trimZeros; - for (sumiWeights = 0, hWeight = -WEIGHTONE, weightsPtr = weightsMem, i = i0; i < i1; i++) - { - /* evaluate the filter function: */ - fWeight = (*windowFunction)((i + 0.5 - srcCenter) / scaleFactor); - - /* normalize against the peak sumWeights, because the sums are not allowed to leave -32768/32767 */ - fWeight = fWeight * nrmWeights; - iWeight = int(round(fWeight)); - - /* find first nonzero */ - if (stillzero && (iWeight == 0)) - { - i0++; - } - else - { - AZ_Assert((-fWeight >= -32768.5) && (-fWeight <= 32767.5), "%s:The weight exceeded the maximum weight-coefficient.", __FUNCTION__); - - if (!peaknorm) - { - sumiWeights += iWeight; - } - else - { - sumiWeights = maximum(sumiWeights, iWeight); - } - -#define sgnextend(n, iWeight) (n & 1 ? (iWeight < 0 ? -1 : 0) : iWeight) - if (numRepetitions < 0) - { - /* add weight to table, interleaved sign */ - for (n = 0; n < -numRepetitions; n++) - { - *weightsPtr++ = sgnextend(n, -iWeight); - } - } - else - { - /* add weight to table */ - for (n = 0; n < numRepetitions; n++) - { - *weightsPtr++ = -iWeight; - } - } - - stillzero = false; - - /* find last nonzero */ - if (iWeight != 0) - { - lastnonzero = i; - } - - /* check for negative values */ - if (iWeight < 0) - { - pm = pma = true; - } - - /* find most influential value */ - if (iWeight >= hWeight) - { - highest = i; - hWeight = iWeight; - } - } - } - - if (sumiWeights == 0) - { - i0 = (i0 + i1) >> 1; - i1 = (i0 + 1); - - for (n = 0, weightsPtr = weightsMem; n < numRepetitions; n++) - { - *weightsPtr++ = -WEIGHTONE; - } - } - else - { - /* skip leading and trailing zeros */ - if (trimZeros) - { - /* set i0 and i1 to the nonzero support of the filter */ - i0 = i0; - i1 = i1 = lastnonzero + 1; - } - - if (sumiWeights != WEIGHTONE) - { - /* Fudge with the highest value */ - i = highest; - - /* fudge srcCenter sample */ - iWeight = WEIGHTONE - sumiWeights; - - for (n = 0, weightsPtr = weightsMem + (i - i0) * numRepetitions; n < numRepetitions; n++) - { - *weightsPtr++ -= iWeight; - } - } - } - - /* the new adjusted range of source samples to buffer: */ - weightsObjs[dstPosition].first = i0; - weightsObjs[dstPosition].last = i1; - weightsObjs[dstPosition].hasNegativeWeights = pm; - weightsObjs[dstPosition].weights = weightsMem; - } - - plusminus = pma; - return weightsObjs; - } -} diff --git a/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.h b/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.h deleted file mode 100644 index 0dee77aa1a..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "FIR-Windows.h" - -namespace ImageProcessing -{ - /* #################################################################################################################### - */ - template - inline DataType abs (const DataType& ths) { return (ths < 0 ? -ths : ths); } - template - inline void minmax (const DataType& ths, DataType& mn, DataType& mx) { mn = (mn > ths ? ths : mn); mx = (mx < ths ? ths : mx); } - template - inline DataType minimum(const DataType& ths, const DataType& tht) { return (ths < tht ? ths : tht); } - template - inline DataType maximum(const DataType& ths, const DataType& tht) { return (ths > tht ? ths : tht); } - - /* #################################################################################################################### - */ - - template - class FilterWeights - { - public: - FilterWeights() - : weights(nullptr) - { - } - - ~FilterWeights() - { - delete[] weights; - } - - public: - // window-position - int first, last; - - // do we encounter positive as well as negative weights - bool hasNegativeWeights; - - /* weights, summing up to -(1 << 15), - * means weights are given negative - * that enables us to use signed short - * multiplication while occupying 0x8000 - */ - T* weights; - }; - - /* #################################################################################################################### - */ - - void calculateFilterRange (unsigned int srcFactor, int& srcFirst, int& srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, - double blurFactor, class IWindowFunction* windowFunction); - - template - FilterWeights* calculateFilterWeights(unsigned int srcFactor, int srcFirst, int srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, signed short int numRepetitions, - double blurFactor, class IWindowFunction* windowFunction, - bool peaknorm, bool& plusminus); - - template<> - FilterWeights* calculateFilterWeights(unsigned int srcFactor, int srcFirst, int srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, signed short int numRepetitions, - double blurFactor, class IWindowFunction* windowFunction, - bool peaknorm, bool& plusminus); - - -} //end namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/FIR-Windows.h b/Gems/ImageProcessing/Code/Source/Converters/FIR-Windows.h deleted file mode 100644 index b814d911d0..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/FIR-Windows.h +++ /dev/null @@ -1,1283 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : A collection of window functions with Finite Impulse Response FIR -// and some helper window functions with Infinite Impulse Response IIR - -#pragma once -#include -#include - -/* #################################################################################################################### - */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -//the original file was from cry's RC.exe with all the filters. We decided we would only use few of them for users -namespace ImageProcessing -{ - template - F cube(const F& op) { return op * op * op; } - - template - F square(F fOp) { return(fOp * fOp); } - - enum EWindowFunction - { - eWindowFunction_Combiner = 0, - - /*--------------- unit-area filters for unit-spaced samples ----------------*/ - eWindowFunction_Point = 1, - - eWindowFunction_Box = 2, // box, pulse, Fourier window, 1st order (constant) b-spline - eWindowFunction_Triangle = 3, // triangle, Bartlett window, 2nd order (linear) b-spline - eWindowFunction_Linear = eWindowFunction_Triangle, - eWindowFunction_Bartlett = eWindowFunction_Triangle, - - eWindowFunction_Quadric = 4, // 3rd order (quadratic) b-spline - eWindowFunction_Bilinear = eWindowFunction_Quadric, - eWindowFunction_Welch = eWindowFunction_Quadric, - eWindowFunction_Cubic = 5, // 4th order (cubic) b-spline - eWindowFunction_Hermite = 6, // 4th order (cubic hermite) b-spline - eWindowFunction_Catrom = 7, // Catmull-Rom spline, Overhauser spline - - eWindowFunction_Sine = 8, // IIR - eWindowFunction_Sinc = 9, // Sinc, perfect lowpass filter (infinite) - eWindowFunction_Bessel = 10, // Bessel (for circularly symm. 2-d filt, inf) - eWindowFunction_Lanczos = 11, // Lanczos filtering, windowed Sinc - - /*------------------ filters for non-unit spaced samples -------------------*/ - eWindowFunction_Gaussian = 12, // Gaussian (infinite) - eWindowFunction_Normal = 13, // Normal distribution (infinite) - - /*------------------------- parameterized filters --------------------------*/ - eWindowFunction_Mitchell = 14, // Mitchell & Netravali's two-param cubic - - /*--------------------------- window functions -----------------------------*/ - eWindowFunction_Hann = 15, // Hanning window - eWindowFunction_BartlettHann = 16, - eWindowFunction_Hamming = 17, // Hamming window - eWindowFunction_Blackman = 18, // Blackman window - eWindowFunction_BlackmanHarris = 19, - eWindowFunction_BlackmanNuttall = 20, - eWindowFunction_Flattop = 21, - - /*------------------------- parameterized windows --------------------------*/ - eWindowFunction_Kaiser = 22, // parameterized Kaiser window - - /*---------------------------- custom windows ------------------------------*/ - eWindowFunction_SigmaSix = 23, // two Normal distributions - eWindowFunction_KaiserSinc = 24, // Kaiser and Sinc - - eWindowFunction_Num = eWindowFunction_KaiserSinc + 1, - }; - - enum EWindowEvaluation - { - eWindowEvaluation_Sum, - eWindowEvaluation_Max, - eWindowEvaluation_Min, - }; - - /* #################################################################################################################### - */ - template - class IWindowFunction - { - public: - virtual ~IWindowFunction() {} - - virtual const char* getName() const = 0; - virtual T getLength() const = 0; - - virtual bool isCardinal() const = 0; - virtual bool isInfinite() const = 0; - virtual bool isUnitSpaced() const = 0; - virtual bool isCentered() const = 0; - - public: - virtual T operator () (T pos) const = 0; - }; - - /* #################################################################################################################### - * box, pulse, Fourier window, - * box function also know as rectangle function - * 1st order (constant) b-spline - */ - template - class BoxWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Box-window"; - } - virtual T getLength() const - { - return 0.5; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos <= 0.5) - { - return 1.0; - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * triangle, Bartlett window, - * triangle function also known as lambda function - * 2nd order (linear) b-spline - */ - template - class TriangleWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Triangle-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return 1.0 - pos; - } - return 0.0; - } - }; - - /* #################################################################################################################### - * 3rd order (quadratic) b-spline - */ - template - class QuadricWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Quadric-window"; - } - virtual T getLength() const - { - return 1.5; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 0.5) - { - return 0.75 - square(pos); - } - if (pos < 1.5) - { - return 0.50 * square(pos - 1.5); - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * 4th order (cubic) b-spline - */ - template - class CubicWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Cubic-window"; - } - virtual T getLength() const - { - return 2.0; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return 0.5 * cube(pos) - square(pos) + 2.0 / 3.0; - } - if (pos < 2.0) - { - return cube(2.0 - pos) / 6.0; - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Hermite filter - * f(x) = 2|x|^3 - 3|x|^2 + 1, -1 <= x <= 1 - */ - template - class HermiteWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Hermite-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return 2.0 * cube(pos) - 3.0 * square(pos) + 1.0; - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Catmull-Rom spline, Overhauser spline - */ - template - class CatromWindowFunction - : public IWindowFunction - { - public: - CatromWindowFunction() { } - - public: - virtual const char* getName() const - { - return "Catrom-window"; - } - virtual T getLength() const - { - return 2.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return 1.5 * cube(pos) - 2.5 * square(pos) + 1.0; - } - if (pos < 2.0) - { - return -0.5 * cube(pos) + 2.5 * square(pos) - 4.0 * pos + 2.0; - } - return 0.0; - } - }; - - /* #################################################################################################################### - */ - template - class SineWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Sine-window"; - } - virtual T getLength() const - { - return 0.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return sin(pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * sinc, perfect lowpass filter (infinite) - * - * Note: Some people say sinc(x) is sin(x)/x. Others say it's - * sin(PI*x)/(PI*x), a horizontal compression of the former which is - * zero at integer values. We use the latter, whose Fourier transform - * is a canonical rectangle function (edges at -1/2, +1/2, height 1). - */ - template - class SincWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Sinc-window"; - } - virtual T getLength() const - { - return 4.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos == 0.0) - { - return 1.0; - } - - return sin(M_PI * pos) / (M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Bessel (for circularly symm. 2-d filt, infinite) - * See Pratt "Digital Image Processing" p. 97 for Bessel functions - */ - template - class BesselWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Bessel-window"; - } - virtual T getLength() const - { - return 3.2383; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos == 0.0) - { - return M_PI / 4.0; - } - return AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER(M_PI * pos) / (2.0 * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Lanczos filter - */ - template - class LanczosWindowFunction - : public SincWindowFunction - { - public: - LanczosWindowFunction(T tap = 3.0) - { - this->tap = AZ::GetMax(3.0, tap); - } - - protected: - T tap; - - public: - virtual const char* getName() const - { - return "Lanczos-window"; - } - virtual T getLength() const - { - return tap; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < tap) - { - return ((SincWindowFunction) * this)(pos) * ((SincWindowFunction) * this)(pos / tap); - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Gaussian filter (infinite) - */ - template - class GaussianWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Gaussian-window"; - } - virtual T getLength() const - { - return 1.25; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return exp(-2.0 * square(pos)) * sqrt(2.0 / M_PI); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * normal distribution (infinite) - * Normal(x) = Gaussian(x/2)/2 - */ - template - class NormalWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Normal-window"; - } - virtual T getLength() const - { - return 2.5; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return exp(-square(pos) / 2.0) / sqrt(2.0 * M_PI); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - */ - template - class SigmaSixWindowFunction - : public IWindowFunction - { - public: - SigmaSixWindowFunction(T diameter = 1.0, T negative = 0.0) - { - // we aim for 6 * sigma = 99,99996% of all values - const T sigma = 1.0 / 3.0; - - s2 = sigma * sigma * 2.0; - d2 = s2 / (diameter * diameter); - d = diameter; - n = negative; - } - - protected: - T s2, d2, d, n; - - public: - virtual const char* getName() const - { - return "SigmaSix-window"; - } - virtual T getLength() const - { - return 1.44; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - T o = exp(-square(pos) / s2) - (1.0 - 0.9999996); - T i = exp(-square(pos) / d2) - (1.0 - 0.9999996); - return (pos >= d ? 0.0 : i) - o * n; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Mitchell & Netravali's two-param cubic - * see Mitchell & Netravali, - * "Reconstruction Filters in Computer Graphics", SIGGRAPH 88 - */ - template - class MitchellWindowFunction - : public IWindowFunction - { - public: - MitchellWindowFunction(T b = 1.0 / 3.0, T c = 1.0 / 3.0) - { - p0 = (6. - 2. * b) / 6.; - p2 = (-18. + 12. * b + 6. * c) / 6.; - p3 = (12. - 9. * b - 6. * c) / 6.; - q0 = (8. * b + 24. * c) / 6.; - q1 = (-12. * b - 48. * c) / 6.; - q2 = (6. * b + 30. * c) / 6.; - q3 = (-b - 6. * c) / 6.; - } - - protected: - T p0, p2, p3, q0, q1, q2, q3; - - public: - virtual const char* getName() const - { - return "Mitchell-window"; - } - virtual T getLength() const - { - return 2.0; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return p3 * cube(pos) + p2 * square(pos) + p0; - } - if (pos < 2.0) - { - return q3 * cube(pos) + q2 * square(pos) + q1 * pos + q0; - } - return 0.0; - } - }; - - /* #################################################################################################################### - * Hanning window (infinite) - */ - template - class HannWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Hann-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.5 + 0.5 * cos(M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * BartlettHanning window (infinite) - */ - template - class BartlettHannWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Bartlett-Hann-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.62 + 0.48 * (1.0 - pos) + 0.38 * cos(M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Hamming window (infinite) - */ - template - class HammingWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Hamming-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.53836 + 0.46164 * cos(M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Blackman window (infinite) - */ - template - class BlackmanWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Blackman-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.42659 - + 0.49656 * cos(M_PI * pos) - + 0.07685 * cos(2.0 * M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * BlackmanHarris window (infinite) - */ - template - class BlackmanHarrisWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Blackman-Harris-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.35875 - + 0.48829 * cos(M_PI * pos) - + 0.14128 * cos(2.0 * M_PI * pos) - + 0.01168 * cos(3.0 * M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * BlackmanNuttall window (infinite) - */ - template - class BlackmanNuttallWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Blackman-Nuttall-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.3635819 - + 0.4891775 * cos(M_PI * pos) - + 0.1365995 * cos(2.0 * M_PI * pos) - + 0.0106411 * cos(3.0 * M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * FlatTop window (infinite) - */ - template - class FlatTopWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Flat-Top-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.215578948 - + 0.416631580 * cos(M_PI * pos) - + 0.277263158 * cos(2.0 * M_PI * pos) - + 0.083578947 * cos(3.0 * M_PI * pos) - + 0.006947368 * cos(4.0 * M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * parameterized Kaiser window (infinite) - * from Oppenheim & Schafer, Hamming - */ - template - class KaiserWindowFunction - : public IWindowFunction - { - public: - KaiserWindowFunction(T a = 6.5) - { - /* typically 4a = a; - this->i0a = 1. / bessel_i0(a); - } - - protected: - T a, i0a; - - /* modified zeroth order Bessel function of the first kind. */ - static T bessel_i0(T x) - { - #define EPSILON 1e-7 - const T y = square(x) / 4.0; - - T sum = 1.0; - T t = y; - - for (int i = 2; t > EPSILON; i++) - { - sum += t; - t *= y / square(i); - } - - return sum; - - #undef EPSILON - } - - public: - virtual const char* getName() const - { - return "Kaiser-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return i0a * bessel_i0(a * sqrt(1.0 - square(pos))); - } - }; - - /* #################################################################################################################### - */ - template - class CombinerWindowFunction - : public IWindowFunction - { - public: - CombinerWindowFunction(IWindowFunction* fu, IWindowFunction* wi) - { - shaper = fu; - restrictor = wi; - } - - protected: - IWindowFunction* shaper; - IWindowFunction* restrictor; - - public: - virtual const char* getName() const - { - return "Combiner of two window-generators"; - } - virtual T getLength() const - { - return shaper->getLength(); - } - - virtual bool isCardinal() const - { - return shaper->isCardinal() && restrictor->isCardinal(); - } - virtual bool isInfinite() const - { - return shaper->isInfinite() && restrictor->isInfinite(); - } - virtual bool isUnitSpaced() const - { - return shaper->isUnitSpaced() && restrictor->isUnitSpaced(); - } - virtual bool isCentered() const - { - return shaper->isCentered() && restrictor->isCentered(); - } - - public: - virtual T operator () (T pos) const - { - return (*shaper)(pos) * (*restrictor)(pos / shaper->getLength()); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - */ - template - class PointWindowFunction - : public BoxWindowFunction - { - public: - PointWindowFunction() - : BoxWindowFunction() { } - - public: - virtual const char* getName() const - { - return "Point-window"; - } - virtual T getLength() const - { - return 0.0; - } - }; -} //end namespace ImageProcessing - diff --git a/Gems/ImageProcessing/Code/Source/Converters/Gamma.cpp b/Gems/ImageProcessing/Code/Source/Converters/Gamma.cpp deleted file mode 100644 index c30385c608..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Gamma.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include - -#include -#include -#include -#include - -#include -#include - -#include - -namespace ImageProcessing -{ - /////////////////////////////////////////////////////////////////////////////////// - // Lookup table for a function 'float fn(float x)'. - // Computed function values are stored in the table for x in [0.0; 1.0]. - // - // If passed x is less than xMin (xMin must be >= 0) or greater than 1.0, - // then the original function is called. - // Otherwise, a value from the table (linearly interpolated) - // is returned. - template - class FunctionLookupTable - { - public: - FunctionLookupTable(float(*fn)(float x), float xMin, float maxAllowedDifference) - : m_fn(fn) - , m_xMin(xMin) - , m_fMaxDiff(maxAllowedDifference) - { - } - - void Initialize() const - { - m_initialized = true; - AZ_Assert(m_xMin >= 0.0f, "wrong initial data for m_xMin"); - for (int i = 0; i <= TABLE_SIZE; ++i) - { - const float x = i / (float)TABLE_SIZE; - const float y = (*m_fn)(x); - m_table[i] = y; - } - } - - inline float compute(float x) const - { - if (x < m_xMin || x > 1) - { - return m_fn(x); - } - - const float f = x * TABLE_SIZE; - - const int i = int(f); - - if (!m_initialized) - { - Initialize(); - } - - if (i >= TABLE_SIZE) - { - return m_table[TABLE_SIZE]; - } - - const float alpha = f - i; - return (1 - alpha) * m_table[i] + alpha * m_table[i + 1]; - } - - public: - bool Test(const float maxDifferenceAllowed) const - { - if (int(-0.99f) != 0 || - int(+0.00f) != 0 || - int(+0.01f) != 0 || - int(+0.99f) != 0 || - int(+1.00f) != 1 || - int(+1.01f) != 1 || - int(+1.99f) != 1 || - int(+2.00f) != 2 || - int(+2.01f) != 2) - { - return false; - } - - if (m_xMin < 0) - { - return false; - } - - const int n = 1000000; - for (int i = 0; i <= n; ++i) - { - const float x = 1.1f * (i / (float)n); - const float resOriginal = m_fn(x); - const float resTable = compute(x); - const float difference = resOriginal - resTable; - - if (fabs(difference) > maxDifferenceAllowed) - { - return false; - } - } - return true; - } - - private: - float(*m_fn)(float x); - float m_xMin; - mutable float m_table[TABLE_SIZE + 1]; - mutable bool m_initialized = false; - float m_fMaxDiff = 0.0f; - }; - - - static float GammaToLinear(float x) - { - return (x <= 0.04045f) ? x / 12.92f : powf((x + 0.055f) / 1.055f, 2.4f); - } - - static float LinearToGamma(float x) - { - return (x <= 0.0031308f) ? x * 12.92f : 1.055f * powf(x, 1.0f / 2.4f) - 0.055f; - } - - static FunctionLookupTable<1024> s_lutGammaToLinear(GammaToLinear, 0.04045f, 0.00001f); - static FunctionLookupTable<1024> s_lutLinearToGamma(LinearToGamma, 0.05f, 0.00001f); - - /////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////// - bool ImageToProcess::GammaToLinearRGBA32F(bool bDeGamma) - { - // return immediately if there is no need to de-gamma image and the source is in the desired format - EPixelFormat srcFmt = m_img->GetPixelFormat(); - if (!bDeGamma && (srcFmt == ePixelFormat_R32G32B32A32F)) - { - return true; - } - - //convert to 32F first - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcFmt)) - { - AZ_Warning("Image Processing", false, "This is not common user case with compressed format input. But it may continue"); - ConvertFormat(ePixelFormat_R32G32B32A32F); - } - - IImageObjectPtr srcImage = m_img; - EPixelFormat dstFmt = ePixelFormat_R32G32B32A32F; - IImageObjectPtr dstImage(m_img->AllocateImage(dstFmt)); - - //create pixel operation function for src and dst images - IPixelOperationPtr srcOp = CreatePixelOperation(srcFmt); - IPixelOperationPtr dstOp = CreatePixelOperation(dstFmt); - - //get count of bytes per pixel for both src and dst images - uint32 srcPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(srcFmt)->bitsPerBlock / 8; - uint32 dstPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->bitsPerBlock / 8; - - const uint32 dwMips = dstImage->GetMipCount(); - float r, g, b, a; - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* srcPixelBuf; - uint32 srcPitch; - srcImage->GetImagePointer(dwMip, srcPixelBuf, srcPitch); - uint8* dstPixelBuf; - uint32 dstPitch; - dstImage->GetImagePointer(dwMip, dstPixelBuf, dstPitch); - - const uint32 pixelCount = srcImage->GetPixelCount(dwMip); - - for (uint32 i = 0; i < pixelCount; ++i, srcPixelBuf += srcPixelBytes, dstPixelBuf += dstPixelBytes) - { - srcOp->GetRGBA(srcPixelBuf, r, g, b, a); - if (bDeGamma) - { - r = s_lutGammaToLinear.compute(r); - g = s_lutGammaToLinear.compute(g); - b = s_lutGammaToLinear.compute(b); - } - - dstOp->SetRGBA(dstPixelBuf, r, g, b, a); - } - } - - m_img = dstImage; - - if (bDeGamma) - { - m_img->RemoveImageFlags(EIF_SRGBRead); - } - return true; - } - - void ImageToProcess::LinearToGamma() - { - if (Get()->HasImageFlags(EIF_SRGBRead)) - { - AZ_Assert(false, "%s: input image is already SRGB", __FUNCTION__); - return; - } - - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_img->GetPixelFormat())) - { - AZ_Assert(false, "This is not common user case with compressed format input. But it may continue"); - ConvertFormat(ePixelFormat_R32G32B32A32F); - } - - EPixelFormat srcFmt = m_img->GetPixelFormat(); - IImageObjectPtr srcImage = m_img; - - IImageObjectPtr dstImage(m_img->AllocateImage(srcFmt)); - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(srcFmt); - - //get count of bytes per pixel for both src and dst images - uint32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(srcFmt)->bitsPerBlock / 8; - - const uint32 dwMips = srcImage->GetMipCount(); - float r, g, b, a; - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* srcPixelBuf; - uint32 srcPitch; - srcImage->GetImagePointer(dwMip, srcPixelBuf, srcPitch); - uint8* dstPixelBuf; - uint32 dstPitch; - dstImage->GetImagePointer(dwMip, dstPixelBuf, dstPitch); - - const uint32 pixelCount = srcImage->GetPixelCount(dwMip); - - for (uint32 i = 0; i < pixelCount; ++i, srcPixelBuf += pixelBytes, dstPixelBuf += pixelBytes) - { - pixelOp->GetRGBA(srcPixelBuf, r, g, b, a); - r = s_lutLinearToGamma.compute(r); - g = s_lutLinearToGamma.compute(g); - b = s_lutLinearToGamma.compute(b); - pixelOp->SetRGBA(dstPixelBuf, r, g, b, a); - } - } - - m_img = dstImage; - Get()->AddImageFlags(EIF_SRGBRead); - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/HighPass.cpp b/Gems/ImageProcessing/Code/Source/Converters/HighPass.cpp deleted file mode 100644 index 7660d02016..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/HighPass.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - - // higher mip level is subtracted by lower mip level when applying the [cheap] high pass filter - void ImageToProcess::CreateHighPass(AZ::u32 dwMipDown) - { - //no need to convert if mip go down 0 - if (dwMipDown == 0) - { - return; - } - - const EPixelFormat ePixelFormat = m_img->GetPixelFormat(); - - if (ePixelFormat != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "You need convert the orginal image to ePixelFormat_R32G32B32A32F before call this function"); - return; - } - - - AZ::u32 dwWidth, dwHeight, dwMips; - dwWidth = m_img->GetWidth(0); - dwHeight = m_img->GetHeight(0); - dwMips = m_img->GetMipCount(); - - if (dwMipDown >= dwMips) - { - AZ_Warning("Image Processing", false, "CreateHighPass can't go down %i MIP levels for high pass as there are not\ - enough MIP levels available, going down by %i instead", dwMipDown, dwMips - 1); - dwMipDown = dwMips - 1; - } - - IImageObjectPtr newImage(IImageObject::CreateImage(dwWidth, dwHeight, dwMips, ePixelFormat)); - newImage->CopyPropertiesFrom(m_img); - - IPixelOperationPtr pixelOp = CreatePixelOperation(ePixelFormat); - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat)->bitsPerBlock / 8; - - AZ::u32 dstMips = newImage->GetMipCount(); - for (AZ::u32 dstMip = 0; dstMip < dwMipDown; ++dstMip) - { - // linear interpolation - FilterImage(MipGenType::triangle, MipGenEvalType::sum, 0.0f, 0.0f, m_img, dwMipDown, newImage, dstMip, NULL, NULL); - - const AZ::u32 pixelCountIn = m_img->GetWidth(dstMip) *m_img->GetHeight(dstMip); - const AZ::u32 pixelCountOut = newImage->GetWidth(dstMip) * newImage->GetHeight(dstMip); - - //substraction - AZ::u8* srcPixelBuf; - AZ::u32 srcPitch; - m_img->GetImagePointer(dstMip, srcPixelBuf, srcPitch); - AZ::u8* dstPixelBuf; - AZ::u32 dstPitch; - newImage->GetImagePointer(dstMip, dstPixelBuf, dstPitch); - const AZ::u32 pixelCount = newImage->GetPixelCount(dstMip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, srcPixelBuf += pixelBytes, dstPixelBuf += pixelBytes) - { - float r1, g1, b1, a1, r2, g2, b2, a2; - pixelOp->GetRGBA(srcPixelBuf, r1, g1, b1, a1); - pixelOp->GetRGBA(dstPixelBuf, r2, g2, b2, a2); - - r2 = AZ::GetClamp(r1 - r2 + 0.5f, 0.0f, 1.0f); - g2 = AZ::GetClamp(g1 - g2 + 0.5f, 0.0f, 1.0f); - b2 = AZ::GetClamp(b1 - b2 + 0.5f, 0.0f, 1.0f); - a2 = AZ::GetClamp(a1 - a2 + 0.5f, 0.0f, 1.0f); - pixelOp->SetRGBA(dstPixelBuf, r2, g2, b2, a2); - } - } - - // mips below the chosen highpass mip are grey - for (AZ::u32 dstMip = dwMipDown; dstMip < dstMips; ++dstMip) - { - AZ::u8* dstPixelBuf; - AZ::u32 dstPitch; - newImage->GetImagePointer(dstMip, dstPixelBuf, dstPitch); - const AZ::u32 pixelCount = newImage->GetPixelCount(dstMip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, dstPixelBuf += pixelBytes) - { - pixelOp->SetRGBA(dstPixelBuf, 0.5f, 0.5f, 0.5f, 1.0f); - } - } - - m_img = newImage; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/Histogram.cpp b/Gems/ImageProcessing/Code/Source/Converters/Histogram.cpp deleted file mode 100644 index 23cd836891..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Histogram.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include - -#include - -/////////////////////////////////////////////////////////////////////////////////// - -namespace ImageProcessing -{ - float GetLuminance(const float& r, const float& g, const float& b) - { - return (r * 0.30f + g * 0.59f + b * 0.11f); - } - - bool ComputeLuminanceHistogram(IImageObjectPtr imageObject, Histogram<256>& histogram) - { - EPixelFormat pixelFormat = imageObject->GetPixelFormat(); - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(pixelFormat))) - { - AZ_Assert(false, "%s function only works with uncompressed pixel format", __FUNCTION__); - return false; - } - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(pixelFormat); - - //setup histogram bin - static const size_t binCount = 256; - Histogram::Bins bins; - Histogram::clearBins(bins); - - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormat)->bitsPerBlock / 8; - - const AZ::u32 mipCount = imageObject->GetMipCount(); - float color[4]; - for (uint32 mip = 0; mip < mipCount; ++mip) - { - AZ::u8* pixelBuf; - AZ::u32 pitch; - imageObject->GetImagePointer(mip, pixelBuf, pitch); - const uint32 pixelCount = imageObject->GetPixelCount(mip); - - for (uint32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - - const float luminance = AZ::GetClamp(GetLuminance(color[0], color[1], color[2]), 0.0f, 1.0f); - const float f = luminance * binCount; - if (f <= 0) - { - ++bins[0]; - } - else - { - const int bin = int(f); - ++bins[(bin < binCount) ? bin : binCount - 1]; - } - } - } - - histogram.set(bins); - return true; - } -} // end namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/Histogram.h b/Gems/ImageProcessing/Code/Source/Converters/Histogram.h deleted file mode 100644 index 4f73f23a74..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Histogram.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -namespace ImageProcessing -{ - template - class Histogram - { - public: - typedef AZ::u64 Bins[BIN_COUNT]; - - public: - Histogram() - { - } - - static void clearBins(Bins& bins) - { - memset(&bins, 0, sizeof(bins)); - } - - void set(const Bins& bins) - { - m_bins[0] = bins[0]; - m_binsCumulative[0] = bins[0]; - double sum = 0.0f; - for (size_t i = 1; i < BIN_COUNT; ++i) - { - m_bins[i] = bins[i]; - m_binsCumulative[i] = m_binsCumulative[i - 1] + bins[i]; - sum += i * double(bins[i]); - } - - const AZ::u64 totalCount = getTotalSampleCount(); - m_meanBin = (totalCount <= 0) ? 0.0f : float(sum / totalCount); - } - - AZ::u64 getTotalSampleCount() const - { - return m_binsCumulative[BIN_COUNT - 1]; - } - - float getPercentage(size_t minBin, size_t maxBin) const - { - const AZ::u64 totalCount = getTotalSampleCount(); - - if ((totalCount <= 0) || (minBin > maxBin) || (maxBin < 0) || (minBin >= BIN_COUNT)) - { - return 0.0f; - } - - minBin = AZ::GetMax(minBin, size_t(0)); - maxBin = AZ::GetMin(maxBin, BIN_COUNT-1); - - const AZ::u64 count = m_binsCumulative[maxBin] - ((minBin <= 0) ? 0 : m_binsCumulative[minBin-1]); - - return float((double(count) * 100.0) / double(totalCount)); - } - - float getMeanBin() const - { - return m_meanBin; - } - - private: - Bins m_bins; - Bins m_binsCumulative; - float m_meanBin; - }; - - bool ComputeLuminanceHistogram(IImageObjectPtr imageObject, Histogram<256>& histogram); -} diff --git a/Gems/ImageProcessing/Code/Source/Converters/Normalize.cpp b/Gems/ImageProcessing/Code/Source/Converters/Normalize.cpp deleted file mode 100644 index bb41991385..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Normalize.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include -#include - -namespace ImageProcessing -{ - template - static void AdjustScaleForQuantization(float fBaseValue, float fBaseLine, float& cScale, float& cMinColor, float& cMaxColor) - { - const int qOne = (1 << qBits) - 1; - const int qUpperBits = (8 - qBits); - const int qLowerBits = qBits - qUpperBits; - - const int v = int(floor(fBaseValue * qOne)); - - int v0 = v - (v != 0); - int v1 = v + 0; - int v2 = v + (v != qOne); - - v0 = (v0 << qUpperBits) | (v0 >> qLowerBits); - v1 = (v1 << qUpperBits) | (v1 >> qLowerBits); - v2 = (v2 << qUpperBits) | (v2 >> qLowerBits); - - const float f0 = v0 / 255.0f; - const float f1 = v1 / 255.0f; - const float f2 = v2 / 255.0f; - - float fBaseLock = -1; - - if (fabsf(f0 - fBaseValue) < fabsf(fBaseLock - fBaseValue)) - { - fBaseLock = f0; - } - if (fabsf(f1 - fBaseValue) < fabsf(fBaseLock - fBaseValue)) - { - fBaseLock = f1; - } - if (fabsf(f2 - fBaseValue) < fabsf(fBaseLock - fBaseValue)) - { - fBaseLock = f2; - } - - float lScale = (1.0f - fBaseLock) / (1.0f - fBaseLine); - float vScale = (1.0f - fBaseValue) / (1.0f - fBaseLine); - float sScale = lScale / vScale; - - float csScale = (cScale / sScale); - float csBias = cMinColor - (1.0f - sScale) * (cScale / sScale); - - if ((csBias > 0.0f) && ((csScale + csBias) < 1.0f)) - { - cMinColor = csBias; - cScale = csScale; - cMaxColor = csScale + csBias; - } - } - - /////////////////////////////////////////////////////////////////////////////////// - - void CImageObject::NormalizeImageRange(EColorNormalization eColorNorm, EAlphaNormalization eAlphaNorm, bool bMaintainBlack, int nExponentBits) - { - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: unsupported source format", __FUNCTION__); - return; - } - - uint32 dwWidth, dwHeight, dwMips; - GetExtent(dwWidth, dwHeight, dwMips); - - // find image's range, can be negative - float cMinColor[4] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX }; - float cMaxColor[4] = { -FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX }; - - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* pSrcMem; - uint32 dwSrcPitch; - GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - dwHeight = GetHeight(dwMip); - dwWidth = GetWidth(dwMip); - for (uint32 dwY = 0; dwY < dwHeight; ++dwY) - { - const float* pSrcPix = (float*)&pSrcMem[dwY * dwSrcPitch]; - for (uint32 dwX = 0; dwX < dwWidth; ++dwX) - { - cMinColor[0] = AZ::GetMin(cMinColor[0], pSrcPix[0]); - cMinColor[1] = AZ::GetMin(cMinColor[1], pSrcPix[1]); - cMinColor[2] = AZ::GetMin(cMinColor[2], pSrcPix[2]); - cMinColor[3] = AZ::GetMin(cMinColor[3], pSrcPix[3]); - - cMaxColor[0] = AZ::GetMax(cMaxColor[0], pSrcPix[0]); - cMaxColor[1] = AZ::GetMax(cMaxColor[1], pSrcPix[1]); - cMaxColor[2] = AZ::GetMax(cMaxColor[2], pSrcPix[2]); - cMaxColor[3] = AZ::GetMax(cMaxColor[3], pSrcPix[3]); - - pSrcPix += 4; - } - } - } - - if (bMaintainBlack) - { - cMinColor[0] = AZ::GetMin(0.f, cMinColor[0]); - cMinColor[1] = AZ::GetMin(0.f, cMinColor[1]); - cMinColor[2] = AZ::GetMin(0.f, cMinColor[2]); - cMinColor[3] = AZ::GetMin(0.f, cMinColor[3]); - } - - AZ_Assert(cMaxColor[0] >= cMinColor[0] && cMaxColor[1] >= cMinColor[1] && - cMaxColor[2] >= cMinColor[2] && cMaxColor[3] >= cMinColor[3], "bad color range"); - - // some graceful threshold to avoid extreme cases - if (cMaxColor[0] - cMinColor[0] < (3.f / 255)) - { - cMinColor[0] = AZ::GetMax(0.f, cMinColor[0] - (2.f / 255)); - cMaxColor[0] = AZ::GetMin(1.f, cMaxColor[0] + (2.f / 255)); - } - if (cMaxColor[1] - cMinColor[1] < (3.f / 255)) - { - cMinColor[1] = AZ::GetMax(0.f, cMinColor[1] - (2.f / 255)); - cMaxColor[1] = AZ::GetMin(1.f, cMaxColor[1] + (2.f / 255)); - } - if (cMaxColor[2] - cMinColor[2] < (3.f / 255)) - { - cMinColor[2] = AZ::GetMax(0.f, cMinColor[2] - (2.f / 255)); - cMaxColor[2] = AZ::GetMin(1.f, cMaxColor[2] + (2.f / 255)); - } - if (cMaxColor[3] - cMinColor[3] < (3.f / 255)) - { - cMinColor[3] = AZ::GetMax(0.f, cMinColor[3] - (2.f / 255)); - cMaxColor[3] = AZ::GetMin(1.f, cMaxColor[3] + (2.f / 255)); - } - - // calculate range to normalize to - const float fMaxExponent = powf(2.0f, (float)nExponentBits) - 1.0f; - const float cUprValue = powf(2.0f, fMaxExponent); - - if (eColorNorm == eColorNormalization_PassThrough) - { - cMinColor[0] = cMinColor[1] = cMinColor[2] = 0.f; - cMaxColor[0] = cMaxColor[1] = cMaxColor[2] = 1.f; - } - - // don't touch alpha channel if not used - if (eAlphaNorm == eAlphaNormalization_SetToZero) - { - // Store the range explicitly into the structure for read-back. - // The formats which request range expansion don't support alpha. - cMinColor[3] = 0.f; - cMaxColor[3] = cUprValue; - } - else if (eAlphaNorm == eAlphaNormalization_PassThrough) - { - cMinColor[3] = 0.f; - cMaxColor[3] = 1.f; - } - - // get the origins of the color model's lattice for the range of values - // these values need to be encoded as precise as possible under quantization - AZ::Vector4 cBaseLines = AZ::Vector4(0.0f, 0.0f, 0.0f, 0.0f); - AZ::Vector4 cScale = AZ::Vector4(cMaxColor[0] - cMinColor[0], cMaxColor[1] - cMinColor[1], - cMaxColor[2] - cMinColor[2], cMaxColor[3] - cMinColor[3]); - -#if 0 - // NOTE: disabled for now, in the future we can turn this on to force availability - // of value to guarantee for example perfect grey-scales (using YFF) - switch (GetImageFlags() & EIF_Colormodel) - { - case EIF_Colormodel_RGB: - cBaseLines = Vec4(0.0f, 0.0f, 0.0f, 0.0f); - break; - case EIF_Colormodel_CIE: - cBaseLines = Vec4(0.0f, 1.f / 3, 1.f / 3, 0.0f); - break; - case EIF_Colormodel_IRB: - cBaseLines = Vec4(0.0f, 1.f / 2, 1.f / 2, 0.0f); - break; - case EIF_Colormodel_YCC: - case EIF_Colormodel_YFF: - cBaseLines = Vec4(1.f / 2, 0.0f, 1.f / 2, 0.0f); - break; - } - - Vec4 cBaseScale = cBaseLines; - cBaseLines = cBaseLines - cMinColor; - cBaseLines = cBaseLines / cScale; - - if ((cBaseLines.x > 0.0f) && (cBaseLines.x < 1.0f)) - { - AdjustScaleForQuantization<5>(cBaseLines.x, cBaseScale.x, cScale.x, cMinColor.x, cMaxColor.x); - } - if ((cBaseLines.y > 0.0f) && (cBaseLines.y < 1.0f)) - { - AdjustScaleForQuantization<6>(cBaseLines.y, cBaseScale.y, cScale.y, cMinColor.y, cMaxColor.y); - } - if ((cBaseLines.z > 0.0f) && (cBaseLines.z < 1.0f)) - { - AdjustScaleForQuantization<5>(cBaseLines.z, cBaseScale.z, cScale.z, cMinColor.z, cMaxColor.z); - } -#endif - - // normalize the image - AZ::Vector4 vMin = AZ::Vector4(cMinColor[0], cMinColor[1], cMinColor[2], cMinColor[3]); - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* pSrcMem; - uint32 dwSrcPitch; - GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - dwHeight = GetHeight(dwMip); - dwWidth = GetWidth(dwMip); - for (uint32 dwY = 0; dwY < dwHeight; ++dwY) - { - AZ::Vector4* pSrcPix = (AZ::Vector4*)&pSrcMem[dwY * dwSrcPitch]; - for (uint32 dwX = 0; dwX < dwWidth; ++dwX) - { - *pSrcPix = *pSrcPix - vMin; - *pSrcPix = *pSrcPix / cScale; - *pSrcPix = *pSrcPix * cUprValue; - - pSrcPix++; - } - } - } - - // set up a range - SetColorRange(AZ::Color(cMinColor[0], cMinColor[1], cMinColor[2], cMinColor[3]), - AZ::Color(cMaxColor[0], cMaxColor[1], cMaxColor[2], cMaxColor[3])); - - // set up a flag - AddImageFlags(EIF_RenormalizedTexture); - } - - void CImageObject::ExpandImageRange([[maybe_unused]] EColorNormalization eColorMode, EAlphaNormalization eAlphaMode, int nExponentBits) - { - AZ_Assert(!((eAlphaMode != eAlphaNormalization_SetToZero) && (nExponentBits != 0)), "%s: Unexpected alpha mode", __FUNCTION__); - - if (!HasImageFlags(EIF_RenormalizedTexture)) - { - return; - } - - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: only supports source format A32B32G32R32F", __FUNCTION__); - return; - } - - uint32 dwWidth, dwHeight, dwMips; - GetExtent(dwWidth, dwHeight, dwMips); - - // calculate range to normalize to - const float fMaxExponent = powf(2.0f, (float)nExponentBits) - 1.0f; - float cUprValue = powf(2.0f, fMaxExponent); - - // find image's range, can be negative - AZ::Color cMinColor = AZ::Color(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX); - AZ::Color cMaxColor = AZ::Color(-FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX); - - GetColorRange(cMinColor, cMaxColor); - - // don't touch alpha channel if not used - if (eAlphaMode == eAlphaNormalization_SetToZero) - { - // Overwrite the range explicitly into the structure. - // The formats which request range expansion don't support alpha. - cUprValue = cMaxColor.GetA(); - - cMinColor.SetA(1.f); - cMaxColor.SetA(1.f); - } - - // expand the image - const AZ::Vector4 cScale = cMaxColor.GetAsVector4() - cMinColor.GetAsVector4(); - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* pSrcMem; - uint32 dwSrcPitch; - GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - dwHeight = GetHeight(dwMip); - dwWidth = GetWidth(dwMip); - for (uint32 dwY = 0; dwY < dwHeight; ++dwY) - { - AZ::Vector4* pSrcPix = (AZ::Vector4*)&pSrcMem[dwY * dwSrcPitch]; - for (uint32 dwX = 0; dwX < dwWidth; ++dwX) - { - *pSrcPix = *pSrcPix / cUprValue; - *pSrcPix = *pSrcPix * cScale; - *pSrcPix = *pSrcPix + cMinColor.GetAsVector4(); - - pSrcPix++; - } - } - } - - // set up a range - SetColorRange(AZ::Color(0.0f, 0.0f, 0.0f, 0.0f), AZ::Color(1.0f, 1.0f, 1.0f, 1.0f)); - - // set up a flag - RemoveImageFlags(EIF_RenormalizedTexture); - } - - /////////////////////////////////////////////////////////////////////////////////// - - void CImageObject::NormalizeVectors(AZ::u32 firstMip, AZ::u32 maxMipCount) - { - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: only supports source format A32B32G32R32F", __FUNCTION__); - return; - } - - uint32 lastMip = AZ::GetMin(firstMip + maxMipCount, GetMipCount()); - for (uint32 mip = firstMip; mip < lastMip; ++mip) - { - const uint32 pixelCount = GetPixelCount(mip); - uint8* imageMem; - uint32 pitch; - GetImagePointer(mip, imageMem, pitch); - float* pPixels = (float*)imageMem; - - for (uint32 i = 0; i < pixelCount; ++i, pPixels += 4) - { - AZ::Vector3 vNormal = AZ::Vector3(pPixels[0] * 2.0f - 1.0f, pPixels[1] * 2.0f - 1.0f, pPixels[2] * 2.0f - 1.0f); - - // TODO: every opposing vector addition produces the zero-vector for - // normals on the entire sphere, in that case the forward vector [0,0,1] - // isn't necessarily right and we should look at the adjacent normals - // for a direction - if (vNormal.IsZero()) - { - vNormal = AZ::Vector3(1.0f, 0.0f, 0.0f); - } - else - { - vNormal.NormalizeSafe(); - } - - pPixels[0] = vNormal.GetX() * 0.5f + 0.5f; - pPixels[1] = vNormal.GetY() * 0.5f + 0.5f; - pPixels[2] = vNormal.GetZ() * 0.5f + 0.5f; - } - } - } - - /////////////////////////////////////////////////////////////////////////////////// - void CImageObject::ScaleAndBiasChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& scale, const AZ::Vector4& bias) - { - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: only supports source format A32B32G32R32F", __FUNCTION__); - return; - } - - const uint32 lastMip = AZ::GetMin(firstMip + maxMipCount, GetMipCount()); - for (uint32 mip = firstMip; mip < lastMip; ++mip) - { - const uint32 pixelCount = GetPixelCount(mip); - uint8* imageMem; - uint32 pitch; - GetImagePointer(mip, imageMem, pitch); - float* pPixels = (float*)imageMem; - - for (uint32 i = 0; i < pixelCount; ++i, pPixels += 4) - { - pPixels[0] = pPixels[0] * scale.GetX() + bias.GetX(); - pPixels[1] = pPixels[1] * scale.GetY() + bias.GetY(); - pPixels[2] = pPixels[2] * scale.GetZ() + bias.GetZ(); - pPixels[3] = pPixels[3] * scale.GetW() + bias.GetW(); - } - } - } - - /////////////////////////////////////////////////////////////////////////////////// - void CImageObject::ClampChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& min, const AZ::Vector4& max) - { - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: only supports source format A32B32G32R32F", __FUNCTION__); - return; - } - - const uint32 lastMip = AZ::GetMin(firstMip + maxMipCount, GetMipCount()); - for (uint32 mip = firstMip; mip < lastMip; ++mip) - { - - const uint32 pixelCount = GetPixelCount(mip); - uint8* imageMem; - uint32 pitch; - GetImagePointer(mip, imageMem, pitch); - float* pPixels = (float*)imageMem; - - for (uint32 i = 0; i < pixelCount; ++i, pPixels += 4) - { - pPixels[0] = AZ::GetClamp(pPixels[0], float(min.GetX()), float(max.GetX())); - pPixels[1] = AZ::GetClamp(pPixels[1], float(min.GetY()), float(max.GetY())); - pPixels[2] = AZ::GetClamp(pPixels[2], float(min.GetZ()), float(max.GetZ())); - pPixels[3] = AZ::GetClamp(pPixels[3], float(min.GetW()), float(max.GetW())); - } - } - } - -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.cpp b/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.cpp deleted file mode 100644 index 034dcdfda1..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include - -#include -#include -#include -#include - -/////////////////////////////////////////////////////////////////////////////////// -//functions for maintaining alpha coverage. - -namespace ImageProcessing -{ - //convertion: all data type supported by pixel channel <=> float - float U8ToF32(uint8 in) - { - return in / 255.f; - } - - uint8 F32ToU8(float in) - { - return aznumeric_cast(round(AZ::GetClamp(in, 0.f, 1.f) * 255)); - } - - float U16ToF32(uint16 in) - { - return in / 65535.f; - } - - uint16 F32ToU16(float in) - { - return aznumeric_cast(round(AZ::GetClamp(in, 0.f, 1.f) * 65535.f)); - } - - float HalfToF32(SHalf in) - { - return in; - } - - SHalf F32ToHalf(float in) - { - return SHalf(in); - } - - //stucture for RGBE pixel format - struct RgbE - { - static const int RGB9E5_EXPONENT_BITS = 5; - static const int RGB9E5_MANTISSA_BITS = 9; - static const int RGB9E5_EXP_BIAS = 15; - static const int RGB9E5_MAX_VALID_BIASED_EXP = 31; - static const int MAX_RGB9E5_EXP = (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS); - static const int RGB9E5_MANTISSA_VALUES = (1 << RGB9E5_MANTISSA_BITS); - static const int MAX_RGB9E5_MANTISSA = (RGB9E5_MANTISSA_VALUES - 1); - - static float MAX_RGB9E5; - - unsigned int r : 9; - unsigned int g : 9; - unsigned int b : 9; - unsigned int e : 5; - - static int log2(float x) - { - int bitfield = *((int*)(&x)); - bitfield &= ~0x80000000; - - return ((bitfield >> 23) - 127); - } - - void GetRGBF(float& outR, float& outG, float& outB) const - { - int exponent = e - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; - float scale = powf(2.0f, aznumeric_cast(exponent)); - outR = r * scale; - outG = g * scale; - outB = b * scale; - } - - void SetRGBF(const float& inR, const float& inG, const float& inB) - { - float rf = AZStd::GetMax(0.0f, AZStd::GetMin(inR, MAX_RGB9E5)); - float gf = AZStd::GetMax(0.0f, AZStd::GetMin(inG, MAX_RGB9E5)); - float bf = AZStd::GetMax(0.0f, AZStd::GetMin(inB, MAX_RGB9E5)); - float mf = AZStd::GetMax(rf, AZStd::GetMax(gf, bf)); - - e = AZStd::GetMax(0, log2(mf) + (RGB9E5_EXP_BIAS + 1)); - - int exponent = e - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; - float scale = powf(2.0f, aznumeric_cast(exponent)); - - r = AZStd::GetMin(511, (int)floorf(rf / scale + 0.5f)); - g = AZStd::GetMin(511, (int)floorf(gf / scale + 0.5f)); - b = AZStd::GetMin(511, (int)floorf(bf / scale + 0.5f)); - } - }; - - float RgbE::MAX_RGB9E5 = (((float)MAX_RGB9E5_MANTISSA) / RGB9E5_MANTISSA_VALUES * (1 << MAX_RGB9E5_EXP)); - - //ePixelFormat_R8G8B8A8 - class PixelOperationR8G8B8A8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[0]); - g = U8ToF32(data[1]); - b = U8ToF32(data[2]); - a = U8ToF32(data[3]); - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(r); - data[1] = F32ToU8(g); - data[2] = F32ToU8(b); - data[3] = F32ToU8(a); - } - }; - - //ePixelFormat_R8G8B8X8 - class PixelOperationR8G8B8X8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[0]); - g = U8ToF32(data[1]); - b = U8ToF32(data[2]); - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, [[maybe_unused]] const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(r); - data[1] = F32ToU8(g); - data[2] = F32ToU8(b); - data[3] = 0xff; - } - }; - - //ePixelFormat_B8G8R8A8 - class PixelOperationB8G8R8A8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[2]); - g = U8ToF32(data[1]); - b = U8ToF32(data[0]); - a = U8ToF32(data[3]); - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(b); - data[1] = F32ToU8(g); - data[2] = F32ToU8(r); - data[3] = F32ToU8(a); - } - }; - - //ePixelFormat_R8G8 - class PixelOperationR8G8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[0]); - g = U8ToF32(data[1]); - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(r); - data[1] = F32ToU8(g); - } - }; - - //ePixelFormat_R8 - class PixelOperationR8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[0]); - g = 0.f; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(r); - } - }; - - //ePixelFormat_A8 - class PixelOperationA8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - a = U8ToF32(data[0]); - //save alpha information to rgb too. useful for preview. - r = a; - g = a; - b = a; - } - - void SetRGBA(uint8* buf, [[maybe_unused]] const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(a); - } - }; - - //ePixelFormat_R16G16B16A16 - class PixelOperationR16G16B16A16 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint16* data = (uint16*)(buf); - r = U16ToF32(data[0]); - g = U16ToF32(data[1]); - b = U16ToF32(data[2]); - a = U16ToF32(data[3]); - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - uint16* data = (uint16*)(buf); - data[0] = F32ToU16(r); - data[1] = F32ToU16(g); - data[2] = F32ToU16(b); - data[3] = F32ToU16(a); - } - }; - - //ePixelFormat_R16G16 - class PixelOperationR16G16 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint16* data = (uint16*)(buf); - r = U16ToF32(data[0]); - g = U16ToF32(data[1]); - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - uint16* data = (uint16*)(buf); - data[0] = F32ToU16(r); - data[1] = F32ToU16(g); - } - }; - - //ePixelFormat_R16 - class PixelOperationR16 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint16* data = (uint16*)(buf); - r = U16ToF32(data[0]); - g = 0.f; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - uint16* data = (uint16*)(buf); - data[0] = F32ToU16(r); - } - }; - - //ePixelFormat_R9G9B9E5 - class PixelOperationR9G9B9E5 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const RgbE* data = (RgbE*)(buf); - data->GetRGBF(r, g, b); - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, [[maybe_unused]] const float& a) override - { - RgbE* data = (RgbE*)(buf); - data->SetRGBF(r, g, b); - } - }; - - //ePixelFormat_R32G32B32A32F - class PixelOperationR32G32B32A32F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const float* data = (float*)(buf); - r = data[0]; - g = data[1]; - b = data[2]; - a = data[3]; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - float* data = (float*)(buf); - data[0] = r; - data[1] = g; - data[2] = b; - data[3] = a; - } - }; - - //ePixelFormat_R32G32F - class PixelOperationR32G32F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const float* data = (float*)(buf); - r = data[0]; - g = data[1]; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - float* data = (float*)(buf); - data[0] = r; - data[1] = g; - } - }; - - //ePixelFormat_R32F - class PixelOperationR32F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const float* data = (float*)(buf); - r = data[0]; - g = 0.f; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - float* data = (float*)(buf); - data[0] = r; - } - }; - - //ePixelFormat_R16G16B16A16F - class PixelOperationR16G16B16A16F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const SHalf* data = (SHalf*)(buf); - r = data[0]; - g = data[1]; - b = data[2]; - a = data[3]; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - SHalf* data = (SHalf*)(buf); - data[0] = SHalf(r); - data[1] = SHalf(g); - data[2] = SHalf(b); - data[3] = SHalf(a); - } - }; - - //ePixelFormat_R16G16F - class PixelOperationR16G16F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const SHalf* data = (SHalf*)(buf); - r = data[0]; - g = data[1]; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - SHalf* data = (SHalf*)(buf); - data[0] = SHalf(r); - data[1] = SHalf(g); - } - }; - - //ePixelFormat_R16F - class PixelOperationR16F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const SHalf* data = (SHalf*)(buf); - r = data[0]; - g = 0.f; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - SHalf* data = (SHalf*)(buf); - data[0] = SHalf(r); - } - }; - - IPixelOperationPtr CreatePixelOperation(EPixelFormat pixelFmt) - { - switch (pixelFmt) - { - case ePixelFormat_R8G8B8A8: - return AZStd::make_shared(); - case ePixelFormat_R8G8B8X8: - return AZStd::make_shared(); - case ePixelFormat_B8G8R8A8: - return AZStd::make_shared(); - case ePixelFormat_R8G8: - return AZStd::make_shared(); - case ePixelFormat_R8: - return AZStd::make_shared(); - case ePixelFormat_A8: - return AZStd::make_shared(); - case ePixelFormat_R16G16B16A16: - return AZStd::make_shared(); - case ePixelFormat_R16G16: - return AZStd::make_shared(); - case ePixelFormat_R16: - return AZStd::make_shared(); - case ePixelFormat_R9G9B9E5: - return AZStd::make_shared(); - case ePixelFormat_R32G32B32A32F: - return AZStd::make_shared(); - case ePixelFormat_R32G32F: - return AZStd::make_shared(); - case ePixelFormat_R32F: - return AZStd::make_shared(); - case ePixelFormat_R16G16B16A16F: - return AZStd::make_shared(); - case ePixelFormat_R16G16F: - return AZStd::make_shared(); - case ePixelFormat_R16F: - return AZStd::make_shared(); - default: - AZ_Assert(false, "This function should be only called for uncompressed pixel format"); - break; - } - return nullptr; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.h b/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.h deleted file mode 100644 index 4ce8a20643..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - class IPixelOperation - { - public: - virtual ~IPixelOperation() {} - - virtual void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) = 0; - virtual void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) = 0; - }; - - typedef AZStd::shared_ptr IPixelOperationPtr; - IPixelOperationPtr CreatePixelOperation(EPixelFormat pixelFmt); - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.cpp b/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.cpp deleted file mode 100644 index fb62bd258f..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - - bool EditorHelper::s_IsPixelFormatStringInited = false; - const char* EditorHelper::s_PixelFormatString[ImageProcessing::EPixelFormat::ePixelFormat_Count]; - - void EditorHelper::InitPixelFormatString() - { - if (!s_IsPixelFormatStringInited) - { - s_IsPixelFormatStringInited = true; - } - - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - for (int format = 0; format < EPixelFormat::ePixelFormat_Count; format ++) - { - const PixelFormatInfo* info = pixelFormats.GetPixelFormatInfo((EPixelFormat)format); - s_PixelFormatString[(EPixelFormat)format] = ""; - if (info) - { - s_PixelFormatString[(EPixelFormat)format] = info->szName; - } - else - { - AZ_Error("Texture Editor", false, "Cannot find name of EPixelFormat %i", format); - } - } - } - - const AZStd::string EditorHelper::GetFileSizeString(AZ::u32 fileSizeInBytes) - { - AZStd::string fileSizeStr; - - static double kb = 1024.0f; - static double mb = kb * 1024.0; - static double gb = mb * 1024.0; - - static AZStd::string byteStr = "B"; - static AZStd::string kbStr = "KB"; - static AZStd::string mbStr = "MB"; - static AZStd::string gbStr = "GB"; - -#if AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX - kb = 1000.0; - mb = kb * 1000.0; - gb = mb * 1000.0; - - kbStr = "kB"; - mbStr = "mB"; - gbStr = "gB"; -#endif // AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX - - if (fileSizeInBytes < kb) - { - fileSizeStr = AZStd::string::format("%u%s", fileSizeInBytes, byteStr.c_str()); - } - else if (fileSizeInBytes < mb) - { - double size = fileSizeInBytes / kb; - fileSizeStr = AZStd::string::format("%.2f%s", size, kbStr.c_str()); - } - else if (fileSizeInBytes < gb) - { - double size = fileSizeInBytes / mb; - fileSizeStr = AZStd::string::format("%.2f%s", size, mbStr.c_str()); - } - else - { - double size = fileSizeInBytes / gb; - fileSizeStr = AZStd::string::format("%.2f%s", size, gbStr.c_str()); - } - return fileSizeStr; - } - - const AZStd::string EditorHelper::ToReadablePlatformString(const AZStd::string& platformRawStr) - { - AZStd::string readableString; - AZStd::string platformStrLowerCase = platformRawStr; - AZStd::to_lower(platformStrLowerCase.begin(), platformStrLowerCase.end()); - if (platformStrLowerCase == "pc") - { - readableString = "PC"; - } - else if (platformStrLowerCase == "es3") - { - readableString = "Android"; - } - else if (platformStrLowerCase == "osx_gl") - { - readableString = "macOS"; - } - else if (platformStrLowerCase == "provo") - { - readableString = "Provo"; - } - else if (platformStrLowerCase == "ios") - { - readableString = "iOS"; - } - else - { - return platformRawStr; - } - - return readableString; - } - - - EditorTextureSetting::EditorTextureSetting(const AZ::Uuid& sourceTextureId) - { - const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* fullDetails = AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry::GetSourceByUuid(sourceTextureId); - InitFromPath(fullDetails->GetFullPath()); - } - - EditorTextureSetting::EditorTextureSetting(const AZStd::string& texturePath) - { - InitFromPath(texturePath); - } - - void EditorTextureSetting::InitFromPath(const AZStd::string& texturePath) - { - m_fullPath = texturePath; - AzFramework::StringFunc::Path::GetFullFileName(texturePath.c_str(), m_textureName); - - m_img = IImageObjectPtr(LoadImageFromFile(m_fullPath)); - - if (m_img == nullptr) - { - AZ_Warning("Texture Editor", false, "%s is not a valid texture image.", texturePath.c_str()); - return; - } - - bool generatedDefaults = false; - m_settingsMap = TextureSettings::GetMultiplatformTextureSetting(m_fullPath, generatedDefaults); - - // Get the preset id from one platform. The preset id for each platform should always be same - AZ_Assert(m_settingsMap.size() > 0, "There is no platform information"); - AZ::Uuid presetId = m_settingsMap.begin()->second.m_preset; - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(presetId); - - if (!preset) - { - AZ_Warning("Texture Editor", false, "Cannot find preset %s! Will assign a suggested one for the texture.", presetId.ToString().c_str()); - presetId = BuilderSettingManager::Instance()->GetSuggestedPreset(m_fullPath, m_img); - - for (auto& settingIter : m_settingsMap) - { - settingIter.second.ApplyPreset(presetId); - } - } - } - - void EditorTextureSetting::SetIsOverrided() - { - for (auto& it : m_settingsMap) - { - m_overrideFromPreset = false; - TextureSettings& textureSetting = it.second; - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(textureSetting.m_preset); - if (presetSetting != nullptr) - { - if ((textureSetting.m_sizeReduceLevel != presetSetting->m_sizeReduceLevel) || - (textureSetting.m_suppressEngineReduce != presetSetting->m_suppressEngineReduce) || - (presetSetting->m_mipmapSetting != nullptr && textureSetting.m_mipGenType != presetSetting->m_mipmapSetting->m_type)) - { - m_overrideFromPreset = true; - } - } - else - { - AZ_Error("Texture Editor", false, "Texture Preset %s is not found!", textureSetting.m_preset.ToString().c_str()); - } - } - } - - void EditorTextureSetting::SetToPreset(const AZStd::string& presetName) - { - m_overrideFromPreset = false; - - AZ::Uuid presetId = BuilderSettingManager::Instance()->GetPresetIdFromName(presetName); - if (presetId.IsNull()) - { - AZ_Error("Texture Editor", false, "Texture Preset %s has no associated UUID.", presetName.c_str()); - return; - } - - for (auto& settingIter : m_settingsMap) - { - settingIter.second.ApplyPreset(presetId); - } - } - - //Get the texture setting on certain platform - TextureSettings& EditorTextureSetting::GetMultiplatformTextureSetting(const AZStd::string& platform) - { - AZ_Assert(m_settingsMap.size() > 0, "Texture Editor", "There is no texture settings for texture %s", m_fullPath.c_str()); - PlatformName platformName = platform; - if (platform.empty()) - { - platformName = BuilderSettingManager::s_defaultPlatform; - } - if (m_settingsMap.find(platformName) != m_settingsMap.end()) - { - return m_settingsMap[platformName]; - } - else - { - AZ_Error("Texture Editor", false, "Cannot find texture setting on platform %s", platformName.c_str()); - } - return m_settingsMap.begin()->second; - } - - bool EditorTextureSetting::GetFinalInfoForTextureOnPlatform(const AZStd::string& platform, AZ::u32 wantedReduce, ResolutionInfo& outResolutionInfo) - { - if (m_settingsMap.find(platform) == m_settingsMap.end()) - { - return false; - } - - // Copy current texture setting and set to desired reduce - TextureSettings textureSetting = m_settingsMap[platform]; - wantedReduce = AZStd::min(AZStd::max(s_MinReduceLevel, wantedReduce), s_MaxReduceLevel); - textureSetting.m_sizeReduceLevel = wantedReduce; - - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(textureSetting.m_preset, platform); - if (presetSetting) - { - EPixelFormat pixelFormat = presetSetting->m_pixelFormat; - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - - AZ::u32 inputWidth = m_img->GetWidth(0); - AZ::u32 inputHeight = m_img->GetHeight(0); - - // Update input width and height if it's a cubemap - if (presetSetting->m_cubemapSetting != nullptr) - { - CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(m_img); - if (srcCubemap == nullptr) - { - return false; - } - inputWidth = srcCubemap->GetFaceSize(); - inputHeight = inputWidth; - outResolutionInfo.arrayCount = 6; - delete srcCubemap; - } - - GetOutputExtent(inputWidth, inputHeight, outResolutionInfo.width, outResolutionInfo.height, outResolutionInfo.reduce, &textureSetting, presetSetting); - - AZ::u32 mipMapCount = pixelFormats.ComputeMaxMipCount(pixelFormat, outResolutionInfo.width, outResolutionInfo.height); - outResolutionInfo.mipCount = presetSetting->m_mipmapSetting != nullptr && textureSetting.m_enableMipmap ? mipMapCount : 1; - - return true; - } - else - { - return false; - } - } - - bool EditorTextureSetting::RefreshMipSetting(bool enableMip) - { - bool enabled = true; - for (auto& it : m_settingsMap) - { - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(it.second.m_preset); - if (enableMip) - { - if (preset && preset->m_mipmapSetting) - { - it.second.m_enableMipmap = true; - it.second.m_mipGenType = preset->m_mipmapSetting->m_type; - } - else - { - it.second.m_enableMipmap = false; - enabled = false; - AZ_Error("Texture Editor", false, "Preset %s does not support mipmap!", preset->m_name.c_str()); - } - } - else - { - it.second.m_enableMipmap = false; - enabled = false; - } - } - return enabled; - } - - void EditorTextureSetting::PropagateCommonSettings() - { - if (m_settingsMap.size() <= 1) - { - //Only one setting available, no need to propagate - return; - } - - TextureSettings& texSetting = GetMultiplatformTextureSetting(); - for (auto& it = ++ m_settingsMap.begin(); it != m_settingsMap.end(); ++it) - { - const PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - if (it->first != defaultPlatform) - { - it->second.m_enableMipmap = texSetting.m_enableMipmap; - it->second.m_maintainAlphaCoverage = texSetting.m_maintainAlphaCoverage; - it->second.m_mipGenEval = texSetting.m_mipGenEval; - it->second.m_mipGenType = texSetting.m_mipGenType; - for (size_t i = 0; i < TextureSettings::s_MaxMipMaps; i++) - { - it->second.m_mipAlphaAdjust[i] = texSetting.m_mipAlphaAdjust[i]; - } - } - } - } - - AZStd::list EditorTextureSetting::GetResolutionInfo(AZStd::string platform, AZ::u32& minReduce, AZ::u32& maxReduce) - { - AZStd::list resolutionInfos; - // Set the min/max reduce to the global value range first - minReduce = s_MaxReduceLevel; - maxReduce = s_MinReduceLevel; - for (AZ::u32 i = s_MinReduceLevel; i <= s_MaxReduceLevel; i++) - { - ResolutionInfo resolutionInfo; - GetFinalInfoForTextureOnPlatform(platform, i, resolutionInfo); - // If actual reduce is lower than desired reduce, it reaches the limit and we can stop try lower resolution - if (i > resolutionInfo.reduce) - { - break; - } - // Finds out the final min/max reduce based on range in different platforms - minReduce = AZStd::min(resolutionInfo.reduce, minReduce); - maxReduce = AZStd::max(resolutionInfo.reduce, maxReduce); - resolutionInfos.push_back(resolutionInfo); - } - return resolutionInfos; - } - - AZStd::list EditorTextureSetting::GetResolutionInfoForMipmap(AZStd::string platform) - { - AZStd::list resolutionInfos; - unsigned int baseReduce = m_settingsMap[platform].m_sizeReduceLevel; - ResolutionInfo baseInfo; - GetFinalInfoForTextureOnPlatform(platform, baseReduce, baseInfo); - resolutionInfos.push_back(baseInfo); - for (AZ::u32 i = 1; i < baseInfo.mipCount; i++) - { - ResolutionInfo resolutionInfo = baseInfo; - resolutionInfo.width = AZStd::max(baseInfo.width >> i, 1); - resolutionInfo.height = AZStd::max(baseInfo.height >> i, 1); - resolutionInfo.reduce = baseInfo.reduce + i; - resolutionInfo.mipCount = 1; - resolutionInfos.push_back(resolutionInfo); - } - return resolutionInfos; - } - -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.h b/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.h deleted file mode 100644 index cbba723f06..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -namespace ImageProcessingEditor -{ - class EditorHelper - { - public: - static const char* s_PixelFormatString[ImageProcessing::EPixelFormat::ePixelFormat_Count]; - static void InitPixelFormatString(); - static const AZStd::string GetFileSizeString(AZ::u32 fileSizeInBytes); - static const AZStd::string ToReadablePlatformString(const AZStd::string& platformRawStr); - - private: - static bool s_IsPixelFormatStringInited; - }; - - struct ResolutionInfo - { - AZ::u32 width = 0; - AZ::u32 height = 0; - AZ::u32 arrayCount = 1; - AZ::u32 reduce = 0; - AZ::u32 mipCount = 0; - }; - - struct EditorTextureSetting - { - AZStd::string m_textureName = ""; - AZStd::string m_fullPath = ""; - ImageProcessing::MultiplatformTextureSettings m_settingsMap; - bool m_overrideFromPreset = false; - bool m_modified = false; - ImageProcessing::IImageObjectPtr m_img; - - EditorTextureSetting(const AZ::Uuid& sourceTextureId); - EditorTextureSetting(const AZStd::string& texturePath); - ~EditorTextureSetting() = default; - - void InitFromPath(const AZStd::string& texturePath); - - void SetIsOverrided(); - - void SetToPreset(const AZStd::string& presetName); - - //Get the texture setting on certain platform - ImageProcessing::TextureSettings& GetMultiplatformTextureSetting(const AZStd::string& platform = ""); - - //Gets the final resolution/reduce/mip count for a texture on a certain platform - //@param wantedReduce indicates the reduce level that's preferred - //@return successfully get the value or not - bool GetFinalInfoForTextureOnPlatform(const AZStd::string& platform, AZ::u32 wantedReduce, ResolutionInfo& outResolutionInfo); - - //Refresh the mip setting when the mip map setting is enabled/disabled. - //@return whether the mipmap is enabled or not. - bool RefreshMipSetting(bool enableMip); - - //Propagate non platform specific settings from the first setting to all the settings stored in m_settingsMap - void PropagateCommonSettings(); - - //Returns a list of calculated final resolution info based on different base reduce levels - AZStd::list GetResolutionInfo(AZStd::string platform, AZ::u32& minReduce, AZ::u32& maxReduce); - - //Returns a list of calculated final resolution info based on different mipmap levels - AZStd::list GetResolutionInfoForMipmap(AZStd::string platform); - }; - - - class ImageProcessingEditorInteralNotifications - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ///////////////////////////////////////////////////////////////////////// - - //! Used to inform the settings changed across widgets - virtual void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform) = 0; - }; - - using EditorInternalNotificationBus = AZ::EBus; - -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.cpp b/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.cpp deleted file mode 100644 index c646d7adad..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "ImagePopup.h" -#include -#include -#include - -namespace ImageProcessingEditor -{ - ImagePopup::ImagePopup(QImage previewImage, QWidget* parent /*= nullptr*/) - : QDialog(parent, Qt::Dialog | Qt::FramelessWindowHint | Qt::Popup) - , m_ui(new Ui::ImagePopup) - { - m_ui->setupUi(this); - m_previewImage = previewImage; - - if (!m_previewImage.isNull()) - { - int height = previewImage.height(); - int width = previewImage.width(); - - this->resize(width, height); - m_ui->imageLabel->resize(width, height); - QPixmap pixmap = QPixmap::fromImage(previewImage); - m_ui->imageLabel->setPixmap(pixmap); - - this->setFocusPolicy(Qt::FocusPolicy::NoFocus); - this->setModal(false); - } - } - - ImagePopup::~ImagePopup() - { - - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.h b/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.h deleted file mode 100644 index adc91d9dfe..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace Ui -{ - class ImagePopup; -} - -namespace ImageProcessingEditor -{ - class ImagePopup - : public QDialog - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(ImagePopup, AZ::SystemAllocator, 0); - explicit ImagePopup(QImage previewImage, QWidget* parent = nullptr); - ~ImagePopup(); - - private: - QScopedPointer m_ui; - QImage m_previewImage; - - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.ui b/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.ui deleted file mode 100644 index 419812b686..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.ui +++ /dev/null @@ -1,43 +0,0 @@ - - - ImagePopup - - - Qt::WindowModal - - - - 0 - 0 - 400 - 300 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.cpp deleted file mode 100644 index e0e70e30be..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "MipmapSettingWidget.h" -#include - -#include -#include -#include - -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - MipmapSettingWidget::MipmapSettingWidget(EditorTextureSetting& textureSetting, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::MipmapSettingWidget) - , m_textureSetting(&textureSetting) - { - m_ui->setupUi(this); - - - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "Serialization context not available"); - - m_ui->propertyEditor->SetAutoResizeLabels(true); - m_ui->propertyEditor->Setup(serializeContext, this, true, 250); - - m_ui->propertyEditor->ClearInstances(); - TextureSettings* instance = &m_textureSetting->GetMultiplatformTextureSetting(); - const AZ::Uuid& classId = AZ::SerializeTypeInfo::GetUuid(instance); - m_ui->propertyEditor->AddInstance(instance, classId); - m_ui->propertyEditor->InvalidateAll(); - m_ui->propertyEditor->ExpandAll(); - - RefreshUI(); - - EditorInternalNotificationBus::Handler::BusConnect(); - } - - MipmapSettingWidget::~MipmapSettingWidget() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - void MipmapSettingWidget::RefreshUI() - { - TextureSettings& texSetting = m_textureSetting->GetMultiplatformTextureSetting(); - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(texSetting.m_preset); - if (preset == nullptr || preset->m_mipmapSetting == nullptr) - { - m_ui->enableCheckBox->setCheckState(Qt::CheckState::Unchecked); - m_ui->enableCheckBox->setEnabled(false); - m_ui->propertyEditor->hide(); - } - else - { - bool showMipMap = texSetting.m_enableMipmap; - m_ui->enableCheckBox->setEnabled(true); - m_ui->enableCheckBox->setCheckState(showMipMap ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - QObject::connect(m_ui->enableCheckBox, &QCheckBox::clicked, this, &MipmapSettingWidget::OnCheckBoxStateChanged); - if (showMipMap) - { - m_ui->propertyEditor->show(); - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - } - else - { - m_ui->propertyEditor->hide(); - this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - } - } - m_ui->propertyEditor->InvalidateValues(); - } - - void MipmapSettingWidget::OnCheckBoxStateChanged(bool checked) - { - bool finalChecked = m_textureSetting->RefreshMipSetting(checked); - - if (finalChecked) - { - m_ui->propertyEditor->show(); - } - else - { - m_ui->propertyEditor->hide(); - } - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, false, BuilderSettingManager::s_defaultPlatform); - } - - - void MipmapSettingWidget::AfterPropertyModified(AzToolsFramework::InstanceDataNode* /*pNode*/) - { - //Only the first texture setting reflected is changed, we need to propagate the change to every texture settings. - m_textureSetting->PropagateCommonSettings(); - m_ui->propertyEditor->InvalidateValues(); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, false, BuilderSettingManager::s_defaultPlatform); - } - - void MipmapSettingWidget::OnEditorSettingsChanged(bool needRefresh, const AZStd::string& /*platform*/) - { - if (needRefresh) - { - RefreshUI(); - } - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.h b/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.h deleted file mode 100644 index 813c09eb77..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#endif - -namespace Ui -{ - class MipmapSettingWidget; -} - -namespace ImageProcessingEditor -{ - class MipmapSettingWidget - : public QWidget - , public AzToolsFramework::IPropertyEditorNotify - , protected EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(MipmapSettingWidget, AZ::SystemAllocator, 0); - explicit MipmapSettingWidget(EditorTextureSetting& textureSetting, QWidget* parent = nullptr); - ~MipmapSettingWidget(); - - //IPropertyEditorNotify Interface - void BeforePropertyModified([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {} - void AfterPropertyModified(AzToolsFramework::InstanceDataNode* pNode) override; - void SetPropertyEditingActive([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {} - void SetPropertyEditingComplete([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {} - void SealUndoStack() override {} - - public slots: - void OnCheckBoxStateChanged(bool checked); - - protected: - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - - private: - void RefreshUI(); - QScopedPointer m_ui; - EditorTextureSetting* m_textureSetting; - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.ui deleted file mode 100644 index bdab04033c..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.ui +++ /dev/null @@ -1,89 +0,0 @@ - - - MipmapSettingWidget - - - - 0 - 0 - 583 - 489 - - - - - 0 - 0 - - - - Form - - - - - - - - Mipmap Settings - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Enable - - - - - - - - - - 0 - 0 - - - - - - - - Qt::Vertical - - - - 20 - 1 - - - - - - - - - AzToolsFramework::ReflectedPropertyEditor - QFrame -
AzToolsFramework/UI/PropertyEditor/ReflectedPropertyEditor.hxx
- 1 -
-
- - -
diff --git a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.cpp b/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.cpp deleted file mode 100644 index e3fc2500c2..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "PresetInfoPopup.h" -#include -#include -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - // Help functions to convert enum to strings - static const char* RGBWeightToString(RGBWeight weight) - { - static const char* RGBWeightNames[] = { "uniform", "luminance", "ciexyz" }; - AZ_Assert(weight <= RGBWeight::ciexyz, "Invalid RGBWeight!"); - return RGBWeightNames[(int)weight]; - } - - static const char* ColorSpaceToString(ColorSpace colorSpace) - { - static const char* colorSpaceNames[] = { "linear", "sRGB", "auto" }; - AZ_Assert(colorSpace <= ColorSpace::autoSelect, "Invalid ColorSpace!"); - return colorSpaceNames[(int)colorSpace]; - } - - static const char* MipGenTypeToString(MipGenType mipGenType) - { - static const char* mipGenTypeNames[] = { "point", "average", "linear" , "bilinear" , "gaussian" , "blackmanHarris", "kaiserSinc" }; - AZ_Assert(mipGenType <= MipGenType::kaiserSinc, "Invalid MipGenType!"); - return mipGenTypeNames[(int)mipGenType]; - } - - static const char* CubemapFilterTypeToString(CubemapFilterType cubemapFilterType) - { - static const char* cubemapFilterTypeNames[] = { "disc", "cone", "cosine" , "gaussian" , "cosine power" , "ggx" }; - AZ_Assert(cubemapFilterType <= CubemapFilterType::ggx, "Invalid CubemapFilterType!"); - return cubemapFilterTypeNames[(int)cubemapFilterType]; - } - - PresetInfoPopup::PresetInfoPopup(const PresetSettings* presetSettings, QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent, Qt::Dialog | Qt::Popup) - , m_ui(new Ui::PresetInfoPopup) - { - m_ui->setupUi(this); - RefreshPresetInfoLabel(presetSettings); - } - - PresetInfoPopup::~PresetInfoPopup() - { - - } - void PresetInfoPopup::RefreshPresetInfoLabel(const PresetSettings* presetSettings) - { - - QString presetInfoText = ""; - if (!presetSettings) - { - presetInfoText = "Invalid Preset!"; - m_ui->infoLabel->setText(presetInfoText); - return; - } - - presetInfoText += QString("UUID: %1\n").arg(presetSettings->m_uuid.ToString().c_str()); - presetInfoText += QString("Name: %1\n").arg(presetSettings->m_name.c_str()); - presetInfoText += QString("RGB Weight: %1\n").arg(RGBWeightToString(presetSettings->m_rgbWeight)); - presetInfoText += QString("Source ColorSpace: %1\n").arg(ColorSpaceToString(presetSettings->m_srcColorSpace)); - presetInfoText += QString("Destination ColorSpace: %1\n").arg(ColorSpaceToString(presetSettings->m_destColorSpace)); - presetInfoText += QString("FileMasks: "); - int i = 0; - for (auto& mask : presetSettings->m_fileMasks) - { - presetInfoText += i > 0 ? ", " : ""; - presetInfoText += mask.c_str(); - i++; - } - presetInfoText += "\n"; - presetInfoText += QString("Suppress Engine Reduce: %1\n").arg(presetSettings->m_suppressEngineReduce ? "True" : "False"); - presetInfoText += QString("Discard Alpha: %1\n").arg(presetSettings->m_discardAlpha ? "True" : "False"); - presetInfoText += QString("Is Power Of 2: %1\n").arg(presetSettings->m_isPowerOf2 ? "True" : "False"); - presetInfoText += QString("Is Color Chart: %1\n").arg(presetSettings->m_isColorChart ? "True" : "False"); - presetInfoText += QString("High Pass Mip: %1\n").arg(presetSettings->m_highPassMip); - presetInfoText += QString("Gloss From Normal: %1\n").arg(presetSettings->m_glossFromNormals); - presetInfoText += QString("Use Legacy Gloss: %1\n").arg(presetSettings->m_isLegacyGloss ? "True" : "False"); - presetInfoText += QString("Mip Re-normalize: %1\n").arg(presetSettings->m_isMipRenormalize ? "True" : "False"); - presetInfoText += QString("Streamable Mips Number: %1\n").arg(presetSettings->m_numStreamableMips); - presetInfoText += QString("Swizzle: %1\n").arg(presetSettings->m_swizzle.c_str()); - if (presetSettings->m_cubemapSetting) - { - presetInfoText += QString("[Cubemap Settings]\n"); - presetInfoText += QString("Filter: %1\n").arg(CubemapFilterTypeToString(presetSettings->m_cubemapSetting->m_filter)); - presetInfoText += QString("Angle: %1\n").arg(presetSettings->m_cubemapSetting->m_angle); - presetInfoText += QString("Mip Angle: %1\n").arg(presetSettings->m_cubemapSetting->m_mipAngle); - presetInfoText += QString("Mip Slope: %1\n").arg(presetSettings->m_cubemapSetting->m_mipSlope); - presetInfoText += QString("Edge Fixup: %1\n").arg(presetSettings->m_cubemapSetting->m_edgeFixup); - presetInfoText += QString("Generate Diff: %1\n").arg(presetSettings->m_cubemapSetting->m_generateDiff ? "True" : "False"); - presetInfoText += QString("Diffuse Probe Preset: %1\n").arg(presetSettings->m_cubemapSetting->m_diffuseGenPreset.ToString().c_str()); - } - - if (presetSettings->m_mipmapSetting) - { - presetInfoText += QString("[MipMapSetting]\n"); - presetInfoText += QString("Type: %1\n").arg(MipGenTypeToString(presetSettings->m_mipmapSetting->m_type)); - } - - m_ui->infoLabel->setText(presetInfoText); - } -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.h b/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.h deleted file mode 100644 index 64fa666d25..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace ImageProcessing -{ - class PresetSettings; -} -namespace Ui -{ - class PresetInfoPopup; -} - -namespace ImageProcessingEditor -{ - class PresetInfoPopup - : public AzQtComponents::StyledDialog - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(PresetInfoPopup, AZ::SystemAllocator, 0); - explicit PresetInfoPopup(const ImageProcessing::PresetSettings* preset, QWidget* parent = nullptr); - ~PresetInfoPopup(); - void RefreshPresetInfoLabel(const ImageProcessing::PresetSettings* presetSettings); - private: - QScopedPointer m_ui; - - - - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.ui b/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.ui deleted file mode 100644 index fd52b34c8e..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.ui +++ /dev/null @@ -1,83 +0,0 @@ - - - PresetInfoPopup - - - Qt::NonModal - - - - 0 - 0 - 300 - 400 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Preset Info - - - false - - - false - - - - - - 10 - - - 10 - - - 10 - - - 10 - - - 10 - - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.cpp deleted file mode 100644 index 73340a45a7..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "ResolutionSettingItemWidget.h" -#include -#include - -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - - ResolutionSettingItemWidget::ResolutionSettingItemWidget(ResoultionWidgetType type, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::ResolutionSettingItemWidget) - { - m_ui->setupUi(this); - m_type = type; - - EditorInternalNotificationBus::Handler::BusConnect(); - } - - ResolutionSettingItemWidget::~ResolutionSettingItemWidget() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - void ResolutionSettingItemWidget::Init(AZStd::string platform, EditorTextureSetting* editorTextureSetting) - { - m_platform = platform; - m_editorTextureSetting = editorTextureSetting; - m_textureSetting = &m_editorTextureSetting->m_settingsMap[m_platform]; - m_preset = BuilderSettingManager::Instance()->GetPreset(m_textureSetting->m_preset, platform); - SetupResolutionInfo(); - RefreshUI(); - if (m_type == ResoultionWidgetType::TexturePropety) - { - m_ui->formatLabel->show(); - m_ui->formatComboBox->hide(); - } - else - { - m_ui->formatLabel->hide(); - m_ui->formatComboBox->show(); - QObject::connect(m_ui->formatComboBox, static_cast(&QComboBox::currentIndexChanged), this, &ResolutionSettingItemWidget::OnChangeFormat); - } - QObject::connect(m_ui->downResSpinBox, static_cast(&QSpinBox::valueChanged), this, &ResolutionSettingItemWidget::OnChangeDownRes); - - } - - void ResolutionSettingItemWidget::RefreshUI() - { - m_ui->platformLabel->setText(EditorHelper::ToReadablePlatformString(m_platform).c_str()); - - m_ui->downResSpinBox->setRange(m_minReduce, m_maxReduce); - int clampedReduce = AZStd::min(AZStd::max(m_textureSetting->m_sizeReduceLevel, s_MinReduceLevel), s_MaxReduceLevel); - auto it = m_resolutionInfos.begin(); - it = AZStd::next(it, clampedReduce); - m_ui->downResSpinBox->setValue(it->reduce); - - QString finalResolution; - - if (it->arrayCount > 1) - { - finalResolution = QString("%1 x %2 x %3").arg(QString::number(it->width), QString::number(it->height), QString::number(it->arrayCount)); - } - else - { - finalResolution = QString("%1 x %2").arg(QString::number(it->width), QString::number(it->height)); - } - - m_ui->sizeLabel->setText(finalResolution); - - QString finalFormat = GetFinalFormat(m_textureSetting->m_preset); - if (m_type == ResoultionWidgetType::TexturePropety) - { - m_ui->formatLabel->setText(finalFormat); - } - else - { - SetupFormatComboBox(); - m_ui->formatComboBox->setCurrentText(finalFormat); - } - } - - void ResolutionSettingItemWidget::SetupResolutionInfo() - { - m_resolutionInfos = m_editorTextureSetting->GetResolutionInfo(m_platform, m_minReduce, m_maxReduce); - } - - void ResolutionSettingItemWidget::OnChangeDownRes(int downRes) - { - if ((unsigned int)downRes >= m_minReduce && (unsigned int)downRes <= m_maxReduce) - { - m_textureSetting->m_sizeReduceLevel = downRes; - RefreshUI(); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, false, m_platform); - } - } - - QString ResolutionSettingItemWidget::GetFinalFormat([[maybe_unused]] const AZ::Uuid& presetId) - { - if (m_preset && m_preset->m_pixelFormat >=0 && m_preset->m_pixelFormat < ePixelFormat_Count) - { - return EditorHelper::s_PixelFormatString[m_preset->m_pixelFormat]; - } - return QString(); - } - - - void ResolutionSettingItemWidget::SetupFormatComboBox() - { - m_ui->formatComboBox->clear(); - } - - void ResolutionSettingItemWidget::OnChangeFormat([[maybe_unused]] int index) - { - bool oldState = m_ui->formatComboBox->blockSignals(true); - m_ui->formatComboBox->blockSignals(oldState); - } - - void ResolutionSettingItemWidget::OnEditorSettingsChanged(bool needRefresh, const AZStd::string& /*platform*/) - { - if (needRefresh) - { - m_preset = BuilderSettingManager::Instance()->GetPreset(m_textureSetting->m_preset, m_platform); - SetupResolutionInfo(); - RefreshUI(); - } - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.h b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.h deleted file mode 100644 index ef86ad716e..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace ImageProcessing -{ - class PresetSettings; -} -namespace Ui -{ - class ResolutionSettingItemWidget; -} - -namespace ImageProcessingEditor -{ - enum class ResoultionWidgetType - { - TexturePipeline, //Fully editable - TexturePropety, //Only DownRes is editable - }; - - class ResolutionSettingItemWidget - : public QWidget - , EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - - AZ_CLASS_ALLOCATOR(ResolutionSettingItemWidget, AZ::SystemAllocator, 0); - explicit ResolutionSettingItemWidget(ResoultionWidgetType type, QWidget* parent = nullptr); - ~ResolutionSettingItemWidget(); - void Init(AZStd::string platform, EditorTextureSetting* editorTextureSetting); - - public slots: - - void OnChangeDownRes(int downRes); - void OnChangeFormat(int index); - - protected: - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - - private: - - void SetupFormatComboBox(); - void SetupResolutionInfo(); - void RefreshUI(); - QString GetFinalFormat(const AZ::Uuid& presetId); - - QScopedPointer m_ui; - ResoultionWidgetType m_type; - AZStd::string m_platform; - ImageProcessing::TextureSettings* m_textureSetting; - EditorTextureSetting* m_editorTextureSetting; - const ImageProcessing::PresetSettings* m_preset; - //Cached list of calculated final resolution info based on different reduce levels - AZStd::list m_resolutionInfos; - //Final reduce level range - unsigned int m_maxReduce; - unsigned int m_minReduce; - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.ui deleted file mode 100644 index 5e5055e382..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.ui +++ /dev/null @@ -1,205 +0,0 @@ - - - ResolutionSettingItemWidget - - - - 0 - 0 - 400 - 20 - - - - - 0 - 0 - - - - - 400 - 0 - - - - - 400 - 20 - - - - Form - - - Qt::LeftToRight - - - - 0 - - - QLayout::SetDefaultConstraint - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 60 - 0 - - - - - 60 - 16777215 - - - - - 60 - 0 - - - - Provo - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 0 - - - - TextLabel - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 0 - - - - TextLabel - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.cpp deleted file mode 100644 index 4fe8bdbb0b..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "ResolutionSettingWidget.h" -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - ResolutionSettingWidget::ResolutionSettingWidget(ResoultionWidgetType type, EditorTextureSetting& textureSetting, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::ResolutionSettingWidget) - , m_textureSetting(&textureSetting) - { - m_ui->setupUi(this); - m_type = type; - - //Put default platform in the first row - ResolutionSettingItemWidget* item = new ResolutionSettingItemWidget(ResoultionWidgetType::TexturePropety, this); - item->Init(BuilderSettingManager::s_defaultPlatform, m_textureSetting); - m_ui->listLayout->addWidget(item); - - //Add the other platforms in the list - for (auto& it : m_textureSetting->m_settingsMap) - { - AZStd::string platform = it.first; - if (platform != BuilderSettingManager::s_defaultPlatform) - { - ResolutionSettingItemWidget* item2 = new ResolutionSettingItemWidget(ResoultionWidgetType::TexturePropety, this); - item2->Init(platform, m_textureSetting); - m_ui->listLayout->addWidget(item2); - } - } - - // Tooltips - m_ui->downResLabel->setToolTip(QString("Adjust the resolution based on the target platform. \ - Use this setting to preserve the resolution of a source file even though it appears smaller in the game. \ - Select 0 to preserve the original size or 5 for the maximum reduction.")); - } - - ResolutionSettingWidget::~ResolutionSettingWidget() - { - - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.h b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.h deleted file mode 100644 index 1960130521..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace Ui -{ - class ResolutionSettingWidget; -} - -namespace ImageProcessingEditor -{ - class ResolutionSettingWidget - : public QWidget - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(ResolutionSettingWidget, AZ::SystemAllocator, 0); - explicit ResolutionSettingWidget(ResoultionWidgetType type, EditorTextureSetting& texureSetting, QWidget* parent = nullptr); - ~ResolutionSettingWidget(); - - private: - QScopedPointer m_ui; - ResoultionWidgetType m_type; - EditorTextureSetting* m_textureSetting; - - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.ui deleted file mode 100644 index d8987a37eb..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.ui +++ /dev/null @@ -1,177 +0,0 @@ - - - ResolutionSettingWidget - - - - 0 - 0 - 550 - 300 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - 0 - - - - - 0 - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - - 60 - 0 - - - - - 60 - 16777215 - - - - - 60 - 0 - - - - Platform - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - DownRes - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - Size - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - Format - - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.cpp deleted file mode 100644 index da78295c80..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "TexturePresetSelectionWidget.h" -#include - -#include -#include -#include -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - TexturePresetSelectionWidget::TexturePresetSelectionWidget(EditorTextureSetting& textureSetting, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::TexturePresetSelectionWidget) - , m_textureSetting(&textureSetting) - { - m_ui->setupUi(this); - - // Add presets into combo box - m_presetList.clear(); - auto& presetFilterMap = BuilderSettingManager::Instance()->GetPresetFilterMap(); - - AZStd::set noFilterPresetList; - - // Check if there is any filtered preset list first - for(auto& presetFilter : presetFilterMap) - { - if (presetFilter.first.empty()) - { - noFilterPresetList = presetFilter.second; - } - else if (IsMatchingWithFileMask(m_textureSetting->m_textureName, presetFilter.first)) - { - for(const AZStd::string& presetName : presetFilter.second) - { - m_presetList.insert(presetName); - } - } - } - // If no filtered preset list available or should list all presets, use non-filter list - if (m_presetList.size() == 0 || m_listAllPresets) - { - m_presetList = noFilterPresetList; - } - - foreach (const AZStd::string& presetName, m_presetList) - { - m_ui->presetComboBox->addItem(QString(presetName.c_str())); - } - - // Set current preset - const AZ::Uuid& currPreset = m_textureSetting->GetMultiplatformTextureSetting().m_preset; - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(currPreset); - - if (presetSetting) - { - m_ui->presetComboBox->setCurrentText(presetSetting->m_name.c_str()); - QObject::connect(m_ui->presetComboBox, static_cast(&QComboBox::currentIndexChanged), this, &TexturePresetSelectionWidget::OnChangePreset); - - // Suppress engine reduction checkbox - m_ui->serCheckBox->setCheckState(m_textureSetting->GetMultiplatformTextureSetting().m_suppressEngineReduce ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - - SetCheckBoxReadOnly(m_ui->serCheckBox, presetSetting->m_suppressEngineReduce); - QObject::connect(m_ui->serCheckBox, &QCheckBox::clicked, this, &TexturePresetSelectionWidget::OnCheckBoxStateChanged); - - // Set convention label - SetPresetConvention(presetSetting); - } - - // Reset btn - QObject::connect(m_ui->resetBtn, &QPushButton::clicked, this, &TexturePresetSelectionWidget::OnRestButton); - - // PresetInfo btn - QObject::connect(m_ui->infoBtn, &QPushButton::clicked, this, &TexturePresetSelectionWidget::OnPresetInfoButton); - - // Tooltips - m_ui->activeFileConventionLabel->setToolTip(QString("Displays the supported naming convention for the selected preset.")); - m_ui->presetComboBox->setToolTip(QString("Choose a preset to update the preview and other properties.")); - m_ui->resetBtn->setToolTip(QString("Reset values to current preset defaults.")); - m_ui->serCheckBox->setToolTip(QString("Preserves the original size. Use this setting for textures that include text.")); - m_ui->infoBtn->setToolTip(QString("Show detail properties of the current preset")); - - EditorInternalNotificationBus::Handler::BusConnect(); - } - - TexturePresetSelectionWidget::~TexturePresetSelectionWidget() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - void TexturePresetSelectionWidget::OnCheckBoxStateChanged(bool checked) - { - for (auto& it : m_textureSetting->m_settingsMap) - { - it.second.m_suppressEngineReduce = checked; - } - m_textureSetting->SetIsOverrided(); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, false, BuilderSettingManager::s_defaultPlatform); - } - - void TexturePresetSelectionWidget::OnRestButton() - { - m_textureSetting->SetToPreset(AZStd::string(m_ui->presetComboBox->currentText().toUtf8().data())); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, true, BuilderSettingManager::s_defaultPlatform); - } - - void TexturePresetSelectionWidget::OnChangePreset(int index) - { - QString text = m_ui->presetComboBox->itemText(index); - m_textureSetting->SetToPreset(AZStd::string(text.toUtf8().data())); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, true, BuilderSettingManager::s_defaultPlatform); - } - - void ImageProcessingEditor::TexturePresetSelectionWidget::OnPresetInfoButton() - { - const AZ::Uuid& currPreset = m_textureSetting->GetMultiplatformTextureSetting().m_preset; - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(currPreset); - m_presetPopup.reset(new PresetInfoPopup(presetSetting, this)); - m_presetPopup->installEventFilter(this); - m_presetPopup->show(); - } - - void TexturePresetSelectionWidget::OnEditorSettingsChanged(bool needRefresh, const AZStd::string& /*platform*/) - { - if (needRefresh) - { - bool oldState = m_ui->serCheckBox->blockSignals(true); - m_ui->serCheckBox->setChecked(m_textureSetting->GetMultiplatformTextureSetting().m_suppressEngineReduce); - // If the preset's SER is true, texture setting should not override - const AZ::Uuid& currPreset = m_textureSetting->GetMultiplatformTextureSetting().m_preset; - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(currPreset); - if (presetSetting) - { - SetCheckBoxReadOnly(m_ui->serCheckBox, presetSetting->m_suppressEngineReduce); - SetPresetConvention(presetSetting); - // If there is preset info dialog open, update the text - if (m_presetPopup && m_presetPopup->isVisible()) - { - m_presetPopup->RefreshPresetInfoLabel(presetSetting); - } - } - m_ui->serCheckBox->blockSignals(oldState); - } - } - - bool TexturePresetSelectionWidget::IsMatchingWithFileMask(const AZStd::string& filename, const AZStd::string& fileMask) - { - if (fileMask.empty()) - { - // Will not match with empty string - return false; - } - else - { - // Extract the file name and compare if it ends with file mask or not - AZStd::string filenameNoExt; - AzFramework::StringFunc::Path::GetFileName(filename.c_str(), filenameNoExt); - return filenameNoExt.length() >= fileMask.length() && filenameNoExt.compare(filenameNoExt.length() - fileMask.length(), fileMask.length(), fileMask) == 0; - } - } - - void ImageProcessingEditor::TexturePresetSelectionWidget::SetPresetConvention(const PresetSettings* presetSettings) - { - AZStd::string conventionText = ""; - if (presetSettings) - { - int i = 0; - for (const PlatformName& filemask : presetSettings->m_fileMasks) - { - conventionText += i > 0 ? " " + filemask : filemask; - i++; - } - } - m_ui->conventionLabel->setText(QString(conventionText.c_str())); - } - - void ImageProcessingEditor::TexturePresetSelectionWidget::SetCheckBoxReadOnly(QCheckBox* checkBox, bool readOnly) - { - checkBox->setAttribute(Qt::WA_TransparentForMouseEvents, readOnly); - checkBox->setFocusPolicy(readOnly ? Qt::NoFocus : Qt::StrongFocus); - checkBox->setEnabled(!readOnly); - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.h b/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.h deleted file mode 100644 index c490fdbf1f..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#include -#endif - -class QCheckBox; -namespace Ui -{ - class TexturePresetSelectionWidget; -} - -namespace ImageProcessingEditor -{ - class TexturePresetSelectionWidget - : public QWidget - , protected EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(TexturePresetSelectionWidget, AZ::SystemAllocator, 0); - explicit TexturePresetSelectionWidget(EditorTextureSetting& texureSetting, QWidget* parent = nullptr); - ~TexturePresetSelectionWidget(); - - public slots: - void OnCheckBoxStateChanged(bool checked); - void OnRestButton(); - void OnChangePreset(int index); - void OnPresetInfoButton(); - - protected: - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - - private: - QScopedPointer m_ui; - AZStd::set m_presetList; - EditorTextureSetting* m_textureSetting; - QScopedPointer m_presetPopup; - bool IsMatchingWithFileMask(const AZStd::string& filename, const AZStd::string& fileMask); - void SetPresetConvention(const ImageProcessing::PresetSettings* presetSettings); - void SetCheckBoxReadOnly(QCheckBox* checkBox, bool readOnly); - - bool m_listAllPresets = true; - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.ui deleted file mode 100644 index 73a7741dde..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.ui +++ /dev/null @@ -1,91 +0,0 @@ - - - TexturePresetSelectionWidget - - - - 0 - 0 - 624 - 118 - - - - Form - - - - - - - - - - - - - Active file conventions - - - - - - - Texture presets - - - - - - - - - - Active preset - - - - - - - - - - - :/Reset.png - - - - - - - - Suppress spec reduction - - - - - - - - - - - :/info.png - - - - - 16 - 16 - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.cpp deleted file mode 100644 index 8a1cd3b650..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.cpp +++ /dev/null @@ -1,639 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "TexturePreviewWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - - TexturePreviewWidget::TexturePreviewWidget(EditorTextureSetting& texureSetting, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::TexturePreviewWidget) - , m_textureSetting(&texureSetting) - { - m_ui->setupUi(this); - - m_platform = BuilderSettingManager::s_defaultPlatform; - // For now, only provide preview for default platform - m_previewConverter = AZStd::make_unique(m_textureSetting->m_fullPath, &m_textureSetting->GetMultiplatformTextureSetting()); - - m_updateTimer = new QTimer(this); - connect(m_updateTimer, &QTimer::timeout, this, &TexturePreviewWidget::UpdatePreview); - m_updateTimer->setSingleShot(false); - - m_ui->infoLayer->setAttribute(Qt::WA_NoSystemBackground); - m_ui->mipLevelLabel->setAttribute(Qt::WA_NoSystemBackground); - m_ui->imageSizeLabel->setAttribute(Qt::WA_NoSystemBackground); - m_ui->fileSizeLabel->setAttribute(Qt::WA_NoSystemBackground); - - // Setup preview mode combo box - static const QString previewModeString[] = { "RGB", - "R", - "G", - "B", - "Alpha", - "RGBA" }; - - for (int i = 0; i < (int)PreviewMode::Count; i ++) - { - m_ui->previewComboBox->addItem(previewModeString[i]); - } - - QSize size = m_ui->imageLabel->size(); - m_imageLabelSize = aznumeric_cast(size.width()); - - SetUpResolutionInfo(); - RefreshUI(true); - - QObject::connect(m_ui->previewCheckBox, &QCheckBox::clicked, this, &TexturePreviewWidget::OnTiledChanged); - QObject::connect(m_ui->nextMipBtn, &QPushButton::clicked, this, &TexturePreviewWidget::OnNextMip); - QObject::connect(m_ui->prevMipBtn, &QPushButton::clicked, this, &TexturePreviewWidget::OnPrevMip); - QObject::connect(m_ui->previewComboBox, static_cast(&QComboBox::currentIndexChanged), this, &TexturePreviewWidget::OnChangePreviewMode); - - // Set up Refresh button - m_alwaysRefreshAction = new QAction("Always refresh preview", this); - m_alwaysRefreshAction->setCheckable(true); - m_alwaysRefreshAction->setChecked(m_alwaysRefreshPreview); - QObject::connect(m_alwaysRefreshAction, &QAction::triggered, this, &TexturePreviewWidget::OnAlwaysRefresh); - - m_refreshPerClickAction = new QAction("Press to refresh preview", this); - m_refreshPerClickAction->setCheckable(true); - m_refreshPerClickAction->setChecked(!m_alwaysRefreshPreview); - QObject::connect(m_refreshPerClickAction, &QAction::triggered, this, &TexturePreviewWidget::OnRefreshPerClick); - - QMenu* menu = new QMenu(this); - menu->addAction(m_alwaysRefreshAction); - menu->addAction(m_refreshPerClickAction); - - m_ui->refreshBtn->setMenu(menu); - AzQtComponents::PushButton::applySmallIconStyle(m_ui->refreshBtn); - - QObject::connect(m_ui->refreshBtn, &QPushButton::clicked, this, &TexturePreviewWidget::OnRefreshClicked); - m_alwaysRefreshIcon.addFile(QStringLiteral(":/refresh.png"), QSize(), QIcon::Normal, QIcon::On); - m_refreshPerClickIcon.addFile(QStringLiteral(":/refresh-active.png"), QSize(), QIcon::Normal, QIcon::On); - m_ui->refreshBtn->setIcon(m_alwaysRefreshIcon); - - m_ui->busyLabel->SetBusyIconSize(16); - SetImageLabelText(QString(), false); - - // Tooltips - m_ui->previewComboBox->setToolTip(QString("Preview the texture in different channels.")); - m_ui->previewCheckBox->setToolTip(QString("Show or hide a 2x2 tiling of the texture.")); - m_ui->hotkeyLabel->setToolTip(QString("Preview different texture states with keyboard shortcuts.")); - m_ui->refreshBtn->setToolTip(QString("Provide different ways to refresh the preview. Click on the button to refresh manually.")); - - EditorInternalNotificationBus::Handler::BusConnect(); - } - - TexturePreviewWidget::~TexturePreviewWidget() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - void TexturePreviewWidget::resizeEvent(QResizeEvent *event) - { - QWidget::resizeEvent(event); - - QSize size = m_ui->mainWidget->size(); - m_ui->infoLayer->resize(size); - - QSize imageSize = m_ui->imageLabel->size(); - QPoint center = m_ui->mainWidget->rect().center(); - m_ui->imageLabel->move(center - QPoint(imageSize.width() / 2, imageSize.height() / 2)); - QSize busyLabelSize = m_ui->busyLabel->size(); - m_ui->busyLabel->move(center - QPoint(busyLabelSize.width() + m_ui->imageLabel->sizeHint().width() / 2, busyLabelSize.width() / 2)); - } - - void TexturePreviewWidget::SetUpResolutionInfo() - { - m_resolutionInfos = m_textureSetting->GetResolutionInfoForMipmap(m_platform); - m_mipCount = (unsigned int)m_resolutionInfos.size(); - if (m_currentMipIndex > (int)m_mipCount) - { - m_currentMipIndex = 0; - } - } - - void TexturePreviewWidget::OnEditorSettingsChanged([[maybe_unused]] bool needRefresh, const AZStd::string& platform) - { - // Only update the preview if there is any change in current platform - if (platform == m_platform) - { - SetUpResolutionInfo(); - RefreshUI(true); - } - } - - void TexturePreviewWidget::RefreshUI(bool fullRefresh) - { - m_ui->mipLevelLabel->setText(QString("Mip %1").arg(QString::number(m_currentMipIndex))); - m_ui->previewCheckBox->setCheckState(m_previewTiled ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - - bool hasNextMip = m_currentMipIndex < (int)m_mipCount - 1; - m_ui->nextMipBtn->setVisible(hasNextMip); - - bool hasPrevMip = m_currentMipIndex > 0; - m_ui->prevMipBtn->setVisible(hasPrevMip); - - RefreshWarning(); - - if (m_currentMipIndex < m_resolutionInfos.size()) - { - auto it = AZStd::next(m_resolutionInfos.begin(), m_currentMipIndex); - QString finalResolution; - if (it->arrayCount > 1) - { - finalResolution = QString("Image Size: %1 x %2 x %3").arg(QString::number(it->width), QString::number(it->height), QString::number(it->arrayCount)); - } - else - { - finalResolution = QString("Image Size: %1 x %2").arg(QString::number(it->width), QString::number(it->height)); - } - m_ui->imageSizeLabel->setText(finalResolution); - - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(m_textureSetting->GetMultiplatformTextureSetting().m_preset); - if (preset) - { - uint32 size = pixelFormats.EvaluateImageDataSize(preset->m_pixelFormat, it->width, it->height) * it->arrayCount; - AZStd::string fileSizeString = EditorHelper::GetFileSizeString(size); - QString finalFileSize = QString("File Size: %1").arg(fileSizeString.c_str()); - m_ui->fileSizeLabel->setText(finalFileSize); - } - - if (m_alwaysRefreshPreview) - { - RefreshPreviewImage(fullRefresh ? RefreshMode::Convert : RefreshMode::Mip); - } - - } - else - { - AZ_Error("Texture Setting", false, "Cannot find mip reduce level for mip %d", m_currentMipIndex); - } - } - - void TexturePreviewWidget::OnNextMip() - { - if (m_currentMipIndex >= (int)m_mipCount - 1) - { - return; - } - m_currentMipIndex ++; - RefreshUI(false); - } - - - void TexturePreviewWidget::OnPrevMip() - { - if (m_currentMipIndex <= 0) - { - return; - } - - m_currentMipIndex--; - RefreshUI(false); - } - - void TexturePreviewWidget::UpdatePreview() - { - if (!m_previewConverter->IsDone()) - { - float progress = m_previewConverter->GetProgress(); - SetImageLabelText(QString("Converting for preview...Progress %1%").arg(QString::number(progress * 100, 'f', 2))); - return; - } - - m_updateTimer->stop(); - m_previewImageRaw = m_previewConverter->GetOutputImage(); - - GenerateMipmap(m_currentMipIndex); - GenerateChannelImage(m_previewMode); - PaintPreviewImage(); - } - - void TexturePreviewWidget::OnAlwaysRefresh() - { - m_alwaysRefreshPreview = true; - m_alwaysRefreshAction->setChecked(true); - m_refreshPerClickAction->setChecked(false); - - m_ui->refreshBtn->setIcon(m_alwaysRefreshIcon); - } - - void TexturePreviewWidget::OnRefreshPerClick() - { - m_alwaysRefreshPreview = false; - m_alwaysRefreshAction->setChecked(false); - m_refreshPerClickAction->setChecked(true); - - m_ui->refreshBtn->setIcon(m_refreshPerClickIcon); - } - - void TexturePreviewWidget::OnRefreshClicked() - { - RefreshPreviewImage(RefreshMode::Convert); - } - - void TexturePreviewWidget::GenerateMipmap(int mip) - { - // Clear all cached preview images - for (int i = 0; i < (int)PreviewMode::Count; i++) - { - m_previewImages[i] = QImage(); - } - - if (m_previewImageRaw && (AZ::u32)mip < m_previewImageRaw->GetMipCount() ) - { - uint8* imageBuf; - uint32 pitch; - m_previewImageRaw->GetImagePointer(mip, imageBuf, pitch); - const uint32 width = m_previewImageRaw->GetWidth(mip); - const uint32 height = m_previewImageRaw->GetHeight(mip); - m_previewImages[PreviewMode::RGBA] = QImage(imageBuf, width, height, pitch, QImage::Format_RGBA8888); - } - else - { - AZ_Error("Texture Editor", false, "Cannot generate mip preview from an invalid image."); - } - - } - - void TexturePreviewWidget::GenerateChannelImage(PreviewMode channel) - { - // If there is no preview image generated, ignore this function - if (m_previewImages[PreviewMode::RGBA].isNull()) - { - AZ_Error("Texture Editor", false, "Cannot generate channel image from an invalid image."); - return; - } - - if (m_previewImages[channel].isNull()) - { - // Copy the RGBA image before changing the color - QImage previewImg = m_previewImages[PreviewMode::RGBA].copy(); - for (int x = 0; x < previewImg.width(); x++) - { - for (int y = 0; y < previewImg.height(); y++) - { - QRgb pixel = previewImg.pixel(x, y); - int r = qRed(pixel); - int g = qGreen(pixel); - int b = qBlue(pixel); - int a = qAlpha(pixel); - - switch (channel) - { - case ImageProcessingEditor::RGB: - pixel = qRgba(r, g, b, 255); - break; - case ImageProcessingEditor::RRR: - pixel = qRgba(r, r, r, 255); - break; - case ImageProcessingEditor::GGG: - pixel = qRgba(g, g, g, 255); - break; - case ImageProcessingEditor::BBB: - pixel = qRgba(b, b, b, 255); - break; - case ImageProcessingEditor::Alpha: - pixel = qRgba(a, a, a, 255); - break; - default: - break; - } - - previewImg.setPixel(x, y, pixel); - } - } - // Cache the image in current preview mode - m_previewImages[channel] = previewImg; - } - } - - void TexturePreviewWidget::RefreshPreviewImage(RefreshMode mode) - { - // Ignore any none-conversion refresh request when the image is being converted - if (m_updateTimer->isActive() && mode != RefreshMode::Convert) - { - return; - } - - switch (mode) - { - case RefreshMode::Convert: - { - // Start conversion in a AZ::Job - m_previewConverter->StartConvert(); - // Start the timer to trigger the update function - m_updateTimer->start(s_updateInterval); - SetImageLabelText(QString("Converting for preview...Progress 0.01%")); - } - break; - case RefreshMode::Mip: - { - GenerateMipmap(m_currentMipIndex); - GenerateChannelImage(m_previewMode); - PaintPreviewImage(); - } - break; - case RefreshMode::Channel: - { - GenerateChannelImage(m_previewMode); - PaintPreviewImage(); - } - break; - default: - PaintPreviewImage(); - break; - } - } - - void TexturePreviewWidget::PaintPreviewImage() - { - if (m_previewImages[m_previewMode].isNull()) - { - SetImageLabelText(QString("Conversion failed, please check console for more information."), false); - return; - } - SetImageLabelText(QString(), false); - - // Paint the image on to the image label - QPixmap pixMap = QPixmap::fromImage(m_previewImages[m_previewMode]); - QSize size = m_ui->imageLabel->size(); - QPixmap finalPix = pixMap.copy(); - finalPix.fill(Qt::transparent); - finalPix = finalPix.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); - QPainter painter(&finalPix); - painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); - QRect rect = finalPix.rect(); - if (m_previewTiled) - { - pixMap = pixMap.scaled(size / 2, Qt::KeepAspectRatio, Qt::SmoothTransformation); - painter.drawTiledPixmap(rect, pixMap); - } - else - { - painter.drawPixmap(rect, pixMap); - } - // Recenter the image label - float aspectRatio = static_cast(finalPix.width()) / static_cast(finalPix.height()); - QSize preferredSize; - if (aspectRatio >= 1.0f) - { - preferredSize = QSize(aznumeric_cast(m_imageLabelSize), aznumeric_cast(m_imageLabelSize / aspectRatio)); - } - else - { - preferredSize = QSize(aznumeric_cast(m_imageLabelSize * aspectRatio), aznumeric_cast(m_imageLabelSize)); - } - - m_ui->imageLabel->resize(preferredSize); - m_ui->imageLabel->setPixmap(finalPix); - - QPoint center = m_ui->mainWidget->rect().center(); - m_ui->imageLabel->move(center - QPoint(preferredSize.width() / 2, preferredSize.height() / 2)); - - } - - void TexturePreviewWidget::SetImageLabelText(const QString& text, bool busyStatus /*= true*/) - { - // Since setting pixmap will change the label size - // Need to set back to initial size and recenter before displaying text - m_ui->imageLabel->resize(QSize(aznumeric_cast(m_imageLabelSize), aznumeric_cast(m_imageLabelSize))); - QPoint center = m_ui->mainWidget->rect().center(); - m_ui->imageLabel->move(center - QPoint(aznumeric_cast(m_imageLabelSize / 2), aznumeric_cast(m_imageLabelSize / 2))); - m_ui->imageLabel->setText(text); - - // Set busy label status and position to align with the text - m_ui->busyLabel->SetIsBusy(busyStatus); - QSize size = m_ui->busyLabel->size(); - m_ui->busyLabel->move(center - QPoint(size.width() + m_ui->imageLabel->sizeHint().width() / 2, size.width() / 2)); - m_ui->busyLabel->setVisible(busyStatus); - } - - void TexturePreviewWidget::RefreshWarning() - { - int imageWidth = m_textureSetting->m_img->GetWidth(0); - int imageHeight = m_textureSetting->m_img->GetHeight(0); - AZStd::list stretchedPlatform; - - for (auto& iter: m_textureSetting->m_settingsMap) - { - PlatformName platform = iter.first; - const PresetSettings* presetSettings = BuilderSettingManager::Instance()->GetPreset(iter.second.m_preset, platform); - if (presetSettings) - { - EPixelFormat dstFmt = presetSettings->m_pixelFormat; - if (!CPixelFormats::GetInstance().IsImageSizeValid(dstFmt, imageWidth, imageHeight, false)) - { - stretchedPlatform.push_back(EditorHelper::ToReadablePlatformString(platform).c_str()); - } - } - } - - if (stretchedPlatform.size() > 0) - { - QString warningText = QString("The output image will be stretched on Platform:"); - int i = 0; - for (AZStd::string platform: stretchedPlatform) - { - warningText += i > 0 ? ", " : " "; - warningText += platform.c_str(); - i ++; - } - m_ui->warningLabel->setText(warningText); - m_ui->warningLabel->setVisible(true); - m_ui->warningIcon->setVisible(true); - } - else - { - m_ui->warningLabel->setVisible(false); - m_ui->warningIcon->setVisible(false); - } - } - - void TexturePreviewWidget::OnChangePreviewMode(int index) - { - if (index < (int)PreviewMode::Count) - { - m_previewMode = (PreviewMode)index; - - RefreshPreviewImage(RefreshMode::Channel); - } - } - - void TexturePreviewWidget::OnTiledChanged(bool checked) - { - m_previewTiled = checked; - RefreshPreviewImage(RefreshMode::Repaint); - } - - bool TexturePreviewWidget::OnQtEvent(QEvent * event) - { - if (event->type() == QEvent::KeyPress) - { - const QKeyEvent* ke = static_cast(event); - if (ke->isAutoRepeat()) - { - return false; //ignore repeat key event - } - - if (ke->key() == Qt::Key_Space) - { - if (!m_updateTimer->isActive()) // Only popup when image is not converting - { - m_previewPopup.reset(new ImagePopup(m_previewImages[m_previewMode], this)); - m_previewPopup->installEventFilter(this); - m_previewPopup->show(); - event->accept(); - return true; - } - } - else if (ke->key() == Qt::Key_Alt) - { - m_previewMode = PreviewMode::Alpha; - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - else if (ke->key() == Qt::Key_Shift) - { - m_previewMode = PreviewMode::RGBA; - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - } - else if (event->type() == QEvent::KeyRelease) - { - const QKeyEvent* ke = static_cast(event); - if (ke->isAutoRepeat()) - { - return false; //ignore repeat key event - } - if (ke->key() == Qt::Key_Space) - { - if (m_previewPopup) - { - m_previewPopup->hide(); - } - event->accept(); - return true; - } - else if (ke->key() == Qt::Key_Alt) - { - m_previewMode = (PreviewMode)m_ui->previewComboBox->currentIndex(); - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - else if (ke->key() == Qt::Key_Shift) - { - m_previewMode = (PreviewMode)m_ui->previewComboBox->currentIndex(); - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - } - else if (event->type() == QEvent::ApplicationStateChange) - { - const QApplicationStateChangeEvent* appEvent = static_cast(event); - AZ_Warning("Texture Editor", false, "app status change %d", appEvent->applicationState()); - if (appEvent->applicationState() != Qt::ApplicationState::ApplicationActive) - { - PreviewMode currPreviewMode = (PreviewMode)m_ui->previewComboBox->currentIndex(); - if (m_previewMode != currPreviewMode) - { - m_previewMode = currPreviewMode; - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - } - } - else if (event->type() == QEvent::ShortcutOverride) - { - // since we respond to the following things, let Qt know so that shortcuts don't override us - - QKeyEvent* kev = static_cast(event); - int key = kev->key() | kev->modifiers(); - switch (key) - { - case Qt::Key_Space: - case Qt::Key_Alt: - case Qt::Key_Shift: - event->accept(); - return true; - break; - - default: - break; - } - } - return false; - } - - bool TexturePreviewWidget::eventFilter(QObject* obj, QEvent* event) - { - if (event->type() == QEvent::KeyRelease) - { - const QKeyEvent* ke = static_cast(event); - if (ke->key() == Qt::Key_Space && !ke->isAutoRepeat()) - { - if (m_previewPopup) - { - m_previewPopup->hide(); - } - return true; - } - } - else if (event->type() == QEvent::ApplicationStateChange) - { - const QApplicationStateChangeEvent* appEvent = static_cast(event); - if (appEvent->applicationState() != Qt::ApplicationState::ApplicationActive) - { - if (m_previewPopup) - { - m_previewPopup->hide(); - } - } - return true; - } - - return QWidget::eventFilter(obj, event); - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.h b/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.h deleted file mode 100644 index 84ef09d366..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#include -#include - -#include -#endif - -namespace Ui -{ - class TexturePreviewWidget; -} - -namespace ImageProcessingEditor -{ - enum PreviewMode - { - RGB = 0, - RRR, - GGG, - BBB, - Alpha, - RGBA, - Count - }; - - enum class RefreshMode - { - Convert, // Convert the whole image from beginning, takes longest time - Mip, // Generate a new mip from from converted image - Channel, // Generate a new channel image from converted image - Repaint, - }; - - class TexturePreviewWidget - : public QWidget - , protected EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(TexturePreviewWidget, AZ::SystemAllocator, 0); - explicit TexturePreviewWidget(EditorTextureSetting& texureSetting, QWidget* parent = 0); - ~TexturePreviewWidget(); - bool OnQtEvent(QEvent* event); - - public slots: - void OnTiledChanged(bool checked); - void OnPrevMip(); - void OnNextMip(); - void OnChangePreviewMode(int index); - void UpdatePreview(); - void OnAlwaysRefresh(); - void OnRefreshPerClick(); - void OnRefreshClicked(); - - protected: - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - void resizeEvent(QResizeEvent *event) override; - bool eventFilter(QObject* obj, QEvent* event) override; - - private: - void SetUpResolutionInfo(); - void RefreshUI(bool fullRefresh = false); - void RefreshPreviewImage(RefreshMode mode); - void GenerateMipmap(int mip); - void GenerateChannelImage(PreviewMode channel); - void PaintPreviewImage(); - void SetImageLabelText(const QString& text, bool busyStatus = true); - void RefreshWarning(); - - AZStd::list m_resolutionInfos; - QScopedPointer m_ui; - EditorTextureSetting* m_textureSetting; - int m_currentMipIndex = 0; - bool m_previewTiled = false; - float m_imageLabelSize = 0; - AZStd::string m_platform; - unsigned int m_mipCount = 1; - - /////////////////////////////////////////// - // Preview window - PreviewMode m_previewMode = PreviewMode::RGB; - QScopedPointer m_previewPopup; - AZStd::unique_ptr m_previewConverter; - ImageProcessing::IImageObjectPtr m_previewImageRaw; - QImage m_previewImages[PreviewMode::Count]; - QTimer* m_updateTimer; - static const int s_updateInterval = 200; - //////////////////////////////////////////// - - //////////////////////////////////////////// - // Refresh button - bool m_alwaysRefreshPreview = true; - QAction* m_alwaysRefreshAction = nullptr; - QAction* m_refreshPerClickAction = nullptr; - QIcon m_refreshPerClickIcon; - QIcon m_alwaysRefreshIcon; - //////////////////////////////////////////// - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.ui deleted file mode 100644 index 5f42fc8fd9..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.ui +++ /dev/null @@ -1,371 +0,0 @@ - - - TexturePreviewWidget - - - - 0 - 0 - 672 - 579 - - - - Form - - - - - - - - - - - Preview tiled - - - - - - - - 0 - 0 - - - - Shift: RGBA | Alt:Alpha | Space: Full-size - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - - 0 - 500 - - - - - - 0 - 0 - 171 - 185 - - - - - 0 - 0 - - - - Qt::RightToLeft - - - - - - - - - - - - - - - - 0 - 0 - - - - - 16 - 16 - - - - - 26 - 25 - - - - - - - :/warning.png - - - - - - - - - Qt::Vertical - - - - 115 - 32 - - - - - - - - - - - - - - :/Forward.png - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - ... - - - - :/Backward.png - - - - - - - - - - Qt::Vertical - - - - 115 - 32 - - - - - - - - - - - - Mip 1 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Image size: 2048 x 2048 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - File Size: 4,096 KB - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - 0 - 0 - - - - Qt::LeftToRight - - - true - - - - - - - - - - 24 - 24 - - - - false - - - false - - - QToolButton::MenuButtonPopup - - - Qt::ToolButtonIconOnly - - - false - - - - - - - - - - - 0 - 0 - 400 - 400 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 2048 - 2048 - - - - image - - - true - - - Qt::AlignCenter - - - - - - 510 - 80 - 30 - 30 - - - - - 0 - 0 - - - - - 10 - 10 - - - - - 0 - 0 - - - - - 24 - 24 - - - - imageLabel - infoLayer - busyLabel - - - - - - - AzQtComponents::StyledBusyLabel - QWidget -
AzQtComponents/Components/StyledBusyLabel.h
- 1 -
-
- - - - -
diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.cpp b/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.cpp deleted file mode 100644 index 90044a18c0..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "TexturePropertyEditor.h" -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -namespace ImageProcessingEditor -{ - TexturePropertyEditor::TexturePropertyEditor(const AZ::Uuid& sourceTextureId, QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent, Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint | Qt::WindowTitleHint) - , m_ui(new Ui::TexturePropertyEditor) - , m_textureSetting(sourceTextureId) - , m_validImage(true) - { - if (m_textureSetting.m_img == nullptr) - { - m_validImage = false; - return; - } - - m_ui->setupUi(this); - - //Initialize all the format string here - EditorHelper::InitPixelFormatString(); - - //TexturePreviewWidget will be the widget to preview mipmaps - m_previewWidget.reset(aznew TexturePreviewWidget(m_textureSetting, this)); - m_ui->mainLayout->layout()->addWidget(m_previewWidget.data()); - - //TexturePresetSelectionWidget will be the widget to select the preset for the texture - m_presetSelectionWidget.reset(aznew TexturePresetSelectionWidget(m_textureSetting, this)); - m_ui->mainLayout->layout()->addWidget(m_presetSelectionWidget.data()); - - //ResolutionSettingWidget will be the table section to display mipmap resolution for each platform - m_resolutionSettingWidget.reset(aznew ResolutionSettingWidget(ResoultionWidgetType::TexturePropety, m_textureSetting, this)); - m_ui->mainLayout->layout()->addWidget(m_resolutionSettingWidget.data()); - - //MipmapSettingWidget will be simple ReflectedProperty editor to reflect mipmap settings section - m_mipmapSettingWidget.reset(aznew MipmapSettingWidget(m_textureSetting, this)); - m_ui->mainLayout->layout()->addWidget(m_mipmapSettingWidget.data()); - - // Disable horizontal scroll - m_ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - QObject::connect(m_ui->saveBtn, &QPushButton::clicked, this, &TexturePropertyEditor::OnSave); - QObject::connect(m_ui->helpBtn, &QPushButton::clicked, this, &TexturePropertyEditor::OnHelp); - QObject::connect(m_ui->cancelBtn, &QPushButton::clicked, this, &QDialog::reject); - - EditorInternalNotificationBus::Handler::BusConnect(); - - // When checkbox and combobox is focused, they will intercept the space shortcut, need to disable focus on them first - // to get space shortcut pass through - QList checkBoxWidgets = QObject::findChildren(); - for (QCheckBox* widget: checkBoxWidgets) - { - widget->setFocusPolicy(Qt::NoFocus); - } - QList comboBoxWidgets = QObject::findChildren(); - for (QComboBox* widget : comboBoxWidgets) - { - widget->setFocusPolicy(Qt::NoFocus); - } - this->setFocusPolicy(Qt::StrongFocus); - - } - - TexturePropertyEditor::~TexturePropertyEditor() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - bool TexturePropertyEditor::HasValidImage() - { - return m_validImage; - } - - void TexturePropertyEditor::OnEditorSettingsChanged([[maybe_unused]] bool needRefresh, const AZStd::string& /*platform*/) - { - m_textureSetting.m_modified = true; - } - - void TexturePropertyEditor::OnSave() - { - if (!m_validImage) - { - return; - } - - bool sourceControlActive = false; - AzToolsFramework::SourceControlConnectionRequestBus::BroadcastResult(sourceControlActive, &AzToolsFramework::SourceControlConnectionRequests::IsActive); - AZStd::string outputPath = m_textureSetting.m_fullPath + ImageProcessing::TextureSettings::modernExtensionName; - - if (sourceControlActive) - { - using ApplicationBus = AzToolsFramework::ToolsApplicationRequestBus; - bool checkoutResult = false; - ApplicationBus::BroadcastResult(checkoutResult, &ApplicationBus::Events::RequestEditForFileBlocking, outputPath.c_str(), "Checking out .imagesetting file", []([[maybe_unused]] int& current, [[maybe_unused]] int& max) {}); - - if (checkoutResult) - { - SaveTextureSetting(outputPath); - } - else - { - AZ_Error("Texture Editor", false, "Cannot checkout file '%s' from source control.", outputPath.c_str()); - } - } - else - { - const bool fileExisted = AZ::IO::FileIOBase::GetInstance()->Exists(outputPath.c_str()); - const bool fileReadOnly = AZ::IO::FileIOBase::GetInstance()->IsReadOnly(outputPath.c_str()); - - if (!fileExisted || !fileReadOnly) - { - SaveTextureSetting(outputPath); - } - } - } - - void TexturePropertyEditor::SaveTextureSetting(AZStd::string outputPath) - { - if (!m_validImage) - { - return; - } - - ImageProcessing::TextureSettings& baseSetting = m_textureSetting.GetMultiplatformTextureSetting(); - for (auto& it : m_textureSetting.m_settingsMap) - { - baseSetting.ApplySettings(it.second, it.first); - } - - ImageProcessing::StringOutcome outcome = ImageProcessing::TextureSettings::WriteTextureSetting(outputPath, baseSetting); - - if (outcome.IsSuccess()) - { - // Since setting is successfully saved, we can safely delete the legacy setting now - DeleteLegacySetting(); - } - else - { - AZ_Error("Texture Editor", false, "Cannot save texture settings!"); - } - } - - void TexturePropertyEditor::DeleteLegacySetting() - { - AZStd::string legacyFile = m_textureSetting.m_fullPath + ImageProcessing::TextureSettings::legacyExtensionName; - const bool fileExisted = AZ::IO::FileIOBase::GetInstance()->Exists(legacyFile.c_str()); - if (fileExisted) - { - bool sourceControlActive = false; - AzToolsFramework::SourceControlConnectionRequestBus::BroadcastResult(sourceControlActive, &AzToolsFramework::SourceControlConnectionRequests::IsActive); - - if (sourceControlActive) - { - AzToolsFramework::SourceControlCommandBus::Broadcast(&AzToolsFramework::SourceControlCommandBus::Events::RequestDelete, legacyFile.c_str(), - [](bool success, const AzToolsFramework::SourceControlFileInfo& info) - { - //Deletes the file locally if it's not tracked by source control - if (!success && !info.IsManaged()) - { - AZ::IO::FileIOBase::GetInstance()->Remove(info.m_filePath.c_str()); - } - }); - } - else - { - AZ::IO::FileIOBase::GetInstance()->Remove(legacyFile.c_str()); - } - } - } - - - void TexturePropertyEditor::OnHelp() - { - QString webLink = tr("https://docs.aws.amazon.com/console/lumberyard/texturepipeline"); - QDesktopServices::openUrl(QUrl(webLink)); - } - - - bool TexturePropertyEditor::event(QEvent* event) - { - bool needsBlocking = false; - if (m_previewWidget) - { - needsBlocking = m_previewWidget->OnQtEvent(event); - } - return needsBlocking ? true : QWidget::event(event); - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.h b/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.h deleted file mode 100644 index 77261d820a..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#endif - -namespace Ui -{ - class TexturePropertyEditor; -} - -namespace ImageProcessingEditor -{ - class TexturePropertyEditor - : public AzQtComponents::StyledDialog - , protected EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - - AZ_CLASS_ALLOCATOR(TexturePropertyEditor, AZ::SystemAllocator, 0); - explicit TexturePropertyEditor(const AZ::Uuid& sourceTextureId, QWidget* parent = nullptr); - ~TexturePropertyEditor(); - - bool HasValidImage(); - - protected: - void OnSave(); - void OnHelp(); - - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - - bool event(QEvent* event) override; - - private: - QScopedPointer m_ui; - QScopedPointer m_previewWidget; - QScopedPointer m_presetSelectionWidget; - QScopedPointer m_resolutionSettingWidget; - QScopedPointer m_mipmapSettingWidget; - - EditorTextureSetting m_textureSetting; - bool m_validImage = true; - - void SaveTextureSetting(AZStd::string outputPath); - void DeleteLegacySetting(); - - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.ui b/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.ui deleted file mode 100644 index 33a7fd3376..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.ui +++ /dev/null @@ -1,120 +0,0 @@ - - - TexturePropertyEditor - - - - 0 - 0 - 580 - 1100 - - - - - 580 - 800 - - - - - 580 - 1200 - - - - Texture Settings Editor - - - - - - - 0 - 0 - - - - true - - - - - 0 - 0 - 560 - 1049 - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - ? - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - Apply - - - - - - - Close - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h b/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h deleted file mode 100644 index 962cd81668..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License").All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file.Do not -* remove or modify any license notices.This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once -#include - -typedef AZ::s8 int8; -typedef AZ::s8 sint8; -typedef AZ::u8 uint8; - -typedef AZ::s16 int16; -typedef AZ::s16 sint16; -typedef AZ::u16 uint16; - -typedef AZ::s32 int32; -typedef AZ::s32 sint32; -typedef AZ::u32 uint32; - -typedef float f32; -typedef double f64; diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.cpp b/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.cpp deleted file mode 100644 index 8c0dc0ff56..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -namespace ImageProcessing -{ - BuilderPluginComponent::BuilderPluginComponent() - { - // AZ Components should only initialize their members to null and empty in constructor - // after construction, they may be deserialized from file. - } - - BuilderPluginComponent::~BuilderPluginComponent() - { - } - - void BuilderPluginComponent::Init() - { - } - - void BuilderPluginComponent::Activate() - { - // create and initialize BuilderSettingManager once since it's will be used for image conversion - BuilderSettingManager::CreateInstance(); - - auto outcome = ImageProcessing::BuilderSettingManager::Instance()->LoadBuilderSettings(); - AZ_Error("Image Processing", outcome.IsSuccess(), "Failed to load default preset settings!"); - - // Activate is where you'd perform registration with other objects and systems. - // Since we want to register our builder, we do that here: - AssetBuilderSDK::AssetBuilderDesc builderDescriptor; - builderDescriptor.m_name = "Image Worker Builder"; - builderDescriptor.m_version = 2; - builderDescriptor.m_analysisFingerprint = AZStd::string::format("%d", ImageProcessing::BuilderSettingManager::Instance()->BuilderSettingsVersion()); - - for (int i = 0; i < s_TotalSupportedImageExtensions; i++) - { - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(s_SupportedImageExtensions[i], AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - } - - //add ".dds" here separately since we only apply copy operation for this type of file. and there won't be export option for dds files. - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.dds", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_busId = azrtti_typeid(); - builderDescriptor.m_createJobFunction = AZStd::bind(&ImageBuilderWorker::CreateJobs, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - builderDescriptor.m_processJobFunction = AZStd::bind(&ImageBuilderWorker::ProcessJob, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - m_imageBuilder.BusConnect(builderDescriptor.m_busId); - ImageProcessingRequestBus::Handler::BusConnect(); - AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor); - } - - void BuilderPluginComponent::Deactivate() - { - ImageProcessingRequestBus::Handler::BusDisconnect(); - m_imageBuilder.BusDisconnect(); - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - } - - void BuilderPluginComponent::Reflect(AZ::ReflectContext* context) - { - // components also get Reflect called automatically - // this is your opportunity to perform static reflection or type registration of any types you want the serializer to know about - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(0) - ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })) - ; - } - - BuilderSettingManager::Reflect(context); - BuilderSettings::Reflect(context); - PresetSettings::Reflect(context); - CubemapSettings::Reflect(context); - MipmapSettings::Reflect(context); - TextureSettings::Reflect(context); - } - - void BuilderPluginComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("ImagerBuilderPluginService", 0x6dc0db6e)); - } - - void BuilderPluginComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("ImagerBuilderPluginService", 0x6dc0db6e)); - } - - IImageObjectPtr BuilderPluginComponent::LoadImage(const AZStd::string& filePath) - { - return IImageObjectPtr(LoadImageFromFile(filePath)); - } - - IImageObjectPtr BuilderPluginComponent::LoadImagePreview(const AZStd::string& filePath) - { - IImageObjectPtr image(LoadImageFromFile(filePath)); - if (image) - { - ImageToProcess imageToProcess(image); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - return imageToProcess.Get(); - } - return image; - } - - void ImageBuilderWorker::ShutDown() - { - // it is important to note that this will be called on a different thread than your process job thread - m_isShuttingDown = true; - } - - // this happens early on in the file scanning pass - // this function should consistently always create the same jobs, and should do no checking whether the job is up to date or not - just be consistent. - void ImageBuilderWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) - { - if (m_isShuttingDown) - { - response.m_result = AssetBuilderSDK::CreateJobsResultCode::ShuttingDown; - return; - } - - // Get the extension of the file - AZStd::string ext; - AzFramework::StringFunc::Path::GetExtension(request.m_sourceFile.c_str(), ext, false); - AZStd::to_upper(ext.begin(), ext.end()); - - // We process the same file for all platforms - for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms) - { - if (ImageProcessing::BuilderSettingManager::Instance()->DoesSupportPlatform(platformInfo.m_identifier)) - { - AssetBuilderSDK::JobDescriptor descriptor; - descriptor.m_jobKey = ext + " Compile"; - descriptor.SetPlatformIdentifier(platformInfo.m_identifier.c_str()); - descriptor.m_critical = false; - descriptor.m_additionalFingerprintInfo = AZStd::string::format("%d", ImageProcessing::BuilderSettingManager::Instance()->BuilderSettingsVersion()); - response.m_createJobOutputs.push_back(descriptor); - } - } - - response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; - return; - } - - // later on, this function will be called for jobs that actually need doing. - // the request will contain the CreateJobResponse you constructed earlier, including any keys and values you placed into the hash table - void ImageBuilderWorker::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) - { - // Before we begin, let's make sure we are not meant to abort. - AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId); - - AZStd::vector productFilepaths; - bool imageProcessingSuccessful = false; - bool needConversion = true; - - //if the original file is a dds file then skip conversion - if (AzFramework::StringFunc::Path::IsExtension(request.m_fullPath.c_str(), "dds", false)) - { - productFilepaths.push_back(request.m_fullPath); - imageProcessingSuccessful = true; - needConversion = false; - } - - // Do conversion and get exported file's path - if (needConversion) - { - AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Performing image conversion: %s\n", request.m_fullPath.c_str()); - ImageConvertProcess* process = CreateImageConvertProcess(request.m_fullPath, request.m_tempDirPath, - request.m_jobDescription.GetPlatformIdentifier()); - - if (process != nullptr) - { - //the process can be stopped if the job is cancelled or the worker is shutting down - while (!process->IsFinished() && !m_isShuttingDown && !jobCancelListener.IsCancelled()) - { - process->UpdateProcess(); - } - - //get process result - imageProcessingSuccessful = process->IsSucceed(); - process->GetAppendOutputFilePaths(productFilepaths); - - delete process; - } - else - { - imageProcessingSuccessful = false; - } - } - - if (imageProcessingSuccessful) - { - AZ::Outcome result = PopulateProducts(request, productFilepaths, response.m_outputProducts); - if (result.IsSuccess()) - { - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; - } - else - { - AZ_Error(AssetBuilderSDK::ErrorWindow, false, result.GetError().c_str()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; - } - } - else - { - if (m_isShuttingDown) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Cancelled job %s because shutdown was requested.\n", request.m_fullPath.c_str()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled; - } - else if (jobCancelListener.IsCancelled()) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Cancelled was requested for job %s.\n", request.m_fullPath.c_str()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled; - } - else - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Unexpected error during processing job %s.\n", request.m_fullPath.c_str()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; - } - } - } - - AZ::Outcome ImageBuilderWorker::PopulateProducts(const AssetBuilderSDK::ProcessJobRequest& request, const AZStd::vector& productFilepaths, AZStd::vector& jobProducts) - { - AssetBuilderSDK::JobProduct* rgbBaseJobProduct = nullptr; - AssetBuilderSDK::JobProduct* diffBaseJobProduct = nullptr; - AssetBuilderSDK::JobProduct* baseJobProduct = nullptr; - AssetBuilderSDK::JobProduct* alphaBaseJobProduct = nullptr; - // Report the image-import result (filepath to one or many '.dds') - - // This reserve is critically important to prevent resizing the vector and invalidating the pointers we need to save off - jobProducts.reserve(productFilepaths.size()); - - for (const auto& product : productFilepaths) - { - AssetBuilderSDK::JobProduct jobProduct(product); - jobProduct.m_dependenciesHandled = true; // Dependencies are handled down below. The base products will have dependencies, lod products won't - jobProducts.push_back(jobProduct); - - AZ::u32 lodLevel = AssetBuilderSDK::GetSubID_LOD(jobProduct.m_productSubID); - - if(jobProduct.m_productSubID == 0) - { - rgbBaseJobProduct = &jobProducts.back(); - } - else if((jobProduct.m_productSubID & AssetBuilderSDK::SUBID_FLAG_DIFF) && lodLevel == 0) - { - diffBaseJobProduct = &jobProducts.back(); - } - else if((jobProduct.m_productSubID & AssetBuilderSDK::SUBID_FLAG_ALPHA) && lodLevel == 0) - { - alphaBaseJobProduct = &jobProducts.back(); - } - } - - //We can have a diff and/or a rgb base. The rgb base always takes precedence when present - baseJobProduct = rgbBaseJobProduct; - - if(!baseJobProduct) - { - baseJobProduct = diffBaseJobProduct; - } - - for (AssetBuilderSDK::JobProduct& jobProduct : jobProducts) - { - AssetBuilderSDK::ProductDependency productDependency(AZ::Data::AssetId(request.m_sourceFileUUID, jobProduct.m_productSubID), 0); - - AZ::u32 lodLevel = AssetBuilderSDK::GetSubID_LOD(jobProduct.m_productSubID); - bool isAlpha = jobProduct.m_productSubID & AssetBuilderSDK::SUBID_FLAG_ALPHA; - - if (lodLevel > 0) - { - if (isAlpha) - { - if (alphaBaseJobProduct) - { - // add all alpha mips to the base alpha texture as product dependency - alphaBaseJobProduct->m_dependencies.push_back(productDependency); - } - else - { - return AZ::Failure(AZStd::string::format("Unable to add (%s) file as a product dependency of the base alpha texture file. Base alpha texture file is missing from the products list.\n", jobProduct.m_productFileName.c_str())); - } - } - else - { - if (baseJobProduct) - { - // add all rgb mips to the base rgb texture as product dependency - baseJobProduct->m_dependencies.push_back(productDependency); - } - else - { - return AZ::Failure(AZStd::string::format("Unable to add (%s) file as a product dependency of the base rgb texture file. Base rgb texture file is missing from the products list.\n", jobProduct.m_productFileName.c_str())); - } - } - } - } - - // Diffuse (_diff) is required by the base (typically for cubemaps) - if (rgbBaseJobProduct && diffBaseJobProduct) - { - AssetBuilderSDK::ProductDependency productDependency(AZ::Data::AssetId(request.m_sourceFileUUID, diffBaseJobProduct->m_productSubID), 0); - rgbBaseJobProduct->m_dependencies.push_back(productDependency); - } - - if (alphaBaseJobProduct && baseJobProduct) - { - // Add the alphaBaseTexture as a product dependency for baseTexture - AssetBuilderSDK::ProductDependency productDependency(AZ::Data::AssetId(request.m_sourceFileUUID, alphaBaseJobProduct->m_productSubID), 0); - baseJobProduct->m_dependencies.push_back(productDependency); - } - - return AZ::Success(); - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.h b/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.h deleted file mode 100644 index 212081ec92..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - //! Builder to process images - class ImageBuilderWorker - : public AssetBuilderSDK::AssetBuilderCommandBus::Handler - { - public: - AZ_RTTI(ImageBuilderWorker, "{525422DE-05B3-4095-966F-90CD7657A7E1}"); - - ImageBuilderWorker() = default; - ~ImageBuilderWorker() = default; - - //! Asset Builder Callback Functions - void CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response); - void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response); - - ////////////////////////////////////////////////////////////////////////// - //!AssetBuilderSDK::AssetBuilderCommandBus interface - void ShutDown() override; // if you get this you must fail all existing jobs and return. - ////////////////////////////////////////////////////////////////////////// - - //! Populates the jobProduct vector with all the entries including their product dependencies - AZ::Outcome PopulateProducts(const AssetBuilderSDK::ProcessJobRequest& request, const AZStd::vector& productFilepaths, AZStd::vector& jobProducts); - - private: - bool m_isShuttingDown = false; - }; - - //! BuilderPluginComponent is to handle the lifecycle of ImageBuilder module. - class BuilderPluginComponent - : public AZ::Component - , protected ImageProcessingRequestBus::Handler - { - public: - AZ_COMPONENT(BuilderPluginComponent, "{2F12E1BE-D8F6-47A4-AC3E-6C5527C55840}") - static void Reflect(AZ::ReflectContext* context); - - BuilderPluginComponent(); // avoid initialization here. - ~BuilderPluginComponent() override; // free memory an uninitialize yourself. - - ////////////////////////////////////////////////////////////////////////// - // AZ::Component - void Init() override; // create objects, allocate memory and initialize yourself without reaching out to the outside world - void Activate() override; // reach out to the outside world and connect up to what you need to, register things, etc. - void Deactivate() override; // unregister things, disconnect from the outside world - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - ////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // ImageProcessingRequestBus interface implementation - IImageObjectPtr LoadImage(const AZStd::string& filePath) override; - IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) override; - //////////////////////////////////////////////////////////////////////// - - private: - ImageBuilderWorker m_imageBuilder; - }; -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings b/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings deleted file mode 100644 index 7e16a3c98f..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings +++ /dev/null @@ -1,8051 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/BTImageLoader.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/BTImageLoader.cpp deleted file mode 100644 index b06ceccddc..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/BTImageLoader.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" - -#include "ImageLoaders.h" - -#include -#include - -#include - -namespace -{ - //--------------------------------------------------------------------------- - // Load and save the VTP Binary Terrain (BT) format, documented here: - // http://vterrain.org/Implementation/Formats/BT.html - - // This structure represents a binary layout in the file. To direct load & save it, we need to remove all structure memory padding -#pragma pack(push,1) - struct BtHeader - { - char headerTag[7]; // Should be "binterr" - char headerTagVersion[3]; // Should be "1.3" - AZ::s32 columns; // # of columns in the heightfield - AZ::s32 rows; // # of rows in the heightfield - AZ::s16 bytesPerPoint; // bytes per height value, either 2 for signed ints or 4 for floats - AZ::s16 isFloatingPointData; // 1 if height values are floats, 0 for 16-bit signed ints - AZ::s16 horizUnits; // 0 if degrees, 1 if meters, 2 if international feet, 3 if US survey feet - AZ::s16 utmZone; // UTM projection zone 1 to 60 or -1 to -60 (see https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system ) - AZ::s16 datum; // Datum value (6001 to 6094), see http://www.epsg.org/ - double leftExtent; // left coordinate projection of the file - double rightExtent; // right coordinate projection of the file - double bottomExtent; // bottom coordinate projection of the file - double topExtent; // top coordinate projection of the file - AZ::s16 externalProjection; // 1 if projection is in an external .prj file, 0 if it's contained in the header - float scale; // vertical units in meters. 0.0 should be treated as 1.0 - char unused[190]; - }; -#pragma pack(pop) - - AZStd::vector LoadFile(const AZStd::string& fileName) - { - AZ::IO::FileIOBase* fileReader = AZ::IO::FileIOBase::GetInstance(); - - if (!fileReader) - { - return {}; - } - - // an engine compatible file reader has been attached, so use that. - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - AZ::u64 fileSize = 0; - - if (!fileReader->Open(fileName.c_str(), AZ::IO::OpenMode::ModeRead | AZ::IO::OpenMode::ModeBinary, fileHandle)) - { - return {}; - } - - if ((!fileReader->Size(fileHandle, fileSize)) || (fileSize == 0)) - { - fileReader->Close(fileHandle); - return {}; - } - - AZStd::vector fileBuf(fileSize); - - if (!fileReader->Read(fileHandle, fileBuf.data(), fileSize, true)) - { - fileReader->Close(fileHandle); - return {}; - } - - fileReader->Close(fileHandle); - - return fileBuf; - } - - bool IsHeaderValid(const BtHeader* header, std::size_t fileSize) - { - bool validData = true; - - // Do some quick error-checking on the header to make sure it meets our expectations - - // Does the header have the right header tag? (binterr1.0 - binterr1.3) - validData = validData && (memcmp(header->headerTag, "binterr", sizeof(header->headerTag)) == 0); - validData = validData && (header->headerTagVersion[0] == '1') && (header->headerTagVersion[1] == '.') && (header->headerTagVersion[2] >= '0') && (header->headerTagVersion[2] <= '3'); - - // Will the grid fit into a reasonable image size? - validData = validData && (header->columns >= 0) && (header->columns < 65536); - validData = validData && (header->rows >= 0) && (header->rows < 65536); - - // Do we either have 32-bit floats or 16-bit ints? - validData = validData && (((header->isFloatingPointData == 1) && (header->bytesPerPoint == 4)) || ((header->isFloatingPointData == 0) && (header->bytesPerPoint == 2))); - - // Is the remaining data exactly the size needed to fill our image? - AZ::s32 total = header->columns * header->rows * header->bytesPerPoint; - validData = validData && ((fileSize - sizeof(BtHeader)) == total); - - return validData; - } -} - -namespace ImageProcessing -{ - bool BTLoader::IsExtensionSupported(const char* extension) - { - return strcmp(extension, "bt") == 0; - } - - /* - Most of the logic here was taken from ImageBT.cpp. Please make sure - any changes are kept in sync :) - */ - IImageObject* BTLoader::LoadImageFromBT(const AZStd::string& fileName) - { - auto fileData = LoadFile(fileName); - - if (fileData.size() < sizeof(BtHeader)) - { - return nullptr; - } - - auto header = reinterpret_cast(fileData.data()); - - if (!header || !IsHeaderValid(header, fileData.size())) - { - return nullptr; - } - - if (header->scale == 0.0f) - { - header->scale = 1.0f; - } - - // The BT format defines the data as stored in column-first order, from bottom to top. - // However, some BT files store the data in row-first order, from top to bottom. - // There isn't anything that clearly specifies which type of file it is. If you load it the wrong way, - // the data will look like a bunch of wavy stripes. - // The only difference I've found in test files is datum values above 8000, which appears to be an invalid value for datum - // (it should be 6001-6904 according to the BT definition) - constexpr AZ::s32 invalidDatumValueDenotingColumnFirstData = 8000; - bool isColumnFirstData = (header->datum >= invalidDatumValueDenotingColumnFirstData) ? true : false; - AZ::s32 imageWidth = 0; - AZ::s32 imageHeight = 0; - - if (isColumnFirstData) - { - imageWidth = header->rows; - imageHeight = header->columns; - } - else - { - imageWidth = header->columns; - imageHeight = header->rows; - } - - IImageObject* image = IImageObject::CreateImage(imageWidth, imageHeight, 1, EPixelFormat::ePixelFormat_R32F); - - AZ::u8* p = nullptr; - AZ::u32 dwPitch = 0; - image->GetImagePointer(0, p, dwPitch); - - auto dst = reinterpret_cast(p); - auto maxPixel = std::numeric_limits::lowest(); - auto minPixel = std::numeric_limits::max(); - auto terrainData = reinterpret_cast(header + 1); - - // Read in the pixel data - if (header->isFloatingPointData) - { - for (AZ::s32 y = 0; y < imageHeight; ++y) - { - for (AZ::s32 x = 0; x < imageWidth; ++x) - { - float height = *reinterpret_cast(terrainData); - terrainData += sizeof(float); - - // Scale based on what our header defines - float setVal = dst[(y * imageWidth) + x] = height * header->scale; - maxPixel = AZStd::max(maxPixel, setVal); - minPixel = AZStd::min(minPixel, setVal); - } - } - } - else - { - for (AZ::s32 y = 0; y < imageHeight; ++y) - { - for (AZ::s32 x = 0; x < imageWidth; ++x) - { - float height = static_cast(*reinterpret_cast(terrainData)); - terrainData += sizeof(AZ::s16); - - // Scale based on what our header defines - float setVal = dst[(y * imageWidth) + x] = height * header->scale; - maxPixel = AZStd::max(maxPixel, setVal); - minPixel = AZStd::min(minPixel, setVal); - } - } - } - - // Scale our range down to 0 - 1 - auto diff = maxPixel - minPixel; - if (AZ::GetAbs(diff) < std::numeric_limits::epsilon()) - { - diff = 1.0f; - } - - auto imagePixels = imageWidth * imageHeight; - for (AZ::s32 i = 0; i < imagePixels; ++i) - { - dst[i] = (dst[i] - minPixel) / diff; - } - - return image; - } -} diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.cpp deleted file mode 100644 index ac6b1d34d5..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include - -namespace ImageProcessing -{ - IImageObject* LoadImageFromFile(const AZStd::string& filename) - { - QFileInfo fileInfo(filename.c_str()); - QString ext = fileInfo.suffix(); - - if (TIFFLoader::IsExtensionSupported(ext.toUtf8())) - { - return TIFFLoader::LoadImageFromTIFF(filename); - } - else if (BTLoader::IsExtensionSupported(ext.toUtf8())) - { - return BTLoader::LoadImageFromBT(filename); - } - else if (QtImageLoader::IsExtensionSupported(ext.toUtf8())) - { - return QtImageLoader::LoadImageFromFile(filename); - } - - AZ_Warning("ImageProcessing", false, "No proper image loader to load file: %s", filename.c_str()); - return nullptr; - } - - bool IsExtensionSupported(const char* extension) - { - if (TIFFLoader::IsExtensionSupported(extension)) - { - return true; - } - else if (BTLoader::IsExtensionSupported(extension)) - { - return true; - } - else if (QtImageLoader::IsExtensionSupported(extension)) - { - return true; - } - return false; - } - - const AZStd::string LoadEmbeddedSettingFromFile(const AZStd::string& filename) - { - QFileInfo fileInfo(filename.c_str()); - QString ext = fileInfo.suffix(); - - if (TIFFLoader::IsExtensionSupported(ext.toUtf8())) - { - return TIFFLoader::LoadSettingFromTIFF(filename); - } - return ""; - } - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.h b/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.h deleted file mode 100644 index ae460b3552..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - class IImageObject; - - IImageObject* LoadImageFromFile(const AZStd::string& filename); - bool IsExtensionSupported(const char* extension); - const AZStd::string LoadEmbeddedSettingFromFile(const AZStd::string& filename); - - // Tiff loader. The loader support uncompressed tiff with with 1~4 channels and 8bit and 16bit uint or 16bits and 32bits float per channel - // QImage also support tiff (tiff plugin), but it only supports 8bits uint - namespace TIFFLoader - { - bool IsExtensionSupported(const char* extension); - // Load a tiff file to an image object. - IImageObject* LoadImageFromTIFF(const AZStd::string& filename); - // Load embedded .exportsettings string from tiff which was exported by deprecated feature of CryTif plugin. - const AZStd::string LoadSettingFromTIFF(const AZStd::string& filename); - };// namespace ImageTIFF - - namespace BTLoader - { - bool IsExtensionSupported(const char* extension); - // Load a BT file to an image object. - IImageObject* LoadImageFromBT(const AZStd::string& fileName); - }// namespace BTLoader - - // Image loader through Qt's QImage with image formats supported native and through plugins - namespace QtImageLoader - { - bool IsExtensionSupported(const char* extension); - // Load image file which supported by QtImage to an image object - IImageObject* LoadImageFromFile(const AZStd::string& filename); - };// namespace QtImageLoader - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/QtImageLoader.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/QtImageLoader.cpp deleted file mode 100644 index dd5dd62b73..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/QtImageLoader.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "ImageProcessing_precompiled.h" - -#include -#include - -#include -#include - -/////////////////////////////////////////////////////////////////////////////////// - -namespace ImageProcessing -{ - namespace QtImageLoader - { - IImageObject* LoadImageFromFile(const AZStd::string& filename) - { - //try to open the image - QImage qimage(filename.c_str()); - if (qimage.isNull()) - { - return NULL; - } - - //convert to format which compatiable our pixel format - if (qimage.format() != QImage::Format_RGBA8888) - { - qimage = qimage.convertToFormat(QImage::Format_RGBA8888); - } - - //create a new image object - IImageObject *pImage = IImageObject::CreateImage(qimage.width(), qimage.height(), 1, - ePixelFormat_R8G8B8A8); - - //get a pointer to the image objects pixel data - uint8* pDst; - uint32 dwPitch; - pImage->GetImagePointer(0, pDst, dwPitch); - - //copy the qImage into the image object - for (uint32 dwY = 0; dwY < (uint32)qimage.height(); ++dwY) - { - uint8* dstLine = &pDst[dwPitch * dwY]; - uchar* srcLine = qimage.scanLine(dwY); - memcpy(dstLine, srcLine, dwPitch); - } - return pImage; - } - - bool IsExtensionSupported(const char* extension) - { - QList imgFormats = QImageReader::supportedImageFormats(); - - for (int i = 0; i < imgFormats.size(); ++i) - { - if (QString::fromUtf8(imgFormats[i]).toLower() == QString(extension).toLower()) - { - return true; - } - } - - return false; - } - }//namespace QtImageLoader -} //namespace ImageProcessing - diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp deleted file mode 100644 index 6c2881423d..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp +++ /dev/null @@ -1,660 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" - -#include -#include -#include -#include - -#include -#include - -#include - -#include // TIFF library - -namespace ImageProcessing -{ - namespace TIFFLoader - { - class TiffFileRead - { - public: - TiffFileRead(const AZStd::string& filename) - : m_tif(nullptr) - { - m_tif = TIFFOpen(filename.c_str(), "r");; - } - - ~TiffFileRead() - { - if (m_tif != nullptr) - { - TIFFClose(m_tif); - } - } - - TIFF *GetTiff() - { - return m_tif; - } - - private: - TIFF *m_tif; - }; - - bool IsExtensionSupported(const char* extension) - { - QString ext = QString(extension).toLower(); - // This is the list of file extensions supported by this loader - return ext == "tif" || ext == "tiff"; - } - - struct TiffData - { - AZ::u32 m_channels = 0; - AZ::u32 m_photometric = 0; - AZ::u32 m_bitsPerPixel = 0; - AZ::u16 m_format = 0; - - AZ::u32 m_width = 0; - AZ::u32 m_height = 0; - - AZ::u32 m_tileWidth = 0; - AZ::u32 m_tileHeight = 0; - bool m_isTiled = false; - AZ::u32 m_bufSize = 0; - - bool m_isGeoTiff = false; - float m_pixelValueScale = 1.0f; - - EPixelFormat m_pixelFormat = EPixelFormat::ePixelFormat_Unknown; - }; - - static void Process8BitTiff(AZ::u8* dst, const AZ::u8* src, AZ::u32 destIdx, AZ::u32 srcIdx, const TiffData& data, AZ::u8& dstMult) - { - if (data.m_channels == 1) - { - if (data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 3] = 0xFF; - - dstMult = 4; - } - } - else if (data.m_channels == 2) - { - if (data.m_photometric == PHOTOMETRIC_SEPARATED) - { - // convert CMY to RGB (PHOTOMETRIC_SEPARATED refers to inks in TIFF, the value is inverted) - dst[destIdx] = aznumeric_cast(0xFF - src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(0xFF - src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = 0x00; - dst[destIdx + 3] = 0xFF; - - dstMult = 4; - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - - dstMult = 2; - } - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx + 2] * data.m_pixelValueScale); - dst[destIdx + 3] = (data.m_channels == 3) ? 0xFF : aznumeric_cast(src[srcIdx + 3] * data.m_pixelValueScale); - - dstMult = 4; - } - } - - static void Process16BitHDRTiff(AZ::s16* dst, const AZ::s16* src, AZ::u32 destIdx, AZ::u32 srcIdx, const TiffData& data, AZ::u8& dstMult) - { - if (data.m_channels == 1) - { - if (data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 3] = 1; - - dstMult = 4; - } - } - else if (data.m_channels == 2) - { - if (data.m_photometric == PHOTOMETRIC_SEPARATED) - { - //but convert CMY to RGB (PHOTOMETRIC_SEPARATED refers to inks in TIFF, the value is inverted) - dst[destIdx] = uint16(1.0f - src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = uint16(1.0f - src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = 0; - dst[destIdx + 3] = 1; - - dstMult = 4; - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - - dstMult = 2; - } - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx + 2] * data.m_pixelValueScale); - dst[destIdx + 3] = (data.m_channels == 3) ? 1 : aznumeric_cast(src[srcIdx + 3] * data.m_pixelValueScale); - - dstMult = 4; - } - } - - static void Process16BitTiff(AZ::u16* dst, const AZ::u16* src, AZ::u32 destIdx, AZ::u32 srcIdx, const TiffData& data, AZ::u8& dstMult) - { - if (data.m_channels == 1) - { - if (data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 3] = 0xFFFF; - - dstMult = 4; - } - } - else if (data.m_channels == 2) - { - if (data.m_photometric == PHOTOMETRIC_SEPARATED) - { - //convert CMY to RGB (PHOTOMETRIC_SEPARATED refers to inks in TIFF, the value is inverted) - dst[destIdx] = 0xFFFF - aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = 0xFFFF - aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = 0x0000; - dst[destIdx + 3] = 0xFFFF; - - dstMult = 4; - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - - dstMult = 2; - } - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx + 2] * data.m_pixelValueScale); - dst[destIdx + 3] = (data.m_channels == 3) ? 0xFFFF : aznumeric_cast(src[srcIdx + 3] * data.m_pixelValueScale); - - dstMult = 4; - } - } - - static void Process32BitHDRTiff(float* dst, const float* src, AZ::u32 destIdx, AZ::u32 srcIdx, const TiffData& data, AZ::u8& dstMult) - { - auto getScaledOrClamped = [&data](auto val) - { - // GeoTiff doesn't clamp because negative values are legitimate when the data represents height values below sea level. - return data.m_isGeoTiff ? (val * data.m_pixelValueScale) : AZ::GetMax(val, 0.0f); - }; - - if (data.m_channels == 1) - { - if (data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - // clamp negative values - const float v = getScaledOrClamped(src[srcIdx]); - dst[destIdx] = v; - } - else - { - // clamp negative values - const float v = getScaledOrClamped(src[srcIdx]); - dst[destIdx] = v; - dst[destIdx + 1] = v; - dst[destIdx + 2] = v; - dst[destIdx + 3] = 1.0f; - - dstMult = 4; - } - } - else if (data.m_channels == 2) - { - if (data.m_photometric == PHOTOMETRIC_SEPARATED) - { - //convert CMY to RGB (PHOTOMETRIC_SEPARATED refers to inks in TIFF, the value is inverted) - dst[destIdx] = 1.0f - getScaledOrClamped(src[srcIdx]); - dst[destIdx + 1] = 1.0f - getScaledOrClamped(src[srcIdx + 1]); - dst[destIdx + 2] = 0.0f; - dst[destIdx + 3] = 1.0f; - - dstMult = 4; - } - else - { - dst[destIdx] = src[srcIdx] * data.m_pixelValueScale; - dst[destIdx + 1] = src[srcIdx + 1] * data.m_pixelValueScale; - - dstMult = 2; - } - } - else - { - // clamp negative values; don't swap red and blue -> RGB(A) - dst[destIdx] = getScaledOrClamped(src[srcIdx]); - dst[destIdx + 1] = getScaledOrClamped(src[srcIdx + 1]); - dst[destIdx + 2] = getScaledOrClamped(src[srcIdx + 2]); - dst[destIdx + 3] = (data.m_channels == 3) ? 1.0f : getScaledOrClamped(src[srcIdx + 3]) * data.m_pixelValueScale; - - dstMult = 4; - } - } - - static TiffData GetTiffData(TIFF* tif) - { - TiffData data; - - TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &data.m_channels); - TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &data.m_photometric); - TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &data.m_bitsPerPixel); - TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &data.m_format); - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &data.m_width); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &data.m_height); - TIFFGetField(tif, TIFFTAG_TILEWIDTH, &data.m_tileWidth); - TIFFGetField(tif, TIFFTAG_TILELENGTH, &data.m_tileHeight); - - // Check to see if this is a tiled TIFF (vs a scanline-based TIFF) - if ((data.m_tileWidth > 0) && (data.m_tileHeight > 0)) - { - // Tiled TIFF, so our buffer needs to be tile-sized - data.m_isTiled = true; - data.m_bufSize = TIFFTileSize(tif); - } - else - { - // Scanline TIFF, so our buffer needs to be scanline-sized. - data.m_bufSize = TIFFScanlineSize(tif); - - // Treat scanlines like a tile of 1 x width size. - data.m_tileHeight = 1; - data.m_tileWidth = data.m_width; - } - - // Defined in GeoTIFF format - http://web.archive.org/web/20160403164508/http://www.remotesensing.org/geotiff/spec/geotiffhome.html - // Used to get the X, Y, Z scales from a GeoTIFF file - constexpr auto GEOTIFF_MODELPIXELSCALE_TAG = 33550; - - // Check to see if it's a GeoTIFF, and if so, whether or not it has the ZScale parameter. - AZ::u32 tagCount = 0; - double* pixelScales = nullptr; - if (TIFFGetField(tif, GEOTIFF_MODELPIXELSCALE_TAG, &tagCount, &pixelScales) == 1) - { - data.m_isGeoTiff = true; - - // if there's an xyz scale, and the Z scale isn't 0, let's use it. - if ((tagCount == 3) && (pixelScales != nullptr) && (pixelScales[2] != 0.0f)) - { - data.m_pixelValueScale = static_cast(pixelScales[2]); - } - } - - // Retrieve the pixel format of the image - switch (data.m_bitsPerPixel) - { - case 8: - { - data.m_pixelFormat = ePixelFormat_R8G8B8X8; - - if (data.m_channels == 1 && data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - data.m_pixelFormat = ePixelFormat_R8; - } - else if (data.m_channels == 4) - { - data.m_pixelFormat = ePixelFormat_R8G8B8A8; - } - - break; - } - - case 16: - { - if (data.m_format == SAMPLEFORMAT_IEEEFP) - { - data.m_pixelFormat = ePixelFormat_R16G16B16A16F; - - if (data.m_channels == 1 && data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - data.m_pixelFormat = ePixelFormat_R16F; - } - } - else - { - data.m_pixelFormat = ePixelFormat_R16G16B16A16; - - if (data.m_channels == 1 && data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - data.m_pixelFormat = ePixelFormat_R16; - } - } - - break; - } - - case 32: - { - if (data.m_format == SAMPLEFORMAT_IEEEFP) - { - data.m_pixelFormat = ePixelFormat_R32G32B32A32F; - - if (data.m_channels == 1 && data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - data.m_pixelFormat = ePixelFormat_R32F; - } - } - - break; - } - - default: - break; - } - - return data; - } - - static IImageObject* LoadTIFF(TIFF* tif) - { - TiffData data = GetTiffData(tif); - AZStd::unique_ptr destImageObject; - destImageObject.reset(IImageObject::CreateImage(data.m_width, data.m_height, - 1, data.m_pixelFormat)); - - uint8* dst; - uint32 pitch; - destImageObject->GetImagePointer(0, dst, pitch); - - AZStd::vector buf(data.m_bufSize); - - AZ::u8 dstMult = 1; - - // Loop across the image height, one tile at a time - for (AZ::u32 imageY = 0; imageY < data.m_height; imageY += data.m_tileHeight) - { - // If we aren't actually tiled, we'll need to read a scanline here - if (!data.m_isTiled) - { - if (TIFFReadScanline(tif, buf.data(), imageY) == -1) - { - AZ_Error("LoadTIFF", false, "Error reading scanline."); - return nullptr; - } - } - - // Loop across the image width, one tile at a time - for (AZ::u32 imageX = 0; imageX < data.m_width; imageX += data.m_tileWidth) - { - // If we *are* tiled, read in a new tile here - if (data.m_isTiled) - { - if (TIFFReadTile(tif, buf.data(), imageX, imageY, 0, 0) == -1) - { - AZ_Error("LoadTIFF", false, "Error reading tile."); - return nullptr; - } - } - - // For each pixel in the tile buffer, read it in and convert. - for (AZ::u32 tileY = 0; tileY < data.m_tileHeight; ++tileY) - { - for (AZ::u32 tileX = 0; tileX < data.m_tileWidth; ++tileX) - { - AZ::u32 srcIdx = ((tileY * data.m_tileWidth) + tileX) * data.m_channels; - AZ::u32 destIdx = (((imageY + tileY) * data.m_width) + (imageX + tileX)) * dstMult; - - switch (data.m_bitsPerPixel) - { - case 8: - Process8BitTiff(dst, buf.data(), destIdx, srcIdx, data, dstMult); - break; - - case 16: - { - switch (data.m_format) - { - case SAMPLEFORMAT_INT: - case SAMPLEFORMAT_IEEEFP: - Process16BitHDRTiff(reinterpret_cast(dst), reinterpret_cast(buf.data()), - destIdx, srcIdx, data, dstMult); - - break; - - default: - Process16BitTiff(reinterpret_cast(dst), reinterpret_cast(buf.data()), - destIdx, srcIdx, data, dstMult); - - break; - } - - break; - } - - case 32: - if (data.m_format == SAMPLEFORMAT_IEEEFP) - { - Process32BitHDRTiff(reinterpret_cast(dst), reinterpret_cast(buf.data()), - destIdx, srcIdx, data, dstMult); - } - else - { - AZ_Error("LoadTIFF", false, "Unknown / unsupported format."); - return nullptr; - } - - break; - - default: - AZ_Error("LoadTIFF", false, "Unknown / unsupported format."); - return nullptr; - } - - } - } - } - } - - return destImageObject.release(); - } - - IImageObject* LoadImageFromTIFF(const AZStd::string& filename) - { - TiffFileRead tiffRead(filename); - TIFF* tif = tiffRead.GetTiff(); - - IImageObject* destImageObject = nullptr; - - if (!tif) - { - AZ_Warning("Image Processing", false, "%s: Open tiff failed (%s)", __FUNCTION__, filename.c_str()); - return destImageObject; - } - - uint32 bitsPerChannel = 0; - uint32 channels = 0; - uint32 format = 0; - TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &channels); - TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerChannel); - TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &format); - - if (channels != 1 && channels != 2 && channels != 3 && channels != 4) - { - AZ_Warning("Image Processing", false, "Unsupported TIFF pixel format (channel count: %d)", channels); - return destImageObject; - } - - uint32 width = 0; - uint32 height = 0; - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); - if (width <= 0 || height <= 0) - { - AZ_Error("Image Processing", false, "%s failed (empty image)", __FUNCTION__); - return destImageObject; - } - - destImageObject = LoadTIFF(tif); - - if (destImageObject == nullptr) - { - AZ_Error("Image Processing", false, "Failed to read TIFF pixels"); - } - - return destImageObject; - } - - const AZStd::string LoadSettingFromTIFF(const AZStd::string& filename) - { - AZStd::string setting = ""; - - TiffFileRead tiffRead(filename); - TIFF* tif = tiffRead.GetTiff(); - - if (tif == nullptr) - { - return setting; - } - - // get image metadata - const unsigned char* buffer = nullptr; - unsigned int bufferLength = 0; - - if (!TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &bufferLength, &buffer)) // 34377 IPTC TAG - { - return setting; - } - - const unsigned char* const bufferEnd = buffer + bufferLength; - - // detailed structure here: - // https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_pgfId-1037504 - while (buffer < bufferEnd) - { - const unsigned char* const bufferStart = buffer; - - // sanity check - if (buffer[0] != '8' || buffer[1] != 'B' || buffer[2] != 'I' || buffer[3] != 'M') - { - AZ_Warning("Image Processing", false, "Invalid Photoshop TIFF file [%s]!", filename.c_str()); - return setting; - } - buffer += 4; - - // get image resource id - const unsigned short resourceId = (((unsigned short)buffer[0]) << 8) | (unsigned short)buffer[1]; - buffer += 2; - - // get size of pascal string - const unsigned int nameSize = (unsigned int)buffer[0]; - ++buffer; - - // get pascal string - AZStd::string szName(buffer, buffer + nameSize); - buffer += nameSize; - - // align 2 bytes - if ((buffer - bufferStart) & 1) - { - ++buffer; - } - - // get size of resource data - const unsigned int resDataSize = - (((unsigned int)buffer[0]) << 24) | - (((unsigned int)buffer[1]) << 16) | - (((unsigned int)buffer[2]) << 8) | - (unsigned int)buffer[3]; - buffer += 4; - - // IPTC-NAA record. Contains the [File Info...] information. Old RC use this section to store the setting string. - if (resourceId == 0x0404) - { - const unsigned char* const iptcBufferStart = buffer; - - // Old RC uses IPTC ApplicationRecord tags SpecialInstructions to store the setting string - // IPTC Details: https://iptc.org/std/photometadata/specification/mapping/iptc-pmd-newsmlg2.html - unsigned int iptcPos = 0; - while (iptcPos + 5 < resDataSize) - { - int marker = iptcBufferStart[iptcPos++]; - int recordNumber = iptcBufferStart[iptcPos++]; - int dataSetNumber = iptcBufferStart[iptcPos++]; - int fieldLength = (iptcBufferStart[iptcPos++] << 8); - fieldLength += iptcBufferStart[iptcPos++]; - - // Ignore fields other than SpecialInstructions - if (marker != 0x1C || recordNumber != 0x02 || dataSetNumber != 0x28 ) - { - iptcPos += fieldLength; - continue; - } - - //save the setting string before close file - setting = AZStd::string(iptcBufferStart + iptcPos, iptcBufferStart + iptcPos + fieldLength); - return setting; - } - } - - buffer += resDataSize; - - // align 2 bytes - if ((buffer - bufferStart) & 1) - { - ++buffer; - } - } - - return setting; - } - - }// namespace ImageTIFF - -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessingModule.cpp b/Gems/ImageProcessing/Code/Source/ImageProcessingModule.cpp deleted file mode 100644 index 9cd28b39fe..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessingModule.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include "ImageProcessingSystemComponent.h" -#include "ImageBuilderComponent.h" -#include "AtlasBuilder/AtlasBuilderComponent.h" - -namespace ImageProcessing -{ - class ImageProcessingModule - : public AZ::Module - { - public: - AZ_RTTI(ImageProcessingModule, "{A5392495-DD0E-4719-948A-B98DBAE88197}", AZ::Module); - - ImageProcessingModule() - : AZ::Module() - { - // Push results of the components' ::CreateDescriptor() into m_descriptors here. - m_descriptors.insert(m_descriptors.end(), { - ImageProcessingSystemComponent::CreateDescriptor(), //system component for editor - BuilderPluginComponent::CreateDescriptor(), //builder component for AP - TextureAtlasBuilder::AtlasBuilderComponent::CreateDescriptor(), //builder component for texture atlas - }); - } - - /** - * Add required SystemComponents to the SystemEntity. - */ - AZ::ComponentTypeList GetRequiredSystemComponents() const override - { - return AZ::ComponentTypeList{ - azrtti_typeid(), - }; - } - }; -} - -// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM -// The first parameter should be GemName_GemIdLower -// The second should be the fully qualified name of the class above -AZ_DECLARE_MODULE_CLASS(Gem_ImageProcessing, ImageProcessing::ImageProcessingModule) diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.cpp b/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.cpp deleted file mode 100644 index 6629dc592a..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "ImageProcessingSystemComponent.h" -#include -#include - -namespace ImageProcessing -{ - void ImageProcessingSystemComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(0) - ; - } - } - - void ImageProcessingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("ImageBuilderService", 0x43c4be37)); - } - - void ImageProcessingSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("ImageBuilderService", 0x43c4be37)); - } - - void ImageProcessingSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - (void)required; - } - - void ImageProcessingSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) - { - (void)dependent; - } - - void ImageProcessingSystemComponent::Init() - { - - } - - void ImageProcessingSystemComponent::Activate() - { - // Call to allocate BuilderSettingManager - BuilderSettingManager::CreateInstance(); - - ImageProcessingEditor::ImageProcessingEditorRequestBus::Handler::BusConnect(); - AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect(); - AzToolsFramework::AssetBrowser::AssetBrowserTexturePreviewRequestsBus::Handler::BusConnect(); - ImageProcessingRequestBus::Handler::BusConnect(); - } - - void ImageProcessingSystemComponent::Deactivate() - { - ImageProcessingRequestBus::Handler::BusDisconnect(); - ImageProcessingEditor::ImageProcessingEditorRequestBus::Handler::BusDisconnect(); - AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect(); - AzToolsFramework::AssetBrowser::AssetBrowserTexturePreviewRequestsBus::Handler::BusDisconnect(); - - // Deallocate BuilderSettingManager - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - } - - void ImageProcessingSystemComponent::OpenSourceTextureFile(const AZ::Uuid& textureSourceID) - { - if (textureSourceID.IsNull()) - { - QMessageBox::warning(QApplication::activeWindow(), "Warning", - "Texture source does not have a unique ID. This can occur if the source asset has not yet been processed by the Asset Processor.", - QMessageBox::Ok); - } - else - { - ImageProcessingEditor::TexturePropertyEditor editor(textureSourceID, QApplication::activeWindow()); - if (!editor.HasValidImage()) - { - QMessageBox::warning(QApplication::activeWindow(), "Warning", "Invalid texture file", QMessageBox::Ok); - return; - } - editor.exec(); - } - } - - IImageObjectPtr ImageProcessingSystemComponent::LoadImage(const AZStd::string& filePath) - { - return IImageObjectPtr(LoadImageFromFile(filePath)); - } - - IImageObjectPtr ImageProcessingSystemComponent::LoadImagePreview(const AZStd::string& filePath) - { - IImageObjectPtr image(LoadImageFromFile(filePath)); - if (image) - { - ImageToProcess imageToProcess(image); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - return imageToProcess.Get(); - } - return image; - } - - void ImageProcessingSystemComponent::AddSourceFileOpeners(const char* fullSourceFileName, [[maybe_unused]] const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) - { - if (HandlesSource(fullSourceFileName)) - { - openers.push_back( - { - "Image_Processing_Editor", - "Edit Image Settings...", - QIcon(), - [&](const char* fullSourceFileNameInCallback, const AZ::Uuid& sourceUUID) - { - AZ_UNUSED(fullSourceFileNameInCallback); - - if (!LoadTextureSettings()) - { - return; - } - - ImageProcessingEditor::ImageProcessingEditorRequestBus::Broadcast(&ImageProcessingEditor::ImageProcessingEditorRequests::OpenSourceTextureFile, sourceUUID); - } - }); - } - } - - bool ImageProcessingSystemComponent::HandlesSource(AZStd::string_view fileName) const - { - for (int i = 0; i < s_TotalSupportedImageExtensions; i ++ ) - { - if (AZStd::wildcard_match(s_SupportedImageExtensions[i], fileName.data())) - { - return true; - } - } - - return false; - } - - bool ImageProcessingSystemComponent::GetProductTexturePreview(const char* fullProductFileName, QImage& previewImage, AZStd::string& productInfo, AZStd::string& productAlphaInfo) - { - return ImagePreview::GetProductTexturePreview(fullProductFileName, previewImage, productInfo, productAlphaInfo); - } - - bool ImageProcessingSystemComponent::LoadTextureSettings() - { - if (m_textureSettingsLoaded) - { - return true; - } - - // Load the preset settings before opening the editor - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(); - if (outcome.IsSuccess()) - { - m_textureSettingsLoaded = true; - return true; - } - - AZ_Error("Image Processing", false, "Failed to load default preset settings!"); - return false; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.h b/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.h deleted file mode 100644 index 3d6f03b295..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -#include -#include -#include -#include - -namespace ImageProcessing -{ - class ImageProcessingSystemComponent - : public AZ::Component - , protected ImageProcessingRequestBus::Handler - , protected ImageProcessingEditor::ImageProcessingEditorRequestBus::Handler - , protected AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler - , protected AzToolsFramework::AssetBrowser::AssetBrowserTexturePreviewRequestsBus::Handler - { - public: - AZ_COMPONENT(ImageProcessingSystemComponent, "{13B1EB88-316F-4D44-B59C-886F023A5A58}"); - - static void Reflect(AZ::ReflectContext* context); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - - protected: - //////////////////////////////////////////////////////////////////////// - // ImageProcessingEditorRequestBus interface implementation - void OpenSourceTextureFile(const AZ::Uuid& textureSourceID) override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // ImageProcessingRequestBus interface implementation - IImageObjectPtr LoadImage(const AZStd::string& filePath) override; - IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - void Init() override; - void Activate() override; - void Deactivate() override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationsBus::Handler - void AddSourceFileOpeners(const char* fullSourceFileName, const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AzToolsFramework::AssetBrowser::AssetBrowserTexturePreviewRequestsBus::Handler - bool GetProductTexturePreview(const char* fullProductFileName, QImage& previewImage, AZStd::string& productInfo, AZStd::string& productAlphaInfo) override; - //////////////////////////////////////////////////////////////////////// - - private: - bool HandlesSource(AZStd::string_view fileName) const; - - bool LoadTextureSettings(); - - bool m_textureSettingsLoaded = false; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.cpp b/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.cpp deleted file mode 100644 index cb97685105..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.h b/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.h deleted file mode 100644 index 2972414a1f..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -///////////////////////////////////////////////////////////////////////////// -// Qt -///////////////////////////////////////////////////////////////////////////// -#include -#include -#include - -///////////////////////////////////////////////////////////////////////////// -// AZCore -///////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include - -///////////////////////////////////////////////////////////////////////////// -//Type definitions -///////////////////////////////////////////////////////////////////////////// -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Android.h b/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Android.h deleted file mode 100644 index ab7622478b..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Android.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "pc" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 0 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 0 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 0 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 1 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 0 diff --git a/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Platform.h deleted file mode 100644 index db38b9f980..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android.cmake b/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android_files.cmake deleted file mode 100644 index fd81e56d8d..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_Android.h -) diff --git a/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Linux.h b/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Linux.h deleted file mode 100644 index f1186391ad..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Linux.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "pc" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 0 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 0 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 1 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 0 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 0 diff --git a/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Platform.h deleted file mode 100644 index 4131e01743..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux.cmake b/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux_files.cmake deleted file mode 100644 index 5f1d5dfd84..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_Linux.h -) diff --git a/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Mac.h b/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Mac.h deleted file mode 100644 index b2e35a528d..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Mac.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "osx_gl" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 1 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 0 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 1 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 0 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 1 diff --git a/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Platform.h deleted file mode 100644 index bc9d313e91..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac.cmake b/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac.cmake deleted file mode 100644 index 4d5680a30d..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac.cmake +++ /dev/null @@ -1,10 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# diff --git a/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac_files.cmake deleted file mode 100644 index a25ce357a8..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_Mac.h -) diff --git a/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Platform.h deleted file mode 100644 index d2a32135c3..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Windows.h b/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Windows.h deleted file mode 100644 index 0410a31986..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Windows.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER _j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "pc" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 0 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 1 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 0 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 0 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 0 diff --git a/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows.cmake b/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows_files.cmake deleted file mode 100644 index eabc30e929..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_Windows.h -) diff --git a/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_Platform.h deleted file mode 100644 index 4ecfd207ca..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_iOS.h b/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_iOS.h deleted file mode 100644 index 55b1be4d77..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_iOS.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "osx_gl" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 1 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 0 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 1 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 1 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 1 diff --git a/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios.cmake b/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios_files.cmake deleted file mode 100644 index 12d59f3933..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_iOS.h -) diff --git a/Gems/ImageProcessing/Code/Source/Processing/DDSHeader.h b/Gems/ImageProcessing/Code/Source/Processing/DDSHeader.h deleted file mode 100644 index 9fd0827e21..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/DDSHeader.h +++ /dev/null @@ -1,230 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once -#include -#include -#include - -//! The following defines and constants are extracted from ImageExtensionHelper.h -//! Please make sure they are always synced with ImageExtensionHelper.h - -#define IMAGE_BUIDER_MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((AZ::u32)(AZ::u8)(ch0) | ((AZ::u32)(AZ::u8)(ch1) << 8) | \ - ((AZ::u32)(AZ::u8)(ch2) << 16) | ((AZ::u32)(AZ::u8)(ch3) << 24)) - -// This header defines constants and structures that are useful when parsing -// DDS files. DDS files were originally designed to use several structures -// and constants that are native to DirectDraw and are defined in ddraw.h, -// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar -// (compatible) constants and structures so that one can use DDS files -// without needing to include ddraw.h. - - -//Needed to write out DDS files on Mac -#if AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS -#define DDPF_ALPHAPIXELS 0x00000001 // Texture contains alpha data -#define DDPF_ALPHA 0x00000002 // For alpha channel only uncompressed data -#define DDPF_FOURCC 0x00000004 // Texture contains compressed RGB data -#define DDPF_RGB 0x00000040 // Texture contains uncompressed RGB data -#define DDPF_YUV 0x00000200 // For YUV uncompressed data -#define DDPF_LUMINANCE 0x00020000 // For single channel color uncompressed data - -#define DDSCAPS_COMPLEX 0x00000008 // Must be used on any file that contains more than one surface -#define DDSCAPS_MIPMAP 0x00400000 // Should be used for a mipmap -#define DDSCAPS_TEXTURE 0x00001000 // Required -#endif - -#define DDS_FOURCC 0x00000004 // DDPF_FOURCC -#define DDS_RGB 0x00000040 // DDPF_RGB -#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE -#define DDS_SIGNED 0x00080000 // DDPF_SIGNED -#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS -#define DDS_LUMINANCEA 0x00020001 // DDS_LUMINANCE | DDPF_ALPHAPIXELS -#define DDS_A 0x00000001 // DDPF_ALPHAPIXELS -#define DDS_A_ONLY 0x00000002 // DDPF_ALPHA - -#define DDS_FOURCC_A16B16G16R16 0x00000024 // FOURCC A16B16G16R16 -#define DDS_FOURCC_V16U16 0x00000040 // FOURCC V16U16 -#define DDS_FOURCC_Q16W16V16U16 0x0000006E // FOURCC Q16W16V16U16 -#define DDS_FOURCC_R16F 0x0000006F // FOURCC R16F -#define DDS_FOURCC_G16R16F 0x00000070 // FOURCC G16R16F -#define DDS_FOURCC_A16B16G16R16F 0x00000071 // FOURCC A16B16G16R16F -#define DDS_FOURCC_R32F 0x00000072 // FOURCC R32F -#define DDS_FOURCC_G32R32F 0x00000073 // FOURCC G32R32F -#define DDS_FOURCC_A32B32G32R32F 0x00000074 // FOURCC A32B32G32R32F - -#define DDSD_CAPS 0x00000001l // default -#define DDSD_PIXELFORMAT 0x00001000l -#define DDSD_WIDTH 0x00000004l -#define DDSD_HEIGHT 0x00000002l -#define DDSD_LINEARSIZE 0x00080000l - -#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT -#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT -#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH -#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH -#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE - -#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE -#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP -#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX - -#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX -#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX -#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY -#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY -#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ -#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ - -#define DDS_CUBEMAP_ALLFACES (DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX | \ - DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY | \ - DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ) - -#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME - -#define DDS_RESF1_NORMALMAP 0x01000000 -#define DDS_RESF1_DSDT 0x02000000 - - -namespace ImageProcessing -{ - const static AZ::u32 FOURCC_DX10 = IMAGE_BUIDER_MAKEFOURCC('D', 'X', '1', '0'); - const static AZ::u32 FOURCC_DDS = IMAGE_BUIDER_MAKEFOURCC('D', 'D', 'S', ' '); - const static AZ::u32 FOURCC_FYRC = IMAGE_BUIDER_MAKEFOURCC('F', 'Y', 'R', 'C'); - - //The values of each elements in this enum should be same as ITexture ETEX_TileMode enum. - enum DDS_TileMode : AZ::u8 - { - eTM_None = 0, - eTM_LinearPadded, - eTM_Optimal, - }; - - struct DDS_PIXELFORMAT - { - AZ::u32 dwSize; - AZ::u32 dwFlags; - AZ::u32 dwFourCC; - AZ::u32 dwRGBBitCount; - AZ::u32 dwRBitMask; - AZ::u32 dwGBitMask; - AZ::u32 dwBBitMask; - AZ::u32 dwABitMask; - - const bool operator == (const DDS_PIXELFORMAT& fmt) const - { - return dwFourCC == fmt.dwFourCC && - dwFlags == fmt.dwFlags && - dwRGBBitCount == fmt.dwRGBBitCount && - dwRBitMask == fmt.dwRBitMask && - dwGBitMask == fmt.dwGBitMask && - dwBBitMask == fmt.dwBBitMask && - dwABitMask == fmt.dwABitMask && - dwSize == fmt.dwSize; - } - - }; - - struct DDS_HEADER_DXT10 - { - // we're unable to use native enums, so we use AZ::u32 instead. - AZ::u32 /*DXGI_FORMAT*/ dxgiFormat; - AZ::u32 /*D3D10_RESOURCE_DIMENSION*/ resourceDimension; - AZ::u32 miscFlag; - AZ::u32 arraySize; - AZ::u32 reserved; - }; - - struct DDS_HEADER - { - AZ::u32 dwSize; - AZ::u32 dwHeaderFlags; - AZ::u32 dwHeight; - AZ::u32 dwWidth; - AZ::u32 dwPitchOrLinearSize; - AZ::u32 dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwHeaderFlags - AZ::u32 dwMipMapCount; - AZ::u32 dwAlphaBitDepth; - AZ::u32 dwReserved1; // Crytek image flags - float fAvgBrightness; // Average top mip brightness. Could be f16/half - float cMinColor[4]; - float cMaxColor[4]; - DDS_PIXELFORMAT ddspf; - AZ::u32 dwSurfaceFlags; - AZ::u32 dwCubemapFlags; - AZ::u8 bNumPersistentMips; - AZ::u8 tileMode; //DDS_TileMode - AZ::u8 bReserved2[6]; - AZ::u32 dwTextureStage; - - - inline const bool IsValid() const { return sizeof(*this) == dwSize; } - inline const bool IsDX10Ext() const { return ddspf.dwFourCC == FOURCC_DX10; } - inline const AZ::u32 GetMipCount() const { return AZStd::GetMax(1u, (AZ::u32)dwMipMapCount); } - - inline const size_t GetFullHeaderSize() const - { - if (IsDX10Ext()) - { - return sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); - } - - return sizeof(DDS_HEADER); - } - }; - - // standard description of file header - struct DDS_FILE_DESC - { - AZ::u32 dwMagic; - DDS_HEADER header; - - inline const bool IsValid() const { return dwMagic == FOURCC_DDS && header.IsValid(); } - inline const size_t GetFullHeaderSize() const { return sizeof(dwMagic) + header.GetFullHeaderSize(); } - }; - - // chunk identifier - const static AZ::u32 FOURCC_CExt = IMAGE_BUIDER_MAKEFOURCC('C', 'E', 'x', 't'); // Crytek extension start - const static AZ::u32 FOURCC_CEnd = IMAGE_BUIDER_MAKEFOURCC('C', 'E', 'n', 'd'); // Crytek extension end - const static AZ::u32 FOURCC_AttC = IMAGE_BUIDER_MAKEFOURCC('A', 't', 't', 'C'); // Chunk Attached Channel - - //Fourcc for pixel formats which aren't supported by dx10, such as astc formats, etc formats, pvrtc formats - //They are used for dwFourCC of dds header's DDS_PIXELFORMAT to identify non-dx10 pixel formats - const static AZ::u32 FOURCC_EAC_R11 = IMAGE_BUIDER_MAKEFOURCC('E', 'A', 'R', ' '); - const static AZ::u32 FOURCC_EAC_RG11 = IMAGE_BUIDER_MAKEFOURCC('E', 'A', 'R', 'G'); - const static AZ::u32 FOURCC_ETC2 = IMAGE_BUIDER_MAKEFOURCC('E', 'T', '2', ' '); - const static AZ::u32 FOURCC_ETC2A = IMAGE_BUIDER_MAKEFOURCC('E', 'T', '2', 'A'); - const static AZ::u32 FOURCC_PVRTC2 = IMAGE_BUIDER_MAKEFOURCC('P', 'V', 'R', '2'); - const static AZ::u32 FOURCC_PVRTC4 = IMAGE_BUIDER_MAKEFOURCC('P', 'V', 'R', '4'); - const static AZ::u32 FOURCC_ASTC_4x4 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '4', '4'); - const static AZ::u32 FOURCC_ASTC_5x4 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '5', '4'); - const static AZ::u32 FOURCC_ASTC_5x5 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '5', '5'); - const static AZ::u32 FOURCC_ASTC_6x5 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '6', '5'); - const static AZ::u32 FOURCC_ASTC_6x6 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '6', '6'); - const static AZ::u32 FOURCC_ASTC_8x5 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '8', '5'); - const static AZ::u32 FOURCC_ASTC_8x6 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '8', '6'); - const static AZ::u32 FOURCC_ASTC_10x5 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'A', '5'); - const static AZ::u32 FOURCC_ASTC_10x6 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'A', '6'); - const static AZ::u32 FOURCC_ASTC_8x8 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '8', '8'); - const static AZ::u32 FOURCC_ASTC_10x8 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'A', '8'); - const static AZ::u32 FOURCC_ASTC_10x10 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'A', 'A'); - const static AZ::u32 FOURCC_ASTC_12x10 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'C', 'A'); - const static AZ::u32 FOURCC_ASTC_12x12 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'C', 'C'); - - //legacy formats names. they are only used for load rc.exe's dds formats - const static AZ::u32 FOURCC_DXT1 = IMAGE_BUIDER_MAKEFOURCC('D', 'X', 'T', '1'); - const static AZ::u32 FOURCC_DXT3 = IMAGE_BUIDER_MAKEFOURCC('D', 'X', 'T', '3'); - const static AZ::u32 FOURCC_DXT5 = IMAGE_BUIDER_MAKEFOURCC('D', 'X', 'T', '5'); - const static AZ::u32 FOURCC_3DCP = IMAGE_BUIDER_MAKEFOURCC('A', 'T', 'I', '1'); - const static AZ::u32 FOURCC_3DC = IMAGE_BUIDER_MAKEFOURCC('A', 'T', 'I', '2'); -} diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp deleted file mode 100644 index b5fc329a03..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp +++ /dev/null @@ -1,1014 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -//qt has convenience functions to handle file -#include -#include - -//for texture splitting -//mininum number of low level mips will be saved in the base file. -#define MinPersistantMips 3 -//mininum texture size to be splitted. A texture will only be split when the size is larger than this number -#define MinSizeToSplit 1<<5 - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) - #if defined(TOOLS_SUPPORT_JASPER) - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageProcess, Jasper) - #endif - #if defined(TOOLS_SUPPORT_PROVO) - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageProcess, Provo) - #endif - #if defined(TOOLS_SUPPORT_SALEM) - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageProcess, Salem) - #endif -#endif - -namespace ImageProcessing -{ - - IImageObjectPtr ImageConvertProcess::GetOutputImage() - { - if (m_image) - { - return m_image->Get(); - } - return nullptr; - } - - IImageObjectPtr ImageConvertProcess::GetOutputAlphaImage() - { - return m_alphaImage; - } - - IImageObjectPtr ImageConvertProcess::GetOutputDiffCubemap() - { - return m_diffCubemapImage; - } - - void ImageConvertProcess::GetAppendOutputFilePaths(AZStd::vector& outPaths) - { - for (const auto& path : m_productFilepaths) - { - outPaths.push_back(path); - } - } - - ImageConvertProcess::ImageConvertProcess(const IImageObjectPtr inputImage, const TextureSettings& textureSetting, - const PresetSettings& presetSetting, bool isPreview, bool isStreaming, bool canOverridePreset, - const AZStd::string& outputPath, const AZStd::string& platformId) : - m_inputImage(inputImage), - m_textureSetting(textureSetting), - m_presetSetting(presetSetting), - m_canOverridePreset(canOverridePreset), - m_image(nullptr), - m_isPreview(isPreview), - m_outputPath(outputPath), - m_progressStep(0), - m_isFinished(false), - m_isSucceed(false), - m_processTime(0), - m_isStreaming(isStreaming), - m_platformId(platformId) - { - } - - ImageConvertProcess::~ImageConvertProcess() - { - delete m_image; - } - - bool ImageConvertProcess::IsConvertToCubemap() - { - return m_presetSetting.m_cubemapSetting != nullptr; - } - - void ImageConvertProcess::UpdateProcess() - { - if (m_isFinished) - { - return; - } - - switch (m_progressStep) - { - case StepValidateInput: - //validate - if (!ValidateInput()) - { - m_isSucceed = false; - break; - } - - //set start time - m_startTime = AZStd::GetTimeUTCMilliSecond(); - - //identify the alpha content of input image if gloss from normal wasn't set - m_alphaContent = m_inputImage->GetAlphaContent(); - - //create image for process - m_image = new ImageToProcess(IImageObjectPtr(m_inputImage->Clone())); - - break; - case StepGenerateColorChart: - //GenerateColorChart. - if (m_presetSetting.m_isColorChart) - { - m_image->CreateColorChart(); - } - break; - case StepConvertToLinear: - //convert to linear space and the output image pixel format should be rgba32f - ConvertToLinear(); - break; - case StepSwizzle: - //convert texture format. - if (m_presetSetting.m_swizzle.size() >= 4) - { - m_image->Get()->Swizzle(m_presetSetting.m_swizzle.substr(0, 4).c_str()); - m_alphaContent = m_image->Get()->GetAlphaContent(); - } - - //convert gloss map (alhpa channel) from legacy distribution to new one - if (m_presetSetting.m_isLegacyGloss) - { - m_image->Get()->ConvertLegacyGloss(); - } - break; - case StepOverridePreset: - if (m_canOverridePreset) - { - // Set the pixel format to BC3 if the source contains greyscale alpha and BC1 if it does not. - if (m_presetSetting.m_pixelFormat == ePixelFormat_BC1 - || m_presetSetting.m_pixelFormat == ePixelFormat_BC1a - || m_presetSetting.m_pixelFormat == ePixelFormat_BC3) - { - if (m_alphaContent == EAlphaContent::eAlphaContent_Greyscale) - { - m_presetSetting.m_pixelFormat = ePixelFormat_BC3; - } - else if (m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlackAndWhite - || m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlack - || m_alphaContent == EAlphaContent::eAlphaContent_OnlyWhite) - { - m_presetSetting.m_pixelFormat = ePixelFormat_BC1a; - } - else - { - m_presetSetting.m_pixelFormat = ePixelFormat_BC1; - } - } - } - break; - case StepCubemapLayout: - //convert cubemap image's layout to vertical strip used in game. - if (IsConvertToCubemap()) - { - if (!m_image->ConvertCubemapLayout(CubemapLayoutVertical)) - { - m_image->Set(nullptr); - } - } - break; - case StepPreNormalize: - //normalize base image before mipmap generation if glossfromnormals is enabled and require normalize - if (m_presetSetting.m_isMipRenormalize && m_presetSetting.m_glossFromNormals) - { - // Normalize the base mip map. This has to be done explicitly because we need to disable mip renormalization to - // preserve the normal length when deriving the normal variance - m_image->Get()->NormalizeVectors(0, 1); - } - break; - case StepDiffCubemap: - //create diffuse cubemap. We need to have better way to handle one input multiple export settings later. - CreateDiffuseCubemap(); - break; - case StepMipmap: - //generate mipmaps - if (IsConvertToCubemap()) - { - FillCubemapMipmaps(); - } - else - { - FillMipmaps(); - } - //add image flag - if (m_presetSetting.m_suppressEngineReduce || m_textureSetting.m_suppressEngineReduce) - { - m_image->Get()->AddImageFlags(EIF_SupressEngineReduce); - } - break; - case StepGlossFromNormal: - //get gloss from normal for all mipmaps and save to alpha channel - if (m_presetSetting.m_glossFromNormals) - { - bool hasAlpha = (m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlack - || m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlackAndWhite - || m_alphaContent == EAlphaContent::eAlphaContent_Greyscale); - - m_image->Get()->GlossFromNormals(hasAlpha); - //set alpha content so it won't be ignored later. - m_alphaContent = EAlphaContent::eAlphaContent_Greyscale; - } - break; - case StepPostNormalize: - //normalize all the other mipmaps - if (!IsConvertToCubemap() && m_presetSetting.m_isMipRenormalize) - { - if (m_presetSetting.m_glossFromNormals) - { - //normalize other mips except first mip - m_image->Get()->NormalizeVectors(1, 100); - } - else - { - //normalize all mips - m_image->Get()->NormalizeVectors(0, 100); - } - - m_image->Get()->AddImageFlags(EIF_RenormalizedTexture); - } - break; - case StepCreateHighPass: - if (m_presetSetting.m_highPassMip > 0) - { - m_image->CreateHighPass(m_presetSetting.m_highPassMip); - } - break; - case StepConvertOutputColorSpace: - //comvert image from linear space to desired output color space - ConvertToOuputColorSpace(); - break; - case StepAlphaImage: - //save alpha channel to separate image if it's needed - CreateAlphaImage(); - break; - case StepConvertPixelFormat: - //convert pixel format - ConvertPixelformat(); - break; - case StepSaveToFile: - //save to file - if (!m_isPreview) - { - m_isSucceed = SaveOutput(); - } - else - { - m_isSucceed = true; - } - break; - } - - m_progressStep++; - - if (m_image == nullptr || m_image->Get() == nullptr || m_progressStep >= StepAll) - { - m_isFinished = true; - AZStd::sys_time_t endTime = AZStd::GetTimeUTCMilliSecond(); - m_processTime = aznumeric_cast((endTime - m_startTime) / 1000); - } - - //output conversion log - if (m_isSucceed && m_isFinished) - { - const uint32 sizeTotal = m_image->Get()->GetTextureMemory(); - if (m_isPreview) - { - AZ_TracePrintf("Image Processing", "Image ( %d bytes) converted in %f seconds\n", sizeTotal, m_processTime); - } - else - { - AZ_TracePrintf("Image Processing", "Image converted and saved to %s ( %d bytes) with %f seconds\n", m_outputPath.c_str(), - sizeTotal, m_processTime); - } - } - } - - void ImageConvertProcess::ProcessAll() - { - while (!m_isFinished) - { - UpdateProcess(); - } - } - - float ImageConvertProcess::GetProgress() - { - return m_progressStep / (float)StepAll; - } - - bool ImageConvertProcess::IsFinished() - { - return m_isFinished; - } - - bool ImageConvertProcess::IsSucceed() - { - return m_isSucceed; - } - - //function to get desired output image extent - void GetOutputExtent(AZ::u32 inputWidth, AZ::u32 inputHeight, AZ::u32& outWidth, AZ::u32& outHeight, AZ::u32& outReduce, - const TextureSettings* textureSettings, const PresetSettings* presetSettings) - { - outWidth = inputWidth; - outHeight = inputHeight; - outReduce = 0; - - if (textureSettings == nullptr || presetSettings == nullptr) - { - return; - } - - //don't do any reduce for color chart - if (presetSettings->m_isColorChart) - { - return; - } - - //get suitable size for dest pixel format - CPixelFormats::GetInstance().GetSuitableImageSize(presetSettings->m_pixelFormat, inputWidth, inputHeight, - outWidth, outHeight); - - //desired reduce level. 1 means reduce one level - uint sizeReduceLevel = textureSettings->m_sizeReduceLevel; - - outReduce = 0; - - //reduce to not exceed max texture size - if (presetSettings->m_maxTextureSize > 0) - { - while (outWidth > presetSettings->m_maxTextureSize || outHeight > presetSettings->m_maxTextureSize) - { - outWidth >>= 1; - outHeight >>= 1; - outReduce++; - } - } - - //if it requires to reduce more and the result size will still larger than min texture size, then reduce - while (outReduce < sizeReduceLevel && - (outWidth >= presetSettings->m_minTextureSize * 2 && outHeight >= presetSettings->m_minTextureSize * 2)) - { - outWidth >>= 1; - outHeight >>= 1; - outReduce++; - } - } - - bool ImageConvertProcess::ConvertToLinear() - { - //de-gamma only if the input is sRGB. this will convert other uncompressed format to RGBA32F - return m_image->GammaToLinearRGBA32F(m_presetSetting.m_srcColorSpace == ColorSpace::sRGB); - } - - //mipmap generation - bool ImageConvertProcess::FillMipmaps() - { - //this function only works with pixel format rgba32f - const EPixelFormat srcPixelFormat = m_image->Get()->GetPixelFormat(); - if (srcPixelFormat != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s only works with pixel format rgba32f", __FUNCTION__); - return false; - } - - //only if the src image has one mip - if (m_image->Get()->GetMipCount() != 1) - { - AZ_Assert(false, "%s called for a mipmapped image. ", __FUNCTION__); - return false; - } - - //get output image size - uint32 outWidth; - uint32 outHeight; - uint32 outReduce = 0; - GetOutputExtent(m_image->Get()->GetWidth(0), m_image->Get()->GetHeight(0), outWidth, outHeight, outReduce, &m_textureSetting, - &m_presetSetting); - - //max mipmap count - uint32 mipCount = UINT32_MAX; - if (m_presetSetting.m_mipmapSetting == nullptr || !m_textureSetting.m_enableMipmap) - { - mipCount = 1; - } - - //create new new output image with proper side - IImageObjectPtr outImage(IImageObject::CreateImage(outWidth, outHeight, mipCount, ePixelFormat_R32G32B32A32F)); - - //filter setting for mip map generation - float blurH = 0; - float blurV = 0; - - //fill mipmap data for uncompressed output image - for (uint32 mip = 0; mip < outImage->GetMipCount(); mip++) - { - FilterImage(m_textureSetting.m_mipGenType, m_textureSetting.m_mipGenEval, blurH, blurV, m_image->Get(), 0, outImage, mip, nullptr, nullptr); - } - - //transfer alpha coverage - if (m_textureSetting.m_maintainAlphaCoverage) - { - outImage->TransferAlphaCoverage(&m_textureSetting, m_image->Get()); - } - - //set back to image - m_image->Set(outImage); - return true; - } - - void ImageConvertProcess::CreateAlphaImage() - { - //if alpha content doesn't have alpha or we need to discard alpha, skip - //we won't create alpha image for cubemap too - if (m_alphaContent == EAlphaContent::eAlphaContent_Absent - || m_alphaContent == EAlphaContent::eAlphaContent_OnlyWhite - || m_presetSetting.m_discardAlpha || IsConvertToCubemap()) - { - return; - } - - //Ensure that the PixelFormatAlpha is set otherwise no need to create m_alphaImage - if (m_presetSetting.m_pixelFormatAlpha == ePixelFormat_Unknown) - { - return; - } - - //now create alpha image - ImageToProcess alphaImage(m_image->Get()); - alphaImage.ConvertFormat(ePixelFormat_A8); - - - if(CPixelFormats::GetInstance().IsFormatSingleChannel(m_presetSetting.m_pixelFormatAlpha)) - { - alphaImage.ConvertFormat(m_presetSetting.m_pixelFormatAlpha); - } - else - { - //For PVRTC compression we need to clear out the alpha to get accurate rgb compression. - if (IsPVRTCFormat(m_presetSetting.m_pixelFormat) || IsASTCFormat(m_presetSetting.m_pixelFormat)) - { - alphaImage.ConvertFormat(ePixelFormat_R8G8B8A8); - alphaImage.Get()->Swizzle("rgb1"); - alphaImage.ConvertFormat(m_presetSetting.m_pixelFormatAlpha); - } - else - { - AZ_Assert(false, "Did you apply the correct pixel format for PixelFormatAlpha?"); - } - } - - //get final result and save it to member variable for later use - m_alphaImage = alphaImage.Get(); - - m_image->Get()->AddImageFlags(EIF_AttachedAlpha); - } - - //pixel format convertions - bool ImageConvertProcess::ConvertPixelformat() - { - - //For PVRTC compression we need to clear out the alpha to get accurate rgb compression. - if(m_alphaImage && (IsPVRTCFormat(m_presetSetting.m_pixelFormat) || IsASTCFormat(m_presetSetting.m_pixelFormat))) - { - m_image->Get()->Swizzle("rgb1"); - } - - - //set up compress option - ICompressor::EQuality quality; - if (m_isPreview) - { - quality = ICompressor::eQuality_Preview; - } - else - { - quality = ICompressor::eQuality_Normal; - } - m_image->GetCompressOption().compressQuality = quality; - m_image->GetCompressOption().rgbWeight = m_presetSetting.GetColorWeight(); - m_image->ConvertFormat(m_presetSetting.m_pixelFormat); - return true; - } - - //convert color space from linear to sRGB space if it's neccessary - bool ImageConvertProcess::ConvertToOuputColorSpace() - { - if (m_presetSetting.m_destColorSpace == ColorSpace::sRGB) - { - m_image->LinearToGamma(); - } - else if (m_presetSetting.m_destColorSpace == ColorSpace::autoSelect) - { - //convert to sRGB color space if it's dark image (converting bright images decreases image quality) - bool bThresholded = false; - { - Histogram<256> histogram; - if (ComputeLuminanceHistogram(m_image->Get(), histogram)) - { - const size_t medianBinIndex = 116; - float percentage = histogram.getPercentage(medianBinIndex, 255); - - // The image has significant amount of dark pixels, it's good to use sRGB - bThresholded = (percentage < 50.0f); - } - } - - if (bThresholded) - { - bool convertToSRGB = true; - - // if the image is BC1 compressable, additionally estimate the conversion error - // to only convert if it doesn't introduce error - if (CPixelFormats::GetInstance().IsImageSizeValid(ePixelFormat_BC1, m_image->Get()->GetWidth(0), - m_image->Get()->GetHeight(0), false)) - { - //get image in RGB space - ImageToProcess imageProcess(m_image->Get()); - imageProcess.LinearToGamma(); - - ICompressor::CompressOption option; - option.compressQuality = ICompressor::eQuality_Preview; - option.rgbWeight = m_presetSetting.GetColorWeight(); - - float errorLinearBC1; - float errorSrgbBC1; - GetBC1CompressionErrors(m_image->Get(), errorLinearBC1, errorSrgbBC1, option); - - // Don't convert if it would lower the image quality when saved as sRGB according to GetDXT1GammaCompressionError() - if (errorSrgbBC1 >= errorLinearBC1) - { - convertToSRGB = false; - } - } - - // our final conclusion: if the texture had a significant percentage of dark pixels and, - // if applicable, it was BC1 compressable and gamma compression wouldn't introduce error, - // then we convert it to sRGB - if (convertToSRGB) - { - m_image->LinearToGamma(); - } - } - } - return true; - } - - bool ImageConvertProcess::ValidateInput() - { - //valid the input image and output settings here. - uint32 dwWidth, dwHeight; - dwWidth = m_inputImage->GetWidth(0); - dwHeight = m_inputImage->GetHeight(0); - - EPixelFormat dstFmt = m_presetSetting.m_pixelFormat; - - //check if whether input image can be a cubemap - if (m_presetSetting.m_cubemapSetting) - { - if (CubemapLayout::GetCubemapLayoutInfo(m_inputImage) == nullptr) - { - AZ_Error("Image Processing", false, "Invalid image size %dx%d using as cubemap. Requires power of two with 6x1, 1x6, 4x3 or 3x4 layouts", dwWidth, dwHeight); - return false; - } - } - else if (!CPixelFormats::GetInstance().IsImageSizeValid(dstFmt, dwWidth, dwHeight, false)) - { - AZ_Warning("Image Processing", false, "Image size will be scaled for pixel format %s", CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->szName); - } - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - if (ImageProcess##PrivateName::DoesSupport(m_platformId))\ - {\ - if(!ImageProcess##PrivateName::IsPixelFormatSupported(m_presetSetting.m_pixelFormat))\ - {\ - AZ_Error("Image Processing", false, "Unsupported pixel format %s for %s",\ - CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->szName, m_platformId.c_str());\ - return false;\ - }\ - } - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - - return true; - } - - bool ImageConvertProcess::SaveOutput() - { - //if the path wasn't specified, skip - if (m_outputPath.empty()) - { - AZ_Error("Image Processing", false, "No output path provided for saving"); - return false; - } - - //set all mips as presistent mips by default. it will be modified if the image is splitted later - m_image->Get()->SetNumPersistentMips(m_image->Get()->GetMipCount()); - - //split - if (m_isStreaming && m_presetSetting.m_numStreamableMips > 0) - { - IImageObjectPtr curImage = m_image->Get(); - - if (curImage->GetMipCount() > MinPersistantMips && (curImage->GetWidth(0) > MinSizeToSplit || - curImage->GetWidth(0) > MinSizeToSplit)) - { - //calculate final persistance mip count - AZ::u32 persistantMips = MinPersistantMips; - if (m_presetSetting.m_numStreamableMips < curImage->GetMipCount() - MinPersistantMips) - { - persistantMips = curImage->GetMipCount() - m_presetSetting.m_numStreamableMips; - } - curImage->SetNumPersistentMips(persistantMips); - curImage->AddImageFlags(EIF_Splitted); - - //add flags for alpha image too, assuming alpha image has same size as origin - if (m_alphaImage) - { - m_alphaImage->SetNumPersistentMips(persistantMips); - m_alphaImage->AddImageFlags(EIF_Splitted); - } - } - } - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - if (ImageProcess##PrivateName::DoesSupport(m_platformId))\ - {\ - ImageProcess##PrivateName::PrepareImageForExport(m_image->Get());\ - ImageProcess##PrivateName::PrepareImageForExport(m_alphaImage);\ - } - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - - AZStd::vector outputFilePaths; - if (!m_image->Get()->SaveImage(m_outputPath.c_str(), m_alphaImage, outputFilePaths)) - { - AZ_Error("Image Processing", false, "Save image to %s failed", m_outputPath.c_str()); - return false; - } - - for (auto& path : outputFilePaths) - { - m_productFilepaths.push_back(path); - } - return true; - } - - ImageConvertProcess* CreateImageConvertProcess(const AZStd::string& imageFilePath, const AZStd::string& exportDir - , const PlatformName& platformName, AZ::SerializeContext* context) - { - AZStd::string metafilePath; - BuilderSettingManager::Instance()->MetafilePathFromImagePath(imageFilePath, metafilePath); - TextureSettings textureSettings; - - MultiplatformTextureSettings multiTextureSetting; - bool canOverridePreset = false; - - multiTextureSetting = TextureSettings::GetMultiplatformTextureSetting(imageFilePath, canOverridePreset, context); - if (multiTextureSetting.empty()) - { - AZ_Error("Image Processing", false, "Could not determine export settings for image file [%s] due to previous error(s). Skipping export...", imageFilePath.c_str()); - return nullptr; - } - - if (multiTextureSetting.find(platformName) != multiTextureSetting.end()) - { - textureSettings = multiTextureSetting[platformName]; - } - else - { - PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - if (multiTextureSetting.find(defaultPlatform) != multiTextureSetting.end()) - { - textureSettings = multiTextureSetting[defaultPlatform]; - } - else - { - textureSettings = (*multiTextureSetting.begin()).second; - } - } - - //load image. Do it earlier so GetSuggestedPreset function could use the information of file to choose better preset - IImageObjectPtr srcImage(LoadImageFromFile(imageFilePath)); - if (srcImage == nullptr) - { - AZ_Error("Image Processing", false, "Load image file %s failed", imageFilePath.c_str()); - return nullptr; - } - - //if get textureSetting failed, use the default texture setting, and find suitable preset for this file - //in very rare user case, an old texture setting file may not have a preset. We fix it over here too. - if (textureSettings.m_preset.IsNull()) - { - textureSettings.m_preset = BuilderSettingManager::Instance()->GetSuggestedPreset(imageFilePath, srcImage); - } - - //get preset - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(textureSettings.m_preset, platformName); - - if (preset == nullptr) - { - AZStd::string uuidStr; - textureSettings.m_preset.ToString(uuidStr); - AZ_Assert(false, "%s cannot find image preset with ID %s.", imageFilePath.c_str(), uuidStr.c_str()); - return nullptr; - } - - //generate export file name - QDir dir(exportDir.c_str()); - if (!dir.exists()) - { - dir.mkpath("."); - } - AZStd::string fileName, outputPath; - AzFramework::StringFunc::Path::GetFileName(imageFilePath.c_str(), fileName); - fileName += ".dds"; - AzFramework::StringFunc::Path::Join(exportDir.c_str(), fileName.c_str(), outputPath, true, true); - - //if it need streaming - bool isStreaming = BuilderSettingManager::Instance()->GetBuilderSetting(platformName)->m_enableStreaming; - - //create convert process - ImageConvertProcess* process = new ImageConvertProcess(srcImage, textureSettings, *preset, false, isStreaming, - canOverridePreset, outputPath, platformName); - - return process; - } - - void ImageConvertProcess::CreateDiffuseCubemap() - { - //only need to convert if the diffuseGenPreset in cubemap setting is set - if (m_presetSetting.m_cubemapSetting == nullptr || m_presetSetting.m_cubemapSetting->m_diffuseGenPreset.IsNull()) - { - return; - } - - //need to create another ImageConvertProcess - //prepare preset setting and texture setting - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset( - m_presetSetting.m_cubemapSetting->m_diffuseGenPreset, m_platformId); - - TextureSettings textureSettings = m_textureSetting; - m_textureSetting.m_preset = m_presetSetting.m_cubemapSetting->m_diffuseGenPreset; - - if (preset == nullptr) - { - AZ_Error("Image Processing", false,"Couldn't find preset for diffuse cubemap generation"); - return; - } - - //generate export file name. add "_diff" in the end of file name - AZStd::string fileName, folderName, outProductPath; - AzFramework::StringFunc::Path::GetFileName(m_outputPath.c_str(), fileName); - AzFramework::StringFunc::Path::GetFullPath(m_outputPath.c_str(), folderName); - fileName += "_diff.dds"; - AzFramework::StringFunc::Path::Join(folderName.c_str(), fileName.c_str(), outProductPath, true, true); - - //create convert process - //we might be able to use current image result for the input to save some performance. But it's more safe to use input image - bool canOverridePreset = false; - ImageConvertProcess* process = new ImageConvertProcess(m_inputImage, textureSettings, *preset, - false, m_isStreaming, canOverridePreset, outProductPath, m_platformId); - if (process) - { - process->ProcessAll(); - if (process->IsSucceed()) - { - process->GetAppendOutputFilePaths(m_productFilepaths); - m_diffCubemapImage = process->m_image->Get(); - } - else - { - AZ_Error("Image Processing", false, "Convert diffuse cubemap failed"); - } - delete process; - } - else - { - AZ_Error("Image Processing", false, "Create convert process for diffuse cubemap failed"); - } - } - - bool ConvertImageFile(const AZStd::string& imageFilePath, const AZStd::string& exportDir, - AZStd::vector& outPaths, const PlatformName& platformName, AZ::SerializeContext* context) - { - bool result = false; - ImageConvertProcess* process = CreateImageConvertProcess(imageFilePath, exportDir, platformName, context); - if (process) - { - process->ProcessAll(); - result = process->IsSucceed(); - if (result) - { - process->GetAppendOutputFilePaths(outPaths); - } - delete process; - } - return result; - } - - IImageObjectPtr MergeOutputImageForPreview(IImageObjectPtr image, IImageObjectPtr alphaImage) - { - if (!image) - { - return IImageObjectPtr(); - } - - ImageToProcess imageToProcess(image); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - IImageObjectPtr previewImage = imageToProcess.Get(); - - // If there is separate Alpha image, combine it with output - if (alphaImage) - { - // Create pixel operation function for rgb and alpha images - IPixelOperationPtr imageOp = CreatePixelOperation(ePixelFormat_R8G8B8A8); - IPixelOperationPtr alphaOp = CreatePixelOperation(ePixelFormat_A8); - - // Convert the alpha image to A8 first - ImageToProcess imageToProcess2(alphaImage); - imageToProcess2.ConvertFormat(ePixelFormat_A8); - IImageObjectPtr previewImageAlpha = imageToProcess2.Get(); - - const uint32 imageMips = previewImage->GetMipCount(); - const uint32 alphaMips = previewImageAlpha->GetMipCount(); - - // Get count of bytes per pixel for both rgb and alpha images - uint32 imagePixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat_R8G8B8A8)->bitsPerBlock / 8; - uint32 alphaPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat_A8)->bitsPerBlock / 8; - - AZ_Assert(imageMips <= alphaMips, "Mip level of alpha image is less than origin image!"); - - // For each mip level, set the alpha value to the image - for (uint32 mipLevel = 0; mipLevel < imageMips; ++mipLevel) - { - const uint32 pixelCount = previewImage->GetPixelCount(mipLevel); - const uint32 alphaPixelCount = previewImageAlpha->GetPixelCount(mipLevel); - - AZ_Assert(pixelCount == alphaPixelCount, "Pixel count for image and alpha image at mip level %d is not equal!", mipLevel); - - uint8* imageBuf; - uint32 pitch; - previewImage->GetImagePointer(mipLevel, imageBuf, pitch); - - uint8* alphaBuf; - uint32 alphaPitch; - previewImageAlpha->GetImagePointer(mipLevel, alphaBuf, alphaPitch); - - float rAlpha, gAlpha, bAlpha, aAlpha, rImage, gImage, bImage, aImage; - - for (uint32 i = 0; i < pixelCount; ++i, imageBuf += imagePixelBytes, alphaBuf += alphaPixelBytes) - { - alphaOp->GetRGBA(alphaBuf, rAlpha, gAlpha, bAlpha, aAlpha); - imageOp->GetRGBA(imageBuf, rImage, gImage, bImage, aImage); - imageOp->SetRGBA(imageBuf, rImage, gImage, bImage, aAlpha); - } - } - } - - return previewImage; - } - - // This function will convert compressed image to RGBA32. - // Also if the image is in sRGB space will convert it to Linear space. - IImageObjectPtr GetUncompressedLinearImage(IImageObjectPtr ddsImage) - { - if (ddsImage) - { - ImageToProcess processImage(ddsImage); - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(ddsImage->GetPixelFormat())) - { - processImage.ConvertFormat(ePixelFormat_R32G32B32A32F); - } - if (ddsImage->HasImageFlags(EIF_SRGBRead)) - { - processImage.GammaToLinearRGBA32F(true); - } - return processImage.Get(); - } - return nullptr; - } - - float GetErrorBetweenImages(IImageObjectPtr inputImage1, IImageObjectPtr inputImage2) - { - // First make sure images are in uncompressed format and linear space - // Convert them if necessary - IImageObjectPtr image1 = GetUncompressedLinearImage(inputImage1); - IImageObjectPtr image2 = GetUncompressedLinearImage(inputImage2); - - const float errorValue = FLT_MAX; - - if (!image1 || !image2) - { - AZ_Warning("Image Processing", false, "Invalid images passed into %s function", __FUNCTION__); - return errorValue; - } - - // Two images should share same size - if (image1->GetWidth(0) != image2->GetWidth(0) || image1->GetHeight(0) != image2->GetHeight(0)) - { - AZ_Warning("Image Processing", false, "%s function only can get error between two images with same size", __FUNCTION__); - return errorValue; - } - - //create pixel operation function - IPixelOperationPtr pixelOp1 = CreatePixelOperation(image1->GetPixelFormat()); - IPixelOperationPtr pixelOp2 = CreatePixelOperation(image2->GetPixelFormat()); - - //get count of bytes per pixel - AZ::u32 pixelBytes1 = CPixelFormats::GetInstance().GetPixelFormatInfo(image1->GetPixelFormat())->bitsPerBlock / 8; - AZ::u32 pixelBytes2 = CPixelFormats::GetInstance().GetPixelFormatInfo(image2->GetPixelFormat())->bitsPerBlock / 8; - - float color1[4]; - float color2[4]; - AZ::u8* mem1; - AZ::u8* mem2; - uint32 pitch1, pitch2; - - float sumDeltaSqLinear = 0; - - //only process the highest mip - image1->GetImagePointer(0, mem1, pitch1); - image2->GetImagePointer(0, mem2, pitch2); - - const uint32 pixelCount = image1->GetPixelCount(0); - - for (uint32 i = 0; i < pixelCount; ++i) - { - pixelOp1->GetRGBA(mem1, color1[0], color1[1], color1[2], color1[3]); - pixelOp2->GetRGBA(mem2, color2[0], color2[1], color2[2], color2[3]); - - sumDeltaSqLinear += (color1[0] - color2[0]) * (color1[0] - color2[0]) - + (color1[1] - color2[1]) * (color1[1] - color2[1]) - + (color1[2] - color2[2]) * (color1[2] - color2[2]); - - mem1 += pixelBytes1; - mem2 += pixelBytes2; - } - - return sumDeltaSqLinear / pixelCount; - } - - void GetBC1CompressionErrors(IImageObjectPtr originImage, float& errorLinear, float& errorSrgb, - ICompressor::CompressOption option) - { - errorLinear = 0; - errorSrgb = 0; - - if (originImage->HasImageFlags(EIF_SRGBRead)) - { - AZ_Assert(false, "The input origin image of %s function need be in linear color space", __FUNCTION__); - return; - } - - //compress and decompress in linear space - ImageToProcess processLinear(originImage); - processLinear.SetCompressOption(option); - processLinear.ConvertFormat(ePixelFormat_BC1); - processLinear.ConvertFormat(ePixelFormat_R32G32B32A32F); - - errorLinear = GetErrorBetweenImages(originImage, processLinear.Get()); - - //compress and descompress in srgb space, then convert back to linear space to compare to original image - ImageToProcess processSrgb(originImage); - processSrgb.SetCompressOption(option); - processSrgb.LinearToGamma(); - processSrgb.ConvertFormat(ePixelFormat_BC1); - processSrgb.ConvertFormat(ePixelFormat_R32G32B32A32F); - processSrgb.GammaToLinearRGBA32F(true); - - errorSrgb = GetErrorBetweenImages(originImage, processSrgb.Get()); - } - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.h b/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.h deleted file mode 100644 index 01cd422672..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -#include -#include -#include -#include -#include - -#include -#include - -namespace ImageProcessing -{ - class IImageObject; - class ImageToProcess; - - //Convert image file with its image export setting and save to specified folder. - //this function can be useful for a cancelable job - class ImageConvertProcess* CreateImageConvertProcess(const AZStd::string& imageFilePath, - const AZStd::string& exportDir, const PlatformName& platformName, AZ::SerializeContext* context = nullptr); - - //Convert image file with its image export setting and save to specified folder. it will return when the whole conversion is done. - //Could be used for command mode or test - bool ConvertImageFile(const AZStd::string& imageFilePath, const AZStd::string& exportDir, AZStd::vector& outPaths, - const PlatformName& platformName = "", AZ::SerializeContext* context = nullptr); - - //image filter function - void FilterImage(MipGenType genType, MipGenEvalType evalType, float blurH, float blurV, const IImageObjectPtr srcImg, int srcMip, - IImageObjectPtr dstImg, int dstMip, QRect* srcRect, QRect* dstRect); - - //get compression error for an image converting to certain format - void GetBC1CompressionErrors(IImageObjectPtr originImage, float& errorLinear, float& errorSrgb, - ICompressor::CompressOption option); - - float GetErrorBetweenImages(IImageObjectPtr inputImage1, IImageObjectPtr inputImage2); - - //Combine image with alpha image if any and output as RGBA8 - IImageObjectPtr MergeOutputImageForPreview(IImageObjectPtr image, IImageObjectPtr alphaImage); - - //get output image size and mip count based on the texture setting and preset setting - - //other helper functions - //Get desired output image size based on the texture settings - void GetOutputExtent(AZ::u32 inputWidth, AZ::u32 inputHeight, AZ::u32& outWidth, AZ::u32& outHeight, AZ::u32& outReduce, - const TextureSettings* textureSettings, const PresetSettings* presetSettings); - - class ImageConvertProcess - { - public: - //constructor - ImageConvertProcess(const IImageObjectPtr inputImage, const TextureSettings& textureSetting, - const PresetSettings& presetSetting, bool isPreview, bool isStreaming, bool canOverridePreset, - const AZStd::string& outputPath, const AZStd::string& platformId); - ~ImageConvertProcess(); - - //doing image conversion, this function need to be called repeatly until the process is done - //it could used for a working thread which may need to cancel a process - void UpdateProcess(); - - //doing all conversion in one step. This function will call UpdateProcess in a while loop until it's done. - void ProcessAll(); - - //for multi-thread - //get percentage of image convertion progress - float GetProgress(); - bool IsFinished(); - bool IsSucceed(); - - //get output images - IImageObjectPtr GetOutputImage(); - IImageObjectPtr GetOutputAlphaImage(); - IImageObjectPtr GetOutputDiffCubemap(); - - //get output file paths and append the paths to the outPaths vector. - void GetAppendOutputFilePaths(AZStd::vector& outPaths); - - private: - enum ConvertStep - { - StepValidateInput = 0, - StepGenerateColorChart, - StepConvertToLinear, - StepSwizzle, - StepOverridePreset, - StepCubemapLayout, - StepPreNormalize, - StepDiffCubemap, - StepMipmap, - StepGlossFromNormal, - StepPostNormalize, - StepCreateHighPass, - StepConvertOutputColorSpace, - StepAlphaImage, - StepConvertPixelFormat, - StepSaveToFile, - StepAll - }; - - //input image and settings - const IImageObjectPtr m_inputImage; - TextureSettings m_textureSetting; - PresetSettings m_presetSetting; - bool m_canOverridePreset; - bool m_isPreview; - AZStd::string m_outputPath; - AZStd::string m_platformId; - - //some global settings from builder setting - bool m_isStreaming; - - //for alpha - //to indicate the current alpha chanenl content - EAlphaContent m_alphaContent; - //An image object to hold alpha channel in a seperate image - IImageObjectPtr m_alphaImage; - - //for cubemap - //An image object to save output result of diffuse cubemap conversion - IImageObjectPtr m_diffCubemapImage; - - //image for processing - ImageToProcess *m_image; - - //progress - uint32 m_progressStep; - bool m_isFinished; - bool m_isSucceed; - - //all the output products' paths - AZStd::vector m_productFilepaths; - - //for get processing time - AZStd::sys_time_t m_startTime; - double m_processTime; //in seconds - - private: - //validate the input image and settings - bool ValidateInput(); - - //mipmap generation - bool FillMipmaps(); - - //mipmap generation for cubemap - bool FillCubemapMipmaps(); - - //special case: create diffuse cubemap - void CreateDiffuseCubemap(); - - //convert color space to linear with pixel format rgba32f - bool ConvertToLinear(); - - //convert to output color space before compression - bool ConvertToOuputColorSpace(); - - //create alpha image if it's needed - void CreateAlphaImage(); - - //pixel format convertion/compression - bool ConvertPixelformat(); - - //save output image to a file - bool SaveOutput(); - - //if it's converting for cubemap - bool IsConvertToCubemap(); - }; - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.cpp deleted file mode 100644 index cab3918a05..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - IImageObjectPtr ImageConvertOutput::GetOutputImage(OutputImageType type) const - { - if (type < OutputImageType::Count) - { - return m_outputImage[static_cast(type)]; - } - else - { - return IImageObjectPtr(); - } - } - - void ImageConvertOutput::SetOutputImage(IImageObjectPtr image, OutputImageType type) - { - if (type < OutputImageType::Count) - { - m_outputImage[static_cast(type)] = image; - } - else - { - AZ_Error("ImageProcess", false, "Cannot set output image to %d", type); - } - } - - void ImageConvertOutput::SetReady(bool ready) - { - m_outputReady = ready; - } - - bool ImageConvertOutput::IsReady() const - { - return m_outputReady; - } - - float ImageConvertOutput::GetProgress() const - { - return m_progress; - } - - void ImageConvertOutput::SetProgress(float progress) - { - m_progress = progress; - } - - void ImageConvertOutput::Reset() - { - for (int i = 0; i < static_cast(OutputImageType::Count); i ++ ) - { - m_outputImage[i] = nullptr; - } - m_outputReady = false; - m_progress = 0.0f; - } - - ImageConvertJob::ImageConvertJob(IImageObjectPtr image, const TextureSettings* textureSetting, - const PresetSettings* preset, bool isPreview, const AZStd::string& platformId, - ImageConvertOutput* output, bool autoDelete /*= true*/, AZ::JobContext* jobContext /*= nullptr*/) - : AZ::Job(autoDelete, jobContext) - , m_isPreview(isPreview) - , m_isCancelled(false) - , m_output(output) - { - AZ_Assert(m_output, "Needs to have an output destination for image conversion!"); - if (image && textureSetting && preset) - { - bool isStreaming = BuilderSettingManager::Instance()->GetBuilderSetting(platformId)->m_enableStreaming; - bool canOverridePreset = false; - m_process = AZStd::make_unique(image, *textureSetting, *preset, isPreview, isStreaming, canOverridePreset, "", platformId); - } - } - - void ImageConvertJob::Process() - { - if (!m_process) - { - AZ_Error("Image Processing", false, "Cannot start processing, invalid setting or image!"); - m_output->SetReady(true); - m_output->SetProgress(1.0f); - return; - } - m_output->SetReady(false); - while (!m_process->IsFinished() && !IsJobCancelled()) - { - m_process->UpdateProcess(); - if (m_isPreview) - { - m_output->SetProgress(m_process->GetProgress() / static_cast(m_previewProcessStep)); - } - else - { - m_output->SetProgress(m_process->GetProgress()); - } - } - - IImageObjectPtr outputImage = m_process->GetOutputImage(); - IImageObjectPtr outputImageAlpha = m_process->GetOutputAlphaImage(); - - m_output->SetOutputImage(outputImage, ImageConvertOutput::Base); - m_output->SetOutputImage(outputImageAlpha, ImageConvertOutput::Alpha); - - if (m_isPreview && !IsJobCancelled()) - { - // For preview, combine image output with alpha if any - m_output->SetProgress(1.0f / static_cast(m_previewProcessStep)); - IImageObjectPtr combinedImage = MergeOutputImageForPreview(outputImage, outputImageAlpha); - m_output->SetOutputImage(combinedImage, ImageConvertOutput::Preview); - } - - m_output->SetReady(true); - m_output->SetProgress(1.0f); - } - - void ImageConvertJob::Cancel() - { - m_isCancelled = true; - } - - bool ImageConvertJob::IsJobCancelled() - { - return m_isCancelled || IsCancelled(); - } - - - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.h b/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.h deleted file mode 100644 index fb3f26af50..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - class ImageConvertProcess; - - class ImageConvertOutput - { - public: - enum OutputImageType - { - Base = 0, // Might contains alpha or not - Alpha, // Separate alpha image - Preview, // Combine base image with alpha if any, format RGBA8 - Count - }; - - IImageObjectPtr GetOutputImage(OutputImageType type) const; - void SetOutputImage(IImageObjectPtr image, OutputImageType type); - void SetReady(bool ready); - bool IsReady() const; - float GetProgress() const; - void SetProgress(float progress); - void Reset(); - - private: - IImageObjectPtr m_outputImage[OutputImageType::Count]; - bool m_outputReady = false; - float m_progress = 0.0f; - }; - - class ImageConvertJob - : public AZ::Job - { - public: - AZ_CLASS_ALLOCATOR(ImageConvertJob, AZ::ThreadPoolAllocator, 0) - - ImageConvertJob(IImageObjectPtr image, const TextureSettings* textureSetting, const PresetSettings* preset - , bool isPreview, const AZStd::string& platformId, ImageConvertOutput* output, bool autoDelete = true - , AZ::JobContext* jobContext = nullptr); - - void Process() override; - // Cancel the job itself - void Cancel(); - // Whether the job is being cancelled or the whole job group is being cancelled - bool IsJobCancelled(); - - private: - static const int m_previewProcessStep = 2; - - AZStd::unique_ptr m_process; - bool m_isPreview; - AZStd::atomic_bool m_isCancelled; - ImageConvertOutput* m_output; - }; -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageFlags.h b/Gems/ImageProcessing/Code/Source/Processing/ImageFlags.h deleted file mode 100644 index 2f09fbb588..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageFlags.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -//! The following constants are extracted from ImageExtensionHelper.h -//! Please make sure they are always synced with the same constants defined in ImageExtensionHelper.h - -namespace ImageProcessing -{ - // flags to propagate from the RC to the engine through GetImageFlags() - // 32bit bitmask, numbers should not change as engine relies on them - const static AZ::u32 EIF_Cubemap = 0x1; - const static AZ::u32 EIF_Volumetexture = 0x2; - const static AZ::u32 EIF_Decal = 0x4; // this is usually set through the preset - const static AZ::u32 EIF_Greyscale = 0x8; // hint for the engine (e.g. greyscale light beams can be applied to shadow mask), can be for DXT1 because compression artfacts don't count as color - const static AZ::u32 EIF_SupressEngineReduce = 0x10; // info for the engine: don't reduce texture resolution on this texture - const static AZ::u32 EIF_UNUSED_BIT = 0x40; // Free to use - const static AZ::u32 EIF_AttachedAlpha = 0x400; // info for the engine: it's a texture with attached alpha channel - const static AZ::u32 EIF_SRGBRead = 0x800; // info for the engine: if gamma corrected rendering is on, this texture requires SRGBRead (it's not stored in linear) - const static AZ::u32 EIF_DontResize = 0x8000; // info for the engine: for dds textures that shouldn't be resized with r_TexResolution - const static AZ::u32 EIF_RenormalizedTexture = 0x10000; // info for the engine: for dds textures that have renormalized color range - const static AZ::u32 EIF_CafeNative = 0x20000; // info for the engine: native Cafe texture format - const static AZ::u32 EIF_RestrictedPlatformONative = 0x40000; // native tiled texture for restrict platform O - const static AZ::u32 EIF_Tiled = 0x80000; // info for the engine: texture has been tiled for the platform - const static AZ::u32 EIF_RestrictedPlatformDNative = 0x100000; // native tiled texture for restrict platform D - const static AZ::u32 EIF_Splitted = 0x200000; // info for the engine: this texture is splitted - const static AZ::u32 EIF_Colormodel = 0x7000000; // info for the engine: bitmask: colormodel used in the texture - const static AZ::u32 EIF_Colormodel_RGB = 0x0000000; // info for the engine: colormodel is RGB (default) - const static AZ::u32 EIF_Colormodel_CIE = 0x1000000; // info for the engine: colormodel is CIE (used for terrain) - const static AZ::u32 EIF_Colormodel_YCC = 0x2000000; // info for the engine: colormodel is Y'CbCr (used for reflectance) - const static AZ::u32 EIF_Colormodel_YFF = 0x3000000; // info for the engine: colormodel is Y'FbFr (used for reflectance) - const static AZ::u32 EIF_Colormodel_IRB = 0x4000000; // info for the engine: colormodel is IRB (used for reflectance) -} diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.cpp deleted file mode 100644 index 7a6b1e3002..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.cpp +++ /dev/null @@ -1,1417 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -// Indicates a 2D texture is a cube-map texture. -#define DDS_RESOURCE_MISC_TEXTURECUBE 0x4 - -namespace ImageProcessing -{ - - IImageObject* IImageObject::CreateImage(AZ::u32 width, AZ::u32 height, - AZ::u32 maxMipCount, EPixelFormat pixelFormat) - { - return aznew CImageObject(width, height, maxMipCount, pixelFormat); - } - - CImageObject::CImageObject(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat) - : m_pixelFormat(pixelFormat) - , m_colMinARGB(0.0f, 0.0f, 0.0f, 0.0f) - , m_colMaxARGB(1.0f, 1.0f, 1.0f, 1.0f) - , m_averageBrightness(0.63f) - , m_imageFlags(0) - , m_numPersistentMips(0) - { - ResetImage(width, height, maxMipCount, pixelFormat); - } - - EPixelFormat CImageObject::GetPixelFormat() const - { - return m_pixelFormat; - } - - AZ::u32 CImageObject::GetPixelCount(AZ::u32 mip) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "Mip doesn't exist: %d", mip); - - return m_mips[mip]->m_width * m_mips[mip]->m_height; - } - - AZ::u32 CImageObject::GetWidth(AZ::u32 mip) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "Mip doesn't exist: %d", mip); - - return m_mips[mip]->m_width; - } - - AZ::u32 CImageObject::GetHeight(AZ::u32 mip) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "Mip doesn't exist: %d", mip); - - return m_mips[mip]->m_height; - } - - AZ::u32 CImageObject::GetMipCount() const - { - return (AZ::u32)m_mips.size(); - } - - void CImageObject::ResetImage(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat) - { - //check input - AZ_Assert(width > 0 && height > 0, "image width and height need to larger than 0. width: %d, height: %d", width, height); - AZ_Assert(maxMipCount > 0, "image mipmap count need to larger than 0. maxMipCount: %d", maxMipCount); - - //clean up mipmaps - for (AZ::u32 mip = 0; mip < AZ::u32(m_mips.size()); ++mip) - { - delete m_mips[mip]; - } - - m_pixelFormat = pixelFormat; - m_colMinARGB = AZ::Color(0.0f, 0.0f, 0.0f, 0.0f); - m_colMaxARGB = AZ::Color(1.0f, 1.0f, 1.0f, 1.0f); - m_averageBrightness = 0.0f; - m_imageFlags = 0; - m_numPersistentMips = 0; - m_mips.clear(); - - const PixelFormatInfo* const pFmt = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat); - AZ_Assert(pFmt, "can't find pixe format info for %d", m_pixelFormat); - - const AZ::u32 mipCount = AZStd::min(maxMipCount, - CPixelFormats::GetInstance().ComputeMaxMipCount(m_pixelFormat, width, height)); - - m_mips.reserve(mipCount); - - for (AZ::u32 mip = 0; mip < mipCount; ++mip) - { - MipLevel* const pEntry = aznew MipLevel; - - AZ::u32 localWidth = width >> mip; - AZ::u32 localHeight = height >> mip; - if (localWidth < 1) - { - localWidth = 1; - } - if (localHeight < 1) - { - localHeight = 1; - } - - pEntry->m_width = localWidth; - pEntry->m_height = localHeight; - - if (pFmt->bCompressed) - { - const AZ::u32 blocksInRow = (pEntry->m_width + (pFmt->blockWidth - 1)) / pFmt->blockWidth; - pEntry->m_pitch = (blocksInRow * pFmt->bitsPerBlock) / 8; - pEntry->m_rowCount = (localHeight + (pFmt->blockHeight - 1)) / pFmt->blockHeight; - } - else - { - pEntry->m_pitch = (pEntry->m_width * pFmt->bitsPerBlock) / 8; - pEntry->m_rowCount = localHeight; - } - - pEntry->Alloc(); - - m_mips.push_back(pEntry); - } - } - - bool CImageObject::CompareImage(const IImageObjectPtr otherImage) const - { - CImageObject* other = static_cast(otherImage.get()); - if (other == nullptr) - { - return false; - } - - if (m_pixelFormat == other->m_pixelFormat - && m_colMinARGB == other->m_colMinARGB - && m_colMaxARGB == other->m_colMaxARGB - && m_averageBrightness == other->m_averageBrightness - && m_imageFlags == other->m_imageFlags - && m_numPersistentMips == other->m_numPersistentMips - && m_mips.size() == other->m_mips.size()) - { - for (int mip = 0; mip < m_mips.size(); mip++) - { - if (!(*m_mips[mip] == *other->m_mips[mip])) - { - return false; - } - } - return true; - } - return false; - } - - uint CImageObject::GetTextureMemory() const - { - int totalSize = 0; - for (int mip = 0; mip < m_mips.size(); mip++) - { - totalSize += CPixelFormats::GetInstance().EvaluateImageDataSize(m_pixelFormat, - m_mips[mip]->m_width, m_mips[mip]->m_height); - } - - return totalSize; - } - - EAlphaContent CImageObject::GetAlphaContent() const - { - if (CPixelFormats::GetInstance().IsPixelFormatWithoutAlpha(m_pixelFormat)) - { - return EAlphaContent::eAlphaContent_Absent; - } - - //if it's compressed format, return indeterminate. if user really want to know the content, they may convert the format to ARGB8 first - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat)) - { - AZ_Assert(false, "the function only works right with uncompressed formats. convert to uncompressed format if you get accurate result"); - return EAlphaContent::eAlphaContent_Indeterminate; - } - - //go though alpha channel of first mip - //create pixel operation function to access pixel data - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel for images - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - // counts of blacks and white - uint nBlacks = 0; - uint nWhites = 0; - - float r, g, b, a; - AZ::u8* pixelBuf; - AZ::u32 pitch; - GetImagePointer(0, pixelBuf, pitch); - - const AZ::u32 pixelCount = GetPixelCount(0); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, r, g, b, a); - if (a == 0.0f) - { - ++nBlacks; - } - else if (a == 1.0f) - { - ++nWhites; - } - else - { - return EAlphaContent::eAlphaContent_Greyscale; - } - } - - if (nBlacks == 0) - { - return EAlphaContent::eAlphaContent_OnlyWhite; - } - - if (nWhites == 0) - { - return EAlphaContent::eAlphaContent_OnlyBlack; - } - - return EAlphaContent::eAlphaContent_OnlyBlackAndWhite; - } - - // clone this image-object's contents - IImageObject* CImageObject::Clone() const - { - const EPixelFormat srcPixelformat = GetPixelFormat(); - - IImageObject* pRet = AllocateImage(); - - AZ::u32 dwMips = pRet->GetMipCount(); - for (AZ::u32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - //AZ::u32 dwLocalWidth = GetWidth(dwMip); // we get error on NVidia with this (assumes input is 4x4 as well) - AZ::u32 dwLocalHeight = GetHeight(dwMip); - - AZ::u32 dwLines = dwLocalHeight; - - if (CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcPixelformat)) - { - dwLines = m_mips[dwMip]->m_rowCount; - } - - AZ::u8* pMem; - AZ::u32 dwPitch; - GetImagePointer(dwMip, pMem, dwPitch); - - AZ::u8* pDstMem; - AZ::u32 dwDstPitch; - pRet->GetImagePointer(dwMip, pDstMem, dwDstPitch); - - for (AZ::u32 dwY = 0; dwY < dwLines; ++dwY) - { - memcpy(&pDstMem[dwDstPitch * dwY], &pMem[dwPitch * dwY], AZStd::min(dwPitch, dwDstPitch)); - } - } - return pRet; - } - - void CImageObject::ClearColor(float r, float g, float b, float a) - { - //if it's compressed format, return directly - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat)) - { - AZ_Assert(false, "The %s function only works with uncompressed formats", __FUNCTION__); - return; - } - //create pixel operation function to access pixel data - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel for images - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - AZ::u8* pixelBuf; - AZ::u32 pitch; - - AZ::u32 mips = GetMipCount(); - for (AZ::u32 mip = 0; mip < mips; ++mip) - { - GetImagePointer(mip, pixelBuf, pitch); - const AZ::u32 pixelCount = GetPixelCount(mip); - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->SetRGBA(pixelBuf, r, g, b, a); - } - } - } - - // allocate an empty image with the same properties as the given image and the requested format - IImageObject* CImageObject::AllocateImage(EPixelFormat pixelFormat) const - { - AZ::u32 width = GetWidth(0); - AZ::u32 height = GetHeight(0); - - if (!CPixelFormats::GetInstance().IsImageSizeValid(pixelFormat, width, height, false)) - { - AZ_Assert(false, "Cann't allocate image with format: %d", pixelFormat); - return nullptr; - } - - CImageObject* pRet = aznew CImageObject(width, height, GetMipCount(), pixelFormat); - pRet->CopyPropertiesFrom(this); - return pRet; - } - - IImageObject* CImageObject::AllocateImage() const - { - return AllocateImage(m_pixelFormat); - } - - CImageObject::~CImageObject() - { - for (size_t i = 0; i < m_mips.size(); ++i) - { - delete m_mips[i]; - } - m_mips.clear(); - } - - //note: there are some unreasonable parts of the save files formats for cry textures. We might need to rethink about - // it for new renderer - bool CImageObject::SaveImage(const char* filename, IImageObjectPtr alphaImage, AZStd::vector& outFilePaths) const - { - AZ::IO::SystemFile file; - file.Open(filename, AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY); - - AZ::IO::SystemFileStream fileSaveStream(&file, true); - if (!fileSaveStream.IsOpen()) - { - - AZ_Warning("Image Processing", false, "%s: failed to create file %s", __FUNCTION__, filename); - return false; - } - - if (alphaImage) - { - AZ_Assert(HasImageFlags(EIF_AttachedAlpha), "attached alpha image flag wasn't set"); - AZ_Assert(!alphaImage->HasImageFlags(EIF_AttachedAlpha), "alpha image shouldn't have attached alpha image flag"); - - // inherit cubemap and decal image flags to attached alpha image - alphaImage->AddImageFlags(GetImageFlags() & (EIF_Cubemap - | EIF_Decal | EIF_Splitted)); - alphaImage->SetNumPersistentMips(m_numPersistentMips); - } - - bool bOk = SaveImage(fileSaveStream); - bool hasSplitFlag = HasImageFlags(EIF_Splitted); - - //append alpha image data in the end if there is no split - if (bOk && alphaImage && !hasSplitFlag) - { - //4 bytes extension tag, 4 bytes attached alpha tag, then 4 bytes of chunk size - fileSaveStream.Write(sizeof(FOURCC_CExt), &FOURCC_CExt); // marker for the start of Crytek Extended data - fileSaveStream.Write(sizeof(FOURCC_AttC), &FOURCC_AttC); // Attached Channel chunk - - AZ::u32 size = 0; - AZ::u32 sizeBytes = sizeof(size); - fileSaveStream.Write(sizeBytes, &size); //size of attached chunk - - //save alpha image and get the size - AZ::IO::SizeType startPos = fileSaveStream.GetCurPos(); - bOk = alphaImage->SaveImage(fileSaveStream); - AZ::IO::SizeType endPos = fileSaveStream.GetCurPos(); - size = aznumeric_cast(endPos - startPos); - - //move back to beginning of chunk and write chunk size then move back to end - fileSaveStream.Seek(startPos - sizeBytes, AZ::IO::GenericStream::ST_SEEK_BEGIN); - fileSaveStream.Write(sizeBytes, &size); - fileSaveStream.Seek(endPos, AZ::IO::GenericStream::ST_SEEK_BEGIN); - - // marker for the end of Crytek Extended data - fileSaveStream.Write(sizeof(FOURCC_CEnd), &FOURCC_CEnd); - } - - if (!bOk) - { - AZ::IO::SystemFile::Delete(filename); - return false; - } - - // It's important to maintain the product output sequence. Asset Database/Browser will use the first product to determine the source type! - outFilePaths.push_back(filename); - - // save stand alone products - if (hasSplitFlag) - { - // alpha - if (alphaImage) - { - AZStd::string alphaFile = AZStd::string::format("%s.a", filename); - - AZ::IO::SystemFile outAlphaFile; - outAlphaFile.Open(alphaFile.c_str(), AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY); - - AZ::IO::SystemFileStream alphaFileSaveStream(&outAlphaFile, true); - - if (alphaFileSaveStream.IsOpen()) - { - alphaImage->SaveImage(alphaFileSaveStream); - outFilePaths.push_back(alphaFile); - } - else - { - AZ_Warning("Image Processing", false, "%s: failed to create file %s", __FUNCTION__, alphaFile.c_str()); - } - } - - // mips - AZ::u32 numStreamable = GetMipCount() - m_numPersistentMips; - for (AZ::u32 mip = 0; mip < numStreamable; mip++) - { - AZ::u32 nameIdx = numStreamable - mip; - AZStd::string mipFileName = AZStd::string::format("%s.%d", filename, nameIdx); - SaveMipToFile(mip, mipFileName); - outFilePaths.push_back(mipFileName); - if (alphaImage) - { - AZStd::string mipAlphaFileName = mipFileName + "a"; - alphaImage->SaveMipToFile(mip, mipAlphaFileName); - outFilePaths.push_back(mipAlphaFileName); - } - } - } - - return bOk; - } - - bool CImageObject::SaveMipToFile(AZ::u32 mip, const AZStd::string& filename) const - { - AZ::IO::SystemFile saveFile; - saveFile.Open(filename.c_str(), AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY); - - AZ::IO::SystemFileStream saveFileStream(&saveFile, true); - - if (!saveFileStream.IsOpen()) - { - AZ_Warning("Image Processing", false, "%s: failed to create file %s", __FUNCTION__, filename.c_str()); - return false; - } - - saveFileStream.Write(GetMipBufSize(mip), m_mips[mip]->m_pData); - return true; - } - - IImageObject* CreateImageFromHeader(DDS_HEADER& header, DDS_HEADER_DXT10& exthead) - { - EPixelFormat eFormat = ePixelFormat_Unknown; - AZ::u32 dwWidth, dwMips, dwHeight; - AZ::u32 imageFlags = header.dwReserved1; - AZ::Color colMinARGB, colMaxARGB; - - dwWidth = header.dwWidth; - dwHeight = header.dwHeight; - dwMips = 1; - if (header.dwHeaderFlags & DDS_HEADER_FLAGS_MIPMAP) - { - dwMips = header.dwMipMapCount; - } - if ((header.dwSurfaceFlags & DDS_SURFACE_FLAGS_CUBEMAP) && (header.dwCubemapFlags & DDS_CUBEMAP_ALLFACES)) - { - AZ_Assert(header.dwReserved1&EIF_Cubemap, "Image flag should have cubemap flag"); - dwHeight *= 6; - } - - colMinARGB = AZ::Color(header.cMinColor[0], header.cMinColor[1], header.cMinColor[2], header.cMinColor[3]); - colMaxARGB = AZ::Color(header.cMaxColor[0], header.cMaxColor[1], header.cMaxColor[2], header.cMaxColor[3]); - - //get pixel format - { - // DX10 formats - if (header.ddspf.dwFourCC == FOURCC_DX10) - { - AZ::u32 dxgiFormat = exthead.dxgiFormat; - - //remove the SRGB from dxgi format and add sRGB to image flag - if (dxgiFormat == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; - } - else if (dxgiFormat == DXGI_FORMAT_BC1_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_BC1_UNORM; - } - else if (dxgiFormat == DXGI_FORMAT_BC2_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_BC2_UNORM; - } - else if (dxgiFormat == DXGI_FORMAT_BC3_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_BC3_UNORM; - } - else if (dxgiFormat == DXGI_FORMAT_BC7_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_BC7_UNORM; - } - - //add rgb flag if the dxgiformat was changed (which means it was sRGB format) above - if (dxgiFormat != exthead.dxgiFormat) - { - AZ_Assert(imageFlags&EIF_SRGBRead, "Image flags should have SRGBRead flag"); - imageFlags |= EIF_SRGBRead; - } - - //check all the pixel formats and find matching one - if (dxgiFormat != DXGI_FORMAT_UNKNOWN) - { - int i = 0; - for (i; id3d10Format == dxgiFormat) - { - eFormat = (EPixelFormat)i; - break; - } - } - if (i == ePixelFormat_Count) - { - AZ_Error("Image Processing", false, "Unhandled d3d10 format: %d", dxgiFormat); - return nullptr; - } - } - } - else - { - //for non-dx10 formats, use fourCC to find out its pixel formats - //go through all pixel formats and find a match with the fourcc - for (AZ::u32 formatIdx = 0; formatIdx < ePixelFormat_Count; formatIdx++) - { - const PixelFormatInfo *info = CPixelFormats::GetInstance().GetPixelFormatInfo((EPixelFormat)formatIdx); - if (header.ddspf.dwFourCC == info->fourCC) - { - eFormat = (EPixelFormat)formatIdx; - break; - } - } - - //legacy formats. This section is only used for load dds files converted by RC.exe - //our save to dds file function won't use any of these fourcc - if (eFormat == ePixelFormat_Unknown) - { - if (header.ddspf.dwFourCC == FOURCC_DXT1) - { - eFormat = ePixelFormat_BC1; - } - else if (header.ddspf.dwFourCC == FOURCC_DXT5) - { - eFormat = ePixelFormat_BC3; - } - else if (header.ddspf.dwFourCC == FOURCC_3DCP) - { - eFormat = ePixelFormat_BC4; - } - else if (header.ddspf.dwFourCC == FOURCC_3DC) - { - eFormat = ePixelFormat_BC5; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_R32F) - { - eFormat = ePixelFormat_R32F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_G32R32F) - { - eFormat = ePixelFormat_R32G32F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_A32B32G32R32F) - { - eFormat = ePixelFormat_R32G32B32A32F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_R16F) - { - eFormat = ePixelFormat_R16F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_G16R16F) - { - eFormat = ePixelFormat_R16G16F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_A16B16G16R16F) - { - eFormat = ePixelFormat_R16G16B16A16F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_A16B16G16R16) - { - eFormat = ePixelFormat_R16G16B16A16; - } - else if ((header.ddspf.dwFlags == DDS_RGBA || header.ddspf.dwFlags == DDS_RGB) - && header.ddspf.dwRGBBitCount == 32) - { - if (header.ddspf.dwRBitMask == 0x00ff0000) - { - eFormat = ePixelFormat_B8G8R8A8; - } - else - { - eFormat = ePixelFormat_R8G8B8A8; - } - } - else if (header.ddspf.dwFlags == DDS_LUMINANCEA && header.ddspf.dwRGBBitCount == 8) - { - eFormat = ePixelFormat_R8G8; - } - else if (header.ddspf.dwFlags == DDS_LUMINANCE && header.ddspf.dwRGBBitCount == 8) - { - eFormat = ePixelFormat_A8; - } - else if ((header.ddspf.dwFlags == DDS_A || header.ddspf.dwFlags == DDS_A_ONLY || header.ddspf.dwFlags == (DDS_A | DDS_A_ONLY)) && header.ddspf.dwRGBBitCount == 8) - { - eFormat = ePixelFormat_A8; - } - } - } - } - - if (eFormat == ePixelFormat_Unknown) - { - AZ_Error("Image Processing", false, "Unhandled dds pixel format fourCC: %d, flags: %d", - header.ddspf.dwFourCC, header.ddspf.dwFlags); - return nullptr; - } - - IImageObject* newImage = IImageObject::CreateImage(dwWidth, dwHeight, dwMips, eFormat); - - if (dwMips != newImage->GetMipCount()) - { - AZ_Error("Image Processing", false, "Mipcount from image data doesn't match image size and pixelformat"); - delete newImage; - return nullptr; - } - - //set properties - newImage->SetImageFlags(imageFlags); - newImage->SetAverageBrightness(header.fAvgBrightness); - newImage->SetColorRange(colMinARGB, colMaxARGB); - newImage->SetNumPersistentMips(header.bNumPersistentMips); - - return newImage; - } - - float CImageObject::CalculateAverageBrightness() const - { - //if it's compressed format, return a default value - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat)) - { - return 0.5f; - } - - // Accumulate pixel colors of the top mip - double avgOverall[3] = { 0.0, 0.0, 0.0 }; - - //create pixel operation function to access pixel data - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel for images - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - //only calculate mip 0 - AZ::u32 mip = 0; - float color[4]; - AZ::u8* pixelBuf; - AZ::u32 pitch; - GetImagePointer(mip, pixelBuf, pitch); - const AZ::u32 pixelCount = GetPixelCount(mip); - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - avgOverall[0] += color[0]; - avgOverall[1] += color[1]; - avgOverall[2] += color[2]; - } - - const double avg = (avgOverall[0] + avgOverall[1] + avgOverall[2]) / (3 * pixelCount); - - return (float)avg; - } - - bool CImageObject::BuildSurfaceHeader(DDS_HEADER& header) const - { - AZ::u32 dwWidth, dwMips, dwHeight; - GetExtent(dwWidth, dwHeight, dwMips); - - if (dwMips <= 0) - { - AZ_Error("Image Processing", false, "%s: dwMips is %u", __FUNCTION__, (unsigned)dwMips); - return false; - } - - const EPixelFormat format = GetPixelFormat(); - if ((format < 0) || (format >= ePixelFormat_Count)) - { - AZ_Error("Image Processing", false, "%s: Bad format %d", __FUNCTION__, (int)format); - return false; - } - - const PixelFormatInfo* const pPixelFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(format); - - memset(&header, 0, sizeof(DDS_HEADER)); - - header.dwSize = sizeof(DDS_HEADER); - header.dwHeaderFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT; - header.dwWidth = dwWidth; - header.dwHeight = dwHeight; - - if (HasImageFlags(EIF_Cubemap)) - { - header.dwSurfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP; - header.dwCubemapFlags |= DDS_CUBEMAP_ALLFACES; - //save face size instead of image size. - header.dwHeight /= 6; - } - - header.ddspf.dwSize = sizeof(DDS_PIXELFORMAT); - header.ddspf.dwFlags = DDS_FOURCC; - - header.ddspf.dwFourCC = pPixelFormatInfo->fourCC; - - header.dwSurfaceFlags |= DDS_SURFACE_FLAGS_TEXTURE; - - if (dwMips > 1) - { - header.dwHeaderFlags |= DDS_HEADER_FLAGS_MIPMAP; - header.dwMipMapCount = dwMips; - header.dwSurfaceFlags |= DDS_SURFACE_FLAGS_MIPMAP; - } - - // non standardized way to expose some features in the header (same information is in attached chunk but then - // streaming would need to find this spot in the file) - // if this is causing problems we need to change it - header.dwTextureStage = FOURCC_FYRC; - header.dwReserved1 = GetImageFlags(); - header.bNumPersistentMips = (AZ::u8)GetNumPersistentMips(); - - //tile mode for some platform native texture - if (HasImageFlags(EIF_RestrictedPlatformDNative)) - { - header.tileMode = eTM_LinearPadded; - } - else if (HasImageFlags(EIF_RestrictedPlatformONative)) - { - header.tileMode = eTM_Optimal; - } - - // setting up min and max colors - for (int i = 0; i < 4; i ++) - { - header.cMinColor[i] = m_colMinARGB.GetElement(i); - header.cMaxColor[i] = m_colMaxARGB.GetElement(i); - } - - // set avg brightness - header.fAvgBrightness = GetAverageBrightness(); - - return true; - } - - bool CImageObject::BuildSurfaceExtendedHeader(DDS_HEADER_DXT10& exthead) const - { - const EPixelFormat format = GetPixelFormat(); - - const PixelFormatInfo* const pPixelFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(format); - - DXGI_FORMAT dxgiformat = pPixelFormatInfo->d3d10Format; - - // check if we hit a format which can't be stored into a DX10 DDS-file (fe. L8) - if (dxgiformat == DXGI_FORMAT_UNKNOWN) - { - AZ_Error("Image Processing", false, "%s: Format can not be stored in a DDS-file %d", __FUNCTION__, dxgiformat); - return false; - } - - //the dxgi format are different for linear space or gamma space - if (HasImageFlags(EIF_SRGBRead)) - { - switch (dxgiformat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - dxgiformat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - break; - case DXGI_FORMAT_BC1_UNORM: - dxgiformat = DXGI_FORMAT_BC1_UNORM_SRGB; - break; - case DXGI_FORMAT_BC2_UNORM: - dxgiformat = DXGI_FORMAT_BC2_UNORM_SRGB; - break; - case DXGI_FORMAT_BC3_UNORM: - dxgiformat = DXGI_FORMAT_BC3_UNORM_SRGB; - break; - case DXGI_FORMAT_BC7_UNORM: - dxgiformat = DXGI_FORMAT_BC7_UNORM_SRGB; - break; - default: - break; - } - } - else - { - switch (dxgiformat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case DXGI_FORMAT_BC1_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_BC1_UNORM; - break; - case DXGI_FORMAT_BC2_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_BC2_UNORM; - break; - case DXGI_FORMAT_BC3_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_BC3_UNORM; - break; - case DXGI_FORMAT_BC7_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_BC7_UNORM; - break; - default: - break; - } - } - - memset(&exthead, 0, sizeof(exthead)); - - exthead.dxgiFormat = dxgiformat; - exthead.resourceDimension = 3; //texture2d. not used - - if (HasImageFlags(EIF_Volumetexture)) - { - AZ_Assert(false, "There isn't any support for volume texture"); - } - else if (HasImageFlags(EIF_Cubemap)) - { - exthead.miscFlag = DDS_RESOURCE_MISC_TEXTURECUBE; - exthead.arraySize = 6; - } - else - { - exthead.miscFlag = 0; - exthead.arraySize = 1; - } - - return true; - } - - bool CImageObject::SaveImage(AZ::IO::SystemFileStream &saveFileStream) const - { - DDS_FILE_DESC desc; - DDS_HEADER_DXT10 exthead; - - desc.dwMagic = FOURCC_DDS; - - if (!BuildSurfaceHeader(desc.header)) - { - return false; - } - - if (desc.header.IsDX10Ext() && !BuildSurfaceExtendedHeader(exthead)) - { - return false; - } - - saveFileStream.Write(sizeof(desc), &desc); - - if (desc.header.IsDX10Ext()) - { - saveFileStream.Write(sizeof(exthead), &exthead); - } - - AZ::u32 faces = 1; - - //for cubemap. export each face and its mipmap - if (HasImageFlags(EIF_Cubemap)) - { - faces = 6; - } - - AZ::u32 mipStart = 0; - if (HasImageFlags(EIF_Splitted)) - { - if (m_numPersistentMips < m_mips.size()) - { - mipStart = (AZ::u32)m_mips.size() - m_numPersistentMips; - } - else - { - AZ_Assert(false, "numPersistentMips wasn't setup correctly"); - } - } - - for (AZ::u32 face = 0; face < faces; face++) - { - for (AZ::u32 mip = mipStart; mip < m_mips.size(); ++mip) - { - const MipLevel& level = *m_mips[mip]; - AZ::u32 faceBufSize = level.m_pitch*level.m_rowCount / faces; - saveFileStream.Write(faceBufSize, level.m_pData + faceBufSize*face); - } - } - return true; - } - - void CImageObject::GetExtent(AZ::u32& width, AZ::u32& height, AZ::u32& mipCount) const - { - mipCount = (AZ::u32)m_mips.size(); - - width = m_mips[0]->m_width; - height = m_mips[0]->m_height; - } - - AZ::u32 CImageObject::GetMipDataSize(const AZ::u32 mip) const - { - AZ_Assert(mip < m_mips.size(), "mip %d doesn't exist", mip); - - return m_mips[mip]->GetSize(); - } - - void CImageObject::GetImagePointer(const AZ::u32 mip, AZ::u8*& pMem, AZ::u32& pitch) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "requested mip doesn't exist"); - - pMem = m_mips[mip]->m_pData; - pitch = m_mips[mip]->m_pitch; - } - - AZ::u32 CImageObject::GetMipBufSize(AZ::u32 mip) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "requested mip doesn't exist"); - - return m_mips[mip]->m_rowCount * m_mips[mip]->m_pitch; - } - - - void CImageObject::SetMipData(AZ::u32 mip, AZ::u8* mipBuf, AZ::u32 bufSize, AZ::u32 pitch) - { - if (mip >= m_mips.size()) - { - return; - } - m_mips[mip]->m_pData = mipBuf; - m_mips[mip]->m_pitch = pitch; - m_mips[mip]->m_rowCount = bufSize/pitch; - AZ_Assert(bufSize == m_mips[mip]->m_rowCount * pitch, "Bad pitch size"); - } - - // ARGB - void CImageObject::GetColorRange(AZ::Color& minColor, AZ::Color& maxColor) const - { - minColor = m_colMinARGB; - maxColor = m_colMaxARGB; - } - - // ARGB - void CImageObject::SetColorRange(const AZ::Color& minColor, const AZ::Color& maxColor) - { - m_colMinARGB = minColor; - m_colMaxARGB = maxColor; - } - - float CImageObject::GetAverageBrightness() const - { - return m_averageBrightness; - } - - void CImageObject::SetAverageBrightness(const float avgBrightness) - { - m_averageBrightness = avgBrightness; - } - - AZ::u32 CImageObject::GetImageFlags() const - { - return m_imageFlags; - } - - void CImageObject::SetImageFlags(const AZ::u32 imageFlags) - { - m_imageFlags = imageFlags; - } - - void CImageObject::AddImageFlags(const AZ::u32 imageFlags) - { - m_imageFlags |= imageFlags; - } - - void CImageObject::RemoveImageFlags(const AZ::u32 imageFlags) - { - m_imageFlags &= ~imageFlags; - } - - bool CImageObject::HasImageFlags(const AZ::u32 imageFlags) const - { - return (m_imageFlags & imageFlags) != 0; - } - - AZ::u32 CImageObject::GetNumPersistentMips() const - { - return m_numPersistentMips; - } - - void CImageObject::SetNumPersistentMips(AZ::u32 nMips) - { - m_numPersistentMips = nMips; - } - - bool CImageObject::HasPowerOfTwoSizes() const - { - AZ::u32 w, h, mips; - GetExtent(w, h, mips); - return ((w&(w - 1)) == 0) && ((h&(h - 1)) == 0); - } - - // use when you convert an image to another one - void CImageObject::CopyPropertiesFrom(const IImageObjectPtr src) - { - const CImageObject *imageObj = static_cast(src.get()); - CopyPropertiesFrom(imageObj); - } - - void CImageObject::CopyPropertiesFrom(const CImageObject* src) - { - m_colMinARGB = src->m_colMinARGB; - m_colMaxARGB = src->m_colMaxARGB; - m_averageBrightness = src->m_averageBrightness; - m_imageFlags = src->GetImageFlags(); - } - - void CImageObject::Swizzle(const char channels[4]) - { - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat))) - { - AZ_Assert(false, "%s function only works with uncompressed pixel format", __FUNCTION__); - return; - } - - const AZ::u8 channelCnt = 4; - - enum Channel_Id - { - ChannelR = 0, - ChannelG, - ChannelB, - ChannelA, - ChannelVal0, - ChannelVal1, - ChannelTypeCount - }; - - float values[ChannelTypeCount]; - values[ChannelVal0] = 0.f; - values[ChannelVal1] = 1.f; - - AZ::u8 channelIndics[channelCnt]; - for (AZ::u8 idx = 0; idx < channelCnt; idx++) - { - switch (channels[idx]) - { - case 'a': - channelIndics[idx] = ChannelA; - break; - case 'r': - channelIndics[idx] = ChannelR; - break; - case 'g': - channelIndics[idx] = ChannelG; - break; - case 'b': - channelIndics[idx] = ChannelB; - break; - case '0': - channelIndics[idx] = ChannelVal0; - break; - case '1': - channelIndics[idx] = ChannelVal1; - break; - default: - AZ_Assert(false, "%s function only works with channel name \"rgba01\"", __FUNCTION__); - return; - } - } - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel - uint32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - const uint32 mips = (uint32)m_mips.size(); - for (uint32 mip = 0; mip < mips; ++mip) - { - uint8* pixelBuf = m_mips[mip]->m_pData; - const uint32 pixelCount = GetPixelCount(mip); - - for (uint32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, values[ChannelR], values[ChannelG], values[ChannelB], values[ChannelA]); - pixelOp->SetRGBA(pixelBuf, values[channelIndics[0]], values[channelIndics[1]], - values[channelIndics[2]], values[channelIndics[3]]); - } - } - } - - void CImageObject::GlossFromNormals(bool hasAuthoredGloss) - { - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat))) - { - AZ_Assert(false, "%s function only works with uncompressed pixel format", __FUNCTION__); - return; - } - - // Derive new roughness from normal variance to preserve the bumpiness of normal map mips and to reduce specular aliasing. - // The derived roughness is combined with the artist authored roughness stored in the alpha channel of the normal map. - // The algorithm is based on the Frequency Domain Normal Mapping implementation presented by Neubelt and Pettineo at Siggraph 2013. - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - const AZ::u32 mips = (AZ::u32)m_mips.size(); - float color[4]; - for (AZ::u32 mip = 0; mip < mips; ++mip) - { - AZ::u8* pixelBuf = m_mips[mip]->m_pData; - const AZ::u32 pixelCount = GetPixelCount(mip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - - // Get length of the averaged normal - AZ::Vector3 normal(color[0] * 2.0f - 1.0f, color[1] * 2.0f - 1.0f, color[2] * 2.0f - 1.0f); - - float len = AZ::GetMax(normal.GetLength(), 1.0f / (1 << 15)); - - float authoredSmoothness = hasAuthoredGloss ? color[3] : 1.0f; - float finalSmoothness = authoredSmoothness; - - if (len < 1.0f) - { - // Convert from smoothness to roughness (needs to match shader code) - float authoredRoughness = (1.0f - authoredSmoothness) * (1.0f - authoredSmoothness); - - // Derive new roughness based on normal variance - float kappa = (3.0f * len - len * len * len) / (1.0f - len * len); - float variance = 1.0f / (2.0f * kappa); - float finalRoughness = AZ::GetMin(sqrtf(authoredRoughness * authoredRoughness + variance), 1.0f); - - // Convert roughness back to smoothness - finalSmoothness = 1.0f - sqrtf(finalRoughness); - } - - pixelOp->SetRGBA(pixelBuf, color[0], color[1], color[2], finalSmoothness); - - } - } - } - - void CImageObject::ConvertLegacyGloss() - { - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat))) - { - AZ_Assert(false, "%s function only works with uncompressed pixel format", __FUNCTION__); - return; - } - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - const AZ::u32 mips = (AZ::u32)m_mips.size(); - float color[4]; - for (AZ::u32 mip = 0; mip < mips; ++mip) - { - AZ::u8* pixelBuf = m_mips[mip]->m_pData; - const AZ::u32 pixelCount = GetPixelCount(mip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - // Convert from (1 - s * 0.7)^6 to (1 - s)^2 - color[3] = 1 - pow(1.0f - color[3] * 0.7f, 3.0f); - pixelOp->SetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - } - } - } - - IImageObject* LoadImageFromDdsFile(const AZStd::string& filename) - { - AZ::IO::SystemFile file; - file.Open(filename.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_ONLY); - - AZ::IO::SystemFileStream fileLoadStream(&file, true); - if (!fileLoadStream.IsOpen()) - { - AZ_Warning("Image Processing", false, "%s: failed to open file %s", __FUNCTION__, filename.c_str()); - return nullptr; - } - - AZStd::string ext = ""; - AzFramework::StringFunc::Path::GetExtension(filename.c_str(), ext, false); - bool isAlphaImage = (ext == "a"); - - IImageObject* imageObj = LoadImageFromDdsFile(fileLoadStream); - - //load mips from seperated files if it's splitted - if (imageObj && imageObj->HasImageFlags(EIF_Splitted)) - { - AZStd::string baseName; - if (isAlphaImage) - { - baseName = filename.substr(0, filename.size() - 2); - } - else - { - baseName = filename; - } - - AZ::u32 externalMipCount = 0; - if (imageObj->GetNumPersistentMips() < imageObj->GetMipCount()) - { - externalMipCount = imageObj->GetMipCount() - imageObj->GetNumPersistentMips(); - } - //load other mips from files with number extensions - for (AZ::u32 mipIdx = 1; mipIdx <= externalMipCount; mipIdx++) - { - AZ::u32 mip = externalMipCount - mipIdx; - AZStd::string mipFileName = AZStd::string::format("%s.%d%s", baseName.c_str(), mipIdx, isAlphaImage?"a":""); - - AZ::IO::SystemFile mipFile; - mipFile.Open(mipFileName.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_ONLY); - - AZ::IO::SystemFileStream mipFileLoadStream(&mipFile, true); - - if (!mipFileLoadStream.IsOpen()) - { - AZ_Warning("Image Processing", false, "%s: failed to open mip file %s", __FUNCTION__, mipFileName.c_str()); - break; - } - - AZ::u32 pitch; - AZ::u8* mem; - imageObj->GetImagePointer(mip, mem, pitch); - AZ::u32 bufSize = imageObj->GetMipBufSize(mip); - mipFileLoadStream.Read(bufSize, mem); - } - } - - return imageObj; - } - - IImageObject* LoadImageFromDdsFile(AZ::IO::SystemFileStream& fileLoadStream) - { - if (fileLoadStream.GetLength() - fileLoadStream.GetCurPos() < sizeof(DDS_FILE_DESC)) - { - AZ_Error("Image Processing", false, "%s: Trying to load a none-DDS file", __FUNCTION__); - return nullptr; - } - - DDS_FILE_DESC desc; - DDS_HEADER_DXT10 exthead; - - AZ::IO::SizeType startPos = fileLoadStream.GetCurPos(); - fileLoadStream.Read(sizeof(desc.dwMagic), &desc.dwMagic); - - if (desc.dwMagic != FOURCC_DDS) - { - desc.dwMagic = FOURCC_DDS; - //the old cry .a file doesn't have "DDS " in the beginning of the file. - //so reset to previous position - fileLoadStream.Seek(startPos, AZ::IO::GenericStream::ST_SEEK_BEGIN); - } - - fileLoadStream.Read(sizeof(desc.header), &desc.header); - - if (!desc.IsValid()) - { - AZ_Error("Image Processing", false, "%s: Trying to load a none-DDS file", __FUNCTION__); - return nullptr; - } - - if (desc.header.IsDX10Ext()) - { - fileLoadStream.Read(sizeof(exthead), &exthead); - } - - IImageObject* outImage = CreateImageFromHeader(desc.header, exthead); - - if (outImage == nullptr) - { - return nullptr; - } - - //load mip data - AZ::u32 mipStart = 0; - //There are at least three lowest mips are in the file if it was splitted. This is to load splitted dds file exported by legacy rc.exe - int numPersistentMips = outImage->GetNumPersistentMips(); - if (numPersistentMips == 0 && outImage->HasImageFlags(EIF_Splitted)) - { - outImage->SetNumPersistentMips(3); - } - - if (outImage->HasImageFlags(EIF_Splitted) - && outImage->GetMipCount() > outImage->GetNumPersistentMips()) - { - mipStart = outImage->GetMipCount() - outImage->GetNumPersistentMips(); - } - - AZ::u32 faces = 1; - if (outImage->HasImageFlags(EIF_Cubemap)) - { - faces = 6; - } - - for (AZ::u32 face = 0; face < faces; face++) - { - for (AZ::u32 mip = mipStart; mip < outImage->GetMipCount(); ++mip) - { - AZ::u32 pitch; - AZ::u8* mem; - outImage->GetImagePointer(mip, mem, pitch); - AZ::u32 faceBufSize = outImage->GetMipBufSize(mip) / faces; - fileLoadStream.Read(faceBufSize, mem + faceBufSize*face); - } - } - - return outImage; - } - - IImageObject* LoadAttachedImageFromDdsFile(const AZStd::string& filename, IImageObjectPtr originImage) - { - if (originImage == nullptr) - { - return nullptr; - } - - AZ_Assert(originImage->HasImageFlags(EIF_AttachedAlpha), - "this function should only be called for origin image loaded from same file with attached alpha flag"); - - AZ::IO::SystemFile file; - file.Open(filename.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_ONLY); - - AZ::IO::SystemFileStream fileLoadStream(&file, true); - if (!fileLoadStream.IsOpen()) - { - AZ_Warning("Image Processing", false, "%s: failed to open file %s", __FUNCTION__, filename.c_str()); - return nullptr; - } - - DDS_FILE_DESC desc; - DDS_HEADER_DXT10 exthead; - - fileLoadStream.Read(sizeof(desc), &desc); - if (desc.dwMagic != FOURCC_DDS) - { - AZ_Error("Image Processing", false, "%s:Trying to load a none-DDS file", __FUNCTION__); - return nullptr; - } - - if (desc.header.IsDX10Ext()) - { - fileLoadStream.Read(sizeof(exthead), &exthead); - } - - //skip size for originImage's mip data - for (AZ::u32 mip = 0; mip < originImage->GetMipCount(); ++mip) - { - AZ::u32 bufSize = originImage->GetMipBufSize(mip); - fileLoadStream.Seek(bufSize, AZ::IO::GenericStream::ST_SEEK_CUR); - } - - IImageObject* alphaImage = nullptr; - - AZ::u32 marker = 0; - fileLoadStream.Read(4, &marker); - if (marker == FOURCC_CExt) // marker for the start of Crytek Extended data - { - fileLoadStream.Read(4, &marker); - if (FOURCC_AttC == marker) // Attached Channel chunk - { - AZ::u32 size = 0; - fileLoadStream.Read(4, &size); - - alphaImage = LoadImageFromDdsFile(fileLoadStream); - fileLoadStream.Read(4, &marker); - } - - if (FOURCC_CEnd == marker ) // marker for the end of Crytek Extended data - { - fileLoadStream.Read(4, &marker); - } - } - - return alphaImage; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.h b/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.h deleted file mode 100644 index e6f40dac2e..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.h +++ /dev/null @@ -1,199 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -namespace ImageProcessing -{ - // ImageObject allows the abstraction of different kinds of - // images generated during conversion - class CImageObject: public IImageObject - { - public: - AZ_CLASS_ALLOCATOR(CImageObject, AZ::SystemAllocator, 0); - - public: - // Constructors - CImageObject(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat); - ~CImageObject(); - - //virtual functions from IImageObject - IImageObject* AllocateImage(EPixelFormat pixelFormat) const override; - IImageObject* AllocateImage() const override; - IImageObject* Clone() const override; - EPixelFormat GetPixelFormat() const override; - AZ::u32 GetPixelCount(AZ::u32 mip) const override; - AZ::u32 GetWidth(AZ::u32 mip) const override; - AZ::u32 GetHeight(AZ::u32 mip) const override; - AZ::u32 GetMipCount() const override; - bool IsCubemap() const override - { - return false; - }; - - void GetImagePointer(AZ::u32 mip, AZ::u8*& pMem, AZ::u32& pitch) const override; - AZ::u32 GetMipBufSize(AZ::u32 mip) const override; - void SetMipData(AZ::u32 mip, AZ::u8* mipBuf, AZ::u32 bufSize, AZ::u32 pitch) override; - - AZ::u32 GetImageFlags() const override; - void SetImageFlags(AZ::u32 imageFlags) override; - void AddImageFlags(AZ::u32 imageFlags) override; - void RemoveImageFlags(AZ::u32 imageFlags) override; - bool HasImageFlags(AZ::u32 imageFlags) const override; - - //image data operations and calculations - void ScaleAndBiasChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& scale, const AZ::Vector4& bias) override; - void ClampChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& min, const AZ::Vector4& max) override; - - void TransferAlphaCoverage(const TextureSettings* textureSetting, const IImageObjectPtr srcImg) override; - float ComputeAlphaCoverageScaleFactor(AZ::u32 mip, float fDesiredCoverage, float fAlphaRef) const override; - float ComputeAlphaCoverage(AZ::u32 firstMip, float fAlphaRef) const override; - - bool CompareImage(const IImageObjectPtr otherImage) const override; - - bool SaveImage(const char* filename, IImageObjectPtr alphaImage, AZStd::vector& outFilePaths) const override; - bool SaveImage(AZ::IO::SystemFileStream& out) const override; - bool SaveMipToFile(AZ::u32 mip, const AZStd::string& filename) const override; - - uint GetTextureMemory() const override; - - EAlphaContent GetAlphaContent() const override; - - void NormalizeVectors(AZ::u32 firstMip, AZ::u32 maxMipCount) override; - - void CopyPropertiesFrom(const IImageObjectPtr src) override; - - void Swizzle(const char channels[4]) override; - - void GetColorRange(AZ::Color& minColor, AZ::Color& maxColor) const override; - void SetColorRange(const AZ::Color& minColor, const AZ::Color& maxColor) override; - float GetAverageBrightness() const override; - void SetAverageBrightness(float avgBrightness) override; - AZ::u32 GetNumPersistentMips() const override; - void SetNumPersistentMips(AZ::u32 nMips) override; - - void GlossFromNormals(bool hasAuthoredGloss) override; - void ConvertLegacyGloss() override; - void ClearColor(float r, float g, float b, float a) override; - //end virtual functions from IImageObject - - private: - - enum EColorNormalization - { - eColorNormalization_Normalize, - eColorNormalization_PassThrough, - }; - - enum EAlphaNormalization - { - eAlphaNormalization_SetToZero, - eAlphaNormalization_Normalize, - eAlphaNormalization_PassThrough, - }; - - private: - class MipLevel - { - public: - AZ_CLASS_ALLOCATOR(MipLevel, AZ::SystemAllocator, 0); - - AZ::u32 m_width; - AZ::u32 m_height; - AZ::u32 m_rowCount; // for compressed textures m_rowCount is usually less than m_height - AZ::u32 m_pitch; // row size in bytes - AZ::u8* m_pData; - - public: - MipLevel() - : m_width(0) - , m_height(0) - , m_rowCount(0) - , m_pitch(0) - , m_pData(0) - { - } - - ~MipLevel() - { - delete[] m_pData; - m_pData = 0; - } - - void Alloc() - { - AZ_Assert(m_pData == 0, "Mip data must be empty before Allocation!"); - m_pData = new AZ::u8[m_pitch * m_rowCount]; - } - - AZ::u32 GetSize() const - { - AZ_Assert(m_pitch, "Pitch must be greater than zero!"); - return m_pitch * m_rowCount; - } - - bool operator==(const MipLevel& other) - { - if (m_width == other.m_width && m_height == other.m_height - && m_rowCount == other.m_rowCount && m_pitch == other.m_pitch) - { - return (memcmp(m_pData, other.m_pData, m_pitch * m_rowCount) == 0); - } - return false; - } - }; - - private: - EPixelFormat m_pixelFormat; - std::vector m_mips; // stores *pointers* to avoid reallocations when elements are erase()'d - - AZ::Color m_colMinARGB; // ARGB will be added the properties of the DDS file - AZ::Color m_colMaxARGB; // ARGB will be added the properties of the DDS file - float m_averageBrightness; // will be added to the properties of the DDS file - AZ::u32 m_imageFlags; // combined from CImageExtensionHelper::EIF_Cubemap,... - AZ::u32 m_numPersistentMips; // number of mipmaps won't be splitted - - public: - //reset this image object to specified format and size - void ResetImage(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat); - - //get mip count and the origin (top mip) size - void GetExtent(AZ::u32& width, AZ::u32& height, AZ::u32& mipCount) const; - - AZ::u32 GetMipDataSize(AZ::u32 mip) const; - - //! calculates the average brightness for a texture - float CalculateAverageBrightness() const; - - bool HasPowerOfTwoSizes() const override; - - void CopyPropertiesFrom(const CImageObject* src); - - // Computes the dynamically used range for the texture and expands it to use the - // full range [0,2^(2^ExponentBits-1)] for better quality. - void NormalizeImageRange(EColorNormalization eColorNorm, EAlphaNormalization eAlphaNorm, bool bMaintainBlack = false, int nExponentBits = 0); - // Brings normalized ranges back to it's original range. - void ExpandImageRange(EColorNormalization eColorNorm, EAlphaNormalization eAlphaNorm, int nExponentBits = 0); - - private: - //build image file header from this image object - bool BuildSurfaceHeader(DDS_HEADER& header) const; - bool BuildSurfaceExtendedHeader(DDS_HEADER_DXT10& exthead) const; - }; - -} // namespace ImageProcessing - - diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.cpp deleted file mode 100644 index 09085540a9..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - - -namespace ImageProcessing -{ - - ImagePreview::ImagePreview(const AZStd::string& inputImageFile, TextureSettings* textureSetting) - : m_imageFileName(inputImageFile) - , m_textureSetting(textureSetting) - , m_presetSetting(nullptr) - , m_inputImage(nullptr) - { - InitializeJobSettings(); - } - - void ImagePreview::StartConvert() - { - // If there is ongoing job, cancel it - Cancel(); - m_output.Reset(); - if (m_inputImage == nullptr) - { - // Load input image - m_inputImage = IImageObjectPtr(LoadImageFromFile(m_imageFileName)); - } - // Get preset if the setting in texture is changed - if (m_presetSetting == nullptr || m_presetSetting->m_uuid != m_textureSetting->m_preset) - { - m_presetSetting = BuilderSettingManager::Instance()->GetPreset(m_textureSetting->m_preset); - } - const bool isPreview = true; - const bool autoDelete = false; - PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - - m_convertJob = AZStd::make_unique(m_inputImage, m_textureSetting, m_presetSetting, - isPreview, defaultPlatform, &m_output, autoDelete, m_jobContext.get()); - m_convertJob->SetDependent(&m_doneJob); - m_convertJob->Start(); - } - - bool ImagePreview::IsDone() - { - return m_output.IsReady(); - } - - float ImagePreview::GetProgress() - { - if (!m_output.IsReady()) - { - return m_output.GetProgress(); - } - return 1.0f; - } - - void ImagePreview::Cancel() - { - if (m_convertJob) - { - m_convertJob->Cancel(); - // Block until job completes - m_doneJob.StartAndWaitForCompletion(); - - AZ_Assert(m_output.IsReady(), "Conversion job is not done yet!"); - } - m_convertJob.release(); - m_doneJob.Reset(true); - } - - IImageObjectPtr ImagePreview::GetOutputImage() - { - return m_output.GetOutputImage(ImageConvertOutput::Preview); - } - - ImagePreview::~ImagePreview() - { - Cancel(); - // Maintain the releasing order - m_jobManager.release(); - m_jobContext.release(); - m_jobCancelGroup.release(); - } - - void ImagePreview::InitializeJobSettings() - { - AZ::JobManagerDesc desc; - AZ::JobManagerThreadDesc threadDesc; - desc.m_workerThreads.push_back(threadDesc); - // Check to ensure these have not already been initialized. - AZ_Error("Image Processing", !m_jobManager && !m_jobCancelGroup && !m_jobContext, "ImagePreview::InitializeJobSettings is being called again after it has already been initialized"); - m_jobManager = AZStd::make_unique(desc); - m_jobCancelGroup = AZStd::make_unique(); - m_jobContext = AZStd::make_unique(*m_jobManager, *m_jobCancelGroup); - - new (&m_doneJob) AZ::JobCompletion(m_jobContext.get()); //re-initialize with the job context - } - - - void GetImageInfoString(IImageObjectPtr image, bool isAlpha, AZStd::string& output) - { - if (!image) - { - return; - } - - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - EPixelFormat format = image->GetPixelFormat(); - const PixelFormatInfo* info = pixelFormats.GetPixelFormatInfo(format); - if (info) - { - output += AZStd::string::format("Format: %s\r\n", info->szName); - } - - AZ::u32 mipCount = image->GetMipCount(); - output += AZStd::string::format("Mip Count: %d\r\n", mipCount); - - AZ::u32 memSize = image->GetTextureMemory(); - AZStd::string memSizeString = ImageProcessingEditor::EditorHelper::GetFileSizeString(memSize); - output += AZStd::string::format("Memory Size: %s\r\n", memSizeString.c_str()); - - if (!isAlpha) - { - if (image->HasImageFlags(EIF_SRGBRead)) - { - output += "Color Space: sRGB\r\n"; - } - else - { - output += "Color Space: Linear\r\n"; - } - - if (image->HasImageFlags(EIF_Cubemap)) - { - output += "Cubemap\r\n"; - } - } - - AZ::u32 imageFlag = image->GetImageFlags(); - output += AZStd::string::format("Image Flag: 0x%08x\r\n", imageFlag); - } - - bool ImagePreview::GetProductTexturePreview(const char* fullProductFileName, QImage& previewImage, AZStd::string& productInfo, AZStd::string& productAlphaInfo) - { - if (!AzFramework::StringFunc::Path::IsExtension(fullProductFileName, "dds", false)) - { - return false; - } - - IImageObjectPtr originImage = IImageObjectPtr(LoadImageFromDdsFile(fullProductFileName)); - IImageObjectPtr alphaImage; - - if (originImage && originImage->HasImageFlags(EIF_AttachedAlpha)) - { - if (originImage->HasImageFlags(EIF_Splitted)) - { - AZStd::string alphaFileName = AZStd::string::format("%s.a", fullProductFileName); - alphaImage = IImageObjectPtr(LoadImageFromDdsFile(alphaFileName)); - - } - else - { - alphaImage = IImageObjectPtr(LoadAttachedImageFromDdsFile(fullProductFileName, originImage)); - } - } - - GetImageInfoString(originImage, false, productInfo); - GetImageInfoString(alphaImage, true, productAlphaInfo); - - IImageObjectPtr combinedImage = MergeOutputImageForPreview(originImage, alphaImage); - if (combinedImage) - { - AZ::u8* imageBuf; - AZ::u32 pitch; - combinedImage->GetImagePointer(0, imageBuf, pitch); - const AZ::u32 width = originImage->GetWidth(0); - const AZ::u32 height = originImage->GetHeight(0); - QImage result = QImage(imageBuf, width, height, pitch, QImage::Format_RGBA8888); - previewImage = result.copy(); // Return a deep copy here - return true; - } - - return false; - } - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.h b/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.h deleted file mode 100644 index 25be5ed37c..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace ImageProcessing -{ - // The reason to have image preview class, we should keep the source image loaded once, - // we could restart conversion and cancel the old conversion at anytime when setting changed - class ImagePreview - { - public: - ImagePreview(const AZStd::string& inputImageFile, TextureSettings* textureSetting); - ~ImagePreview(); - - void InitializeJobSettings(); - void StartConvert(); - bool IsDone(); - float GetProgress(); - void Cancel(); - IImageObjectPtr GetOutputImage(); - - // Output preview image for Asset Browser - static bool GetProductTexturePreview(const char* fullProductFileName, QImage& previewImage, AZStd::string& productInfo, AZStd::string& productAlphaInfo); - - private: - AZStd::string m_imageFileName; - IImageObjectPtr m_inputImage; - const TextureSettings* m_textureSetting; - const PresetSettings* m_presetSetting; - - IImageObjectPtr m_outputImage; - IImageObjectPtr m_outputAlphaImage; - - ImageConvertOutput m_output; - - AZStd::unique_ptr m_jobManager; - AZStd::unique_ptr m_jobCancelGroup; - AZStd::unique_ptr m_jobContext; - AZStd::unique_ptr m_convertJob; - AZ::JobCompletion m_doneJob; - }; - - // Get basic image info as string - void GetImageInfoString(IImageObjectPtr image, bool isAlpha, AZStd::string& output); - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageToProcess.h b/Gems/ImageProcessing/Code/Source/Processing/ImageToProcess.h deleted file mode 100644 index 080fd602e8..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageToProcess.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -namespace ImageProcessing -{ - - //cubemap layouts - enum CubemapLayoutType - { - CubemapLayoutHorizontal = 0, //6x1 strip. with rotations. - CubemapLayoutHorizontalCross, //4x3. - CubemapLayoutVerticalCross, //3x4 - CubemapLayoutVertical, //1x6 strip. new output format. it's better because the memory is continuous for each face - CubemapLayoutTypeCount, - CubemapLayoutNone = CubemapLayoutTypeCount - }; - - class ImageToProcess - { - private: - IImageObjectPtr m_img; - ICompressor::CompressOption m_compressOption; - - private: - ImageToProcess(const ImageToProcess&); - - public: - ImageToProcess(IImageObjectPtr img) - { - m_img = img; - } - - ~ImageToProcess() - { - } - - void Set(IImageObjectPtr img) - { - m_img = img; - } - - IImageObjectPtr Get() const - { - return m_img; - } - - ICompressor::CompressOption& GetCompressOption() - { - return m_compressOption; - } - - void SetCompressOption(const ICompressor::CompressOption& compressOption) - { - m_compressOption = compressOption; - } - - public: - // --------------------------------------------------------------------------------- - //! can be used to compress, requires a preset - void ConvertFormat(EPixelFormat fmtTo); - void ConvertFormatUncompressed(EPixelFormat fmtTo); - - // --------------------------------------------------------------------------------- - // Arguments: - // bDeGamma - apply de-gamma correction - bool GammaToLinearRGBA32F(bool bDeGamma); - void LinearToGamma(); - - // --------------------------------------------------------------------------------- - // Resizers for A32B32G32R32F - - // Prerequisites: image width is even, ARGB32F only, no mips. - void DownscaleTwiceHorizontally(); - - // Prerequisites: height is even, ARGB32F only, no mips. - void DownscaleTwiceVertically(); - - // Prerequisites: width is pow of 2, ARGB32F only, no mips. - void UpscalePow2TwiceHorizontally(); - - // Prerequisites: height is pow of 2, ARGB32F only, no mips. - void UpscalePow2TwiceVertically(); - - // --------------------------------------------------------------------------------- - // Tools for A32B32G32R32F - - // input needs to be in range 0..1 - void AddNormalMap(const IImageObject* pAddBump); - - void CreateHighPass(uint32 dwMipDown); - - void CreateColorChart(); - - //convert various original cubemap layouts to new layout - bool ConvertCubemapLayout(CubemapLayoutType newLayout); - - }; -}// namespace ImageProcessing - diff --git a/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.cpp b/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.cpp deleted file mode 100644 index 3bfa371dc0..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include - -namespace ImageProcessing -{ - CPixelFormats* CPixelFormats::s_instance = nullptr; - - CPixelFormats& CPixelFormats::GetInstance() - { - if (s_instance == nullptr) - { - s_instance = new CPixelFormats(); - } - - return *s_instance; - } - - void CPixelFormats::DestroyInstance() - { - delete s_instance; - s_instance = nullptr; - } - - PixelFormatInfo::PixelFormatInfo( - int a_bitsPerPixel, - int a_Channels, - bool a_Alpha, - const char* a_szAlpha, - uint32 a_minWidth, - uint32 a_minHeight, - int a_blockWidth, - int a_blockHeight, - int a_bitsPerBlock, - bool a_bSquarePow2, - DXGI_FORMAT a_d3d10Format, - AZ::u32 a_fourCC, - ESampleType a_eSampleType, - const char* a_szName, - const char* a_szDescription, - bool a_bCompressed, - bool a_bSelectable) - : nChannels(a_Channels) - , bHasAlpha(a_Alpha) - , minWidth(a_minWidth) - , minHeight(a_minHeight) - , blockWidth(a_blockWidth) - , blockHeight(a_blockHeight) - , bitsPerBlock(a_bitsPerBlock) - , bSquarePow2(a_bSquarePow2) - , szAlpha(a_szAlpha) - , d3d10Format(a_d3d10Format) - , fourCC(a_fourCC) - , eSampleType(a_eSampleType) - , szName(a_szName) - , szLegacyName(a_szName) - , szDescription(a_szDescription) - , bCompressed(a_bCompressed) - , bSelectable(a_bSelectable) - { - //validate pixel format - //a_bitsPerPixel could be 0 if it's ACTC format since the actual bits per-pixel could be 6.4, 5.12 etc. - if (a_bitsPerPixel) - { - AZ_Assert(a_bitsPerPixel * blockWidth * blockHeight == bitsPerBlock, "PixelFormatInfo: Wrong block setting"); - } - - AZ_Assert(szName, "szName can't be nullptr"); - AZ_Assert(nChannels > 0 && nChannels <= 4, "unreasonable channel count %d", nChannels); - AZ_Assert(a_szDescription, "szDescription can't be nullptr"); - AZ_Assert(blockWidth > 0 && blockHeight > 0, "blcok size need to be larger than 0: %d x %d", blockWidth, blockHeight); - AZ_Assert(minWidth > 0 && minHeight > 0, "piexel required mininum image size need to be larger than 0: %d x %d", minWidth, minHeight); - if (!bCompressed) - { - AZ_Assert(blockWidth == 1 && blockHeight == 1, "Uncompressed format shouldn't have block which size > 1"); - } - } - - CPixelFormats::CPixelFormats() - { - InitPixelFormats(); - - m_removedLegacyFormats["DXT1"] = ePixelFormat_BC1; - m_removedLegacyFormats["DXT1a"] = ePixelFormat_BC1a; - m_removedLegacyFormats["DXT3"] = ePixelFormat_BC3; - m_removedLegacyFormats["DXT3t"] = ePixelFormat_BC3t; - m_removedLegacyFormats["DXT5"] = ePixelFormat_BC3; - m_removedLegacyFormats["DXT5t"] = ePixelFormat_BC3t; - m_removedLegacyFormats["3DCp"] = ePixelFormat_BC4; - m_removedLegacyFormats["3DC"] = ePixelFormat_BC5; - } - - void CPixelFormats::InitPixelFormat(EPixelFormat format, const PixelFormatInfo& formatInfo) - { - AZ_Assert((format >= 0) && (format < ePixelFormat_Count), "Unsupport pixel format: %d", format); - - if (m_pixelFormatInfo[format].szName && m_pixelFormatNameMap.find(formatInfo.szName) != m_pixelFormatNameMap.end()) - { - // double initialization - AZ_Assert(false, "Pixel format already exist: %s", m_pixelFormatInfo[format].szName); - } - m_pixelFormatNameMap[formatInfo.szName] = format; - m_pixelFormatInfo[format] = formatInfo; - } - - void CPixelFormats::InitPixelFormats() - { - // Unsigned Formats - // Data in an unsigned format must be positive. Unsigned formats use combinations of - // (R)ed, (G)reen, (B)lue, (A)lpha, (L)uminance - InitPixelFormat(ePixelFormat_R8G8B8A8, PixelFormatInfo(32, 4, true, "8", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R8G8B8A8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "R8G8B8A8", "32-bit RGBA pixel format with alpha, using 8 bits per channel", false, true)); - InitPixelFormat(ePixelFormat_R8G8B8X8, PixelFormatInfo(32, 4, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R8G8B8A8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "R8G8B8X8", "32-bit RGB pixel format, where 8 bits are reserved for each color", false, true)); - InitPixelFormat(ePixelFormat_R8G8, PixelFormatInfo(16, 2, false, "0", 1, 1, 1, 1, 16, false, DXGI_FORMAT_R8G8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "R8G8", "16-bit red/green, using 8 bits per channel", false, false)); - InitPixelFormat(ePixelFormat_R8, PixelFormatInfo( 8, 1, false, "0", 1, 1, 1, 1, 8, false, DXGI_FORMAT_R8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "R8", "8-bit red only", false, false)); - InitPixelFormat(ePixelFormat_A8, PixelFormatInfo( 8, 1, true, "8", 1, 1, 1, 1, 8, false, DXGI_FORMAT_A8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "A8", "8-bit alpha only", false, true)); - InitPixelFormat(ePixelFormat_R16G16B16A16, PixelFormatInfo(64, 4, true, "16", 1, 1, 1, 1, 64, false, DXGI_FORMAT_R16G16B16A16_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint16, "R16G16B16A16", "64-bit ARGB pixel format with alpha, using 16 bits per channel", false, false)); - InitPixelFormat(ePixelFormat_R16G16, PixelFormatInfo(32, 2, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R16G16_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint16, "R16G16", "32-bit red/green, using 16 bits per channel", false, false)); - InitPixelFormat(ePixelFormat_R16, PixelFormatInfo(16, 1, false, "0", 1, 1, 1, 1, 16, false, DXGI_FORMAT_R16_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint16, "R16", "16-bit red only", false, false)); - - // Custom FourCC Formats - // Data in these FourCC formats is custom compressed data and only decodable by certain hardware. - InitPixelFormat(ePixelFormat_ASTC_4x4, PixelFormatInfo(0, 4, true, "?", 16, 16, 4, 4, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_4x4, ESampleType::eSampleType_Compressed, "ASTC_4x4", "ASTC 4x4 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_5x4, PixelFormatInfo(0, 4, true, "?", 16, 16, 5, 4, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_5x4, ESampleType::eSampleType_Compressed, "ASTC_5x4", "ASTC 5x4 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_5x5, PixelFormatInfo(0, 4, true, "?", 16, 16, 5, 5, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_5x5, ESampleType::eSampleType_Compressed, "ASTC_5x5", "ASTC 5x5 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_6x5, PixelFormatInfo(0, 4, true, "?", 16, 16, 6, 5, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_6x5, ESampleType::eSampleType_Compressed, "ASTC_6x5", "ASTC 6x5 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_6x6, PixelFormatInfo(0, 4, true, "?", 16, 16, 6, 6, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_6x6, ESampleType::eSampleType_Compressed, "ASTC_6x6", "ASTC 6x6 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_8x5, PixelFormatInfo(0, 4, true, "?", 16, 16, 8, 5, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_8x5, ESampleType::eSampleType_Compressed, "ASTC_8x5", "ASTC 8x5 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_8x6, PixelFormatInfo(0, 4, true, "?", 16, 16, 8, 6, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_8x6, ESampleType::eSampleType_Compressed, "ASTC_8x6", "ASTC 8x6 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_8x8, PixelFormatInfo(0, 4, true, "?", 16, 16, 8, 8, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_8x8, ESampleType::eSampleType_Compressed, "ASTC_8x8", "ASTC 8x8 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_10x5, PixelFormatInfo(0, 4, true, "?", 16, 16, 10, 5, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_10x5, ESampleType::eSampleType_Compressed, "ASTC_10x5", "ASTC 10x5 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_10x6, PixelFormatInfo(0, 4, true, "?", 16, 16, 10, 6, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_10x6, ESampleType::eSampleType_Compressed, "ASTC_10x6", "ASTC 10x6 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_10x8, PixelFormatInfo(0, 4, true, "?", 16, 16, 10, 8, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_10x8, ESampleType::eSampleType_Compressed, "ASTC_10x8", "ASTC 10x8 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_10x10, PixelFormatInfo(0, 4, true, "?", 16, 16, 10, 10, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_10x10, ESampleType::eSampleType_Compressed, "ASTC_10x10", "ASTC 10x10 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_12x10, PixelFormatInfo(0, 4, true, "?", 16, 16, 12, 10, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_12x10, ESampleType::eSampleType_Compressed, "ASTC_12x10", "ASTC 12x10 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_12x12, PixelFormatInfo(0, 4, true, "?", 16, 16, 12, 12, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_12x12, ESampleType::eSampleType_Compressed, "ASTC_12x12", "ASTC 12x12 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_PVRTC2, PixelFormatInfo(2, 4, true, "2", 16, 16, 8, 4, 64, true, DXGI_FORMAT_UNKNOWN, FOURCC_PVRTC2, ESampleType::eSampleType_Compressed, "PVRTC2", "POWERVR 2 bpp compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_PVRTC4, PixelFormatInfo(4, 4, true, "2", 8, 8, 4, 4, 64, true, DXGI_FORMAT_UNKNOWN, FOURCC_PVRTC4, ESampleType::eSampleType_Compressed, "PVRTC4", "POWERVR 4 bpp compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_EAC_R11, PixelFormatInfo(4, 1, true, "4", 4, 4, 4, 4, 64, false, DXGI_FORMAT_UNKNOWN, FOURCC_EAC_R11, ESampleType::eSampleType_Compressed, "EAC_R11", "EAC 4 bpp single channel texture format", true, false)); - InitPixelFormat(ePixelFormat_EAC_RG11, PixelFormatInfo(8, 2, false, "0", 4, 4, 4, 4, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_EAC_RG11, ESampleType::eSampleType_Compressed, "EAC_RG11", "EAC 8 bpp dual channel texture format", true, false)); - InitPixelFormat(ePixelFormat_ETC2, PixelFormatInfo(4, 3, false, "0", 4, 4, 4, 4, 64, false, DXGI_FORMAT_UNKNOWN, FOURCC_ETC2, ESampleType::eSampleType_Compressed, "ETC2", "ETC2 RGB 4 bpp compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ETC2a, PixelFormatInfo(8, 4, true, "4", 4, 4, 4, 4, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ETC2A, ESampleType::eSampleType_Compressed, "ETC2a", "ETC2 RGBA 8 bpp compressed texture format", true, false)); - - // Standardized Compressed DXGI Formats (DX10+) - // Data in these compressed formats is hardware decodable on all DX10 chips, and manageable with the DX10-API. - InitPixelFormat(ePixelFormat_BC1, PixelFormatInfo(4, 3, false, "0", 4, 4, 4, 4, 64, false, DXGI_FORMAT_BC1_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC1", "BC1 compressed texture format", true, true)); - InitPixelFormat(ePixelFormat_BC1a, PixelFormatInfo(4, 4, true, "1", 4, 4, 4, 4, 64, false, DXGI_FORMAT_BC1_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC1a", "BC1a compressed texture format with transparency", true, true)); - InitPixelFormat(ePixelFormat_BC3, PixelFormatInfo(8, 4, true, "3of8", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC3_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC3", "BC3 compressed texture format", true, true)); - InitPixelFormat(ePixelFormat_BC3t, PixelFormatInfo(8, 4, true, "3of8", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC3_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC3t", "BC3t compressed texture format with transparency", true, true)); - InitPixelFormat(ePixelFormat_BC4, PixelFormatInfo(4, 1, false, "0", 4, 4, 4, 4, 64, false, DXGI_FORMAT_BC4_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC4", "BC4 compressed texture format for single channel maps. 3DCp", true, true)); - InitPixelFormat(ePixelFormat_BC4s, PixelFormatInfo(4, 1, false, "0", 4, 4, 4, 4, 64, false, DXGI_FORMAT_BC4_SNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC4s", "BC4 compressed texture format for signed single channel maps", true, true)); - InitPixelFormat(ePixelFormat_BC5, PixelFormatInfo(8, 2, false, "0", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC5_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC5", "BC5 compressed texture format for two channel maps or normalmaps. 3DC", true, true)); - InitPixelFormat(ePixelFormat_BC5s, PixelFormatInfo(8, 2, false, "0", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC5_SNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC5s", "BC5 compressed texture format for signed two channel maps or normalmaps", true, true)); - InitPixelFormat(ePixelFormat_BC6UH, PixelFormatInfo(8, 3, false, "0", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC6H_UF16, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC6UH", "BC6 compressed texture format, unsigned half", true, true)); - InitPixelFormat(ePixelFormat_BC7, PixelFormatInfo(8, 4, true, "8", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC7_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC7", "BC7 compressed texture format", true, true)); - InitPixelFormat(ePixelFormat_BC7t, PixelFormatInfo(8, 4, true, "8", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC7_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC7t", "BC7t compressed texture format with transparency", true, true)); - - // Float formats - // Data in a Float format is floating point data. - InitPixelFormat(ePixelFormat_R9G9B9E5, PixelFormatInfo(32, 3, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, FOURCC_DX10, ESampleType::eSampleType_Compressed, "R9G9B9E5", "32-bit RGB pixel format with shared exponent", false, true)); - InitPixelFormat(ePixelFormat_R32G32B32A32F, PixelFormatInfo(128, 4, true, "23", 1, 1, 1, 1, 128, false, DXGI_FORMAT_R32G32B32A32_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Float, "R32G32B32A32F", "four float channels", false, false)); - InitPixelFormat(ePixelFormat_R32G32F, PixelFormatInfo(64, 2, false, "0", 1, 1, 1, 1, 64, false, DXGI_FORMAT_R32G32_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Float, "R32G32F", "two float channels", false, false)); // FIXME: This should be eTF_R32G32F, but CryTek did not add that enum to ITexture.h yet - InitPixelFormat(ePixelFormat_R32F, PixelFormatInfo(32, 1, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R32_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Float, "R32F", "one float channel", false, false)); - InitPixelFormat(ePixelFormat_R16G16B16A16F, PixelFormatInfo(64, 4, true, "10", 1, 1, 1, 1, 64, false, DXGI_FORMAT_R16G16B16A16_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Half, "R16G16B16A16F", "four half channels", false, false)); - InitPixelFormat(ePixelFormat_R16G16F, PixelFormatInfo(32, 2, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R16G16_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Half, "R16G16F", "two half channel", false, false)); - InitPixelFormat(ePixelFormat_R16F, PixelFormatInfo(16, 1, false, "0", 1, 1, 1, 1, 16, false, DXGI_FORMAT_R16_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Half, "R16F", "one half channel", false, false)); - - //legacy BGRA8 - InitPixelFormat(ePixelFormat_B8G8R8A8, PixelFormatInfo(32, 4, true, "8", 1, 1, 1, 1, 32, false, DXGI_FORMAT_B8G8R8A8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "B8G8R8A8", "32-bit BGRA pixel format with alpha, using 8 bits per channel", false, true)); - - InitPixelFormat(ePixelFormat_R32, PixelFormatInfo(32, 1, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_FORCE_UINT, FOURCC_DX10, ESampleType::eSampleType_Uint32, "R32", "32-bit red only", false, false)); - - //Set legacy name it can be used for convertion - m_pixelFormatInfo[ePixelFormat_R8G8B8A8].szLegacyName = "A8R8G8B8"; - m_pixelFormatInfo[ePixelFormat_R8G8B8X8].szLegacyName = "X8R8G8B8"; - m_pixelFormatInfo[ePixelFormat_R8G8].szLegacyName = "G8R8"; - m_pixelFormatInfo[ePixelFormat_R16G16B16A16].szLegacyName = "A16B16G16R16"; - m_pixelFormatInfo[ePixelFormat_R16G16].szLegacyName = "G16R16"; - m_pixelFormatInfo[ePixelFormat_R32G32B32A32F].szLegacyName = "A32B32G32R32F"; - m_pixelFormatInfo[ePixelFormat_R32G32F].szLegacyName = "G32R32F"; - m_pixelFormatInfo[ePixelFormat_R16G16B16A16F].szLegacyName = "A16B16G16R16F"; - m_pixelFormatInfo[ePixelFormat_R16G16F].szLegacyName = "G16R16F"; - - //validate all pixel formats are proper initialized - for (int i = 0; i < ePixelFormat_Count; ++i) - { - if (m_pixelFormatInfo[i].szName == 0) - { - // Uninitialized entry. Should never happen. But, if it happened: make sure that entries from - // the EPixelFormat enum and InitPixelFormat() calls match. - AZ_Assert(false, "InitPixelFormats error: not all pixel formats have an implementation."); - } - } - } - - - EPixelFormat CPixelFormats::FindPixelFormatByName(const char* name) - { - if (m_pixelFormatNameMap.find(name) != m_pixelFormatNameMap.end()) - { - return m_pixelFormatNameMap[name]; - } - return ePixelFormat_Unknown; - } - - EPixelFormat CPixelFormats::FindPixelFormatByLegacyName(const char* name) - { - if (m_removedLegacyFormats.find(name) != m_removedLegacyFormats.end()) - { - return m_removedLegacyFormats[name]; - } - - for (int i = 0; i < ePixelFormat_Count; ++i) - { - if (azstricmp(m_pixelFormatInfo[i].szLegacyName, name) == 0) - { - return (EPixelFormat)i; - } - } - return ePixelFormat_Unknown; - } - - const PixelFormatInfo* CPixelFormats::GetPixelFormatInfo(EPixelFormat format) - { - AZ_Assert((format >= 0) && (format < ePixelFormat_Count), "Unsupport pixel format: %d", format); - return &m_pixelFormatInfo[format]; - } - - bool CPixelFormats::IsPixelFormatUncompressed(EPixelFormat format) - { - AZ_Assert((format >= 0) && (format < ePixelFormat_Count), "Unsupport pixel format: %d", format); - return !m_pixelFormatInfo[format].bCompressed; - } - - bool CPixelFormats::IsPixelFormatWithoutAlpha(EPixelFormat format) - { - AZ_Assert((format >= 0) && (format < ePixelFormat_Count), "Unsupport pixel format: %d", format); - return !m_pixelFormatInfo[format].bHasAlpha; - } - - uint32 CPixelFormats::ComputeMaxMipCount(EPixelFormat format, uint32 width, uint32 height) - { - const PixelFormatInfo* const pFormatInfo = GetPixelFormatInfo(format); - - AZ_Assert(pFormatInfo != nullptr, "ComputeMaxMipCount: unsupport pixel format %d", format); - - uint32 tmpWidth = width; - uint32 tmpHeight = height; - - bool bIgnoreBlockSize = CanImageSizeIgnoreBlockSize(format); - - uint32 mipCountW = 0; - while ((tmpWidth >= pFormatInfo->minWidth) && (bIgnoreBlockSize || (tmpWidth % pFormatInfo->blockWidth == 0))) - { - ++mipCountW; - tmpWidth >>= 1; - } - - uint32 mipCountH = 0; - while ((tmpHeight >= pFormatInfo->minHeight) && (bIgnoreBlockSize || (tmpHeight % pFormatInfo->blockHeight == 0))) - { - ++mipCountH; - tmpHeight >>= 1; - } - - //for compressed image, use minmum mip out of W and H because any size below won't be compressed properly - //for non-compressed image. use maximum mip count. for example the lowest two mips of 128x64 would be 2x1 and 1x1 - const uint32 mipCount = (pFormatInfo->bCompressed) - ? AZStd::min(mipCountW, mipCountH) - : AZStd::max(mipCountW, mipCountH); - - // In some cases, user may call this function for image size which is qualified for this pixel format, - // the mipCount could be 0 for those cases. Round it to 1 if it happend. - return AZStd::max((uint32)1, mipCount); - } - - bool CPixelFormats::CanImageSizeIgnoreBlockSize(EPixelFormat format) - { - // ASTC is a kind of block compression but it doesn't need the image size to be interger mutiples of block size. - // reference: https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_texture_compression_astc_hdr.txt - //"For images which are not an integer multiple of the block size, additional texels are added to the edges - // with maximum X and Y.These texels may be any color, as they will not be accessed." - bool bIgnoreBlockSize = IsASTCFormat(format); - - return bIgnoreBlockSize; - } - - bool CPixelFormats::IsImageSizeValid(EPixelFormat format, uint32 imageWidth, uint32 imageHeight, [[maybe_unused]] bool logWarning) - { - const PixelFormatInfo* const pFormatInfo = GetPixelFormatInfo(format); - AZ_Assert(pFormatInfo != nullptr, "IsImageSizeValid: unsupport pixel format %d", format); - - //if the format requires image to be sqaure and power of 2 - if (pFormatInfo->bSquarePow2 && ((imageWidth != imageHeight) || (imageWidth & (imageWidth - 1)) != 0)) - { - AZ_Warning("ImageBuilder", !logWarning, "Image size need to be square and power of 2 for pixel format %s", - pFormatInfo->szName); - return false; - } - - // minimum size required by the pixel format - if (imageWidth < pFormatInfo->minWidth || imageHeight < pFormatInfo->minHeight) - { - AZ_Warning("ImageBuilder", !logWarning, "The image size (%dx%d) is smaller than minimum size (%dx%d) for pixel format %s", - imageWidth, imageHeight, pFormatInfo->minWidth, pFormatInfo->minHeight, pFormatInfo->szName); - return false; - } - - //check image size againest block size - if (!CanImageSizeIgnoreBlockSize(format)) - { - if (imageWidth % pFormatInfo->blockWidth != 0 || imageHeight % pFormatInfo->blockHeight != 0) - { - AZ_Warning("ImageBuilder", !logWarning, "Image size (%dx%d) need to be integer multiplier of compression block size (%dx%d) for pixel format %s", - imageWidth, imageHeight, pFormatInfo->minWidth, pFormatInfo->minHeight, pFormatInfo->szName); - return false; - } - } - - return true; - } - - AZ::u32 NextPowOf2(AZ::u32 value) - { - value--; - value |= value >> 1; - value |= value >> 2; - value |= value >> 4; - value |= value >> 8; - value |= value >> 16; - value++; - return value; - } - - void CPixelFormats::GetSuitableImageSize(EPixelFormat format, AZ::u32 imageWidth, AZ::u32 imageHeight, - AZ::u32& outWidth, AZ::u32& outHeight) - { - const PixelFormatInfo* const pFormatInfo = GetPixelFormatInfo(format); - AZ_Assert(pFormatInfo != nullptr, "IsImageSizeValid: unsupport pixel format %d", format); - - outWidth = imageWidth; - outHeight = imageHeight; - - // minimum size required by the pixel format - if (outWidth < pFormatInfo->minWidth) - { - outWidth = pFormatInfo->minWidth; - } - if (outHeight < pFormatInfo->minHeight) - { - outHeight = pFormatInfo->minHeight; - } - - if (pFormatInfo->bSquarePow2 && ((outWidth != outHeight) || (outWidth & (outWidth - 1)) != 0)) - { - AZ::u32 sideSide = AZ::GetMax(outWidth, outHeight); - outWidth = NextPowOf2(sideSide); - outHeight = outWidth; - } - - //check image size againest block size - //if the format requires square and power of 2. we can skip this step - if (!CanImageSizeIgnoreBlockSize(format) && !pFormatInfo->bSquarePow2) - { - if (outWidth % pFormatInfo->blockWidth != 0) - { - outWidth = ((outWidth + pFormatInfo->blockWidth -1) / pFormatInfo->blockWidth) * pFormatInfo->blockWidth; - } - if (outHeight % pFormatInfo->blockHeight != 0) - { - outHeight = ((outHeight + pFormatInfo->blockHeight - 1) / pFormatInfo->blockHeight) * pFormatInfo->blockHeight; - } - } - - } - - uint32 CPixelFormats::EvaluateImageDataSize(EPixelFormat format, uint32 imageWidth, uint32 imageHeight) - { - const PixelFormatInfo* const pFormatInfo = GetPixelFormatInfo(format); - AZ_Assert(pFormatInfo != nullptr, "IsImageSizeValid: unsupport pixel format %d", format); - - //the image should pass IsImageSizeValid test to be eavluated correctly - if (!IsImageSizeValid(format, imageWidth, imageHeight, false)) - { - return 0; - } - - // get number of blocks (ceiling round up for block count) and multiply with bits per block. Divided by 8 to get - // final byte size - return (((imageWidth + pFormatInfo->blockWidth -1) / pFormatInfo->blockWidth) * - ((imageHeight + pFormatInfo->blockHeight - 1) / pFormatInfo->blockHeight) * pFormatInfo->bitsPerBlock) / 8; - } - - bool CPixelFormats::IsFormatSingleChannel(EPixelFormat fmt) - { - return (m_pixelFormatInfo[fmt].nChannels == 1); - } - - bool CPixelFormats::IsFormatSigned(EPixelFormat fmt) - { - // all these formats contain signed data, the FP-formats contain scale & biased unsigned data - return (fmt == ePixelFormat_BC4s || fmt == ePixelFormat_BC5s /*|| fmt == ePixelFormat_BC6SH*/); - } - - bool CPixelFormats::IsFormatFloatingPoint(EPixelFormat fmt, bool bFullPrecision) - { - // all these formats contain floating point data - if (!bFullPrecision) - { - return ((fmt == ePixelFormat_R16F || fmt == ePixelFormat_R16G16F || - fmt == ePixelFormat_R16G16B16A16F) || (fmt == ePixelFormat_BC6UH || fmt == ePixelFormat_R9G9B9E5)); - } - else - { - return ((fmt == ePixelFormat_R32F || fmt == ePixelFormat_R32G32F || fmt == ePixelFormat_R32G32B32A32F)); - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.h b/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.h deleted file mode 100644 index aee61d1a9f..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include // DX10+ formats. DXGI_FORMAT - -#include - -#include -#include - -namespace ImageProcessing -{ - //The original implementation was from cryhalf's CryConvertFloatToHalf and CryConvertHalfToFloat function - struct SHalf - { - explicit SHalf(float floatValue) - { - AZ::u32 Result; - - AZ::u32 intValue = ((AZ::u32*)(&floatValue))[0]; - AZ::u32 Sign = (intValue & 0x80000000U) >> 16U; - intValue = intValue & 0x7FFFFFFFU; - - if (intValue > 0x47FFEFFFU) - { - // The number is too large to be represented as a half. Saturate to infinity. - Result = 0x7FFFU; - } - else - { - if (intValue < 0x38800000U) - { - // The number is too small to be represented as a normalized half. - // Convert it to a denormalized value. - AZ::u32 Shift = 113U - (intValue >> 23U); - intValue = (0x800000U | (intValue & 0x7FFFFFU)) >> Shift; - } - else - { - // Rebias the exponent to represent the value as a normalized half. - intValue += 0xC8000000U; - } - - Result = ((intValue + 0x0FFFU + ((intValue >> 13U) & 1U)) >> 13U) & 0x7FFFU; - } - h = (Result | Sign); - } - - operator float() const - { - AZ::u32 Mantissa; - AZ::u32 Exponent; - AZ::u32 Result; - - Mantissa = h & 0x03FF; - - if ((h & 0x7C00) != 0) // The value is normalized - { - Exponent = ((h >> 10) & 0x1F); - } - else if (Mantissa != 0) // The value is denormalized - { - // Normalize the value in the resulting float - Exponent = 1; - - do - { - Exponent--; - Mantissa <<= 1; - } while ((Mantissa & 0x0400) == 0); - - Mantissa &= 0x03FF; - } - else // The value is zero - { - Exponent = -112; - } - - Result = ((h & 0x8000) << 16) | // Sign - ((Exponent + 112) << 23) | // Exponent - (Mantissa << 13); // Mantissa - - return *(float*)&Result; - } - - private: - AZ::u16 h; - }; - - enum class ESampleType - { - eSampleType_Uint8, - eSampleType_Uint16, - eSampleType_Uint32, - eSampleType_Half, - eSampleType_Float, - eSampleType_Compressed, - }; - - struct PixelFormatInfo - { - - int nChannels; // channel count per pixel - bool bHasAlpha; // has alpha channel or not - const char* szAlpha; // a string of bits of alpha channel used to show brief of the pixel format - uint32 minWidth; // minimum width required for image using this pixel format - uint32 minHeight; // minimum height required for image using this pixel format - int blockWidth; // width of the block for block based compressing - int blockHeight; // Height of the block for block based compressing - int bitsPerBlock; // bits per pixel before uncompressed - bool bSquarePow2; // whether the pixel format requires image size be square and power of 2. - DXGI_FORMAT d3d10Format; // the mapping d3d10 pixel format - ESampleType eSampleType; // the data type used to present pixel - const char* szLegacyName; // name used for cryEngine - const char* szName; // name for showing in editors - const char* szDescription; // description for showing in editors - bool bCompressed; // if it's a compressed format - bool bSelectable; // shows up in the list of usable destination pixel formats in the dialog window - AZ::u32 fourCC; // fourCC to identify a none d3d10 format - - PixelFormatInfo() - : szAlpha(0) - , bitsPerBlock(-1) - , d3d10Format(DXGI_FORMAT_UNKNOWN) - , szName(0) - , szDescription(0) - , fourCC(0) - { - } - - PixelFormatInfo( - int a_bitsPerPixel, - int a_Channels, - bool a_Alpha, - const char* a_szAlpha, - uint32 a_minWidth, - uint32 a_minHeight, - int a_blockWidth, - int a_blockHeight, - int a_bitsPerBlock, - bool a_bSquarePow2, - DXGI_FORMAT a_d3d10Format, - AZ::u32 a_fourCC, - ESampleType a_eSampleType, - const char* a_szName, - const char* a_szDescription, - bool a_bCompressed, - bool a_bSelectable); - }; - - class CPixelFormats - { - public: - //singleton - static CPixelFormats& GetInstance(); - static void DestroyInstance(); - - const PixelFormatInfo* GetPixelFormatInfo(EPixelFormat format); - - bool IsPixelFormatWithoutAlpha(EPixelFormat format); - bool IsPixelFormatUncompressed(EPixelFormat format); - - //functions seems only used for BC compressions. need re-evaluate later - bool IsFormatSingleChannel(EPixelFormat fmt); - bool IsFormatSigned(EPixelFormat fmt); - bool IsFormatFloatingPoint(EPixelFormat fmt, bool bFullPrecision); - - //find the pixel format for name used by Cry's RC.ini - //returns ePixelFormat_Unknown if the name was not found in registed format list - EPixelFormat FindPixelFormatByLegacyName(const char* name); - - //find pixel format by its name - EPixelFormat FindPixelFormatByName(const char* name); - - //returns maximum lod levels for image which has certain pixel format, width and height. - uint32 ComputeMaxMipCount(EPixelFormat format, uint32 imageWidth, uint32 imageHeight); - - //check if the input image size work with the pixel format. Some compression formats have requirements with the input image size. - bool IsImageSizeValid(EPixelFormat format, uint32 imageWidth, uint32 imageHeight, bool logWarning); - - //get suitable new size for an image with certain width, height and pixel format - void GetSuitableImageSize(EPixelFormat format, AZ::u32 imageWidth, AZ::u32 imageHeight, - AZ::u32& outWidth, AZ::u32& outHeight); - - //check if the image size of the specified pixel format need to be integer mutiple of block size - bool CanImageSizeIgnoreBlockSize(EPixelFormat format); - - //eavluate image data size. it doesn't include mips - uint32 EvaluateImageDataSize(EPixelFormat format, uint32 imageWidth, uint32 imageHeight); - - private: - CPixelFormats(); - void InitPixelFormats(); - void InitPixelFormat(EPixelFormat format, const PixelFormatInfo& formatInfo); - - private: - static CPixelFormats *s_instance; - - PixelFormatInfo m_pixelFormatInfo[ePixelFormat_Count]; - - //pixel format name to pixel format enum - AZStd::map m_pixelFormatNameMap; - - // some formats from cryEngine were removed. using this name-pixelFormat mapping to look for new format - AZStd::map m_removedLegacyFormats; - }; - - template - bool IsPowerOfTwo(TInteger x); - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Tests/AtlasBuilderTest.cpp b/Gems/ImageProcessing/Code/Tests/AtlasBuilderTest.cpp deleted file mode 100644 index 61462475a7..0000000000 --- a/Gems/ImageProcessing/Code/Tests/AtlasBuilderTest.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "ImageProcessing_precompiled.h" -#include "Source/AtlasBuilder/AtlasBuilderWorker.h" -#include "Source/ImageBuilderComponent.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include - -using namespace TextureAtlasBuilder; -using namespace ImageProcessing; - -#if defined(AZ_PLATFORM_APPLE_OSX) -# define AZ_ROOT_TEST_FOLDER "./" -#else -# define AZ_ROOT_TEST_FOLDER "" -#endif - -namespace UnitTest -{ - class AtlasBuilderTest - : public ::testing::Test - , public AzToolsFramework::AssetSystemRequestBus::Handler - { - protected: - void SetUp() override - { - AZ::AllocatorInstance::Create(); - - m_app.reset(aznew AZ::ComponentApplication()); - AZ::ComponentApplication::Descriptor desc; - desc.m_useExistingAllocator = true; - m_app->Create(desc); - - BuilderSettingManager::CreateInstance(); - - m_context = AZStd::make_unique(); - BuilderPluginComponent::Reflect(m_context.get()); - - //load qt plugins for some image file formats support - int argc = 0; - char** argv = nullptr; - m_coreApplication.reset(new QCoreApplication(argc, argv)); - - m_engineRoot.reset(new AZStd::string(AZ::Test::GetEngineRootPath())); - - // Startup default local FileIO (hits OSAllocator) if not already setup. - if (AZ::IO::FileIOBase::GetInstance() == nullptr) - { - AZ::IO::FileIOBase::SetInstance(aznew AZ::IO::LocalFileIO()); - } - - AzToolsFramework::AssetSystemRequestBus::Handler::BusConnect(); - } - - void TearDown() override - { - AzToolsFramework::AssetSystemRequestBus::Handler::BusDisconnect(); - - delete AZ::IO::FileIOBase::GetInstance(); - AZ::IO::FileIOBase::SetInstance(nullptr); - - m_app->Destroy(); - m_app = nullptr; - - m_context.release(); - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - - m_engineRoot.reset(); - m_coreApplication.reset(); - - AZ::AllocatorInstance::Destroy(); - } - - AZStd::string GetFullPath(AZStd::string_view fileName) - { - const AZStd::string testsFolder = *m_engineRoot + "/Gems/ImageProcessing/Code/Tests/"; - return AZStd::string::format("%s%.*s", testsFolder.c_str(), aznumeric_cast(fileName.size()), fileName.data()); - } - - AZStd::unique_ptr m_context; - AZStd::unique_ptr m_app; - AZStd::unique_ptr m_coreApplication; // required by engine root and IsExtensionSupported - AZStd::unique_ptr m_engineRoot; - - public: - AssetBuilderSDK::ProcessJobRequest CreateTestJobRequest( - const AZStd::string& testFileName, - const AZStd::string& watchFolder, - const AZStd::string& tempDirPath, - [[maybe_unused]] bool critical, - QString platform, - AZ::s64 jobId = 0) - { - AZStd::string fullPath; - AzFramework::StringFunc::Path::Join( - watchFolder.c_str(), testFileName.c_str(), fullPath, true, true); - - bool valid = true; - AtlasBuilderInput testInput = AtlasBuilderInput::ReadFromFile(fullPath, watchFolder, valid); - - AssetBuilderSDK::ProcessJobRequest request; - request.m_sourceFile = testFileName; - request.m_fullPath = fullPath; - request.m_tempDirPath = tempDirPath; - request.m_jobId = jobId; - request.m_platformInfo.m_identifier = platform.toUtf8().constData(); - request.m_jobDescription = AtlasBuilderWorker::GetJobDescriptor(testFileName, testInput); - - return request; - } - - AZStd::string GetTestFolderPath() - { - return AZ_ROOT_TEST_FOLDER; - } - - ////////////////////////////////////////////////////////////////////////// - // AssetSystemRequestBus - bool GetAbsoluteAssetDatabaseLocation([[maybe_unused]] AZStd::string& result) override { return false; }; - const char* GetAbsoluteDevGameFolderPath() override { return ""; }; - const char* GetAbsoluteDevRootFolderPath() override { return ""; }; - bool GetRelativeProductPathFromFullSourceOrProductPath([[maybe_unused]] const AZStd::string& fullPath, [[maybe_unused]] AZStd::string& outputPath) override { return false; }; - bool GetFullSourcePathFromRelativeProductPath([[maybe_unused]] const AZStd::string& relPath, [[maybe_unused]] AZStd::string& fullPath) override { return false; }; - bool GetAssetInfoById([[maybe_unused]] const AZ::Data::AssetId& assetId, [[maybe_unused]] const AZ::Data::AssetType& assetType, [[maybe_unused]] const AZStd::string& platformName, [[maybe_unused]] AZ::Data::AssetInfo& assetInfo, [[maybe_unused]] AZStd::string& rootFilePath) override { return false; }; - bool GetSourceInfoBySourcePath(const char* sourcePath, AZ::Data::AssetInfo& assetInfo, AZStd::string& watchFolder) override - { - assetInfo.m_relativePath = sourcePath; - watchFolder = GetFullPath("TestAssets"); - return true; - }; - bool GetSourceInfoBySourceUUID([[maybe_unused]] const AZ::Uuid& sourceUuid, [[maybe_unused]] AZ::Data::AssetInfo& assetInfo, [[maybe_unused]] AZStd::string& watchFolder) override { return false; }; - bool GetScanFolders([[maybe_unused]] AZStd::vector& scanFolders) override { return false; }; - bool GetAssetSafeFolders([[maybe_unused]] AZStd::vector& assetSafeFolders) override { return false; }; - bool IsAssetPlatformEnabled([[maybe_unused]] const char* platform) override { return false; }; - int GetPendingAssetsForPlatform([[maybe_unused]] const char* platform) override { return -1; }; - bool GetAssetsProducedBySourceUUID([[maybe_unused]] const AZ::Uuid& sourceUuid, [[maybe_unused]] AZStd::vector& productsAssetInfo) override { return false; }; - }; - - TEST_F(AtlasBuilderTest, ProcessJob_ProcessValidTextureAtlas_OutputProductDependencies) - { - AZStd::string builderSetting(*m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"); - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(builderSetting, m_context.get()); - - // create the test job - AssetBuilderSDK::ProcessJobRequest request = CreateTestJobRequest( - "TextureAtlasTest.texatlas", GetFullPath("TestAssets"), GetTestFolderPath(), false, BuilderSettingManager::s_defaultPlatform.c_str(), 1); - - AssetBuilderSDK::ProcessJobResponse response; - - AtlasBuilderWorker testBuilder; - testBuilder.ProcessJob(request, response); - - ASSERT_EQ(response.m_resultCode, AssetBuilderSDK::ProcessJobResultCode::ProcessJobResult_Success); - - // texture atlas builder only has two output products - ASSERT_EQ(response.m_outputProducts.size(), 2); - - // textureatlasidx depends on dds its paired with, but not the other way around - AZ::Data::AssetId ddsProductAssetId(request.m_sourceFileUUID, response.m_outputProducts[static_cast(Product::DdsProduct)].m_productSubID); - AZStd::vector textureatlasidxProductDependencies = response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependencies; - ASSERT_EQ(textureatlasidxProductDependencies.size(), 1); - ASSERT_EQ(textureatlasidxProductDependencies[0].m_dependencyId, ddsProductAssetId); - - AZStd::vector ddsProductDependencies = response.m_outputProducts[static_cast(Product::DdsProduct)].m_dependencies; - ASSERT_EQ(ddsProductDependencies.size(), 0); - } -} diff --git a/Gems/ImageProcessing/Code/Tests/ImageProcessing_Test.cpp b/Gems/ImageProcessing/Code/Tests/ImageProcessing_Test.cpp deleted file mode 100644 index 78094bf90f..0000000000 --- a/Gems/ImageProcessing/Code/Tests/ImageProcessing_Test.cpp +++ /dev/null @@ -1,1544 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -//Enable generate image files for result of some tests. -//This is slow and only useful for debugging. This should be disabled for unit test -//#define DEBUG_OUTPUT_IMAGES - -//There are some test functions in this test which are DISABLED. They were mainly for programming tests. -//It's only recommended to enable them for programming test purpose. - -#include -#include -#include "../Source/ImageBuilderComponent.h" - -using namespace ImageProcessing; - -namespace UnitTest -{ - -class ImageProcessingTest - : public ScopedAllocatorSetupFixture - // Only used to provide the serialize context - , public AZ::ComponentApplicationBus::Handler -{ -protected: - AZStd::unique_ptr m_coreApplication; // required by engine root and IsExtensionSupported - AZStd::unique_ptr m_context; - AZStd::string m_engineRoot; - - void SetUp() override - { - BuilderSettingManager::CreateInstance(); - - //prepare reflection - m_context = AZStd::make_unique(); - BuilderPluginComponent::Reflect(m_context.get()); - AZ::DataPatch::Reflect(m_context.get()); - - // Startup default local FileIO (hits OSAllocator) if not already setup. - if (AZ::IO::FileIOBase::GetInstance() == nullptr) - { - AZ::IO::FileIOBase::SetInstance(aznew AZ::IO::LocalFileIO()); - } - - // Adding this handler to allow utility functions access the serialize context - AZ::ComponentApplicationBus::Handler::BusConnect(); - AZ::Interface::Register(this); - - //load qt plugins for some image file formats support - int argc = 0; - char** argv = nullptr; - m_coreApplication.reset(new QCoreApplication(argc, argv)); - m_engineRoot = AZ::Test::GetEngineRootPath(); - - InitialImageFilenames(); - - ImageProcessingEditor::EditorHelper::InitPixelFormatString(); - } - - - void TearDown() override - { - delete AZ::IO::FileIOBase::GetInstance(); - AZ::IO::FileIOBase::SetInstance(nullptr); - - m_context.reset(); - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - - AZ::Interface::Unregister(this); - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - - m_coreApplication.reset(); - } - - // ComponentApplicationMessages overrides... - AZ::ComponentApplication* GetApplication() override { return nullptr; } - void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override { } - void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override { } - void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override { } - void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override { } - void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler&) override { } - void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler&) override { } - void SignalEntityActivated(AZ::Entity* entity) override { } - void SignalEntityDeactivated(AZ::Entity* entity) override { } - bool AddEntity(AZ::Entity*) override { return false; } - bool RemoveEntity(AZ::Entity*) override { return false; } - bool DeleteEntity(const AZ::EntityId&) override { return false; } - AZ::Entity* FindEntity(const AZ::EntityId&) override { return nullptr; } - AZ::BehaviorContext* GetBehaviorContext() override { return nullptr; } - AZ::JsonRegistrationContext* GetJsonRegistrationContext() override { return nullptr; } - const char* GetAppRoot() const override { return nullptr; } - const char* GetEngineRoot() const override { return nullptr; } - const char* GetExecutableFolder() const override { return nullptr; } - AZ::Debug::DrillerManager* GetDrillerManager() override { return nullptr; } - void EnumerateEntities(const EntityCallback& /*callback*/) override {} - void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override {} - // The only one function we need to implement. - AZ::SerializeContext* GetSerializeContext() override - { - return m_context.get(); - } - - //enum names for Images with specific identification - enum ImageFeature - { - Image_20X16_RGBA8_Png = 0, - Image_32X32_16bit_F_Tif, - Image_32X32_32bit_F_Tif, - Image_200X200_RGB8_Jpg, - Image_512X288_RGB8_Tga, - Image_1024X1024_RGB8_Tif, - Image_UpperCase_Tga, - Image_512x512_Normal_Tga, - Image_128x128_Transparent_Tga, - Image_237x177_RGB_Jpg, - Image_GreyScale_Png, - Image_BlackWhite_Png, - Image_TerrainHeightmap_Bt - }; - - //image file names for testing - AZStd::map m_imagFileNameMap; - - //intialial image file names for testing - void InitialImageFilenames() - { - const AZStd::string fileFolder = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/"; - - m_imagFileNameMap[Image_20X16_RGBA8_Png] = fileFolder + AZStd::string("20x16_32bit.png"); - m_imagFileNameMap[Image_32X32_16bit_F_Tif] = fileFolder + AZStd::string("32x32_16bit_f.tif"); - m_imagFileNameMap[Image_32X32_32bit_F_Tif] = fileFolder + AZStd::string("32x32_32bit_f.tif"); - m_imagFileNameMap[Image_200X200_RGB8_Jpg] = fileFolder + AZStd::string("200x200_24bit.jpg"); - m_imagFileNameMap[Image_512X288_RGB8_Tga] = fileFolder + AZStd::string("512x288_24bit.tga"); - m_imagFileNameMap[Image_1024X1024_RGB8_Tif] = fileFolder + AZStd::string("1024x1024_24bit.tif"); - m_imagFileNameMap[Image_UpperCase_Tga] = fileFolder + AZStd::string("uppercase.TGA"); - m_imagFileNameMap[Image_512x512_Normal_Tga] = fileFolder + AZStd::string("512x512_RGB_N.tga"); - m_imagFileNameMap[Image_128x128_Transparent_Tga] = fileFolder + AZStd::string("128x128_RGBA8.tga"); - m_imagFileNameMap[Image_237x177_RGB_Jpg] = fileFolder + AZStd::string("237x177_RGB.jpg"); - m_imagFileNameMap[Image_GreyScale_Png] = fileFolder + AZStd::string("greyscale.png"); - m_imagFileNameMap[Image_BlackWhite_Png] = fileFolder + AZStd::string("BlackWhite.png"); - m_imagFileNameMap[Image_TerrainHeightmap_Bt] = fileFolder + AZStd::string("TerrainHeightmap.bt"); - } - -public: - //helper function to save an image object to a file through QtImage - static void SaveImageToFile(const IImageObjectPtr imageObject, const AZStd::string imageName, AZ::u32 maxMipCnt = 100) - { -#ifndef DEBUG_OUTPUT_IMAGES - return; -#endif - if (imageObject == nullptr) - { - return; - } - - //create the directory if it's not exist - const AZStd::string outputDir = AZ::Test::GetEngineRootPath() + "/Gems/ImageProcessing/Code/Tests/TestAssets/Output/"; - QDir dir(outputDir.c_str()); - if (!dir.exists()) - { - dir.mkpath("."); - } - - //save origin file pixel format so we could use it to generate name later - EPixelFormat originPixelFormat = imageObject->GetPixelFormat(); - - //convert to RGBA8 before can be exported. - ImageToProcess imageToProcess(imageObject); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - - IImageObjectPtr finalImage = imageToProcess.Get(); - - //for each mipmap - for (uint32 mip = 0; mip < finalImage->GetMipCount() && mip < maxMipCnt; mip++) - { - uint8* imageBuf; - uint32 pitch; - finalImage->GetImagePointer(mip, imageBuf, pitch); - uint32 width = finalImage->GetWidth(mip); - uint32 height = finalImage->GetHeight(mip); - - //generate file name - char filePath[2048]; - azsprintf(filePath, "%s%s_%s_mip%d_%dx%d.png", outputDir.c_str(), imageName.c_str() - , CPixelFormats::GetInstance().GetPixelFormatInfo(originPixelFormat)->szName - , mip, width, height); - - QImage qimage(imageBuf, width, height, pitch, QImage::Format_RGBA8888); - qimage.save(filePath); - } - } - - static bool GetComparisonResult(IImageObjectPtr image1, IImageObjectPtr image2, QString& output) - { - bool isImageLoaded = true; - bool isDifferent = false; - - if (image1 == nullptr) - { - isImageLoaded = false; - output += ",Image 1 does not exist. "; - } - - if (image2 == nullptr) - { - isImageLoaded = false; - output += ",Image 2 does not exist. "; - } - - if (!isImageLoaded) - { - return (!image1 && !image2) ? false: true; - } - - // Mip - int mip1 = image1->GetMipCount(); - int mip2 = image2->GetMipCount(); - int mipDiff = abs(mip1 - mip2); - - isDifferent |= mipDiff != 0; - - // Format - EPixelFormat format1 = image1->GetPixelFormat(); - EPixelFormat format2 = image2->GetPixelFormat(); - - isDifferent |= (format1 != format2); - - // Flag - AZ::u32 flag1 = image1->GetImageFlags(); - AZ::u32 flag2 = image2->GetImageFlags(); - - isDifferent |= (flag1 != flag2); - - // Size - int memSize1 = image1->GetTextureMemory(); - int memSize2 = image2->GetTextureMemory(); - int memDiff = abs(memSize1 - memSize2); - - isDifferent |= memDiff != 0; - - // Error - float error = GetErrorBetweenImages(image1, image2); - - static float EPSILON = 0.000001f; - isDifferent |= abs(error) >= EPSILON; - - output += QString(",%1/%2,%3,%4/%5,%6/%7,").arg(QString::number(mip1,'f',1), QString::number(mip2,'f',1), QString::number(mipDiff), - QString(ImageProcessingEditor::EditorHelper::s_PixelFormatString[format1]), - QString(ImageProcessingEditor::EditorHelper::s_PixelFormatString[format2]), - QString::number(flag1, 16), QString::number(flag2, 16)); - - output += QString("%1/%2,%3,%4").arg(QString(ImageProcessingEditor::EditorHelper::GetFileSizeString(memSize1).c_str()), - QString(ImageProcessingEditor::EditorHelper::GetFileSizeString(memSize2).c_str()), - QString(ImageProcessingEditor::EditorHelper::GetFileSizeString(memDiff).c_str()), - QString::number(error, 'f', 8)); - - - return isDifferent; - } - - - static bool CompareDDSImage(const QString& imagePath1, const QString& imagePath2, QString& output) - { - IImageObjectPtr image1, alphaImage1, image2, alphaImage2; - - - image1 = IImageObjectPtr(LoadImageFromDdsFile(imagePath1.toUtf8().constData())); - if (image1 && image1->HasImageFlags(EIF_AttachedAlpha)) - { - if (image1->HasImageFlags(EIF_Splitted)) - { - alphaImage1 = IImageObjectPtr(LoadImageFromDdsFile(QString(imagePath1 + ".a").toUtf8().constData())); - } - else - { - alphaImage1 = IImageObjectPtr(LoadAttachedImageFromDdsFile(imagePath1.toUtf8().constData(), image1)); - } - } - - image2 = IImageObjectPtr(LoadImageFromDdsFile(imagePath2.toUtf8().constData())); - if (image2 && image2->HasImageFlags(EIF_AttachedAlpha)) - { - if (image2->HasImageFlags(EIF_Splitted)) - { - alphaImage2 = IImageObjectPtr(LoadImageFromDdsFile(QString(imagePath2 + ".a").toUtf8().constData())); - } - else - { - alphaImage2 = IImageObjectPtr(LoadAttachedImageFromDdsFile(imagePath2.toUtf8().constData(), image2)); - } - } - - if (!image1 && !image2) - { - output += "Cannot load both image file! "; - return false; - } - bool isDifferent = false; - - isDifferent = GetComparisonResult(image1, image2, output); - - - QFileInfo fi(imagePath1); - AZStd::string imageName = fi.baseName().toUtf8().constData(); - SaveImageToFile(image1, imageName + "_new"); - SaveImageToFile(image2, imageName + "_old"); - - if (alphaImage1 || alphaImage2) - { - isDifferent |= GetComparisonResult(alphaImage1, alphaImage2, output); - } - - return isDifferent; - } -}; - -// test CPixelFormats related functions -TEST_F(ImageProcessingTest, TestPixelFormats) -{ - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - - //verify names which was used for legacy rc.ini - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC7t") == ePixelFormat_BC7t); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("ETC2A") == ePixelFormat_ETC2a); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("PVRTC4") == ePixelFormat_PVRTC4); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC1") == ePixelFormat_BC1); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("ETC2") == ePixelFormat_ETC2); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC1a") == ePixelFormat_BC1a); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC3") == ePixelFormat_BC3); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC7") == ePixelFormat_BC7); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC5s") == ePixelFormat_BC5s); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("EAC_RG11") == ePixelFormat_EAC_RG11); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC4") == ePixelFormat_BC4); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("EAC_R11") == ePixelFormat_EAC_R11); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("A8R8G8B8") == ePixelFormat_R8G8B8A8); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC6UH") == ePixelFormat_BC6UH); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("R9G9B9E5") == ePixelFormat_R9G9B9E5); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("X8R8G8B8") == ePixelFormat_R8G8B8X8); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("A16B16G16R16F") == ePixelFormat_R16G16B16A16F); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("G8R8") == ePixelFormat_R8G8); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("G16R16") == ePixelFormat_R16G16); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("G16R16F") == ePixelFormat_R16G16F); - - //some legacy format need to be mapping to new format. - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("DXT1") == ePixelFormat_BC1); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("DXT5") == ePixelFormat_BC3); - - //calculate mipmap count. no cubemap support at this moment - - //for all the non-compressed textures, if there minimum required texture size is 1x1 - for (uint32 i = 0; i < ePixelFormat_Count; i++) - { - EPixelFormat pixelFormat = (EPixelFormat)i; - if (pixelFormats.IsPixelFormatUncompressed(pixelFormat)) - { - //square, power of 2 sizes for uncompressed format which minimum required size is 1x1 - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 128) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 64, 64) == 7); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 4, 4) == 3); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 2, 2) == 2); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 1, 1) == 1); - - //non-square, power of 2 sizes for uncompressed format which minimum required size is 1x1 - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 64) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 32) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 32, 2) == 6); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 2, 1) == 2); - - //Non power of 2 sizes for uncompressed format which minimum required size is 1x1 - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 64) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 32) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 32, 2) == 6); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 2, 1) == 2); - } - } - - //check function IsImageSizeValid && EvaluateImageDataSize function - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 2, 1, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 4, 4, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 16, 16, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 16, 32, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 34, 34, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 256, 256, false) == true); - - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 2, 1, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 16, 16, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 16, 32, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 34, 34, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 256, 256, false) == true); - - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 2, 1, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 16, 16, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 16, 32, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 34, 34, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 256, 256, false) == true); - - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 2, 1, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 16, 16, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 16, 32, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 34, 34, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 256, 256, false) == true); -} - -// test image file loading -TEST_F(ImageProcessingTest, TestImageLoaders) -{ - //file extention support for different loader - ASSERT_TRUE(IsExtensionSupported("jpg") == true); - ASSERT_TRUE(IsExtensionSupported("JPG") == true); - ASSERT_TRUE(IsExtensionSupported(".JPG") == false); - ASSERT_TRUE(IsExtensionSupported("tga") == true); - ASSERT_TRUE(IsExtensionSupported("TGA") == true); - ASSERT_TRUE(IsExtensionSupported("tif") == true); - ASSERT_TRUE(IsExtensionSupported("tiff") == true); - ASSERT_TRUE(IsExtensionSupported("bt") == true); - - IImageObjectPtr img; - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_1024X1024_RGB8_Tif])); - - ASSERT_TRUE(img != nullptr); - ASSERT_TRUE(img->GetWidth(0) == 1024); - ASSERT_TRUE(img->GetHeight(0) == 1024); - ASSERT_TRUE(img->GetMipCount() == 1); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8X8); - - //load png - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_20X16_RGBA8_Png])); - ASSERT_TRUE(img != nullptr); - ASSERT_TRUE(img->GetWidth(0) == 20); - ASSERT_TRUE(img->GetHeight(0) == 16); - ASSERT_TRUE(img->GetMipCount() == 1); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - //load jpg - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_200X200_RGB8_Jpg])); - ASSERT_TRUE(img->GetWidth(0) == 200); - ASSERT_TRUE(img->GetHeight(0) == 200); - ASSERT_TRUE(img->GetMipCount() == 1); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - //tga - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_512X288_RGB8_Tga])); - ASSERT_TRUE(img->GetWidth(0) == 512); - ASSERT_TRUE(img->GetHeight(0) == 288); - ASSERT_TRUE(img->GetMipCount() == 1); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - //image with upper case extension - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_UpperCase_Tga])); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - //16bits float tif - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_32X32_16bit_F_Tif])); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R16G16B16A16F); - - //32bits float tif - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_32X32_32bit_F_Tif])); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R32G32B32A32F); - - //BT - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_TerrainHeightmap_Bt])); - ASSERT_TRUE(img != nullptr); - EXPECT_EQ(img->GetWidth(0), 128); - EXPECT_EQ(img->GetHeight(0), 128); - EXPECT_EQ(img->GetMipCount(), 1); - EXPECT_EQ(img->GetPixelFormat(), ePixelFormat_R32F); -} - -TEST_F(ImageProcessingTest, PresetSettingCopyAssignmentOperatorOverload_WithDynamicallyAllocatedSettings_ReturnsTwoSeparateAllocations) -{ - PresetSettings presetSetting; - presetSetting.m_mipmapSetting = AZStd::unique_ptr(new MipmapSettings()); - presetSetting.m_cubemapSetting = AZStd::unique_ptr(new CubemapSettings()); - - // Explicit invoke assignment operator by splitting the operation into two lines. - PresetSettings otherPresetSetting; - otherPresetSetting = presetSetting; - - EXPECT_NE(otherPresetSetting.m_cubemapSetting, presetSetting.m_cubemapSetting); - EXPECT_NE(otherPresetSetting.m_mipmapSetting, presetSetting.m_mipmapSetting); -} - -TEST_F(ImageProcessingTest, PresetSettingCopyConstructor_WithDynamicallyAllocatedSettings_ReturnsTwoSeparateAllocations) -{ - PresetSettings presetSetting; - presetSetting.m_mipmapSetting = AZStd::unique_ptr(new MipmapSettings()); - presetSetting.m_cubemapSetting = AZStd::unique_ptr(new CubemapSettings()); - - PresetSettings otherPresetSetting(presetSetting); - - EXPECT_NE(otherPresetSetting.m_cubemapSetting, presetSetting.m_cubemapSetting); - EXPECT_NE(otherPresetSetting.m_mipmapSetting, presetSetting.m_mipmapSetting); -} - -TEST_F(ImageProcessingTest, PresetSettingEqualityOperatorOverload_WithIdenticalSettings_ReturnsEquivalent) -{ - PresetSettings presetSetting; - PresetSettings otherPresetSetting(presetSetting); - - EXPECT_TRUE(otherPresetSetting == presetSetting); -} - -TEST_F(ImageProcessingTest, PresetSettingEqualityOperatorOverload_WithDifferingDynamicallyAllocatedSettings_ReturnsUnequivalent) -{ - PresetSettings presetSetting; - presetSetting.m_mipmapSetting = AZStd::unique_ptr(new MipmapSettings()); - presetSetting.m_mipmapSetting->m_type = MipGenType::gaussian; - - PresetSettings otherPresetSetting(presetSetting); - otherPresetSetting.m_mipmapSetting = AZStd::unique_ptr(new MipmapSettings()); - otherPresetSetting.m_mipmapSetting->m_type = MipGenType::blackmanHarris; - - EXPECT_FALSE(otherPresetSetting == presetSetting); - -} - -//this test is to test image data won't be lost between uncompressed formats (for low to high precision or same precision) -TEST_F(ImageProcessingTest, TestConvertFormatUncompressed) -{ - //source image - IImageObjectPtr srcImage(LoadImageFromFile(m_imagFileNameMap[Image_200X200_RGB8_Jpg])); - ImageToProcess imageToProcess(srcImage); - - //image pointers to hold precessed images for comparison - IImageObjectPtr dstImage1, dstImage2, dstImage3, dstImage4, dstImage5; - - //compare four channels pixel formats - //we will convert to target format then convert back to RGBX8 so they can compare to easy other - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8A8); - dstImage1 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16G16B16A16); - ASSERT_FALSE(srcImage->CompareImage(imageToProcess.Get())); //this is different than source image - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8A8); - dstImage2 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16G16B16A16F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8A8); - dstImage3 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R32G32B32A32F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8A8); - dstImage4 = imageToProcess.Get(); - - ASSERT_TRUE(dstImage2->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage3->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage4->CompareImage(dstImage1)); - - // three channels formats - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage1 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R9G9B9E5); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage2 = imageToProcess.Get(); - - ASSERT_TRUE(dstImage2->CompareImage(dstImage1)); - - //convert image to all one channel formats then convert them back to RGBX8 for comparison - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage1 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage2 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage3 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R32F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage4 = imageToProcess.Get(); - - ASSERT_TRUE(dstImage2->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage3->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage4->CompareImage(dstImage1)); - - //convert image to all two channels formats then convert them back to RGBX8 for comparison - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage1 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16G16); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage2 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16G16F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage3 = imageToProcess.Get(); - - ASSERT_TRUE(dstImage2->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage3->CompareImage(dstImage1)); -} - -TEST_F(ImageProcessingTest, DISABLED_TestConvertPVRTC) -{ - //load builder presets - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - AZStd::vector outPaths; - AZStd::string inputFile = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif"; - const AZStd::string outputFolder = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/temp/"; - ImageConvertProcess* process = CreateImageConvertProcess(inputFile, outputFolder, "ios", m_context.get()); - if (process != nullptr) - { - //the process can be stopped if the job is cancelled or the worker is shutting down - int step = 0; - while (!process->IsFinished()) - { - process->UpdateProcess(); - step++; - } - - //get process result - ASSERT_TRUE(process->IsSucceed()); - - SaveImageToFile(process->GetOutputImage(), "rgb", 10); - SaveImageToFile(process->GetOutputAlphaImage(), "alpha", 10); - - process->GetAppendOutputFilePaths(outPaths); - delete process; - } - - //ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, "ios", m_context.get())); - -} - -TEST_F(ImageProcessingTest, DISABLED_TestConvertFormat) -{ - EPixelFormat pixelFormat; - IImageObjectPtr srcImage; - - //images to be tested - static const int imageCount = 5; - ImageFeature images[imageCount] = { - Image_20X16_RGBA8_Png, - Image_32X32_16bit_F_Tif, - Image_32X32_32bit_F_Tif , - Image_512x512_Normal_Tga , - Image_128x128_Transparent_Tga }; - - for (int imageIdx = 0; imageIdx < imageCount; imageIdx++) - { - //get image's name and it will be used for output file name - QFileInfo fi(m_imagFileNameMap[images[imageIdx]].c_str()); - AZStd::string imageName = fi.baseName().toUtf8().constData(); - - srcImage = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[images[imageIdx]])); - ImageToProcess imageToProcess(srcImage); - - //test ConvertFormat functions againest all the pixel formats - for (pixelFormat = ePixelFormat_R8G8B8A8; pixelFormat < ePixelFormat_Unknown;) - { - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormat(pixelFormat); - - ASSERT_TRUE(imageToProcess.Get()); - - //if the format is compressed and there is no compressor for it, it won't be converted to the expected format - if (ICompressor::FindCompressor(pixelFormat, true) == nullptr - && !CPixelFormats::GetInstance().IsPixelFormatUncompressed(pixelFormat)) - { - ASSERT_TRUE(imageToProcess.Get()->GetPixelFormat() != pixelFormat); - } - else - { - //validate the size and it may not working for some uncompressed format - if (!CPixelFormats::GetInstance().IsImageSizeValid( - pixelFormat, srcImage->GetWidth(0), srcImage->GetHeight(0), false)) - { - ASSERT_TRUE(imageToProcess.Get()->GetPixelFormat() != pixelFormat); - } - else - { - ASSERT_TRUE(imageToProcess.Get()->GetPixelFormat() == pixelFormat); - - //save the image to a file so we can check the visual result - SaveImageToFile(imageToProcess.Get(), imageName, 1); - - //convert back to an uncompressed format and expect it will be successful - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - ASSERT_TRUE(imageToProcess.Get()->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - } - } - - //next pixel format - pixelFormat = EPixelFormat(pixelFormat + 1); - } - } -} - -TEST_F(ImageProcessingTest, DISABLED_TestImageFilter) -{ - AZStd::string testImageFile = m_imagFileNameMap[Image_1024X1024_RGB8_Tif]; - IImageObjectPtr srcImage, dstImage; - - QFileInfo fi(testImageFile.c_str()); - AZStd::string imageName = fi.baseName().toUtf8().constData(); - - //load src image and convert it to RGBA32F - srcImage = IImageObjectPtr(LoadImageFromFile(testImageFile)); - ImageToProcess imageToProcess(srcImage); - imageToProcess.ConvertFormat(ePixelFormat_R32G32B32A32F); - srcImage = imageToProcess.Get(); - - //create dst image with same size and mipmaps - dstImage = IImageObjectPtr( - IImageObject::CreateImage(srcImage->GetWidth(0), srcImage->GetHeight(0), 3, - ePixelFormat_R32G32B32A32F)); - - //for each filters - const std::array, 7> allFilters = - { - { - {MipGenType::point, "point"}, - {MipGenType::box, "box" }, - { MipGenType::triangle, "triangle" }, - { MipGenType::quadratic, "Quadratic" }, - { MipGenType::blackmanHarris, "blackmanHarris" }, - { MipGenType::kaiserSinc, "kaiserSinc" } - } - }; - - for (std::pair filter : allFilters) - { - for (uint mip = 0; mip < dstImage->GetMipCount(); mip++) - { - FilterImage(filter.first, MipGenEvalType::sum, - 0, 0, imageToProcess.Get(), 0, dstImage, mip, nullptr, nullptr); - } - SaveImageToFile(dstImage, imageName + "_" + filter.second); - } -} - -TEST_F(ImageProcessingTest, TestColorSpaceConversion) -{ - IImageObjectPtr srcImage(LoadImageFromFile(m_imagFileNameMap[Image_GreyScale_Png])); - - ImageToProcess imageToProcess(srcImage); - imageToProcess.GammaToLinearRGBA32F(true); - SaveImageToFile(imageToProcess.Get(), "GammaTolinear_DeGamma", 1); - imageToProcess.LinearToGamma(); - SaveImageToFile(imageToProcess.Get(), "LinearToGamma_DeGamma", 1); -} - -//This function can be used to modify some value in the builder setting and keep all presets uuid then save back to setting file -//It will only change the file if the file was checked out -TEST_F(ImageProcessingTest, DISABLED_ModifyBuilderSetting) -{ - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - QFileInfo fileInfo(buiderSetting.c_str()); - if (fileInfo.isWritable()) - { - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - BuilderSettingManager::Instance()->WriteBuilderSettings(buiderSetting, m_context.get()); - } -} - -TEST_F(ImageProcessingTest, VerifyRestrictedPlatform) -{ - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - PlatformNameList platforms = BuilderSettingManager::Instance()->GetPlatformList(); - -#ifndef AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - ASSERT_TRUE(platforms.size() == 4); -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -} - -TEST_F(ImageProcessingTest, DISABLED_TestCubemap) -{ - //load builder presets - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - const AZStd::string outputFolder = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/temp/"; - AZStd::string inputFile; - AZStd::vector outPaths; - - inputFile = m_engineRoot + "/Assets/Engine/EngineAssets/Shading/defaultProbe_cm.tif"; - - IImageObjectPtr srcImage(LoadImageFromFile(inputFile)); - ImageToProcess imageToProcess(srcImage); - imageToProcess.ConvertCubemapLayout(CubemapLayoutVertical); - SaveImageToFile(imageToProcess.Get(), "Vertical", 100); - imageToProcess.ConvertCubemapLayout(CubemapLayoutHorizontalCross); - SaveImageToFile(imageToProcess.Get(), "HorizontalCross", 100); - imageToProcess.ConvertCubemapLayout(CubemapLayoutVerticalCross); - SaveImageToFile(imageToProcess.Get(), "VerticalCross", 100); - imageToProcess.ConvertCubemapLayout(CubemapLayoutHorizontal); - SaveImageToFile(imageToProcess.Get(), "VerticalHorizontal", 100); - - ImageConvertProcess* process = CreateImageConvertProcess(inputFile, outputFolder, "pc"); - - if (process != nullptr) - { - int step = 0; - while (!process->IsFinished()) - { - process->UpdateProcess(); - step++; - char name[100]; - azsprintf(name, "cubemap_%d", step); - //SaveImageToFile(process->GetOutputImage(), name, 1); - } - - //get process result - ASSERT_TRUE(process->IsSucceed()); - - SaveImageToFile(process->GetOutputImage(), "cubemap", 100); - SaveImageToFile(process->GetOutputDiffCubemap(), "diffCubemap", 100); - SaveImageToFile(process->GetOutputAlphaImage(), "alpha", 1); - process->GetAppendOutputFilePaths(outPaths); - - delete process; - } -} - -//test image conversion for builder -TEST_F(ImageProcessingTest, DISABLED_TestBuilderImageConvertor) -{ - AZStd::string oldCacheFolder = "E:/Javelin_old_tex_cache/textures"; - AZStd::string srcFolder = "E:/Javelin_NWLYDev/dev/Assets/Textures"; - - //load builder presets - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - const AZStd::string outputFolder = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/temp/"; - AZStd::string inputFile; - AZStd::vector outPaths; - - inputFile = srcFolder + "/terrain/cry/detail/grass_with_stones_displ.tif"; - inputFile = m_imagFileNameMap[Image_128x128_Transparent_Tga]; - AZStd::string oldFile = oldCacheFolder + "/terrain/cry/detail/grass_with_stones_displ.dds"; - ImageConvertProcess* process = CreateImageConvertProcess(inputFile, outputFolder, "pc", m_context.get()); - - if (process != nullptr) - { - //the process can be stopped if the job is cancelled or the worker is shutting down - int step = 0; - while (!process->IsFinished() ) - { - process->UpdateProcess(); - step++; - } - - //get process result - ASSERT_TRUE(process->IsSucceed()); - - SaveImageToFile(process->GetOutputImage(), "rgb", 10); - SaveImageToFile(process->GetOutputAlphaImage(), "alpha", 10); - - process->GetAppendOutputFilePaths(outPaths); - - QString output; - //CompareDDSImage(outPaths[0].c_str(), oldFile.c_str(), output); - delete process; - } - - - -/* //test cases for different presets - //ddna - inputFile = "../AutomatedTesting/Objects/ParticleAssets/ShowRoom/showroom_pipe_blue_001_m_ddna.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //cubemap - inputFile = "../AutomatedTesting/Levels/Samples/Camera_Sample/Cubemaps/noon_cm.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //albedo - inputFile = "../AutomatedTesting/Objects/ParticleAssets/ShowRoom/showroom_steel_brushed_001_diff.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - inputFile = "../AutomatedTesting/materials/pbs_reference/light_leather_diff.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - inputFile = "../Gems/PBSreferenceMaterials/Assets/materials/pbs_reference/brushed_steel.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //ui ReferenceImage auto preset - inputFile = "../Bems/UiBasics/Assets/UI/Textures/Prefab/textinput_normal.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //albedo with generic alpha auto preset - inputFile = "../AutomatedTesting/textures/GettingStartedTextures/LY_Logo_Beaver.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //color chart - inputFile = "../Gems/PBSreferenceMaterials/Assets/materials/pbs_reference/colorcharts/debug_contrast_low_cch.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); -*/ -} - - -//test image loading function for output dds files -TEST_F(ImageProcessingTest, DISABLED_TestLoadDdsImage) -{ - IImageObjectPtr originImage, alphaImage; - AZStd::string inputFolder = m_engineRoot + "/Cache/AutomatedTesting/pc/automatedtesting/engineassets/texturemsg/"; - AZStd::string inputFile; - - inputFile = "E:/Javelin_NWLYDev/dev/Cache/Assets/pc/assets/textures/blend_maps/moss/jav_moss_ddn.dds"; - - IImageObjectPtr newImage = IImageObjectPtr(LoadImageFromDdsFile(inputFile)); - if (newImage->HasImageFlags(EIF_AttachedAlpha)) - { - if (newImage->HasImageFlags(EIF_Splitted)) - { - alphaImage = IImageObjectPtr(LoadImageFromDdsFile(inputFile+".a")); - - } - else - { - alphaImage = IImageObjectPtr(LoadAttachedImageFromDdsFile(inputFile, newImage)); - } - } - - SaveImageToFile(newImage, "jav_moss_ddn", 10); -} - -TEST_F(ImageProcessingTest, DISABLED_CompareOutputImage) -{ - AZStd::string curretTextureFolder = m_engineRoot + "/TestAssets/TextureAssets/assets_new/textures"; - AZStd::string oldTextureFolder = m_engineRoot + "/TestAssets/TextureAssets/assets_old/textures"; - bool outputOnlyDifferent = false; - QDirIterator it(curretTextureFolder.c_str(), QStringList() << "*.dds", QDir::Files, QDirIterator::Subdirectories); - QFile f("../texture_comparison_output.csv"); - f.open(QIODevice::ReadWrite | QIODevice::Truncate); - // Write a header for csv file - f.write("Texture Name, Path, Mip new/old, MipDiff, Format new/old, Flag new/old, MemSize new/old, MemDiff, Error, AlphaMip new/old, AlphaMipDiff, AlphaFormat new/old, AlphaFlag new/old, AlphaMemSize new/old, AlphaMemDiff, AlphaError\r\n"); - int i = 0; - while (it.hasNext()) - { - i++; - it.next(); - - QString fileName = it.fileName(); - QString newFilePath = it.filePath(); - QString sharedPath = QString(newFilePath).remove(curretTextureFolder.c_str()); - QString oldFilePath = QString(oldTextureFolder.c_str()) + sharedPath; - QString output; - if (QFile::exists(oldFilePath)) - { - bool isDifferent = CompareDDSImage(newFilePath, oldFilePath, output); - if (outputOnlyDifferent && !isDifferent) - { - continue; - } - else - { - f.write(fileName.toUtf8().constData()); - f.write(","); - f.write(sharedPath.toUtf8().constData()); - f.write(output.toUtf8().constData()); - } - } - else - { - f.write(fileName.toUtf8().constData()); - f.write(","); - f.write(sharedPath.toUtf8().constData()); - output += ",No old file for comparison!"; - f.write(output.toUtf8().constData()); - } - f.write("\r\n"); - } - f.close(); -} - - -TEST_F(ImageProcessingTest, EditorTextureSettingTest) -{ - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - auto TestFunc = [](const AZStd::string& textureFilepath, bool isCubemap) { - - ImageProcessingEditor::EditorTextureSetting setting(textureFilepath); - const TextureSettings& textSettings = setting.m_settingsMap["pc"]; - auto& presetId = textSettings.m_preset; - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(presetId); - AZ::u32 arrayCount = 1; - AZ::u32 originalWidth = setting.m_img->GetWidth(0); - AZ::u32 originalHeight = setting.m_img->GetHeight(0); - - if (isCubemap) - { - ASSERT_TRUE(preset->m_cubemapSetting != nullptr); - CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(setting.m_img); - ASSERT_TRUE(srcCubemap != nullptr); - - originalWidth = srcCubemap->GetFaceSize(); - originalHeight = srcCubemap->GetFaceSize(); - arrayCount = 6; - - delete srcCubemap; - } - - // Test GetFinalInfoForTextureOnPlatform function - { - for (AZ::u32 reduce = 0; reduce < 15; reduce++) - { - ImageProcessingEditor::ResolutionInfo info; - if (setting.GetFinalInfoForTextureOnPlatform("pc", reduce, info)) - { - ASSERT_TRUE(info.reduce <= reduce); - ASSERT_TRUE(info.arrayCount == arrayCount); - ASSERT_TRUE(info.width == AZStd::max(originalWidth >> info.reduce, 1)); - ASSERT_TRUE(info.height == AZStd::max(originalHeight >> info.reduce, 1)); - if (preset->m_maxTextureSize > 0) - { - ASSERT_TRUE(info.width <= preset->m_maxTextureSize); - ASSERT_TRUE(info.height <= preset->m_maxTextureSize); - } - if (preset->m_minTextureSize > 0) - { - ASSERT_TRUE(info.width >= preset->m_minTextureSize); - ASSERT_TRUE(info.height >= preset->m_minTextureSize); - } - } - } - } - - // Test GetResolutionInfo function - { - AZ::u32 minReduce, maxReduce; - auto resolutions = setting.GetResolutionInfo("pc", minReduce, maxReduce); - ASSERT_TRUE(resolutions.size() > 0); - ASSERT_TRUE(resolutions.size() == maxReduce - minReduce + 1); - for (auto& info : resolutions) - { - ASSERT_TRUE(info.reduce >= minReduce); - ASSERT_TRUE(info.reduce <= maxReduce); - ASSERT_TRUE(info.arrayCount == arrayCount); - ASSERT_TRUE(info.width == AZStd::max(originalWidth >> info.reduce, 1)); - ASSERT_TRUE(info.height == AZStd::max(originalHeight >> info.reduce, 1)); - ASSERT_TRUE(info.width >= 1); - ASSERT_TRUE(info.height >= 1); - } - } - - // Test GetResolutionInfo function - { - auto resolutions = setting.GetResolutionInfoForMipmap("pc"); - for (auto& info : resolutions) - { - ASSERT_TRUE(info.arrayCount == arrayCount); - ASSERT_TRUE(info.width == AZStd::max(originalWidth >> info.reduce, 1)); - ASSERT_TRUE(info.height == AZStd::max(originalHeight >> info.reduce, 1)); - ASSERT_TRUE(info.width >= 1); - ASSERT_TRUE(info.height >= 1); - } - setting.m_settingsMap["pc"].m_sizeReduceLevel += 1; - auto reducedResolutions = setting.GetResolutionInfoForMipmap("pc"); - ASSERT_TRUE(resolutions.size() >= reducedResolutions.size()); - } - }; - - // For cubemap texture - AZStd::string textureFilePath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif"; - TestFunc(textureFilePath, true); - - // For albedo texture - textureFilePath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif"; - TestFunc(textureFilePath, false); -} - -class ImageProcessingSerializationTest - : public ScopedAllocatorSetupFixture -{ -protected: - AZStd::unique_ptr m_context; - AZStd::string m_engineRoot; - - void SetUp() override - { - BuilderSettingManager::CreateInstance(); - - m_context = AZStd::make_unique(); - BuilderPluginComponent::Reflect(m_context.get()); - AZ::DataPatch::Reflect(m_context.get()); - - // Startup default local FileIO (hits OSAllocator) if not already setup. - if (AZ::IO::FileIOBase::GetInstance() == nullptr) - { - AZ::IO::FileIOBase::SetInstance(aznew AZ::IO::LocalFileIO()); - } - { - int argc = 0; - char** argv = nullptr; - QCoreApplication app(argc, argv); - m_engineRoot = AZ::Test::GetEngineRootPath(); - } - } - - void TearDown() override - { - delete AZ::IO::FileIOBase::GetInstance(); - AZ::IO::FileIOBase::SetInstance(nullptr); - - m_context.reset(); - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - } -}; - -TEST_F(ImageProcessingSerializationTest, DISABLED_LoadBuilderSettingsFromRC_SerializingLegacyDataIn_InvalidFiles) -{ - AZStd::string filepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/rc.ini_Missing"; - ASSERT_FALSE(BuilderSettingManager::Instance()->LoadBuilderSettingsFromRC(filepath).IsSuccess()); - - filepath = m_engineRoot + "/Code/Tools/RC/Config/rc/rc.ini"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettingsFromRC(filepath); - ASSERT_TRUE(outcome.IsSuccess()); - - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - - // Load legacy texture settings from file that not exists - TextureSettings legacyTextureSetting; - AZStd::string notExistingFile = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/NotExistingFile"; - auto legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile("", notExistingFile, legacyTextureSetting, m_context.get()); - EXPECT_FALSE(legacyLoadOutcome.IsSuccess()); - - // Load legacy texture settings from file whose format is wrong - - // Wrong override data - AZStd::string wrongFormatFile = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/invalid.exportsettings"; - AZStd::string wrongFormatContent = "/autooptimizefile=0 /preset=Diffuse_highQ /reduce=\"es3:0,randomdata,ios:3,osx_gl:0,pc:4\" /ser=0"; - if (AZ::IO::FileIOBase::GetInstance()->Open(wrongFormatFile.c_str(), AZ::IO::OpenMode::ModeWrite, fileHandle)) - { - AZ::IO::FileIOBase::GetInstance()->Write(fileHandle, wrongFormatContent.c_str(), wrongFormatContent.size()); - AZ::IO::FileIOBase::GetInstance()->Close(fileHandle); - } - else - { - EXPECT_TRUE(false); - } - legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile("", wrongFormatFile, legacyTextureSetting, m_context.get()); - EXPECT_FALSE(legacyLoadOutcome.IsSuccess()); - - // Wrong format data - wrongFormatContent = "//// ,&*&#$@#/preset=Diffuse_highQ / //reduce=0 /ser=0"; - if (AZ::IO::FileIOBase::GetInstance()->Open(wrongFormatFile.c_str(), AZ::IO::OpenMode::ModeWrite, fileHandle)) - { - AZ::IO::FileIOBase::GetInstance()->Write(fileHandle, wrongFormatContent.c_str(), wrongFormatContent.size()); - AZ::IO::FileIOBase::GetInstance()->Close(fileHandle); - } - legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile("", wrongFormatFile, legacyTextureSetting, m_context.get()); - EXPECT_FALSE(legacyLoadOutcome.IsSuccess()); - - AZ::IO::FileIOBase::GetInstance()->Remove(wrongFormatFile.c_str()); -} - - -TEST_F(ImageProcessingSerializationTest, TextureSettingReflect_SerializingLegacyDataIn_EmbeddedSetting) -{ - AZStd::string buiderSetting(m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"); - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - // Load legacy texture settings - TextureSettings legacyTextureSetting; - AZStd::string textureFilepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif"; - AZStd::string textureSetting = LoadEmbeddedSettingFromFile(textureFilepath); - EXPECT_FALSE(textureSetting.empty()); - - auto legacyLoadOutcome = TextureSettings::LoadLegacyTextureSetting(textureFilepath, textureSetting, legacyTextureSetting, m_context.get()); - // Ensure we loaded and parsed the texture settings correctly. - EXPECT_TRUE(legacyLoadOutcome.IsSuccess()); - EXPECT_EQ(legacyTextureSetting.m_preset, BuilderSettingManager::Instance()->GetPresetIdFromName("LensOptics")); -} - -TEST_F(ImageProcessingSerializationTest, TextureSettingReflect_SerializingLegacyDataIn_CommonAndPlatformSpecificSettingsAreSerializedCorrectly) -{ - AZStd::string buiderSetting(m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"); - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - // Load legacy texture settings - TextureSettings legacyTextureSetting; - AZStd::string textureFilepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif"; - auto legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile(textureFilepath, - textureFilepath + TextureSettings::legacyExtensionName, legacyTextureSetting, m_context.get()); - - // Ensure we loaded and parsed the texture settings correctly. - EXPECT_TRUE(legacyLoadOutcome.IsSuccess()); - EXPECT_EQ(legacyTextureSetting.m_mipGenType, MipGenType::kaiserSinc); - EXPECT_EQ(legacyTextureSetting.m_preset, BuilderSettingManager::Instance()->GetPresetIdFromName("Albedo")); - EXPECT_EQ(legacyTextureSetting.m_mipAlphaAdjust[0], 62); - EXPECT_EQ(legacyTextureSetting.m_suppressEngineReduce, false); - - // Ensure overrides are properly parsed as well. - { - TextureSettings iosTextureSettings; - auto iosOutcome = TextureSettings::GetPlatformSpecificTextureSetting("ios", legacyTextureSetting, iosTextureSettings, m_context.get()); - EXPECT_TRUE(iosOutcome.IsSuccess()); - EXPECT_EQ(iosTextureSettings.m_sizeReduceLevel, 3); - } -} - -TEST_F(ImageProcessingSerializationTest, TextureSettingReflect_SerializingModernDataOutThenIn_PreSerializedAndPostSerializedDataIsEquivalent) -{ - AZStd::string buiderSetting(m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"); - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - // Load legacy texture settings - TextureSettings legacyTextureSetting; - AZStd::string textureFilepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif"; - auto legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile(textureFilepath, - textureFilepath+TextureSettings::legacyExtensionName, legacyTextureSetting, m_context.get()); - - // Let's make modifications to the loaded texture setting - // Modification1: Set reduce level for common settings. - // Modification2: Set reduce level for iOS-override settings. - legacyTextureSetting.m_sizeReduceLevel = 1337; - TextureSettings iosOverride = legacyTextureSetting; - iosOverride.m_sizeReduceLevel = 0xDAD; - legacyTextureSetting.ApplySettings(iosOverride, "ios", m_context.get()); - - // Write the modified texture settings to file, using AZ::Serialization. - AZStd::string modernMetafilePath = textureFilepath + TextureSettings::modernExtensionName; - auto writeOutcome = TextureSettings::WriteTextureSetting(modernMetafilePath, legacyTextureSetting, m_context.get()); - EXPECT_TRUE(writeOutcome.IsSuccess()); - - // Load the modified settings back to memory, using AZ::Serialization - TextureSettings modernTextureSetting; - auto modernLoadOutcome = TextureSettings::LoadTextureSetting(modernMetafilePath, modernTextureSetting, m_context.get()); - - // Ensure what we just serialized-in is identical to what we serialized-out. - // The comparison operator also compares overrides. - EXPECT_TRUE(modernLoadOutcome.IsSuccess()); - EXPECT_TRUE(modernTextureSetting.Equals(legacyTextureSetting, m_context.get())); - - // Remove the temp file that was written out. - AZ::IO::FileIOBase::GetInstance()->Remove(modernMetafilePath.c_str()); -} - -TEST_F(ImageProcessingSerializationTest, TextureSettingReflect_SerializingModernDataInAndOut_WritesAndParsesFileAccurately) -{ - AZStd::string filepath = "test.xml"; - - // Fill-in structure with test data - TextureSettings fakeTextureSettings; - fakeTextureSettings.m_preset = AZ::Uuid::CreateRandom(); - fakeTextureSettings.m_sizeReduceLevel = 0; - fakeTextureSettings.m_suppressEngineReduce = true; - fakeTextureSettings.m_enableMipmap = false; - fakeTextureSettings.m_maintainAlphaCoverage = true; - fakeTextureSettings.m_mipAlphaAdjust = { 0xDEAD, 0xBADBEEF, 0xBADC0DE, 0xFEEFEE, 0xBADF00D, 0xC0FFEE }; - fakeTextureSettings.m_mipGenEval = MipGenEvalType::max; - fakeTextureSettings.m_mipGenType = MipGenType::quadratic; - - // Write test data to file - auto writeOutcome = TextureSettings::WriteTextureSetting(filepath, fakeTextureSettings, m_context.get()); - EXPECT_TRUE(writeOutcome.IsSuccess()); - - // Parse test data to file - TextureSettings parsedFakeTextureSettings; - auto readOutcome = TextureSettings::LoadTextureSetting(filepath, parsedFakeTextureSettings, m_context.get()); - EXPECT_TRUE(readOutcome.IsSuccess()); - EXPECT_TRUE(parsedFakeTextureSettings.Equals(fakeTextureSettings, m_context.get())); - - // Delete temp data - AZ::IO::FileIOBase::GetInstance()->Remove(filepath.c_str()); -} - -TEST_F(ImageProcessingSerializationTest, DISABLED_BuilderSettingsReflect_SerializingDataInAndOut_WritesAndParsesFileAccurately) -{ - AZStd::string buildSettingsFilepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/tempPresets.settings"; - AZStd::string rcFilePath = m_engineRoot + "/Code/Tools/RC/Config/rc/rc.ini"; - - auto loadOutcome = BuilderSettingManager::Instance()->LoadBuilderSettingsFromRC(rcFilePath); - ASSERT_TRUE(loadOutcome.IsSuccess()); - - //Save the preset loaded from rc.ini for later comparison - AZ::Uuid oldPresetSettingsUuid = BuilderSettingManager::Instance()->GetPresetIdFromName("NormalsFromDisplacement"); - const PresetSettings oldPresetSetting = *BuilderSettingManager::Instance()->GetPreset(oldPresetSettingsUuid, "pc"); - - //Save builder settings to new file format - auto writeOutcome = BuilderSettingManager::Instance()->WriteBuilderSettings(buildSettingsFilepath, m_context.get()); - ASSERT_TRUE(writeOutcome.IsSuccess()); - - //Re-load Builder Settings - auto reloadOutcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buildSettingsFilepath, m_context.get()); - ASSERT_TRUE(reloadOutcome.IsSuccess()); - - //Find the same preset - AZ::Uuid newPresetSettingsUuid = BuilderSettingManager::Instance()->GetPresetIdFromName("NormalsFromDisplacement"); - const PresetSettings newPresetSetting = *BuilderSettingManager::Instance()->GetPreset(newPresetSettingsUuid, "pc"); - - // Delete temp data - AZ::IO::FileIOBase::GetInstance()->Remove(buildSettingsFilepath.c_str()); - - //make sure the preset loaded from RC.ini is same as the preset loaded from builder setting - ASSERT_EQ(oldPresetSetting, newPresetSetting); -} - -class ProductDependencyTest - : public AllocatorsTestFixture -{ -public: - void SetUp() override - { - AllocatorsTestFixture::SetUp(); - m_data = AZStd::make_unique(); - m_data->m_request.m_sourceFileUUID = AZ::Uuid::CreateRandom(); - m_data->m_rgbBaseFilePath = AZStd::string("Foo/test.dds"); - m_data->m_alphaBaseFilePath = AZStd::string("Foo/test.dds.a"); - m_data->m_diffBaseFilePath = "Foo/test_diff.dds"; - - for (int idx = 1; idx < NumOfMips; idx++) - { - m_data->m_rgbMipsFilePath.push_back(AZStd::string::format("Foo/test.dds.%d", idx)); - m_data->m_alphaMipsFilePath.push_back(AZStd::string::format("Foo/test.dds.%da", idx)); - } - } - - void TearDown() override - { - m_data.reset(); - AllocatorsTestFixture::TearDown(); - } - - - bool ValidateResult(const AZStd::vector& productFilePaths, const AZStd::unordered_map& productDependencyMap) - { - AZStd::vector jobProducts; - m_data->m_imageBuilderWorker.PopulateProducts(m_data->m_request, productFilePaths, jobProducts); - - EXPECT_EQ(productFilePaths.size(), jobProducts.size()); - - for (const AssetBuilderSDK::JobProduct& jobProduct : jobProducts) - { - auto found = productDependencyMap.find(jobProduct.m_productFileName); - if (found != productDependencyMap.end()) - { - EXPECT_EQ(jobProduct.m_dependencies.size(), found->second); - - if (jobProduct.m_dependencies.size() != found->second) - { - return false; - } - } - } - - return true; - } -protected: - - struct StaticData - { - AssetBuilderSDK::ProcessJobRequest m_request; - AZStd::string m_rgbBaseFilePath; - AZStd::vector m_rgbMipsFilePath; - AZStd::string m_alphaBaseFilePath; - AZStd::vector m_alphaMipsFilePath; - AZStd::string m_diffBaseFilePath; - ImageProcessing::ImageBuilderWorker m_imageBuilderWorker; - }; - - AZStd::unique_ptr m_data; - static const int NumOfMips = 5; -}; - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBFile_Emit_None) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = 0; - productDependencyMap[m_data->m_alphaBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBFileAndMips_Emit_All) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = m_data->m_rgbMipsFilePath.size(); - productDependencyMap[m_data->m_alphaBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBFileAndBaseAlpha_Emit_ALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.push_back(m_data->m_alphaBaseFilePath); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = 1; // one for the alphaBaseFile - productDependencyMap[m_data->m_alphaBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBFile_Emit_ALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.push_back(m_data->m_alphaBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - productFilePaths.insert(productFilePaths.end(), m_data->m_alphaMipsFilePath.begin(), m_data->m_alphaMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = m_data->m_rgbMipsFilePath.size() + 1; // adding one for the alphaBaseFile - productDependencyMap[m_data->m_alphaBaseFilePath] = m_data->m_alphaMipsFilePath.size(); - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependency_Rgb_Diff_EmitALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.push_back(m_data->m_diffBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = m_data->m_rgbMipsFilePath.size() + 1; // adding one for the diffBaseFile - productDependencyMap[m_data->m_alphaBaseFilePath] = 0; - productDependencyMap[m_data->m_diffBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependency_Diff_Alpha_EmitALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_diffBaseFilePath); - productFilePaths.push_back(m_data->m_alphaBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - productFilePaths.insert(productFilePaths.end(), m_data->m_alphaMipsFilePath.begin(), m_data->m_alphaMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = 0; - productDependencyMap[m_data->m_alphaBaseFilePath] = m_data->m_alphaMipsFilePath.size(); - productDependencyMap[m_data->m_diffBaseFilePath] = m_data->m_rgbMipsFilePath.size() + 1; // adding one for the alphaBaseFile - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependency_Rgb_Diff_Alpha_EmitALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.push_back(m_data->m_diffBaseFilePath); - productFilePaths.push_back(m_data->m_alphaBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - productFilePaths.insert(productFilePaths.end(), m_data->m_alphaMipsFilePath.begin(), m_data->m_alphaMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = m_data->m_rgbMipsFilePath.size() + 2; // adding one for the alphaBaseFile and one for diffBaseFile - productDependencyMap[m_data->m_alphaBaseFilePath] = m_data->m_alphaMipsFilePath.size(); - productDependencyMap[m_data->m_diffBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBMissing_Error_OK) -{ - AZStd::vector productFilePaths; - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - AZStd::vector jobProducts; - AZ::Outcome result = m_data->m_imageBuilderWorker.PopulateProducts(m_data->m_request, productFilePaths, jobProducts); - - EXPECT_FALSE(result.IsSuccess()); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseAlphaMissing_Error_OK) -{ - AZStd::vector productFilePaths; - productFilePaths.insert(productFilePaths.end(), m_data->m_alphaMipsFilePath.begin(), m_data->m_alphaMipsFilePath.end()); - AZStd::vector jobProducts; - AZ::Outcome result = m_data->m_imageBuilderWorker.PopulateProducts(m_data->m_request, productFilePaths, jobProducts); - - EXPECT_FALSE(result.IsSuccess()); -} - -} - -AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif deleted file mode 100644 index 0a03a3f231..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:db3450a2e68b0ac5d88e82ed01c897ed4ea60a502bf1f44760c6f63ce4970816 -size 3157396 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif.exportsettings b/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif.exportsettings deleted file mode 100644 index 0417122033..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumptype=none /M=62,18,32,83,50,50 /preset=Diffuse_highQ /mipgentype=kaiser /reduce="es3:0,ios:3,osx_gl:0,pc:4,provo:1" /ser=0 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/128x128_RGBA8.tga b/Gems/ImageProcessing/Code/Tests/TestAssets/128x128_RGBA8.tga deleted file mode 100644 index b94d39d838..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/128x128_RGBA8.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:116cd9a554235a0a2bf1b2ebbc7fdc38f50aafad7910cad01a7373bbfda3f562 -size 65580 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/200x200_24bit.jpg b/Gems/ImageProcessing/Code/Tests/TestAssets/200x200_24bit.jpg deleted file mode 100644 index d682456d63..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/200x200_24bit.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:588e3bca4304823fdf795fd96a640d3b1e31cc8e82dc1cb1835071aa96f2eb22 -size 34658 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/20x16_32bit.png b/Gems/ImageProcessing/Code/Tests/TestAssets/20x16_32bit.png deleted file mode 100644 index a7f48148f1..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/20x16_32bit.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bd5106eebb6cf264fdac5f3568977fc8f944df4a4d4de6b0e9f35b3a001a3001 -size 206 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/237x177_RGB.jpg b/Gems/ImageProcessing/Code/Tests/TestAssets/237x177_RGB.jpg deleted file mode 100644 index 637ce7a86a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/237x177_RGB.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af31ad61e58d030ef5406685fbccf67f83054fd81cf840aa308e513940f68645 -size 22767 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_16bit_f.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_16bit_f.tif deleted file mode 100644 index cfe2389ab5..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_16bit_f.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dfa0e2bbe4691b2fc98e8456298fc05d771cf2b30c61bba992b340abd2bacd91 -size 23944 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_32bit_f.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_32bit_f.tif deleted file mode 100644 index 7fb71acf75..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_32bit_f.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fee58c41e2306ad03870b517963f353f9be30378fbbe61e596007f4c3ac4b2cd -size 30088 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/512x288_24bit.tga b/Gems/ImageProcessing/Code/Tests/TestAssets/512x288_24bit.tga deleted file mode 100644 index 7f2daece10..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/512x288_24bit.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f0098e9308e50755484b9bc7205422a54106c593d5d36073bbdbd822c9d459d -size 366890 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/512x512_RGB_N.tga b/Gems/ImageProcessing/Code/Tests/TestAssets/512x512_RGB_N.tga deleted file mode 100644 index d47f00912a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/512x512_RGB_N.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:646a9a9035cc3f4dfd57babc0055710d2f5bb8aee0a792f2b65d69b4fd6a94b3 -size 786450 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/BlackWhite.png b/Gems/ImageProcessing/Code/Tests/TestAssets/BlackWhite.png deleted file mode 100644 index dfe856790a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/BlackWhite.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:969c6597a6346c5ff8ae24b4ae143bacbeed2944dd139ddef9b440483dbe4c02 -size 8866921 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif deleted file mode 100644 index 090991ec7a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:265ae231486dc6d5d61aa2416b0010ea743722f7238660faeed9edacd46e8a6b -size 6303186 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TerrainHeightmap.bt b/Gems/ImageProcessing/Code/Tests/TestAssets/TerrainHeightmap.bt deleted file mode 100644 index d79577ea185cbdde0d8142037ae64567cfda534d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65792 zcmeFYg;P|2{51{|q97tl2r7#G5d#$!mHR#iMNz>(R6+#7Anin@1*Abl3?xOmOF$Gw zvAeqqyW3~Ke&;vy{0qOCXLok*-aB`9cJ6t<;+)sHt{zKPEnKm}c+ju_IXSuic`3@t z%bs#_Rl2gb|Lfs`|K0ijw*R{qApWmY{@=&{cLn}`cm+E9JR7@K+tci3_YyOUjF)CD zZXKj9yN5`|4*4XFU8NvS-)S!{ zOwtqk%6f=#9s3EZwML?){QwbmwVyEFGC<6{J3wgp^b-L?dx(rLIzpvHQ{?8Fg=eJ6yUQiZ##Cv<_fV%K}GXZ)6eMk$F21KW!I zciW5iKQzU`1P#$-(pntfEGMpq|B;TkD~TW0ZN!Kz?WHIoflw9>u(mvKk zWUbN{1O5yWx7rKQwAV@u^_eS9mU)RCF&jnT*$C0uF-cgKriypL*`h<6Jh69IuJHSu zE%qeu6EOvOLNy~t1k6nnTE}*XuR7br=j>Rq?rgY-9ug>q1^NkZXFstbGgu578zBb% zh!;HzW5l$(LBj2{yD-q3A8N=> zsf=Phc03HD!!&7$Av;oil|( zy0@4<#8;@^2o$ZB_=#DX0ix$_Uy<@6K>U{#CJc|n3xCfTA@@C0m_CUXe^1AWIfgsL z;m|!oRV_yVxdx&SiOI%IN2>&T=Q5WE_Zel3c>S)lB%uvv1O9@;xJxpO&TTs zOfwNDocf5okDW!ForZYQQ%&sut17a`wHI%-HARPe>caVox+s38A`%|U3EgS$q%zx^ zlELH?QpA@1(g*C7&TNm7ZVg)^eb{3r&CJu3DvlgAv)(q|?0@igpI&PAp>(+PGGdE# zN3}}QZS_b>_}*5;P3$hF4H+RcwI_>N{%#_vc7q5k+9HgWB#LcKDWaiYp78iqB~-_s z5TfOV=vwzgw5Wd&W{KZ~um5*(zT+3sJ?xA4J>ZY9?EYQECbx+8^-shJ>7E#O<%Zbg ze_0r&oEBySPl=S2lVZ`flj7{jQ{wdA3!?kJ^TIawknp`xAZA}k71y z=>F^>ylvWuk@ucU>Xv7vPgTWI^vD<~#&WYXsKHIjvB{E_y|^Krk<$<(UiK6-cR>`5 zb`sZA?8FhtOQg6g6O~Z`qV{H-kb9ITs-D)0Hbak#E;Wb6rHhBe&(wp$F11z^{W&hS zmR}O(iq}NUkGo>-=oXRj;)75Tf5cmzR!Hijh;JiQux*AqZtT^7L4AApsA=G#vIf@7 z)kK)NKB{bbBJE;t+;i!H^XI!jF{%?H=c=Of0wo+Q{w@lK+!MEt9uv+dOT;AITyc3x zrogg2;@Iu&;=9sTky;Wj5|>7c6txhcInH0y$1D>Qk9&)z+Qs6x#v-x4jk9>t+fmGJ zKU;KuXD#-ZjuY4C4i^oDeZ=+II^xmXHbN!$lXS`El;kxaPcjS(m9#CUNO3x?CA~J` z|M0KReqna!g^%>=VYM_R;j1)qRu|#sY$m2QISSKHtHk)Np<=pSqG;TnF07MFM4W1a zxEyg(T>5fd=(TPUS`KnpwyiCc%{xLz(#Mub-I08vJ04y&z=?~7Sa-8G%!eCd;$b~_ znQDW!+K9N(2`_haz{f=$@akQAR9sNQ#s{iURB3}xBNcGwuM%2@{t`zLo(U!E%R)8w zfOwmcEDl7i6uz7-D(;LCLsYwnF0LBl@JI#m)&8&K`$k@Luly@Tc2E$0`8`Cvi=CL% z5-9X3Sn=|f$l3E#lwVhbb%!?S=H3=Np@K=( zO4xEx8I>GwbRN(X+4KIxnBl|l(!~@5?M-2FZw$t@0M9R(P!Bnp%D6uBh4@r@ zS76?Ck(PBu47EEYcJDYLjyyanR4+A&IM0J3LA^?}Q?3xk4kcpV+Z-_>d9RqIx?4PM zlO#4Z#R|uwF!B0jfLL*Mm1wSY6GvuE6(Vw!sJHJX9F-Ks$7wetvw^wNX2;ditFPUq z1tIDG@Yhh%kn(42l}0H&mikWZBF=`47q5T%h@I0Tg-Y3O5!#e5T7Rh%3rdfRgyYwQ zS?F`|{Kprun~Ine+a3Y)_29VQ5IALocgIGex?W)PDI(k#c-nP5)PGnYBGDYB7KF|D zvFJHqEUvna!RKG2vAbp@%o0q{W${pyOdf>oJ&dsaO;3y;*aN4gcf$pHExfv}f_Y27 zh}E0Vh(Gm(eA@NvF_J5aag@0zNZ>u!t(*J9A|>rjiyi>G!#jL zjWKfTFzhvw;M>s}D}(Kk6_FK`f=UY+s^s$(nd0X5Hye4Yro)*^& z8pNKdm10*@foQcXU9@!HA@+}m6R)Ss>S-@`@w%hA$Q;{KL?$ZR|ueu>@M!gn^XMc(CH;Pc6 zs|J&VP6!^>4d*)khxv8Jm_2<28e0Tj&z^=W>GqiY)d?PXE;v=a08)Ebe9?8q{gLw# za>E5j_qrgbjT3r5pNld*2N->Igme8I6qV1!t$ovB&}9mAevCn8!7w~%XN);x`l8&o zGqxtSLA%}0L|^l3qQU)^_-T1Uyj)%{f;(4>fKCTRmfuaW_Qh?H)#bVvGVr#zJ@t#o zd8CYx!yT~WmL5z7>0nK!Hm=ro#5Lb;aCtKrH%|a6ezUN{XgS|$_rv}s-+oF3XWi%JdLwnsPvCjClm}~P` zv?{(O+T1@a&X24W)AtpM)pfhYkD(FbzM-dR^L3o)zRo}-8h@3}E0s!Zo;XXdEYAMJ z|Luc`($?-LrOTi7h3_&OalA*UP*2<^#(5nRx|5!Zzbjio&8a=~3w1F%qX$&)_JjY7 z!5I8<1iCymL!Vl6+^(8{Trmya*PSs~ehJbWS7ZMCO_+K)5WjQ-Fw1xYR%rR-oN@pL zI|g8snLmz~2jF#&KxF&~!V|+FD7D*&Zr4}Bd7dY1l^xN!*&3UhCga3&3(V9Vjk=SA zFn&xge6#EUlk>firQH>KjXPsPqZZa?>)>~EH*6Ygh#5Xzusot0?(H=~@!C|4ADebm;$Pzu3(j|kX&h{o31SR}njfZT~4z?c*q*_H|Z&Vx-s zA>6{ta4)qSMoUXE|7{JX*dD{@4X1H(^Eur8d>*qi&SB26W+Zkygl{Jgpx5Af)MV8o zIrk9WL>@wjXuzQN6)>7m0N0MGNKM#|vJDBCp%sN91Rzpl8PuLRVwv#_tmtnADQg1G zlnC@y8HIZX2g7W@Kxk$S#JIoxu+gX|uI|&v3S}LLubODBrH+MOZ4ua23H7}`i`9c3 zig~hJ`DtpED9}t1JKsbIPk0MwQ-~>>I*I0s=cKWPe$vRTPyXQ_P~##+`Q4Ec=NgGz zyCq_n{!S5Icu>f|HQ2K~hskj)ouP;QErUPbtu|tXJ3=~|M3m;nt zSk<`TqR|4}JmiQw{hU#+IUjcGow4rrTx?zH1E1LSFtZ7Sv04a{R3k7sDH3MJ+fmZA z6ITLLQ8zLNfAflPPq7T~#WlDzsveim9E76D3DhZHLXE=>yzG1vdpBN#OXd~a7-xQdPVysotKLOI>MiVTdlyx?ccFX!F2)YJjeT;L zp)mU>zRjpc=7|CvvCP2lG21a|Qv$}jN270ZF!n6N^_ne0QE#aVOjxi@kV`t7VcpM#!j57l<`bS@cf9VPN3wlUuZig*PT0uwgh0xn|Mx4I3 zUz{D5A$+IBh*t02#Nm{_;_%l;(nF&y(xkvo|L`BNV4bAX^ijHNY$g^~1d9$Og<{?P z>%zfC4ukt?VSnrYpmJ_Bo}aNmt${3tX3xNsUbB(e$pO~`91xM=0E=c&;a8df)qT+rT9FujG6G-PgyUiF&G;D;hLEPsco-gv@`@M~x5UAxEE&DEcVYC^ zM3`qsW7n8ibd}}U4Vl~E;hu~^^HSj$xerC-3vgjm1@_rj!(in>$jv;4N0*M{cCWLz z9)B4-pIyhw&$sa`^BEL^KcWx+pixbp{u>pTFinB$d&~39ncq0vB*%NJ6xgXjg>FyP zIrDV~?r>6P_xo))uYGHtGHgZT7jm4}QI2st{^F*R9A|sV@r%+QSpN43>VF@j|ATXw zqSt^mktLYnor`leS;%jfit?I0h%!vZJ%<=1yxNS~KI`#ow-+4iJP>QN7|D4aNE$N_ zzi!S#heuZE=W7A=4->H7Q{Zg4gfs1pArm!_U9EwYA@WeV_DpO)bWwDg(I7U)rHi5p z8ONOkacj9B2N<@0AVO&iwOno{U zpTAkbzuhdX`CyOQ^R9@v;D#$JT~T(`4cQh8a5umkAv;&YW$b!f)DOX)ut;R|-wGx3 z9q8XD10(Nd;$nF^=9Q*nz^6=fQOU=rvBmJcUx7|%tC3t$3B7_!G`=WA(atPSaz z^3enET-AWdr%vEn@dfA|xP~d!w@};pK1>Xs;!fEcIEQ?|7lXH$TKExJhkwHM{$KPS zpu#zaHTbnei^&eU^nb6z^hr9b-rSK#4t8LzlNJMB=&`A=2i30kW?e}yc3a(pDW|)! z*tj!8-*jT#mk!)s)t>2r>MSg3&r8-C{4%&b*BiBAc3*ienDz?eeXhd8`ZyZTHK0?E zdMMk~V7GS_EZ>#D{aqGr-ATfkf*5!>hho-_5S%{087~@wandyq&z;v{)N~)vbureg zo{x3==c2!zE!q@WAo%TYbeq=$hfUNl|K(4y_`*}MsMUG#U~H-Q=olp;5~d3EIAx)+ zJy}YAp)CCm|JU8OTRJtln^2LKiMAJHn#TR}Vn~Cm@7$^*TXRE^=rI9z#T*#uxWLAK zAqFXV;9{3$*nQ6vehS{u4D^KdJ|EooTZV|7m8jJA$K09WXwr`_eVd;lAdG{EdxJ+{cOJ#W{D zH@h3r=V=3m?v`Dz@>+!KXh61aGfFyM#Epa3u=C9|tn79T!*L7#S8m`$+b573Uf^Z+ zXIQ=c2~Br7`c0On%Wh@vn5x3Y#qHQyLyf;hTdMC-VgC$OZt>G#JNeE$Wnsvk@dFsu zbs%qSG@}01zVy1-i)!gTImGloYPBEARg+Aa{dzRtx{qeJ#1XW(J&bEo2e58eA6{D5 zo$Io?@nUH=wv6pY<(FOQtKO9%F1q~iM4jO#igbSQUY2_vK<(fS_yu1__=?N$4LpmX zqfcV2{Q-2?REX7gvS6jY8}}@>qw|UFa9y2*$ft=I5*mxZ^%1f@C{5Wyj%IbX8Uh(%Rtq5CYR#+76gx|XsU|WM1ZWk@VV*M4+ zxV0S7Da%mZ;EkBy-Z)U~jSrejabIaYK6nSA{elo&h>XV5&xy#{v!W`6u=v@1eAK*$GV|Lw zyzDX@YcAo=?yGpMbO%EfpJSLp3w+GpVCmeCxc%S@x}W_9wvY#7&_Q`Q5695tELhTW62EMp&V8K8C10m=z-ntYn@-~1+vcoI8BG`K5iD$P%xjki z^H=m>4pSS%%e(*M8TMk<_s-PP@4%Y=t(h3`3#a#f#^ZtSu{G%xHk^0?{}T_OfBh;J zJ(krb`JEUtY%5%4{Z;Ss&4}Obhb@U-=&->K z*kcYkivd`FMGI9fD#-S35tonE3)PKrVsejJ;?!PEk$NLvTIHen5C3cG$0Y59@#5x( zcyYM7QT#IdAnqP+k81ngC|PTQD^`=SEy@9JvKPyG)a9^9TLagwYoO3&C5#rYLy5z3 zO#kKs{~w-k>f(Xb8`oiZ({kAK^2Lk^Az0B6g+o7*ApOXO!lr6GpLGBxvRH4~eGb=M zuOVOi0s1SyhKBN6bbk99lMS9>)U@|FYxfCxVc&6o@h@z-{{tF&-|+6}M-=w`fX~*i zaP#^bWaWRsp?5!E`TZLf$jQ;jT7^gC)LGC$pOeG-GGc}?HB(G^^QIY39F`c;WJ;Ga zraU=+1ReJdqq*5&UNbbJ;k|zR;4ql8#7H*S3of*uzy+%&anKfPI)u#NfRdTCcrlx! zuQ*X{&wQ2)TEtt{-aKFI$%_-*nVRgz(aRl~d3H8GeYK|N=?UDv!h+tHEm#{weziB{ zzL+6AyRkPv-tI!h5uI3atQ`wmT2r;U6`zI6bD7~E49oeBAxUo$f9)Y&MBPHm>MNMr z>kLxn9s^~4%ZT!7tc@?mTIF1*Kg+;p_Y}w*#$n6(5NuLeff?{$UT1rP^{kC3s zZrmPS*S{8vzSj!vFVW&=rL}O{-c}gb~%3jebG|y3BuagSA{!WpfT9jz) z+J<6|8o&O~;oosRXsn9E~_?Ags@7EdPFaJYjNU-g^BrmyCl z)KSpZQgF^%@I(8FoIJ{sF9y!ww0U!=d)1MjBi-nex0D~Omr+k=HG3@2<*&>s6?!s=}sat*Ddr7uo7Rp*HnBCbe$Cpi}oy`SAkIbZEx0 zll3@yx&n?ri=lTj2YD-!kti31S=~3`M&E^4e_KUl|5C5Z?Po!<3&LZYfwpe9xOWg5Q#LEI*%rP8*g9#E|XXZ9mi0y`W6yCzCc6fceIXE%TyJg0cxln|b4Lyxr9-b1-FW4EUp|>OnDPdu z{PJxQpA^jDfx<;R=DvdeS+C}@s1+RFcPRtTxUD;Aoa(uZ4SAS^7ez9tF{jNfTH;N4W`xA+6K4Y!LWBg}z1C~6C#+XCUwXTBt z`#d~3yc6PSEM~k4Kufd-didJF@Szz_KkSQ(YU-#pdnww_sgr5t(IPcy9|SR}s3$yW-3Hp*Xs4JpMS%z|5=8IMUt&Q!aa9 z!clLexh==|M+?!#Z6U6DIia2Y94v^nL5_`trs>0B*LomcrVfCr#ZXiYH^=0@&d>@D zfWznnl)uS?`ou<SqlsRmH2EBIavqxTcj=9;JPKJZ2lQ5Ki`6fI$ zeIz}!hjXXdP@aD_n9bn>=(BAA6^#3{@Av_nvuY$Cl#ioR=2ZUloXIgST{xw7DR1oC z#KHXnnNk->`QyRV85Ts1rvW^4*_XW&*Yd^EmGoG;jOP89vh7HBp6KXB#|Uq#sjpy{ za9=8D22){bDElr5qv^ zVwFJNi|}Xke;e8B#!AXPS;*6&^O!c>p1)4m^1kU*wzRh3nJ`oO_zYmr-i919RG-6c zY4d8K4u`DPrj^u@dta(?xwA60oLbRL@e7V>zQB>RtH@e#6g{r&hw+YFj9R-3YH#B3 zD19^X$9uyzY$l>QjKP)-Juxgp4LSE72{XSMp;#L&#yy)X)=yFt?M$~zRcRXk@K@84 z6CPvNi@8#T7*+dNG`vy4@?+f*Suqr?6)aHR!3IzI&qu+^j_sFH1dn#$f@E{c_-_9#eS8-;AZzgV^4r7tOu9^1gjnW@~omj@qsqoUco* z1}I^eQn zFKDFGj&$~T4ckIj$ zH;s5fc^o%~Skl{hI)mESa>UKK)Y&(mh80eXGjgPsh8<^=%;K^2GdSnfY+mo?zz@o< z+@b zwsLzw3_lh`(cLzZ1`%OY84yaZ_FEWJDLdY3D~;bKamT40v<}+MrH}UTPf`Z$FJ)8b zY&P{AvS_$-4^!on>Hj&N!5^b(Dn-)pWduuQ>tW942v)WU=UuUxgL((EpGN?D=&q&i zUQY(Wf#tKN@M(v!w0b>=q6jX8bzA-gXzvp=WA_2$*9UD$VEBFc;s7wqu(AW}F}4j+pfE(0|zvkB_!PhT(V7Rr88yG|LvD!vjRH z%)g=It|&COrAWHoYX9)xq192GijNf=eb0#Nl!rozE-ZKU!|)%&Q7Y3E5>Cy=?OZ2J z&tHh|^A}_NTQ@vPc7$*3R4D&3MMczLym0M>muEU7$wvznk`}t=c7~5@e|XyVL0_w0 z2<~ZwrjpU<`guAQzFCX6GX3t`$x_Vx^#D6FTCqv4J(u3^#`&*I7*{%(yDr*sx~ek| z&s#{hk3KY9zmx_WmN9Vm5~?ipVu`#L!`m$8;5v7fK3K}`du8?g!X`?)H}iOY6b&}U zGxg*)W{ud%A*c4xzegskQnL8GG=sW|8Qk+TlLKY@i*KcK6jS)hZ6{k@-_CIXiHsZ< zOBrXOLqsfpuH44gaXWZrXbL~yN@ecMy&N&*%n*CmhjPh`LKB!z$H zC$m-0tt`lm<-q7T4tteA^DFT@ZV*c+g&1DE7Rlxn;oS5qm@`Z_vSyGcKbzTcaQjJ| zlRcK>9uH-SmN9e34rPFhhjvvn=Jv+^+Qj_jUWGy3QFN&- zhUvbY(0CArW?4UWzrq5K*7U^K4$9bYzC~O+eoTBmpCXnY+bC3;#)vXMCDG3}P0}t? z`G^0zIz4eDFiBWxT@x*1T4QgYu5dIQh`nFUaI|tV{5sg-#U2Orv2}uv&3xQ%c7vY0 z3#1eqJWDafi;n%Uc}rL9Z_-4rW?KaJ=zx~79WZx9U;LTX8yzn9hQZ$v$R249TjQx1 zffevej>6*AC79=X9o8@ZqIPH}9=y_zulPcc=a3c1jwkT;a`sQfU4Db{K9EZxbk50g2m{$(msZr(jw`Qv6&4jn^>9c!LI4{Jp6tVEyK*%a^8$#A!K`9 zaDT~YX1EXI>fpYt@1xIC?(M0#s}%!Yzk<`N>nQU$jze-an4^^q`Iqt7oi5{K4<4f?J>VGj_-NXUeoM`XQd%{kk z9p3Nmg|0Gxf_#`I^ae~rN?UtOw{U{VEk~>!F&E*>=i{RD0+@cb!K(!lmfH`4$4YHH zT-6pCJ%5UVNCoV%RKbinUGc-s7(KiPA*c#)m@oyFNj8W$xgG|~lX1+U0>|=YI?hr# z77W*7ly85k+!1WI(1!2FF5u_*bs z$$XG4b@NP3AneG}b=fOS?OHEPqzacN@y7eXD}*&E?#dS;~XWMGU%9 z#6F`6+1*@r&ggtT{GG!=v-fgyd@9dH?4q^xZdR6M@btwj`d-WC!u9!lFJDF}az6tv zRP%>bIXizV;eVe?xyYf2A4;=%*kmuAMr1NHE1eJCr_i@~C)4ti`KfUSRa+&|Fg%gb z%eQh~N*v4cBY0~~Fb8U^W9!$8=+ZKWgcVP9nM~g_E7|dhe0Rv4DnCuRNv1>2n`^*+ zrJCe=MK*qZkGppsV1Mi-Y_dCoF$ra8TeJhk#=eN`ISremjj^`8JwCO)C(Kkz#aP2A zVX@p%%)Q!23@LvjSyjeM&+GsG)Bg`#?Je}RGlc!3=OX={CN%YoaQY*VuV8~ep>}wx zV~?Qv*=VQZh#^h$5xPgF{r_@?|DhT1X={nGPeI@qBwDhW&;`@v2o6d-aQF zP|Pmsugv1d;zI5jUCp)w8+f$UA*S0l^4PKi%qy*7yQ(Ty4y&Y2&q{{OsG_S}1r;2N zxpPV$J%{b(@B4drSr+#tzcQ$FXdml$}e& z$<}~;A$?cnQeN7}6W#W5nOg?iHK);UM;g29rSVqIPO4Ad$weEIsiC}$^H;{Q$A4k; z(Db8C+A>aiM?X@Zw+^>F-rE2vzMgR#CYy38F7%hgu++;JjSKc9+o z$K7FaDHz$)li_S$j|q>?BX8JqIEBb@RgD@o?i%pIv60*`#fAenxN?)hQhpq>ilaAf zVBr~m_Hhbg&(>i)WgE>6r{g)&eLKr_cktlyM6Oqe=Xb3*8K;Y*|6W=C9=eaehgb2x z%Z+Sae1bRsJH?EUll(H`7;`!`(CA@3zw6gAMAY$Wa2=C(?dPzdYTln(L?iVaZkP21 ze-5X!z$2U6=jPMgxRe^-tH?F=^k}T-I`spTORJ;bg&MZ5sph$c3a&IOrQU!d4%wI| z(-m{LwM`D&)#r1sO&)K>%4$&0G*;y7Axd^|{?Bb3TADz6+bGVJf+>!!VV~VAX?xC_ zTmLSkUmr)FK4iO{x=N(Lo|`O)n98`-Rl^=Ml-XZJeZhUF%={PntMT z99@wsG80KTq{g_C_MR?V)$@{03t zKKB6m+gosD-(M(8n(X_@kjDK-v(>?A3=Wx3`8Y3b7`2RsmsfFUq8|;ag6N$Y&Rfp0 z^w-uR%ldpDWbB=cnEAAfUZQC=v8F7xryH2ys zxnn%7b%Z56Oyk)O=B#@;f&a0kxdqB=uEIXF5|6DD5K!rZ*|o${ zeLXxV{wNmLmWc-^R*I^A+QNKDv$W<+rlioYS$h3T?jQaJE&qw2F}cDq>8r@k*2mHi z8J2a^u{dB6A~P1?N}(rOuUQ7|($z3|z7{LjuEnhfYtXi%8_sQ(z70^8;L`QOhm6D|x1=jH9E9__}*OkH_ZomtzSzu!b{+Hqbn=k=`AS@Y9Dz zemL03v1yIG*Zm+*f3D-K)^*&iQq9U~&g35D#OpU<$@xg2|IA4^p- z8C{u5t)08+WU`&1fwA1PYYX2D3FE8tL40nvp5YGO3@}{45>F>i^0Z~~)k)m*#hiui z!`W>@A13DOQ-PYqdSxywdk4RYOE9`nj;PZ6SLKoR5--_XHN<@nJDq*T% zC?*Da$bp>Xa9?&1pTY6#E>oG8iS%hY* zE%>l61?_{&kC;B zHf3h&?&kyDOh(6qxuE&nD zxrq7g_ZT|kB3>Al;>eoq_^#-S_n*zNyiOD2uRj&DpVbKS<)LEt>tUjC`8#RtqYP>N z4r@uZ-I0IzKU~pAtXJ79Oq1V;e$TYAz+^bAZcm2YG)Fue?S%`kmdRq*7gZ(xSeh1y zRNDZYr9Yb2u7~Gpcl=!KieFEr;m&h&oCzC)&X-5yK$*-N_GBF{jEKehfFi7Yb^#Id zJ|OCo3Vp72WXI(?ymv~QwI$k|KS`UH>btRT#XvroW5V1Z!P65hd8eZlyBk_@+BO>= z^{|uaXU=TxxtJTA*Hg_rjGcx=u+}b`A1_7o)sZNwZ;0dF4vCymvzz> z)k_x_!k>zhV>ECDM&Q&5$nW8RORApOlC~VnO#Lxtc@T2D_~E8;AnvLLBV>j@luQF~ z_3B!DTjheey0g&sy#w@KxnaNxFH}~9;Y#HW?7dcl1#yq@{Ae2%UFgaT`~JLcW5n)# z2T)~ZZw~#>kZDu;Gv3OW<35@4{m`*&KVckoCrC7wX`@P~#?fs4M6O+JMU~~V*#49o zyDZtn-LHeV$|;m*w#s_K{oxb=5lqUCVWwpQgY|c@`+_v~o|wb9OQlp-tz|3U{nW{+ z;_|_joa0=>LiJkOB-L`<<^wFuKgb)GWa}WQhAEn*ENYc2)7|&dvUnfgZYktWQ9*C% zAe)aKZSm;EQhz0VPrY&goWjKj2;B;yzh4sy}k0}M*7=QoRLI$4+VldN~_ z`KN#r&gJpl^?W*f%H!-cxm;wJ&0@za#?@pptS*fq<99K&CW-ea#&PV<2==uO;{MAk zSyt=LzcmY){@sCYy=^#V{si_OHzzJX%vVtyQgF3 zy>1A&D37Ue)uQA}qR`qrL)eBWi^YBkQdKuSDW>dy@i$V?72>5K5SfiO|<$C2m$`2H>ga}~p}eO46oOTyus7lzpSO}J~j7AA{= zpj#D%gRjDoY88hu^9zuC=@`miy+y58J9?@Z(!hT(%NGviU3+8BnP^0-u>O3!XE5D5 z4d-nq6VC5HhMz0Paz!T-F77mvYFEbaUNRZeeIj>N&*0=LSE^+!=a3qIj&us-+O0v{ z*FS{k=ZEr&W;iVm#?bEaHrhYkO-IWtzI<229QjIKSX;??6{UQBri9~UoXyX=l7?OO z^Mgx02V~Vzb?tsOm{#!OTkwnibm|XREHBeUlnAgCq^RzS5_kb^qf3Oj!r*)%^8sj5w?y%f#n8I229dAU zqrbN=^uGq7jcGU@`NZJTuC2JLnvAPIccM+>cJz50537f<2#VegpEfBNoRxvnRX6)|_9y2rL zt%)XVt}$U`|51FJJdP*Kt=WD0EDr4L##J#s?EPjfS7~kH>Xm*R{9yxE@7utf13{c* zA1m{6Y-7s3U39*iM%Cn8o~b zlFP>`dwJ%jOke)Ell4Z4eEK7bQx1o6@TWkQ*RN;sz;(PbVFhzDT)EQHmQkm`Fx^2M zxlxZU2}&$p^#Fm2NAU7X5eB~72ERFLaLqu%iYzrac0Vq%75&6d$KGPZ@$=I2%y`Kl zy0`RYZt6e$-80&Y&P|b`qt;n*>8lbJzvzvdttTNk%?0{OE75UG|mz#!i$+nS8W+#4|;=;<8ZY&zLkR4ZfuyEKCnN5EMd!AoQ5#+~@(;_%;R~*~=?c{8$ z4CWt^>3XY*s9RdZhR6a2Zpq;>8OOI@na76lCG0h(noHuVc+Iwi7xjyoH>rre-wHT0 zu9)Axm&j%X#SDI0%+{RFvU3UB+7$Ee<|1bP&gCo5EN<J(TrpNQFZjNNpDZ_X^XdS;oxYK!-Ycmin|I7yFoy+W#!+kFU^?B_=e8n6zPEUS zT{}+T((o#j`lQ3G|7Lu)m?iT+8e;MJ>*CJOI5Dr&Kw+8GB+X3TDrFs=AgSCs_78up zd1^wdcc^gx+a%g;mPg7L1NeS7#j2;XFjp+a)^!`;c0C-=GiA8<*oBhUyRdssCS0E7 zqN`U0{^TCOj4j8os`fH!@@`{mmwQ+fbQ5WwPq6svXE;A;O}nn`W%HR%?BJr$!Uf$q zqIw{opEF^2>UbK=p2W>#CvxH^!FLU#Ib_#ZhS&+#TMM=%Tku7tHCHy;QrToKGuF5; z;PYHwu%5|Rzo*m1ek$$S&60U=T-j~d3KoTIlzDaoWg2fJ7dIy{d09Fip3Y&?y+Z2z zPtDz($P z<+Cg&k1nox)XdJ~bF~6q{!z@fIVCjTSV)x-#k}&jj3QBnvz|;tcqqFYc||#=^snM6 z{aU6N*U&_&qr#m1+*DD`WvbQuHM)w5kIQ6yv6wnN3ivQEhu=_oBosh(Lz2bQ< zHGhorJr_e6tReGcq(xa7Tb`8C|6?f)WjMZZEn$vNE{`AH$GD(OT7Jyn zjZXWRB-sHGBTpbY$w`FllGok3aM1up-{-mDrJOZ|DV5~a~$V59M0!{p69vuwQe%r zQan_TM&X-52!6@?<1@p+>zodP)7yo0O4b-#X#~^9DmZgO7O#qhkSaS&0tdS3&FflH z8Iw`=~IrjD8(z?;2MgKaJ$qMxhoro^j80h(@WI;?_d4v`1v_e?c>~F zcM10-`8Bt~K$NbP&Zd&zdbGd5h8FL0rwtTB*^-HrZ<0ryEtS;Tc9YglYo^x+dT34Z zOLA!WN`m)zz*z}mj;<&sY!-p2=$=wAc)vq*kGLsR`aZH^+#q6~^7)j1ApeaJ^#-1ix6}QGqEg=V{{m z@&ydzn})9BD5tQF?4Ul#Ta6sOc15=lNs0e;D&_M8VP~8riR-(D*zY2N@sR zA{&A3!5Az=5+2V@gZ2A#)Ucla!s0CKU6PB-NqO)P%f*p=#`FHj#@#=eOw*YG<4dfc zq*QpwWFXfi6Jx#7G5S6gg%%lDe?1$jr}Obcu@L;Xig4&jF%AV5<5pq`a{EhRmwE+q zlPdAwO~xPST*r3XYBU&J$A+A8#Ksk)zOe|Ft_9G1m<3NR87C*O?||?HOfe5ZwzfBv z8(pz=`EH23vxaZyO3a$9it{3Jh*ug1&8{Cb^1Y9YSG3d8@Cus#B8AGCcV>#uM!KIU zOWF#rxY@;#+}s5gTnfwIDEnBW7k*LWU;UdL|LCc&JjA)$!*3T{#ta#_OV1eI<5ZWM}`9H5UD_!A+ITc(Zo{ z+IrTZl6@y+pKXTWx~<6gVU1OR8xXmF9bR5C!s{pv%r{VmtA`xkTw{9b!?O_QtAZDg zfFEhA@l13ZdOMuhY<3D;+I`?0=#N>B{s>up9%DlNG1m7yPLDs26H9}kGbs|HW8-nq z@gh1WCS$|lBqZCXK#wm2K_MAfuq+elQ?ik?APZNua*z|tX1AtnoO91aoMHy9AIrc@ z_GdL3v+yH07jF4^Xx1#mSoRh)yD&U>#buZ&7b4=wW!MasK(4X^8|tq^Hv0w!1nV%o zyAIDLR>5#hCCu%w;<5P^tbfn2Cy6YC97=(j&P7<1Mc}xZKSnjq;M0$NxEOAOyQfUB z?-|pWv(G@ZQyeZNh^ovF^rg0&3SQo%lJD7cqdJsyEDw@~&QeM+8%vq1u5qEce%!zj zj!XN|uLn!3fA#N`9o3t!V8^u>#c}$dZ*m{^^m7>(#L237A)P+9ni40u(gg7UO1YU% z`_J7ZHNHo*TjVqC2@!-?xG4JHNZ^N*BoaiXK=hyt&NJ=O9}{J4)mDMhVs-fM*1+AD znpn3<9VxwPuu{;))EoNP>1>8-SR-VO9ZsFvf+Ou)P^Wt1Uas!q2_i5Zy1L(Zj3M9@A1dn@Bp+w4aB@_VMt4j!p=^n-#By$67uqp$g}_&qWR!kUI4Mr1*mJzN4rB2Hh#H` z`K)(Pi719%bP-A)6k=47{mS^_D{RKpnp1^m9XIjoNdsygHR6NAE#?KNgWo_cw5xC6 zWN;;x6c=K~&kW4Cl!!27dnQp|6nLqCTo`iL+jq$c9( z2N~E(D&XPkS-8w_X>OY`Mt9A{e#3>3@KMK;8a?EGUje(ZE0KI|IT}|0!oh~xRMec|mqKf6A_j(+@ z7=2>1<~x#zc~4Ia1kg!Rh|*kw@&zj}eJj&;$C<&ppWyl$$eL&Y*I`@SnY0VL!;hdO z`2^yYdcf1(2YH8l(4)(G1?Te!r$9JbMq!^}H2j%%ME2!H9Mrgoi0$e4Fgpj^tqL$k zrx;%2u7G!JDRPI3nIEhe@GgO3LkYy6l;TK93APB7VlwL+`-U##mud+%xm-r2ei4oq zmqJsk0_R4nP?UTV{l{-1{(c+Y9d3u1PCE`CX-4veTX0)m4FRbukY+fA@{yTZRoG!(@F2aE92l{Q;N#=jci05EDooaO_ z+3RZTWyAt4Mx!PF^BGVOE~9PVRpL>UeR_G-FHCIf`hmx z?uP#1)0h?Pf=|coab}GTau2S?*`Mkd7?OdZq5$U9zM#DcjWo#LPKO&mkfoO>zw~ZxIBglyO394n8pba3-4}dOusD*rtZeowFmHR>Ino6d0@*?FT{`c zfr_0!#Jz*yVH|==#?S7rVQ+(X43rlnvpy^f)A|Y_!?YhAcdwy+QaK7&6~olH7&+P{ z7&EOL)9lLe;%+%sD;L9dWg$k6vwNTQk#p7*VdeND*!mS?d_)EEj#MMJvko!RO?WTT zfej6J@l?1A-DmH@QK%KwE9&s1`5JBrm7wlGCe$_J!QUAQheh59zH$ieem0DoScRpR zb#T&H1zRpF!^&D3d!LEm{)G?p(d;g@+^D1}aS6-==SK!zR#aZANjgJQ$@9~5?##GI zZmPcuSD6~|um0Wo*YupC=5xF2PH-I(Ib6&9PEJMo8<(_b8hK1-JW`i4{mEwD_}#fQ zm)$J|>7z6yQvyL9GuZcZ4pi(H;_$E*;=A;ro3aY`RV|S{fobT4x8Yze!>g37u+DWY zDk4@R<&FuCWtrh)uqE8)t!H&#jWI#%@aw1zI<$8|uGk4)^YwLii4qU|dZpek?793&ZiMld>_eIR|&y8~=PpF(jmmadl=9 zeqPN(JmV1Fi01vn8E${iWqzU}Xc$(2SF#2Q3`10|X~4Y;ZFs%B6HO`);Lg{HnC0!5 z;Cu`7B&zY1;Z1uM=iskVJR+E;bQ#mRS-Ltw%V;b5crBo5u^d0^mjcrkAU|s+W_XL? zq}VW-)pXMR9al-(ES2(Q&yvb)8(K0`gVr!j2JiAgPFg65dw!Bx2DTObtAFEghF(vE zG}lOuF(e(&QZn60x%-*-E-y4m6P`W={)?SLsZwvc~nfe{fMNUoR<0b4n&Q4vNO z)4vpae@40nH|ciUH98vDO3$`Er*X4h6aU~Bdh}HQ$CN}-?>Ge`<+Jc$ff^LVfW{vN z(2q5RbKeH^O>}^^^1_n z<}2Jqr#H=o>HrxUKHo#zd7{?KLW z+mk~Fo)^*?ofZmCeM9SK@L}BYahTF92Wx9Jgqdn#;clQqO&_;<*TRcwuPa^cQ4n(w zyO|%v;QA??^f-x!37%N|!4KmP1>kBx82GYcF-0~B!ZsOrbUp`5H|D@0EuHBU67gqz z0wxs4V|dmjSnN&4)1p+|XK#fU(}RZ2W&B}JCN7`O!EB}>*}tO{veH+uCiog2nOEav zRW+hr>)>e8gzfvdj?k^-%(nZCVWt3bOP0p6ylq%^&mgmjrYMBDH4E*3c zQ}Vgs&6_#VkB$H8Z~61EUWd;+y;MDIZtgRG&g@kUC%9o8iR{p%qNF`kzH29+RPTC>8U0{>zQ}^r4b5R*1*twJtlS7LG8(IyuyAcwH}6ui91H~ zeeqx8Iq*FV!qDv~gtf&(N+$_&3)7i5AQd`$5;1joJjOOf<3>Uho<>Dua(o=7Ouoo; zi^-@lPsbJh3?MKADc`b?&#>gC4W+npsT2>URpOl2b=E&uA@pc1)IZf>eEKbHzS4q) zYny=jYRs%)J!ApHHKH=IFT{a)Uu9D>0~Z$ z+)2TwH_=$Ybb`{Nr=g>@2Qf{Xu*+^Wk`q@V!kI&4iz>G0|A&}%aa_v(Mi0~O(jA^c z63&dEF?!4sBDjOzyBIR9_)OaSVU%;IkqL%r+ut{L!glccSnlSHGfcMI*%h6g zKF~N82v?^djByA;t{n4Q?KzJR>1T1p%nK8?9zi6-@G@I1u}Rkwx!a9V&gQ}y$5*2D z(<&6cT7?aJR$ybEE>6a1;FaAX6fB*I1H%%G&*8xYnE?`b{)~hRTj_Uj34P}a%Mcacub(-GL9bVM^fg;8sgjhkviW9At!J-sf6{P z)!?MM93JdGYA&;b(3d^vS>b}DtP_xv@qixFU=(^WU4cpvrml;GPD>nOr!s%Qlz5!# zWBP){(YP5E1%qSJsQE7%Z%$vp&j6MAJ=jNXH zFYOQxm25|~gB9kgnV|WL9^N=DLC6e6#IVn)_S9!8kiSFot;@-HYb>pp>q#-0>&T~9 zgEH<-rNWgjxs>-8xzH1g^%8UlWEk z>P(BfF$gQV0$~<>7Jr*hL9F2bQY`JUC1N8)3|GVaq6rjofZ%3*EWK!m_?>!a+^>z} zzG|2sITr_)O+!fi6Z*u7Ptjw(c}F54#XIg=tciOlU!f3@u`w zlO2m3=;Znkdh1zARj!XnaQR;fksXKX*%P2}S`zA-ve4f4AN2n$!S75xv`#mK@vhYf zOSWdS*e+N+--q`>XK*6i8@7-AAT=)t-%P`?^K}fGbmOtVGy%~!;sJ>`B)&^vUY|=? zXdj2SN8)kz_65i_M8K&i8r!DCq0&7L_XI9t)8s@XElGuxL@pLemO^E11#Dzk?LS_J z4&#y2m$H5kRfw5hfjuWK<5W^U-g8-aDsl`|V!?(H5~}Z{tvO}H=M_T=9d5LecMYkWRHB7#A|!R^4!1Esn7a}* zj|<-w`>+0y8(sDKNBOvqzT3G|FUq*#t)rZf^+eiyPMOxb*pjbUFr|p)5bv29x_bI0 zZ8I0ak&OSamtP0<57uJ8k|Q3~ox$o|erRn7z=OTP|9A_7DPi~#5Q6mjU}OphV8VVM z9C~;X{>FPT#@G(e^)2BgVv6g`gJ0aDh3QMx7|yPR&GOnf$8=ykbCfYbKnj8MlMK!8 zQN(eUrxwdFsHStI8M2)I8^4r3cFd)kZ!AaBbp_oTmdQtVTtwMzu3Wp@?FbJ&@S-94ET{2lbK{wXVb^wcB8 zxt$9Sb2j6zbA9~0v`2R;bxl;IJ0G@EhMhm9nx|6d;VPQy{gTAri(paqY#h1Cq?%$@ z7{AsDAD9kD^ngF+#RQVu_jtis;|Ts1?tt%q zmMCPrzEux!JW~x7tjFKox)A*8^RdN432POm<9CiAYz{u8kD1r0a7Hry@;*zuF4@w~ zqKRbP|BNfwD(8yy$Iw~x6=b@HWli4mq#^zU3O>O+(c|OkZ+j8#l~}g+g{9E(QhQ$e%!1 zo(M;RQUauh(-Eo1xIdLVJW0%l^Rhf#Kaqpn?qpo~F9y%}!mz?K44D~WFq<0%zH=84 zeEtGzvg5%2Jrxl}dEiMcL0xzDjoMW_U006r3{P6lFh-YRrVrB3z-QG&*0WrI z;>sY5#QHH!tS5vboFV(#2Fre1fPd~v?At~7=C1<7|7PJs{X}Ra{-JAzJ@jO-h(z}W z(v!Q6bmW8{eV-*oxnI6;)#fZC)OQ1SqnL+#@$&e;`cL3@)6?-C&wV=N%;2TXUJT}=b5PANzJa4w(294$^lwb3G~x?c zz5sk+`m2e?%mdjHfmERgxI7Gju4NE9Q~i-!;f30LAsh*t3dcGH%(PK~ zev&5U{m{cPWtPkE%NSjf8(_hFCnx$?jzhFBCW;4Ol3+0It_a7s_-I__OGG-;YfWFB zgSg^c$k-O3zP1obV{_4DlaAcAvFJS*fz{tbvBNP8|7Bjle!dIX&>M>@_Yx3vERE?) zbD_;!jJ?L?csEdqliF7pCQ^#WWehhg$OTJB#p^k#FtUq>opu!7tz&(ZiXZBhoq^#m zrUNUrg57;XEVKjK8(EIcEMN3XD_ihB9?S@&q8zu~RBS7*T8ae{8t2~_fm?I#6 zG6E`EAy}y#fQ+YpFiLlasKfzCD{MuU)kdh?T!TSdLo~-~Kx1$Y)JCQwN>CI*3OvX+ z?xPzHjU*{kNZ~ib>Cxo_WUin|w%wn&V!s?NuyiSBe0(|AHo`)=&+oJl)MPUWyGMZ^Af{r(~xv4ll6bO*cz4x!yimT#(3V>*2S<_ z&cmU~WCR|I!!-9u9O;V0o(IgM;uH(54+%)NPJ$QH{oa|)d}#&wFl#MB$MZ6%Un@hM zK{@(-E@RxATs)CTLw`vEN_NI#(e-dhrkzJhm=`7~xIlCFc3i(`id`Q#w8?0~a_Kxw zOq+?})01&x;~2!td?M@1E%eSfjo#>Z()cf%DO_hBO;Zpez3e7V#NCrynI+4uFTAFg z7C!G^{k@DL^%jIHb3SHa+;oX{E+|@zTzr^czj-aoYdlD$Pl9NbP(Gc=?jQ-HQ3`36 zgsJ0vjGeF&lRnxYE^s%j{akUF-A^%>&tlfZ0K9JqfqhR19!G{^`uafp^=JLxS}%t6 z9)qHf1FQx&qW;)=M$VX^*pcBeVyXzaDTl!rF=+Y;pwg$Gjzx7-k4i07`(=}fViIL& zoS}W|=99tqPuvc}FmCg;S9)Q0&+A>1bmTT%8$-kIY{;X_hpg{J(Xdet#lC2!ro4VC zod1W-FydGzE{*Lhhs%^t6TW+vW8%Y=*zucTQLu$gvmg6gv`2JY-5_fo6}2>d94J$%gUiM?FuBdi{bn?4@rI*uw~lr zc(HiQ2#tYdcsyPoU|wW1ruAK)jrhu3+*zHEBXNZ&+FXLO9i`axuoUS^1-K=e17(L) zT)G?&&#)-`<_ST~(sQ_|d>TF1cO(DPdbn5^;*f+6VuMxCp`?tRWin{{A&%h50vN-x z(8iysqd&_NNcE!!85XZ+nLUeX&Vg}Mw7!MoT^7h4U9ZO#J3P_L)%#!l(_Uxky}bkO zY)As9R@Tc+gb3;NE792BX7rt9JOwF5ko}wz+TitodLn<)`?x8vmstW?6(dN(2DZ+- zAY*nID@D#g(#!{MYRG2&W24aR@AS&6rzv-+G(&dgr_lYAapKn3!Ukl94vw%&k zF&bxc=rW!M1CJ@F=f)yg;1|U&d`PceW;z_jnD$3M7u!p+7zUe* zk;#{F_ih`YcL;u#u;$Bb`jS+FQU%pB4nce zpGVBZug!Ukrz~Rn)k4IH6+>f6DH@*^LYvFO-u6sP@l8STlLTydZ~+xe2Ut<-hnHF| zn6%v*>wg&Iha-nnTQ!V$EW0N@Hdn`kndHAiCDwET7 zmgn=xjpjRDpuy%sdVKUQ&0hb5hIA)km)AlJY}3bo-4?JoWe1}dyYWH&7@|bH@o=X< zdWzbKfd#T0-d2mIS$f9C0QY@tco>J<6mq%f|=cy>nhztS;xZj^VxbcQcT-%nvdfR7taRxaP zNWO0`wJ}{{SwRu$@pRLW6hC?vNnys+dC(u!##Jk0Bp$Fv|70g5OF5&{_86A5yR&RZ zA6Unog>!KboVSLdy*`OywAuLTU4Y61#qf_R!_Up-DBn_wG&`o@bGwQnzbd#3*T7&) zHI6;J!QS{Au)J7}@H5qDW^>#ho~x+;!1%(RRGiVjgwyfKxP3hxSegwBjRNr67onbc zj5-*9*mkBEb!Q7Pop}Q;>SsY^I1&3}V{!RK6j~($vEAMS^W*nnlIUs}jV#0b6O7AH zT!^S2EF)=~9I|;>2Ce!SOuzGqr1y1^hi);;{E8s=1Bc1rrzI`XSD`gdqV!p!m-CvM zz$NA|>_6m<-iwJ!|IW_=qbj|X)y7<3%V2PM2kKIkm=WS zIuP1U?w@{=ai;|1{bobJco`;Ym_hjbM#RS3<5b2GytnW~a^qP{SQ`l6aOTZn80xYG zXYtb09r~lr;M3ZPsk^ozZN?VtA7_Qf4XeQ`NX#F#0OfBbkvH<0E)CqHzY)b`_alcS zB67&4q=W{BD{1`S3rvHuiDbj(QPRK%?uF(J&P6DLn<{>ldnr7N9)0kmH9jm)SG$g? zg1*wXvl2{0stnNy9OjmpLn+@HC#D}loW}|HEb~P+>+4^n24gRqQ9kfQ;EPNY`ZpyY zZ)`SPV+zr1Rsv;(t2n>!8m1nrhD&}u(>FC?#-kQo%4x>9Wz7F|r4Aaq8gN*u0a^2# z@%~#Y`xK+kvkX$d3XvX| zi-SDb5UogKUcp50^2einFbwAU{`k#2q5Si6C~-?ZNu-3c+?M0?Qezc~o|;YOreYN7@PyNpiRC8$GUSAWpXu!q zRrpu`=CK`m$qvjLWEsO%?d#;mr;nj=6727&uOfL3JBqsQO~QMUDBq@@s$_;p?x--5 zJEh^+vKZF8SyqAedU!h9qebvAT4wmbYTbF*#|0y4aR}Pl&!fli9I7w*;DV?dWEnTO zw8NTZd2NE)`L&2#wH!7Rbm8fy1OXKZtUmUGB9AqbeNqlBZpfsWZY(1?wuq)k7t=$p zSeluBh|K@6eDvi@sbr@-%ZZ;u!@(?HfaT$G2h(Zokv4Mt@|I@o<41|NEF?A5Ah>N6 z&cELb+h=~Uy=SNUytSKmc4}wW=|7of}XHKt02D^w#>T{j0x6YP(+Aj1^qZ z$tX^<^$urcAV9O(?g33@j^h0`ko$fYT4WVUc~cAN{YVd~J>Qib~$2u{&AQ@d87R3 zIlN^!1+QoX7LJR->H3QpFO&)ivlIk(XJO*T%aGl9h23q{n18ep@s1t1zvLdoMtdQA z@&&3ZU%=7-DHG_(3%!|7Lf7*0utmvAa3 zj-*29Nix$Oq+x_8Iu)*W;?cX4@y_h*58ZV|_)Z&y z=o;X~wngZFHW`auzthnESJbN5N5gYpkpHV5il5U)$HT7E_=Gg7{~1XWRsESaV?RAy zV@!rTvb5*uPwpg7Gq>12gnOpBlpCmirx)t8|6lzdMtACoI~a3cbfdZCInCS|%U_)Q zGAZ)zT1mGk`ZE)HsN@wJ@OVh&q1)s4W6z$P&&m5=g+UivKyK(e!B!O3+KW0t{lYH zh+=i{cRE$@f=;D1QEPb}+394{?EBZV=QanprR-UEuo;Z5$kxuL06;h*l39U^i zqAZ7-w5jbSwYD&yiKrw5-R1D{sv71Bnc_*xcA&x)zrT8+bz=bd$ArMjF%+ljqM)sK z3Bq1!jKj}@xpy}9wHLs7Z5dKit5DW=i)GB+hU)Sj$OJrx`qj7St?EblRhEW2)Q@G! zFA=r>1(rxWg<9xC?9_jV?vw`%Gw#CWOC6AFtHpBp64Wpq>7;Eb@Jvs}$BabujY&n_ zP&W9OFR`kr1S2!caEEDx)fICP=#`ARh8URWhhRv6Wed`%d(p;>eAUx zwx?#J3t1kBAV-~YI`*NDe&~vz>(*?vsc|rp+JH}dJ7FN{iVKOpSP~eF(57(kypCkK z$q}e&3dX9d{-~Jlj=MpuPh|Nf$>J+8Jg|&m9BO!Wd@g1@l!dUH1Sa+gq0{m`RjNOs zL-$%~rC%|v%86h*L%hiBh6{<@I#2i4WYEF+<#h2>E0rF;N7bsm6sPx+f{y%Ry@~{y zoc}{uo*L{6jo{jAjaTB%cyx{BMosa@tF#cPbVT6jKpYC?l2N)M6I~qhb+CE9=j&xG z$*jQV!_{yYxrJ`u4!E3pfP1>nv1Rcf{(c!op8Qwr75RoqPlxfhY!L2MZz0g|8tcBj z!eZ0s@REBDht$VNUT`16@=cHsDTk;<7Lvl!@UlD^(~VP5!ua7MMp=0Dv`ud*TjZ-|yFv*doMu4`>nMLQH^O1p8J9qPMB6n)LJ(txj z&zXf?{&)T-e;w6}fCIPxZ9F&eK{+S*w3oZTkDtb3I(^@yPOdx_^n2GHs{iau%EN45 zhCnyf=nJBE@l52r)`IF*ODxTCgsabS9F6e7uW zS-Q8{jnX3{>1c8x9caEmo31{lwY%R@^R%yYJL?-A2^WIxt!XeVSOV`=tB_`Gg-J%t zAI5YY>1+nsZW@BLI+g>d%CHrkEF7J183~h%QJQ}ld>2Zw`785pc~+zQM-%E6-@)Nq z_c8tSBW#g)jm?E$aCF~K6t3pcKRWUkqicSmHt7qtpZNs0_)k#ZIE2&729P@QEo`b@ z;8x{B)xsWnP{Plt>q%L!=P1ZL$&gHVqd-lJM3z z1_fp8y2OCh8nO)OVm9ONo`9qcytumVC2baKC7-Hdipjr7{=PvZX6Z$O{jTII z0vJ#3bjo9Kw?Ij)d^HyU1@#h9vdNMQW`&jsh89^`}Y5_iT=oWUUr7l@45LVCLi zf;E?;JN#JGL0zoZ)7%mv39KAXk%bQCVrbST2sZh#^V%Sc5 z4&8~rN#!O#rW3@S4ANLM(DbYX9%=?lan5RI#P)op=*$nynz+-t8rDN0m;u>@vHPMRQeu(=gm_%M!y3)pt!e_ zNB?OapZ-7@pMJq3K7Ac2UVU!QZ%nQEhV_Srk#p-4KG?j&tgEl!cCr_qrtR2}dIM`F zRzQ*E!z>zGia}MD7pR+w*_$$1&P^5^6EYC7B^7zn2{2f30qtW$F#OyHp?94j7`_pI zK5HZ2N{;y&#-RN55ZgD_LsLg;NhYR%O4MWM@!Rv1=;1( zolEY&&1t#}aF4C>lr~9+whM2i-QNBb)R;y|i3n9INJ%@u zF5Cs{bXb@&|R#Tquh zKVDMHGIeUPM7$0vtnN;SZoznOBg!n=nWwrFKNEYP8}kC2?+>t?*Uw0)`wPEOKK<_p z1@t3$1@sl<1@)(w@#{a#;nCNZ{(4fFTE!r#5USTg=DZog<^+)*v2POQPs z^;LMEdYLW8%VxRasYp^wge&VkI}gWV3449gG97 zKPiOm%ezU0%|^FZR?%UpRE z7A461M~cVBQQycYw}H)oD?b!-J5=2`+oil55Bnh#$;a{b9pEBAUF4$A-QrrY{*prn6Nl}*FXmkysn`*H;y$)9bZb8Sk z1uM6=!c?;rCTlxTe&i10Svs*puLr}so?-d9e)#VF%y6IYC^h8O|CK7Bza~gf|5t^e z{-FUu{l*h~`cfu;SdPtSeEn|#w*IeBE%5}G@7>4nl-ro1)`DwA^_aEr2Gj7AL!M5-hg+R0mo|;?Z9gh(%6fZ`FlMD);jK|O7LHc&>Hsj?g zD4Ai~)lcI|a+K}Mn&U$Hjy5#i*@VR1*U^tzrev~uB~7k3BjHyjl<`W1(uL{e3Ij^}a#~a+Y79Y+)dF;RXtE~~>s=m2#0-`xwaOeZ>w9t31Xu~f~TXP&OuaTlP z={hv|q9cif1XEs3F&+KTMXxd#4t!xMZo8`C%5n?1h3rOK&I!C2>xH}izO4WAfsUUi zN?C4Od-zGLaXo<;Jr{N_J2Sp~ALc1oBVXAZJ_XBheTxddvh1&#FVpd9i(DbjI#yz#Srs;|tbxCM175{8W5ui%$n9yy z6T>#RyWK-X$9>#k#B}mKR!2#8o>e~Lk^CqEs(JOFrSa>39pTsS?B~~?HIrXoT7_5t zq1P|my#E<1lHZ`(<~ah!^ zTj(k#DzXQ#kKntG5`M)E^O`(t~*+QemxyWbKlET?Qb0#7idpvpF+qk zvw-$j+$LB3QFiX8LNZzvyBpaK6s!GM@}CF3j$?QKc0btJ`NGi83#FkR;5l>#yiRU# z_Hto;;yx6w-i?^Jji3P&C_m6bi0nM1vYcyKe&!`>62W7BAx!HKKvnV&D&PEyY%1Dm zR$(p4jc;V{TL)!dW`5JtA87E|Hxj)tOlK7Mu=U$?SdVC9=$bitBkd4A?jRhh+@ZsI zkQSE5JCWh3tMbz@pYf|hETc_(pd7VIjKgO%9 zUSxzlgLX$BgFU%SGfsvJ?P*^sCH@ZU@?SF}J$P_d-j*&&wJY^9rJGhvd*#5SV)c;80+!Q*n;V0){RmI&*_Td~hPyAPZ!5!l` zpJ;b(WL_SZu)Brp`2LbR(Ef+B>l31nxzkDRqbkkOx1vpvesp*sl~h~XsBzwR%Cnz} zDI$vz`*szQt9GKa!VSJ#z2NxJkLm0DaG$(!BGnV&D^H_h!clZO??YPlc03-l33B($ zu;?>~yqOCirzQ_+(}~c1ER5B{ziH#4Axb&ras3*#a`@IdW?#?M-VmY zLI8gQHszP&uQ|i`7o?YQ4?O7rcOkgT@?83xTD$3s)-!|d-|jxE!7-}U7R*}m8RfB!p9NOFQ|o}A&9bZ+vZ zDlT8-KBxSBfZOaVK$ANrlh*awG->4;aLEk^9L94wHN_#oq@;8Xmay^#tPgA4b0aE+}Vi!0M$Ykb0woSz8x?_nSOE z=S+mXya;}u;laW3m*n^PF10ReA+bL#)Yf#LHm5dHNPaDy)#@adOMSF@@gUt+{7aJl zqL{7EaOf{{Q2sz2i@y-o3|V4#{AQe=x)+Mw?s&4mh!8c!=97k6@|r82XJ*VWsyJAO##0NA`4O5jZK z*8A`DVfkl1csb&MoZzE~yS5L3XSU6l3a^C_H-_zgc`py&@oZm& zw*fq+uY=$s2kfOCID6HFdGoy4rtlz~dl!nbFJYMO6p7OVG1y|mejZI^{1o%(*q4FF zlCiV_yP}PvEc6gG*!X;Tt-j+SrQoqijYr?||%r zcHFzuj={*ga2VT-Z3(@IT-nQJna3FP=z)hy7v6`oz{8~q`!g?NP%9mA-7MotEeIM* z{9&``H0=KDLZ#GtBz)AzG1H|iA4-mGC>O!=^iQ-|xr@?_u2Q0AJRM+}TN~xh5U;ZX z$(pPs69;D6TuAgxY9^_g%F(3=C6Ya-OP9YGkormks$HQQTnGL2j5nS*4>kHy=+YU7B%4t(*6pLlUoB+0pn-&Q+bG+uh591u zXu4V#J>LC{v?hF{bDRHCvxE>Dw~m8ft0-ioW#Ex87u}Dvv3GDSVHe#|%3*3Kq0ITj} z<&DQE7u`CR zK7K9LV!Gm4s0flou^=CQZ0M%R8_LMuKb&$ZJ;`X$n-*KS(8V8{=+j%4%OAgje*XXN z?K89J^*bpF30X>-D@_>xwSq?7bVxl-k0$2mQbdU=y-uG^2ZE&7Jt*`_`pyYZGu!E&>9&NTH?S<|E?wGEwT-;Lg^+_%5v}vR zMaR=#)3_E<{LELve=`YAoF&UQ+JT$PkE4uf0A^;gT=PpFOlNfxytDVS%q0h`Fcsw*h8Humx*Z+}p-eEcS?;9`Lp==FGlS)Ntq5C=`tAwJA zN(rSjNFt@7z0=-HLJ190$(E52AsN{-+hb(>uCL$m9M6BxfycZ1{(Roob)K)+gkE~G z^#v*Xc|{VbkLX$9LpqWDk&HWq@t{Tmsg^_G7$A>XLzN+HqK^J$2S70o}_coml+;M5gd6`SN7jO>Kf1iT(sndu%$85i)$FcTr3pO;L zz{|pm5I=btkt#iZu2trBOZJr1{R3&W&0| zc9KriV6lLn?wU#C*vtIHc_Q^bF(;=~TY4$yMj!K>$i00jSq3bjC*|{Lk z6-DU&!Ztzcww;3f$p63pA3r@>Albc3FvGh;U{mv1a5r!eZFEtmau}1P#Wc!)WJ#lT z`_pBc9NI0>Kq`mXJ!ANjdc0)eRHKeGV^a)Xwg^#^UEz1%7t^$Nz|bQY7XyN@@e$wm zPP=24<1&oPnGZ$g0W=I@$Hfxn1!!=NL{l0+=Za!p$Urp9h@j`4B>H7VIm0Z?{R&CE zZWP6!O+&G#U@RKnX`sP)3LXzLMW)_#1f|V}PS`?NRxC%wjP(c-3qX(1CbTdwT-Rs^ z?|l-W!_V2HlQNN;wF?t8QsK8C1?Gd2a85e|PRDbhIjtN^_4!Wdd=wgrr*LQZY0#sS z*yC~n^LkD~e9&pE?mrFXi>GiVx)nDZkK@>xM!0c5BZy}S-RaEl5j%}KdG2u@z6jV~ zMN`%dynKC|T|QmdvbO`}))(<4=`^ww8gZ#$AAC3;SfQ4LxUJ!^>RgQxpXTvA+HYH+UJDYcHcQ7LFA5%!vj%c+jGx z#q?R-mWnc#&<*8P?19)qA9rmdU6qY=-OHUK7Fv`2Y%@BVq{41#3G$qLNnjNoA-JS3 z`tS2!NFxQF?^6Zm*03+yWFYtF$-nAUDQo{-vV?1ABg{hv7DEME0!h|_>B>|8g9*F1P{7@3O28knW@mtRVS|0j{ zP@VvpQA&{Q8Vw!iA=u(M6f$QmdtRp!{eHmZ51KYW%k za{6b∋6APi-LWvl7lfS3^(L6AgFS%~!S!gBSXvP&)*g73=_-8qX}36qGO%cKVJ? zluydwJxwb7AEiJ$CKazta$w(C3Jl&4yZ(cy2|tSQ702+4b04CC3oV*#Jc;c1YxN_IG$a-W_Ve$I_EHqH`9j`JVr`y&ct4u4B5{RY;s} zhxn_DSa$Lp9=&OTXKNLnjLCtpVggzM!nk|14o6?jhW|hvc*)7*`XO<2KEF*`zcQ)l zygfY|Kb`8E^~m$3E?JzhB8MO+O24#(P6$?!gtH%cya*)E)j>3Wf;ZJn*u=iz07@9R zlV0Y>)6OT+Lb~Q<$PpW8y0vhLFOal%-)N)}Jrl_9V&fcz~B zEWEx5X^n0W8{mt0Z69VXY{0S_FBFtIp+jvxdYp`~F
  • 7ZtEgRvxEi$6~^r(P-wm zZSF8d9IIDGNXA5*d8Utbng)0|Ll^nN`nYXj3O&v`HjNM8=O$?gb0=mo6? z_WAAfgUgAncsy+fzM1a8-60XEO^m?@(*(Tx!c5@BSt#0=ga1OaA-z5mqg2w7SdxyZ zMLEoWDMY({IXZ{$#Rj2j{PkznpG6H`Ogey@zRZ1I&wRHlwK(?tC?-5SicJ$6q51bP zelq8)Sc5rVKDC(Z%=bv$lUUty7T(J)V*Z0mDExd0wG9`sSLXt5)Skm?k(119KLVeM zz4-ee3(iZUQM^15PEIc9A376nuS`VMQRe5cWBhvU1*%xGi*k?Ikb9m>9j|3yi zmbRfHKWDNwcchrx&a}}kh<>jNp^~$)q(Xsel}ToMUnYT zA2MF(K<6qk(^rCrGp}HFFaW1g)S%IT}X5&ttE=Fz~i|jX};dFQmdYA=zyj>A?h06H2V?2c4YU6yl zF#<1};Y}=XAlw|GqUI1^F&n$NE1a8Whc`SI4=VRWm{k}eg~Kq{VLQZ*24hS^7#?!} zAo6c4GISGRVv@>z&QzG#W#Yd%xv*GJgl;G1!T!ua->qz%=kNX*6Y}`GCm-=cO3-?@ z9P4kCGfTPxb?KE@8L|)leO2%{QjO{!cDwwlgU_%AJPZH;$zkxRCk8TOzS)xF>TE z7ve;*5gr$*;>X1yc)YKla$Z~@i`$trKg6HpY}Zl2*mbns+kw9STuEQ2`q3>lUy3*N zr&V&%G}C~y?)gQeIe8BSO)Mva^+n|Qw482z-$UPV0X&L~IJE6(rFF2>yFB?uT7lmgnTOi_7vgKw_<>~PkW1tQ5{nTqk>9k z3-5z%OC`I+s&Jq4nJ=#&#uMclEOe~GJ?>_{8CVVPyNB>?^AQ9+IgX&o=aC$L0rN#J z;$rA|ED1S_OH!wxV%G$rz4e&;gZXll&$;Jhm|BEmRR?$BD~W#}EhspRfoOynWa@s> zk@0O5a=w_pZAzzJ=SJ0K|-1TDaI#-d`g(jN)`7C`t z*-FE@>Z#M9mZm>GOyYYhNoaimnM7yM$;;6+`=vYCtIp&cjU4srwF^3wX8r%?zj}gT zYhk58TI;Pg803Vna&VG=s#HtV!;Z8>L6Zl1%(=TGQW3Kg=Fd+EF1q zEKq>y3LO|vH-c&6Oq`ao!`OQ(vE;wyIJ})5ZiO~D***&k_6e|UHsQ}%V>}F=irL+! zSX-rw{_hjOU%myD2gem0gwTVq`(--l=w-@n~4XVY5F$~mHhIZ;1b-SA8^07vFW z;G}dcUPdRtCzNwVQ3>pbOvbGL(y-7t8|UKl@l3Q3Lpt&>^l2XYcbD)zZ8yC5OuyDw z!7*z;gmo%$%B>tj_ZKs#g8hvNc?kKNg(-qOb}wJ?&xlm7y$NPB!n5MiG{@9kOD%PC6VcABj2w^MY|9ny@wMN1>DQMu1q>V9{U-u~B2 zR*m%(X7P|DYP$FKqpKc=%u|MJ&8!6oH5n3@YZ#DUeE3kMgDUus-keH5ge@u z!BX?^cgjK}nAqT#vMo~Vtg!2;0E4uNyS=lpSltr$zgwcb$pS*Bra>lbGHjO{Ao7_7 zj)pH~-pNY1+;N3}+6Jh`1>)s_0PK?Xg>H)v6uxeRLRc_n`f@Mxcs$~5lX2BN4PR0+ zur!igKpS%*&Y#~WSIe+9w;T%di?Bbi0P-)(Q2wTpXQ?&ldVUCzwFfZgWHnq*RA4=4 zvnAx&7v++Lm+qOEVUi1DuM+NB?8eaSV!Rn!fXXptaH+1qhL#H4{aV3}*gfo)+7H#g zhY%#w02l3}IGxr6aidch+sCs3sSDWNcMdx5*fFu;7^Yg*;rAKlfOHk(Ol>+=+ebmn zb3Jpi_`R=I7gizT(7jCtH`PCoL~%C_PwS-oJJ)Hv{Y`qp^HBTG4=GFgGR1v7Nwy6a zY1!{iQhI!wgm2!bi=TLA=J|!1$9$w&hA+tU+ilWIy-I&qwb3TW6Lh_-g}O!^Ci+lG zvl@2MFIjK;Jl2SRjy?(&IC=j&|H2egLEWG_L4#qxV4l)A-m#icq@OXJoH?0(Jef?b z?~G~0F)IppTSjNEN08gBDmuF13T?Q;bNFk_9OAp#Pf_N7C7R(ezXwjuvt*tUqx=z4+Y%n98V-$-lanorI3hS8tC^{2*|II?@%$X=jvO!M5D%7fZVrW0_i0ABp zlOO`Gb0RU^YbUgJgrW9i1iJob@wj(S(c0Ee))K3Qvm0&%xeoTN4(h{ z?w9Vtommwy-CTm3RpqeF+lz^sHMqT|9(VZNT`s2@lV4RL&8-A3`}44SVm3BNWn--q z^Bmf8@pMWt9DbBxnr<WhrhAEyI!AGCX1aZ@Uh2qwVXlZ^%*H*w%>6>doxx zJceAI7GzkTz#bfjZCfL*wbtPc@0_j}mqIr>3%h0FIlI3V=b2~Qwq1ZBOSLgtPab2Q zOT)I~FP%L9j;gjkp+}Ei)3`jh&)K>PM#=m~X9)K>|G3g5Rbe^VdubQY|zJ`L%<&j-Z81DoHO5BgFi-V}nf$Yv%WL`D`Dqg4z#^8n6I!4C#u*ZH6@e#SGg#fUWlz# z1!!$9#MMbfDBn`Vyw%+hL?6Juzjc^y&rII~&2YYQ4CkYc;Yd>>@4AoR!A0KloT}$M z)In4*Gqj7JGiNOFQN?$THOz1eHupkGmMuzWO^3@89ju)?7Hv9%uqJ%~uDARo2aWIa z;^aQHA55)4r16F zD-7KIOe@u1(Q>(7TGe))l=)|1cuGCl_3x%Lqd7AzGMCbt#b`lp%)j$5*~q;|j~(q! zaQL$h27~=@Hf|dNI-=lbo5Itu*i#crY0bJycRpq=YOgOd=p)Z)DV^hPRV`v`aaU%lt3ebZE5P_!89l<_22n>Ma~!0c$^cAP!glxbCsy8!+@H08qxl8 zZL%#^r_mcVX%X|lqcZhq?#9`)@PiNCD$63>AGIXSteGN_PxLWD0#@R~5cz8)&I-%p zY^VZsFcw?fm2gpoiKO^SIN0t+i6uMK{^mhqW&z(TOAzH<4&NYV zEg99|_@r8-oIQ-qQU@{iRuy!Msu7*S3`Ri{78aerL;F+sxvv3nrh9n@kdMf$RD?^! zVr*|DOvc7wd;)XdGMO7aD+^2CW#QBBZ2YRrW9C>1rs$PpH+vqJ&0#+L5bo`*Z@@3^ zZ;ZH9gUN6AqvU1<9=8?Y{?Ro=P?&G9YvAx7#bXcj6e@qwA5%29N_4Bs1=#dd8!oMs$GS3?8#meym}$9h~iUJHi_ zhoQsWnl;Sb(e`RYZT(5Sns^GA4jqNjE@t}H7vsyqG|X8Og_wzWkXarzS(w_BkI99loFyqogWO&`?W@L;;=|~RKZq&p3tX>Vj%H>^A1=yg22wV% zA~UdzJ7uZXndlDPg`{UmXpz~8(4D-SSm%LJR!b1n$ypB*18mM##wOj-FjkYo=hY(6 z{Ur>k9K@5W| zB_OC3$9!Eej58HMO6xC*nzU~HpuHr5FZ0B3`-3FzZyk<aC4fxTF?$#~p&nqN5n6 z)r@DenvuTm7^Lr1qr$TUH&$mLV_GbPWx~p0FpGW2 zq!P$w6(isY`+;AUBQa_Z`ZOva&v^nF^ISAYWuZxJ7g~O&z~D>@4l*}p(||;XyT!rW zka>8%+p$y4AFH+3;{1!nxEv|K=WDv~Rg=S@JZTgU=d9OoN&HnGh-rMcZk;2JC6}a8 zm@owSzlFF5z5R$>`uV61^8s-s(kkt+Sb~D0k3>yWR9; z(Gz;{o(&g;@tr9iGsZJp z$2%Jfjmn`|Q4J;kT3oAPCr4g0JK4@4LZS`1%*tG2cMeXIPoq=(4CdZ##oE=)NK$UW zSD#aO_2dE!z0RV}{S+$Bv|!ST78H~;!iGHzred`a{auf`p+^uo=LnXI9KjX&gE$aU z4wWAnuyIVpiRCf4eq|?;HKMUbJOMerDZCR%h0dgO{J5Kmy78I#@-7|so6?c|B^!t4 z<-o5s3sq6+5PzQncYZ(pq7jFJmT1_?L}O7(gDco_)QHneo}DYAKG?893J&D+!vOHLt8&R-SUA% z2YjO41z$)*?+@906NTaiQO?*({`11x-Wq}f1KG3W#Xmy}zS9VkK8o3Qo7SbDrDcIt zbRaT`PN%IT$%~`OHt_#H|GrK01b+L@3$E!7rs=g4De%Nhx-){E-=o)3mWVe^Kfab- z?Q3Y}$CXsGX%#gZcu@O}t@LeNETy>TlZ|^V&y-rocyb5*o!&#w_r0Q*Uxbi8P6WFQ zWO4iI7$nrpuJJ?+JsBZ%Vney{Zhq272H!kX1+s4l~cpj^&jW?<2jR75l- zLqs(Wzm~*em}m^w{0#)#- zaR@SV#c{#l~p5yQqWB1jD$0PTwd@l{3= z7vBuTft}1rx+;Mmf25HnEWx>ZVN}@sNB6y-)2R_xX~wN)GF-if#2>`b-G%nlI(|6q z`jGbT^S`BfuHcO1X~Ct9gJ}KfNp$tpJe~nLlgTy@>N4F#ceaPn>@EHz&3v6nvOX01 zW*hY|hpA&{8m;Kerk|&G(;l~aa@K5P2J$^|$4u7KQ!r~BA$Rd{S26@Mnu);(a zFON>c=VlwcTfY_)1wmNR7K3rjhg#W|0i(HjoVlt%W%(gozI+sFyHBFn;Q}%aUd8s? zxB0vDHa>cF;r-Nm*k|+rU%MWna`OXJ`t@LQ>}_Od-$eMO>u{WW1v7a5y6HkIJEo4I z{Z=DVn6YjAe$KImTAiv!H&)Hf)@)uICC=j1}cG9Rk9 zp56$7(w0y}jE+D{RVcf*LZEK69rBm9qxDuGau)`{*(4lWZNgy98BUkZKrHqPK>P+D zyb4AbrHu1_0;v3F(hMnx8BKC)O*E{pmtL!crph2;lD@R*;sx55TML~S5k z-VT7GsW8OK`{~)z5A?;cn@+f0r0rJq^nO<%*(gTPTWu>^^hTPRC6oT0|Cs98f{?Q( z1@&%2D8F|KwS_LE?~}5|T}h** z>k8@5@q;9n*i7p?+UV`n+w^$kE1IG&iZhmjur*^OO1~%~ajFJ3JvBgltu<1odcZ*} z6c*ue&^O3{zykde$t-f1Nr@F z5Nlret72%ec^nyS%b>B6nY8hD7S-)frgQ(L(#N4?w72aLooZ>M z?9JzCmS;Du+01v=p;G8B7zXnmMR?v&MM~Qw#466g_08^xH4lg3_hiV}od$>>45sHTQJn_!RJT47(e_uR-3)W%=3M?z4{$8jo-j~ z(n~D*`;5KF50Djb8$NdJ_;&9sT&r5pE_4KyLk^+GZ6A(Tmq4n$0BwCacr-U3-;>!N zKaI2D`|>a~Di0MCGhiN-g2?SLobw6BHFxGgO=SP@oz>{Dbc1^PDrO(Cf2Z9BYUgM3 zd~-HPaUR6n7Qxxp0q@G35IEL_ePaCI%;rptr8)C%r(i;+5eCgRVRrdcs12No054-) zR@6s8sVWq%jlf|QNgOyL#BPw^jnvE1xdj2q!6B8{YXLuuSgL1h`L0&X*F|@9ZFkiX!2gt4@jo7 zOb)q2#(?|Y*kdeGuEp``aXn!IA;=~iMg z&yZv3?b#S|Kaxb<_Nk<&okp=YlgTnJgH#+!X`bp{?&8*vXj3CKEWSbu=3>w4Vu-fyM)sOYJlw$dvKxn>URIBl zLr=k6R=z$%oAi%R;__0u&HX(C`&D#!tS-qud@JZ4;`8tP ztMsP}X5Ba@PkJmT6lY9^Hr_T`c>ki&#wd2~KQ*hbafF<0m z-ptI_IiGexcux{eKVVO6a2&=tCqRN3MO$B`;Nz2B=w()2OI;l77KCF4bL`#EuZ3;q za-8wEgXLBJNd%8BU|IU9LGY-dMp0@%{L~?fhvplX$QpB!~QIHNEigGt8C>BWJ?k@?x z3y8t>wJ6dbN`VeZ<8yoP;6XR(Sq_W8+skQJ7TyVsK;n-a}?l5 z9*muJJY%dd%efiX~2 zQbODeE!-$nL%*m3#=cR($z!^hP;9`wKtmkiOw>^)LrmFfgm>HZV9>3GU0GwW$ZZsY zMvulP_85GMQ-lrwn>}70p>O1PhAW43g^>u}KNR*EvZ$3E%-r%p_!%`A11*N&%>d5Z zw+-Q*sSK)S4T58wG(NqNz|D9GTwFH*4#vM|!vs`*HgFw3gl-+fAMG zGD$;zCpl{@r4_#8=s)*PL1Urqzw@uDG!+OxKO_iW{#~H`L7qg4jcLeiJ5uuSqs6jO zWb`M6RxQe*+tXk<4E&XGU;qCq_Dh7GTnTXdgM>js`OS0S$~d9x;m*W z@*b^{7J}GCDU97P5+aUjn6ugx31o*G+z0Uqj7G8?ziXXkw)TVq+$bu<8_#mgGpvUB z!UM1kZ9wnGRvc)$ibC7__`dlmBp*MAw%touUVI7JwS9PW{sSid`i!Tc|3O*p1LTrk zLB*#R{+V3}Sbqf$mZ#CGQ;#2A70^@4#=)Fe?jl7%a-JWW;ypkMe39Di2ZcqOk>wfz zqw_n_ue1%R0|H=wcOAxUbb{){1yJ~F!aIh^P)lIf9LC{Uvl8ylRz>Lsb+|54#>-`z zsBoJI-Ox#xU}nS)BNGfbXo7L)r{VAFDLCNI+0{=P5E34XaeHKOD18JZBo#RmHx3I{ ztH67OGH#q5kBp^?a4DBZd&p=sdJo5{q|x9uKQ4=p!seC{I2SSmuOy{_atUlWDhb~b zF*G&|z!EL5bELH{-0CEhYT+q6foc=#OqPRlDTV`K(HsYP6T< zfn{_js*Epg>JcZQEyZ?=}hh>gRH0IpCSbLSE6{-BZH6IdB^3< zo+wO*u)|`Ee(DRq@jG$nVLS#&q(fx@?{-QGV8JssQ?)%ft-cSXZgsG1ZbiwW4%8gG zg9m))lWTl{uKuTZKKUhv4SS7K1K(g-)>{l;*vBrE*XWCT!u*C?7`4Cv@vMBCaQ$hILEDyb4S%-V4#M9V>A)fI1y3ZT9|uj5)Kv_qtbpR zghggyrw1@0-W>YlO<)}~8TYv7T%xRs9oNQV$3;zaP1k^mo+iviCqZnP9-6YXuq;U( z8gtYz>LlNpyA@H{$=nw+c|=5yg639PO#3R0i!Vem!EhkbG6v%B%I{><_KAju_K>RF zWePidnl2A(qP!aiDLuQCbibw3l#qCOBD0Z7%0L0kN_EpZDYz{)```JmF*6hlNUvw# zn-I_PlxdK#fO-Ya^mu0=8S2H;49!ex)+(d@ss~AobIDnuN9odN&H?)#Aq9g=v^TDk z94|khM@mmJWuh90hVX(RTYHa1Mwf~KY_ za^5LGrGGfON6ElETMCQoM43nYo21sgrn$^XwrsmeyJO9lk`ho|G>IA;yy+Jdpg7w}oqeO{k;rc4xBV69Uz3f$&GD#Fh=BM{W6({6opy?K889jBdY0?x- zj4{Hpvgz#aw8V0mg_zK@6z|ro#1I`vXf0TYNssK2GMVp-Bdrl!yBJ|FY4-*w`)jj*=dYEbEAWY_6C7?3q3y>tsn^De9?tV;#!NivT~4FN^Gm78rG~_Z z9jBn^EA(tzH5RwMKcIC1b{Hcr&c}E`Wd73~+Q8!_Liw+_+gdb#)%L1T2KgRR`2B zaE7U_3l0wF=Sr(9&l6Xpp^fJU)vl=3UxV>gYcb`*YUpxbMx|&aZoXdtZM_s9rWz+ z8T#(kKwD2$Q~l3UdNMYLu1h46@}r$3lHy5XtE@Ct&2zb|zMzEM7lKJ_ix=I6!OD5qXXZYQuEa5J-5W|Am4)olk=%n+z7Kri9>#)T-rdT!p{utY zhs>{|ZG9)6ez*a}w>Rp=4MGuX8GC|ZZ|j&@Tf{tk)8_Gdmg_{9M;Uoul8 zfisHH#xPVd!MY{PonU_U(L?GuK7{8|zowwC-3->bz=+?oxg#_m|NAF2couiLreg|! z9*_5#Aja1Mm%Xg<{iHo&`&Pmue>o<#+v5TI$&deb#KPp&D17gVKMgME`LYgswS1tp z#1Gu~>H?Ifbn~?~=8-1ZQcka=WzIIx2w}~9rA0V}X<#bsxmkw`C zrWM(dBzkr;T{*vk9-TI)@B7EmgqRP4r^_n^V%EC<&j0IwI)atl{hd=UOj|E$(BrZ5 zX_JvRO_qx#`3bvd{IVi4v)@lHUz@0QdLpn>N{CNd9L7s?-}V!OBn9;#U*QN<3coL1toix>6JldsMN#nDeOzhP{u~3 zaXdShhh-zP!JRaq{GTqo6b&%OpZ!y7Eb+Z*K01`=qQB1qBa8^n1AtS`R_M`kg3%8z zC|ufvI;Hg(ebOBX`dm&fg8p;v4t^M7Jck{*K$`B>Bi#3OWYDtgs3v6NlR zPi*pepI(BijeF7NU4udPbyzOo><;hro;9_=uKffiY&(T{KTq(_&M~w^^K<`r4R`M< z_`Ny{5eJw@Y3Pd=*B$X@lsP`APr$S4F}S*28aGOYz@tN#kD`Y$eS$Wfa=`^=05bkT zs9#Z4aHFVP;8OTWa4UT*bH6QUQKc8<$3#+XMIx;(NuzW7+5eb!j6Uaeuy5}X$y$CT ziT#{AHJ5~^0((cy6!H6>Iwp8?$0y7PFZ!qBqpbzI3oKD(vKS}WS-IoX8qhEwENb^d zU+PvIz7vex^az-|h(fDHEH+<`$AiiQs5Yjcnc1v@>tt{D5 zIS&IfmS8b=HX4_EVELvHJb4p?-OBOoj*EdzVH8#{Z{W0D2#$p^^GYuSLM{I2)Lw_R z{;oKB-4$VV{C!Zl28I(>!}IkT=0$j+Z7ch{XghKYw;d8y|wk zz{%KfO%u;ot7C=xIOH44W3c;BJP7BkP?spC-~3L#YRm>2dzD80|n%uwhkL@2P=v|jDkoR~akk@AB z<2=xuEgqa9j;06I$@Jh`7TMh?r&{?&%1>ygscjF)P5djZcs>ByTgV-lksDv8hm+>sT|7i_N=5qvgE{ECf4VX8B zUA&*;q5UO^{f9}o+ZKmGGnjd>GXmq^g`;61X8<+@KqzD#W*>LP$=z$w!tR4FRc@H> z;D%Tw53KF?z=}*Ccw26T@w;t^>J5NPp%-q3IYWQ24K`1nff-A5**mHM`C?TJKcfJ@ z&vH<99*!vgL8ulH#hC9amoKCXD!&i=cmBGXBL%bjGX(*E9t+Mdmt&XK400I4U7+>Fk+sJ!I=;Z_?7G9V5bSfbqMPp%)t}$ zg&6%~B|avuMRkQAwyFo?azZ%1?Tdi_g-{qYhjT|W3f18;sM#EcSqnI0u__TC-zA}h zy(^1@;$V^=gFtbf*}2BUeK~V6ebNvkpN%2E3h>}#F{&cUaOYJ8^4QT(^=m)QY3;?# zXS<=#d12wnNmv{a2Gde^WLw!_=X6dbdzBTckK+@C~ihOoiw{e z&r9FZ!CqkmHx5GK8hLy^IuVA)O!)V=!nQm+SiM+^poDeER0zk-ngkqtlLDEm$=Ez1 z31`#z&-*eOuAFIEtQH1gxh?!`^yEIXE9AC#pm6P4e7)_?JTgzrQuM$f{!GLS@`l}> zEikML#BR#~M5XxR(PwAeP`1XKA?D~9FcrSfC!rXsIH;w7AumQ@rP)yEEF1*;rQ*mm z_(@8Uk7@3v3pDw83#ELnr3)&1>8D#h6@E#ktzF@C(UE<48na1nln&jFk)#cg*99}B zlLY#YWd5DMQPvPaSAD8rc>aCCvY=6PKf;{kGu+ANQxpwIP3QYVG0pC;rt5!NnFV}} zEajimFbxrfgpE=acY#1eVtu@Gmy zsv@xU#ZF9~7YW@jJ274}23B620eKw5*@!sQwj|(*ZW2^ZCSsm?3`TV9MCye|<{xr4 zt34LM?32_kOh%Rm&j{9L@^@+uB&d+zo62yXvtz3sl*0L35q^A6hqO){Tz&^3G{g-b z4=uoDZ(}I%{7rGwFuXPYLBE=AlH1C2RLt`duh0{;uDz4Q-5=AdEB{f(d@(2=9*!{w zR58NN0J_dI@vwOzj60U|tkw(HSA}9NVi0~Y9wj#tpwB;_Q%A(%hE6PQ@Lp3qEeyGu zTX9l+6Pl*@;QQ;1IQ!QR9+G~z<=_KTzl{+2&kw3~zPJ*(86xvH!J)(#x8%H`zswnz z3>KhsuLX3cPsfVghU|OOVt%&xJN#+7&1-WWYxD zH4ds;vDjZ2gI{l>F|#=a`qFWDT^xg$sz@|c?8G&YmU$Nm%dxTi9T*2o znIvYXa(0{V3OVe^e0eGl`iZ$1&0bDDE8gkdi^O_oe;mE)ireq4u}EV&B&X^jtamJK zG!JA>5c{Q$caW>uX-chPz8G_c)Xw+NeYcm?7}-zDiw0xM(#-7;BX#Dhz;tn6PZ^FV5uD=Z{mAB%l+*V{)Z%4~3{{L^^ zhIcQvp}KS{uBrt>W?BH$CH>L1WHZhk_rF*Um_NzF-mxuq)|H@DPZC>&vQZTHsQ_%87mTq(IyJq`Z zy1X=o-go4ZWmy&3S01O`Q?HR>nE=oF*I1nU>f%pJ&!3u>;v~b7EHlb?)2RZ zoCV`UJU`jtfWRxOabcz(Oft5i#Cr!!&BCy9+fFQ79|N;*F__C)yVnn6Q0c}qfNhZ& z$LH+!4+>ybx$JW9-b8Fer0YQ*BiodXFXGSVRhB zk7S@#Ap?6hra`wh0dFRTV|)BYED&`?iG~e&k_F5HGr-h9CA_>Qh5TV(D6#z!y%^d< zG6y@Tv~-;gedA8y_VLG*hng+oQ1n{1LaKPwb0)%nq$Sk-t)U;zyi(>@*#Wf4bi(l zgFJ1f(#V_KE4R&#+I7uoQ~{qoJRU+@Mf=gSUtBA6?K^IGzC}^>f4D7vm-})qV#cHs zs7UAgRdXj^cO)Y(B@*8&X5;H7!swgYI4mOx)9<(0o`w{5Mq1+E{y!GlBP{tI%l`V` zW^!9VoH=RGMLm{c`kc{ zJ{>-8LZ|y%llE69+Ph#1=PY?r^$tH;&)2^}GK$=lVn}Bm&xq#h7WFNW=G{&rcg;jf z{}RvVaq+a!A&zvW@{Gf^8)&<*n)HmBD+>oliwN|n;c1hFRiAix8a-{ z5J}bZV`xHg0@cq=rDx-L!$c*M0!`BCX-*fBs-Jvw?O8~v%T)6aEL@Tt-DPn{c z?VQ`6`vXNt?^qYFojzdm;CFcF(t@V8yV&~sAr_auK%o0?s0~mcn^w-AaT!f!E)(dK zu{XIXE+WsZi|C8W67n9kg6{IY98Ba%T)}TNFqAHRI{VomkS#UPs^BR+G8r z8nWRm+^FXpxIaFIYaG|p`Av~j`XZDHE0$9#?+G4v_okk}>D0{iftf4ZNqX1}N(*+O zxUmjY965%p3;2A{OqJZY*C%a?C^eq>jB^uPpkwj?by_#@%<%$tZ$81fiFs&_+sbtq zoCWS4f`Fqw5F06A&jEdmO_M~H*L9|{B$oBs|BwIGDfdN4o4l3{8giYvmMLJ+2Rqy@ z3&!sCSqQjQh~u5-Am(=u$;VsJn$U#0%5hSFF{ zkdC1z?$NY=ei&KnhLHQdP||hhx#G&focR(=liP#o-m+lIb_^lqs9;hx3!(XrQDpWz zma26VXqQ`102e(X?%AB-yTsB&Qwg$jmH; z?Ec1)a9{&z%16?U%_})aZZU1j@T0+&9^4B(k+`{t?6`;8&ul999q{)t(wgk=nUHa@ z1~pqMQNMD2_rEGa3x2$ZRZA15lyM$!!VOffJdd{1Cs1E`0Jmmu#YWQv%vutHF?Zcj zK1x8sI9)yy5J!#4WtRAQEmO<+`j7wZKcijvyfKn(kiW{Va$P9T-bHNfA~=+#!tYN$ zbZ%9_k?!z2L<`1@|A9V9ak5z|Lmkn)27RnV%6A6R_i!~ziO{6+&PL?^)r|A_tjSf> ziQGdxX^z@L>h@ki%O6FNWo9hB(o7&!CR69W6sk#2p{5^+boy5emFPxOY;OcjyUY7% zqCwOmwwOeV{m4$lk3_uY(~3ZUikY~SmUb?q4Wq;P>@JdsbA{9AZ=l$`^)yv(9cj*3 zP5vz_=y>)r^4}apC;tSH)qQVTZ90k8b1TXB^XAkze-sU|A3|F`%8;M47*(kMM4My> z@_QdbY2qDtoOz64JDYItLMz5r{KDL7c{)}zoF-*hl2L&p{dhQ)!YZe8KdA?;bDB$+ zqyo7HH<-o_ji!6LvD7{(j@PvD)Hit(O-^4=HSeS7^``Z7ymc*IKfRu^a$;!2hmG`1 zHHtyu37$Q@C zu~ie!F~!H>?CA2gf9r4h`h(!yFPfF#y~0F?_k+6LXr3SEhs#M^`G$GrqEw!PtI`lqt2>8lHfJH zPac29$8MxdilyAbl6{ zrpWAxB=Lih$vqpoe8!dn4D4voMk}siGNp=8T^jIq5aER^>7Eg%7dQHFJm?R`>3qSd zEMXeU2mA9lg`;O<3S@9Xr&Owy7REKL?&G@WbpnASv))>#D*P%iD{Ey^J z{y3W9o=6rxDP+Oxz)IasbU{6e&ReaZPPrhenzM)kY-dwrmMg8yb*AV>Cz7h0KxY3< zA&q!%{+{^LQMq7JmX72cg(&Wg3Z>V^i|F?!ABwr^PM(k5NK$1A9eO{V#`4*_x2-c3 zt#_c3dP@>HWh{yxIrKj50y zm)O4kFKVp@k&C(x&2b(}27Qc{nLE>#8lD&2I-Tc*&!ZyIKw8rjLM@*?J=Zlx{elZ*+6&sXI!gO821f_aXl~J4>e23Ih)TzHh9pJbB>%5ZbxUy zigsKbL)#CSQXyvo2ENmwd-pisT33bhEad5`2KNc6h*CrIPpr=RjQMX~!<#c74rSKx zY=)CixV#@SC7IZ{I|e%6{9&%! zWKuuRuurQb@x5g<+ME_(oKp&3?%R)9tz~$z`zoe*|A$hvV?p+Jm=FBT|Me4lxeuv( z+HV|m5+&`)5@gGLXFi|gXjtPAD%h^i^&b|rZH5yqn&3rK9sTJT*U*npSWoMHV=3P< zj;2Y((#D!-deIm{8SYETC36A!Z=XYxHKx%D9gw1g4gKk~CJ6-_(%|pA{WDi8x13Fk z_t2VKmXY$f<+PL6W9HS~)E(hUpQ@e7*>nO`xH!=$37#*uQJ|HccGUEo&+X2Rq9Ri* z>ba>(ebZEVwznd^xgkX>cXh+_#CyDQe1jvS8)0|q4!SdLq5bkb>{WS)R<^Hmj| zZ>C31yT?+~K6}#VxS*6(SePNY0a!9G(v9$DexZm@}^akoEbsc>(){o zKbzL^-%2v#HDzx^a$SphveWx4MR*t6>c?VJq<=Wz#JPUob z5rwH~(PTxg4IH9IMRJ3vY@s}PbxV=3LzIFJ{={{jfpKh36TJBRXTZaAFmNn|!iHR~ z!%2k-_vuieFP2#XC*JAfHqU_B`sNXHx|GdMxJ+PI-ERC_|1~4u3LkGTVr56lS-yxE zV!cfepW}^%EBXEZ-`LRlHo#y3#@5~wK?4wV@|_wSkjCS*5q^EiJs4zL0Zn}6wUChz@ofgELf3?Q|G zTw^&%o8S1WHd<*}K&F?>eJ#IpsQ4>aSzRH@-P1q9n838@qm!GA=*{lX6-DpYn zzc|~XmMFB}L^_k=MsaJsc^>3ka(wSc!BhQs#_$53=jKn}r51BN#8Tn_G*UUZjGnDp zOgl;zl4_S9eLpdWUd8xO#6x%LyETcDUpkWk_r^V3Yfn3T$I`bKBdO=89<{v~Ml%ys zY42K95;~Mfq(YWt-;2|YTOuT}{|Ap$B$^FwnUJ)n8iZ{S>>vo(i%K|JWd zjVYvXglEbp{~;&Y}tGbI9InCdEW@ z{SKegS8sEqi$M;gtYt@)3#_RB`_c3#a0Cq=s7LjehLLkWH5&X}ku-Aq)2bwCnsHx@ zQs;=0b@^Z1Th$AR!JYqlz^)J8V)2aMh<__X8;um{2-j#AGh=>^k0y1+ahwYxkjn#s zKJ9g+q?E~I6zNI@M(*@3k7wHU_oUZ+PalnTCx;^*WG(JVy>Hw}ztWu=56vKnbMAD) ziJwos6Df?dv4X!kaJ`@d4ZLnchpnx-j$}0b%`l+c?b`IHdKeuTp+@czDx5hgPuEkp z$FE6@vJU>nZJux3zPky_H{67n;TahGJ%Zoy*;x1|2|B-4<73(!%;R3pS)Adq_lhFU z<+ZZTuazu5JC&7-SutPh%Kx4J8=eSZC3D%}qbJ$elHaW5ryjypT(J945Qf?%DNgs z%8eRLjknAw!fG@bms(QkBOCHQW6x{F@g%u;A{~gHOx@pHN%6%bl6>PtFPn(Y{&65f zF&nCTYe8zUW~9Du1jXLgqK`d;iH0f@+-0e@w?B>FFHP?u!8uM6)Uu9ysVS@*|L zrn@EG=DOj{++Wbfb>zhz`oy?CAw5uornjroqc=)i``Vx0*Gtixi=wpsVK;WAy~Vy8 z+}~wghbh}mV%GBg$R3x0cgE3pk?RL9g-MvP)rzwKha>oyG^XJ(E53Dzji0ifReu=C z*!|=G)<4_hv9RQXFAK^kVejvKW+s=_F@XfkF7QR@qBsdwgUwU(X%33QA;Y3v7~vqqv$@@ z3BQXspd*?3B=5`5z&Rr+q{x(J?Hx&GyNtAt&fG> z<-RPw`6$zIddqNA8HT)Q*zD+un_;0?_aO=A96(OWAtY`+f>!~@uyNmU ztol=hk9V)2!Qd`lK52yN^2ZR{^#Uu5Ij_d!3)X+^!xeWa8lEIi+0uh(<&vS45;B~| zF+CdpW+bhfWJ)1gW5_X%YX`m?(ueN`^xNKu8X8B^2#+x&(rrfDzmK8vOIB2GVoz0< zt?5-8uL+dRXturyIrF~bX0F3j(6iu-Fs{uN(WfM?t#2KmOjWItG+@_XXmO2nzU)_A z`_zV(k8NDP{u#C1KcKm`7q**4>ASo*877HR;ZJGW+oDV=IfH4ZxDL(pFrbms45>zA z1buHdrN(S4dg{h`R{nP6QEfv@n#a&VfWJBHx)F=?j2{J4jn?DN2^fN%Yl^Xp+?{N{|_B(MD?%CsJ+#c&dueo!)GZ8Il8oX z*DzXLJAlf5%W+LYKcbUjyyy5Eed9kPxbYRNogQG~r)ubymBQxL0kDr-Vf!l%uP!V? zspDj9GPFXq&u~mQ-4F9@TiG%6J&(OUBh*U}^?pZh6{^rXqSP>zBJs!+tyVN@TjN2ebcP~>=Hp363ZvgexeoIBnF z`eI4j=37#^w*?u?kD{zlEz&I2piA3^(ca5LIMaq}-sj5GS`GdzS#w{`VsX+>kfbek zQgpRWn(}AM(0-48RNc^@j`woy)FMs#yu^T<()Eb_8qPg|8Z?a5>GmuY%J$@ZbTBL28?(NikfcWxyWPLx42-ia>?!OZ;Klt8n55q5EHqU_vER;r~a)v7I zyNe-3?FmaLKhCD_&0yD^<}$^W0jy(t#=rI7S9ViqkebA-^LMbu`&XEPSvLzBIT)v% zIs3oZ1y^Hy5vCW0TRpMpdcr5_kS_`2RUV_N5 zN~Egtd9gzs$_8*g%#M2y^q=5usEwdqhyl>wCwFe0}!V~Rg%M561B>Axx?diKbOJeC^J^DupqGvof*r`oh%REN|x zG|Ambjq-=ck$JW_t$X(ia_4xSz}JVETzMI%R$j!P(90;%zk!o#4?x;4vA^{zw(XQ8 zSof!{|G&3NDbg@?Wl9cJBVVpv4!x~M-!z-hMSOo=V-cRX+ke97*W2u zHeLLoN*^P*e^W!5;=B7(r;#)%?-r+d3coR}r42*3zQ!fPSCGx;d)B2B+ADjIPiEKMQ4@$`m|$C=KA+jy=3)KD2589Y4o4UI{Y1hbT%HR(0{d^hd0eeuMVqO~`D0 zfB^A&yx(yKBPEWaFKQ2jo-}ARaSpg*0Hk7FQQ(PDFP*((MbLq3%90t%vMT;#_G*5E!d8XA$eHmbp)Rmm0+M< z8BFZT@hSW)L_gG`t@Rq(242ItA9t|g!xPNrtU9fPKhRE+p+nJ1WV=$0PI7M8DSvHp z)X=58ce-SJQit}=(V`jyZ3=qCS%ZHyXv>eGG@PIBy$95&D`^lVPgJ0VyeFBdD?;Z# zeSmA?OOz_yMZ&~d#C$sgd6#mGkUNhlhpMrC6xV$OK1FZFcSNq2q|9(RYM-G%L9PlE z_H+R44I4ySqXv^>KTR?`ph@d)YLI7x7WWD3klPns>WLXnUX6n(+-v}yxFkcZu@aP< zBTnXaBGknDBI`0gAbsBp9IU+!m!oy4?yZ4L^%dkyyN?CEuP{-R-<>VKK;;!@J06pw zB};f;$54TyoB3>~L7J8i5GT#qKXE?e6Q;Di!m`&-@%{Wg^lIEf_wmbEmr()noMKGb zmkT$W&B(UggsLII7*pR){8Ay-Y&46sjb*Fm6fl$b_3X0gCze|#hw|gv$bVvvzEk7zJjM-t-;)S#7r zIZrNHjoo4Y-e&^5NTPTM$!0J#vCUSP} z68AD>MVBI6`2&N>{{R!U6G-Z_%uPc;j zf`<~N{ZyteO#{e1MujTXRjJ)bg%m;*Xs(_NrC4&G_M30$`1TncE?+Uon`cw~eh%>i zx6pe362i^PVWnD%ter=AK3^%0yPU`2$2YN8sS$nhTz8h#iVA+`sAw0V7%ve@l<33J zoL{KrcWINOZ?L%QIr`e~p~2`X+*efN)uAdhk2?XE-b46NxeuQnZGoqIGV*UmVxN~k zoJw3V-oqZ*)g!^i4#mu6V%VYH#PXh=XA3NISk>{>O!nkBCK=u#WLquyxBlA<_X|G^ zhO=0Q#jN4bR`y8uB=gT|V6qKgSSZf|IcTkpo&!b*=^Krtgt3rKwL^WE9iNd1_;SM$ zr%q46=gku#?Jyb7*Sf*A+6&Wo9%;y*2<&dy03-iRnDaalMv2Kdnx2k|)-5O;zYBrB zc^DX6h+yth`|{sqtmJcSse%qXTHgm7eQ6qOFH4HQxW*(^kscBEz7Ow5a#m7geL{k& z`-xGfswfSK7NZ9*dy#PEGwyC^h3D4CcvycI4kfjaJ5`CDLrRbzcLbj1hmrKT7*8#Z zVQ|b@1X|X>h-(>NuV_JtLN@}>^r3#Q2z9zj(5MkSgD_f_z8sgPwvn8v=`2N$4#|+s zU(PtRk)exKlJtGsA2^A2K!QJOU3ty;BHf7XjZZ+Ccc6c^7M?w27!gs7g@^MHES7^G z?{-4{=59nUD8l-yW%!_T35Tt(LBae!+8#dT^SL)zJGKR>tOeSCUf^f^BOI{eSy&D? z@Yv)s*K<{1zUm2tWF1CP>3*EE+>MZFTaaUvgl_L>l%HS5nGGH=ie-3uaWrnc(8jx^ zO7IHmW~W^4u+E6%OvQ9F+ustv0!JG#Hsz_%v&rM%`j@t32nBEZu?RMqO;e3ygO=}Q zZ{JohbI}KEW=sbY{V9e-3wc!3DWl+-DlR`)$HZU_?0=^T?-m`5ov4S!p#}(FYK*nZ zO`&z>U&;p?nU_;bIz zB=6ZR7ak*3`X(04uET%A8T>d@%rjC85cqB%9BgtCb~FdE8}lJze|#C2d=)mPZ+|HRb$y;%RX5AS{c;Ps;)==J%*weUUIFz7QzEq#ZMH80Tj z{yyXnT}Pr-9rWK`fLY50d~d5jPH7q9wT|Mx@jgV%-3-h6B&4J!;QIbFj61apPi*th z`tTSo-Y7@a>r;bgv zeZ=x=Ua_SbA6V*&Z>%HeH!DsSN3e}J_Q**f>!KuH^8P}sY=5ZKD&X*`fyj8uvnJD2 z(fCmv>bEtymP`w3J_eXI&=eX=Z6UwM6#=&M@u+Au0>>nvQDO^fuJ47%AI_0jU4ny4 zt57xb0>%%&3W>r7Xt0Mk5_Jz}#@)oJF*ji%^8nrtAHZ+(T{MnwfDfO4&x*T(x2_lQ z%j_)T#7|;dMZ_;tl{ky9?u|oWOT?FmFh3Gg^h*P0OxM*=00aFU#^*Pt&xA*;V)s*~-_Xcn&OK!fPoA-c%>S6$!v9$1w>NCe`4*N`@QMvAZedjp z?^w9o57x6p9D3FLVW>X{o}Pwy?q`QqH*cJa;5^BgHTXL<4xXzM5oDVQ6^ZSLQrL;O zm${JM%DEzy#eAjhB*;eR%_pUS5nyU0;}&1OQFTaZ`5%-hGM2l&T~wiORtIn^{;Voq>`cNvL>| zgzbhY@G?q;mVYKr-P?j43%9~XJ`0XDsVEq}388YUQ83;g*zbWuCnmv?_vv1Go8x7- zE+kq9;WT6r?$FJA&OK-T*DtfdJk!-~$W}JXBa{`~9MAF!)mbY#1u2U>Vcur-f9v1W zXDEz(eni+cNtD@ZnX-&u9!y?rCF?xBk?k``WJf-yb3jlQJE@(;T1vOEnUQ(SJ^Kig zw>rp<^&DV@#z$D7V+s2hevC)IA7(qAA7rc{k6n$=XLtU~XHHcI*`fQD?8WT+EIRxh zJ0I4~Wa6bUxOFJBO)Pnyh!cXQxZ+gxbcAm6M!=qhs8rzu`((j(9GJ6{uiYM)S?A!4%RWdH@589} z95fm3LXy@Nm~2f(s#GkD*Dr^~DnA&$osCXuAFO^p4+VFE;OVgvGdqIO8MFk;_s@f% zd=TwZVD zyd}e~c<3`DPdnD*JCUuqHl2;A@nrH^v)H#^UhL%gx$O1gm28w}B=cMt&PGY+inxazH|h$y+;F>{j~sge&RxQXyOWXQ(_$}JeI#bx#<=Pui! z_LU_+>xa&86=aAHL2aZazDpWlm(B}_9x^7-a2&1;WH6U-#=~$&e4IWGGkNC5H#t*`wKs=j`&bNICg7*M6BegTK=C0b zY}+E>Opq0#`;S0SqXsT!tDyF@BD(9Oc#Yr7)~x%$(i0ysKgG*zj?GE-w|*~^>`P+F z8&|S}3R776&=G9!)qZUFf6s)X>O(@E<$PiOjHeDF{7+)zHHU;NuEII%-9mfvHNhqF zlW?m;lBtO(u%fhqO!i9ga}r`{N_Ii}joS6i8lRg`B|TL!T) z-s-F{d=MXUD6$E6v{;dn0ei1&!CIninZq+LR=GEXjaNxznlam$^OPL6!ls1f4!giY zv#+tV=l7ZRke6)VThk?}y;o5Dhej zs^h)J5d8KZigBwop>ahAKEn-QI+;I1C-e~#sD+VE!(nBhi_|@aFnVH&lX;dr14qEX z+vAbP9C1L}32AV`F$)H_Qajiv*@0o1EvI~8GQsDk|ZL8vNI;q|8y z-Y)EiK20&W)O4{!hd;1I@7^+>o+s?T+H0)(LM027J<7@!?qN@IQrX%K;mr1eH?wXQ znCwVBc0WjlRh2vuUK$@2T-R+7UOhAxwwfINxBeAF6CDgvq=f`2S0Uz8ykNODSD3q^ zM9@54CcIHNCmgG&65JP^6=ukt5y~f53VWB=2roa?2#5Ap3ae}m2!UJn39BrNgy}U$ z1nuYo!8h}yAbb9b&|>piP`3Xle3|t_2>PnTw*59>Qf9Wyvv4wVh@HW1f11ZmbuDI( zpGL4df8yA2pLCY?Z97X;&tZjM3fP#<#jNvL2`jWb%~p=6WKqeL>|En{wq*Ea=DX=C ztD0WNYCY>%+x$AFR$R}F4R5m_M)%p56_1#2<3px)^&b1(^ngV*JYkDdUov;|4p#p8 zCmS0lju)j;@U)lZS|3@=;-5k5<)x7jDuE+jBIqjn&E_5NVj5>YvyY}NEV1ALi@#UH z^KnnIqF<%#!`5T$XLb>r@G758h|Fgp!a??F{86@XPZ_&=w~U>6P{s;lPq5xKoT=tp z&vx10VB)#8Ow0BXV@j9V>`k@IE9MgGx_6PW-ZSj$!BQr&_XulwSj-}EianTJ#pZsh zW*(V!%)jOe^B1XOH&$I@yPlk7{ff%i7V%;hT2jcCZOLQRf3jIqR66UwHimukS~*<5{ZHNM`M;#-tjg*ao~8-l$y=L7dDy-T|3`7DD_|RZ~ZL~Njj_u zO>nT=cEcf0UrGp6)DQv+MhJA#Owg;e6wYn55-cxT2wrWYg|hSJ!iW9VLf_aCLQ8|X zFlA4FAv;P;u=bG=_FGB_Yb)i1zr%+MClaiMBf%bma3e_AUK}Hg%H1lstvDjwp=zPC z@rID`tU<`NelE-xYZij5I)t4bqU^P%EK7@3VkbAKGN}k{R`-1*v)@08-RVD?b?c8| zTTfcBs14R^uA&W-+-Jw0=Mme|>CBp)Tv+ud7nUM3nLWsJV?%tr*t>-@S?r@}OyY<; zb8Vi>&dLR_cdvrkycu!K-Yki^eo162%TrmSM>_i&n8r@MN@GV#Q<-ByJR7$yhQ}(0 zF{PG8%=GB zQDPw`(yT|MTbMn+N$78JRnY%&QV7h*6$baE3O~=T5XL2q7jz9Y1lKQJ4)znv9jxV7 LI&2vJ+5Z0kw_0Eh diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest.texatlas b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest.texatlas deleted file mode 100644 index 5cd9287208..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest.texatlas +++ /dev/null @@ -1,50 +0,0 @@ -TextureAtlasTest/button.tif -TextureAtlasTest/buttonPressed.tif -TextureAtlasTest/buttonSlider.tif -TextureAtlasTest/checkbox_spritesheet.tif -TextureAtlasTest/checkered3.tif -TextureAtlasTest/Circle_Shadow.tif -TextureAtlasTest/CircleFrame.tif -TextureAtlasTest/CircleGradient.png -TextureAtlasTest/CircleMask.tif -TextureAtlasTest/empty_icon.tif -TextureAtlasTest/fixed_image.tif -TextureAtlasTest/flipbook_walking.tif -TextureAtlasTest/mask.tif -TextureAtlasTest/outline.tif -TextureAtlasTest/outlineRounded.tif -TextureAtlasTest/panelBkgd.tif -TextureAtlasTest/ParticleGlow.tif -TextureAtlasTest/pattern02.tif -TextureAtlasTest/pattern02_big.tif -TextureAtlasTest/pattern02vertical.tif -TextureAtlasTest/pattern02vertical_big.tif -TextureAtlasTest/pattern03.tif -TextureAtlasTest/pattern03_big.tif -TextureAtlasTest/scroll_box_icon_1.tif -TextureAtlasTest/scroll_box_icon_2.tif -TextureAtlasTest/scroll_box_icon_3.tif -TextureAtlasTest/scroll_box_icon_4.tif -TextureAtlasTest/scroll_box_icon_5.tif -TextureAtlasTest/scroll_box_icon_6.tif -TextureAtlasTest/scroll_box_icon_7.tif -TextureAtlasTest/scroll_box_icon_8.tif -TextureAtlasTest/scroll_box_icon_9.tif -TextureAtlasTest/scroll_box_icon_10.tif -TextureAtlasTest/scroll_box_map.tif -TextureAtlasTest/selected.tif -TextureAtlasTest/shadowInside2.tif -TextureAtlasTest/shadowInsideSquare.tif -TextureAtlasTest/imagesequence/flipbook_walking_00.png -TextureAtlasTest/imagesequence/flipbook_walking_01.png -TextureAtlasTest/imagesequence/flipbook_walking_02.png -TextureAtlasTest/imagesequence/flipbook_walking_03.png -TextureAtlasTest/imagesequence/flipbook_walking_04.png -TextureAtlasTest/imagesequence/flipbook_walking_05.png -TextureAtlasTest/imagesequence/flipbook_walking_06.png -TextureAtlasTest/imagesequence/flipbook_walking_07.png -TextureAtlasTest/imagesequence/flipbook_walking_08.png -TextureAtlasTest/imagesequence/flipbook_walking_09.png -TextureAtlasTest/imagesequence/flipbook_walking_10.png -TextureAtlasTest/imagesequence/flipbook_walking_11.png - diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleFrame.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleFrame.tif deleted file mode 100644 index 392119bd62..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleFrame.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:839defde93893bced650c3aae365da2492ed5d3a36833f0d23b842a64459a73a -size 1069744 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleGradient.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleGradient.png deleted file mode 100644 index ab4a88134e..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleGradient.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9a1ada36ae4b3ef01744ab9041f6b822470c2c7595934a05d9eae8dbf4312e90 -size 38112 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleMask.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleMask.tif deleted file mode 100644 index fd29516609..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleMask.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8474b897fe02f70ed8d0e5c47cae8c816c832a7a5739b8c32317737fd275774f -size 1069752 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/Circle_Shadow.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/Circle_Shadow.tif deleted file mode 100644 index a9e9885ee0..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/Circle_Shadow.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65145dca27e8ddf865019947659956bae3cec4ff069bc0ff6dc4d87379fbd6fe -size 1070868 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/ParticleGlow.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/ParticleGlow.tif deleted file mode 100644 index 50fd39d881..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/ParticleGlow.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4633d813a6111cfe518853737897925b60616ad73f99fc47a4342c5fd2d5134b -size 267526 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/button.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/button.tif deleted file mode 100644 index d43f5383ec..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/button.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4c5e07103351b9c8a05056c00abc44370c39cfb9480f5e99d1612ae9ad45cfc5 -size 37780 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonPressed.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonPressed.tif deleted file mode 100644 index eec732a736..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonPressed.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c10511cc5898f3edd24c24099d3dc569ebe9f014af01a523b708d74523209189 -size 37804 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonSlider.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonSlider.tif deleted file mode 100644 index 59fdd32998..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonSlider.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:75a0174a65eb945fdb579816968c42de002ec6210f75add6d4c2829bd1cb8c5a -size 37980 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkbox_spritesheet.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkbox_spritesheet.tif deleted file mode 100644 index 6e2b74b486..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkbox_spritesheet.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:40a03c12c1a0123a1fcfaa3f44d343d4318917a9b5851748c74accaa33efda56 -size 17765 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkered3.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkered3.tif deleted file mode 100644 index c1530d4b81..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkered3.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6546cc22a1030d2207cd98f8b9afa18abccd24e8b603770c8af6f2c08a769ff0 -size 22360 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/empty_icon.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/empty_icon.tif deleted file mode 100644 index 34a317e80e..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/empty_icon.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:23a048ecd54699e9f243f33e9d73b8d8611100357da3f7bcb56a5e1fed08b463 -size 362 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/fixed_image.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/fixed_image.tif deleted file mode 100644 index e1c6d3ad0e..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/fixed_image.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cced003316fae3dec3244be8967b7e28a9168d6184362bd0eb65828ac8a0b53b -size 25642 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/flipbook_walking.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/flipbook_walking.tif deleted file mode 100644 index 9a0f604003..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/flipbook_walking.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:91e7ffe470fddde4459e54eb889b2074dc26e8a1c705238c70672b5b3563098a -size 2303404 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_00.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_00.png deleted file mode 100644 index 770d3c724f..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:356ad2eaf78f24ff44f9a136fa22a17f7114052fff3061b417a48ae6b2767ab0 -size 8742 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_01.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_01.png deleted file mode 100644 index f0624bcdf6..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5eab5cb57ba50dc1d08abb610599ae6cd8e486dfb8bef1492e01a372ad5b31f -size 7979 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_02.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_02.png deleted file mode 100644 index 36e2450e1b..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:969a99c99f596f36a51893b14f2f70976809bc7a2ffb1794d0ebca0d5ad20604 -size 7575 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_03.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_03.png deleted file mode 100644 index e18a46d1d6..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:73a6871305f9ee31ae35d78634cd88bb13d4da5273fce11ae5f353460d43e3c9 -size 5923 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_04.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_04.png deleted file mode 100644 index e6235daabd..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b28de207784be22c7f501e6ada59e9f9174446f43dba9929633627429e8e0ce3 -size 7076 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_05.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_05.png deleted file mode 100644 index 65f5792ac9..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4b74237f5e285dd4eab6d1936b639aa1b87f285e5473b3514f9c1713eef39813 -size 8163 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_06.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_06.png deleted file mode 100644 index 61e547151f..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ad6946b610769ba6d2ccc4269cfae24c5e4f30964fd499442108f8bf17c2e8cd -size 8846 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_07.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_07.png deleted file mode 100644 index d3e1aa0ef6..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dddff30e20fc4e2f36bedaaca14606d44c9085e8c73841f339ed0a9bc08f26bd -size 7927 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_08.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_08.png deleted file mode 100644 index bdf29b4777..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_08.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d52afab812c6fc8e9c0916c71dc2ea8d957f4326ff9a0ce71658aae06f9d07e5 -size 7459 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_09.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_09.png deleted file mode 100644 index 26fd687534..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_09.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1dad7ebe7690cc9318838dd63bfcace0fad67e14f8f1916dca2fb6ebd267a26c -size 6123 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_10.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_10.png deleted file mode 100644 index dae9568f47..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a91f9d4be1e432e7b4fa998722ecea178e38ae63ca9f521bb04e5ce2e5159e0f -size 7619 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_11.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_11.png deleted file mode 100644 index 60f52297c5..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2979e15676720eb2b81d792880360f8ea26e17322253800b4432f84541d7da7b -size 8245 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/mask.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/mask.tif deleted file mode 100644 index 5e3cd778b4..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/mask.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:764d622d9c589f89f164f4a23d0b66270c25d34c2ecb687640c4ea3e2da55035 -size 36812 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outline.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outline.tif deleted file mode 100644 index 79bdc27a73..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outline.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e502b7ad23409df89c713c9ce43e1df159d4a634f35fec220a7cf8b5e6c2807f -size 56428 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outlineRounded.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outlineRounded.tif deleted file mode 100644 index e48f6108e7..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outlineRounded.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fb9616528ac43a6c46c8f3b4802cbc7cea51ccc0f86dbc5d156fe0806f34edf0 -size 66024 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/panelBkgd.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/panelBkgd.tif deleted file mode 100644 index b9ad540ce0..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/panelBkgd.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5abfb3bfd5eb8044ec3fde65c65d515a43179c87734b1813dc71c07050841b9f -size 27704 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02.tif deleted file mode 100644 index c9895b73b3..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:739955d9e61a89f732316876e1d1ae0503a6296f946324d7d0305b71e12c9f9e -size 23776 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02_big.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02_big.tif deleted file mode 100644 index 50b056d4ef..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02_big.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ed7bdcd8572fda83219564e8a92cc6f3d4d15e40e8c5950bf1412f74a799edd9 -size 24824 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical.tif deleted file mode 100644 index f8f2fd578c..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:290a417825baaed85811bcc29d91fd0ba436463dadc1648f669c5042234f96c1 -size 23948 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical_big.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical_big.tif deleted file mode 100644 index afebca233e..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical_big.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:005b9d7623d9ea1e4a470f6fee67f1eb5f38d7a1ad4e357e0036ce81850c6d5f -size 26032 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03.tif deleted file mode 100644 index 7a13c37c36..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6730661ad80d0d9b94c2c05b9cb321e5e5646a99b267d1680cf8fa9b8d62fb42 -size 23792 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03_big.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03_big.tif deleted file mode 100644 index 0098f2ce53..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03_big.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ba16a432f64432c6de9b52703faa1dc413c880e284c8719b3e56c737af6d4a0 -size 26720 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_1.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_1.tif deleted file mode 100644 index a21d2aaaa3..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_1.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0426d9b043f9033967a31a3392b80651871af1d4e60eada2d17e445c19105e32 -size 284432 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_10.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_10.tif deleted file mode 100644 index 54ea437920..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_10.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4eef390a93715bd46f196dc0c7ca311300ae7aca33b8163555b6429e91450497 -size 283492 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_2.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_2.tif deleted file mode 100644 index 9f7ba47daa..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_2.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a3d0845d8cc9c75a51ad2c812e6c72ca8147bae2ce12a7ea80e07f579bead937 -size 284884 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_3.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_3.tif deleted file mode 100644 index 4dc54a1950..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_3.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ee3d82984650486f6d2cf4488b60b1723f143134fdb763e390a7fc7c52ace18 -size 284872 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_4.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_4.tif deleted file mode 100644 index 54433305f8..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_4.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:becdab2a389207a942895017511cf453fe059c275dce25c1f5efd41ef13c9d38 -size 285396 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_5.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_5.tif deleted file mode 100644 index 5eae045870..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_5.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:da0222316fcabd92da0908d1750122296e11f7b3e2669e4cbfed3e8c15f08cb0 -size 285076 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_6.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_6.tif deleted file mode 100644 index 54611d8187..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_6.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3d0414c7d73a2ec33a50225af455819abb41f8d35077d3b3ec6bff8cabc3ff6b -size 283664 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_7.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_7.tif deleted file mode 100644 index 2da7dba224..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_7.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:05490310ee718b472efe4b8272077a88e2edf2992c253f46930c9ff1eb52a1e2 -size 283072 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_8.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_8.tif deleted file mode 100644 index 7115f20b1d..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_8.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba9fb34b4769374304e50d54cd34d1b971a5ec975cdae60ac33aa672c738e245 -size 283216 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_9.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_9.tif deleted file mode 100644 index c4f9f70332..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_9.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d96c5874954efba8c1c164fe5395a3a73647c09c887fe41d74d3a0f7b109ea8 -size 283488 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_map.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_map.tif deleted file mode 100644 index 8235c16cfc..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_map.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98b4c4ee5937d1211a4cf9deca85291bbe1419753cd80d97726839aaacd37699 -size 1597872 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/selected.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/selected.tif deleted file mode 100644 index 6d97b05566..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/selected.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fae0b4d2b33ec478d440fdfdb495a36a3980254087291ffdb5557abd66ffbb6e -size 37124 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInside2.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInside2.tif deleted file mode 100644 index ed0a235b5c..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInside2.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea15986ef41dafe27f642ca91cccbc89e58247bee6b3f8e7e95bf7e5748c29d4 -size 36848 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInsideSquare.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInsideSquare.tif deleted file mode 100644 index 26c13cf93b..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInsideSquare.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:095c764409002b30048579c50c552e63b1578acc473a0bce4a646fdc0748df64 -size 37312 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/greyscale.png b/Gems/ImageProcessing/Code/Tests/TestAssets/greyscale.png deleted file mode 100644 index 6df643605a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/greyscale.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0c0bcbed46bceef7e0686b9b42027d28d98f637c9f7d0d1370eb9911921ba531 -size 1518 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif deleted file mode 100644 index 5c3c4c7a6f..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:461580d9bdd4919b72d1703284f53667378d7345ea57f4c52272ef17603a91c1 -size 3148003 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif deleted file mode 100644 index 4fb9dce719..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cd619f19b99ea234c44c79a39413faa18e85a4817a57674c27ebf050edad5515 -size 3776022 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/red.png b/Gems/ImageProcessing/Code/Tests/TestAssets/red.png deleted file mode 100644 index 800faddee4..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/red.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:37d146db3de179add861ee86d2316ef1dd413cdb0b02448b3b95bf0023f44bae -size 613 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/uppercase.TGA b/Gems/ImageProcessing/Code/Tests/TestAssets/uppercase.TGA deleted file mode 100644 index d3808cdbce..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/uppercase.TGA +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6b6c1bf24dd39159e38c880071abad7b7315c8667192ff2495501dd0b1dec9c -size 85419 diff --git a/Gems/ImageProcessing/Code/imageprocessing_files.cmake b/Gems/ImageProcessing/Code/imageprocessing_files.cmake deleted file mode 100644 index 98aa870b46..0000000000 --- a/Gems/ImageProcessing/Code/imageprocessing_files.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../Assets/Editor/Resources.qrc - ../Assets/Editor/Backward.png - ../Assets/Editor/Forward.png - ../Assets/Editor/reset.png - Source/ImageProcessingModule.cpp -) diff --git a/Gems/ImageProcessing/Code/imageprocessing_headers_files.cmake b/Gems/ImageProcessing/Code/imageprocessing_headers_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Gems/ImageProcessing/Code/imageprocessing_headers_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Gems/ImageProcessing/Code/imageprocessing_static_files.cmake b/Gems/ImageProcessing/Code/imageprocessing_static_files.cmake deleted file mode 100644 index 07bf2ad375..0000000000 --- a/Gems/ImageProcessing/Code/imageprocessing_static_files.cmake +++ /dev/null @@ -1,133 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - Source/ImageProcessing_precompiled.cpp - Source/ImageProcessing_precompiled.h - Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp - Source/Compressors/CryTextureSquisher/CryTextureSquisher.h - Include/ImageProcessing/ImageProcessingBus.h - Include/ImageProcessing/ImageProcessingEditorBus.h - Include/ImageProcessing/PixelFormats.h - Include/ImageProcessing/ImageObject.h - Source/ImageProcessingSystemComponent.cpp - Source/ImageProcessingSystemComponent.h - Source/ImageBuilderComponent.cpp - Source/ImageBuilderComponent.h - Source/ImageBuilderBaseType.h - Source/BuilderSettings/MipmapSettings.h - Source/BuilderSettings/MipmapSettings.cpp - Source/BuilderSettings/CubemapSettings.h - Source/BuilderSettings/CubemapSettings.cpp - Source/BuilderSettings/PresetSettings.h - Source/BuilderSettings/PresetSettings.cpp - Source/BuilderSettings/TextureSettings.h - Source/BuilderSettings/TextureSettings.cpp - Source/BuilderSettings/BuilderSettings.cpp - Source/BuilderSettings/BuilderSettings.h - Source/BuilderSettings/BuilderSettingManager.cpp - Source/BuilderSettings/BuilderSettingManager.h - Source/BuilderSettings/ImageProcessingDefines.h - Source/BuilderSettings/PlatformSettings.h - Source/Processing/ImageObjectImpl.h - Source/Processing/ImageObjectImpl.cpp - Source/Processing/PixelFormatInfo.h - Source/Processing/PixelFormatInfo.cpp - Source/Processing/ImageConvert.h - Source/Processing/ImageConvert.cpp - Source/Processing/ImageConvertJob.h - Source/Processing/ImageConvertJob.cpp - Source/Processing/ImagePreview.h - Source/Processing/ImagePreview.cpp - Source/Processing/ImageToProcess.h - Source/Processing/ImageFlags.h - Source/Processing/DDSHeader.h - Source/ImageLoader/ImageLoaders.h - Source/ImageLoader/ImageLoaders.cpp - Source/ImageLoader/QtImageLoader.cpp - Source/ImageLoader/TIFFLoader.cpp - Source/ImageLoader/BTImageLoader.cpp - Source/Editor/EditorCommon.h - Source/Editor/EditorCommon.cpp - Source/Editor/TexturePropertyEditor.cpp - Source/Editor/TexturePropertyEditor.h - Source/Editor/TexturePropertyEditor.ui - Source/Editor/MipmapSettingWidget.cpp - Source/Editor/MipmapSettingWidget.h - Source/Editor/MipmapSettingWidget.ui - Source/Editor/ResolutionSettingWidget.cpp - Source/Editor/ResolutionSettingWidget.h - Source/Editor/ResolutionSettingWidget.ui - Source/Editor/ResolutionSettingItemWidget.cpp - Source/Editor/ResolutionSettingItemWidget.h - Source/Editor/ResolutionSettingItemWidget.ui - Source/Editor/TexturePresetSelectionWidget.cpp - Source/Editor/TexturePresetSelectionWidget.h - Source/Editor/TexturePresetSelectionWidget.ui - Source/Editor/TexturePreviewWidget.cpp - Source/Editor/TexturePreviewWidget.h - Source/Editor/TexturePreviewWidget.ui - Source/Editor/ImagePopup.cpp - Source/Editor/ImagePopup.h - Source/Editor/ImagePopup.ui - Source/Editor/PresetInfoPopup.cpp - Source/Editor/PresetInfoPopup.h - Source/Editor/PresetInfoPopup.ui - Source/Converters/Gamma.cpp - Source/Converters/FIR-Filter.cpp - Source/Converters/FIR-Windows.h - Source/Converters/FIR-Weights.h - Source/Converters/FIR-Weights.cpp - Source/Converters/AlphaCoverage.cpp - Source/Converters/PixelOperation.h - Source/Converters/PixelOperation.cpp - Source/Converters/Normalize.cpp - Source/Converters/ConvertPixelFormat.cpp - Source/Converters/Cubemap.h - Source/Converters/Cubemap.cpp - Source/Converters/ColorChart.cpp - Source/Converters/HighPass.cpp - Source/Converters/Histogram.cpp - Source/Converters/Histogram.h - ../External/CubeMapGen/CBBoxInt32.cpp - ../External/CubeMapGen/CBBoxInt32.h - ../External/CubeMapGen/CCubeMapProcessor.cpp - ../External/CubeMapGen/CCubeMapProcessor.h - ../External/CubeMapGen/CImageSurface.cpp - ../External/CubeMapGen/CImageSurface.h - ../External/CubeMapGen/VectorMacros.h - Source/Compressors/Compressor.h - Source/Compressors/Compressor.cpp - Source/Compressors/CTSquisher.h - Source/Compressors/CTSquisher.cpp - Source/Compressors/PVRTC.cpp - Source/Compressors/PVRTC.h - Source/Compressors/ETC2.cpp - Source/Compressors/ETC2.h - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h - Source/Compressors/CryTextureSquisher/ColorTypes.h - Source/AtlasBuilder/AtlasBuilderComponent.h - Source/AtlasBuilder/AtlasBuilderComponent.cpp - Source/AtlasBuilder/AtlasBuilderWorker.h - Source/AtlasBuilder/AtlasBuilderWorker.cpp -) - -set(SKIP_UNITY_BUILD_INCLUSION_FILES - Source/Compressors/PVRTC.cpp - Source/Compressors/PVRTC.h -) - - diff --git a/Gems/ImageProcessing/Code/imageprocessing_tests_files.cmake b/Gems/ImageProcessing/Code/imageprocessing_tests_files.cmake deleted file mode 100644 index 290f00104a..0000000000 --- a/Gems/ImageProcessing/Code/imageprocessing_tests_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - Tests/ImageProcessing_Test.cpp - Tests/AtlasBuilderTest.cpp -) diff --git a/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.cpp b/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.cpp deleted file mode 100644 index 5e80267f56..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.cpp +++ /dev/null @@ -1,129 +0,0 @@ - -//============================================================================= -//CBBoxInt32 -// 3D bounding box with int32 coordinates -// -//============================================================================= -// (C) 2005 ATI Research, Inc., All rights reserved. -//============================================================================= -// modifications by Crytek GmbH -// modifications by Amazon - -#include - -#include "CBBoxInt32.h" - -#define CP_MIN_INT32 0x80000000 -#define CP_MAX_INT32 0x7fffffff -#define CP_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define CP_MAX(a, b) (((a) > (b)) ? (a) : (b)) - - -namespace ImageProcessing -{ - //-------------------------------------------------------------------------------------- - // CBBoxInt32 - //-------------------------------------------------------------------------------------- - CBBoxInt32::CBBoxInt32(void) - { - Clear(); - } - - - //-------------------------------------------------------------------------------------- - // Text to see if CBBoxInt32 is empty or not - //-------------------------------------------------------------------------------------- - bool CBBoxInt32::Empty(void) - { - if ((m_minCoord[0] > m_maxCoord[0]) || - (m_minCoord[1] > m_maxCoord[1]) || - (m_minCoord[2] > m_maxCoord[2])) - { - return true; - } - else - { - return false; - } - } - - - //-------------------------------------------------------------------------------------- - // Clear bounding box extents - //-------------------------------------------------------------------------------------- - void CBBoxInt32::Clear(void) - { - m_minCoord[0] = CP_MAX_INT32; - m_minCoord[1] = CP_MAX_INT32; - m_minCoord[2] = CP_MAX_INT32; - m_maxCoord[0] = CP_MIN_INT32; - m_maxCoord[1] = CP_MIN_INT32; - m_maxCoord[2] = CP_MIN_INT32; - } - - - //-------------------------------------------------------------------------------------- - // Augment bounding box extents by specifying point to include in bounding box - //-------------------------------------------------------------------------------------- - void CBBoxInt32::Augment(int32 aX, int32 aY, int32 aZ) - { - m_minCoord[0] = CP_MIN(m_minCoord[0], aX); - m_minCoord[1] = CP_MIN(m_minCoord[1], aY); - m_minCoord[2] = CP_MIN(m_minCoord[2], aZ); - m_maxCoord[0] = CP_MAX(m_maxCoord[0], aX); - m_maxCoord[1] = CP_MAX(m_maxCoord[1], aY); - m_maxCoord[2] = CP_MAX(m_maxCoord[2], aZ); - } - - - //-------------------------------------------------------------------------------------- - // Augment bounding box extents by specifying x coordinate to include in bounding box - //-------------------------------------------------------------------------------------- - void CBBoxInt32::AugmentX(int32 aX) - { - m_minCoord[0] = CP_MIN(m_minCoord[0], aX); - m_maxCoord[0] = CP_MAX(m_maxCoord[0], aX); - } - - - //-------------------------------------------------------------------------------------- - // Augment bounding box extents by specifying x coordinate to include in bounding box - //-------------------------------------------------------------------------------------- - void CBBoxInt32::AugmentY(int32 aY) - { - m_minCoord[1] = CP_MIN(m_minCoord[1], aY); - m_maxCoord[1] = CP_MAX(m_maxCoord[1], aY); - } - - - //-------------------------------------------------------------------------------------- - // Augment bounding box extents by specifying x coordinate to include in bounding box - //-------------------------------------------------------------------------------------- - void CBBoxInt32::AugmentZ(int32 aZ) - { - m_minCoord[2] = CP_MIN(m_minCoord[2], aZ); - m_maxCoord[2] = CP_MAX(m_maxCoord[2], aZ); - } - - - //-------------------------------------------------------------------------------------- - // Clamp minimum values in bbox to be no larger than aX, aY, aZ - //-------------------------------------------------------------------------------------- - void CBBoxInt32::ClampMin(int32 aX, int32 aY, int32 aZ) - { - m_minCoord[0] = CP_MAX(m_minCoord[0], aX); - m_minCoord[1] = CP_MAX(m_minCoord[1], aY); - m_minCoord[2] = CP_MAX(m_minCoord[2], aZ); - } - - - //-------------------------------------------------------------------------------------- - // Clamp maximum values in bbox to be no larger than aX, aY, aZ - //-------------------------------------------------------------------------------------- - void CBBoxInt32::ClampMax(int32 aX, int32 aY, int32 aZ) - { - m_maxCoord[0] = CP_MIN(m_maxCoord[0], aX); - m_maxCoord[1] = CP_MIN(m_maxCoord[1], aY); - m_maxCoord[2] = CP_MIN(m_maxCoord[2], aZ); - } -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.h b/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.h deleted file mode 100644 index a6bbe0c327..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.h +++ /dev/null @@ -1,32 +0,0 @@ -//============================================================================= -//CBBoxInt32 -// 3D bounding box with int32 coordinates -// -//============================================================================= -// (C) 2005 ATI Research, Inc., All rights reserved. -//============================================================================= -// modifications by Crytek GmbH -// modifications by Amazon - -#pragma once - -namespace ImageProcessing -{ - //bounding box class with coords specified as int32 - class CBBoxInt32 - { - public: - int32 m_minCoord[3]; //upper left back corner - int32 m_maxCoord[3]; //lower right front corner - - CBBoxInt32(); - bool Empty(void); - void Clear(void); - void Augment(int32 a_X, int32 a_Y, int32 a_Z); - void AugmentX(int32 a_X); - void AugmentY(int32 a_Y); - void AugmentZ(int32 a_Z); - void ClampMin(int32 a_X, int32 a_Y, int32 a_Z); - void ClampMax(int32 a_X, int32 a_Y, int32 a_Z); - }; -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/External/CubeMapGen/CCubeMapProcessor.cpp b/Gems/ImageProcessing/External/CubeMapGen/CCubeMapProcessor.cpp deleted file mode 100644 index 794e860f28..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CCubeMapProcessor.cpp +++ /dev/null @@ -1,2237 +0,0 @@ -//============================================================================= -// (C) 2005 ATI Research, Inc., All rights reserved. -//============================================================================= -// modifications by Crytek GmbH -// modifications by Amazon - -#include -#include "CCubeMapProcessor.h" - -#include - -#define CP_PI 3.14159265358979323846 - - -namespace ImageProcessing -{ - - //------------------------------------------------------------------------------ - // D3D cube map face specification - // mapping from 3D x,y,z cube map lookup coordinates - // to 2D within face u,v coordinates - // - // --------------------> U direction - // | (within-face texture space) - // | _____ - // | | | - // | | +Y | - // | _____|_____|_____ _____ - // | | | | | | - // | | -X | +Z | +X | -Z | - // | |_____|_____|_____|_____| - // | | | - // | | -Y | - // | |_____| - // | - // v V direction - // (within-face texture space) - //------------------------------------------------------------------------------ - - //Information about neighbors and how texture coorrdinates change across faces - // in ORDER of left, right, top, bottom (e.g. edges corresponding to u=0, - // u=1, v=0, v=1 in the 2D coordinate system of the particular face. - //Note this currently assumes the D3D cube face ordering and orientation - CPCubeMapNeighbor sg_CubeNgh[6][4] = - { - //XPOS face - {{CP_FACE_Z_POS, CP_EDGE_RIGHT }, - {CP_FACE_Z_NEG, CP_EDGE_LEFT }, - {CP_FACE_Y_POS, CP_EDGE_RIGHT }, - {CP_FACE_Y_NEG, CP_EDGE_RIGHT }}, - //XNEG face - {{CP_FACE_Z_NEG, CP_EDGE_RIGHT }, - {CP_FACE_Z_POS, CP_EDGE_LEFT }, - {CP_FACE_Y_POS, CP_EDGE_LEFT }, - {CP_FACE_Y_NEG, CP_EDGE_LEFT }}, - //YPOS face - {{CP_FACE_X_NEG, CP_EDGE_TOP }, - {CP_FACE_X_POS, CP_EDGE_TOP }, - {CP_FACE_Z_NEG, CP_EDGE_TOP }, - {CP_FACE_Z_POS, CP_EDGE_TOP }}, - //YNEG face - {{CP_FACE_X_NEG, CP_EDGE_BOTTOM}, - {CP_FACE_X_POS, CP_EDGE_BOTTOM}, - {CP_FACE_Z_POS, CP_EDGE_BOTTOM}, - {CP_FACE_Z_NEG, CP_EDGE_BOTTOM}}, - //ZPOS face - {{CP_FACE_X_NEG, CP_EDGE_RIGHT }, - {CP_FACE_X_POS, CP_EDGE_LEFT }, - {CP_FACE_Y_POS, CP_EDGE_BOTTOM }, - {CP_FACE_Y_NEG, CP_EDGE_TOP }}, - //ZNEG face - {{CP_FACE_X_POS, CP_EDGE_RIGHT }, - {CP_FACE_X_NEG, CP_EDGE_LEFT }, - {CP_FACE_Y_POS, CP_EDGE_TOP }, - {CP_FACE_Y_NEG, CP_EDGE_BOTTOM }} - }; - - - //3x2 matrices that map cube map indexing vectors in 3d - // (after face selection and divide through by the - // _ABSOLUTE VALUE_ of the max coord) - // into NVC space - //Note this currently assumes the D3D cube face ordering and orientation - #define CP_UDIR 0 - #define CP_VDIR 1 - #define CP_FACEAXIS 2 - - float sgFace2DMapping[6][3][3] = { - //XPOS face - {{ 0, 0, -1}, //u towards negative Z - { 0, -1, 0}, //v towards negative Y - {1, 0, 0}}, //pos X axis - //XNEG face - {{0, 0, 1}, //u towards positive Z - {0, -1, 0}, //v towards negative Y - {-1, 0, 0}}, //neg X axis - //YPOS face - {{1, 0, 0}, //u towards positive X - {0, 0, 1}, //v towards positive Z - {0, 1 , 0}}, //pos Y axis - //YNEG face - {{1, 0, 0}, //u towards positive X - {0, 0 , -1}, //v towards negative Z - {0, -1 , 0}}, //neg Y axis - //ZPOS face - {{1, 0, 0}, //u towards positive X - {0, -1, 0}, //v towards negative Y - {0, 0, 1}}, //pos Z axis - //ZNEG face - {{-1, 0, 0}, //u towards negative X - {0, -1, 0}, //v towards negative Y - {0, 0, -1}}, //neg Z axis - }; - - - //The 12 edges of the cubemap, (entries are used to index into the neighbor table) - // this table is used to average over the edges. - int32 sg_CubeEdgeList[12][2] = { - {CP_FACE_X_POS, CP_EDGE_LEFT}, - {CP_FACE_X_POS, CP_EDGE_RIGHT}, - {CP_FACE_X_POS, CP_EDGE_TOP}, - {CP_FACE_X_POS, CP_EDGE_BOTTOM}, - - {CP_FACE_X_NEG, CP_EDGE_LEFT}, - {CP_FACE_X_NEG, CP_EDGE_RIGHT}, - {CP_FACE_X_NEG, CP_EDGE_TOP}, - {CP_FACE_X_NEG, CP_EDGE_BOTTOM}, - - {CP_FACE_Z_POS, CP_EDGE_TOP}, - {CP_FACE_Z_POS, CP_EDGE_BOTTOM}, - {CP_FACE_Z_NEG, CP_EDGE_TOP}, - {CP_FACE_Z_NEG, CP_EDGE_BOTTOM} - }; - - - //Information about which of the 8 cube corners are correspond to the - // the 4 corners in each cube face - // the order is upper left, upper right, lower left, lower right - int32 sg_CubeCornerList[6][4] = { - { CP_CORNER_PPP, CP_CORNER_PPN, CP_CORNER_PNP, CP_CORNER_PNN }, // XPOS face - { CP_CORNER_NPN, CP_CORNER_NPP, CP_CORNER_NNN, CP_CORNER_NNP }, // XNEG face - { CP_CORNER_NPN, CP_CORNER_PPN, CP_CORNER_NPP, CP_CORNER_PPP }, // YPOS face - { CP_CORNER_NNP, CP_CORNER_PNP, CP_CORNER_NNN, CP_CORNER_PNN }, // YNEG face - { CP_CORNER_NPP, CP_CORNER_PPP, CP_CORNER_NNP, CP_CORNER_PNP }, // ZPOS face - { CP_CORNER_PPN, CP_CORNER_NPN, CP_CORNER_PNN, CP_CORNER_NNN } // ZNEG face - }; - - - //-------------------------------------------------------------------------------------- - // Convert cubemap face texel coordinates and face idx to 3D vector - // note the U and V coords are integer coords and range from 0 to size-1 - // this routine can be used to generate a normalizer cube map - //-------------------------------------------------------------------------------------- - void TexelCoordToVect(int32 a_FaceIdx, float a_U, float a_V, int32 a_Size, float *a_XYZ) - { - float nvcU, nvcV; - float tempVec[3]; - - //scale up to [-1, 1] range (inclusive) - nvcU = (2.0f * ((float)a_U + 0.5f) / a_Size ) - 1.0f; - nvcV = (2.0f * ((float)a_V + 0.5f) / a_Size ) - 1.0f; - - //generate x,y,z vector (xform 2d NVC coord to 3D vector) - //U contribution - VM_SCALE3(a_XYZ, sgFace2DMapping[a_FaceIdx][CP_UDIR], nvcU); - //V contribution - VM_SCALE3(tempVec, sgFace2DMapping[a_FaceIdx][CP_VDIR], nvcV); - VM_ADD3(a_XYZ, tempVec, a_XYZ); - //add face axis - VM_ADD3(a_XYZ, sgFace2DMapping[a_FaceIdx][CP_FACEAXIS], a_XYZ); - - //normalize vector - VM_NORM3(a_XYZ, a_XYZ); - } - - - //-------------------------------------------------------------------------------------- - // Convert 3D vector to cubemap face texel coordinates and face idx - // note the U and V coords are integer coords and range from 0 to size-1 - // this routine can be used to generate a normalizer cube map - // - // returns face IDX and texel coords - //-------------------------------------------------------------------------------------- - void VectToTexelCoord(float *a_XYZ, int32 a_Size, int32 *a_FaceIdx, int32 *a_U, int32 *a_V ) - { - float nvcU, nvcV; - float absXYZ[3]; - float maxCoord; - float onFaceXYZ[3]; - int32 faceIdx; - int32 u, v; - - //absolute value 3 - VM_ABS3(absXYZ, a_XYZ); - - if( (absXYZ[0] >= absXYZ[1]) && (absXYZ[0] >= absXYZ[2]) ) - { - maxCoord = absXYZ[0]; - - if(a_XYZ[0] >= 0) //face = XPOS - { - faceIdx = CP_FACE_X_POS; - } - else - { - faceIdx = CP_FACE_X_NEG; - } - } - else if ( (absXYZ[1] >= absXYZ[0]) && (absXYZ[1] >= absXYZ[2]) ) - { - maxCoord = absXYZ[1]; - - if(a_XYZ[1] >= 0) //face = XPOS - { - faceIdx = CP_FACE_Y_POS; - } - else - { - faceIdx = CP_FACE_Y_NEG; - } - } - else // if( (absXYZ[2] > absXYZ[0]) && (absXYZ[2] > absXYZ[1]) ) - { - maxCoord = absXYZ[2]; - - if(a_XYZ[2] >= 0) //face = XPOS - { - faceIdx = CP_FACE_Z_POS; - } - else - { - faceIdx = CP_FACE_Z_NEG; - } - } - - //divide through by max coord so face vector lies on cube face - VM_SCALE3(onFaceXYZ, a_XYZ, 1.0f/maxCoord); - nvcU = VM_DOTPROD3(sgFace2DMapping[ faceIdx ][CP_UDIR], onFaceXYZ ); - nvcV = VM_DOTPROD3(sgFace2DMapping[ faceIdx ][CP_VDIR], onFaceXYZ ); - - u = (int32)floor( a_Size * 0.5f * (nvcU + 1.0f) ); - v = (int32)floor( a_Size * 0.5f * (nvcV + 1.0f) ); - - *a_FaceIdx = faceIdx; - *a_U = u; - *a_V = v; - } - - - //-------------------------------------------------------------------------------------- - // gets texel ptr in a cube map given a direction vector, and an array of - // CImageSurfaces that represent the cube faces. - // - //-------------------------------------------------------------------------------------- - CP_ITYPE *GetCubeMapTexelPtr(float *a_XYZ, CImageSurface *a_Surface) - { - int32 u, v, faceIdx; - - //get face idx and u, v texel coordinate in face - VectToTexelCoord(a_XYZ, a_Surface[0].m_Width, &faceIdx, &u, &v ); - - u = VM_MIN(u, a_Surface[0].m_Width - 1); - v = VM_MIN(v, a_Surface[0].m_Width - 1); - - return( a_Surface[faceIdx].GetSurfaceTexelPtr(u, v) ); - } - - - //-------------------------------------------------------------------------------------- - // Compute solid angle of given texel in cubemap face for weighting taps in the - // kernel by the area they project to on the unit sphere. - // - // Note that this code uses an approximation to the solid angle, by treating the - // two triangles that make up the quad comprising the texel as planar. If more - // accuracy is required, the solid angle per triangle lying on the sphere can be - // computed using the sum of the interior angles - PI. - // - //-------------------------------------------------------------------------------------- - float TexelCoordSolidAngle(int32 a_FaceIdx, float a_U, float a_V, int32 a_Size) - { - float cornerVect[4][3]; - double cornerVect64[4][3]; - - float halfTexelStep = 0.5f; //note u, and v are in texel coords (where each texel is one unit) - double edgeVect0[3]; - double edgeVect1[3]; - double xProdVect[3]; - double texelArea; - - //compute 4 corner vectors of texel - TexelCoordToVect(a_FaceIdx, a_U - halfTexelStep, a_V - halfTexelStep, a_Size, cornerVect[0] ); - TexelCoordToVect(a_FaceIdx, a_U - halfTexelStep, a_V + halfTexelStep, a_Size, cornerVect[1] ); - TexelCoordToVect(a_FaceIdx, a_U + halfTexelStep, a_V - halfTexelStep, a_Size, cornerVect[2] ); - TexelCoordToVect(a_FaceIdx, a_U + halfTexelStep, a_V + halfTexelStep, a_Size, cornerVect[3] ); - - VM_NORM3_UNTYPED(cornerVect64[0], cornerVect[0] ); - VM_NORM3_UNTYPED(cornerVect64[1], cornerVect[1] ); - VM_NORM3_UNTYPED(cornerVect64[2], cornerVect[2] ); - VM_NORM3_UNTYPED(cornerVect64[3], cornerVect[3] ); - - //area of triangle defined by corners 0, 1, and 2 - VM_SUB3_UNTYPED(edgeVect0, cornerVect64[1], cornerVect64[0] ); - VM_SUB3_UNTYPED(edgeVect1, cornerVect64[2], cornerVect64[0] ); - VM_XPROD3_UNTYPED(xProdVect, edgeVect0, edgeVect1 ); - texelArea = 0.5f * sqrt( VM_DOTPROD3_UNTYPED(xProdVect, xProdVect ) ); - - //area of triangle defined by corners 1, 2, and 3 - VM_SUB3_UNTYPED(edgeVect0, cornerVect64[2], cornerVect64[1] ); - VM_SUB3_UNTYPED(edgeVect1, cornerVect64[3], cornerVect64[1] ); - VM_XPROD3_UNTYPED(xProdVect, edgeVect0, edgeVect1 ); - texelArea += 0.5f * sqrt( VM_DOTPROD3_UNTYPED(xProdVect, xProdVect ) ); - - return texelArea; - } - - - - //-------------------------------------------------------------------------------------- - //Builds a normalizer cubemap - // - // Takes in a cube face size, and an array of 6 surfaces to write the cube faces into - // - // Note that this normalizer cube map stores the vectors in unbiased -1 to 1 range. - // if _bx2 style scaled and biased vectors are needed, uncomment the SCALE and BIAS - // below - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::BuildNormalizerCubemap(int32 a_Size, CImageSurface *a_Surface ) - { - int32 iCubeFace, u, v; - - //iterate over cube faces - for(iCubeFace=0; iCubeFace<6; iCubeFace++) - { - a_Surface[iCubeFace].Clear(); - a_Surface[iCubeFace].Init(a_Size, a_Size, 3); - - //fast texture walk, build normalizer cube map - CP_ITYPE *texelPtr = a_Surface[iCubeFace].m_ImgData; - - for(v=0; v < a_Surface[iCubeFace].m_Height; v++) - { - for(u=0; u < a_Surface[iCubeFace].m_Width; u++) - { - TexelCoordToVect(iCubeFace, (float)u, (float)v, a_Size, texelPtr); - - //VM_SCALE3(texelPtr, texelPtr, 0.5f); - //VM_BIAS3(texelPtr, texelPtr, 0.5f); - - texelPtr += a_Surface[iCubeFace].m_NumChannels; - } - } - } - } - - - //-------------------------------------------------------------------------------------- - //Builds a normalizer cubemap, with the texels solid angle stored in the fourth component - // - //Takes in a cube face size, and an array of 6 surfaces to write the cube faces into - // - //Note that this normalizer cube map stores the vectors in unbiased -1 to 1 range. - // if _bx2 style scaled and biased vectors are needed, uncomment the SCALE and BIAS - // below - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::BuildNormalizerSolidAngleCubemap(int32 a_Size, CImageSurface *a_Surface ) - { - //iterate over cube faces - for(int32 iCubeFace=0; iCubeFace<6; iCubeFace++) - { - a_Surface[iCubeFace].Clear(); - a_Surface[iCubeFace].Init(a_Size, a_Size, 4); //First three channels for norm cube, and last channel for solid angle - } - - //iterate over cube faces - for(int32 iCubeFace=0; iCubeFace<6; iCubeFace++) - { - const int32 height = a_Surface[iCubeFace].m_Height; - const int32 width = a_Surface[iCubeFace].m_Width; - - for(int32 v=0; v 0) - { - neighborFace = sg_CubeNgh[faceIdx][i].m_Face; - neighborEdge = sg_CubeNgh[faceIdx][i].m_Edge; - - //For certain types of edge abutments, the bleedOverBBoxMin, and bleedOverBBoxMax need to - // be flipped: the cases are - // if a left edge mates with a left or bottom edge on the neighbor - // if a top edge mates with a top or right edge on the neighbor - // if a right edge mates with a right or top edge on the neighbor - // if a bottom edge mates with a bottom or left edge on the neighbor - //Seeing as the edges are enumerated as follows - // left =0 - // right =1 - // top =2 - // bottom =3 - // - // so if the edge enums are the same, or the sum of the enums == 3, - // the bbox needs to be flipped - if( (i == neighborEdge) || ((i+neighborEdge) == 3) ) - { - bleedOverBBoxMin[i] = (a_SrcSize-1) - bleedOverBBoxMin[i]; - bleedOverBBoxMax[i] = (a_SrcSize-1) - bleedOverBBoxMax[i]; - } - - - //The way the bounding box is extended onto the neighboring face - // depends on which edge of neighboring face abuts with this one - switch(sg_CubeNgh[faceIdx][i].m_Edge) - { - case CP_EDGE_LEFT: - a_FilterExtents[neighborFace].Augment(0, bleedOverBBoxMin[i], 0); - a_FilterExtents[neighborFace].Augment(bleedOverAmount[i], bleedOverBBoxMax[i], 0); - break; - case CP_EDGE_RIGHT: - a_FilterExtents[neighborFace].Augment( (a_SrcSize-1), bleedOverBBoxMin[i], 0); - a_FilterExtents[neighborFace].Augment( (a_SrcSize-1) - bleedOverAmount[i], bleedOverBBoxMax[i], 0); - break; - case CP_EDGE_TOP: - a_FilterExtents[neighborFace].Augment(bleedOverBBoxMin[i], 0, 0); - a_FilterExtents[neighborFace].Augment(bleedOverBBoxMax[i], bleedOverAmount[i], 0); - break; - case CP_EDGE_BOTTOM: - a_FilterExtents[neighborFace].Augment(bleedOverBBoxMin[i], (a_SrcSize-1), 0); - a_FilterExtents[neighborFace].Augment(bleedOverBBoxMax[i], (a_SrcSize-1) - bleedOverAmount[i], 0); - break; - } - - //clamp filter extents in non-center tap faces to remain within surface - a_FilterExtents[neighborFace].ClampMin(0, 0, 0); - a_FilterExtents[neighborFace].ClampMax(a_SrcSize-1, a_SrcSize-1, 0); - } - - //If the bleed over amount bleeds past the adjacent face onto the opposite face - // from the center tap face, then process the opposite face entirely for now. - //Note that the cases in which this happens, what usually happens is that - // more than one edge bleeds onto the opposite face, and the bounding box - // encompasses the entire cube map face. - if(bleedOverAmount[i] > a_SrcSize) - { - uint32 oppositeFaceIdx; - - //determine opposite face - switch(faceIdx) - { - case CP_FACE_X_POS: - oppositeFaceIdx = CP_FACE_X_NEG; - break; - case CP_FACE_X_NEG: - oppositeFaceIdx = CP_FACE_X_POS; - break; - case CP_FACE_Y_POS: - oppositeFaceIdx = CP_FACE_Y_NEG; - break; - case CP_FACE_Y_NEG: - oppositeFaceIdx = CP_FACE_Y_POS; - break; - case CP_FACE_Z_POS: - oppositeFaceIdx = CP_FACE_Z_NEG; - break; - default: // CP_FACE_Z_NEG: - oppositeFaceIdx = CP_FACE_Z_POS; - break; - } - - //just encompass entire face for now - a_FilterExtents[oppositeFaceIdx].Augment(0, 0, 0); - a_FilterExtents[oppositeFaceIdx].Augment((a_SrcSize-1), (a_SrcSize-1), 0); - } - } - - minV=minV; - } - - - //-------------------------------------------------------------------------------------- - //ProcessFilterExtents - // Process bounding box in each cube face - // - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::ProcessFilterExtents(float *a_CenterTapDir, float a_DotProdThresh, - CBBoxInt32 *a_FilterExtents, CImageSurface *a_NormCubeMap, CImageSurface *a_SrcCubeMap, - CP_ITYPE *a_DstVal, uint32 a_FilterType, bool a_bUseSolidAngleWeighting, float a_SpecularPower) - { - //accumulators are 64-bit floats in order to have the precision needed - // over a summation of a large number of pixels - double dstAccumFace[6][4]; - double weightAccumFace[6]; - - const int32 nSrcChannels = a_SrcCubeMap[0].m_NumChannels; - - //norm cube map and srcCubeMap have same face width - const int32 faceWidth = a_NormCubeMap[0].m_Width; - - //amount to add to pointer to move to next scanline in images - const int32 normCubePitch = faceWidth * a_NormCubeMap[0].m_NumChannels; - const int32 srcCubePitch = faceWidth * a_SrcCubeMap[0].m_NumChannels; - - //iterate over cubefaces - for(int32 iFaceIdx=0; iFaceIdx<6; iFaceIdx++ ) - { - //dest accum - for(int32 k=0; k= a_DotProdThresh ) - { - CP_ITYPE weight; - - //for now just weight all taps equally, but ideally - // weight should be proportional to the solid angle of the tap - if(a_bUseSolidAngleWeighting == true) - { //solid angle stored in 4th channel of normalizer/solid angle cube map - weight = *(texelVect+3); - } - else - { //all taps equally weighted - weight = 1.0f; - } - - switch(a_FilterType) - { - case CP_FILTER_TYPE_COSINE_POWER: - { - if(tapDotProd > 0.0f) - { - weight *= pow(tapDotProd, a_SpecularPower) * tapDotProd; - } - else - { - weight = 0; - } - } - break; - case CP_FILTER_TYPE_CONE: - case CP_FILTER_TYPE_ANGULAR_GAUSSIAN: - { - //weights are in same lookup table for both of these filter types - weight *= m_FilterLUT[(int32)(tapDotProd * (m_NumFilterLUTEntries - 1))]; - } - break; - case CP_FILTER_TYPE_COSINE: - { - if(tapDotProd > 0.0f) - { - weight *= tapDotProd; - } - else - { - weight = 0.0f; - } - } - break; - case CP_FILTER_TYPE_DISC: - default: - break; - } - - //iterate over channels - for(int32 k=0; k>= 1; - - m_NumMipLevels++; - - //terminate if mip chain becomes too small - if(mipLevelSize == 0) - { - return; - } - } - } - - - //-------------------------------------------------------------------------------------- - //Copy and convert cube map face data from an external image/surface into this object - // - // a_FaceIdx = a value 0 to 5 speciying which face to copy into (one of the CP_FACE_? ) - // a_Level = mip level to copy into - // a_SrcType = data type of image being copyed from (one of the CP_TYPE_? types) - // a_SrcNumChannels = number of channels of the image being copied from (usually 1 to 4) - // a_SrcPitch = number of bytes per row of the source image being copied from - // a_SrcDataPtr = pointer to the image data to copy from - // a_Degamma = original gamma level of input image to undo by degamma - // a_Scale = scale to apply to pixel values after degamma (in linear space) - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::SetInputFaceData(int32 a_FaceIdx, int32 a_SrcType, int32 a_SrcNumChannels, - int32 a_SrcPitch, void *a_SrcDataPtr, float a_MaxClamp, float a_Degamma, float a_Scale) - { - //since input is being modified, terminate any active filtering threads - TerminateActiveThreads(); - - m_InputSurface[a_FaceIdx].SetImageDataClampDegammaScale( a_SrcType, a_SrcNumChannels, a_SrcPitch, - a_SrcDataPtr, a_MaxClamp, a_Degamma, a_Scale ); - } - - - //-------------------------------------------------------------------------------------- - //Copy and convert cube map face data from this object into an external image/surface - // - // a_FaceIdx = a value 0 to 5 speciying which face to copy into (one of the CP_FACE_? ) - // a_Level = mip level to copy into - // a_DstType = data type of image to copy to (one of the CP_TYPE_? types) - // a_DstNumChannels = number of channels of the image to copy to (usually 1 to 4) - // a_DstPitch = number of bytes per row of the dest image to copy to - // a_DstDataPtr = pointer to the image data to copy to - // a_Scale = scale to apply to pixel values (in linear space) before gamma for output - // a_Gamma = gamma level to apply to pixels after scaling - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::GetInputFaceData(int32 a_FaceIdx, int32 a_DstType, int32 a_DstNumChannels, - int32 a_DstPitch, void *a_DstDataPtr, float a_Scale, float a_Gamma) - { - m_InputSurface[a_FaceIdx].GetImageDataScaleGamma( a_DstType, a_DstNumChannels, a_DstPitch, - a_DstDataPtr, a_Scale, a_Gamma ); - } - - - //-------------------------------------------------------------------------------------- - //ChannelSwapInputFaceData - // swizzle data in first 4 channels for input faces - // - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::ChannelSwapInputFaceData(int32 a_Channel0Src, int32 a_Channel1Src, - int32 a_Channel2Src, int32 a_Channel3Src ) - { - int32 iFace, u, v, k; - int32 size; - CP_ITYPE texelData[4]; - int32 channelSrcArray[4]; - - //since input is being modified, terminate any active filtering threads - TerminateActiveThreads(); - - size = m_InputSize; - - channelSrcArray[0] = a_Channel0Src; - channelSrcArray[1] = a_Channel1Src; - channelSrcArray[2] = a_Channel2Src; - channelSrcArray[3] = a_Channel3Src; - - //Iterate over faces for input images - for(iFace=0; iFace<6; iFace++) - { - for(v=0; v> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - - return float(bits) * 2.3283064365386963e-10; // float(bits) * 2^-32 - } - - inline void HammersleySequence(uint32 sampleIndex, uint32 sampleCount, float* vXi) - { - vXi[0] = float(sampleIndex) / float(sampleCount); - vXi[1] = RadicalInverse2(sampleIndex); - } - - void ImportanceSampleGGX(float* vXi, float roughness, float* vNormal, float* vOut) - { - float phi = 2 * CP_PI * vXi[0]; - float cosTheta = sqrtf((1 - vXi[1]) / ( 1 + (roughness * roughness - 1) * vXi[1])); - float sinTheta = sqrtf(1 - cosTheta * cosTheta); - - float vH[3]; - vH[0] = sinTheta * cosf(phi); - vH[1] = sinTheta * sinf(phi); - vH[2] = cosTheta; - - float vUpVectorX[3] = {1, 0, 0}; - float vUpVectorZ[3] = {0, 0, 1}; - float vTangentX[3]; - float vTangentY[3]; - float vTempVec[3]; - - // Build local frame - VM_XPROD3(vTempVec, fabs(vNormal[2]) < 0.999f ? vUpVectorZ : vUpVectorX, vNormal); - VM_NORM3(vTangentX, vTempVec); - VM_XPROD3(vTangentY, vNormal, vTangentX); - - // Convert from tangent to world space - vOut[0] = vTangentX[0] * vH[0] + vTangentY[0] * vH[1] + vNormal[0] * vH[2]; - vOut[1] = vTangentX[1] * vH[0] + vTangentY[1] * vH[1] + vNormal[1] * vH[2]; - vOut[2] = vTangentX[2] * vH[0] + vTangentY[2] * vH[1] + vNormal[2] * vH[2]; - } - - - void CCubeMapProcessor::FilterCubeSurfacesGGX(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, int32 a_SampleCount, float a_Roughness, - int32 a_FaceIdxStart, int32 a_FaceIdxEnd, int32 a_ThreadIdx) - { - const uint32 numChannels = VM_MIN(m_NumChannels, 4); - const int32 dstSize = a_DstCubeMap[0].m_Width; - - //thread progress - m_ThreadProgress[a_ThreadIdx].m_StartFace = a_FaceIdxStart; - m_ThreadProgress[a_ThreadIdx].m_EndFace = a_FaceIdxEnd; - - //process required faces - for(int32 iCubeFace = a_FaceIdxStart; iCubeFace <= a_FaceIdxEnd && !m_shutdownWorkerThreadSignal; iCubeFace++) - { - //iterate over dst cube map face texel - for(int32 v = 0; v < dstSize && !m_shutdownWorkerThreadSignal; v++) - { - CP_ITYPE *texelPtr = a_DstCubeMap[iCubeFace].m_ImgData + v * a_DstCubeMap[iCubeFace].m_NumChannels * dstSize; - - m_ThreadProgress[a_ThreadIdx].m_CurrentFace = iCubeFace; - m_ThreadProgress[a_ThreadIdx].m_CurrentRow = v; - - for (int32 u = 0; u < dstSize && !m_shutdownWorkerThreadSignal; u++) - { - float color[4] = { 0 }; - float totalWeight = 0; - float vH[3]; - float vL[3]; - - // Assume normal and view vector to be vCenterTapDir - float vCenterTapDir[3]; - TexelCoordToVect(iCubeFace, (float)u, (float)v, dstSize, vCenterTapDir); - - for (uint32 i = 0; i < (uint32)a_SampleCount && !m_shutdownWorkerThreadSignal; i++) - { - float vXi[2]; - HammersleySequence(i, a_SampleCount, vXi); - ImportanceSampleGGX(vXi, a_Roughness, vCenterTapDir, vH); - - float fVdotH = VM_DOTPROD3(vCenterTapDir, vH); - vL[0] = 2 * fVdotH * vH[0] - vCenterTapDir[0]; - vL[1] = 2 * fVdotH * vH[1] - vCenterTapDir[1]; - vL[2] = 2 * fVdotH * vH[2] - vCenterTapDir[2]; - - float fNdotL = VM_DOTPROD3(vCenterTapDir, vL); - if (fNdotL > 0) - { - CP_ITYPE *sourceTexel = GetCubeMapTexelPtr(vL, a_SrcCubeMap); - for (uint32 k = 0; k < numChannels; k++) - { - color[k] += sourceTexel[k] * fNdotL; - } - - totalWeight += fNdotL; - } - } - - for (uint32 k = 0; k < numChannels; k++) - { - texelPtr[k] = color[k] / totalWeight; - } - - texelPtr += a_DstCubeMap[iCubeFace].m_NumChannels; - } - } - } - } - - - void CCubeMapProcessor::FilterCubeMapMipChain(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale, - int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle, float a_GlossScale, float a_GlossBias, - int32 a_SampleCountGGX) - { - int32 i; - float coneAngle; - - if(a_FilterType == CP_FILTER_TYPE_COSINE_POWER || a_FilterType == CP_FILTER_TYPE_GGX) - { - // Don't filter top mipmap - a_BaseFilterAngle = 0; - } - - //Build filter lookup tables based on the source miplevel size - PrecomputeFilterLookupTables(a_FilterType, m_InputSurface[0].m_Width, a_BaseFilterAngle); - - //initialize thread progress - m_ThreadProgress[0].m_CurrentMipLevel = 0; - m_ThreadProgress[0].m_CurrentRow = 0; - m_ThreadProgress[0].m_CurrentFace = 0; - - //Filter the top mip level (initial filtering used for diffuse or blurred specular lighting ) - FilterCubeSurfaces(m_InputSurface, m_OutputSurface[0], a_BaseFilterAngle, a_FilterType, a_bUseSolidAngle, - 0, //start at face 0 - 5, //end at face 5 - 0); //thread 0 is processing - - m_ThreadProgress[0].m_CurrentMipLevel = 1; - m_ThreadProgress[0].m_CurrentRow = 0; - m_ThreadProgress[0].m_CurrentFace = 0; - - - FixupCubeEdges(m_OutputSurface[0], a_FixupType, a_FixupWidth); - - //Cone angle start (for generating subsequent mip levels) - coneAngle = a_InitialMipAngle; - - //generate subsequent mip levels - for(i=0; i<(m_NumMipLevels-1) && !m_shutdownWorkerThreadSignal; i++) - { - m_ThreadProgress[0].m_CurrentMipLevel = i+1; - m_ThreadProgress[0].m_CurrentRow = 0; - m_ThreadProgress[0].m_CurrentFace = 0; - - CImageSurface* srcCubeImage = m_OutputSurface[i]; - - if (a_FilterType == CP_FILTER_TYPE_GGX) - { - uint32 numUsableMips = m_NumMipLevels - 2; // Lowest used mip is 4x4 - float smoothness = VM_MAX(1.0f - (float)(i + 1) / (float)(numUsableMips - 1), 0.0f); - - // Convert smoothness to roughness (needs to match shader code) - float roughness = (1.0f - smoothness) * (1.0f - smoothness); - - FilterCubeSurfacesGGX(srcCubeImage, m_OutputSurface[i+1], a_SampleCountGGX, roughness, - 0, //start at face 0 - 5, //end at face 5 - 0 //thread 0 is processing - ); - } - else - { - float specPow = 1.0f; - - if(a_FilterType == CP_FILTER_TYPE_COSINE_POWER) - { - uint32 numMipsForGloss = m_NumMipLevels - 2; // Lowest used mip is 4x4 - float gloss = VM_MAX(1.0f - (float)(i + 1) / (float)(numMipsForGloss - 1), 0.0f); - - // Compute specular power (this must match shader code) - specPow = pow(2.0f, a_GlossScale * gloss + a_GlossBias); - - // Blinn to Phong approximation: (R.E)^p == (N.H)^(4*p) - specPow /= 4.0f; - - coneAngle = ComputeBaseFilterAngle(specPow); - srcCubeImage = m_InputSurface; - } - - //Build filter lookup tables based on the source miplevel size - PrecomputeFilterLookupTables(a_FilterType, srcCubeImage->m_Width, coneAngle); - - //filter cube surfaces - FilterCubeSurfaces(srcCubeImage, m_OutputSurface[i+1], coneAngle, a_FilterType, a_bUseSolidAngle, - 0, //start at face 0 - 5, //end at face 5 - 0, //thread 0 is processing - specPow); - } - - m_ThreadProgress[0].m_CurrentMipLevel = i+2; - m_ThreadProgress[0].m_CurrentRow = 0; - m_ThreadProgress[0].m_CurrentFace = 0; - - FixupCubeEdges(m_OutputSurface[i+1], a_FixupType, a_FixupWidth); - - coneAngle = coneAngle * a_MipAnglePerLevelScale; - } - - m_Status = CP_STATUS_FILTER_COMPLETED; - } - - - //-------------------------------------------------------------------------------------- - //Builds the following lookup tables prior to filtering: - // -normalizer cube map - // -tap weight lookup table - // - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::PrecomputeFilterLookupTables(uint32 a_FilterType, int32 a_SrcCubeMapWidth, float a_FilterConeAngle) - { - float srcTexelAngle; - int32 iCubeFace; - - //angle about center tap that defines filter cone - float filterAngle; - - //min angle a src texel can cover (in degrees) - srcTexelAngle = (180.0f / (float)CP_PI) * atan2f(1.0f, (float)a_SrcCubeMapWidth); - - //filter angle is 1/2 the cone angle - filterAngle = a_FilterConeAngle / 2.0f; - - //ensure filter angle is larger than a texel - if(filterAngle < srcTexelAngle) - { - filterAngle = srcTexelAngle; - } - - //ensure filter cone is always smaller than the hemisphere - if(filterAngle > 90.0f) - { - filterAngle = 90.0f; - } - - //build lookup table for tap weights based on angle between current tap and center tap - BuildAngleWeightLUT(a_SrcCubeMapWidth * 2, a_FilterType, filterAngle); - - //clear pre-existing normalizer cube map - for(iCubeFace=0; iCubeFace<6; iCubeFace++) - { - m_NormCubeMap[iCubeFace].Clear(); - } - - //Normalized vectors per cubeface and per-texel solid angle - BuildNormalizerSolidAngleCubemap(a_SrcCubeMapWidth, m_NormCubeMap); - - } - - //-------------------------------------------------------------------------------------- - //The key to the speed of these filtering routines is to quickly define a per-face - // bounding box of pixels which enclose all the taps in the filter kernel efficiently. - // Later these pixels are selectively processed based on their dot products to see if - // they reside within the filtering cone. - // - //This is done by computing the smallest per-texel angle to get a conservative estimate - // of the number of texels needed to be covered in width and height order to filter the - // region. the bounding box for the center taps face is defined first, and if the - // filtereing region bleeds onto the other faces, bounding boxes for the other faces are - // defined next - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::FilterCubeSurfaces(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, - float a_FilterConeAngle, int32 a_FilterType, bool a_bUseSolidAngle, int32 a_FaceIdxStart, - int32 a_FaceIdxEnd, int32 a_ThreadIdx, float a_SpecularPower) - { - const int32 srcSize = a_SrcCubeMap[0].m_Width; - const int32 dstSize = a_DstCubeMap[0].m_Width; - - //min angle a src texel can cover (in degrees) - const float srcTexelAngle = (180.0f / (float)CP_PI) * atan2f(1.0f, (float)srcSize); - - //angle about center tap to define filter cone - float filterAngle; - - //filter angle is 1/2 the cone angle - filterAngle = a_FilterConeAngle / 2.0f; - - //ensure filter angle is larger than a texel - if(filterAngle < srcTexelAngle) - { - filterAngle = srcTexelAngle; - } - - //ensure filter cone is always smaller than the hemisphere - if(filterAngle > 90.0f) - { - filterAngle = 90.0f; - } - - //the maximum number of texels in 1D the filter cone angle will cover - // used to determine bounding box size for filter extents - //ensure conservative region always covers at least one texel - const int32 filterSize = AZ::GetMax((int32)ceil(filterAngle / srcTexelAngle), 1); - - //dotProdThresh threshold based on cone angle to determine whether or not taps - // reside within the cone angle - const float dotProdThresh = cosf( ((float)CP_PI / 180.0f) * filterAngle ); - - //thread progress - m_ThreadProgress[a_ThreadIdx].m_StartFace = a_FaceIdxStart; - m_ThreadProgress[a_ThreadIdx].m_EndFace = a_FaceIdxEnd; - - //process required faces - for(int32 iCubeFace = a_FaceIdxStart; iCubeFace <= a_FaceIdxEnd && !m_shutdownWorkerThreadSignal; iCubeFace++) - { - //iterate over dst cube map face texel - for(int32 v = 0; v < dstSize && !m_shutdownWorkerThreadSignal; v++) - { - CP_ITYPE *texelPtr = a_DstCubeMap[iCubeFace].m_ImgData + v * a_DstCubeMap[iCubeFace].m_NumChannels * dstSize; - - m_ThreadProgress[a_ThreadIdx].m_CurrentFace = iCubeFace; - m_ThreadProgress[a_ThreadIdx].m_CurrentRow = v; - - for(int32 u=0; u 0.0f) - { - totalMipComputation = pow(m_InputSize * m_BaseFilterAngle , 2.0f) * (m_OutputSize * m_OutputSize); - } - else - { - totalMipComputation = pow(m_InputSize * 0.01f , 2.0f) * (m_OutputSize * m_OutputSize); - } - - progressMipComputation = 0.0f; - if(a_FilterProgress->m_CurrentMipLevel > 0) - { - progressMipComputation = totalMipComputation; - } - - //filtering angle for this miplevel - filterAngle = m_InitialMipAngle; - dstSize = m_OutputSize; - - //computation for entire base mip level (if current level is base level) - if(a_FilterProgress->m_CurrentMipLevel == 0) - { - currentMipComputation = totalMipComputation; - currentMipSize = dstSize; - } - - //compuatation to generate subsequent mip levels - for(i=1; i 180) - { - filterAngle = 180; - } - - //note src size is dstSize*2 since miplevels are generated from the subsequent level - computation = pow(dstSize * 2 * filterAngle, 2.0f) * (dstSize * dstSize); - - totalMipComputation += computation; - - //accumulate computation for completed mip levels - if(a_FilterProgress->m_CurrentMipLevel > i) - { - progressMipComputation = totalMipComputation; - } - - //computation for entire current mip level - if(a_FilterProgress->m_CurrentMipLevel == i) - { - currentMipComputation = computation; - currentMipSize = dstSize; - } - } - - //fraction of compuation time processing the entire current mip level will take - currentMipComputation /= totalMipComputation; - progressMipComputation /= totalMipComputation; - - progressFaceComputation = currentMipComputation * - (float)(a_FilterProgress->m_CurrentFace - a_FilterProgress->m_StartFace) / - (float)(1 + a_FilterProgress->m_EndFace - a_FilterProgress->m_StartFace); - - currentFaceComputation = currentMipComputation * - 1.0f / - (1 + a_FilterProgress->m_EndFace - a_FilterProgress->m_StartFace); - - progressRowComputation = currentFaceComputation * - ((float)a_FilterProgress->m_CurrentRow / (float)currentMipSize); - - //progress completed - a_FilterProgress->m_FractionCompleted = - progressMipComputation + - progressFaceComputation + - progressRowComputation; - - - if( a_FilterProgress->m_CurrentFace < 0) - { - a_FilterProgress->m_CurrentFace = 0; - } - - if( a_FilterProgress->m_CurrentMipLevel < 0) - { - a_FilterProgress->m_CurrentMipLevel = 0; - } - - if( a_FilterProgress->m_CurrentRow < 0) - { - a_FilterProgress->m_CurrentRow = 0; - } - - } - - - //-------------------------------------------------------------------------------------- - // Return string describing the current status of the cubemap processing threads - // - //-------------------------------------------------------------------------------------- - WCHAR *CCubeMapProcessor::GetFilterProgressString(void) - { - WCHAR threadProgressString[CP_MAX_FILTER_THREADS][CP_MAX_PROGRESS_STRING]; - int32 i; - - for(i=0; i -#include -#include -#include - -#include "VectorMacros.h" -#include "CBBoxInt32.h" -#include "CImageSurface.h" - -//has routines for saving .rgbe files -#define CG_RGBE_SUPPORT - - -#ifndef WCHAR -#define WCHAR wchar_t -#endif //WCHAR - - -//used to index cube faces -#define CP_FACE_X_POS 0 -#define CP_FACE_X_NEG 1 -#define CP_FACE_Y_POS 2 -#define CP_FACE_Y_NEG 3 -#define CP_FACE_Z_POS 4 -#define CP_FACE_Z_NEG 5 - - -//used to index image edges -// NOTE.. the actual number corresponding to the edge is important -// do not change these, or the code will break -// -// CP_EDGE_LEFT is u = 0 -// CP_EDGE_RIGHT is u = width-1 -// CP_EDGE_TOP is v = 0 -// CP_EDGE_BOTTOM is v = height-1 -#define CP_EDGE_LEFT 0 -#define CP_EDGE_RIGHT 1 -#define CP_EDGE_TOP 2 -#define CP_EDGE_BOTTOM 3 - -//corners of CUBE map (P or N specifys if it corresponds to the -// positive or negative direction each of X, Y, and Z -#define CP_CORNER_NNN 0 -#define CP_CORNER_NNP 1 -#define CP_CORNER_NPN 2 -#define CP_CORNER_NPP 3 -#define CP_CORNER_PNN 4 -#define CP_CORNER_PNP 5 -#define CP_CORNER_PPN 6 -#define CP_CORNER_PPP 7 - -//data types processed by cube map processor -// note that UNORM data types use the full range -// of the unsigned integer to represent the range [0, 1] inclusive -// the float16 datatype is stored as D3Ds S10E5 representation -#define CP_VAL_UNORM8 0 -#define CP_VAL_UNORM8_BGRA 1 -#define CP_VAL_UNORM16 10 -#define CP_VAL_FLOAT16 20 -#define CP_VAL_FLOAT32 30 - - -//return codes for thread execution -// warning STILL_ACTIVE maps to 259, so the number 259 is reserved in this case -// and should only be used for STILL_ACTIVE -#define CP_THREAD_COMPLETED 0 -#define CP_THREAD_TERMINATED 15 -#define CP_THREAD_STILL_ACTIVE STILL_ACTIVE - -#define CP_MAX_PROGRESS_STRING 1024 - -// Type of data used internally by cube map processor -// just in case for any reason more preecision is needed, -// this type can be changed down the road -#define CP_ITYPE float - -// Filter type -#define CP_FILTER_TYPE_DISC 0 -#define CP_FILTER_TYPE_CONE 1 -#define CP_FILTER_TYPE_COSINE 2 -#define CP_FILTER_TYPE_ANGULAR_GAUSSIAN 3 -#define CP_FILTER_TYPE_COSINE_POWER 4 -#define CP_FILTER_TYPE_GGX 5 - - -// Edge fixup type (how to perform smoothing near edge region) -#define CP_FIXUP_NONE 0 -#define CP_FIXUP_PULL_LINEAR 1 -#define CP_FIXUP_PULL_HERMITE 2 -#define CP_FIXUP_AVERAGE_LINEAR 3 -#define CP_FIXUP_AVERAGE_HERMITE 4 - - -// Max potential cubemap size is limited to 65k (2^16 texels) on a side -#define CP_MAX_MIPLEVELS 16 - -//maximum number of threads running for cubemap processor is 2 -#define CP_MAX_FILTER_THREADS 2 - -//initial number of filtering threads for cubemap processor -#define CP_INITIAL_NUM_FILTER_THREADS 1 - - -//current status of cubemap processor -#define CP_STATUS_READY 0 -#define CP_STATUS_PROCESSING 1 -#define CP_STATUS_FILTER_TERMINATED 2 -#define CP_STATUS_FILTER_COMPLETED 3 - - -#define CP_SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } -#define CP_SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } - -namespace ImageProcessing -{ - - - //information about cube maps neighboring face after traversing - // across an edge - struct CPCubeMapNeighbor - { - uint8 m_Face; //index of neighboring face - uint8 m_Edge; //edge in neighboring face that abuts this face - }; - - - //-------------------------------------------------------------------------------------------------- - //structure used to store current progress of the filtering - //-------------------------------------------------------------------------------------------------- - struct SFilterProgress - { - //status of current cube map processing - int32 m_CurrentFace; - int32 m_CurrentRow; - int32 m_CurrentMipLevel; - - int32 m_StartFace; - int32 m_EndFace; - - float m_FractionCompleted; //Approximate fraction of work completed for this thread - }; - - - //-------------------------------------------------------------------------------------------------- - //structure used to pass filtering parameters for Thread 0 - //-------------------------------------------------------------------------------------------------- - struct SThreadOptionsThread0 - { - class CCubeMapProcessor *m_cmProc; - float m_BaseFilterAngle; - float m_InitialMipAngle; - float m_MipAnglePerLevelScale; - float m_GlossScale; - float m_GlossBias; - int32 m_FilterType; - int32 m_FixupType; - int32 m_FixupWidth; - int32 m_SampleCountGGX; - bool m_bUseSolidAngle; - }; - - - //-------------------------------------------------------------------------------------------------- - //structure used to pass filtering parameters to the process for Thread 1 (if used) - //-------------------------------------------------------------------------------------------------- - struct SThreadOptionsThread1 - { - class CCubeMapProcessor *m_cmProc; - CImageSurface *m_SrcCubeMap; - CImageSurface *m_DstCubeMap; - float m_FilterConeAngle; - int32 m_FilterType; - bool m_bUseSolidAngle; - int32 m_FaceIdxStart; - int32 m_FaceIdxEnd; - int32 m_ThreadIdx; - }; - - - //-------------------------------------------------------------------------------------------------- - //Class to filter, perform edge fixup, and build a mip chain for a cubemap - //-------------------------------------------------------------------------------------------------- - class CCubeMapProcessor - { - public: - - //cubemap processor status - int32 m_Status; - - //information about threads actively processing the cubemap - int32 m_NumFilterThreads; - bool m_bThreadInitialized[CP_MAX_FILTER_THREADS]; - - AZStd::thread m_ThreadHandle[CP_MAX_FILTER_THREADS]; - - AZ::u32 m_ThreadID[CP_MAX_FILTER_THREADS]; - SFilterProgress m_ThreadProgress[CP_MAX_FILTER_THREADS]; - WCHAR m_ProgressString[CP_MAX_PROGRESS_STRING]; - - //filtering parameters last used for filtering - float m_BaseFilterAngle; - float m_InitialMipAngle; - float m_MipAnglePerLevelScale; - - int32 m_InputSize; //input cubemap size (e.g. face width and height of topmost mip level) - int32 m_OutputSize; //output cubemap size (e.g. face width and height of topmost mip level) - int32 m_NumMipLevels; //number of output mip levels - int32 m_NumChannels; //number of channels in cube map processor - - CP_ITYPE *m_FilterLUT; //filter weight lookup table (scale dot product 0-1 range to index into it) - int32 m_NumFilterLUTEntries; //number of filter lookup table entries - - CImageSurface m_NormCubeMap[6]; //normalizer cube map and solid angle lookup table - - CImageSurface m_InputSurface[6]; //input faces for topmost mip level - - CImageSurface m_OutputSurface[CP_MAX_MIPLEVELS][6]; //output faces for all mip levels - - private: - //========================================================================================================== - //BuildNormalizerCubemap(int32 a_Size, CImageSurface *a_Surface ); - // Builds a normalizer cubemap of size a_Size. This routine deallocates the CImageSurfaces passed - // into the the function and reallocates them with the correct size and 3 channels to store the - // normalized vector for each texel. - // - // a_Size [in] size of normalizer cubemap - // a_Surface [out] Pointer to array of 6 CImageSurfaces where normalizer cube faces will be stored - // - //========================================================================================================== - void BuildNormalizerCubemap(int32 a_Size, CImageSurface *a_Surface); - - //========================================================================================================== - //void BuildNormalizerSolidAngleCubemap(int32 a_Size, CImageSurface *a_Surface ); - // Builds a normalizer|solid angle cubemap of size a_Size. This routine deallocates the CImageSurfaces - // passed into the the function and reallocates them with the correct size and 4 channels to store the - // normalized vector, and solid angle for each texel. - // - // a_Size [in] - // a_Surface [out] Pointer to array of 6 CImageSurfaces where normalizer cube faces will be stored - // - //========================================================================================================== - void BuildNormalizerSolidAngleCubemap(int32 a_Size, CImageSurface *a_Surface); - - //========================================================================================================== - //Clears filter extent bounding boxes for each face of the cubemap - // - // a_FilterExtents [in] Array of 6 bounding boxes (corresponding to the 6 cubemap faces) to clear - //========================================================================================================== - void ClearFilterExtents(CBBoxInt32 *a_FilterExtents); - - //========================================================================================================== - //void DetermineFilterExtents(float *a_CenterTapDir, int32 a_SrcSize, int32 a_BBoxSize, - // CBBoxInt32 *a_FilterExtents); - // - //Determines bounding boxes for each cube face for a single kernels angular extent - // a_CenterTapDir [in] Vector of 3 float32s specifying the center tap direction - // a_SrcSize [in] Source cubemap size (for the miplevel used as input to the filtering) - // a_BBoxSize [in] Maximum length in texels of the bbox extent derived from the filtering - // cone angle - // a_FilterExtents [out] Array of 6 bounding boxes (corresponding to the 6 cubemap faces) to clear - //========================================================================================================== - void DetermineFilterExtents(float *a_CenterTapDir, int32 a_SrcSize, int32 a_BBoxSize, CBBoxInt32 *a_FilterExtents); - - //========================================================================================================== - //void ProcessFilterExtents(float *a_CenterTapDir, float a_DotProdThresh, CBBoxInt32 *a_FilterExtents, - // CImageSurface *a_NormCubeMap, CImageSurface *a_SrcCubeMap, CP_ITYPE *a_DstVal, uint32 a_FilterType, - // bool a_bUseSolidAngle ); - // - //Processes all the texels within the bounding boxes in order to accumulate all the weighted taps to - // compute a single fitered texel value. - // - //a_CenterTapDir [in] Center tap directions - //a_DotProdThresh [in] Threshhold on dot product between center tap and - //a_FilterExtents [in] array of 6 bounding boxes describing rough filter extents for each face - //a_NormCubeMap [in] normalizer|solid angle cubemap - //a_SrcCubeMap [in] array of 6 faces comprising the miplevel of the source cubemap the filter is - // generated from - //a_DstVal [out] resulting filtered texel color - //a_FilterType [in] filter type: Choose one of the following options: CP_FILTER_TYPE_DISC, - // CP_FILTER_TYPE_CONE, CP_FILTER_TYPE_COSINE, CP_FILTER_TYPE_ANGULAR_GAUSSIAN - //a_bUseSolidAngle [in] Set this to true in order to incorporate the solid angle subtended - // each texel in the filter kernel in the filtering. - // - //========================================================================================================== - void ProcessFilterExtents(float *a_CenterTapDir, float a_DotProdThresh, CBBoxInt32 *a_FilterExtents, - CImageSurface *a_NormCubeMap, CImageSurface *a_SrcCubeMap, CP_ITYPE *a_DstVal, uint32 a_FilterType, - bool a_bUseSolidAngle, float a_SpecularPower); - - //========================================================================================================== - //void FixupCubeEdges(CImageSurface *a_CubeMap, int32 a_FixupType, int32 a_FixupWidth); - // - //Apply edge fixup to a cubemap mip level. - // - //a_CubeMap [in/out] Array of 6 images comprising cubemap miplevel to apply edge fixup to. - //a_FixupType [in] Specifies the technique used for edge fixup. Choose one of the following, - // CP_FIXUP_NONE, CP_FIXUP_PULL_LINEAR, CP_FIXUP_PULL_HERMITE, CP_FIXUP_AVERAGE_LINEAR, - // CP_FIXUP_AVERAGE_HERMITE - //a_FixupWidth [in] Fixup width in texels - // - //========================================================================================================== - void FixupCubeEdges(CImageSurface *a_CubeMap, int32 a_FixupType, int32 a_FixupWidth); - - //========================================================================================================== - //void BuildAngleWeightLUT(int32 a_NumFilterLUTEntries, int32 a_FilterType, float a_FilterAngle); - // - // Builds filter weight lookup table in order to quickly evaluate the weight of a particular texel - // for the Cone and Angular Gaussian fiter types. This lookup table is quickly indexed using the - // same dot product between the center tap and current texel that is used to determine whether a - // texel is inside or outside the filtering kernel. - // - //a_NumFilterLUTEntries [in] Number of entries in filter weight lookup table - //a_FilterType [in] Filter type - //a_FilterAngle [in] Filtering half cone angle - //========================================================================================================== - void BuildAngleWeightLUT(int32 a_NumFilterLUTEntries, int32 a_FilterType, float a_FilterAngle); - - //========================================================================================================== - //void PrecomputeFilterLookupTables(uint32 a_FilterType, int32 a_SrcCubeMapWidth, float a_FilterConeAngle); - // - // Builds the following lookup tables prior to filtering: - // -normalizer cube map - // -filter weight lookup table - // - //a_FilterType [in] Filter type - //a_SrcCubeMapWidth [in] source cubemap size - //a_FilterConeAngle [in] Filtering half cone angle - //========================================================================================================== - void PrecomputeFilterLookupTables(uint32 a_FilterType, int32 a_SrcCubeMapWidth, float a_FilterConeAngle); - - //========================================================================================================== - //void EstimateFilterThreadProgress(SFilterProgress *a_FilterProgress); - // - // Estimates percentage complete for a filtering thread for the current tap that is being filtered - // - //a_FilterProgress [in/out] Information about the filtereing thread's current position, and range of faces - // that it will process. - //========================================================================================================== - void EstimateFilterThreadProgress(SFilterProgress *a_FilterProgress); - - public: - //========================================================================================================== - //note that these functions are only public so that they can be called from within the global scope - // from the thread starting point functions. These should not be called by any other functions external - // to the class. - //========================================================================================================== - void FilterCubeMapMipChain(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale, - int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle, float a_GlossScale, float a_GlossBias, - int32 a_SampleCountGGX); - void FilterCubeSurfaces(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, float a_FilterConeAngle, - int32 a_FilterType, bool a_bUseSolidAngle, int32 a_FaceIdxStart, int32 a_FaceIdxEnd, int32 aThreadIdx, - float a_SpecularPower = 1.0f); - void FilterCubeSurfacesGGX(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, int32 a_SampleCount, float a_Roughness, - int32 a_FaceIdxStart, int32 a_FaceIdxEnd, int32 aThreadIdx); - - public: - CCubeMapProcessor(void); - ~CCubeMapProcessor(); - - //========================================================================================================== - // void Init(int32 a_InputSize, int32 a_OutputSize, int32 a_NumMipLevels, int32 a_NumChannels); - // - // Initializes cube map processor class - // - // a_InputSize [in] Size of the input cubemap - // a_OutputSize [in] Size of the input cubemap - // a_NumMipLevels [in] Number of miplevels in the output cubemap - // a_NumChannels [in] Number of color channels (internally) in the input and output cubemap - //========================================================================================================== - void Init(int32 a_InputSize, int32 a_OutputSize, int32 a_NumMipLevels, int32 a_NumChannels); - - - //========================================================================================================== - // void GetInputFaceData(int32 a_FaceIdx, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - // void *a_DstDataPtr, float a_Scale, float a_Gamma); - // - // Copies image data from the input cube map into a destination image. These routine describe the output - // image layout using a pitch and a pointer so that the image can be copied from a subrect of a locked - // D3D surface easily. Note that when reading out the image data, the intensity scale is applied first, - // and then degamma. - // - // a_FaceIdx [in] Index (0-5) of the input cubemap cube face to read the image data from. - // a_DstType [in] Data type for the image data being copied out the input cube map. - // choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16 - // CP_VAL_FLOAT16, CP_VAL_FLOAT32. - // a_DstNumChannels [in] Number of channels in the destination image. - // a_DstPitch [in] Pitch in bytes of the destination image. - // a_DstDataPtr [in] Pointer to the top-left pixel in the destination image. - // a_Scale [in] Scale factor to apply to intensities. - // a_Gamma [in] Degamma to apply to intensities. - // - //========================================================================================================== - void GetInputFaceData(int32 a_FaceIdx, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - void *a_DstDataPtr, float a_Scale, float a_Gamma); - - - //========================================================================================================== - // void SetInputFaceData(int32 a_FaceIdx, int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, - // void *a_SrcDataPtr, float a_MaxClamp, float a_Scale, float a_Gamma ); - // - // Copies image data from a source image into one of the faces in the input cubemap in the cubemap. - // processor. These routines describe the output image layout using a pitch and a pointer so that the image - // can be copied from a subrect of a locked D3D surface easily. Note that the clamping is applied first, - // followed by the scale and then gamma. - // - // a_FaceIdx [in] Index (0-5) of the input cubemap cube face to write the image data into - // a_SrcType [in] Data type for the image data being copied into the cube map processor. - // choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16 - // CP_VAL_FLOAT16, CP_VAL_FLOAT32. - // a_SrcNumChannels [in] Number of channels in the source image. - // a_SrcPitch [in] Pitch in bytes of the source image. - // a_SrcDataPtr [in] Pointer to the top-left pixel in the source image. - // a_MaxClamp [in] Max value to clamp the input intensity values to. - // a_Degamma [in] Degamma to apply to input intensities. - // a_Scale [in] Scale factor to apply to input intensities. - // - //========================================================================================================== - void SetInputFaceData(int32 a_FaceIdx, int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, - void *a_SrcDataPtr, float a_MaxClamp, float a_Degamma, float a_Scale); - - - //========================================================================================================== - // void GetOutputFaceData(int32 a_FaceIdx, int32 a_Level, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - // void *a_DstDataPtr, float a_Scale, float a_Gamma ); - // - // a_FaceIdx [in] Index (0-5) of the output cubemap cube face to read the image data from. - // a_Level [in] Miplevel of the output cubemap to read from - // a_DstType [in] Data type for the image data being copied out the input cube map. - // choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16 - // CP_VAL_FLOAT16, CP_VAL_FLOAT32 - // a_DstNumChannels [in] Number of channels in the destination image. - // a_DstPitch [in] Pitch in bytes of the destination image. - // a_DstDataPtr [in] Pointer to the top-left pixel in the destination image. - // a_Scale [in] Scale factor to apply to intensities. - // a_Gamma [in] Degamma to apply to intensities. - // - //========================================================================================================== - void GetOutputFaceData(int32 a_FaceIdx, int32 a_Level, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - void *a_DstDataPtr, float a_Scale, float a_Gamma); - - - //========================================================================================================== - //void InitiateFiltering(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale, - // int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle ); - // - // Starts filtering the cubemap. - // If the number of filter threads is zero, the function does not return until the filtering is complete - // If the number of filter threads is non-zero, a filtering thread (or multiple threads) are started and - // the function returns immediately, with the threads running in the background. - // - // The cube map filtereing is specified using a number of parameters: - // Filtering per miplevel is specified using 2D cone angle (in degrees) that - // indicates the region of the hemisphere to filter over for each tap. - // - // Note that the top mip level is also a filtered version of the original input images - // as well in order to create mip chains for diffuse environment illumination. - // The cone angle for the top level is specified by a_BaseAngle. This can be used to - // generate mipchains used to store the results of preintegration across the hemisphere. - // - // The angle for the subsequent levels of the mip chain are specified by their parents - // filtering angle and a per-level scale and bias - // newAngle = oldAngle * a_MipAnglePerLevelScale; - // - // a_BaseFilterAngle [in] Base filter angle - // a_InitialMipAngle [in] Mip angle used to generate the next level of the mip chain from the base level - // a_MipAnglePerLevelScale [in] Scale factor to iteratively apply to the filtering angle to filter subsequent - // mip-levels. - // a_FilterType [in] Specifies the filtering type for angular extent filtering. Choose one of the - // following options: CP_FILTER_TYPE_DISC, CP_FILTER_TYPE_CONE, - // CP_FILTER_TYPE_COSINE, CP_FILTER_TYPE_ANGULAR_GAUSSIAN - // a_FixupType [in] Specifies the technique used for edge fixup. Choose one of the following, - // CP_FIXUP_NONE, CP_FIXUP_PULL_LINEAR, CP_FIXUP_PULL_HERMITE, - // CP_FIXUP_AVERAGE_LINEAR, CP_FIXUP_AVERAGE_HERMITE - // a_FixupWidth [in] Width in texels of the fixup region. - // a_bUseSolidAngle [in] Set this to true in order to incorporate the solid angle subtended - // each texel in the filter kernel in the filtering. - //========================================================================================================== - void InitiateFiltering(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale, - int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle, - float a_GlossScale, float a_GlossBias, int32 a_SampleCountGGX); - - //========================================================================================================== - // void WriteMipLevelIntoAlpha(void) - // - // Encodes the miplevel in the alpha channel of the output cubemap. - // The miplevel is encoded as (miplevel * 16.0f / 255.0f) so that the miplevel has an exact encoding in an - // 8-bit or 16-bit UNORM representation. - // - //========================================================================================================== - void WriteMipLevelIntoAlpha(void); - - - //========================================================================================================== - // Horizontally flips all the faces in the input cubemap - // - //========================================================================================================== - void FlipInputCubemapFaces(void); - - //========================================================================================================== - // Horizontally flips all the faces in the output cubemap - // - //========================================================================================================== - void FlipOutputCubemapFaces(void); - - - //========================================================================================================== - // Allows for in-place color channel swapping of the input cubemap. This routine can be useful for - // converting RGBA format data to BGRA format data. - // - // a_Channel0Src [in] Index of the color channel used as the source for the new channel 0 - // a_Channel1Src [in] Index of the color channel used as the source for the new channel 1 - // a_Channel2Src [in] Index of the color channel used as the source for the new channel 0 - // a_Channel3Src [in] Index of the color channel used as the source for the new channel 1 - // - //========================================================================================================== - void ChannelSwapInputFaceData(int32 a_Channel0Src, int32 a_Channel1Src, int32 a_Channel2Src, int32 a_Channel3Src); - - - //========================================================================================================== - // Allows for in-place color channel swapping of the output cubemap. This routine can be useful for - // converting RGBA format data to BGRA format data. - // - // a_Channel0Src [in] Index of the color channel used as the source for the new channel 0 - // a_Channel1Src [in] Index of the color channel used as the source for the new channel 1 - // a_Channel2Src [in] Index of the color channel used as the source for the new channel 0 - // a_Channel3Src [in] Index of the color channel used as the source for the new channel 1 - //========================================================================================================== - void ChannelSwapOutputFaceData(int32 a_Channel0Src, int32 a_Channel1Src, int32 a_Channel2Src, int32 a_Channel3Src); - - - //========================================================================================================== - // Resets the current cubemap processor, and deallocates the input and output cubemaps. - // - // This function is automatically called by destructor. - //========================================================================================================== - void Clear(void); - - - //========================================================================================================== - // Terminates any active filtering threads. This stops the filtering of the current cubemap. - // - //========================================================================================================== - void TerminateActiveThreads(void); - - - //========================================================================================================== - // Gets the current filtering progress string - // - //========================================================================================================== - WCHAR *GetFilterProgressString(void); - - - //========================================================================================================== - // Checks to see if either of the filtering threads is active - // - //========================================================================================================== - bool IsFilterThreadActive(uint32 a_ThreadIdx); - - //========================================================================================================== - // Gets the current status of the cubemap processing threads. The possible return values and their - // associated meanings are: - // - // CP_STATUS_READY: The cubemap processor is currently ready to change settings, and to load a - // new input cubemap. - // CP_STATUS_PROCESSING: The cubemap processor is currently filtering a cubemap - // CP_STATUS_FILTER_TERMINATED: The cubemap processor was terminated before the filtering was completed. - // CP_STATUS_FILTER_COMPLETED: The cubemap processor fully completed filtering the cubemap. - // - //========================================================================================================== - int32 GetStatus(void); - - - //========================================================================================================== - // This signifies to the cubemap processor that you have acknowledged a - // CP_STATUS_FILTER_TERMINATED or CP_STATUS_FILTER_COMPLETED status code, and would like to - // reset the cubemap processor to CP_STATUS_READY. - //========================================================================================================== - void RefreshStatus(void); - - AZStd::atomic_bool m_shutdownWorkerThreadSignal; ///< Signals the worker threads to stop. - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.cpp b/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.cpp deleted file mode 100644 index 62daa2b4d7..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -//-------------------------------------------------------------------------------------- -//CImageSurface -// Class for storing, manipulating, and copying image data to and from D3D Surfaces -// -//-------------------------------------------------------------------------------------- -// (C) 2005 ATI Research, Inc., All rights reserved. -//-------------------------------------------------------------------------------------- -// modifications by Crytek GmbH -// modifications by Amazon - -#include - -#include "CImageSurface.h" - - -namespace ImageProcessing -{ - //-------------------------------------------------------------------------------------- - // convert D3D 16 bit float to standard 32 bit float - // Format: - // - // 1 sign bit in MSB, (s) - // 5 bits of biased exponent, (e) - // 10 bits of fraction, (f), with an additional hidden bit - // A float16 value, v, made from the format above takes the following meaning: - // - // (a) if e == 31 and f != 0, then v is NaN regardless of s - // (b) if e == 31 and f == 0, then v = (-1)^s * infinity (signed infinity) - // (c) if 0 < e < 31, then v = (-1)^s * 2^(e-15) * (1.f) - // (d) if e == 0 and f != 0, then v = (-1)^s * 2^(e-14) * (0.f) (denormalized numbers) - // (e) if e == 0 and f == 0, then v = (-1)^s *0 (signed zero) - // - //-------------------------------------------------------------------------------------- - float CPf16Tof32(uint16 aVal) - { - uint32 signVal = (aVal >> 15); //sign bit in MSB - uint32 exponent = ((aVal >> 10) & 0x01f); //next 5 bits after signbit - uint32 mantissa = (aVal & 0x03ff); //lower 10 bits - uint32 rawFloat32Data; //raw binary float data - - //convert s10e5 5-bit exponent to IEEE754 s23e8 8-bit exponent - if (exponent == 31) - { // infinity or Nan depending on mantissa - exponent = 255; - } - else if (exponent == 0) - { // denormalized floats mantissa is treated as = 0.f - exponent = 0; - } - else - { //change 15base exponent to 127base exponent - //normalized floats mantissa is treated as = 1.f - exponent += (127 - 15); - } - - //convert 10-bit mantissa to 23-bit mantissa - mantissa <<= (23 - 10); - - //assemble s23e8 number using logical operations - rawFloat32Data = (signVal << 31) | (exponent << 23) | mantissa; - - //treat raw data as a 32 bit float - return *((float *)&rawFloat32Data); - } - - - //-------------------------------------------------------------------------------------- - // convert standard 32 bit float to D3D 16 bit float - // - // 16-bit float format: - // - // 1 sign bit in MSB, (s) - // 5 bits of biased exponent, (e) - // 10 bits of fraction, (f), with an additional hidden bit - // A float16 value, v, made from the format above takes the following meaning: - // - // (a) if e == 31 and f != 0, then v is NaN regardless of s - // (b) if e == 31 and f == 0, then v = (-1)s*infinity (signed infinity) - // (c) if 0 < e < 31, then v = (-1)s*2(e-15)*(1.f) - // (d) if e == 0 and f != 0, then v = (-1)s*2(e-14)*(0.f) (denormalized numbers) - // (e) if e == 0 and f == 0, then v = (-1)s*0 (signed zero) - //-------------------------------------------------------------------------------------- - uint16 CPf32Tof16(float aVal) - { - uint32 rawf32Data = *((uint32 *)&aVal); //raw binary float data - - uint32 signVal = (rawf32Data >> 31); //sign bit in MSB - uint32 exponent = ((rawf32Data >> 23) & 0xff); //next 8 bits after signbit - uint32 mantissa = (rawf32Data & 0x7fffff); //mantissa = lower 23 bits - - uint16 rawf16Data; - - //convert IEEE754 s23e8 8-bit exponent to s10e5 5-bit exponent - if (exponent == 255) - {//special case 32 bit float is inf or NaN, use mantissa as is - exponent = 31; - } - else if (exponent < ((127 - 15) - 10)) - {//special case, if 32-bit float exponent is out of 16-bit float range, then set 16-bit float to 0 - exponent = 0; - mantissa = 0; - } - else if (exponent >= (127 + (31 - 15))) - { // max 15based exponent for s10e5 is 31 - // force s10e5 number to represent infinity by setting mantissa to 0 - // and exponent to 31 - exponent = 31; - mantissa = 0; - } - else if (exponent <= (127 - 15)) - { //convert normalized s23e8 float to denormalized s10e5 float - - //add implicit 1.0 to mantissa to convert from 1.f to use as a 0.f mantissa - mantissa |= (1 << 23); - - //shift over mantissa number of bits equal to exponent underflow - mantissa = mantissa >> (1 + ((127 - 15) - exponent)); - - //zero exponent to treat value as a denormalized number - exponent = 0; - } - else - { //change 127base exponent to 15base exponent - // no underflow or overflow of exponent - //normalized floats mantissa is treated as= 1.f, so - // no denormalization or exponent derived shifts to the mantissa - exponent -= (127 - 15); - } - - //convert 23-bit mantissa to 10-bit mantissa - mantissa >>= (23 - 10); - - //assemble s10e5 number using logical operations - rawf16Data = (signVal << 15) | (exponent << 10) | mantissa; - - //return re-assembled raw data as a 32 bit float - return rawf16Data; - } - - - //-------------------------------------------------------------------------------------- - //size of data types in bytes - //-------------------------------------------------------------------------------------- - int32 CPTypeSizeOf(int32 a_Type) - { - switch (a_Type) - { - case CP_VAL_UNORM8: - case CP_VAL_UNORM8_BGRA: - return 1; - break; - case CP_VAL_UNORM16: - return 2; - break; - case CP_VAL_FLOAT16: - return 2; - break; - case CP_VAL_FLOAT32: - return 4; - break; - default: - return 1; - break; - } - } - - - //-------------------------------------------------------------------------------------- - //get value of data pointed to by a_Ptr given type information - //-------------------------------------------------------------------------------------- - CP_ITYPE CPTypeGetVal(int32 a_Type, void *a_Ptr) - { - switch (a_Type) - { - case CP_VAL_UNORM8: - case CP_VAL_UNORM8_BGRA: - return (1.0f / 255.0f) * *((uint8 *)a_Ptr); - break; - case CP_VAL_UNORM16: - return (1.0f / 65535.0f) * *((uint16 *)a_Ptr); - break; - case CP_VAL_FLOAT16: - return CPf16Tof32(*((uint16 *)a_Ptr)); - break; - case CP_VAL_FLOAT32: - return *((float *)a_Ptr); - break; - default: - return 0; - break; - } - } - - - //-------------------------------------------------------------------------------------- - //Given a CP_ITYPE value as input, convert it to the given type specified by a_Type - // and write the value to a_Ptr - //-------------------------------------------------------------------------------------- - void CPTypeSetVal(CP_ITYPE a_Val, int32 a_Type, void *a_Ptr) - { - CP_ITYPE clampVal; //clamp value to 0-1 range to output UNORM types - - switch (a_Type) - { - case CP_VAL_UNORM8: - case CP_VAL_UNORM8_BGRA: - clampVal = VM_MIN(VM_MAX(a_Val, 0.0f), 1.0f); - *((uint8 *)a_Ptr) = (uint8)(clampVal * 255.0f); - break; - case CP_VAL_UNORM16: - clampVal = VM_MIN(VM_MAX(a_Val, 0.0f), 1.0f); - *((uint16 *)a_Ptr) = (uint16)(clampVal * 65535.0f); - break; - case CP_VAL_FLOAT16: - *((uint16 *)a_Ptr) = CPf32Tof16(a_Val); - break; - case CP_VAL_FLOAT32: - *((float *)a_Ptr) = a_Val; - break; - default: - break; - } - } - - - //-------------------------------------------------------------------------------------- - //Error handling for imagesurface class - // Pop up dialog box, and terminate application - //-------------------------------------------------------------------------------------- - void CImageSurface::FatalError([[maybe_unused]] const WCHAR *a_Msg) - { - AZ_Error("Image Processing", false, "CImageSurface Error: %s", a_Msg); - } - - - //-------------------------------------------------------------------------------------- - // Image surface - //-------------------------------------------------------------------------------------- - CImageSurface::CImageSurface(void) - { - m_Width = 0; //cubemap face width - m_Height = 0; //cubemap face height - m_NumChannels = 0; //number of channels - m_ImgData = NULL; - - } - - - //-------------------------------------------------------------------------------------- - // Clear - //-------------------------------------------------------------------------------------- - void CImageSurface::Clear(void) - { - m_Width = 0; //cubemap face width - m_Height = 0; //cubemap face height - m_NumChannels = 0; //number of channels - SAFE_DELETE_ARRAY(m_ImgData); //safe delete old image data - } - - - //-------------------------------------------------------------------------------------- - // Initialize surface and associated memory - //-------------------------------------------------------------------------------------- - void CImageSurface::Init(int32 a_Width, int32 a_Height, int32 a_NumChannels) - { - m_Width = a_Width; //cubemap face width - m_Height = a_Height; //cubemap face height - m_NumChannels = a_NumChannels; //number of channels - - SAFE_DELETE_ARRAY(m_ImgData); //safe delete old image data - - m_ImgData = new(std::nothrow) CP_ITYPE[m_Width * m_Height * m_NumChannels]; //assume tight data packing - if (!m_ImgData) - { - FatalError(L"Unable to allocate data for image in CImageSurface::Init."); - } - } - - - //-------------------------------------------------------------------------------------- - //copy and convert data from external buffer into this surface - // - // note that srcPitch == the source pitch in bytes - //-------------------------------------------------------------------------------------- - void CImageSurface::SetImageData(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr) - { - int32 i, j, k; - - CP_ITYPE *dstDataWalk = m_ImgData; - uint8 *srcDataWalk = (uint8 *)a_SrcDataPtr; - - int32 srcValueSize = CPTypeSizeOf(a_SrcType); - int32 srcTexelStep = srcValueSize * a_SrcNumChannels; - int32 numChannelsSet = VM_MIN(a_SrcNumChannels, m_NumChannels); - int32 srcChannelSelect; - - //loop over rows - for (j = 0; j < m_Height; j++) - { - //pointer arithmetic to offset pointer by pitch in bytes - srcDataWalk = ((uint8 *)a_SrcDataPtr + (j * a_SrcPitch)); - - //loop over texels within row - for (i = 0; i < m_Width; i++) - { - srcChannelSelect = 0; - - //loop over channels within texel - for (k = 0; k < numChannelsSet; k++) - { - if (a_SrcType == CP_VAL_UNORM8_BGRA) //swap channels 0, and 2 if in BGRA format - { - switch (k) - { - case 0: - *(dstDataWalk + 2) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - break; - case 2: - *(dstDataWalk + 0) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - break; - default: - *(dstDataWalk + k) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - break; - } - } - else - { - *(dstDataWalk + k) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - } - - srcChannelSelect += srcValueSize; - } - - dstDataWalk += m_NumChannels; - srcDataWalk += srcTexelStep; - } - } - } - - - //-------------------------------------------------------------------------------------- - // Copy and convert data from external buffer into this surface set image data degamma - // and scale - // - //-------------------------------------------------------------------------------------- - void CImageSurface::SetImageDataClampDegammaScale(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, - void *a_SrcDataPtr, float a_MaxClamp, float a_Gamma, float a_Scale) - { - int32 i, j, k; - - CP_ITYPE *dstDataWalk = m_ImgData; - uint8 *srcDataWalk = (uint8 *)a_SrcDataPtr; - - int32 srcValueSize = CPTypeSizeOf(a_SrcType); - int32 srcTexelStep = srcValueSize * a_SrcNumChannels; - int32 numChannelsSet = VM_MIN(a_SrcNumChannels, m_NumChannels); - int32 srcChannelSelect; - - //loop over rows - for (j = 0; j < m_Height; j++) - { - //pointer arithmetic to offset pointer by pitch in bytes - srcDataWalk = ((uint8 *)a_SrcDataPtr + (j * a_SrcPitch)); - - //loop over texels within row - for (i = 0; i < m_Width; i++) - { - srcChannelSelect = 0; - - //loop over channels within texel - for (k = 0; k < numChannelsSet; k++) - { - CP_ITYPE texelVal; - - //get texel value from external buffer - texelVal = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - - //clamp texelVal using max value only - // (using texelVal as the min clamping arguement means no minimum clamping) - VM_CLAMP(texelVal, texelVal, texelVal, a_MaxClamp); - - if (k < 3) //only apply gamma and scale to RGB channels - { - //degamma texel val, by raising to the power gamma - texelVal = pow(texelVal, a_Gamma); - - //scale texel val in linear space (after degamma) - texelVal *= a_Scale; - } - - //write data - if ((a_SrcType == CP_VAL_UNORM8_BGRA) && (k == 0)) - { - *(dstDataWalk + 2) = texelVal; - } - else if ((a_SrcType == CP_VAL_UNORM8_BGRA) && (k == 2)) - { - *(dstDataWalk + 0) = texelVal; - } - else - { - *(dstDataWalk + k) = texelVal; - } - - srcChannelSelect += srcValueSize; - } - - dstDataWalk += m_NumChannels; - srcDataWalk += srcTexelStep; - } - } - } - - - //-------------------------------------------------------------------------------------- - //copy data from this image surface into an external buffer - // - //-------------------------------------------------------------------------------------- - void CImageSurface::GetImageData(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr) - { - int32 i, j, k; - - CP_ITYPE *srcDataWalk = m_ImgData; - uint8 *dstDataWalk = (uint8 *)a_DstDataPtr; - - int32 dstValueSize = CPTypeSizeOf(a_DstType); - int32 dstTexelStep = dstValueSize * a_DstNumChannels; - - int32 numChannelsSet = VM_MIN(a_DstNumChannels, m_NumChannels); - int32 dstChannelSelect; - - //loop over rows - for (j = 0; j < m_Height; j++) - { - //pointer arithmetic to offset pointer by pitch in bytes - dstDataWalk = ((uint8 *)a_DstDataPtr + (j * a_DstPitch)); - - //loop over texels within row - for (i = 0; i < m_Width; i++) - { - dstChannelSelect = 0; - - //loop over channels within texel - for (k = 0; k < numChannelsSet; k++) - { - //write data - if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 0)) - { - CPTypeSetVal(*(srcDataWalk + 2), a_DstType, dstDataWalk + dstChannelSelect); - } - else if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 2)) - { - CPTypeSetVal(*(srcDataWalk + 0), a_DstType, dstDataWalk + dstChannelSelect); - } - else - { - CPTypeSetVal(*(srcDataWalk + k), a_DstType, dstDataWalk + dstChannelSelect); - } - - dstChannelSelect += dstValueSize; - } - - srcDataWalk += m_NumChannels; - dstDataWalk += dstTexelStep; - } - } - } - - - //-------------------------------------------------------------------------------------- - // Scale and then apply gamma to image data, then copy image data into an external buffer - // note: only apply scale and gamma to RGB channels (e.g. first 3 channels) - // - //-------------------------------------------------------------------------------------- - void CImageSurface::GetImageDataScaleGamma(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - void *a_DstDataPtr, float a_Scale, float a_Gamma) - { - int32 i, j, k; - - CP_ITYPE *srcDataWalk = m_ImgData; - uint8 *dstDataWalk = (uint8 *)a_DstDataPtr; - - int32 dstValueSize = CPTypeSizeOf(a_DstType); - int32 dstTexelStep = dstValueSize * a_DstNumChannels; - - int32 numChannelsSet = VM_MIN(a_DstNumChannels, m_NumChannels); - int32 dstChannelSelect; - - //loop over rows - for (j = 0; j < m_Height; j++) - { - //pointer arithmetic to offset pointer by pitch in bytes - dstDataWalk = ((uint8 *)a_DstDataPtr + (j * a_DstPitch)); - - //loop over texels within row - for (i = 0; i < m_Width; i++) - { - dstChannelSelect = 0; - - //loop over channels within texel - for (k = 0; k < numChannelsSet; k++) - { - CP_ITYPE texelVal; - - texelVal = *(srcDataWalk + k); - - if (k < 3) //only apply gamma and scale to RGB channels - { - //scale texel val - texelVal *= a_Scale; - - //apply gamma to texel val by raising the texelVal to the power of (1/gamma) - texelVal = pow(texelVal, 1.0f / a_Gamma); - } - - //write out texture value - if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 0)) - { - CPTypeSetVal(texelVal, a_DstType, dstDataWalk + (dstValueSize * 2)); - } - else if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 2)) - { - CPTypeSetVal(texelVal, a_DstType, dstDataWalk + (dstValueSize * 0)); - } - else - { - CPTypeSetVal(texelVal, a_DstType, dstDataWalk + dstChannelSelect); - } - - - dstChannelSelect += dstValueSize; - } - - srcDataWalk += m_NumChannels; - dstDataWalk += dstTexelStep; - } - } - } - - - //-------------------------------------------------------------------------------------- - //Set image channel a_ChannelIdx to a_ClearColor for all pixels. - // - //-------------------------------------------------------------------------------------- - void CImageSurface::ClearChannelConst(int32 a_ChannelIdx, CP_ITYPE a_ClearColor) - { - int32 u, v; - CP_ITYPE *texelPtr; - - //if channel does not exist, do not attempt to clear the channel - if (a_ChannelIdx > (m_NumChannels - 1)) - { - return; - } - - for (v = 0; v < m_Height; v++) - { - for (u = 0; u < m_Width; u++) - { - texelPtr = GetSurfaceTexelPtr(u, v); - - *(texelPtr + a_ChannelIdx) = a_ClearColor; - } - } - } - - - //-------------------------------------------------------------------------------------- - //Gets texel ptr in a surface given u and v coordinates, - // - //-------------------------------------------------------------------------------------- - CP_ITYPE *CImageSurface::GetSurfaceTexelPtr(int32 u, int32 v) - { - return(m_ImgData + (((m_Width * v) + u) * m_NumChannels)); - } - - - //-------------------------------------------------------------------------------------- - //flips surface image in place horizontally - // - //-------------------------------------------------------------------------------------- - void CImageSurface::InPlaceHorizonalFlip(void) - { - int32 u, v, k; - CP_ITYPE *texelPtrTop, *texelPtrBottom; - - //iterate over V - for (v = 0; v < (m_Height / 2); v++) - { - for (u = 0; u < m_Height; u++) - { - texelPtrTop = GetSurfaceTexelPtr(u, v); - texelPtrBottom = GetSurfaceTexelPtr(u, (m_Height - 1) - v); - - //iterate over channels - for (k = 0; k < m_NumChannels; k++) - { - CP_ITYPE tmpTexelVal; - - tmpTexelVal = *(texelPtrTop + k); - *(texelPtrTop + k) = *(texelPtrBottom + k); - *(texelPtrBottom + k) = tmpTexelVal; - - } - } - } - } - - - //-------------------------------------------------------------------------------------- - //flips surface image in place vertically - // - //-------------------------------------------------------------------------------------- - void CImageSurface::InPlaceVerticalFlip(void) - { - int32 u, v, k; - CP_ITYPE *texelPtrLeft, *texelPtrRight; - - for (u = 0; u < (m_Width / 2); u++) - { - for (v = 0; v < m_Height; v++) - { - texelPtrLeft = GetSurfaceTexelPtr(u, v); - texelPtrRight = GetSurfaceTexelPtr((m_Width - 1) - u, v); - - //iterate over channels - for (k = 0; k < m_NumChannels; k++) - { - CP_ITYPE tmpTexelVal; - - tmpTexelVal = *(texelPtrLeft + k); - *(texelPtrLeft + k) = *(texelPtrRight + k); - *(texelPtrRight + k) = tmpTexelVal; - } - } - } - } - - - //-------------------------------------------------------------------------------------- - //flip image around line defined by u = v (effectively swaps the u and v axises) - //-------------------------------------------------------------------------------------- - void CImageSurface::InPlaceDiagonalUVFlip(void) - { - int32 u, v, k; - CP_ITYPE *texelPtrLeft, *texelPtrRight; - - if (m_Width != m_Height) - { //only flip image if square - return; - } - - for (v = 0; v < m_Height; v++) - { - for (u = 0; u < v; u++) //only iterate over lower left triangle - { - texelPtrLeft = GetSurfaceTexelPtr(u, v); - texelPtrRight = GetSurfaceTexelPtr(v, u); - - //iterate over channels - for (k = 0; k < m_NumChannels; k++) - { - CP_ITYPE tmpTexelVal; - - tmpTexelVal = *(texelPtrLeft + k); - *(texelPtrLeft + k) = *(texelPtrRight + k); - *(texelPtrRight + k) = tmpTexelVal; - } - } - } - } - - //-------------------------------------------------------------------------------------- - // destructor, free all memory used - //-------------------------------------------------------------------------------------- - CImageSurface::~CImageSurface() - { - SAFE_DELETE_ARRAY(m_ImgData); - } -} // namespace ImageProcessing - - - diff --git a/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.h b/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.h deleted file mode 100644 index abd8cc5b50..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.h +++ /dev/null @@ -1,94 +0,0 @@ -//-------------------------------------------------------------------------------------- -//CImageSurface -// Class for storing, manipulating, and copying image data to and from D3D Surfaces -// -//-------------------------------------------------------------------------------------- -// (C) 2005 ATI Research, Inc., All rights reserved. -//-------------------------------------------------------------------------------------- -// modifications by Crytek GmbH -// modifications by Amazon - -#pragma once - -#include -#include - -#include "VectorMacros.h" - - -#ifndef WCHAR -#define WCHAR wchar_t -#endif //WCHAR - -#ifndef SAFE_DELETE -#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } -#endif - -#ifndef SAFE_DELETE_ARRAY -#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } -#endif - - -//Data types processed by cube map processor -// note that UNORM data types use the full range -// of the unsigned integer to represent the range [0, 1] inclusive -// the float16 datatype is stored as D3Ds S10E5 representation -#define CP_VAL_UNORM8 0 -#define CP_VAL_UNORM8_BGRA 1 -#define CP_VAL_UNORM16 10 -#define CP_VAL_FLOAT16 20 -#define CP_VAL_FLOAT32 30 - - -// Type of data used internally by CSurfaceImage -#define CP_ITYPE float - -namespace ImageProcessing -{ - //2D images used to store cube faces for processing, note that this class is - // meant to facilitate the copying of data to and from D3D surfaces hence the name ImageSurface - class CImageSurface - { - public: - int32 m_Width; //image width - int32 m_Height; //image height - int32 m_NumChannels; //number of channels - CP_ITYPE *m_ImgData; //cubemap image data - - private: - //fatal error - void FatalError(const WCHAR *a_Msg); - - public: - CImageSurface(void); - void Clear(void); - void Init(int32 a_Width, int32 a_Height, int32 a_NumChannels); - - //copy data from external buffer into this CImageSurface - void SetImageData(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr); - - // copy image data from an external buffer and scale and degamma the data - void SetImageDataClampDegammaScale(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr, - float a_MaxClamp, float a_Degamma, float a_Scale); - - //copy data from this CImageSurface into an external buffer - void GetImageData(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr); - - //copy image data from an external buffer and scale and gamma the data - void GetImageDataScaleGamma(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr, - float a_Scale, float a_Gamma); - - //clear one of the channels in the CSurfaceImage to a particular color - void ClearChannelConst(int32 a_ChannelIdx, CP_ITYPE a_ClearColor); - - //various image operations that can be performed on the CImageSurface - void InPlaceVerticalFlip(void); - void InPlaceHorizonalFlip(void); - void InPlaceDiagonalUVFlip(void); - - CP_ITYPE *GetSurfaceTexelPtr(int32 a_U, int32 a_V); - ~CImageSurface(); - }; - -} // namespace ImageProcessing - diff --git a/Gems/ImageProcessing/External/CubeMapGen/ReadMe_CubeGen.doc b/Gems/ImageProcessing/External/CubeMapGen/ReadMe_CubeGen.doc deleted file mode 100644 index 56ad1c16b92cf5b1ee637ee57ec3c20b42031152..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 435200 zcmeF42Vhji_Ww6@lqkK3=n6;;frKh3O7BIQpn@*RCRs_cA)7#urW8@J04h=}pn`&3 zLGf8Zupx?q2&f3CPryb~Q9=HnbLP(O-H=6|&tLmLH~H>ubElj(XU@#MyYc-BI~PBF z)-F$>PkT>s&+o^}dP=#@muA0Dapy#NkEb8|aUA}B{P=M>+m+*PpgZURdV*e{Hz3L1 zpZ|pv_;$%^Px@%Sa@5om2b$={f?bf!_rjg?%@Sz0s5t2@9ZmtyGF7|pnAD(9TbpuIkKDNI0 zSm@*a*nHgQPGx_w*QENR{A~U^AZDvm$@mY_*!*mJth{Z^YB1)N!S9M;)Q>$MYV7em zfu7m>?Ddt@|rBZ!Mh*pD%oD z?lwJ`>|1`??H^sY>Hg}i<=0}bsllmkP3nLBJ68T;o4pvma}c7oNPS69MZTp+`TO&~ zp8|35o$^Qe`}lIY`Ln%ak`i0Qcks%YEMJbdYalbvpBuY=jypoe0olP9v4H2q5PbjU~b+ezO2;5lwekT zd?oL|?j8Df@p`XpUNy zL*DElmB^8LWalZFC_L9Y)|Z>>%gzgsK(pt14#j!%f=UrzN=kmN zFJ+u0g%1#qYWqV@y^Cl^PX5TuK#F05@ZV{7NOMzKNY+v#FLIHcPPrUQnSnItzK{xz z(*$p-Ka`Ri$Pof?0s3T*^X3Jz{94^$eje@0gXD=`A!{HzEts2SN*59%cu+CJpX-N` zS-x@Jk$$1L4+8l!16hG=U#>RIXSnFi_T}Y6f2lY;3FVKx#-W9&>j`D{4SH#mIhSBMvn9PLwUiR9DkaBW2|5jBy=Ksr(de?^7SQYez2ml4bjTuaR<%26o}q(=E6fX0BXBlZ@e%#G(97(IjsufS4M)Bnsw5SVO^V zsebk~`MK0Lm4q2u?T`qLnl&TQRL-A0CXgG<7Itt;sxQlz?pF;Bip4Q@t7zLHqK9e+ zvh%59?g^$OO2kfLFXGD$9G4x;2?auJXR5YlZyU4l{r_<%mpW z=VfA-vb}yEOwnqj`NYPlk(1Iyi$-Spvy9PJV}MBH1|>a)LaUF#ciTfwlOV^J4*OEQ zK6)$6xIYyOEV`DDhze&#QS+%mD3I%;09ABDZEOXV_GJd0&N5srlL?jUVD#4r1>%$K z_vO+KAHAR@Wsc;ZfgwUkFySh6rh8JF`h8j9mSKH`qIm)C#{dO$Q6z1e-wQDu7Rg;= zqNFHjTYzPCkyDHq7E#)PYNYw|ppMhk6N!Zr<3SQG6&WNgbwz44qVrFb`?@nYK%nS|M;kB`i?Cd~8^* zzX`YDQ`qnfp{Pha*4uoCA#&mn7CpnzSZzKIC4 zH;2Q_CL?`v-PFaYr*_79*aP)43KbRMt_YCIxyV4|w5e)H?5;7uB7RgS1Y5_5-NJaN zTzPR011LgvI^scH$I|u6R+CAdw(q0zIr)-_h!-Tu4Q6?>@-y?ql@w9*3&XuVq9sI_ zV*0R1)$-I2Q>%_&1<6E+u_Uf~AoQkFkv`t?LF{v+krdV;GeieTiZS>vB3N48Xr7>d zk$Vg^Xo&TC^_tM$i$~lZm!OuyXcoedpOYZo7&$P%gqb5ljwf?j`Gn$#7~ew;T0*IC;arNTxl(G-8S7z9xpzl;(PNBWuA zaC`^zPRgQit+#8BnM&I2;c*+sO*$ z8j0f|UX~1;I$_G3u@pq72nJN@=HS!eo03XAH>c-I2oK=&ywat>NfvGu9vALoW+0R& z5|~D3g_|PYkGPS3dT}Wd>v`e`v{RuGXj^ZGXk`gkM42p|qDx90YEx9Ue=O3Ko)IQ^ z1SG(;O(sHIMkb%ni{zX8^pbl%7tm7H;Cx@Ly?+v zQE6+-AWEbzoVgB(t@eoCODBxg*Fq$V1XEj6C5O-=0!mbF^g5=MQ_}P3;7;5?1UR}v zMsiN%#fh0Y_TPH?!bZ_A9YRY8gcF^I4pP4Zp$t*7akJn{aI7gtY=ZIjY*l<&kRudz zBl$Qq4x!JTf>~KY#@=`c^mPb_hzg2iavc}U7xIYx5-oHTpWakjZSE8&En)>+K8-C! zgvN~Zxs9Sm`ov#TMo|I806CFS!ay^`(Xt~ZM5y3+)IySMqo}FlvVB>B6fXnkbic{P z2vbsGGjC32J{^oVEk9c=o7zyLTekl6v*F8BO6ujc^61>HYGv%P)2UEn=^Qc6Q8^3G zU9^E(PEJ&-+yI=pP`IldLa!lGLSPNE*2vqRz>T;&pNMY4o(e?23ur=?WZdz zVTV*v>meEpW6aO!Iw-NKHsWKLK$sAg+G`m=)4`=>IxqKYQEA#FjH z@)+-E7eGma5TU4iaJ41kmc~Gjc$oGmorezW-0P~&JqAQsLGdD_2WG%zMz@OZ5M8Q-B#Yp>Evn7S4$dHDEJ`+4N)B+Emo&;-;N^=xP9r`Vc!+&- zvfey6CsoHzNVx{eE@G3EX#zSN$r$QTnu@W6Pt0b%`_l> zY3v##X$=g2y-g%-Fw@^9H#eBuFFy~r3s+mm;_%F^aJZmBFK&ROAgB{EJ%OP+{zW`+ zCs%6web73M1_;}oo4g}~1^Bttx2t;bb4@QU^4z)eK(Dt+r#$P~BFI8xsTts52ic6bB_^fY>i&sGAq9snR=eV*MLKC7x zl4M{g(&P%HIP`$65*U<0a<&8$wR_`^k^U5)!&Iz*Ur3KB9_SZWLDj;0M;9r#la?#$ zX>F#Vvs%tRT)b0tH!FxjyT<3zAVVC2VRV)_$2*Cy`cp>1Hzy~01~sb;D4jtXffke%(J^68GZdrbkusVS%A1Olh3eJl ze7aa+jYLeEbdYFd4g+{`LI^CT_;PfhjpXRaE?V-Db>sX++zQo+#P}w*#kgDX-&H6AGNy%;cbQIYg(4mi5RqN$-F+<(1)-Y559?^q`KuUmy z;kY>ck_IiL9?qao909rt7*9u{!)F`y8S7V7XLyTqC_cOxKq?drj>^wr;AzGhxLE}_ zP&USd&cRa+lpsTcC})%(r-_J}Fw54#jQ=#K;gl~mGTnb0oHXhzK}Zo~>3h|=k+2?0gyc&6PhFvr zCa7 z<79`tBKzW2dqX~E1VSp}5${iF5;e3`VpAOdsItZ-lt#4JG7JjiO$SpXwjwUA4DzHe z9>W$=heYJwt5a*5SgznQO!%ATq>k%*2A z6@9QaPefEEm@tZYWBt-_3XQPJlrIf*s4Dd{u^J(eBl7NiEJM^|OcPxuvc(r3HwLx{ zyY0}MB1C#j1Ems{SPqpOdKl8diB1e)Bz)?~VcxhL=_6z|O2AM?f?WK}J z#laaU3&l}-7#z7|40W!I-=to`eYxn+*GyNLL8BNfNm3L&AbKPG5iU>HG%VPb*aT|?}nh8k}i_Qe#6X@Ks z5!_Be%m7_#^k3iw3hC8;aN)F9N>p7#_eE=<*Sok&{SNu0iw4G8()<%+Vkxgd@CXx{5J6vFa=h3nCFVmZB~4Irc?mQp6bIyXdO! zq_)&_7LE?9#--uFAYsgi!zhi%D`646sCnKKg*_tBLhchuO+)(zb> z7t9oknLacbBQyM~I;I4fR@Cr{MTMWY<9 z`x^KY(-SeQNo|_p)uiWQ@uKO{klDyW%H^U-4DKtNeO{}LgmxIJBM1L7`%i^vZb^Vn zj(KIz&YEG7LisZNqJ2H`a_T~1`a>bVb#|IZ=Gszq7DW3?A5Mgce<^R3>j%Ju+qV4 z0>?>=o>LR835TLhd^#+nnu(Yv#MhU44MSZy5OK+7T24fIJv z<%;Q1#Vu3UOk7cjK?XX(Cavsa*6OINAjPIoRofFvb=()zYD0XdgXk~QAjGzney%L6 z+f%6ePDZY(JFJve(*Ox?;#pZ!U`(HFk{LzN1obwRMmRd$nVPRgRnj@k(AJC8*&O|J z9cY_Kyv!lFY+nOuf{es`xeaw{8c)dtG`)JMyL23RevR=P+a*Itod#tt5*Is)>~KuN zXbk2J1L$2Xbz~ODbS%(UJPwT;r{(&Y`psrNjcerRc3+AhdWSJG3O6*z#v``OOFG6D zidcbksQ9n4BHYV5`8XnP1kkj~Da(5js#3=oMCHoAK~vF67f~bX6j96YtSjTmTydpk z&ch+TnKkmN=`BQmd<51xzy@Wnim3Iwb!3i#GMC&ke*%}8m1cY;6NgSlDKe#|wqK;i ziPt%CVLRfG;Em3vXwl-Tiy_fz$H@56YNgD%i*rw0n)xFf1?G!bAE#z*u!M8G17zZj zVL7oWF@p?kk#}(?TwR2AibOBTKqQbsO{%v+`=pjmcN0Pv)TfelRVb1pOT>#LmM8Nx zGAc7ZKU#+uI@UdD<{H&VOB%FlL2!*P>Mc>_hE6CcB(aneD#fCs*j<}cie(Hg3nFJi z$SQL|GMW+<6DJIUbVySNT)aCdt+b7?2#`L=cy-)tgGQQOWQ3uh>AfHkW?JH~WFG0? zRAGvyFVky5=;TnZkibPNJcMB6nn`jEgW3fm;&tN~7%Rg_i&b$l(;BXc&6^oeBG*hY zTIm@ZAVQinn-fW#)P%|p)O1Rk>_>d(mu+^r$g{DAl^Qd}PJAxDqlX+tup`c@C1mY5_@UX>r zI#F&_WN@Pzp+11rD|#lpP*dsr2p1t-&U9Rd$l5FK;2z#C&ghCYMB#;s_!GUEV)J&S zvZzE`uU8IHKrKm>M2&&CAViCpB&Icq-Uc?XC)JTe&_`5;UYst;dMNe^A!PzlA{=2G zZv9y+71CGWXE~MWr(r(oVk<+}Ya)LbuS9l5VG|34C~_B^5j|34hKl86`oc>Moctlo zKv@OFG|)glBPOAwt%8#?nHavCh^6Bw6BN&p*%+l!C*z%X8_1+u!?uyiiTq-)Y-1W| zGwoztLtH@Yz0UObBJ*)Fb=pb7qLOP{Y$E~G=!z8@&lRd*B%})c-8J-TSUX(1aIM_6 zurot4D90ER`O{?1geCM7gQcB;h^r7_pjfiP1Yj-Z7_7b;OPMeYE4>NhTY6CQa1bs$ zA6Y0%()7^TUpSPQli029S%)~rdhmbN`o7gO>`mglB>$Fi)0o*QK!#0`;|6rq(P zl%@+y%t&P!YGO`W7T+VYSVod~O%BuQiK&5+rXv%2xXEj|7lX1|6Hz#&DOTSYPC4zG z*-cap{LAXq$61uo)t-5v?PR=%0A(G04IwoNnnPr4pE90Z6x1ssS9pTw- z;bypIPS&m#nS0I3sj#eNouaJKW))mj7DEe1YCAXYjPs?6j{dsm+Z~dTr*{02^%p{a*KH1&oyc>h zgziNh`k`grdfU9=P^5n+%ji5?KYEU{00|Km&qc3VI3rj@T1H`su5xY|s-fYmQPew40sg960DZ!hZ z;BB7ZZIR$@X_U5=P8_hNOi832B$=DlMcNG8w`jRe+@9J-^&+OaPH#&DMpq0-@tT9l zj9$Z1S+a5{Y?A66f}MM2VVW!u6N6=ze@XLAI-4ZK+N)ffg=w7QRlp;0%*A14cXrn~ z@$p?*Mxz8JhH93|wDrolXo+>#%`R7!l}~ngjn6x>uCs7RB-<%ghS4k`qHAI5k%qSt|N0sUiAI=-#j&f!&FX%! zO7ta+baf0O3NH~#AL>Xypq3y%dlZwj*1DgJQl00()Cj4%%gTCPXY_}}iW1}hbM5XP z-R>byH}r?Cw*8gZivMf89wKcfTrS?Fb%YArWUCJdmE(t+?!kC+j)}uA+c>>?ZiCQN zYinlrn4=moyWgA>O^nOFm<&Z>qjOVN!k9!lZS75L9Zi>ua)rBZ$Lte5aG62d35jB0 z{+(uEhr~i->0~*H#^cRsQz{=~aWdyk^^AdV=i+1m^{7&(OkWm*jDcFm6RX4u7p4=5 zw1qR^*_|w1ifvk1X|MCY2^qFuKe@i=jbyCMlG`Dhn}zk!YqFhtbh-hs_-) zO{O;@YapFrbl8z~ui$|oe%wvUDwMNEVWJn#CdNmG;Tms&?y|7P@fHk+Y%Pi+pp159 zmWAP`T@MvbPDNmZj2}8==4AL-2j*HnVb%;s#%d%rWX8rxYJHYXR>(VJf7?@8(N%Yw znSgO22IPJd-i38`twxN(=!>Kj5lAx!CP#%zaK>5Uz#+B>9bG`w9Iu%a4`)HA5TH{i z!cL3{_{VAiIwrIZk$4H}Gio@UGHl#lBM=%wHB}H1<(j0&QPQXCGV*oJ-M~@fa6WN! zgXzqu8c`1EIkN=B@%POcXRZv9(S_C0VTs;5GkQ84l@bs_T_-L58ojL4Te~eCt=fk{ z<*XCnAjTk%P(*ru(dn-JhOmfGL(8UCX#qb^I6+~dMVQhoEy$H{HN9f8ouDCo(3{jM zd`LHIGSZqvW#hC6;j+E2)pg;ml7Ki4p&&n#6EemX7nANb{D4WiKS=zSwRd7S81zaP zOYH|};J_;@irRV`3}kV6Uk2_8-T`LazPCS<_R@#=3!=~Um**~IsE@*{sH61_!)|am z9O1;ArJYn=nc$dd9ZoosO}isj$JRk^Fa)I;ekRLAy$Rcy_3wz2tg4b6&7d&sokj9g z@f6h-{%TOoMLs8)l~6*Ik}zVI)Xo$UOmdl>sA```Frkk7tRY#rRWj2moi5YzB$Okw z`UR60UQ};Zi~Q*}+N{Q4+|rSa5X)mIE5xMKI7>+J?IOf?ansNr56-MTRK0X&4&>ob zts@>=c!oLBg0LA8Y8uPt*c-Vb9jj5+qAqFIO6Mj59GT{3J(3*i15VuU#F?dkJFy<{ z+NmbeA``o|my+6q4YlpEAisTHL3&U7d;&F$^b#tn4jG)lw-HP%HiI}F#OR773XGU^ zZ+{=lrXZ-dw?x}zxpR<(&SK~7x&eArZV6^b+GF!mdrNvKfjKnm(vn-YDgX}gM6N?c z$d}l8Hy51>$5>8>1?Ztm6R4dtYv{NEVdEZ&BnSa*=cf*eF4Yt5H1mz>(@0-02_q3Q z!|)Eyqq34z;zdkQqt7z3)F~3UW|n=WGhk4bK^X|3wAU-zZjw2VY*;~YRGOsBdTGg6 zX@X{S`q(;&^P=Li2*kDg%)~mVC7pnDHPnEWKC!HlzhBa{=Q6SR%d0iddYOaqzm zoV2o#&q5vh$T}{0v|L1l>hdoMbxH>V%^X^Uz{tN9Q{y?{O_% z6tU4(nJJX8euQ!)K-$3MevvoHo7hZVvJk)|lRP}DAU=gz;5dkdW%SCOPgp7?R@^Sh zi1fPQ9Bi+v%noO*)pSGwX>qMNX7&tkFE2cYR(PeW8SS62)HuE)+T}baCHH1hSxZ(S zqnRB+h0Jo4uv~Fo7r#2I>ufEfCefs)2n&?AffX$;6m$9#XLQ9C^LVsMf)r~QX3uL& z^EB$F`Up96NUMt1gN)EsabrYwO+hbt1q<3?1%6ZpoNHur7Eh#CllCT4ncgS64k{ zr5wW$5d_l|nJ34XGf|!xKM-#gBj8M0V|>EAVAiak8OC>#2x}igj052lDqs3Ud5te! zx=rb%q{QTwrAsHZD%~=%RrAuNnMIk-Lg1a~UQrYa z(Oa>^N%{>ndX}6~_S*81Bq0o@j(n}Rr>lPT@nX?fI~$6e6&eQ%=lkHE^vI@1#+7!A zj$4rW_kc`ZSQuu`1Jgf$m`TrWq+oH=k=scN2!HPg&8)DvpCspK6f198XbMQDZ3 ztOIny!m`*K9?A0|bS*{~pba+4(7Z57rOmFXb$NS%uJz%$8;7FOxps6OBH^5Q>Y7!* zkQw?h!Zd}7k(9^x#ea~|y!4)dAg?HBAkTnh=QRvxC~*(&bRtC=8f36j$i^ijFP^** ze?sE55iL{>Ij=`i<4%3hSq%vlW*)WfO52PV?f5mK2f`-XG^j$yCh;mL6>nU7aa63) zh!D&49MLs*LT1i0gtj}!Z-UbLMv?GHMO{t`k{9;`;LBKjB?-17GH#ISOVtYdcTE4t zqM@#`29TaP9NiIi(FM1aX!pyEA6pPxCdrL6%?+x|@Y~_%|$n zvsYlP96Hw;I<8=}_@rb638fh6)KzoFaTc+Nu!Wj<|J{bTyDHO7sRtEaaNz0>Q7yG- zN&q{!G)4=_(2-@~Sz!B?0vyj#);A7oo8w2>u0*5@p)!MVTq<4|mg)8Ba;UK4QM5>R zI1B8CWNn5Nk)bbSl0L~B-yo?~VzabH;=c8kL2%RLmMuBau%Qz>WZaFD(lrbt zHKlU8Iy+pH8YUU1$t+~_E6B`n&Z&sH-WZKG`nVtbN@}HhXpTIiS-1rfSBqF#8RD1) zM`DX|LW%OknYCGV<+0S$i3Vs7Xl+HGNF>Y^f!4%%&QX`Hg$LIodH9K!-iiMwS`%qeL`H3J z-Ep^_=lfHFITD-@7CYU(?X{y75i#l*CJE-HP$k1vWEPs9*SvMdU0rc?;^iyk z=8iVGJuP{An@)#nyhEQc!vB%Dwt0n;eTQ9)#hSV<&@8)?cf?6!3~l5=!dz~4CRaFT_bVaH7$kZ?Ua zD^!gi!`{dwSip?dcrbsgJf>)pg*#vIa5PrvPi+_V&OEYr z@-TVoY8Ej9&STof0-jI{;hZ>JvPw%{XDF{^bldW-y8O+$hIaW_v=BKlIkA>_X<|m~ z?1{J&W>pI$5pC#W7T!xhB-gwfLzj#hNwuOJVUCeqWxh(CGmLa55yZHsqlYX8rdazp ztBL>>lr_ZKSICpY=BhHmu`jgKnAQQ^I@14@9nhv*n~rU~WxZw1X`Wu!H`|f1zNkqD z*Hl3EQ&YUM5KTsp<-q_N~A zk2@tJuREizHX}_TbaBE3NzME%>ENWX@&r2TPqdqnCDz$!Rf0FEnV!HVJh>Z(&6B&9b)HTyTu5?rf19X642>g&BsVWyNW_q&5So%_2H+v@Tarf< z?MtZwEJk6x5Ltv~ibi0WV}Htiy#w+7V{$g;i;ca66A% z$U-h8dJq}Q1BE;}$bxX4NpcFdqqRuYBDH7S!q{FHDVF7xnc)n~tt?m4DI8X~NR^GD zx0+F8CF5niAJP{V=XhBL7&(+6o8v|Z%ikC=6a;Zsntk7JdyxecyXbtbH)0OLMHmFS+^a1zeof}I&d0kr(=y%?%W?S zy4_4zcaSUOZsM%m8a4WM5lV6n`z*2!p4VyS&_8Nr@dV6DWz+FR-{!cl|9?=hKaM~! zm64<+KE8L?aIY}HyprmKbsStcNjO})LGL9=^*J(N~q+RNWLBw;H33>5^%o`7RV90rCTU06|hr(g64C(1u zBnoDe3dM^`E&UXBDsRlQI#ef{Z?VzT||T8vqjTWA69P$p@30qvhDWth7$<7{J!EM?fAZ_6-u zTgIKVEyMnNTP}CE<=T_Bw?Ei`e+?6NXIaJfZuL3EewS z7$Q5JCwk2i-a=v(ma6eXCgSAUcL|Q~J~6z?SKcj%?P!XMj_*7%{7OM|BV4Am>!fAU z)`*b(C1tAgoute{BKOyn`3LPRB!GWOnJSqlX=fpE{A+8Gz;HiR9w8 zGSCg%Eiu`0dN{oaJ{0j+rYVU4k;ZfvMLjG<-zDL}CMH*#MTjiuO3X>)FOe~wn|kxE ze#hm3h(&dBk@u$+Q911oV%1Jew(C))1|j0Kg{!6+6snl(o>Q!zrA-v!OuynHoOZBg z(7=#d9^=CaB6@*mC~iH`aDCy34hiv17+MM)!z3`>rzCX|QQ9cHKQ%ITHDR3b9sBg3 z(6fKH3H|$an?RR5p>vOpSg8RM`giSvjq0JxgQ%^99o{E~h?4S-^?646=#;AsQk@vKdO{`i91@qN5q%{bqYwPr<<4- z58_SPZO6-^p$YPaAHL8N{{%=St8VPFA;eY^>aPeyCbz;gQ~op6*;QsbHAnCGzLJ}n zMU$zv3C;|f?wivc%rXyq#W^gxD612$`81IcTjpi*ev-CV;8|XjB*f8U5i>Ids@BwX ztG7Wj??us1`4e$#qO%|>B;g4c@)9dy-uc2z-? zS6%dqGG|D^6B=fHr_HpPzq!iZ5Pjz!jW>((OpcMrlP&~cxG2*ZMXXnIR9l4_Tf?dc ztCLQx^@?4aKrZ2s%n3yl3RXqRb8NUqbyPalmYKMZZH>_*Jr_kFBi7hu8BRuuR0WGX z#usjyDJoKkPRtrnOl~t=#7EbrI(@Ji*1MLPoXAjC* zxMR>!2VE!H5TXg3hG$Hrvuuzk?@^_-{*Xw&DOL=)zFswAaMeDG`54ABh+?$(u8D;#6UtMTpP*6B&rcMMbK9#j#w~B6O+{?5v!hD zL=uVY$m=LavOrc|Oh-_U$5~j$FOQLS>OYv+XbSy`4MN*FO>Rp%AvfVaL{0G%NEsk6 z6QnPeL(D~5p8oPkE@$asoZkx*1{C^H67pruSM)?O6M6cMQ^{Ul;u8G^UdvqR67}t{ ztmTY;;jVKJVoc%gm+Z2t&?J@D>>A-E2<46MBu|C7XOVb7hxI~^2SkiV`xNuO{TT0_ z73*%E5s3=on3px12gB(7O?{o`DDZ@Ed(BhP8ijFQ6D#pJU6Er$0vcrES5nlGp~CXo zT?yxCFo&4Gs+Ycom!OSAd7AN}U^YwvXn}BCe(Xoy;y{_uEm2Z6Nzzmupno>M6e2&Q zV5%2RY~PnA+QNITWI|TgvtylbUgQyEnPY~htf?}dog~ti9ZN0rBg_p?RU|f~;3m8d zhuRGiWAA#y2V!F0Wa_+UL)K}9>%==d^xbXP4IxSvZEi4EbSJ8WhhEPgGo znYX`r^LUTQV+-;MvL3E5BEG1b@uHRyCr$Hk-ajtUZY8uBi#|Hpm`LBKro?t$CaF9@ zEN?TViuw~jChlwN6}|=od&;}FC9r2N>a3+5Zh@7Pa^Bjj)fPLI31aJfIHlsi~SSxhr8muq(R+q!)HiNjy960&l`uE zz)T*mrbSfcvYBvp*(v>H7Fm)nbMpz|n{@h2)~Kt;ply%bWM?v*<@;C+^KKf^8J9j2 zzrh>f*)C?|$|8BenY0d!dexJ7l!d@wRu!jCh2(=jMow+)~~ON zFm(vY>r{9>0Q?QA(Mn-@j#rygjefo4eOU4~X?|>m*ImiENCTwC&LlXz=n#2-l8b#x z0n>UBa(RJGioDoZbx)Y#9tW8QVJBqv(#&v2N{f(dkWBSx26iog47O8wai$}09kmP{ zy2#wzohm8z9w+{6)Lg40enI$c`t%wY`q&NCUlP!v4jKB!@Deb!9lpG_@s+&YhxP9= zpm&eHy}Y$E^73-pHf=g~?AS!!dY_mdN=fvm<~Ox3y>9AMwP|f{T;)?uTLqKQkE-Re zph({2j{!8xXhouRD4IJ?&47E&k2J-RdRYt_`DIACaBU#RA*8-6RhksBT?t-Uv8b9# zzd`3mL_^*T!Q1qC8Y7%1-7cL3_Gj?GPAs*PXSe$EAPztCpt{!$!_1US(d3c!K-r-v z3hBKeH(g>Uf*|s`^elNJ8bYmhLufI;PfRo*ma6Dtg)7pr*c%g5{Y^9SvND@GYsErW z+14e>>Dt~agHas)m+p15_g}cNN__G7_!9BXccuOvy7B9!A_2~B<(5_A!@nfjtToS% z{>#548qd!Wu^^+MO?-S(tAeCf@$t=*3z{cWM*M&AZ^-gf<#C`GCh39#4f4yx zc}khHa!*tm&JRhyoEBBh=+^H|-FhnUYxW%9*Jw2@s*;fwm_eQoUOkSI8&Glse(T=c z6+RB9lDtkl+qdJ4$XV_!e7v@Fm#FJI$JdTJmKwQpZPB|XHJUlFK@n%8YEaA6yJeZ{ zJN5K>`t>a4xfF~5K8_O%EvjTxJ8z`Z!a^w_qD@>~eyU!0FMPKAb@MjNL$2=w-+*ty zci;!G9~=M&!69%M{0M#mKZ7IS7uk1<@hKks;Jzp7;5+w~J??{@?t`dgQ3s#6ll`AL zh*X+i*G^B}+37QnhhN_=UN_EHH!eL@l*yx4M4>$L3-qq5D)_ErRfrm@pYX@>_ILI@ zW%&p7!I%89_v>ePJZr%^umQXez5?HaAHaTa6qGvCq`6lJSs z2nmqxGpl5LTJcq+-8n|jZ|}F0T2#q+sOGlF`A$90Mn}%}l&g|4bLhj)d9eygN>YDt z=0_){t`N@G-p?7a9I96)M{kvkD#P#P-c`dZp}%ztsbyWYIlVn%?M#Y_RHUNEb5`WI zU(XUKatRc*re8-egI4V(w>YJ>COS#3}U+y#V}zG~zv zOtPOpbMQ}lvur;+wSzV8WPhg6|E_yn^+aEa*DZd=w2j5i1jE4y;Hz6aJyn*-$CQ*^pGn@thvun{T@5$jP^^z8$%&EeT~@aiaGG1v+Yfy1C&EsrN2oC&&v9^i72 z56Ya227`;hAaD>I0&!mK3P=XcK?^{~=Q;Z0(fvpF@7aHJ=TW}49^JfEw(Hlt@{cvI ztaB7Ta}!t$1~&i=^e6-zT;@9i>46$mOR6HZmbDs`t_Jy z=$>`M$7}uiUQ?g?#jt$TKg!}oY$P`CiZTnFJFU%27Cjva+QVPr`&&TxeE?nyzjNWG z@Y?dXAN&;F3SYCpT<|WiJYEP-h0o7}!n_tf3x9tldHD0c`QXQJE!p|E5B9rri#mv% zbyTubJcy#G@ds28RqIvYBKm)}@M9RTIyZ*>x4|!<%{k~e*ani&yTM=%*azIYSj_A3 z^a8hnC15F74c35`wLP9zAhC|e(-cHiF6tmQ5&q||9P+q6|8{kva*KWNy{k;mDIU0Q zaeTq91us9aYg7U6$Qv75rXq2Lx^`S&pUuL0p%jeB8F&h81RsE{;7f1} z#MQ%=fy$sBs1F)|1Td+-$1@pR2d07a1|Cla$OfYuVrRg$ULBW#s4KA#zI11O ziU+ZCb7fXSMufLbdfL%?6=yxCVx@a3z%nY-BNeZ+M4yCb|46{c2Ooi*;1l@wBPb6K zYk)?e1vmoY;bjHT4fF$3ft$|@Ilc$n3wkx9USMSsJ^}a+#3yqwEsOXXU3$?z(x( zq-)1q>!Ogze%Im19ouKh?bB`hOt$Fs`i_sGt8#?S5cm0_SB7(()xBJa5b&H^CBsB$ zrgy!}tywlf__~zg(mZ<|PfTJ?T%mmJkU29gXR~wW(ms!9jaK)29EyjpSRJ>yaBulg zJ59Nu@pj!#@xQIxcQe=PR`QfK`p@gHZTq6#9@-+JVaiq^;rd6TQalNwmzGy<9$5P4 zL+>ZSQ=m)>EE(tux`BJZylBgYW+*suN|OqFO4oF_xep#n~HmNf&2N1lL?u5fMvJQ}juA`~#z<_P<7$V*pX zWoQ8VSAg+g2ABor1CgsG;A!v-_zAQ@zVHc-e7on%o&0@zbnC{g@4mJ5@M~Z0d1=q8 z!_PkX=#$Src=)BmtL~dS=eC<~xb42Vx7|#q9R8pSw+Xq}elhfY-HN8`F?K+gf?o?5nK@sc%5=HEH%mRYylI4vv!LbrM&J1G5LOI)ej&5aJ|_9aig zdT_Eeyq3MH8O||x?!IuYrVO>Xl!ylXMD6xmmv71U+WN!i5t%2`CVg+E>MT{3gAKKR!JOB=WgJ9;x+y@FS zAr1sS16`qOH;~ZrWcEMGj{T1uK&Hqiss@K5=l|*^M0Frh2T?UR#RGRe9b5n90L+Q@ z3Dq0j9kp z&*khpO=s%1UE*=w9*Z;mgOU(yFE+yDVYE{6WRH9#2h%S|KKD(WuJ@-lUaDIqJmZ8ZKfz|Kf?2iD8f#~{vVD+_B*#q}I zaNh#@_L(s6M{SF2}mc z8N)}D!qT_eh$VWz-a&q=hu~DPl~j@Z^oaaqYvkg-IycK6ym)`)`IK0D(8o^x=6HC| zUo{`QwdKiGkq?tfzD<74{gkYdL`#e`t6Xx{%A1wnKaf{XW1;D%;4`ord(>9J^<+b-mmt4_1Rb3zWRv2y&K+I``U)Jt5&R)zb7Ak@cu{d zzWwI=r`&$?r28KnOOwn8dM!Kq8TcUI!oNpD^_9*`vM%PV92q)0dvHMZ!dEypDdm1r zl0)@UHC;K#kvT8vr03ppT50D@mxM~1Qnpnykh6yxa091 zk1yM?E!`hh?RX)j9@_D9_0vRq&{StHtn-m$ zqw~%&Imn*qm&qZb^J)vYKK$%us)x5^w$yaShTJ}UgrnCcKj)bAvM078l0x>}$EKvE zY1xjZTl+P(;YwFcB$crQvL}{cRjHA>l{@8FtdW%D*e_2LtLF=$={?{8I0_QG!$b7m z>i>B5MgQx8`k(B@G>11|49jV4 zUcYy>wX%gSa7^~hd5*D!5+<#x-$E4`0UG*g_>>$zskGYUbj4G;{m}EgZmmDjwbKhq zf8jj-1TzMv9CIA$C3I{_`R0729OYy9yj(Tq%bxfZW)4EWMcyJuruN(0e@CgR%+$5_ zC8kf)V^YuXRCBJ9n%2pA_kAM8^@Ya8vEP-!49Awg!gekA1{?(Ku;XIi#kNlcV%t6a znDPa+KvU2GTm>>gKDZuC0aL+k;2v-pAky^3=7{r2N@+q3z-y6swjv2J?=X*E=oEmVZQ zvKKxkhkMG`*OZTzM(a7AQQ<4yE<7J=!ST+skVft^GT19;j^sm*&K@abPg2HLdr!A7 zm3%uA1#9i_OjSl-yFi1bt>v zD6^%Rr`Vmxca~46?J3o}!U+v7;@oL@%%j9r;znYplIN*zEB{2|Dy`zG{Zt%_yQPfW zC#V_OJv*{nE3(^SODRuWNp8}e(~4($e3C`ZmdZ8@woYcm`0{p~Jq*WU|IL5L{tM5SgD1d>{}}$C z-}7(%H~KF;UkP3Sul~pI|LMQ^@94kq{57x^yz?K!|BHJ4t^Y> z&3{M#h36lGPr>g082%6L{kQ%b{TH5p0rr6J|6};S>u>%$`Y$~H0qh4hUTfp85?5UT zR)V&Jhy#P-g9(v=s5s#mjVw7||04&ZW7fc#@#@u@iFOIYY5Xs%&)@p5`X4WG^8&CC z+z%cE&jQQ$*VtbTwt(NjnFCob2-<>n;1}>4_#Ko+KI(xBfR&d%?DqxzKz}e030 z#vP10mb-}EbKmg_*J(svo-3)Ek=*7=og=tCv8h~V{wC>)L!6hZQp)-opXdyLY|W9$ zW%RY_dVN;++jOh>klx-WxyWpgDMgQ%H;|bM?x)tWS2g3p(w&`Jh0a@{>CFso%<3u=@Gs z&o94c^}N-0&f;(K_)zvW{IGDg)qE&2vHU!T0$=Cdt(=gpp^=#lbB---d1|{({1ecw zdZ{TqwOyHqtV{BcbxEGVF3A(tm6c8^8{9Ev;Lm#ebU)^-_PkLI;h zb36|1Q23tK?m5h3@k&tRDkTV;2-!dFEc zE|K;(0g1rs>~-wl4Ay}+KqYjzIS^fL2`&UaFayj2v%y^O1b7lW3s!(vz#6atYyvyM zKfxhz82kv%xC%K21zycm)(2Uy~}3JeD3LKkKgMFf8f(~%?q%;@-6fH zV{5%7c2fG;)@L|%Oknx_gq$0RzJikQxC^i{FoON7z+&(q_y<@GJ_bd}$B&#p z0*WIKr-O2!K1cvfKtC`6SUED!bsgFD>DJBfZeF+f-Pc~?A)c3bis!CdZ<>D7_54k| zY1~cuZra7zM?>cK_)Rt7nxvMx{r2K4-CitDJaFBv*in+9t>zs;a)kEsq_+^YYKC)c zpUmXG8vV`v`XmmP6abOF6UA20-528Mw=Fb-S`t^+^p`eE0mAJ#p;?)hau zEWCB{t)o-;8$7yOiWn5}s#E$sU9>08wHNC=81q{H3unc=R<7xUnAhZqiXuIK%9C|^ zv94|D@pa5=y(h;mugOq(ms}Ae4az&c!qJ%5ZYwAm^P0$Ik$Ez{F)|w~MNP5G)!~cq zF&PX6mTwE$zX!Yuilw2m;Czq)0$?V154;Z!fEJ8mTY}5L0aB3Os zaVI;)gU?Uxp1(HPmQyR#ol5qjZT%(PsuwzQMTMG$&WMmk-zDm0#sDG`p6a5Lmd~#^ zyndhUCh!gT7W@EsbD1X&h#dSYG9di-WN%hI>FsJ~JE$=hf7yeHNA_HaN{Xp;#I0Sy!vEkLHH|$XCcyP}3 znU_B}r+53_?a>!$Xe@n^CKq|FcGV1Na#7d9dV1;_jfP2Xv2{P9VX;aTt8lVwG3^fb z#k5yp&5wC^IK>}ZkB761_DHIWo(=+o!9?&P5S|?d)id!2z(Q~jcpFsAVoVO|f#F~T zxC-Qg`@sF+8Sp*$0TjzdutAh9h<)&#TPvatqVCxfGg<6=zHr|Ybr6;H|H#1(cimzi zxKqh~iRh7D%W{33a~aL571H(?7Nv&ebv1Y^{2mA_zu$EDeSQ}GHMkPEc`kfy1BQUh zz>VN0@FaK&>;ZehnL*z70IGtPpcOc{YtycEn^r8Hck?`Oa9qaa;lJLP9?_@+?Vm4F z$K_fqe^zw$7?}Tsrfbgv!=nt*~_ksJtH=rVM&Pt#O@PUzF9C#VL0;&5*#R>{pk9B(ZqyK6Yz_JX;j!iK6YL9*%frVC!1B5_`w77Eynub- z`HSEs;O09zzHY_RyQYnqma%kN#xykk@=d+lNh88qDwQr$s*%}~U6Xg4#JW$KAM4us z?(K`dMvde?^A?pN?=F<0QlYuRN@}xW=~<-3!jdBMr^P3`_HS4`a*kz7tBQUGz%}4a z@D_L*yaV=uZ$On?#%`byXbjqc3&CYzC|Cp@0IR^eU<23+{t3PYd%!-h9~=e8z`-y1 z+p=y8ks$fzZ`s0ImrWkMEM@RIi3FYap%p`FEr?0GuZx`@^IEN1vEwR@dgsQxujQoJ zdG0&!<(T)G-!mvW#`ALJ$wl86)`^&$h5{$MwlU$7qI2fHSaMlQZ1X6P32p(F_riDK z@kKy*yck#>3qSV);bWT+{vWs+gurs}D0l_@1bznP^SB>80GG0|7KpzO2)LaZ zK}Z$0_C@p@XA2L@z@ti_3OE}y2dzMBApC6)E(U$U05Adw&vSwBJP$kqmI2HEm)RE? zI1Ikovih-aRxiAD;pBy*7hbt=a$h!+7hbYZT7YaeZP+ZP+&)xqPSMvG-^n{qV{1fs zBuEJ->n%>EQBp#Yw)&5CmHKrZ{Tub0({yN&d4%g1P8q8vC#HOT*dwQy=li4cPnxp2 z@aIQhb+r}xIRQ)s_k%@1^!8~Wy1NPN0eiuI@H;pT;+TTD3Z#K_Fbm8EbHE)ye1YdN z@ssfaCXe1U`QWA$_6GFr5*B0LbQ>41Z!&Sstdz{@?eZ4ns7QXmW1)7eYvUTf81vfY z!8$RoeR6TxnAb)$c_rqxOD3#{dF`?RXU4pCOL_SU?0FR@ErIM)Emnj9%ujtgCSr(v*-)JOV=_U0I?n6fBVXh zVG&|yf6RlZWT$xWjXSs42eEVer#pk#$)c`&7V{qWg+k-|+UMNiSbBYhpxXRf>kuc= zz3tVTIeU@WU@J0_05{K@!|(2(H|Pucf&O41 zu<{UOe=?W`z5?HZ!=O7day7UG+zsXdD?5wWUk<(od%$_)s1FziJ_q~2VQ>UYK*kn= z7r{^8?PAfO{C&XRXB*bO_{=i??%go|uG#$EI$Qqc-*Bt@Pe{uQtdNnnbO|w;NwwR_ z!!Fn3o2swZ?FAiL>u<{l3Bzx3v{nl{*5^WfkBIAx^QK4FnXJk?W%kx}=94kH&cvRf zeET-YTl)6Wa+RT+7dt8SQ?`cZrR69($3dmj3!N#H#?wORWp#85`yYe&@vO@MXM)zC z4Y&Zb16Kn19f~0M5&Q&-O<+wJI3Lsl^+9*g1M~#Fz-3?*$OKv7JMcZIJCXZ9J@Ctq z2loEBWA8_MKiIJPrIi~V->`JU!pG;ZS-D~5_`vvK<5voo&SAY|=_a0L{8pH;mF}Ov zsw}@kqt`n&Dpu6x9D+;7?QdiinKJzASd~2{v8Q~Mj2&4!;j}H+Q>9p$>x*CWQeS?7 ztW2Ca&uz%h&!Y!8=_0>LCU=>u!cUW0=KbY7{1X1vmiL7^$1eWM8R7H2>0jbSTj`Ws zr1efMeqk-U)PS#IC`A;gzV+QdGz{ zs?expZhFXmnTnn>re(wp2hK11oLc7zIb{Y$M&l@#c`kZ z3EC6X5MI^?!plZLc-aI9FPj13Wpi)=XbaqYZO?IM&;@h_-GJ~q2aEJ4;F#N-~sUSA@jHQi@jfb{t4e3_kOYNg-1R)H0L(+cW6doD*T1V=!Q#2 z(H#9DwMJERC5SmfV=pLkeaA*+`t>ZuQt?ve_qa-7D~=y$JrCZP{KV2pe$@+okEBq0 zZGH-jx6Vh-cjC9f^cTLWRL!_4e=z!9$&(fN;X`VsY-OuI=yaOdN-9q!`&)=|Ma~!- zP%jC~7q$&@#CcC0;n$zx)Aw$wM@3Vk4tB;&_SasCDm3cAU4j1(_sg*?r*2$$384NC zp#Al~3UuQHer1_>ID!4qFvniRxAdIWEG}tQMqJw*k(YCy+St_l)Xs~}d#X(7+Mv#? zMJ4Nk^Pj@ud1_;^>Y&`Ljl~vqt+l_{hlGaezBKA}&&YMt%anO}%V+0Ya{Tz#<2ya& zdv@*7)f0!QiQ~_6{1Z zcRC3MmG@9$2`W>Hnw2eCrg&Vj;+_&EE0n5uUQ+1}mzJqi+c&y$^7XS9m#x$B>DBwI z4ESJI-R2{!w#Ys0{7wU>%z0qVfog5WKC`lZ%g+9SsShq$@!Ut`dN#zN*l?Nb(58}c z6wTF+6+CgpX=ce1rOKA%g3yx76-rWMsScM)iL*;5U%$9A1%9x<&VZ4*a~^nR&8{kS zn@>3~aCeK8507v6lq2_I6^d8zTzGNo3^YVrPNnzJr}VgB?V+LfBpZ_x|=@2T*~j?*Sit@TvFtaq1m zyRrG!i>I#GyL9}z9-Eg|nfY|*r|Yk&);QszcedV|J^z_5Z_XH>|N7Lc4qp4)MZ3l< zNo#Y*WpA84XnBcN%ih>G__CbON+#A@*K_26&MWr!ylv05zRy~`^799yuL>NkIlbb? zgU391_JcKEUD)-wC;79S_tTCJyJ_3!-M(Eg?ycP8o(3Eh96T(|VI<(J-8 z%Xi5`kDYTcbH&1;*?oViIjhd+51-!tz1vFdfA7*|2~}Rdvh|D_WovA@h$1*w^p{e;9&ifs*}$+HvOf*!n-=nd-CRaxieZkIcdc7X-f|@?|z`> zus7?S-(&w*?e}b+{nWb?x31rxwJh!R+z;cQ*?KhLsk8dMb$ZvqIny2~SW;zQ`RqFV zm;bbD?Z9(4&h2`!pXv<>uFGn%=+bVsU`N)O4uA2UK_E`_~d1~S5#qJt3x5q0f;}4w`2z~cT z%Cw2wE?5%3^4(rzUcGNe&WFo#-cDH3$Xn26TJo zm8!S=^Vg=2etA*bRZmvibgpmH!DTNV&07BOTUVF5>A2_Up4*bn-TL}XsRQ;sG9mNs z`8f@4SaQwLi>{ng@`m~MXHQ&{-C^6~rAJJ9ukn?w{eItojM`tXsgVEc9S6Rt&~nuD z+|%Ey($HUVOpWV)+|*}xe(RN!>ea0_cyitJ-v$Ma&ENla)n6O@UjO!|*RP$_?6=0_ z`|NsS%dsj$&#m#?ox_t4FF3T~?H^|iI4!qt^7_d)&i;8}-5uLUJhuDycP@IUS@TDO z6>?I}d2a5;D|4^8z4M3$4?j11{9V1@9{cXhD;E4Czrqit9$!)ph=6@KipLA(K_$;Znbnopi|C6v&yvZ+U(6$3HjT;DY<*^;O@I$ zsxl*~?!9--9r9wwxsR@YsNwmIE~wRU#!Zd9KbHES+p3vAT{9-QZc6@^BcaAOq%ZCN z)aIWm-ZTI89cz|+_2R8PTRh!(^qs>R2f9~lU-OQMYi4eLu13r0{&w?!d*aOBa(}<} z@d3|nORH05L#eW=`qK{&Jl?X> z`f-|oIiKM?kNX~KV3i2zSjI1*PPw%zO@xAel_{f+%v|tx%KV=Gd~O5 zoxRChvtsjS?(nV1&O7^x*SFp}{i1=L{?YCq6JFd>dS}l~qmB%`vDtU&OGgKX{5<2} zr?=mD+9MrmHqQ;sIrD|a7d38vev1#@`F6!8r_G)CO#F=lD#x8Qb=6mAeeiU#GOM-RxAs}zVrypm8K*aBJn!;iFD@NkC!yQ&T)bEx)bjvH&gAO0}e7otiwx2xFc52@xk6&mAx0Axj(IIm$@~sD7XHZ4~x~zYUuHv&NH4R#{F>1v44CxpxVa$k9NBE z`D=DPe60G|L-{klo%Q03)5o7P_v-EM)f+S9hixssIqpfH`tTk3#}>V`Z%p^!&iF0y zr*Xg6ykeQ}?I)5BoH1z07q=Xl(P;ChFFm-d(FMy6FDm!g$|sT^n{iIxOMiZ&UDK)U zE*!WwGpT8>#cyv~GQWGTK0SNZ8(yZCr+C)x!vk~t74NAucX;9>@mmtkTyyq!$?MC$ zv%Y(v-LSG{Z@=J+v;DWE3|w&YFQ3(UzjdWOrCuxWl%Dc^L0ZY_zGgRHTjq+IrR&YS z_E7z`pWb)PvjbMuojYgBa}}@iw7&e3i-%6$bmX#LbKe>9{f1Xht6A!Urf=@@eBb`U zFRqxF-|5)yCl;Q4_1KPS@9f-O_mLX@H8<|_l&Uhj_pG$NogZ!Z{DsdqTb@_1*^@hx zYW*;-?VS6suC{XSyg7H)?A820X7!_2KD4MuyrELxt_dNmTsJR z-?GggFMGb;!iRc2)4Klm>t1cz^r3DmFF5UrZ8LAF+u+k%=9V~T>DeC*yE`stS?P`w z>P#9^?bvq}zUsQDYkq?Y8%ylnIO(`2Ej513&ZS>ADc*m(X*U`RnHof4fAn32mnq+|p=k@-L6Ad+oEHTaSCLnl^OCqk$f+-&xf1yh|#c zS2a7kV`ljk)9%<%|M1KAXjpJet{m<)UTn&dj@YM)$8vSNZ+j5tTlAck}lZ(q5R7o?LPB%0`QpEx%&sJBv=+ zKJScKvv=)(?$Qab?0+F?Pv2!X)EqLZMXQyMKiTi||3}$dH^upc@18@DAi*tIaCZoU zyAM9t-~j@`1|Nc3aDopK9Kzu44#62D1b3Ied;vtEtDD&-a~<$h3r zVu`V@M&ycXz>eS>#J*|W_^V{axVX3ke(JGP;yYK@>uAT^YRiGP;5xsy^}pgUH}wr`J8wiY%j8G15gZw{cxo2?e=ovtO3})6 zjIGPT2GfRp9Bf7Smise7f23Y(w}qS0=)W1ttrr-MS1|bxpd9tn%8RHa*i zZ{VugvKt2>Dc>4M#ZMu11h_0YUTe18LlBR-n0aqehSP0#`HDb1-Z%`iN0_ap+rIsp7F+Rj1tL4FWC@S|6Y?clZBv-3|K;x`q zygM+q-bgH1O+)fvUp9Px|GG=bzjwj_J!L*B@l=ZXN?l`Kuw{?2gRz_(o= z_UGBu#LC}vrumR99m*H*%7{z%w|8LXoRq4tj!AqQ{MGSfm8Qtf7>C<1wefr*g2<^G zV+%oyt;@v3R5o2N;4bhxEhRD4hO3SzVwxz7nGQho??93Ns;}=CdqHJ1mYf_IJ(v>Z z9p_Gh-NOQf0lE4K{8Vye*{_O5>sY)ZA+h$CZ$-F>IQACEd@{AI1o)Glvh~5!MJXX} zvW!PAg6aMGwFtLwhTgHcu0k*oQdHa4x|hb8CN zQN=af&KEXQRIx`|_x$2o1-$QllDhLMl}Nww$t6faEuj*B3N^&rnA9lfWk}mBf;7(F zll3HCMRk`(E`#CW6;s*0*U{5$tmodE`75cz7W9P7w&qJ`DdVfL_6s|WrhUhaW_sh( zB>Iwi-#$Eqi28hS>~|YiOj00)#~x<&<2m#*9Jd|^2p_*N@Rkek)Hw!71|~s?A)D{D zi`?v5HQl0J8q#ls69x^Zx~MN%o79zS`6OJ;rUZmYQ(0U^K$SFDg(Ee+#4YaVGlqCoYtP@a zIxV!6+=qKzauNf=ONkVtF$Nx=`YS&sk*wqn7ui3OWcRK4Kpg%4YX8hFp;weCpgS(! z=y{=k7I@Yy5ztGGH`s7{evo&zm)WQEyrhxhm!inV)XAN+R3gQe!*gUbQw&~zOA4Z- z#*tgWM#~BXMi)aHD+y=Ra2agWJSz!`LJ+;n3ww|L+w0iL7zmkUK7HdsQ|Z)F zweFeZs&T$65VieK-&DR2A+^n^_?Ux&tbybkjhSR;f%r6rehUk&BEAZUxiJjqxt82zZ))h*7dP}ke38=p#Kvo? zP%*-~=T1^G-r%i=0b1p%uOjXe!?Bt>*RX9=^36{DV8;{@7Ygn2x4tdx+g?if^NQRQ z@Ze)Lw1RnLVr{w!II*%A35*!uFps&Tqb3#joU!!cX_Xtbx7&=tB&4VzL=&@#7;3y?ChB8e zP-h(WH)TVK-Pir5ZnE(l&}D%C-o>S{jdVE&kg?ptgC;~6z5@Y3F95X94J{+G&2Wpg;-+4 z5N6=|v>B1pu>Poak2<#WToq$gXC(QJ)}qUa#E-?-IF^%KUZV(J(o3=`w#;zhP>u}w zMK$ctgH3!BX1Jkchr3KhPLYzS=(qXJPl=J=XA^AAk#Gl8lFY0{uWu?2*?r6xceKSL zEv%~jPE6heV{9n3d+`W{ktMM;<)}-SW+!1RBH55e&|R`%p8Jk}zQfkDA?{%Y&tSjQ z=+SWoveRduh0s6l{`6Vl_r_YCqHR zHP|*}B=J`|n$6*o;0&kSyN?Buebiiy=<9Ch1|lw4BU1R^&`oihk9R&L2DQMl;Pf4G5pRP19{Qg^|n5XPL!fT-xFy>k2FS^ zKW9_D?r#kYY4v*ByEt5tAS`mtT9ZfyK)Ir7k^Rkh^S$74cq<^Oqm=e8EbxB9_;KbE z$RadopLqbg0L#qUUw`FbUqm@#Jao2QaVc`B8vC~^S7O}>4a05_VK;x1DiJ9G0qXwj z{-ZOAaW)+zGR4Y7BPD>YZnx?ZEHT>XuMUQ~7hiEa+-|6P5%tXQQhdQ_KJK;QDJ6!& z&p=wX0RxQXzuHD1C)0Uw(>t%5gk;~mY%5NQ#;4)I(baXdXKM>*k}_<~;+-P?qY1x$ z-+hp!t#HQSUps~PTes7Xv_a|H7c96a-<*kmanA<_IEm!Yf6IopPF zl8F8yD?b(6L(`OknUOW0MI^Wiw+;4ZdmH1VtRx{b_!w-3JoYnzPK+zerI938;H=WL z9oyw`f|o0k%FKF#M4}zt^TQ9Tq9oeZxi{^1%ZiL{c3C zOBQM5W|7-nr33Y=zgzp^>4usx5Y8%=t-?Nm@PQi$accuOr6uF-Ct&vw{qm#ik@n8 zXqj(vRHkl(F<2G0i9a@Gv8;h(W_KJ^W$+-u&~rt{?N2!N-kIs(qB;BNnR*zO^2bli zEPK;`DtCD4HQL8Y>B8yl!O373SFMa#S8P)d=%syP75QwIrK|UCIK=0O)xIe#Th*CMoHn|v82W_B23 zr=0E%v`5ZW>utl^D9hF_J!|jnv=&gGBl*W2=T~v!MC43aK3Toz`VZi=Q%b9yhd(FL zhFTnotd>P1{6#ML|9XrMZ__N%<0Qqx)?kryFVipA6w)l#WuLCdE!DH7H8!@1p!ip8 z4wDrXu*q#%-sy8u(zs&1X1k->KX+KMR&7>UTT5pfOt~j`$ZnaH?2`I1WTcGWJ zgn^t=dHPmZt2+Bn9hd2=DpJB-jZ{ivwhK;yW^RpPr})uNT^JoXKoOxn`#;wD))d>e)Ve9y=Vf5td_)^YLVMwt`q^YGmL=Kd zi2L6p*$7_TQTl?lMoQ-e0Lvzx4)wTIrF4jW4$@%i+u0SoDEJ@|6>hkyI(TrDf=7=J z7s^s7FvdUf-6w?KO@Y8Ucv4AodEMvybCox@eWw z%q#4GRaN|NU7E~+GorE4Dcw*+sIDdVva+nMxD(?G zC;R$os4c5UDuBMdt?Q4$bwU!KPa^apaz(Y!Rc$-_FjE39DLTB-v=KDh|3Q5v<6VT* zz~b>O0i`tBwatv@&RtT~%?){+XcNMYWq*EQlBlcrndQ(IBAJgnxRAeRv;Z-|2GcUn>!>s>g-p*m+a zz(qC|X8x}+K@em`U%t}}`Z1M<-A3>kgUf)mq)c*Or$)Z22FV%EYN=7C$Sy^s*dCv! z(hwm)sxZ{|L*X`kHXW2$n98cHbg2CjHHWY!w^_w)Jp@fVRb*K}13Uk^eK*QLYgg?$ zlbDq*jcWF}rT99cgRQl#+VrGY=_Yi7^20z(Zo#a4UAwN{5KbQ8I$o^zEr?svKwtV{ZCpE%{# zOo=ZgZpG}e)n{K-5_NDEFD%owiCvM~*e-?&)kS_xh19T3I>EY5l!xyd1sGiGT|rpj z6+u}U0>v9NyxPi@5c>_?7Trd^kE|ZcyIE(Vc^k)g(MDN`yxm`P+^$}Zahg&lV7EBT zR+-VwdY#{e;vI22w^Q%ZPA(%_5Bl5hFbBYKsK8$tMfw3rg2aoyK8+PiC5UQSJfL2_ zoL=r_3k_76F&5)Npr}UPotgrANq)U+*=F<|VWYrAP%u;dizmL?L3Bw1kK0d$F75{v zlRmiL2({o_!MH2km%7)<7rzFaP@+YQ;x1Y7>pUymGa_+jHKYRGlxeC-VS|qa->|EK z;4`NpGZSU1s%$Vc1XCh~&TryVy_0@k<34V;>o=-NQLbuGT{k~2=0T1!CD=)nHxOPS znCvpnY-0{!Ue5r}%5#StoJp$ozdiAn4I4IHW1?AzPXJhKetw6s628yF(!1NsZ}^MG zT5|tgmAJ)#lfU9)Atqg1xa0rng2jIcNbicS2M$twH*!VPPVD9TmAa) z(buLoQQKEV$Rk$1lzw2 zjFtO7y4fin@mpYg#$Jz|orRE_lWnzw9n+@R7|Mib3`4L3m>`%cpQF5k!ZN^lawQVW z#e2+tmD@jtHw5xMCAJM^|l^&O{MmzZpWZT&!)1GEzK4CW#&doyC=)V#vJ ztM}SpPbZ%jE!llQKFWJ6ir;`qP))a3XSk!8l9RbN8K&P%6G*s2A2LB&R*t)NE^+I& zVeVyK2eW2HxrpVn`!$7|E_b|Ynp-tqrIuwpztui!5e~@d39wd@CqfJspOJDM7m&q# zQmN6~hv%V&9=JPcWvjpSb$0@kBzF#HkY7c=#>aIw2n(U>nkz0b42=>E?r!OBiChDg zBK9ubYv<=eKNi=6~B2KI^39W8IBo9J!b1;f9RE<_G@%DL7!3 z(CAd~w_-t*4cf5$Nq_{6klLuUJscCRMdsSy&BmqtHTN-g`~aN4s2{(a+DK~_>*o$< zGlA&Z&*4ry`t;idW-n@*s(3BIyX&MbO~XE; za9}@M;`41`{gH<8MkA=y9~QwkKorAdD|}674oosiGl=$l=Qog~Iuf453G%_Jj=5f! zdZ`(Iu`JBYVws1r=7~&x+oh2&U4SZXKGE+J$HCn-;S-MM$}0`Z9qa3n-q2#ZEJs)W zGj;q4BRccmbEu`XJkuiDxdWihLN`T<6i~3|ZKu`cS^>}X>x0h@MY_Z{N6hXN59d7M zf7OVHy3ubUeaGIU?V*oS^=Q7?k5``9SPEHRG10-NSl|utY~j%!E3J_eqiI)!domgS z&{Y%JFFYEry@b5tZGAZ>xb@Of{Ec@n^*I_@j501&_tqc-)YnTUmYZZr%Kuusyd;sZ zunLlAOLq?dN2-Q{*P`|T;o+U$rDA{Wi8`_fn}=Y zI=48~MXNpvlRxS7a>RgMID3ueUDGtH843NH#5PmXzzjHZdi9wQ{W4K+ z(E`RXGL8;N_W8qm_+sfZ)PHryu*;gK(G!?BRIEG4=iTV+9IpWzjw}5Bwi48gV*?W!cwH zU-^ph;r?nGR-J0}5r|?noJ^uKEe#=#@O#xuUUpCFvf1VSe-5)eR*yzM$=|mlqh#!Q z-82{Rh^Ut^IyE)Ww{NzFT)h{;QfFJhDM+k&p9G(maNqFTJH)0w3G-l>8Q``Rl<-9Hj4}VBx*(Fvo z%#$h3K^3>y5ds5T(A@2n| z7z=H@cxf`IZo2FUg|6ffKU$RD5)s#K{2!pp+7_H00mcrdzMBUY)8f*Fd80SBNJBhl z-p4MzM<&x)86wkW>-`<(7iwD$Fa;l?%Rb24P}!-XMX8j}rUloKt!}ed8z5iZHb?Yb zBow}aVVgL*$F50mh>Rc<$dx0@BEt4X$AY>ac_EPwi-|>*2aLMKLyW%FoMTz%_*#DV zFZA;GuajM^KGI;QlC3nB@;qJ8g^H51OC=&A6(XW)r+v{u9)Fq6U-nL)6Ha}a3b0hn_RO;TEw=hlWmjZ34EzsJ^6EKz zUV2(Ma~N&q{M^~6Qn~Nqe2U9U&6d-;z2nq6QR}g@jpyJxJc54|NOLdc&~khm1Dq5V ze%(DYYWUE%S}meKyzxqzq2f=|*MQe%@HDHixVf|Bq5l5Q(D|cj>dNircPiLm&8$`P zjczx^BDc17Ex)pr!6M1Shp9^ZP8w&8@3@5&&AKMh#P1L$4SMMr?_LACmm0$!O9XL+ zXg+t!3cRhY;9W1xa-W_$Nga3$Za;^fxg1V%Z580{R_s?hHfyra*;QCnJ<3aYQ*mBV z$sLySJ!M}hE0{;mDC4!wPisv;>$~$9dG}sn4S?( z8#RcVLAq=#nFQY?Dq~d;O8PPN>8xORMO7QZ@TYm6E?Za2xIY@C3C42_)Uk2UTcGB+ z$Z|wpQq9|KhCevtZBHE*62`%Gb(g6)bfZfb@Vvziq1(+??LfKHM8#^QqyT;c+FyOd z#m%+roaSu(XM-DhT=sk9mguM<6E>2@-n0dMY1zTQ)mp9O#1&jEUn% zh+$OKLMqtVbnZ*Yz(S_JByOUJ;Ds8CBKMk8m)`#Xr^+A2_U!3FpCcEM39*^bW}Mj1 zof+>x0cX)#3}Ag#p(et$ZB)GI^OQVn-xH}`UG)D42s~de6Pf&Ka53@mqiKZgJEw*& z&*yY_D_y9hc4zDVks)ihxKrJHbTU~{Mr(hjKX4tSbnjx*YeH*mF@qOX8Og94uIay1 z!C?oKvQdw!NG0(%Ic-xeBR-*ec<$}&bHawyLK?>zQhCh04)}VWvm7X3<4IP$-ka%* zw_Fp#(b*=$7M`o?tjLn9T{_DVZv$5<=QqjO&ShWkiNUL+evv!>#WlqQpGwEqFO{d#QK$PIpHK%= z(1J~ryC#7b%zFxS4HoLhG2m<;$6W6kuxW;8WwP&i5ah52dkr%=y*nL1 zm6fs2`a4vDH*BuG5ZQbU ztpW-Ie$ziP(r3iIzlnH9&Uxo`?F?A3Vz4Zt=NNOFT(fGG+5b(_0-{bm)SE&uee4lQ zwqZ`!dr81oUMeCXgZW&sPOv@F{{SSjB+I502~u9M=(@_ye2pPCXjxR| zm*)K8%wuh?-&+}IFnf+=nZSMO=9s$9? zaE_Z0inE+*67J`hWrop+G0iG8<6)JI5i2nxdBL#&P*T>graQQI-^m60%}x{Un()S; z8=(MRccDOE2j;c$D6~9-%1lGudf+$e8gAb$EvBpLPEoSd^L~|8C!@z9#lLa;S`K!G zAyvXMy~ipM!}@%{_NJRZF79EGQNolK-f*_o+ET`Il&(sbo^vGI_}AU#cQW$jwc^CC z45t0J--@r$_Zh7UI_cqYEL&<&j}sI_-_$5%XyDawZu_4?*~BV#St)UrmGwT3fLG1> ziMC*kh)6jxg&x&1(y)iPMqz#+#|OL+=G&q;?A$$$q7a)iQCcKfW+_*KcUF8)&tg<} zjsODf_!zI*TvVy}V3PZ=fRfZqQkGt14Tc{|0_fRpzK9kE;k_!b!E?*Oe;nGTS+U^0 ziRF8%7^RPxWZ5l#b4wjuNaVG=fWg>4NN1$LD&N`&AzzXo0ip`?J7QYt?}FtfO+3UD zdzmS=AE55#{7*pfiFwr=xDdM0G9~-qMmSGm}sdnJqJooWA^UxsrCCI&QxDG^k%O z!MQ>MNW^MUsq$xeDr$EHLXOTO!K8r(5(QD$h_W!zAlQ$pQ|K1*`CBH0)x-j7nI%=@ zy*~8x&qR1IMyb;-rwP2uu7$t!n{yIjv^0&rJPs!Ir+k+868jhXY}8$)mGo@d?q1jk zkoFzS>L)fzoZkg-L!q}Uea4nRUme+ zMJ$c8LAf$8Ow%SQEBmJ9;Z+khZANV{my2CfeentFU;L>cm8jNZC3E_%*Cf9+Ou8yv z@0wH{wRvpq8@NK;W!8SQy{pTl5U2c&=&J83nF>Yd53WqB5iU(I&Kh}Zhhj1=9uG(T zKa;pPO|+k=zT;moM(KZz7ZQvTN%?~tNfHY0UU7eaOp@ImY)eZ?iWAC}Qg#^bY_mj- zuVnS1WSKLSY(Jag2ah0EuRptt2mZKv@v_SyiEdppxmVuOLfDl@RTtMCUFGbhc%|sa zGL33mCuF6O`SI5#p3N1-)A`LyBIv;EZ+PdH#>mvvN!L&r@ipEA+8?6g;Ub@(F~y{B z=M;M$X?{=3NL$^I<0;r*#JHY51D_JHXmRBl{NJRF&$h!c!6Vw@Ik5PQ4?w5!*5>(m zA6GeDuF9k_N3`piw4`Zjj79DS%cg`q%8w@#Z6hB|3(4!xy>*NRChM%nSHPScK5EL!Y088p*RaOs_Y=vK zQFVkz;b&p$5W*>I@j| z9?3$QlDqEp@;8ZKdLi}MgI{3lK!tnpDNy@_ec_)yZTNlWMs=)bn%RLXrMGygK3>_R zpBJwT@3W;0)nZEBE0!mP@3KX$06OC)3neLux?bB} zWtKUr_PvVbj4!WXbHf6X2`|iZVDS65w_pj+o>?)??i@2?Co5%fG{k|{c%3m?o(3TU z>|7J2$4>Lh+{IjW>^vsc0oxTjWc960xIemv(qeq0l2^EI*~@9hlX+X4v*gVSD@gG^ zvo7eq&};A#IvyWP5|)Ez^K^^zy0*EX^b2fBYbz!1h_cvS>8Okh(6Zt)6|?(147tq= z(Qr=kr6HxQ_E+Bu6DtVn90LovCdvFmr>n}Lbxm9C#b)9v&jeMP)IkC=6O)@LjwcKj zg}g&+@#(MgC58_OlqiDq913{=UG;s(b&B-3@s(Oq5k0o zJZ(&Cpl{L)R|L%m%rt2x&K3-P(_nB7qu*Pdr2hb33iw4NgpOvwCv$pKYna1|2;|1% z=NV?Q$f%+V?xkN$D=f*@j#{N!$C#XDG__oVFUcK2lSNhfl(Q|IVB61@Nv6J*jdDwF zE|$xP_A@MNkI9$nA0H4&tn$BQDSVYz_S+yN3vVl$`D69~Yzg$H@EIYUv@{yAw<1cs ztqpG1KKL-L#AJK~WrzMnrxNAgyGmjJDR(4PL;!PWA>sP$q|A+Vc_|N7^ z)0`)!J$?QU@P`ogpaJx`?sDO1d}{7Nw^xCxgUm|bgt-+}RYWo2={Da#XuRx}Q)lpG z4=PhiYo}%adm2+LdF8-Tg;#rU~k5XN2OGH}UDDFFjqpfR~tdqsYiKo399`#xa)8mVt}7 zH=R1>c&dc-%x={RDTw&?L-KpnG0ryG4cX>(H|-0YD2{bu!nfGo1x!^MDFJ6vZd_v$ z%!r6)4)V5XMpG$duq>n6s=Xy1N4N|yInjxT>op%8L1^v46*If0{wrrt7y4bq?1T$D zQ}uwU3$Agh9jnknO;TON`!(NVBF;@|!sC;>K z086Wy8EYI70yiI6=F{AEt4a^_rFjFi6jmeJbMV>W`aqSc8*pY)RJ!EVsHd(ILvnmh zw6z**-YYlselXm@^>b%b(;cBnh5l7j$9+0E%l$fYKYI8{!Gz>wv{HllI2rcD#GOGM z!Tiyn(Mi2#OIvGb8KgUi_FG-la)rS}CUVMCEN=snu^1C}$dlrz&)`A5@L*19pM4ON zmQ* zinnD^7Z+O^t!iH93^qXaK|9+kp7^(CGi@Peuv^>~v%6sV#3%r4d z;e6X0`o2mDi}@1f=-af7O=+iY?8GXz+OL9Tj*vRNJs{e#r^*+hNm>6l_rYnlsn)+O z&CL}4ybn{LVhgZ_wH3V=M!S||Q1D$Ijl73xGK&$!qSlBzzLC%n{#a^0uTk~bH<~l9 zF)_M+A9YWpY1&p}?&kQ$%LZBT?Wt6aN+al7RWy0icGWg4m3h$O8}N9Ni;VxRBI#0ej==XE4#<|+}S1{75pd|hRZD#^R}O@8zAA3$Z~tbglKsY}u@U3DL$3&?sK7b(lA zwfDl%WjfR;>(yDLuKld%^|fTYsK7eTI}?^K7s53$x4(}VZKZ0ww%vqm$SFow|AI;V zGWhnXxrR2ek6;;(Bh5`!?iGk9vlaQ3iW;d0UXd_k ztE`4PVb$`foBeEfiWt;wBo_JsOBSk9=}i)!>|z<9at>+Pj|(Db&eCS&RASMhpf z;Gbhfx9b7_nk!NN0m8sGC#r0?(UwJVUJDk}63d$Q=GR;Id0oD*Wkwc-7tYMAx8CF+ zn03?cK+2jH>%7%CsSWB`I0O=>B>iCmJzIMb7JXPV(61J6Xt_TMa2M-9-^VQY4H}0$ z@fBk$)IvkIcJs`&lMGphYvAHbP;QkH4LzZQM!};jj{g8T1@l>9GlPS(MnY`Mc~BQnoU${+(n{B>Ew!r7q>-zvs-dlk;Qe$G1@nF zv+>;nh9BPkmZ2oJ978gU>q-%%HmCZv^a#9>q;hu7bgONTt5bx{v5zBxvpF|W;4%nP z4VcGA{yWi6i>^!9O;l(BP(O%#{FE3ng@GiApL5hJ4>zj*e&F%OH|*tn`)O$W&&0XM z?Ss6SuhnDI%Cr0g^p-;~Tl3h!-9@tl&yx<2Y(PQm#i{3|*OD9H?C1@jcwja#t*?l638m|^AB@aC+&>8+V^ED4n zaH;DT^^>O3Yh*7pRUx@Cum+6urZ^WgT)e-(4Gfqv+3>Cv0aqW9t;ICf0)fj+&HU|d z4JP_NOb&7C2zn5Tf}Kl2I4h03{dgguX*gT9(P4Woh2J3GLf-nhQzEy59m=w&+&>P* z@-*NuVeNov+Q$@n7_p4@^zp?cJT*zV(MswX_$3$mxL8t9mXcDfuKp1l$Y7X1dOy9U zqM=F3M!k|@Wu;n(llj{P+r2>nex$PM)6Yn(LDi}Ze$OgT&h<6w2R7o$?5Wg`WZV{J z^<<(MJb)FwN{@$9DqI_#Kp?qJE+n31;r*qKGqT;)+2tzAy?Ldwso%9?h}F|cBwjmf}yOwMJ8JMN#qZf5-QE$8Til`h5K?~8P20eWdUvO4ek(=$AC zV!CxMj?R{jglOJ4boTVPehDHS>AqkO^73^*CJk=}YSqN}eRIGK={mz_tc3hwI7BX~ zGHkx~Z^^zD5MTan`^dT0`Ilx&(q0aCrt@DCKMI%T^qlhcbAw;Gk9LSrg6Z?!% zt6sCpHX1^1?{H~t!oUNfN7t}jpWt2&SsiGKtTF=aMLosX}w^z}xbXkj2tgLn()_A7SDpU?{N)BsYUK`dI z(&$VjdOmbcRl4)!7PnC~9nvl9K(2U{UlyHxiQL0o8~i@jiFNyGgS64rlflWCA+Xf# z`Yh>wW3zqk3)v1e$8dup2vZX)Q07$@!}XjhmccD0v4h`^nc`2#%4Uv8ml@1nvlL9| zXUBc;+fpu%XC)xZvB^q*UGGQ_TP~Xoi_^#qRGg37MDdBDhg*6n2=Pdpzvz+o3;g&E^m;@pDOfVLIZCL<+GJ^ zW;z=c;pSg%wb=#FRopF*Dgo09hSjQCFxBWN*RmL6;sV54-=F?t9QRL^B-TuJne|bP z=Bud5<}DPtWnU;>-GUfPOzg2Er;&=7h0gTU?6(WLWK8|4W4v#TjXN9(Z_X z&R=W4gBg3wFb=pZsMu?&pSe(_qzI3@G&e^yt_~G#$lpZjDh9GYmmaqz6z&a0ESqNa z@doV(i@%*r?|k$SQ!?o;OXg~s?eJN3@f#8-^ciaNP>YLdsVVY*jef(bd%^dxqOcN8 zS#>veje77r4U~D;`5yo>CD$yCN);v1tqX!E4M^7xmmal zUv?M)`+pVb1FF3`a_#prmu*|c&xTO*EJWAne1LWTGP@W{)3rL#U>MsXK?E$VKRM#_ zEv`w;uR_?@W4Sk>2J`(p_)V(eYTuJkAi;_=n~B24S7Qu5-%G;&wV@&E3`dclt&4Lb?~4p6Z2kkp zeWdZI-spitxTt%ub;pgDk9+PT%3pg8ifSr3a;k;ra$o@#J^z=MeROSTQTq_59QLl` z-^WyX8~M0X5xe3>YpoEOU{W(|XR4a~{kk%P1U=*HYWJIjx?9Ls<3%w6Mk?_DL#@me-#ed4B zq5VH_5TW2jY@ARvvAB_~v10ogWosYW9)p$BXhF-eHuw1ZeZ^h<24)%7A%TrGje;l! zAsZT@0P!+TicDc={E*faof^KPX#>3}Jz#m#<45P=y}DK@#m_qp$`0&*#V^FEKG;9; z6-b9%o?_(Bc28LiHnojfVL|93NZW2&cSf_4Q)pCr$YwA`M$?R>a)5D4+V&f5 zTM2O)yDHQ5vc&0NBfJqZsKE_r)L`g0yJ`WJSoj`yUo@F%I8$ipnja%Koju7Z;>|E} zPkU}*YLT-Ss}&gi1H`ql_Fu}>Jn0=&L4;PSlt~1+dg-vJ+}|Wn5*}U!de-hd+Fk%JK@`Trr9latTsbg?<|ft&9V!r%@HZdL`QBQ zx{89@$Q>V@?6H&l$7L;7WDXc}YVlnVX80wlZ2r-#d$8u8?a3W9Ar9oMlEG9gK=jbN zG-J71u$!pkO%Wu^m{n%`R4!UvUJ=e8bM)#At$cow*sl5^-gob_{;hacMv9w|q8g8P zO>67&vjVaCH)D90@1rsIHrblKic5R^@l5VRcbY_GwlZ;wVNa~uZKDL|YbooltyCaV zKhW2{NX;2ZA*|8XmX%V|``fZfhz|qmzvb?3CR6G->lu-KtOiKb%u)h_2GY-5f~xaG zmgSevUo2@bJuD6@o#;fLmj&L>y+1bp!5QhfYTtE}Q27*l8@Bs7Z3X^G#fWb4H~suc z;+AWgiCORU)7w?3!GoM5y%E%IT}G!l^ZF163zwO#xnhwfK?90IM6Omw-u(SG4A^&5 zd*BU$W8=}~cC7F7d1}=Ul%?agZ9AHvxA2le{HeX?du62gpD@z+0n zTs(wo!9^AzkTNceqg~5U*WC^@T+BTpY%oz`QY~480S>la6gZ{u-&JVS?=B;=vN$ob zY>QJ>d%DeYwd2;jYw9qDQ@7?M`rt=!jI4FS`MwY-n#m6gFzyLBc7aXxURLU7iywBO zb-D|>#rNd=qIwO2O!Yy8Q;GqDoWh=Yf`{ZEgU3ign`({PRj@h0e#?eRsGI4KUiCp* z9wRZ0&zb>7KiGwI=dC7=*sEZ2sU!=*!Lw{TIyPdm308rb?vf`(-+>un9J+H4Xw4+^ zs-ft8?4^nBzdIn$NuLQP&D2y3b{8KrN>fMW1Bi7vvB6b!It)_lMz|=|^E2sZzlxVD zgV>%kAhlQIQPu%^v4=L5$WxI~>TF6_ENU1QIJ2&)ch>zn=9C9iywq~NQ3+WkntQIe zp>pu#TT^L3VMpqIUNbsjccn5+Y(041Ba?pP0H;dyz*SmV=d32HJsTlwsusP9C5|K` zikJxRlS{RB9O}@qE?>5LnJQ`L2>IvmEj9R2ohk6N*bs;&zutSHM?{*9&ue&6-h?~M zKH2MmCUn$r3%{v;D;3$&mT}@ku1&ZrR>6Z&w8(Nw>ayZTcQ9(lcnP zPy{dU8pzzUR|TUwsAiUHNXe=&;a>yMR?4E*F&US%2k65STWo_R(bE$?r8j@OCUhFe z)Ajs^lyBSrPp$Tk`w3s|o@j-Nh<`EVEo`N{Yj37d;>j^F{yb^8PcF@az)AWh07`Vq zk(>zgdTz+hcK|CY(xD+(opnZH(Aud6J&&k6z*p0aEPHle)sSk@qCm=GH9>|Mr~m-B zfIj#i)~o_B7CZQnxr<nZwx5srw2x;8b7=b zngs}7nOSaSmFuJfvZx?QeuLjU$b{)47S#&ap%kj!FIHKu!xTDmjHg(c^3K4y=~Pa& zL_pocmy5W}e~B)FbW`>WRX~n>*dMFxsSOj(1O%t2TUgOAB!cAt#`F((d76-n=$PwH z#%xu&FO1V|P4!77dSJM_Kg(FHyaY~&G>&@{#Kyk+qE#t)BP_Her(FT9MszbWUqyLB!?7Bh1z&3yqiRINombWdSF$?bam#8{mNfy!Qfv`g@LWyni{Ed zuDTlM%;2Pl_@ap6kiExag%#}AmuhOhy`sQt=Cx;H`p&HZJjkJAnD8Hf{2cjKAN#;B z!vYvKu(-I%mEU#RHBF;9R(f*;<68?v{)R0i#g&b2Zg&eGV`)mIOb(C1RiUTl@hSUD zpkc&Ti72mA-_(WMKqBn*f?A)#jJ+8WdL7P`oXM89=Tc;=(4FPeH*M1-Og1lA48c?0 z=BBU*9A%0X>4DalJs*Z<+?yG;Nt1iKH!5xA-&v^1_4g`)y^OiXLdGVshapu(bXlvXw*Cs!wv(6I?U4wjTO&Wi!Yc*m` z(fC})3Vq2!!U;bph8boHvTjJxXp67047+R`kSV_rC=Qh&2cQIgj&RUS1GD|;Le`1c zTc15;k-jtNiaaKsLtg=6JXV$P=l{JlznGp_rX81&&eni`D=MNhr2>dSRv-&U=o4wb zR5mF|o+I{Az=Q!Ou-V7IwLeZ}V{(23WIo(S@2#ro!UGAm$;-~T9iZ%)`aJe+Ch)R< z9U4(6K6Yq3fs^HraF#^c$tEK#TJfmT4F?)`ht$Qq*ifB|u~g+!z0`^hJaWpw9`*A? z9!!cX(2%oC76BC3Qm?Rr0#PI`rG&a``YJ1GE`S)Ltb(duxMNr;nLMeK;qZ>|glagi zkumOO9p^$Ug3Jg?YWg|;=xb{>eSeIRxuTX{p2~fiToNx=US~kB3^J_!IB>gz=|8|| z|B3Qae5}^MpHHNCzp{0c5_PZtt+}2p2zH)e+T*U>L=2S4E zm3up_Yadj|!|>H?UYwi;RrXStQ5(~gD(oe1XVuit7#N|uKBRo=)@n!Dnt+Qj5ZaR? z__cGQV?W1XH)I{C5T&Ej&a1T9Bct7Xd#j4`A zo6BF}v??iii*{n-Br#-sN9M(*fZ7J|H0N z+m6;x?+R5Th-i^SS#dtY9DF>y=In^6OI;&Medp{o+5Hu4H7Bucxm>95LT~5q?v}B( zsjSy(1G?;>SH;;3{p!1z*Rk9DD!&nA9vV@b@9;e0#q z7Qv~k{rCSDS#K2;g&V*7(%mWDF_d&m$IQSG!weuL-JPP8NSD;mAPqxzgEZ1er$|dT z2qM43|E#t5*?XPa_wv2@*7JOxG_(=7D&B7+&sPs+u0&}9COG@Ck|j7UidyfZo?SE@ zJ7ZA0^Ol_Un^-n7v_(fJeb5lY52_^8f{8FcBCnfB`g6*XQfoxA2Ya~}JkC>9vU@Rp zPPA!x{cS%#5sfSJJie5!bO})md{7)81eU6*oj(&Y-UDkChm$G3*c*-9NIN={57(+- znR4t?&E`jAA^V7TheTMCF@ycityq>)e_$*S%{Dr~lw}Kuy-lk#1;>jrHf84^@Fr?v z8)?@}i~{PpZ!-66K!ienOM4m^dOK%mmsRxtjW5!LLvS(homu64E4`jAuIjripV>=- zSOc|^Qggb=pXNt5-WfhTv*NZ34wC;fxFAJ{{Pex%#0;I)J0;)#d9ev`X0stj!fVtD zFM2iaGv!mAS@YF0!>2;m^9}1Apk$oME|$`tif!%^`7PyihFyz(m?;}Bi_w*%R7Z3S zD`5M?wil_~YF<#$q8`xk&pUfdqmtfVlGnys+5e*y{yOw+k?PfK{i-BDs-vU|M0@j- zV!0BfV5j~zs-&X=_U723dB?w_wBvPP{I3(m6+kmPpg+Y#PrJ$M%SX@hMoA`e;ll4m z;b&M*#}oq4`lLbn^}8;OHYdt7ij{MmHA{0B{;5x37oYHGQ=48NHBPcHmi;O3SS~?~ z!&wgQ1AXjm){-2{IlMZZ4I_Wmbi{VBzczChUJJI^LQC&pz2*gG%4BuaZ+Mhz;b38a z2BwPr>->0!ia*9qV0}Ivh59QYGmiS+EH;s)_HW%@L|Df*i_{1|8lwD+_QDd*!HSNG zJ}U&<4qo$k5AXSO;C7RxV}xY`%-L1qHd>o}8bR%|o=x|Ycb`3ntE*n3US=?Qo6rGO z(YbwcUMA*<{XW04eDi&kWKRIed910++#b0;ZJufI=)JOjz!_V5WG4#}&r%r-V6I#B2R|FO0djObK581hjdRPDu6 zlf_Y7oXE*Iq8kvoi_7B!bfM{=Zz{nUoQ`lr7(D~ZEa=6w$}Q>j%rYJI5y~Y^rny;qXMT{_ zYz`LioRBn1krRiCFHhuhC%T1W52317Jm5c+7J3@6m=@qt4k>?{`jd{+5`IIg#bofH zDUAe&jd32~0R16al4AxN9orUBmy&gwV7$VKtEPRc5A7YHr>famOD$ayC7|R4XFI|? zM9nx|gn>-HZx|uYWZK;WGW%rn*L`sl0IuL=lB@A(Ybe&>WF~CiNF?z!=|p`><@$nLOcpk=n)MM z!yG;U3N5kW{oa711l~dXtL}u&)Z23AUlfIFebepzBW4NCYguF8j)|#>v>mX5bM~@y z#)ctCJ&QB;|3jgb-0xDcZS#tB@}i{8POkK#u>{d-dfUw$vmju@|9zapf7RD4W1B*0Rfh*Z3&XEBET5w| z{LS#$>Z|^b6ql}<+Q^ReNevA5$E2{bGP-m}xQG_u^+J`-W~7KxMW#IobI{d0I zm`p%nvL;Y;OG!0+^CRQDn z+(#x^{FrU@>m2<3!|Sr$weu|VLJ`BKdF;pk!X|i&GzqGMf1bW6CU#SJ!TfQv% zeLVFNq(s*`st}2f2V@OlVFer^K8BoYqK~sE;3#IFMJeLGqdn;7!7dshaG+-Un8vzFG~7>7*q)OSjJG%T&L( zQnH`;8%=h_+`$tNqq^aoa^I#;b9=6mp*UR<6T^k#4;98jvd-IUo~{6D(0ZT+sBo6( zlR#KO+p0ik#lipN>QjL!L`rlhpU(~g^tQ#%ywX~PZGw+Q@5sQ-~Aipurx zl?7rw4?1AwB$w6&ga08uF{T7!gW@SG+jjE<@o>LLY4MlG!A~;`+h`C^>mZhw&7p8` zlOAY!{g#K5;8gXCsyXQk6rn8<8;<(^@3X+nx1VK5sancI!x*1;H`y*op>X)&#^3QL zAR58sQJvKr%9v;2;f<>xk1MC-U;m-xBnKq?FhQ8+%HQM@Wfsv?Pn~X}9(q~~f1e?f zVH-7EFeuS;>cEV@5pTjB68=5c-L_YyzhjUCfByFl#fk>0Wwy1qiNu;I5b-lSp;xV{ zx_(ui{Oj_!{6fL;1Zv3PyoQiqN zVj%Pe@nac{!V1DH;b1C0V4@p%TY7GEpuw{x_q9jYN^nX{a{z=F^f04HQ)|DwNIvW@ zQ`zm(%rmc=+i$qPv3wp862ve6ap;s#(-noJlE*5M0k2i;vC}mY#|X4!{M(Xrki2zD z@tX6Vmku?eD*r2|6W7Ao8y5 zq~6=6|8j1K*!)T;PVzaQ4t?5+;u=4v(xQw_!1{MaB?og@ImTymH_Pfc_4lm|W4bo$ z9!trlXrs=&I{qd>NeQljs?BuSVJU~j`h5PvWt<8|^9=@0<@;RFVBm!4>Bp1Zn5;6j zexr`YJGUik?u<|`(!w?DQH^oHL(Rpwrue98la~5d2mggFElUtpTU~C4 zOaK=HSo435u9ZH?1dOaF{w_jB|S^gt^@@CO^eTFQLy886h<-7`Y5_sdeLgf zr!WyW*YMgB>wuG!Vkz9q^S8I?j`}F@oVWs8khL57wphgE>(C1~qKI%SlLKBBHgisP z*sjvZBC#+U8RMK%fWv%9Ueb%)%4{nRJ>#G8UQ#?RD|D2#^)DZ$8bIXdj38ycGGhVme`CYEh0k=!$ztjWICrrN;X8|$JOmQB-g)vIGR6shn9rOQiVzisY9S; zahz$XR7gYBm9C>FJP~MA2jny$eB-?2raQ{@Qa$RnhIJbdGk9q%tljBo5&}}TcP2|s zEhWWseU&LI^-GN>$HAr5WW>QO@@9BZ`$Jj<$p0vN z6m9Smm%vTC47yzQrb?cex=PQ?lRm@nGF_x+NGl-xVkaZPACTcWmR%`Lwn{bHpayzN zBSBK{sj}VN@^qTe+3&4c)UVvTu=_RS?8_%~i6JjJo+=-Gu9cJ`6ejYYa_Qq2FLN55 z@Z$eIPe|3lR*Qww$nun6C8L%OxJ?{HRQiSMa~ddoXwU$etAx3QgVhhU;;Y~B^-2^? ziG}Ee6BZYjeL8l3gQ>zf{TIjdVkUX9eR_wp1M2#p1qNEsDxp&wob4l z`VxKZL2&?I>Y+=(4uQ2~STd>vuT%GpTvlJMX;9JyW(Wh@ok-?}E~1-y(Z}ae@qb>g zF)Yux>wfn%^41RPH|=t{{~AAq9N=O5G;?eMb!orQw~4 zQ+$H$myW(hzh1~m!-Q=no2Md1_@9Ely9cT(2|`+t%d%3fcgW@xb~^bji&y@#uKs-a zOI%=_=3l0p%(Y;ZRH$uh%ZEw04b=;`Q;oCJA;SvSB9FtA=Xq zMQ$$IN!qf$-Lb>fI2{sdn;>j6R^xdpd(uU zZ$qCqI=cQ3&=x0k8s6VV)u|&z+zwkE6L+T1V^P>qud+bz!3Y+9tq-kwL(L8q1IfU* zjv4JAylOyW751U9(zOg%^9UU>6M)2vpPtyf(u%7@G7wxchn80XTXxLWL^us@FJ67N z2kXtpE(e!NwE2ab`n_5#KSO8|uto?veTUBf<<3e0i3yy7+qq448WYf)bEr@Z@jD7` zT9s9ZvdG;~%ch3(=i2&5x!Cmb|9tJ=*)Dvd4k_b0CYV~l&B^ot>Bac4et+S0tBnF* zu-$bisOGGJy_$ONFHN0~7^D=GUQgbDsfTGcq7B5ExBybMs1!IsT_IJ0Yq(+NqngsY zyN{V*I#)$6fl&U`cvJ=fn8YFd?Ww~cQkJ1Frdlpu+-CnWUMT=rVdl^-m7elOa2Kho z6zu^b`<)G6VD4FC}g;&BNnkeelqyOeFbZ-2kA<*VNM$p-Q}hIsR4U@ zq-!5c;IfKyZKc>Tj3m{B0Bymu#wkjjnN%l*Fky|Bem<>CR;f^&le)q0EY_s4V)>}M zn4!BV6OYkfW%I71xhAqx|F6RXMSX7!`tsL!S>8es0Zu)sFAh%G_8l~g6B9eyljW7d z+Tjs-@MNU~W6mRHbx%QY)L=Tuf|F`P%f#w~30i}GVUX{iSG!zR?V^?OP@m>5S}p2+ zct-~r9W=-1Fve>>(cstsFi;2ngeU<$vt`5~Gpdd+1KxsZ-?3;#)ddm=qNG3E{x zEu`;^kBPqk7;A4H#<%YWOS9Ren&CZs^&J{`1CX#A(b)N~_f(mX$cj{?X_{tLQt98)fcc6< z5ceB5T2vGgSMS(MnUx>f<9hpnxx>LxP~$ugpz0bpZPtXHP@G4|>{1@P6e)tQA;QBU zQ3q?M{e(QZDm;g0`)v!_D5W2t!|auehL$&kxf8eZoj0x1SR0mB-Q= zzxYhOE|5dr2~GZka#eBe;9F!P9EDn-;mbVPr_4Uz1toJv}4rlf2EBUz3&9WF)A+&Z<+$%zI%~qMTn762clk+wj{q0 zvKUo<(n9G{f9u)=OFX~gt9_Z02bfwJgV``gzJBjT*uGAt5|{Yn#6+{ObV%bW`^+3Q z+-dgfbKvbKj$YS=hySTF4>|Gk*kkf+Tfm;8pdfdX;@1s5{yl2)GJQ{j!#K?CN>jEJ ziO%rrCZ~4ky(pf?W2Q14bwjNzrD~4{H!{o20aZprqpgqpG%L;cxz3Pe#V=`qYofJ*slinaY^gh*?nx`ELYOzUOV^+?vr|xF(-3MuT6)Gc+G3Z( zB$!4uEKxzf@b6$m{bIYW*;Y9|9#-pbmY~q!;ZO6Zw_&3A#3Fd}h%ik`Z>_JA#{Xus z=)%p*=a{_1J{Lm8Z^CUR%FA=sAI)e)rIM=(qYb>xw3;Mlpv4 zTNsUWN6dQ$9tj{1V1>=(PyJ)<$AtP0b0$(JW&BF!nSAOavarFbofw6?Pap*2 zoFMsxDP+8*&|94CQYHM8UFJY44d|_PsItuawm_;yAJetfNYFDmU9C>W+0{#`R7vTm%rMgEWs`60F)@yC(YwfrR5 ziNNiJ6T9_{XVJ{#5J5MnozFQXVBzSIsdg(L74K##`b9RtaER-b2RfNPU8bj_qR4Qj zx`!U)%x3)<>T7}0?-ya!{E@tLIxrktC2CXQp~- zX=OJ$d+m~t|4>?E67oZFevjw9I5Pgf#D;2W>vW9(aAh$j<9{falVV#vUw0gim!9{U z_tj<83lnf!G96)YSqdoN2+y@l$T!35;1w+ovUSgX;q!7%{n8<|ToF$wQ1r0O7+pue z)Zy!gopH-IWbVH0oIAo6#3fjx4KSC(DvzHsajmr2m9#;wOrFPGBo`-4qi0MOfBTI` zZdy4VQE@whR*f69XF4(ja z3zRndr|GB=vR-M=yx*qd0;&D*ABv2!w5@Rgd+{VQB03~3orTSJwd%;auXILhS<~?7on+w*Z;IAA~ zk+<1402|eYI?$NUB89svW@e?PXo+ymNo{{}?u(>K^7j`kN%1lRzQE-B`W_vWwZq~! z=6#+?p4aBZJ?M8{B|G$ddpy;g35U+6ktR-pF8ZzCL)?B#tBd@(?tfG#mRwU95Dklt z{5+T9)iYHoI^PMM2F!w(-*QiNdaHb3DFJJ^&qZ8cmpik%c#fqe0WZp{K~jhdri=u@ zl*LL9zi&c@vPFBih~Qwj>URG-JYt!(W!UEFB^=P>FFF&AN2Bf(5ost77(urQZ#|STGc{GAiLkn9F2NQP z8osJgXtMgG(C`0HB5!E;m_m@k;Z1BS#hPp5V{*GBc-3?Ln*#MiT&tCs(^;PEDktSgx5%`qoQ8{Qn&8f zo@iZiEE!X^>WOTEP|-2}Tv7cdGjNpKzZ$bbE__wtK}5fT=EtZ;_astO;n;En18?X> zdng*{npwIAYSk|W5tvKS+yPFs!5sTJV7+Zf)Hh|)-^gvGg#V8h(aTVgp9%77-+oqe z$-ML&QjT*zS5fXAH^evW@s;s$x}gKw!~6#(jWD&sgg%cBkVun$)5ZB{5Xq8vW0m-g&&3^Qf%;IL+7*C*bNPp@wM}6qpDMB zjJl7h#(Ky{m4Jkv3N2ei*$Ma6gL+?CS#r~LxOGwHgId3F8>5v1hPCihQYI4nkE8Z> z`%PECe<=96_t2ub0V2VLC~blxQ2y+zLP25^&yqFH|cjpnTpk{l~;V?@R)a4{Ild6 ziT=sr;Wy@C8qFD^u*!GB?E$PiW#POIEW>+KaQt=FAC+Pu8#Z|03@H~k-^JL1$OwrI zxIl&1H59CvVa zU?%n4UmuQOg{dZ0@&{RF=r(i0PjPUcj9x9R$T(_U6lmILX>usoXGEOFxYM1Ktc!+{ zAdL2x7(Wgyu<^K7VtTdi5$4FQD6=KCYSkTRIK5pupuCcsVlh(T>&^CYA?vi4dY7uy z=mkB@A!-<7(sR47ybD8!ZsE0qAZLor37xMpJw!sGx_f3LfImjezR9+nwALobgHXa& zYUzv=EdhbT1;z`!>sec;u7K>V*ktcp@hR$3Ehsf44djmtUAM8=#W;!7cpXa-PHd-N zfd{E-q1s}wfO~5}iX}MsYEHWjCk7iKvE>{J%eH_8gAD_WLvpSanE~h5(d_Rd-^lH~ zsVE}%Oa+K)QOz?_=lJ)hR(gi>H>j=VuUV1Tu9EBY24-A{*?v|Y?%DWqDaJAeuA5Ix zSH7|1%JN`Y(w~jV;&$e@;Q`9AJHDBXs^lPwS6ij4H9CLj?^32L_m=aH~>)_JP5mJ8r?qp+TccQAZXJ(QrhD@zRW%s6X z?Td%)FOvlN5zt5drS*P#>b?wyX2}J;7|OjJp6cY#;IKJtFV0y+kHNm_c?eUCGE`i4 zHKDN&Hk9FwsHOeBhHVAJg^EiGwdZ&USv#|0#nCd){(o zPw$si>H8DmF+!7Awz%@ldaZ&@ljfbqsgH_5Cwd$ykltML+GA~s!Sb*|?|1q{P@MpUc@-$;z9K2e;QhU3%(vJzFSp`aUMuUQT+6c`J;f)@!{zWc+vg_f4MKy*xFEA!cEj8XJNB_EnT^8%#%Sb8ka6lbOGj3@_UCETT1XAfq6 z7DT@VM5MOFq-4+;_p@w;+gp)!&C(!@P#aQ#RBT&SW_eT>NgBcfD{l2{90d(7Qatno*! zas`}z2h$gD&wi(>WAwoDcUyPNrZD%*scf}BDxwJB+2OBZL4qjD@%I)CBp!)F68wDy z`YUR79)|$|6H-smrXxd(U4r=1?Q%wh1$SW#fBeak`BIxhCSDK3Y%mBM3btfm6FUk z=@$#_6`!>9ejKr$O9+mw$Vbor%&v8hc8X3fd|D|7kK3)PJkX1|k}Yz|qi!U2fO)}& zA5&~l-0Lv6S44$z1n{|0gNKTJr$bX`AaCljQBobTI&rp_Q1%So#ATVrd(9=)+q&)8XcHYJvVXBzKh5zDM-4XnR%%08p-LelM!(s#Ced;vVy| z$cd8rZ^{O;KQ-I?fZ=1ogoeCy6To}}4-z%APva6SlTrO-yH!Y)nVx0N-%18UV65JE zq3QqQIPo3Q%*vfAwvJyHV6^NKg_gN)Bz%j^QPR7)=P=QMY8n4_DNp!hwNBe^x2cp> zhq1i6JM?yN*#{^s!GpZVF-b0SiTb+=(ElK<|IR*G`& zm{RKt+w zk^m|dt)rDsG+Z(tMXp%6`U`Blgu@v+0~ehAP~|ZFaj0f%x24JWdH$NAc^taf#s+=fm+8gSkNRlbr7%&SC6qDJR z*WiYy1oP}|+fY;v$2$6L`+=reWxLlbt|r?RcDs(*82-7|*TulZnYy}G4P^vUGX$yB zOR&@`;9d(|F^AFIot>x{7I)JNscGE=Vgt>A#KfAIhhFJ&Rz% zmi14M15PM9lSbw53^6m`0QceD-(KffjfkL**2yn|fy-;bNRp$in^nNyr+ftLdnbM$U3&K6Be2dTj5@FLDin(BiJMXtmFQAN77a=n~1Ey zqK5DiXrQ4T@XU=0-^_FV`kh`%>tT&Ja-lRVo(ZHuTJKJzQ_G`vJdl~hT!${fe zC`Np4L2gE6R$Bukv-wr0MTmKFddTgL=2DQ zot1LH34gFiy9sRva$zBPQC{hu+%;XAIOKnVPr$mm|Lacu{}w!B*U{x>&sS-+VPD^K z8r1@x^z&9nXKl?!J-E>|+Qwp1wE?=dMkz$}Tv26$Y3zmDQk2}9P_7?hNj%(l5$A|~ zm?AcBHF9`fKp>p}z5_!i@82(coT3f7SokI=hc}H~E9uHbXvdiw?EU*ZNuF|z#$hO* zeP6u!{JoK7;Jt7Y;+@dg>#>W`l#ksG804N(p($6=U*e=4%m5Leb}PS*$sYggfp()A z@n-<=GTDT?y7w)KA%z+R(E00$CNgkpJ|9-8kVTAfGer{(q_@EYUW47w??(8?cYbi9 z^Sq8aF%%d0;zj3-XpV2!8IMb7gh!s-4q#5v*fCfckWqkBT5@*E43!CfTPb#<7ME%(=+fH#MX*Q`)VqQGeivmOU-$Ni1vZtcR*DYl5+ zOWy7|9OLfuAj<=u6TtJq81iD8{PyDRuX_WOh@$Zl{{%W{Ddar+@!sXp`KhZ;FZv>s zq=XD>pLrcMqU^v?!=srmjC{K};&YCPMKzXUAcB!u%Tn#={@2*0=+WR~ZiBG{q!{65 zPU@EUvU})5wdqCWqu11c0hKTSoRy- zi?w~WrdN3OdfZbJSS7+tbdq=7zPE0m&|4+M{X+9^tTRce+Qv1VN} z1_e*YEX@wwMqVthjydH;lXnj*+Smxz@bKnLn6?=gu&0blKl?@}*NXw(CZ3fl(JNOQ z-eRqd$Xo=I9-hiBf3N}ZTpF$^!8DC>TC0c1{kVJX!|lePgTk^?AcGaBTZt0q+it1P8l)Q6pwFg?);>&DEnWDxRU=QmQfOuxs}fRPAN4kPF>sjdx#5#M~f$G z8DCw}MHxAfjiI4{$&ZN|8|hLbsq;XST-x^m(pPi#bs2=HsiHuXWn#mcmqP@PJ|S{G#P4|6BXZ}z}b<|rKaF@7L5*}qNwD} zOVZ(Fx{Lhz@nI42jXUYjCo_|^aeFDx?Sv7FDc17E3XW5Dz18&sNqcCit$#Nzu1+j( zRlLrzBJs*Y$u<|7;o(idv%cwNG)UaQ0H!ELPFp8ir>1W*vuH5y z+Teq8nA-;2l%G_#7Bs@zYJzd6H8nJAGMZT0+a)M$Ho+^77R~IugL0>LHIxl8;R{ZA z!@mF%Z66Szb7(y<-H1*JB>uXqb;Go!9h!_w_02ag=|HhrlP=bn=mk($G{iD_ir8+Mo8# z(=v3&E>&WiuNp5V@DgZ_yiXZvO=r?l$`3c1AIuIQCA9xkM_0y_gsTr|-Af3H23tjt zj2PGLfVpSxu;&>fe&M4!JJjEE@tUpS);1olGO)&kT|}kUSoqi+%-dy1V@z&5q1^A2 zz{I@;&{!Z`(eS((|GIDZeV}?~L5&4MyyN8p_RTPHf+7~g((LELjn5}r*c{F?I-V|E zVLdT1xI1v|<<>1GA$s)^r)q1ecTFz9ud3lORGwVIoeYjsX^;qU`IB8)F&-#IgZj&sXp}g22JF&Ls8F5HrmjZx@-6}M}h9xWIeWP z=NB;rE8B&cJ;YnS12MYA)3EX*Et7%}mb*3CY`c5?->Lp4kjtO9@V+Lm%$U36$9Tp&cejk#-GSUkjWOxK7v+J!&rtej zuk6!1EtY_&IA}YmPysUO`9|RiB}H9k7AlPLM|I6Mh?erO>BBL>qPTpRH>sX3+vxWp zJ8e32*FCu{BkOL)jE>?5uy9c?<<{aVDy37xlWlV0I0P`7S^@-rCcqZnn^RJMeM-zI zds+A;?6Bth_epV;N{-SQ1Tk6lHdoD>I$2x$ki$AeUP4Gnw4u-AEt$djkuL*_ZX@@S zPc(ab9avUr$HulBd8{!$#fD%dtybtZYPQ}uD9GY1 zh3Dtyn?c24`BaPIctM zq}5UX(DdiHvBkUZvkV&AR)UKmTC7Q2k{3#EgB-0>|H?#Rv>~YI^30%Q>h2(B_L1r! z;w@XjX#&AcJbM<$^z&pG9~1|reDfKnrmE_EkM8UA&ngE8HI3Zb>EX@L9d+jz5#e=Z zxKQe+lT#b0!aW$87*yPkjrrayn;2HfYx^r-d^N_+^RSL>_Tu7{U&oEy;|poqMrs(u zj~iXrv*g`>D163pbQU!J0t|DzYZd_GL(R3A=G1%~AY=N|_Bk$M$x1tNYOJOr_scYw z#uMVzPS?1k8zGJ8O4AsSn%c@DQ|UjH@&|RadX*pL29-XTN49pkEb6AHV_)-0*92C@ zzF3#)&#a6G9I8J;QJ;SdsxL#eEJZdHRoRzoh7aCJt_XoYu~)};Vpgf5#*x*&oET;* z0?G2~`0`Gr+C8Jw8Mj~7CS?W1-IfvJ-L2Fye_#F+7))Ho3SBK;xom1SwNNkyJSg*0 zS@~7;%w<_{gBhS?n30h}%{^4J>>c^4pbgm+-9eiid;pO~6pzIX+T94?(p$*B?cETy z4U=_+d0Lu+5v=;t-XVQkW|bs@#U9$o;onH^^!&69?F&#7+H(fZ!x6`~}q)qlvKIoDy2FPLkm(5iITs&E*p)C>>N~>+Mo8 z8G!Id{@umLEE5k=MGX9@uuyCzQFQ4=OD^*Ms!PQx!KtiWv4nDL)x?IhkZ7a&_Qvw<;2&vE(*s-=2OZAd zGVL5Sa!+Ex5|%-3rwgH4&CyqzS*5_`L0XJt9pkCPeu;Vz zk%q=%8lpDe#Kt(_Q^J+eLz8ViEZoU|W+y!@VX;2xMZ>nK61T)L>@Co2OLeHXrR~M$ zRotR@r2zo=SPcrc7xBE7=Zabazn)p8B(i;pL6@CFU#mVm44c6PBNm`Q=G)|erd8&J zjBmF>xKtL_Ql^VfPRjnmO#Kmor@K+Y%)zGY76zW2j-bN@Q3JXkKHG=c>mgkLK(^|~ z44*0eh_$NC&B zS!LUlen5k#!>x3k^f6Rz>CX!Xz>iq}%{VWFf8zNr3`9!0hr4WtrP=3A9Em_iXEnuj z;!UKlzPad$R&oWk&MoNf$uyNcU*-h;hq7b#;+8sYygVWg(fS*xWoeyUJU&LH1361p zUAO@}sHgYLe*HV_@%P1B|Gx5NQ#d`mb@HR2t=d@qNa8WA{giU(4}|WEMCYSY_zP<2 zq%yJa|GeV;UnQrfJGBgB7;PwZw>=XUV7Q<<9J0_fJ;sq={T~WxSyJn-ST|+=Q9#;0 zSs{)gG?G>gKbxfBcG^2!zLGeHqKwN& z;zdb6s(}>`N_Az#!1j;e+$Gzs%&;~LtjE~aAH$oxlygDTXPll;Xpn~ymp+Mh#M-;- zKdLL0myR0fTT7cF+%C7mI%8h=Wg72p5}eFU%!cU-$5?pBjI1%3U5i}!3xoQvM9H#2%D>gNOFXxD&b8odHOvk={ot8 zRfrG~U8JU5#34R>t~r?6f~LBv-dvHaIh(AX6?qY)r!*Ma<6D}BHltfPt>@XwP~X{I zsDHL1-TEnT`GrX0OW6@3-Qh{14^Ej@*OZ^;p$XCF0fPTS8G1ka)G1tpG7Fna;Co|T zLjTzsEvMU;ReE#fBPpbkzycGufbSF&D%uW5PUKCDBGTV7m*d;MmhD{rLdu*wDK4=Z zgDuQOVp=jB@$=)C(3ZXx@?+!G*bv;-DAU+e%7k)RgPqs-ZDJwrlT_iM?|mnR1#+B- zg(sTdj6TL95oz|qpYk1zG?AQ#xa6ud&LMg(mpRw(jWM;-u39#TiTw!objGMt_(%Sg zm`TkofBzPHDgJu9StoMu2%Z^zBr`Q$Ql`t=M>c;`TMezVHXQV#S2Z1Qql*fC_>sczQ_7V8_Cn(P!7I_1V8PzJwS6j+Y`#{V1?VI zm03uY?2unf1qt~xOdRz((7PiGs3*PGQ3U$epAJK!xzoCTX@60q>h?0oPtS#%VS z7&@Cmo~xRzgVeYej?(VFY!1)8n#u4zx}qmm;n+^z*ppVljKgyLsDl_pbJi#?w;-LI z^;jhtzp6vqeVZcTbVg}7#*n6=M2pwgdn>1uxpK5qZoV(Y_>dB_e#>8Y63OAxQrlk= zT1(j!D?dz|z|*hydV5q;QG7$rWNC^Xny>G-%b-7SVhG*cb4__$FfGMml$2SfB~f5&(bXRQ2~Vkefjtxl z3c?_@v|u4}6fO@(cUNS6%|z*#n#bZ^m=ep7dgleojyUo5Z{}y%8LP)VTPG-? zNzG392d-mZMNEP2Eu>UalMbtFxjOnrlqdLr!)61zZE}v*TR}1(5aJV+=X98;HoX1y zP2S3A+njc9Z6NKwxhQ3(Q2)=@2?}*rD;~t+U{e=`bE{x^!&Z8xZQ%@)uC9SHj(+{n zYN*?{D(5yAbGC+{AsziWYd`zRC1XK;O_pEdVHCUy2)aZi+LNl2thdnQU&iJr&Z?)y&Z1K+D?lA~!jEDw zWd?Ud^Zk%;FA3y{stNX_Hvk<8(jN+SLu$QbE-%WEMzbU5EP6|m!;f&9`(lRT1mjW? zCW}^x-b@+&U&(Ga6CEl1}}+aYDTEh<^xe4Q&+hOzrou={&c%30pyySj#CF z^G$L9Ufi~X(L-lg=@GR3vuO{gxb-?&ej`@q{?}12iI<+%`x32eb;o235N1&Y=_JzK zexSegbp&VktZ~B-9lC~bs)a&FWLkX|$q!F7jj0xmSvab|PtO1lTL0fyLqhP3OwKVD ziTT_KHZ_>bW%#bkS+WUmeAHR|YR%A4m-AjiBAS;_pQ5>G73Req_UU~b%TgGYV+B?V zl{nKkZp~`Uu#*1m6%_m`(=2viiM+TXo;w-tiUD(wl5B%-G}S5kh~iw_`<&o^>o*@p ze_282`LH^QuaYOK;zG;H7>$xwjUCcbcPe;vaZxzf*AqqO<99};Le7v?pc6kMztjLvwYg&|Siu%_cGqw&B-bys?O*1=vn_I#-39-#!$$O(IvSLZrfSiGpq7~A4>kn{ zekGYy*9qyG4K{X$stx-d7@ki?&$=Tfs77vtJ5@AMj5-<=nsDuk2?TcuW+~^YPj4ZP z6d0QCGf&R&b%_6-5`@(|Rzg4MtbR5uCBf9Uvh5Cw&l?Xg@_CRHDC@nx%dl=b@Rj=y z1snDL^MUujG$fMj-%*-#>RSNk7PCW>=#j{HhR0|mi2Zj6N+u>Yzp`52g_fcI?u(byHeo$ox*vdm6biVhR3TZf(lYy$`sQCQp` zN&VpY=b5(NCw*Vgs)SYc5lQg*nC4{VwWp%Tv-+=uAD20o*-V44b?7ln?y#Duf;8KDt3y5E5eQTRrV?2omMG=!zy%bwzFh@D}M5dH!=J+VcFws>g zjPhQ9XAzf^A|1Y$jkUy0T_0mdJo|mC-lG)}^4GQ6Y7u8O@YhDbnf5Z2ee7fNK5)+J z08iAh=%#(K)bK63-~{T-+HL&X!DQlD@>N|XbRu=$qL(8R8?j4FkBQ{AdN9v8IDTMyW~riGc#x<2Use^P#2X+NcjteVe$DL47VD^5dLE;F%cL z`|M+Qs#M-F+Py?i1k2ddv37VdH{IbPZ<%}0k&5LirpXb-Jy~!IiXa?$0!c9 z{nbNq22g~7Cx4L6*jE>3(t_EI52~;@m(pJP1b8XN4!Zv3pW$U0*)Cx-*F4Mm)e zF@?iDQiQwV*FTX5lyigv#iH4ze*<>dt=w{~BZfXl83uRh(&*OT#_2xd(xTfNfv1Tl zu=&iYK>5LQ6D-~Lm zAD9qd2k2}kkHedB5+`lkj0tOv=7CqSB07pG5RtS4=HUJ%Wt)CF2&)|3h$?8qR) zm>W-G_Hwu54fnsg<%KGim2VMG5@|jWWs>nZE_GQHvfvr&XQ`7t7GbgqHz}?B%<*K@T=BrW6JSum90> zv;1EoivRuKYx^ZCLZClKcnB3_bZjUNb#*T2KhhHpZQ-1u0CBNRwq=)Z4%D$!;pY}!@TL2s+^PL40tk1QDdF?kQ1u7yUl_I&)Dslw29 z_kcWHiAx7e<=`A0CCtaXq}Laf5tLKxmKA2N3c!HF%!ja&`zx~fB880+sv1Q=JJ(+{ z6i^)q+(q`Qg=>3?JEc&UeR0dfLa(s`MAks?dB

    4khT(TO&RIzwZ@wSX^Udab{+P zxno?3qZ28z>95K$GO%>hftU5)imt<3MMh4#pM!LipDtP`f88enil@Hpi^SuQ)ZNWow?gEW0oH%7!#Wy(y7P2VplX3y z<-Br>n6CEZs;!FRA+l;7ed?1&;adL4wKjJ8N*Bu=2+Jo}_W3?84~xFc5pj;u|HIi^ z2E`S1ZK91OxVr=h+KmPGAPMe`1a}CHyCi`C!Cks>ryF-|2$J9s+&#EUkl;yfzqji9 zYNqZ?&D8yS>ijvU_FlEtvmWs+=-Rf^JBV^gI8rUJ4mmB?@mx}F8}sTgeL=k~FbaLT z@DDWvYrB>G+NFFLlmW7eG&IO^IC)L?ObP4MGZjryhD*_@4S|>{=BIzo^SQUDupuP~ z^m#s^3`<*(y?t_`dUoLwscU;a@3iYAgSwS#WgZnh4LsI2xV~!R5W)@1LS4P*r@m_S z_&3IhwHI?mu%!#l)^TNLdl<2?E-TD#$LcJiWu$nciL$y;4K}Vn+ejlT6-cY|ZY918 zJ_^b0UmRvQqeY~xf^bT}(+%m~B1ByUgtBU^#&lT~MFEczR++cU8zy}z3X!9iSk|-- zOVlY|uv}-2C&2zCMy5U$f%`u|tf|ol?I}*(%WLB(Ff1B`vBY^f779-%--_y-O-X`c z0ackWGn&O%>QUpN>iC?gAIUro^NK{c+Dys;Yq+0Zdo?0O^R`Wr5Nc&)UvXfi&ykxO z*l9QSs=yH1?zw9fVxOteG%^ha?2_pV;=(b>1#()DBT1O1GaChj3#6(1e+<@pM-Q}q z48INZQu``FY0|%(AH4W!B4(@9A&A`io?MqpcgxkeB#)JpJf~VkkQdtWgNGHrTwYs9 zxp{23Jti7qHHdhj%NLH8)yHWFA1qb3=xx{JE*_n#XejfEOnT!894(=6An@^d=T5-2da}N5IssTzT7u0A@Dq6e#I;Kg;hwSnA zYrX6na3e$IF^6(H^9qw(HvQDO-lr|66aih+#fCStZ>oNK*2lnnE?+6bCV~p?ELnAt z?_(IuQHn1sl)djcCR{B1=DW@q`cCne+>$7(OELmsamILo<>lQoy()dAEeHoadPTA+ zwzNSj2a%n%6jYe=bD%B4kF2Gj5QzZl%#}*SO;6~#_lo~Iu;Qa3t%@=9*9|z??$)Th z8sq^ok~pkMrke%%fur<)AN#-S(>2QG!ey3axZ$T5*Gf?Vp^hn-mUCAaBp_LX6c*PHvx1Q4ir_bge$GK97!>U!K(W0o~nLzsIuTYUrUsZ3&>R3)q z*B>GE7u7eRoBsfWc0Ux~MA8epLPp_K$EFk;b4zoAIJoI5x{FX`_=I2V=n;W(vg!~jb zVe`ywU3&jBKUcy9@5|M9FDh!|))E3nKHGK9qr7pkL$P08==|>?ES3TW7>7JEP&Wxr zPA^Y9BS+WD7MU!_qAANJQulmG5AE4Lu(OJ9;;#Kq^14ci2TeF|j;H*AwHKS~D-WB- z+~j4bTcHl=w`8PjSC6o{P@)Wx`uQBU%;@v=mOR2#c4;yhL$MD+U(Zm)K~YtTk9dYZ z)6Xs9=)fE7?G&0p8maTYc9VN%u4;eOEmLl%5abR;|T|_&k=O1HR z<{j6J=EL52NMNfRnsT^I7}wJ5NHcLs8=3Q=BVehMlGvPMX&lF9;nEemB2it#`RU}Fk2Qtev4n8YeW$VQqK!!({_X&~)K8nwHyiDOG4jEHY%YXIUP$$1^ zY)f^iLXQ$b#W2$QuH8uETB|1OzSqm%3Ez43Ot&s#pD1WV=iBUX^aAGUbZl)$)v<9~ zYKKV`U8KSa+t=(+EsOPJfTfWh{FQS3_7ku0ZjitOVoFOmci$*-2jI<9O`TX{&y5 z^h@VG+SHl-t8;Q5`$?w6X4yvxUmtQZ3-O7zn|WV;#p9PU!;Q?TkdKrXVbS)%BxXr{ zGI$ied$-mtDxcRcCO0r!`##;?-=G|Vq{3;W#0>rh+6G(ePacItd&}+EiW-Rx(N*O`Z0ma7Qq58E{L6qf20zQNI8Pn!&e{Z z^k>7TrhC(#n;2b+?7M|29)2TI1!wm*OoOMV!BTb1G%cQM#j$M;=}=ckBWgBY&3dub;z!D9UuDhu6N`s*7l~~9N^JSuVTYR ztvb&O{~VLJ5xZ+VXPo5Vq!7u*+8csqf#qSK-T3(15zXz1`AhH%vXt+j7Vpx(*Mgw7 z-C0!?mW;niI|&~Nt;&FMRY`Wf#}l;>p`3#gkjr=f!ZK=s-&E>VATN>k`G(#yD23q~qFHQ5EFV{#AC|i*Ay`*LWpzyc z#=V;CmS{Z9f&gY1aOwa9HtVCje2qo|SMqdll(~!SU_KImKf`5GF0;XuI7p_bMfc$x zn$#q{j5t{tF|GFOwQbCJITB*My;#j^(Ynt5mS`L=g<%`7&qNcq4{z0?bIxGv81?sk zN0AI8HHlf8nYpvarIHy+LB6*O*GvY+TxMiZklbXCD)pE_p>oLZMJbCcwJcme zD;g}Vc|^9V>LoWFnwO_D50yz1+3$6{8~kkpez;Ut(93}o=o$TRS4(8m$jnh=!zIkF zac`%pw~8WOyELUhK2+KA#&pwroT~;!#$_8peBCIyLP5pP*JUiiv_3o1vh7GR+H^>B zCY;9Lx4_ z%X@72NWf3#g{!duGZaWOtu|2>ip}(&xP$)&XHZ}FKRnU!1;s6@6xq4e3;=`{S{A%<|}BjxC(S z(>&GgxkxaNQqs%xs7=8QeVq`mr2NhEz>(ufdtw{!3HG()&%`|U>-|2BSWEMWp5|Sb z;a#d9jeiMYRn~{V`#sWfTq$JEC!W_7$jXSn20Hf&G@I(}j$}9xcARBHmk4dik)lNBqfj2pC+`PAnH?(CD8 zXRYYgFPrE@ts3=*jT+ElfrJmA+R^Bs2`u^tmx|_jml-CpT!QA0J$rxY9&$hZu%?ce=nhYvKCGHAZ@?X)T9tl<{;lhX>OtZ6W-INTsOF8AU@Xd$(%)G9 zNV}QjxKu+Wk^Kwx_^6acW>!XKpe;qmV}(cmhZHy5vH>q_*VFb(Q>}J5C&Ik-{tZz{ zY0}y_@Mc!?yCwQfpwbp2fd|W`9%zl{KFL*nFB{zdK)13@kO0yJ`rt}m{-EH&H8gS5 zm>VJ)I(;F>*#X&lMxX8K86E9J>MB$KN0Vx1(db}Jro6)bQ`n)Blxm$HW9C`QyZo_P zih(nO3C~O7YX4W1eeiR0j)&5qOyAv)ffQ?7d$ekV8kA8?q(YO4a^$BcQU=>;Zhkmj zW@qYR>|YHxO&zDyQV-HHJ!HPed45n3UNDt%%X>)|yz(w%(j2M!Qk|atoA_b#r(+ex+cL!c zY9doR1q@fsv9(`Egb!hl>9R-4_x8E}Q@Z}E8(e)syh1govN7VDs4Te3r?a(XG88Jw zd5FFVl=O}uAZn$0R%*MOw0%BOC6X4)D+VjJOf6%C%j}4i_Qbhk%sQTQG@ixvm(G&% zO>h1AOpMM~j`{u1uOhwnj5=Sf7bYBL0tK>IN?;NGLc;(qyhWHJk>Lv~fliXgIioqOo*iQuE#nu>xwTF&B?1x|<`P zv5KWeC~}snVa?fPNdE(P2Alc-sgV1bboV8Hc*q`W*`|wpSbw@~e^8knRZ|DAw=ZS6 zsK`nd`ig6vSG|I8&ye*m8fYk|j6=?`_P!ENzUQP6&+=YTeN!c-yG4mdH5sL3$00VE zU_7WOso@@;Zg0;e)Mnd+!aAFQ1f?LsFWX8OxO(A6s0A|Xm-@fS z#arZj@SKoVwtDTkmLlfBp7G(4ZKW)|*Yt%Cg!aURZJKG<5kif2gDH6t`)a+XJmoFg zsZRxen4iRmx2J@o3`1%veIivXztquQ$#fR+_jm6~J%8mBO_ORLKc4pI?^BUve-L}_ zLb7O+v6knY){7BplUVmPrOgrkZwk>21O+h*m*8N4L)1M8<8!*$y-`c9Uz~e5EQeU3 zFK7Uuyf`>%)YZ}|M%>UFiKkt{&)}+<&byrcvjd||PDJDP{VBF{!%lCR9TbM#YCyc? zE45oE!&yG*cshotfe*;Y1POy9R+KM*sydT^XFI)ukUNl}Fml^G+iJtfaJ)2g4KIwFE1pZfZ7Ax_OtPW?ij zMSNwqu&Y>_#JlMMmJBgI>`_+BBa<@7VGGe0;*MdJbF_bea{1KTk9#9jqiCj&o&vM` z*6ZAeoqbuvbcyV!?zZDsHJ`@9ohH^58yDA?#Td@)dv_y>KpvM7-0L@l7H6w)BA( zV_A{IbsUfw)t)J4@%^FXwfc13Z-S921zg9XU*`tH&>QQS5%0w?XgQ7tit|qMeFv@H zD>sJiLYNCrV~tWc zYF+~^Nx7l&jZk^r5pVikpCE~rQDQ5*@ky&LkFEZ1>s>(XdA27VEC@kBrzs5rL=9gD=-b5Lz z>V*n1#eYA-|4{HK^VP(<59P`$X#g$WPI#eSR=&z+knRe3P#dSKUZUWV53l6s<`R(8 z0n#2$smm?p*QG!p@6%hM%;|=vAU$s z=M&we;H#fWOq~50q`j?;ahjxZ?-IZJtLYuId@;F>7qyRx*ok%4IDOG7)^>yCPDJsj z|0XO)qyI@d%cH94!AHM7{?#R+3F@DUMI)RE6HNkzXEHw-J>otZTY3qKe*sZrL_UtDw3`dS^Wqpfpq2j+nnpDy4~nd#8076*SF4_Hv#ky*+7`(5%BfrveQn8-nD>GaDBi4^J0D|DH+M{-EBj-GGPB;$AE z_R!HJ#S3Wor#q+Ri70ASyOtx}l1^1~JsF@tRZTgIXKM3b9bXil#aK5knyTIp`lL2y zJI1e(_0CU_H(-%L`9LwxZ_@pDdt-GzUcpuK?^n$%aYuT$CP7BG)B(krgbf`DtiLgx zsIE=rSf!WZ2PfuqXEzB_J70wRhOG0VJYvu6b5$UY4XUu#w8u9k*#mLxqbFa4aprfa zBs$`d&0)>?NgS}>vsWZT2L6M>hAB4^l}jANp>$bYZ`-Wy+8KT`uG1jD&})vRWt+~# zoP9f6<6UJR*oY0X=CK{Lu{Eod>@6*-wWk6?-=5;0B$6S3b5nwA<%Gj?OXthRnzjuG zbYGgApO1150+Fx?9fdwJAORHE&&h2(jH^-~nU5zaYj7Bw+`E|IqEE{*j!3h}a8KXC zjaD|+(=5k4BI3H5mAo6&axAzGH@9G^RyPC=41x8Oe;~N`Nef=1mdK46s9Wm@QZa~7~^@;+Sc|RKR>Lw2yGQi50db$`o!P)lqRw+dYj0#t1RF+36 zm2KTq_LJbZD;FL?Wr4+!W)S#T3n7ca%)7w~l)SB=HAQ(jF?}-XXDd=U5&S~F6ApB) z02do*Eaz5WY#N)e=m{xWekSc{ZkeLcF+1BQbyYZZu@(!N$y;`b=slMSO*tz0Hl>9& zdls~LS6LgpC%M~zbs0+brrkgbT6`(zwP;@&-9u4CTtr zv((U-so0r0tH=<%)H{9M!~T`oqdXnA$K;z=DgYi_*`R&&Y{jgO2zImnvd7bUcKnb< zri{w~a3WGzv(otax|Z8r4)cRYK=c24$3ZNIPV!&M8t=r0E_UG{24MvsjoUlbQb9GV zmVbaz^{Sbed>5xH-5K5J=fyT~6Uy{;CK4p2o~K{%Cv~St!+u~zN6W8qX6(}W*|2oX zqU8J~`xq})BLuRbaSI4pPz56ZsdK>hvLo;$I1ke*u^bX9nm{q&?+m40O||<&Un;2; zeH)qQl>d@Qcm=6MoJjoLCI%Jt8Z*lB?PKXsh|_N@DbAS~m+OY2lrJqVPkk~Ve^=vT z`5=#BJ*iA>Tqrr6HwPHtj^ER_M_-d0r=X4mH;Ltv!!V}VtHh1$z%^=}$-@Deo_#;K zMAXW)>z|L(5eE4_+7oSJZYSasqRvBn#S;CcZgiuy*d3%U~&1~rxg;FS-3I!p4%e% zb;t|NqU{am56e=?o9pw7HHm^e0{!NYz83VPx5Fk*R4_OJ^Sbk-PrQ+t13s{#H~><^5~)E5Zq46lfn zk~d8%mzYk{EH+r9oZdgiKPtuh_`-%GCnNuxlyFW)hLOiUn;m?zRAu%j^8@x}XY^N; zh>?xaAr~@dA%6sJ=9oNV=6#cZ2dhh~8m)IxYSd$}{&}nSva@TVC@xh+a`6*E*RRq9 zNt+YUq4D`dvUxfP#l+pW990pi$hs2@T@X5QZk5i}Z1Cy4WP@njM(}u@tenWL*0yi# zp*cfyDjXH95P;8{{(&~3LgO!)2LF3)KL9AEF~&Wl%Dd{$ z=}!f6E3ZEX;NqxWi(eV@a+gQhIw=R`YbId_c&=&t_6`4H;}=1OLodLVsYnb2~%ypMGaLyOI8I6AaG zGQ~XZLQDQKr6Xo|>y)SW9>@wLddZro?DDWx!MpqZ7B3x|jRNZ0jslg4)w}tm*|p_k zc{$69tT;d+?m*0Zif_!?>iZC16L1DXvrVW@6>sR>TB2k;Pp!#6KnaWSKI8F~ZdBm@ znoHQxa<+~jm1Y?H08O+`G8R&0n59md^74D;gtVzXq^cj3hfU!0i8hluHC(?+QaQ-i zQ{`TlN1~i56DrahB7clMo{fH_Z304*@UaFgRIimX5QI3(^Di#l#vD)D={VkEp z!adGP234^pM_*Uwh0`6^|Lvx>)0&kx5!GI)xoDwkQUomjFd-0+mMpPzbsFgOrjlG{ z>QKM^D28Up?-Q(@^s^KE-mINxr{ zQTkfRAJIZK+1_m6%Z9&w@Q%5Q<{3ZxP_7%iaAT8}|HA1~pkd^v2TuzQIKGn!l8$0A zK|tNFgh;rpq*zkqUAy%RlZtd3P>k`)*Gt?j#b*u6-scSFZN{3Vxemru)w>Wn!yeu^Vy&w}^9<0j7(N%8VogPYSW@Tv*=sYHB*meuB;-0u|1sZ>wk8 zj>rnAmM;)d7hKKFt=zrlgUV1N0Z*HE^b!g8zk@iiyC1Z1aL|uH&a8`HXc7cAa~}~S zzo>0uT{{i@wM#yCH6r?dxAu^2Y9{b$Tl#3P%*xle*rAHeJKc!rkrf7KscOWQ;VJo0 z)=A-@f&3-qor^)x%~;Tpj+^naTT<+0=kH|}LfT-ubQWFr>W-%9_lX*Qo$1J%B^|AQ z09)Apxl{gE#2D{S`eF;QGW!gebhlalEal|NKR~Ib(mw#*KL8>?69rYy9FP4UpvwP@ zun8f)R$CiYGs(SGa>5__Y2p@*ZqxX{$&jx#>VV{Jn3^4gO-YbVei+~E)1UY@ocj^e z6NGB6z;(`3To3!s-tN4~2eW}$@^JViQ?PYD{r8Q50|q7DgteMK?>t|dM(q)qaD5`9 z%Eqd7F*R;|FZw%sG~nua@~`%D3QD7xU>wDSQtuVrJ?6VHg1-miJl;}^ZOXT%=nsry zRXKnyu*WW8ViY(nD~Au)$5kU3-pD1k$Z({M!^#W+GsuE;uzi@yl5Cnk0XO1_UQF4Q zO!kmIHgs-LJ`Y!1KWe9oRl-ioyiV!LD=<1`CE1dB9g9=|FSm$%u<;c`CkioL&iLS~ zXw@E9Zkns9NAVmTZJfuZkW$(W$wXp}7ONHhQN!xQq1Vu@i2}=TT4Mllcqz7Jb?Yeh zlZY+vln2OL-B;uwlGae5?%!kZ%m)b6Q~9KN(rk!G&xOH^R{%LNinjUk;sM9xr4;Vd zrAh(w>!|@>JX2sTADcfgbnEOA?}kaOIwF*~G7Am%%9k9|<4w}~R$uf(M=ezQ@Y{s! zY}si_^baNkmdOnRL+jV}jErlVI$BY7MBc6$)prYFrf++$yo8Prv>wsJY`{oJ*PzI$ zVKsB3Q7?hK(zr`S| zVnKxcFSRP;so=8_Yr8HZbB3kk(WpZ@2Dl`jbwOdGzpg}I*c4YlyPbX;73mh#s~j4U z2bF*431j_1Tu|iVHx=h(oBY(lt^jR+W2_{g%orayps z^ue=3Jh57*dEP$d+jwd}BDYEB^vKEE^wgyu6VPh(_U)8u@z50?zc|bVRWCi0OM-~W zP|UM0vMC4N9Fh?rD`9wSo(|f3d|uA2honpTVCezI_{inrED4P@raPw_^h!McGk8zq zm=qn(1*Wt>1jRpqk80aY(p993XcThUzc5ZF@~D|6vg^#uS-D)<=PfiioC34#XHsXC zs}MhX=dw%$^w}Gs7gR%$bgBZlV>*Moa?XHIJK9FyNqRW>p_B0zZ7~XlBz+q0(#M>LR04+Yt(44O{K$AD7P%zQ z&r%l1_@F}w++qD8rKk50x&+pfY}%dQallRB+4{@T-?{By%3wq9yFCQ-5XQ~feUU=w z1V~%SAml{*NMSc+TwE;ihFJX-YH%W8bGb9YhH$zxtto+sQBqnTuAX30Uhhbo@=upv zxQ5*%ukM0GG}JJ)d*12cr$`RNo*H^RY z)Iy0bgqh3m(cVg*eJFxEMbRdG65DmOJ12>(aP=JP?Wl*iLJDvrFv2=Xm%B*Orj<9( zUep-Eb0B_Z!x{uI)keQZkrq7AmvXAAsAnHs1JzaP=AFOebhT$+htXEslIK%~h)y1{ zC=A1xi(m|ZI;L}ciPd`-(1^=!pjHpx+a)W&wejN?JNQG%A76M|Ijj&Q?zY8rzDr6) zm@+_HqIc1E3C7RDuV&+#Y=4Ldm-%%Ngmd&#x)+Mmp=IEz0xOJgF3*aW`|almUGn{I zGSS{x1P)_UWxZ6n3YW5p+O3#SopvbqwZNNPxlt8rEM{q>obu9Q-#=#%)sGgJ50#rt zHDVbJOXz-o58if&!;x^=|0{#JST-@Lw{QP`FU>RvGJPDwzPF$L&F~ZRJHjcm$}vt% z3V~_YVjF93K%f;?TH0fE!?J3Qj};C^CchQugtl0KoOMvk%#2s#ydDB%1hMz@CeW)o zQXwcvA~ge=n;e9%aN8^Gx@5O4y<~she!l41awsMcsQ@3{sxrT75OdAjcaK1vWaY7B z*MT9IOo!{7#H9>Oh_olwHl9Kc5y1gL`hi0*WGAsK-^#V4o z&+oe&Z8|nidENRKT(#DRv+8pt^V_7mkdo;o4+vbx#N4Eja~K>->IpA@$K@eg-Cykp zo-5|!DFa7lvJ2w#b_EbjEdBjtV3$F;6KB*dcz@7D@5Zh(zC0kNovl#g8+Mnpeq2@D zYM05r@hOgb@|!Rv->_xg*B(-R8&{=6LT;&?IT59dr%fWt&J^RH(;-_m3xs60YS(rA zJRW1X7WS^vY$8+}^K4%IQ{(}2K`K$Tkx>9Ov`NM|b$a`>4{nX=^t)_R>oS7hM>TkO z*Dd3Y%_sw~HHHDENxaU&F%BpE)Og)y-3}&_7zvDm#=_iw*R>q~8OK8cs{ha9_VhkWW{)ic*&H6H_r@*iu}|8YclO=b(S zl8cp0i!^x8|I}Jcqz=sIIx6tcCE`Y!SXZPUG-B{8yLU~;wJRf^KgqMj$NyGlGDVk` z^EKT1f?h}B^9Utn#G+F- z-c>mj%ZB4k<>r~K=dUD9_VLK5Qxu*2&{e}5EtIDceA~C}+UXP4JTciu~8WJ#smpnQp$_}AZ;T%Z&La!lTsBu6QtiJCARR=qb> zY-uH##%Lo2^m3CHno9n=qAtAn!fa9Q2;Z3Ru%M<$TeD*pREfb6d|Z`Rc>h2p3#V67oB1H z(-6BN>#DM7Xfe%W8i|!7r&?m-Yqd6#M?9XcBNAH*}K+x;-?unC~+@w_VKr(XTAE3#m7`l$B%F{6}4nmh@#iXEqD*F`! z({!j-R!duAF37%L-(yn>Z#uc|gIxyN*LaF+1z_&mS^m6W3ZW+8?_b>&xsJ^>`Zhh{ zp#n=$0W9x|HYxg?fW~;5r5@x>U$BahlD>YeT^x?g^;LFdlAU@7(}|C^2qSR&h=#*g zm?^n5S?T(mg%I?|4!^pOGb}8HTZn{suJRBJO@orxvJmf;CNMlZysNO_4F}F19m;E@ zktWx5mCy=Y&fLWWwu$RGAj}30oL7LfFdh?tu*7v(DLZ|ZMYI)={mA_%=sDa~(!j*i zu~ZpLO%*BAFaA+oGyivT!{DC~t%H*+z*;xbl zwZ6MVs(H?tYBz;OP~A4@RsMYX!ARQQ`QuFCdYV-7tE+)5-|WHj0+Xf@4H-=3MzcQr z63<4VB{SME4QN+F=NQkIwzap0Ud-XTS>+2HYh|tNhMT&YN$!9HLCs4QpDYKRJ zhjM}Ta80Y>;X!AEtCAy;Njzu3fe=Z{YzVk>WyP$@>TdJ(Jk;MQst*=dH!Xq<|mOHPI_JQ zH%u3oYO+=myS1#1d=y0B(7A~u}ng@@@)z=NXhn>W=BQNmNir%~n#mZ8|c z<*#u6_k@rCS_J;*4Jc3;7$a)*zS#VgrK)LF zC~cbQ*Dp&wvw$C-wIoQEanOf4{K^^pLV=WHkPj2#A!}-2fI`TY<}3B%N(fPSa7T1Q z4L3oza_j*NaB8kjVJgya$bc>vtrth=582ZX)QxJxb=y40+kud`W%bRFR=1r7jusk& zQ*+jEsG3i3YlF&2n0XUfv|PmPO~9cpn;d2`pT*?M7i1!}9RyI5Xe;=AzKVXcLGh7X z1ce&;IqVD{zQIllV-}w*V2y74tJ;K$Q#oxdnne(Fg zOzf|w#>T1C{;s`xoGJRmaY$J!$UwGE`JG{}W}hSod)EO0qKH2Ns0o3r!@+^62MI#URd3=4K?lHgAy9}Pzq0PuzA0}7zPt_{yLzql1p99R_KX^V2)G~V|_?=ZR+20y>1$bjv zFyjfevyQ3rS~A*|s%5Kdy%uP~!3<*!VxyyDlQ_gn5mU6*UlOesYL?IB5!VtHr?FE> z7JePxgc#v2RFhL9;$-qGNKIA+qYnX)}iTu5ESE zG{cs3+rAtvjV8ZA4YKsXlf0h<(S#7u{;g^Sm}u7wYehPnICt@A771r1gAD9U%T-79 zG{(kvGQ31JHELvOO$V1V-x!SWY6)IM*L{12P)d{crsKv}W5xmC5tYY>lEz{le0bX4 zMyz{i>=^AH^eIHZr}6#(Z%ai-ByP4XJ6_gvl358sz6y z%Uq&?XX$SN9f5A_ zmw#&6GzREp9m=|=4jCY<442}9rPk`>+Dh-^!^2O4#-2#cOH+Lt)``y56BpgFt|GyF`IWk#x;gd*9*4Xxol z4OoyIw@8Ubd1m=w(n*CH+Q*=VLBDPTr3FzGATX#zk&H z*YtvrB(M1Oks2Xui>kr$Bp7ZIC{yJTIk0!MmTuwH8=l)fs9MW|tEyK?(mDR?Z)#s7 zj&8KeZ)V0G3zWkasowlg=F2E8P)a2+Jn4fYvnDvOkGs$b4cBU5B+ZAZAPMaXtb0st zn>JZcC#l~Z2b(X))7ro$AR2PM7Gcy z3&iC0+&uXR<0xy+{JLn#*C3*Etauoo_20Iu2x<=8mFepw)8$WcVfAtQA03VTPy-#L zrK$OXrf3OX3T5`sRAT;2XM3aB`r5oqT|6V@ozwcx$~eiNYKx=$zKX1c_V>iz?e@4# zFWpi;u#in~u7cJBqT?$1eiQldUM^Is+5UNoMj^z5*` zx-7nR!8SL_12kfaYXs7k8XLdB925HkE&`JlwbGv@Wt+xZe-{h^HNS-kavuM9w*?d@ zx%iu$7%4^>%`q@aqcn(hTeov^RKlgMoAOTLilE^r2NDYu^$s%wf)vIgto#++92Q4w zY4P&kW;rML$CvaaN$b7m3g25xxd9samAv0y!x#ENK$U02Aq$Py;wf~^jofknxIQOh zSYZwEoS9Y!%>JQ``3i$|xx!yRaK{STiG()hl&k1MU>6gl@Jb3uvn976uy>gtt_t2M zzW#u`MgoV}-^)JR=e3InMW5YjOa~|$!b}*I5dtbq=MJwO51TIfTnSFPNev#)x?de9 zc3o8j?B^PJEEp8&A%KcIDJra~UUXw&VFx@mIH%cM$GF&%iE%QTZ@h8ZVfBG1GNTB8 z+1>Gvhk$`#C*pb|T0aKTH zjS!b-$C{8IsLZ_b*9cBxX?3v@g7J0>Cu+CxQnlQuCdJegW2Lw<36jYH&PTb0**CJQ zX11|(+;xXV^N0TS`MQ0=<#3hhLxH25+)VSaLi*r61RWc2H3hIv>ngUQQN3Ugkp;mT zr1y{`Xo1GUICB92Qk599fpzX;azB49!ZD!#2aUfEg#yzPK869TBS#Cg z>a>B5?mXlHl(R)Y0KsTFAn<%`Un{vcCHkvS?9--SZ`3e=8!j1>fEQ?IGZCIr?DDuuoi!X+_g@`n0eHih}?s#QzHEMUh1jMD1AB=8&cB>kJl34`L;>f4^BoDLsY5ZZ) z6F?Vst+XGyfqs$5zi>S+F#GmN)i5!wM0f#rsD_W!jobbMXZ49lIP6L8yM z##}LhU-M^}+ayW3lCoMRheu|a=h#`@5>|{hxY2H=6ZUS7i_B07~Gs{Lu>MfAl3sOf6pHVzgEkr z;GF`6{{UvS60HBq_%xGt&}&=&52rNIEXGC;&5Ygm+DV)$6&Z33mjC6mquMxopz* zMg-MrS4u^4l;B0%6^u5ulhQy_<>kS|KU5mDvsoRIczr}!Gs^n7ej0paKbUE+D=s3= zTh6aL~? z{LRGInymq{fiR2Y_*pu%9jl@E+zLl`JlB?Dj8c!uAdfuZwI>VgMw=)q-12P`_d)2y&mymmZIRjjAdFqg#c}lZeQq`L zWYNkwl4vuERyDRdl^E0?$@V1LdOREkwTPBZfe@WJ#+WX$jshc`lEP#2k((sMTyAJeQk9wP(>W zp#Qtk_rJTh=*G||i?Uw>P1GnwT?eDyC)zb0mQKC)5qVv45Dtx*G7c_=l6Fo7m70?) zS?J68sTphX33#Qey_jKQhc}CR00k(fp_r%~#b$5lEZP1gEw`9p<=Y-<2CYz5F(}i2 z_8u~Gf)g!1Z1>!5kGMeLMDZ~chKDM&#BaGM)R5tk)Q|m1;A5_{hI_kPjXyFbS41IF zj((BCj2p09#?R068L@t|@>-p|K1AN6nb4LulSnclsZom$E0{=^hI}j0As{PRn3U-8kVR4Ws#Idbx}Ce<$|`2p^ADokW+;|%0p&e z)CRqOBvQu>u2cCQ>uPnJMgHgT>}SKrCe&&F2e?oAY&aK6k!@0vrevP&ysK*`s-i!V zY7J7;^9iJ9I*jr_3xG<}r?~mAv_@;UA#-w+S>(qalN~k?7)qLyqF3Y$pv~@m zAkH+dailoL|6~_)VE8)Y)ZnW`v;iqLq(FYJWUgT7hhO`g4?z=E85}Bm@WL;ZO zV)z%a2xQJ^x4=sNl|Bzdgjo&a+(7tOaS!&KMFi*G%f7i)Bd}+66o_xOG>7I*A~94T z8-^(ojIN!e(f|ff#TR35N>s_VeE2a)bS36b_@?g(&3K%vuW8mVBE6gMGEs11=##Q$ z%}WpV`os!NvCEv)qPqR36=l`46%{J9LFL;V{WHy8Ss@a7IZW>dM?=mH7iqyah9VeO z-MVe2XGKMhnBlB^C7#@N6Tg)M_!_fJ$$< zUCF3-GQl#z@*g0%;&ilXw&}X5;{=LoJ-nP>I)YvGcShATgtp{YJX%Rr^wSgc8M zm`X=~w&`m&wdm?)@a=U$Fy7|yT%DT^8KDbRYLJ2Tb#_)-PM1?GIiEx$Yb9vv^RHG~ zf2X*&?GVEvMdJ@vaL#Eb+`l9`F8y%M2GY}%t(i}yNZsgm4QOGNhpAh*2lq>`@eHd} z-lRt4DcYyfodAl(UkRMO^$xPUBx7SWET5M+))`+Hs(@}2tAdo42MX?uU$YpRp#4<1 z?DoD_q#o()#J3Ky`p?qC!eKR^bA%xNK~abR=c>szlJ1<@S&k7Xs(d;9y0C9?v8l?5 z_CM57=Oy{qv%INSaVn_!zsV+plZv}R``P^b@)OIh{YGw~K&=T}8+bOy1p|UKq{H@n zT|Za}oP4paDoCw}dNxeOzKlWfJc^+TzWey#M^wJPe1o!=dr>K30+pM!x3^H>8mbEU zn@abBB7DL6JrApG!h1`piM8&~1rI63SR$-BEx;vR>W&Pv5xq;ouP%(ztO&LWLDqD^ zkE~hBzJ;&Byx?A@y?0ES(KO*h$b`TP(Zq~whV;YPo->ACSC+4)VPBU@-$z)hWcUM| zKQXmrbM#i9Su@mH)9!JW%e?EOP-$;gv{KMiAN!h9b|2oMWK{SJR zGtYTIy@n~3sxDmT_}RJ)zl9w;uXyzXGIf6Hvz~p($a7zC!go@4;og!^;36wz`Lo;L z;6p_u(A)wO{H3O{dfue(|FWhPtH*;bYs43s=iAsFW%N_nPASeBN=csDR^ZvW^2ENq z)2_pmEO8koTl5{6eu%{6R zEPt}j1OrcFKkv)ARhcy<#_p;gGGx)KxcL}9axy#JnMW)3iO=Rpb?NZ#iZs5>@ukg^ z59IDl8eo=_UN*CjO`1CG^)^^GJ?qU*D9-a9EheoVQI?ns8s0OkJ(JphF%9VwdAV7Fmo~p(8Vn zkHlc*Zhd@)QTlPu)@1J(x1Hj{#zLxMijRwm3XvV}D#m!`&rO*7)N`$f=WP-TQ!zM; z^MspVmAK*IhRPx!?z~)S%5HQbh2FtMQaQ$N_|$%t+Js&^5bvOPj|?F4UIhK8`rpKD z{%@7D|KBgc`?r{_Ky#*W4gf4cmzrPQyr!?et&S);leZ{gntfC#9dtN=hkLGo)O zAAo<$06FB*|58x@`_X@D)c;Y?(9qHTQ&3U=^8)=p1r-eg105atL`VNmC;!z0@+wqx zG-Rv)uEpr8?>{ObkKAwMS?2C{QxQrG_~nAkXI=onbIs3>^I z1{y@j2FL+1FfcID(J-)3u~3ks12Bj&8L&v+VUx;en&ObXf%x;qeCkkiH4SMsxo+$YdyE_p( zqx8-~HR+t~E2jea8@XOoB_Iio7^*7`N_H&9@D-|RNby>@mpA8)>rLy{e2bXbCT4cE zbYiqhbVc;8f9-eTe2!GnScJ6SZxgX}1okH-JvMSiYLS~4kgfZa^23MHB6%CIdKKzg zggK2awVZ>Jp6Jx~5YQ$V%Z1=iP7!-sLFe!B<2roqowbJU4fogr>l?3E2$ZoP|FPB2 zQ8BrG!yFZ~bPp)b-U5nHt+(Q#BysC+KO)=|jeaY$4I5%@o-I4Q3vjx)3a#3&84m#$ z>g6%0#gD%X#uNW$!NycdYmr@1#N_RzHQPv~Y3&{NUISHqOe>PJPty(vyKwb^}fqi?8Qd zal^h@_tT$}ATf$KB-Aw|)h>q~Kb~Ou>U`ZsVMUDVo4X}YAqy;g00UQE9_?#Z+{?kz z20j8#AX4=Cj0=ZmqSs8B{mXlLFYCG?v=|-nG|CD2e`M{Eyq3g-$`T)UXccH zz(NHgZ*($Z9;>;>oR2>!um!9eCUlsCFP8p{%Cp-zOUCu%bk&6}Yk`NuLj2s5d+;l;rB@3?9KJ z|D{lJEYvl!2(kZd3vQcb!Ex$sC}p#|*dS}5`R2eV(j6}&7HeI1*kL7@#9(i|s)^tt zi1jc`4dEdsZro)MFRLgNbgD^@P7z5hTsC@RizAofB|nhUksF?7aW0GuS2XxTMW^YY zL+q@zHQN?=mt#&SV%n;IO{L26lS@3*E+LCi3YW;M{}M@ZgJt} zS3^^6z-0}Xx#a3A6$WFQd%s~YjHLEOD{(+}LNHj%`EHI>TRJ4CK@`J-`V@llCViCXgUChp_qczvG60(*BnKY}|rYgx1 zcYosUaVfM^1ZjiTipx{ONhP#;^o6rRt&b_-rXio!C%dQAj|N>6iFNoT;@g7S+FP`0 z>}N=X!8`#=xEnC>{(>!-5a;}-GEQm{lF{6sDpZ7*EwLW{=;2Q|5@}L35epHO=qg{! z-PEGrpC4q?ctxfw`_t~bS8}PgPfZqXk)_=HGK4*_d-9Po%)y9`#_@|?xx|?!1+z2v z#(TomgbbY2_yg2q9(1rsm)Q|vp_tJ)SlUec(!ontvG3nTxrk`9K{w^ z7bgN-7kIC*&}xlgNQ2Ev@WRiZ?`8ogko}kOMi6NNEAqsWK1G`Yg11?${wzu1H(?%My3tc<>=c4yT zKJ~5=fnYE`|2H#6YjsxZA4Qh={yU^GxFG(;XeJHp21dXa+Wkbi{cTXI=?4w^ekUT;Sf^=zqfSW0J){0iuM{UO{XQ`_|8h7mR^v*QxFHv==h^SPAk zY|*t4US3{nuj?5OBaV8~yYM)$9(k>szmgI zz4u~`R?(>99hLv4+T9oY{>5!k2#8le^}E3GESsHqJq|pQ3FXtkOL#l$DX*HW2#q?! zQBx9g-`>6RF-(G2mgWBGisgfj{G#69SBGk?z9HHdRu+qk31XQiTYJx6f9ua6?LtR{ zh5n~wa7G|y;DZwT5aw8zqIQ9`Z%9E)r-1}7|6^fq%*nn%>Jbw!oGIO2W^W~HIDM}u zl*V*ib}0BQy&km19zobP$=Cq>(LiIYjH@R%Ysy>=+Km;N6s_ zV4>iU1cav+_T|RnPvx?7*_hr2=nn?lBxIzm7fNDj{R4dNj-S4Asn!=!vBBz6#>JYr z2XUQf9DTyulj-*rFN8L12o@{N`QxJSThdC}{KEzkpCC9%RJkY**Om$qeMC*A*6$oYuq)ccTW^OoGZFqdH|Rl5i3f z4nqfK9QEif8y2dsX*yHW&}voJRkw!GdNnJIg@n9f{sVMN_FWAubbB&E`W+IEA~sPc zri3-#>`;>IS~d}7*^rIE86rqy!QbBUv3q`#9wXb?c)np!`R1I#3$|dg?F?Kc4D?J8 zoE~no+ofapO>nJRC}h4;X&gMXW^!;k(x!VPs1UD^pl~s8A=2=?xt`^;-yQC?^66Nv z7oQR##Py=?$d=T@QEvC6j|v5#;)K7N=FU(noXak@ws1>e*s>?t0rtptZqc1aJ~f&W zzo2ccIhO$orP9C!hW?G@w#PSP-HBU=(X?_ zpKT-4RG()0KUlHte2LCN!&<$!zJ_niW7ewv1N>Og*y6e_6Uq}XNeQwtaj0G!!j^R+ z31Yy3%zt)KvQA2ML4roV>fo~v;!o*q@F)1AYr~mTO=f~8Bx=P-IJDQWRBtldUB}L& zkAeRWKT$CHD;4`(af{sp4zMZCE_j~mNw+Poz0YLydDw)sr|#RrJK>0d6GdCF_@@&T z-E?6)Vp_9)6`#X0^dw7p+%~-&^}NFp5)kWBn3UA z5;hu{S9l$D^>wTj14)VernFus%^bBQAGEQUP9-(!`bgO{ES|XDkW%8eFXK1z=G4ap z-wf@TNnURsmqSHE0Qvd`wjJ?|4HuXynX{}M>- zgS_TrVKFZrZ!5GlRRrJi>Z30rg(-WG4i4vA6%I?Em+Woin}7&1G;_yVg{o-;&285_ zgO~+C^dCS=RsGW<70sWX_IG|l1IZH)Goi+1V@8ZzxYD4`J0I_X)l^&0OBFVhi-Kmf zEKWbjowkI_Ye(iBecs{cNWT+p$dQ-|eM>bIxq;Zd^%a<|%Rr<{+_+*%di?`<`Wng9 zx=Gw&_w#2FWg?z)e=0Ov2(9~94Rw1z@!$DeEBAh*$y5P$oxj~p{pvYBNAj7KnZ+B% z0o&ibC@3r?7G!g-y|@tUT6dV}xo#7~hcKw#E@(;ynfHub&kzE?rB40UTFcL5-`g%%B&hB5&rmaWK>4u)~xcasFd7~KNfli!t~8k>`hkcx^vvm_INmzcLq3BrCG&^f=LUR3K2tbt=&E&C#7c75r;7qzS~KLgmAt=dNTFf2lcG z>9*`W$9_d?p7F6c-`q41mc>3_eJ#EKl=$;b>32S=+S*S=uZG&qij12~X_ndnCWUAOVt*r=Q}hbRTRF z7JXVo&nvEbQBcsQd724fqN}bM&1`y3l*!O^^2=Gn!p0ravgztvehn|{XEvpOs5v7AdCjm5=9wc_ebHjI|k`;$p3v5cNueedG};AgEWR1qcu z^b65jDI<7Hrs2Aw0*Ba*l6V=KRG!auN_B}IH&7fbB z)J6rWfMS<`9%=Y45w26NEypamBN4QA%J`deCU(LBe1vj43NnY-g9oXR_PJLkf_R$8oUlyh3f@O-ltj?z1; z3%V1Q4evWvXf7s95I-yd($9jX@0qfbq{y!E}t%YOo@%@R=GBO+ixeO}yslldp z3JuOb8+?SSowdkwRyHh}xeRfM)(v_k;(Sm7E5&;4l-4E%tjhAw$fyu!!Z%AP>orvhT<$X0Zdl6SnBL-L)$$1_i<<=8f5pB<9RPG1oSFsiCpkAW-d$Pv8mE>_M2 zmU4BUfJrNbE9hheX6x7(92$0H!ERPvYlM!;HF^Yg)NC6!G1cGNXbN9*$y6^gG!Qo! zf9`!m-~tsrA4Y~(Tt0zj+&VkSmd47%zpbqZ6RnCWT1YKT|2(gYK`pT8T9w_aFY6qI zu23wW)6#U`Qp?Wzgg@ZBTHky>(;ewt8>4UJp&n@a0@Gno)HNj+$UHMd4R45H{;3*Dp|8Oxd`=Dl(FbsoDWh8;?-{)! zdD}KGn-4!YVu|8Cls=(3x^_L5nCV0fQ?hjX^7VWC0;+?^FbA&pO@y)V$fv0dHa2qi z!-*m!FVFl(GOFV4*PqiUqo0}EU-Ll&Fr7qU_jG@bZiizi1-6fW%Cmj$PKd=4%GS7~ zOY+qrZ8bIfsKxXpC?H#jDzha@pBOqM zai*vR<=Wj+(m9^`5+g;|qp$g&Yk>{-GFO+xL1kuln4Y=V%ZkUp%wFC{ zsy3=l1#mxOG>%>R3d!#??3L^1P$v?nw!xK4_vaez`OWcYImcSza|IP5A;UMj9(#M# zJ-sevw(cp@InvwZ&~5!iw_lYWM(9=|6L6+|qYE5%^vp0C{!}k?szPQuO%0kp7Kd;{ zThNkYj{7*s)7{4!x6Sg++UAE)GFWs3?wzOAcOJ?KV=HKIJTkpQXp{}!LyipaA3$Am z%Mo8~x_drqKG?YU=cw!B*O6~EWsE~;KX)$aG_a2POVXCPuk=?e;#8Fvr}C8aEqC+L zV)|BRaNH9MM`>Yazfexex*FpoK9NSmF*i8M3{(W0GNCucH6RYzu&{Il z&Hyby)^9lYXYX zz%IfLdXckL3J{N3-B&Va#$8Uah`gqn;|3CK(0|#_mL%H~B9dlnSt2l1TKh2%IgP6I z+TkohmE?L>oG){D$*9;QNEWR_&O(ojPX7m3zfTRrXD%xj)wQ)YEHNS}bs4gHLOh>s zhY{OXZ6o;N^M(nRhIO*usVzO|2Q9k=%+usQaO>X{7TV)|U0ZAnnfZMhOU&FrLdY@7 zLx&f3cBa7&42Xv_7+s$ehNi}Zq(C5l2&OWTxVxCIC_A4@*azAxcDzjW2T*q2M&rk6M!Nq9oG& zaw92}vh&h$Ft8J8fGnR!S|I;lX2`e+%ZVD>D9P#5nR_9>be_7=z`Qp`X6udneM0^b z1$QcNjdPvu%{K;VhQ4=4oI^I~NLI{`v9YqB?Bzxa1**D83t)@cMu|rTMs9}1kjx=E zb49WzcruM*Uz9Rp+tHya3(G~6i`s6R|1rLft6vWCDf2XSiij+JCatG*$Um7G(fDhr zv4LU2o$Z6-L-29Q;@12?SgKpiD~l*JLci5W;TOc_&1+o5BW28N%mXb$5!AOTJJ)PZ zOe(SPG8GSXaYv0{GvNt-g##}u)Te~C2^xO8%5V7Gm|@edBhUlC-hEK=?wZ4`hgaGB zOP_n^pD~xM`vRfKquUXf?srr@ZRCs7!J>wK-kcnX-=@x!-qRwSzpoiIZ(T9^oNy2iwG0O($XJGHLUl55mgJ2YuFSk0v-cAhVV#pfCwr z`jg&l^2QDBlFqCegJjS->Bnz_rxNZhy=JnS@xkJFfnOX+vrG!n=2F#(ysUnw;i(sp z)ed^2J<7Kd!6IFht`_FlYQHOmfUF(&;wO{!WVUnbzO*oC84KfE^FT&3)UDN1|CF4} zg&?zDaRmdE6nXdF=eqDvy~$ByZo&rFI-}^*iH41NEjuwa&_RaE&>e!{(_`}#N58Ez zj(nGtoW&{9iTE5zPO)MtMox>V-i>}OmZqRUv2T=`j3$%;Ao}(&)td_jG+h1t$r{N; znB_W!0k0>bY|=u%?NNWiNsmkL59P(G_?!WKDiZtB_EvW3=W)JMjhUa<7{HhJlEJ~M`nKR9pWCXiT@rP+jYzFHp)>sr`4q0@RjaooFyRDkk zCB4u;?+`1RA8j6%wUj$m!lF*CHGb>^2Es5!x*YAEvrBc0iG8mPrc!dSOuoPN)ZPDzu$L~ma#Cz+qKATJ1Il`ZgQ1y zUmPxF`<>H+kl_*`JY$?MU;?iVDyF+{2h$6H(4iFkg98#N?aOmpq-z;F{Prnij z&fp;ZMY&tzI`K3kI9F$Fkhr>_E7hNAaJAdz!vVkT7OD}@>G$KJ!+t+R3 zM%-7S3a3_#6&lu+J?$gmvY*)j;8C1Dj$9kQNR)n_S;9oqxhW2AXXnHvQmQ6-FR%WoDzl{T(xsW$L({a-gWPA-3 zt=aRv&&~5sy(mOs@=s5{uE6*ZNv-W?+HS)m5eo&{LA20HJjfvc9MzESjjo;f$a^pKh_?0Yv#=GBDV35 z7%qF4bQPijrxb?>LEAtuGZGQl$S1AmZ(l?xY`$!lL;QGohNq!6!W5Ve@=Kyl4lIkG z@@es+?Am@CpWr)vp1XWqmx%lGTT`)A_g|`V&R`~JQU)4&B#bA~l)X!~DLDfZTy8f4 z9;PmF>0f0V6vFfVeH12$hul&e@d#9s1?MP(w1WX4kPIOF59TTXL2+%6Q~jn(BvC0V z4l{KmC4>>>WDwh)Dmv&R~J}7#?4?ji@ zgQy1!NU|JnkCl|}KY-hv@krD9Y!4seK{E&^M>rC#d~)u@LGtF22O6s}Bu}QBRMY$a z)SrSAsuvwZ<1ekJn_Z`&9fx>NV-Z~8eU^SFQ)RF`-J!ojfoWSG`kL&oir`QeB>_|Q#ceJHd8AMInH4iu}{+8vrw{z zlveGgITF)q>*ePjFyqkPDDTkScr-HRU4M4Se06>lLFv2fv)O^-!u}p3a~(kij(P{3 z#SZ1RtT$@d;caZ|iz=#EGm_Y%vH2ioR<&BzmzPhl+E%HzWVOUmdeyf0BSDy^d(68( zB7w8Hfy*s_@wj;A6-At0+%wJK%@on;rtA?N6(>SOVfEyrUHnJP_}vqHKH_YGCe+(e zKW@cuyNM5$t|p!h^5HuAvJTCJOI-AZl}3k7hl$K4W8Bo=7wv;*jC0?wB-Zr#ipub? z@4FkaLO)o$h+Dj)lbc69E!46xJhdHmbZCWD2zzBjy zoUTu}o%efL@|9P1_O3&c@THs0la+kS7)f@sIxL$ez9FDJK{K4xk9vq{|KVA{9~${8 zZEMIVSz~F4fw@~7dbD{}z?ENm+oS>>LYXJa6vMt^OyJ;srz9W|8y8|VjB`CdFg>w>|C3_rSE=b}ZMZ-|VzQI^S>8MS4x z4-uP59qn8%gzq!#PR5aGI3=t%7aH53e%*v^!qFOhvOoT2b;q9xW4)at*)n6R#@tT^ z%;9PL=2-bUH}h3D9aSV8a**ybQzt0Vx-m!HLS|`CJ;cvoueAiSK#zOqvPLUBheV!C z!x{cORl^N6s_lzq0H-v&On2@ZkBCAWd)mW+@F^zo0BHP@h`Mp}(|1byrMw`@_-`(J zUyXF*)j-r-QU3sE+w-R-6142MpLA__zmle?)#%(@bCu1cb)u6t_(G13V$_Suu)I%p zObmXdO%6xj#ibKUcEpVIr;bh6>?A6yR1CQMi9m1F-n^hn)#yIHOyWPKit9KFkyi^Z zOjp!lk^S3nwV~q^sFizwom1f1EkRj!y2Twe_~~fUumxcvg$|(*x{gn4 zd$;U7%2~-HzOu7%yX^Na(&5O^mFHXj=UAB6ou1%9&rg=Yd2vT!m0qzAjYom5%?#Kk zV({<8!je>xcZ76OiDI;rOO0_3kVK`}on96I9E`x4XCJyc%eR35C|YrEl2Ij?(`VTX zlC`L2tVGDjM{x#qao*+~MJ;{RzF{s4DlN+1-ax0LlQ>xV_RX#7m~Z8`gJ5;s*cmyC z@a1z|^=a#CWNue{3psW?2NBkZ&%cVWPVmfpk0y?oO=B!*`0e}4wT1T!9UMO=ptyM(i=P8$ew&cr`1|{eEvL_heUyH zL>di~9)A$iSoT`s$nph7-ubp#&j_z_X^ifrY9C)4zx-g4yQh%Jp?oJUu4wRaxaMOB z@Fy<7-C;!i%|o}3%oi8ci3YL3cty{UAqDY?6bh+VbM@CpA6SE9htN@F&tKhXa_@bdxav*txH2NPLb744hymx2>UK%Cr&+Tj6x+8d40fNhke76S|JQB@2{KOm6P+B{$V9or6W{RXlx#XHVHKSpnDXo zZ7@)!NLLVqLgoKaE2!aOStCo%udEJkeOH+ac*0F4pd2;VItZ%GU7CAMz{0+#_mS1N zwWQgDhN{QE3P-P2A~@edZy)ScV=S<{_ouMJakasuR8QokZCl%;+ZnUGi=C3CI}?p;|l)md89gye~l9Lki z^%I#M1~*$THwwtEf_UMJ`W2-Q6<6nSEhUOMbI3R5S(3 zJ@wg!uNGp=;}P=r6i;*Mgm%oQq$?Uo=!m}#^sZcS^L^b1iPJL z%V<4MN_zetuSH}4p)eDXqsP{XdYP3;cK0isI41SE)Qj`7!Z(6sM~+~4n}m(!EJi{S zTz+O4MUHW8==C0(`lu>*3Bt#sX@oNxBD(9f+}yv0;zOrvs2o}!&6yV!^=&s6Z42f6 z~ax zVP}M)lPC-Kue&&m)16JDa=JT$wj(-GSSOOTHbE+#YshTWd~bvwQGvtCdM>bhnls5` z^QjzLh-#;uU8bTsHP?FLdtZE4?HN(T@3vLMjX9e#bzgik_1_m@Ev`A!`VQv0?5dA{C8t^Q-KN$&Qw7>&22erCk;Qc z13RKfcb11aNR+vbQv$i5C5Li^=78k(9c#oSO~|GJL*>;V=fI9MC~nnq^vidi+dexH zaX`I+A!lC$lT&1HS!>asI^ex?Dw*S_iD`kXcE@LSN~2IvNE)N~H~Tu?AfsmaWw|?L=27*E})D|^% zmBj8`3arcCAE}C8P(tvtQ8RVV;%;$kOh+@usr)726_zUYS0jI@aS5RR00FcTnsqi2 z1Ay1e76aBS1Hyo7r0v)x*~d8)R!KLmHjwtdyqq#tGVf7ZM$*N%XX|JEnn~-26H?`7 z*Y6>jW(C_(gG2O1p0i$`(aOdJmq=1}O~g<-jxNgn0r;FONY61m6H*%j_FWHl#h_LW zS-}RI9>4AMh&#KVj<_IHHTfRGyVk)8JNZS|f9H(bhkwTsG65=~&6;tS6Gz<*W#t?7 z!@Q8~$gO&C?oGikq2K~wD@9vW#%ZdM4S~o2pZ&aVd6Vc=a{EbGLu!}W<*!G~aMBII z2?s$3PhXqZjceyWmUNlwL1{7o zx2IX;%oT-U9-t^wdH%VZ4y|;&S^4zG%#9F`;kPI!X(AA%Mtm}PO)jzwIwo;sMkkb~ zGRUfl&TOeHc?e5838hfDjb4 zqnJl27X=4WF`9{535Ep?ns51uWSC(x6wg1)kKVIjmFn#o*?^m3x4LL9D5-nI>_y#E z%~y<$193lk@W=*CAAq!Fmu*w>{kQ8EuM1%*Z8{<=Sv&z@MV8d3YkmQZmUGl}S(b*S zqXG3ve3+Urju}cj&l+hihLwRqN#O%yi8wZB9L1V|_rFd33H7|O=SI%!2ky^$R}>evLm z>TRbGBT|aKdM~iWKblyGD^tK$Y)8VGkUorUs=^}Nsmub`&xuu9nKdb3L_4nh62QlC zqAAXraPPk4z5N0-0bZ*B*%F ztM9d>T`9*h8{cVi>wEb0TU0i6&V9x$#y=F$wiryWSy@z_zA_({8A^*)AQa-eUeT-X z3EkJed9n3j;n(C_*O-}?s(Pd;u|)?l5KDvu(>}#Vz15#j$6UqkjTO2xpOkMQTizJxXpx|dBhfe^KmBApx|H9tM>fa zQ$r^C@I$RJyYQx0V#Q6vp$nln*DNi=e`f+PeVICgZ@kljnxOFZCepVSfr4 zAN?N=wHj@^-K`7 zF!P2p%S9yx$B-#c1kDVq+!}axA!LxtX0)))*JOT2vskq&@}ig+Vl(hgOMgh1VtvQ= zF#UOSH3e;|j8$+YnOfG-;NeTG`X+D<#nlBkD&BS1PNL{`fk@eOz&p7YUF&&1Ua~~Q ztwtNM#VYKh4Uo(AAvla-a(p@GFSJPvo#DSIU(V;2R)Lf5PI7vyVS~<0P)`3F=#F@+ z`cysYW__(?XPkdL+_`wPo&-m?i;-nGwmBK}kYhm7uG`;(h4G#_WK-a^8m(=W=FbiH z#LopGB}52ft)nsBHj^()RG*Y&(}B>@@}IP@*}I6|Yr)YV#3LY~L9l18;x4pTOrn`A zxo~B>&wxm0utCwiBi{4rnph&cMc=xG3zQyi;QpfRYiq*UOQ^)2xwdmmjh-6wEPS&T z_Q&a0Nw-#WydMn!r9<`Exy$91?eD3i^H(3@>!5U70g5^6b7c#dq+;d-iNz+x1>wnu zo1$#)8U0G&K?8CD;`IE>W8eGy`B!D-#AEavzVNO9@xvG8G=+xon+Dv}z0{99R{Prr zdiAGM7~S#A!qBaF<%y{Z$Yfn9`g;X_vTrUG@fk%cT6K*%kJ3)wMhCz_YWbQ9SR#ug zeItg8|5G9?AOm*0M)&ifui zQRG<=%iSlTqDSV(Cl{aL^Qx32e&Sq#PjF&5Bjo4&=8xmT4*FOEk(wQ;&!Pcs7)yLS z{3r)eMHUtak3t7{9CnlerwJI|2q83>})mq)sA-i()AIE ztj2ws3ri6c_hG_7kMAV)cdQ|Z3KSyE!p3y}G)r+qz+QO9m;R5a^eTKKd4xlyq`BDHgWmQHdifgFA$aM*rBcRChhE77Qhj zmZ6IDm^J3_{Q$(4D-R{g8I}<#i~AuY_%JxE3<^=P@GEAz8Yz$ogNwDW~d5qTTg!Q&~|}jRh3%XjmFWgO&?zrA;3bhm^(Y> zj1vdjT3(P^pVC5l&#!f}Tir{`E*zH3?62ty=>unocf4(0OCMUT@yEAp-pxvUdy)R) zuAHvr(+w!u#?!koX;!d4e1_0%I3aR}I64s{-EcFltlXRwf%drZaNRq zI;xOOYoFsvv#u8$O6XoQTs^Esm}9)COH?iRm(I9^W)x|EQB$uaNK=h7$|*nT&kxvO z+XdkWcU|;bSLRr~9w*$_^&(lTteX{IjN#P7)u5AN&#qQ_8z6n?Is2ZK*gsW<9fzaO z%kH9##kZY&EBsa3F56bqS;l{hXg>~C zimaDys)P&|qU-@S@~Od})9ZXwQ{yRJ=&%cWK-!yGg*4GHH<{5yR3Z^y@0L3&N%Ft> zHc3V?h-+#$8GfCo--&D$7uaY#e?%vl(p_NfAPj9^|3273q}-xHfynV8UdWg~i5ewU~!3I*mIGiJJ*IF5|E0?+sbb88~?gp6$zDN}w>X z4T&RqD3kD_1%I({Hzu8LpA&J==2*=JPHgbeVdR@t+}{et(t2j;Fl5BpF%QmNuKoiM z?`!O{QpML~9U1$%Qg1F9PRG(f(%F>3t*~t>RJVuvt8$YEk^@Vl(|T;>ZyY=VbzfXi zl+XUg8JFG2{yGRQJmz$x&aY3_JG&b1IjTe`XoWF1X^^`}kV|feB9u31!|eIrWkIrG z0)92HzxeGPiDKD);$w{N9$!_9dnn|oBYY}BnI<44GSc*j@bI5UlXNfS?#_h}R>Q~M zc?Xs144rPVpI5`Ok}&w61&+w9RmjH=k8&`QW|BO{``o3H_^%2rJ%?j++HqCol56?H zUmSo%xMyZ!mm~Wj_M3*6u!K7#qLK#w6<^{MkhS_3qE{CAI~z9kw&OjqbT51GrUxQlj@$+m;2@2t=e=kK*@ zeOnUB8pB*%)DRE`B}4G8QI`tKmXunSmTKzFQB*I;P$;c ze&ImkWFTj>%H4ovQ}N`bW@Qa@>ho~UWB8hBU_GSXmS6?29y*-(vY^Mi>1@3a=;52I z8dWt0R(TD*^N^A#angU7*xaXBhFgniS1zdcO;em*lqFiXxq0VheaAn@|Cz=X?pAAX z?^7F5I-PB+NDlgFg@0Fx>Wy4`DYE~G9m_3FfaGv_Oz#1Oo#n-^;w)T|| zwp=bK-4CixcX^)u@m>EjS24R8G>c$EoGq%6Yr1h44Wo=Mc$fTW^!`sebDmj9%2ReX1<$}PFTM!!a#n+=_u z=AsMM78@fpJ*v;vuw-07nTp5>dm+ZaikXRTXCoRZIFw_D)JkX-sTNO8P@XXgLUBS{uN(SqtF;s<${=?cH)R zqwZxQh*H_DnUrt`R*yPCq};P`87RCeGCm3GcGoy*I7l!R*fJk*SwU1fNsBqmd*l9o zH-c*7xJ$7PjhxYY0CIh_Zl_(dWMyvn+6#&=56Y(}k-Wx#!Z+l7f#hvM%Y3h1a+49@ zCrw~`*>UpSR?cnY(wYLNsbe@B>3K}7kk^Gv?|;+)SLU%%OmJ*l6T)h3RD!S{s_Ax| zvI|-;RWa`+K9&>5a2@W4PlbE9QFZAR9ljV_7cJgNXsSp&XQ8KSZ=WIU!aP(WEs`hS z1hNfmOPe?n&g?ar_^CxO66-I|B|^w>wJx4~oui|DIXyC}fQ`Um1y6T9LJDJ%A7!`Q zSPw1x+>m4>WfM~KpFSgg{9(N;o{f-F%guQeY=7~2nPMe~R%=r3y}(oE>?i}P6$T?M zIx6UUnULcsIU`BhDw)r|v@|*fOdf=b+hb~k7{vJOKjsTw%`V+mha5%C0jBg{O7hqk z3R^NEI3McvY{j!P&P3j|KjMO_};l50Emk|x%mgE{4GEe;5IipeXEG%qG3;~k8+bEZT!3?b&(oO zrfC40i2ENQRpi2LKkUx!Br*k@e}_R9DLeEgW)i4C%D6sZ<(+H_p3!?l)Ei$cfh!iN zfyKXTYE(nGDuPzCPU2FD%@lrV)_v$L6YmjXsuPvVB5(zrI#f(-i&??(4lp6Kq|{O# zw`YK(EtxaDsK6lQaAmdzouqSaiodAhT6QNQZmJVMKqS*+%_~ep^`(M~)?7`v&LuWo z=n3hv3fk&@Gp5XJ__=HIZ6+t9+aj@KIZ@F>YJ zNrUlg%4m!X1L@=Y-pJp6-cwYl?J#8sjiK%QlJV(CJlFJvx%&c#8vWDX%x8;oKZ(?P z#oN8AfJLM)2Tj#Eekk9R>p#Hs-Tgd-Ch>~l`|U@Iy5W_t8il%~XN53S^$pv22lJb7 z<7p7Lrg;jpHGaI%=QlEFQg=1R6E|LyKc)@j!=f2UzSg1)J7)9ZNX6b$R&`-hBqH;X zsotU({w;_d0aq`{8d{^&GC3=u0rYYmaW2SjS}TrIp&Sk7Og7mdsHRF3xK6DJsG*{< z&2^nf&9X^Fi0HhZfAc)!D~NDH>%=Wmy+o0_*(d&8e|2NA*X z;ZjcOUeO%K)rgf|?_rU0aV%L@2`8|PW>9S?0A`qmsrc+**b%IMXO7K8HyB1}5MvfziEjD;4{-sNkqog>C1G7$lyhgNsUR)dXhTyd^?vJQxZ zaJ?b(vVT-t>e(R^#BuAljg~dAMzVg$+AeO5mYe zX%Bx-55>_@!&J(Uin$|c;}QB#k|L$oD_Q9u5cvR_8 zw|%BG^d*eDM(^`qbl)hVrKqj@i|e=4Img)g%ElY+N*tJwp`C#OdC5-R0jz+{)S@T)*?0c{En6~%!~8hxxb)z5h=$im z@Jv`(9@Bt|KbzUFTBl%hbPVuq{>%XbL#>0qf4nyaROTdg)=!^%>^6vHWrd1^U21RV z`F-i8z-A2}Z#CAi$8n=_-5HB;@Pfcyi@yr-u&SAJ_YJCn$I ze_iy@MEB5d;GIFQWt?kGTEhL>el$5rCoWJ&8LiBq)=~MQI4EJRgrNS^2GV|bvmdOL z8!qpPA2qvT>8*cG2h@?#?R3XSFw>np%@hZ?(iSv*Zw8&mc_(dd*1$yr-T}O&UCz43 zRNbsB;~9eKc7a-(kLxEI$vwf}|B!vSi;LT>mugdWuu7=q;m!B`nkIUS3w%?E7Q{_j zKnn;)Z%=&T;Fo`WkBnWCobysY{rs)aM&CS(&^9I6bd53Y^Y$@P7!&fGi_sAW8gDpS z{sTNj-E?(wR#&xqLai>zdj}c_)qS^bVjxL22B&GWqFz9om$!o^0%PTCb@&sPou30d zozI29!M>+&ZdxL+udVOc>lgVwgJT@9@ct5CYBD1oT#9S{V!uWG&Q38s32(IO{|3`QEWbObxZA>uOL5aF4{Q5WnXIkEHjj0UF{v{Y zN{$Fi47{#g%DHd?i2(F_rx2-knM;3=wQ<(A8#ATA3u$fJt*y6m2*x>GaAceepRQN* zjWBfdw7i3l^AJC^X}bdvWi?Gm)Q|@&v=jZ=_$ayK6o#bnFI=uVkf_aSIWZ%a`Fpb4 z3oN6T8)KCN7~2(z;WR@tRjlKfCy)*Na!p`045uaCF0$NLGmqb+UUt z!}qO9wPPU32^)F}tx_}>1oEuhpB34cv1dW@!?#XbB$-bkL43dKUPs}P`rEU+6eQcM z_ULE;24W#61DA3EKZ!NWx3Skjh#FT)VVo(>=#WQ3kO(K|pZ7J>@Bj<}fHnYh6=a9q zR9r#Z)09`kj2!gwue6@k7iR3%8@0{F1SS+09SSFx3gsau?;?_^kT7PLv=v?@@TBgfes46F9a~@rfrvCsk zYHdBM+-_CQ?>kPxm`k@Qs$tGml1egp@J8ccufCv>#RQ>BCjbhk)=DIr!D^TdFSF4C zbt?y`E(Z0n@O^(@TKXg(9MF{n+cc*4t-AH~uZCBz<4NCnAZ&bm4IcDQQcvsUNfBZC>|Ui3 zWssnAj2~K4K%0=A_C0slR<;s`M*cOQx6Hu+k-v_2q+Z*F+;6k8TN&p$nhF>>9cu*Z z8#d4=wB~AoM;oi((Er1o6|57FjbC(%N+!DYb_agMvsP{{TvpUd$SW z$!v== zw;p)*!FU$CptAJ%?+Qx*Eao|-f?NSWSn6qt`C-Lr0&j$DbXz}8x%K# z;(ilWN*X3pjq56&)z!M70Jn|aNQY~RXOBGsQG%0T=`u1CGF8ijW#@}Z%^OQ=vd zIoKBpv%i&feZ)tVA4Td1P;jKdJf}GRV1FEA>s)jDOs)#M&$}sV3QG~xfDU%%%8$!n zKJ!-05A%heNOxBYb5_N4@hLZg%si zb1~DtBhI5XnSr$ccB@7X>&C6o)cmTgQg6iiRa&RGTv=FI?xKn)q%FmCtFiuI`O=;V z>F6mg$J)>9#+1-bKHw{tUfCt$8ZEWMwFK%oInLyPkNinL(x$hw!=DT#ZITdAfX?Uo z{xu1j1z|dd4s*JSMm=h1dp^2Af&du-Cw=-K{{ZBD^xTdrMl+?9+;COgz;y~Bq(j>u z_>+p`W82Q4uV`Ma0Oym2dR;j0d%!=ysN)~Y*X;V|#=8{YqlB{3d=|mx9tQ(&%ki!& zy|*%3f7)Hz4U{EmR2UjME4;u2sYgU<*MUy`IbKNL8-urrx@jQBg$|t1QhFQAG$v6j4GGy6iV(e(~BjN=R?I_j?tV^>&}$^JltUrd$+q;1SK= zO=Im4F`dc6RW}xSsg&DAxe_A=^?Ud9y%oaJnN6zKc)f+GL0Jh;?xwS`+@}MglMsD_ zBMWw{*ILOkR)_8OXj(;xf-+of@7~fJn70e1SwTWe3s4(paga_%E4MSYe0;;jjbnem`EvpP(;-S@>&f-_a90GoV zndfZ2BsHM8Q*#~oW%T~}9q*K3H-yT)Y*R|uc8#Y@l?%5VvLr~&5 z6{I0Vl@z3aK+lQE`I>>mYC6OxSXC*ht79$2a`D=$h);13i#O@2eNM)=$XsTLI~5bm zuT6(2$n~b5dX^(bP|ga0r8UN5vt-JhC0x%-khw1?l5(Y}sb7h$PpR$&MZguZM}epY z-S4?txebO8!N6H-4M{w#tsz}b`0=e-Ip4LuX<2)cR_eF;Z`P1gUC%fDKSrb&00PPu zR}x8Bi4N{}{eHhX!Mv_z;PlS^m3blFyZ*mlontf2lj}}fpanJ};>zhN<D;BA6GD#f9FH{Zbc8oNsTkIYw{%ciTob$VB{ zt0R7+ty%Lc&Z{=RAEB;$lAu^C?od;YxcJo~F|q#utyDqC$CZ6jdA@b#e``b?GgieO zBd&5ht2Y2-q=CPUVhAIxWv!%|XJ3-7{IZh{_L< z8;Y}<-T~X`ib^AAT{(C=s|b|*0A&2?Mf)j9!Y#cv3EU^8N17YUXFX2hpPyv)smEb5 zoRtTH0Pz?&%{+ozN|O@YNRVjA1k~UFnDEMRaYo?9^MfYtH8)7;6I{GC40D9*8 zvL&fU_efeYqO=o@$=rUv`stg6F@4uX+R@^q^MCfI6=q=tfU1tr8$37l!Fl53u?vU# zf#nbZjmeYHc>e%O;|tmmeP%uy=Zaub)y*nGyxv#;0FkH-s($rOO4Wl4LO)y=wz_=-UNfFcXlP}G>I-s? za9r@~Q!Cl^as`Z)eAoh&})WwP<}&db4T^ix!JMsf@$T++{e3@Z(Q_BzvcR z@~|6iNS7@oWP!|4owrQ9= zT#N4!YhgJ?Z~+Rz<*s zno5H%Ivzxg4K~WeiwmAU?p_1AUG{Tm>L89h70d;My2j)X2q(K-{{UB8y5ew!6Wok*^=rVqIt`|L|e0_U~d_$F| z;>r&)#I;D8q`A$2l^#Ux=6CVgCa2HZvD+fk!`&xv)6lMsso1P7p6#c1apeM%1`g*t z40#IUV)?A6>bu3;QC;6I$e#M-x>T~Tl5$dje1O`iOs;ipQO_i=CGtBm)Z*;_9;)64<=D}_GV+JH*b)7nd%+_If2 z8T(iyZ}-<|zR^8M)xSwDBBZv`o3@^0lZ7XnnO~6=!ar*LO3b}qdsA-nC8r!uFi;^x zsMXhJni&h_Jc_JI)_7`)-Z9(<_^hkXJN4^Kz^k1~S^jkuedL;O++n?kosh~DGUCcM z>%UrWDH$MD7ayEURzNE0hDKQcy1Hwp&{bOSfq|bo7IC+qT7gq7_d@he0X~!@;>)IsTF)#SvBgTyXPc5#>}JWp3K`sQ zoMXn2QV}WX?DhOe?yTU3;-qJx&oIyDTuFOhuaWf!w2QSo=*|}#jjS!UC8)e45bdu{ z*{zQ!m=lgyA~>F2smCb*f-AQ!&1|jfOY-`mMWz8eB$Z)D_3K;-_UzPe>fYMjt+fO4 z6DUvZA+1D5klGtZyECY+3`9T(+X!K%P!35vxhhd5M)$ChlUX#pn{P5dB~;r<2eQK- zHxuMP%4&2`MQN)%MHEp&5k(YGgj1;CHMmC7`j+&fg(~TKV$jg!0meioOYZzx$qsw- zJ8go%JLF-j)9}#nTek4qL_=-WIJYe>U8MydggG)x&!+>KKw+h@ow1%mN+TGARu<)`h^kfRnMj?!Cn0PCvAI3Vwp90TYoA8Ih?*3*cXcUyez;G=eW zSI3An2Hc)&m7d-Gpfx`j__cM0nGQc|wa-{rBgJjH=_jxL5PtP~QyH6hb|M2E+lWd> zDvv24N9S8w@isD-HtR3=(&RX~4!Y{Oiq^7JrF}`J$N83-4d>BjOWu8Hyacz zkKQ*}X{*6FJ06speMM>@dHpLbCPEx12L%0U%ex1m@TVc7*D0`ZC1Q(M@FV58s%5k2 zeJd=ceFxKHR8-fe-?6R;vQTKTN^j7Q%DyG6pFft>kS*iPe8mZCKiF&qa7EXu-3@g9 zodsN>to**=R|sp99_k_$7x)DQZI6Dk(I#o$1#z&CA{e9IL zG`4k=v=G^sD+vPJXUvOlZvn}2ksTzFv08$9{cE89#GD=OAlepU?3U1@{4tICb^6o< zX|v0ztcU*q=PZByj{(m zSC-;4&&`fvK>X{KE->GVi(qK*MS zK~!nFc#5tD03JgXNh2ray;n%dA9=1GY%GOz$oP^xg(%{6{dv-TpS7A$MCh$Q~0*N8umKv7ptr; zch~I=!A(u7?R<*>d(=x5$5{Bh5*}^7W4Qp50oyzY){n4pS~`h{;?eOZz+4=U5_Pnt*#AWbi`@r4{A}P7a;%6DHa&(F&L`p)t`)#4b3G&dO zeiu;4XUwYD3BOK8T! zOKDB$TQVJOU?oXk?%2gZj0_y-Anp!xzG^yZQ}n@ysPyfE>j%7YH0vBiwqHR*$;5Wj zq%33YB!ZGgK`A5>Fii_@Br(#{n`OLn?Xb7c$z3)w9-evF4t8!{C;WM;{4tCo>RU6f zl9U^pZn@wHLb-?k0En*8eVZQ8Z70GTC5uX5=0y;@#4D9@14{`3AdbEp{S9&3X0R=* zghw!>r7r`4@PVDbtw<*eVZ@IbD&Bdfz{fFK_wewl6gboAqO?lxFc#E2vSE>3ruK&R zo9MAJZ0#p>%w!-UJ871Zw1kWgLyf$vm>%67uC6>@zqJ|bo6kmaag_6KFPI)()8axm=Xv?k!3uCcfN-&9r1My&St7;L<7i zauP^+wGTA_Rb9g?I3~4J@{@N3kdZj=gIH(g6P@bG=|JZSA1;JeG3U>p<4;)e!$lJK z$l$O0?5L7@`Sh!#J^<_Wr1D?_Ry&`Qz`eH^z(G6`3v|^}+d(UXtQIgTk<({{Uad0;&hbdgtz=cp}AT(zG9! zO{(Q9LB@J`3Qi_L7~ZZCC#L@ZT-Tt2yh>Kq-bPQ;6_#Pvw%_MS)XC|;QCBFIM&VsY zg#_7p0XikiZ!!Qie$<8r-Z=3!uhBe=Wk&;i=C09k@#gEW-+DKKTIFnJq_Liv7|wH9 z_!k>{WOt3Lf947YKZR;$?j#U7x()ZM)ZET6PBGGwdqaU;wdI+o1q$PBbtNcPJOIe6 z3y48kQ-5TPiqo*KMW;u`NBXy=vp00U!6kV(*ylAHH7VZSX;N_3g3Z?iqtiXl{7+`@ zQsRp7+4U+TT1QW^wPnzTm5k?3U`<`3C3`Pk~i??6@8$jZ8>ah%;d3pnM{(o$C)dKpJ@!V zF?*U_eQR;aE5a1vB;cszjP(BX&7T)904`wW!3$8^=4y5QqB_Lf^{vqX?sT$UQBHOQ zoxiV7jylXubILGVt<5;NZ>9^hb`Brg&5;5bAyepSzoUmpB$+oY=X131@ zb+FPGp8Z1w;t<=U(l|O-VY%mnD&eWMVWw#Ny;9#D07g|qEgp{0t zxY=K`-|XSwzYMIlUuw^9D_x4?p!DQ}FS0)dwIpWe$=7$-^B#`QtbW?H<(=j+K#9G>Bne3l_)m@I~@vn>qZjInovsoprU24CsWrJ7oy5QB?$1$BLr6VY| zxeJvV-yMhU3@r^nYHN-GA@-9I`9xO`_?f}(9Ozy+c8<4L?VM895M$|1%RQLw_Qs*` z_p`=`h=-%axH+c7$_crtwj#uc!{6kxu<7SE#t3cga!EOzMpgrz&4?}D9Z*d6i9gyuMor=83v>n7 zOSrHz?W&}<&au_kw7T4>=#UWKB2q7aa;5>%xrOInn*t!nn7rdGrmBe$fm zZdx#9mut?X=+TyD`>ttltUf6SrD<$r?`NxzKjC1#nl(Dl7UZsSs3`8<8?2YLRv-SV-nlE)wny6P0Yx0Ym|Yy<2w8LnS^1O&pq*?|(5a1HcuL z?HsI|8>n<<;2q!P0jJa=iYTeY2#Szy$-0HRu8_NFx0I#J(^pRYfVF%Hi8q?z` zo0e6LzlfcI-BI&fQ-i!lmBUSG2JT&7?n(Hy>R72lTo1!>X)19brAM8WB@ZN{l}hf) zIf7hRHT|cr2Jq>>L%NUKNV zx;G73jOO7NDgqJ!}TH$zpXe6W$9o3pesd7=V zByH1iR?bL~xXOm!c@@xWbqNC_?P9ZT%~(lGsY&wQv5xzz{{UzVpY@Cy!aV!?=PL9& zRjq@n^7X={ao7jbWD$5z+lq7t{;*)ahE~h=wBm=POKfPyLnlqHTQ@%*> zHGGMD-~|M%9}(AjRj-wv=}q4Z5@g`DoQP8x=E@3yJ{^AQ#;!`6IB_aL{{Wa`w))zR z@Z11#{KGYjlVOhdI6_W;)4eX*!aeYrzYJ@?c2=_z(tL6A>s17iu>^eUKQl>yR9Xcm zt_IbBddDfFjI3j)h&1K3F}X5*49s5p^XK{3u_M%d`_?sZCZOz3&~IJ~Gl%jM=hl=G zuz+rmH1Y#$EWnUFI{DR9$;VUmr1?zHf6FK3k}K#J416q{pB!WQSG_Aau6hX%*-Aky zZNE=ZRYbw(pFzDOR4(W2wfGw|KP-_~D7Ic#{JnfiNzHO*kBMEjnq&4-wY!c81zx>sA2J9lt0MOOJI!u0502_=2%+X z_;QtC_4B8}*{6zb=#5Wic+GK^;<%ipPLz#`d^6~3Zw9T6l}!&B8xHI7QTUAv#+laD zewy4E;$4#Sp)BvA?tWIoWn93YvXU!LcFLU+^}_ic?%`5fOQ<0$APk@pk)8T<^r(pJ zk=tWR$B0jXbIuJjP-i0e3DLL!wlTaDN z_7dH}iBb&>qu7G=g%#P-wks-AqK*(_kR!H>7AALYy6?sgzl$>C>=j&BX zuVG{&H)`CKvuB;WLxzX^EkKX7D)$>>(-mmf+7)?Og1baIw^sF43Bbwfe+u=1A zT)DsulB?PV`SPolhEzQ&f(G9+SCPg~*ZWc{rVEvnVK~KPdBQM3=r*eqC?z@c@#rd= z-Rgf|O7h8jtEXi0q@HXKGH@y3b{OEubQ2hS7p9d(FNj zPA6;)OTZq@`hSIdV&Wq<8`bwfaMIgj?C05@&vu7*;l_!&vu%?Z{XqOU?yyxcFUDgb z=G3IT(N^jVC60dej~I1#8TBr%?G4AhM|PIN=Q(z`N}l_&(FQxxkYd~5C1GU}7Pq-l zl#&8hgvwb$TGopBZJ;*8{J=(P;;gahUE>5Q(2uV`oGJr@8HO-v3s)wM% zn?S)&5$k7nau?3tJ@+}C3Y@RRJ)zF7m}E~?yv?$|U>rCO(yuK%MAW=)<86}TeQ+}d zJZqa;b52KBHM37cYTY&TMPVQgWt6m#x0E}_R05Pqz#DzX?RrvEnzsC|=EuqQ9P+cDArB(6dR4slvLvc;v@yjg*B3+~v{wt4qCW4jJ_h;lOE6z+E3 zXgL8#;px6YL$#+6e|7NY@nwr3qE58DF{C3l%g9QX2Hd#!d#kD&uM3c?G82p?NmIEb z01Vv@8Y}A}p^SA&4a0dD7k#u#E z29LCUE9tx{cFjb>{zKrhFImHYkdx+cG6i9zSe_Xu!n|;HrArq$%iF$2`(T_Oy03$% zUf?A__~aUo5=hdY7-4>eYS-=0G*3G!#(MJRv5rD%dnp6gZc|%@ZM3nv2IB+~kyZ~{ z;k}+_(mq3_EZP3>NIs3%>X25PcF>cO+LVHRqO4U4V8-}g&TImwxG;rWJAL<=FD)M!;=B%oa963b zLj$PKrYfkm!cT|ZHmoAAr=ThI#wy)+#|hXIw}Nv=M*eHgmLZ@@aT*dagl8U=P$n`u z40!aUfA5I|^iUrnKMJhf(ZzkfWAg^R=*Z%{=|(^Vwr9Cf7)ko4HI!(^PBt0!MIux&7KgicZ}J zIO)^G8s5=;r5esPt@};gQ(_kq5LShAvTzSY4-cLxiA>ZD$w@=FSXSLDSl`=a^sP;l zoQ{XBT_`r65TTEDo?-_ps$L!GvP^~f;C>izyr#zqy4P<{{U*XtA-8_u4rAeioa6u04Jc>RRt)Vli|GzS5j(% zmT+^^$WWA4uAK8{&-&D`b`9es4h-IHvX;2(gQ@g1%_pf?mZR>9i+YWAwaG4IVE1w6 z$Xaud6h%bx&c{9`wnm-QuGEy=MGoxF0t*$J$CYn~Ak0V8Cna)ZKOE*iAbG@G1t`0!9qqhDq zu%ccGN>rsK3uE8#+M~3$T;)bchLwm^J*)b#Zf%!!f8dd+S7E^{a0e zu(tcQ=hBvAu{!dv-tv~)UN2+xkO)p^8b|)o9ZWgeIYQ1Vy zDQb@aHaLlHe1M~jg{8O*ps77Vzy~Ebg-uzhE?UP^>J3+TdB^U0it!@zHOF34>kE+T zoGA)Bke*IP4B>w;tj^lio*I)4}hSF3zDn5q(`3(d3Ti17+ zoXdU^lk`zVXiAETD58WSiYZ&5EW=Ujy%nd5TUftp+ijSk=F812N|?(SQZhM#=iGRT z;zzb9-6OOBpC#N;nPqHE)Q~*#QaNi=nt7W=k@XV&lErVZx=vD}s1X>4k_ZH3FbM<$ zy=~hK%v{}O8$d19;Ux6~rsP(Kx=2;SP&oeJIVDO+&TxeMC>;kt2Y~5LFNIbmxiTy3 zK|S~J6OrMZ4gQ(>*UyzS;&5uD)Zfgl!iu&?q!iKUwkr61TxBW}R@=%)Ipu4e10!!* z!bs9r*jX{3@A3YZIY{~(eZw^CnA62=Blv&FJUU>0zWT-8H0f!Tyitq;;fjQk%~obG zxLg}1lIz##D&=)AWcXt_@aRA_;9u@-?&C|q{{ZSRK&_p7iWK6&17dtJy&z>Wrj$r0 z%(!IaeoA6eGhlb`A}hDLu#f6Tcy)-Ak0n!jXDn4$O`+9TCkg^;=Y9`kWjp2 zV{uryQZwU?#(eQfn4Htpa$njR zC4{V6rtfKSrI1GBa8uT>vEEZIlq+Hn&o#7UAk9M?o_;l`t+=%ndXt!N4F2?+`$4axK$I>osisOl)n zaFc?rVYPd31=<&uaXoUesg9)(R-&SO4&tr^M4#m!L07H!E5|MsgXg)c=J^IN20ceg zNXedQR>gIN_cZ?ir||y(YW42F^8O#~N(>M5r~d#*ue_xH03v>=0=elDoeo#JPkXPY z;r`X|$Hx4p=hGCV?$44x^ok2(9TI%L5Gd&a^P=H&o9?iBD{rlP9O>!IK9!s(LF$qB zSAxrA;RD<5UY_C!jg;uA1<23xgZA zUIXsb3JBn+lPNf^c}1oIgrfxqQS*=-JDakgs(AcTT? zV|sqa6PQr5Mh1KmdDQamc0M(YUtgtUB(Efa;(mXx_pEA;Ni^qzjd=vwRtF#-F`BB` z!m5gX$gg1FgXKaQt(CzfpU8PtHJ!2NUJ8lv!1Av&F2E$*uL~n==dMmRt%1Vr4S3>@ z5cJ-N)94Og^^Nj9lG2A35W$rx`Ei(tG5Y<3W|tbxeV=17!Q0*Xu^LQN+uhA5ozu7kYfJy%qa^z{vl zjI}+(Gw2oOgwhtCD0aTnTtCxEF6lw5;AyKdOU7a!fom+DeXJd)pf9mM4q)i}!x8ShS&(ir z<3}yMD2Tr7grKB?em5n^Ab>KsiaQjF)pmKfejl-wQ_Mk_G?s&{@?(2_=K^f0SevUW zHl7f`dJ;f9fX&YA_dx>dlm60L$+YOnh7-*#Q~RA45i+MmnK2Ox`|#{`)U>_b_ZIXr zr&(=Hwj?16Q)R}>k>5@mv|Z{v%}Zjj#cDDWVX!stifs%TUiBd<=R=EZk^)+0Del}n z=vv(*4r*^S_hqR)mj{i<-hWv70sjCH3T3o)MyC{b9_w=P)cTS<5k(YLi9n)?D4__g znZemE#Nt+!lFEu6W>d~Iuo6^-2(RFb_=C73anx^$)^)PDIJ6EbaQ%mK-CT84J2S*% zArqZUHJqJ>68ZSNI`52AEJzcFP6oS={*s@zE0-eg_Pq5KcP%o$pP5fvJ^MMd)6;4M0h0gBq=Y1D+k169qL!F zmSsY_K#+!%5h~9bM>7 zwVs7*2?@$_d^W}_Jct=^d^?Tvjg4pE+m!35Wu%g#cTgGSuJ@emf=_e|)vc<|r`%7# zN=L+Y&(rd$i}rkbJ@|pz(#@_@rRFzepKrB0BGS8@e)7?ATWKe_d>nH3pUS-aB_ksQ z({${&*=JL6gHhXJ#^3%QDd{;NO{HhAqYarJ_9DD@T@!9W*sQ%@m1}h#(!o~IKc0%%FFYW?MuU5TiLI) zTf80OHk@L~sg>OR^S8R7^e1CYc~P5^-r(ar%R-fm6d?4$GXbW%4O=*y?0k*KEioA~ z^=A$^gQ(fn@1i+VjYG9+7hx}%L}z5QNdEwpLZXkiS80o9ZO>{)6Zp*3caxw~t;;%g z-op*P*|F)S3ZgZPwvZ&Z1+H}xpW;Ya-yj~i{hd}h_TOQ@Ypa&O_h?!-Q(L%=e$tN! z#TN%7BFq_S9X!=Rpq4e8*Ww5_`4tsDCtUhES>Isy zNE>coiyx1g;LiD{997zERkWe*&MBoNj$9B(Kb2u^mN6D;ln?@09LhgEfTw|`^lLim zZxOF=JeV=9nvQ!>3+;qB>utzdTgV#)V~`Lw$vCIE?85ecP3@`Lb57|8J<+Zo={u`8 zopCNp!3v&~DNdp~ThB6(LrPNc4pN?69(}xLM?9>h2F^D1UAeN;!fRjdi<|ZY%yl0D zxS^tZJHX>?`&6rSk5f-}*K0)7sxsbTq$NsuIou9qB^V%N^9=30db_EnE#(JgIIc$s zT0-)YLF=Cy>i+=tmUy?J_(A^wW?hZ=QEO_~Wzbf5>z=lvmJ(fc9LQ)Wr+fr0)njh( zoDvAGK6}L>2jV*qw0AWad*|V&ba$d7eC{%Lt!|@eRE`~oNkTc8=u(+ zEBw~>vESKwX-kfLM1V4LlUs5PlHqV|F0k6WqMmMVA@i-1?AYwTr~6rP!%6U~R9&63 zMb#Hm0yV_|o<|N6k&r=8^Bj*Vk&kGvv)@(wJ+3xeW0&bVi%j3*nJ{NR1fg+OrwUt+ zr*;b4ak1DOlT0VsTCs)x*cRxI3ytsP)Q-`6DOx?Lr;`xp;-f|QBWV1TPcf*4^-zK4pOD3G6zBk`^9{5pieSJLGaH?L>n6r zobFs)6qx3?5B^fmr~z58z5KEEno#+)MJR(_fPBqYLtyRK%#qTI4oD4uG?p@+=%&1O z*oyn!Ivh@46EAV_UKAu^(bUPc|KFppogC z(zhi#%!ebW5Kyi2;yfw&p_ZQAD6)Z)y_4p`syM!GWoJGWZ(kB}k>y`&huByIm^T+y zP<|hg#e3^s5H`=9RY=N*-&`)6t=F`m4!fVqzASV;9V(@HP{=-;(7gr3-BCF4>FZA3 zCa$qsdm<-9>6r{k)Y{*RVrIQd%}*c z45up?{lhD)(BMfrYx38;1m=y;Yorm3%UnGF06h<3DZJ@hPNC2?h;|5G@Qd!Siyx93 zDJYbb$>mE;B|as5;Chu2zWK=ZuDZ-lqTzQ5RdROgFNZo=yPlwwR=1i&sZFMH$O!9( zkdm%Z;O5>YrrV6(%|1AGdDeP+v`1*04Wi4Y797+!J1lF|d$gT4>}Dh`BQjEw7TH3W zZPMbBu%{Eciq;cc&T)^6Gp~0(G4XCo(FMZx#M@PkqjYxBC8b@5?zq0@Qlz@4V#QOE zLKCqO6jYvGVNR(fIF(CarX+_rHM)xnxHI`d#_J84_$kxB}$mepd8R>#Q${ z)Y`96>ITrJnY`ZQ++#Afkiyt$*OsQ6C`l zsUGQMbdS`MPl_m_itTWUD58WSv$|gBn;xdqx20p2&wYt>R!V@xc@4UA%kh6F^6%wX zDl3o*i6LVDLDI*P)cZI=^P3lo}FA*Z@ zjW1}6s4XFHrUOj-^fdzNxloj(lpGC`02m{sM6U(416tpQdT!?G!;|4dO^)f66}TUS zl(WvVda1-Er;b1R)cyEXd5XkHaUFCgxNR+9`J@3~JId*(rCT2gR1cf~}=_PN$7b*y_>Et=Ny5Ei1P4EW=%W1M9h zj$dCgX;miN`ZIx@`W=m8RR&YeC8pa_+*-L(*dH2+*Z?cR7&(NSq$47*t;bWYCALsh zw-geTq-2tIsRQhv*$Y*1cTn2V`>Ip1-;j(pmQ8-ziS&lp3nw6Z3yz84YsXCdIV#{Lvk|Ia8JAdFi6KS zUc|lwH^rXSJ(9Rjd9=oU%+9BKw2rjqkhdO{5)5^>Z&3>vM|j^V07$`76}rm432ptS zPSCNh{9xhN17XZ@*c>O(AHQyqlHf6ycGQYXhY;KgCmym7J5l z{dcaU{{Ut_$lQ%*#(hAhkflbRBDU!nQgH|^rH3g?^IW(SfEBbjtX0m^92MJ;FTy z07XGh?HKV5ooVe0;x)Q6{rfgsn~W=b_d%qgET{hfONuoC3kQ|W_VCZ&QycB#vDC9$0q2-`sZ-}8-`e*T|Z&CObPI`3k-lnmKIoN}PxCVjT8Z4l&rnR_x1A9-I zQ_<`{(bsFYXpR}lwKh?4V^OAjH^NHP(GI7TK!4{SOxIGswB4Zv%d=*J)*j-*r`j(O z;=Lj|2?!qY*j^4Z$^+*a-vXk8_GkDr{{Rv3e#fb$LqoCj&8fSIanxl6XhD5h&;J0n zkDh94KWKMd*qrR)chGkQwq0u3`@$wvl`XktNn2PS^K!P5K1Y0FtQf_i!{MjyPD znuEf(r^id1#mC4CFVD(TIY=1BH^o|^N@(N^0DLyZC?+$?r2sHfu?J&{!mT(b#2>n| z+2h{p4Hk_{HsRe_h*JW91pPd|Rh@0jjEo%hq!?P6SWqV!@TC+ffk_!4=VRqjaz|x5 z1i<7<&-16LPX2vs*dXpI%`YKdIQ*)rSA&pq<|z;W(L3G>{R-%Owm!9xMpOrh9cvJk zfI-Oh8Q!nieF?_?8&|8%;l*Sc%1-+OS!SLA1Owr}l_p)1d^Q7ms?@xIGuE6_jBP)SZYHFS{hStHXUhv%LPF|f(Y1kuCMqJ*dv5G<4xOdQmirU@?T*E zNNO-~i5$rp03FAVpW5g*u3~!_z)YQSZ*+iE&N+rZ0bR}ZeU8PehB{@z${aTI z><&mIb^EbjMST}h(@#e%v&I}omlw@pUr2RRMLQW2%SRh7X1%MOgZOR2OI!ELGqEA9 z4145u8&5of6f#h(0FmN4`qv{oOt-|g>Ni=4RHP8DVsJBs3~lu_+Ml-dGlum?!uM`}o; zWF&f5y7)E&`;;fce_pkZbd#S`iWg4HH9;sVQ9W_6^r=Voaq&xuoGxRDSDqDdM(@Il)3*y< zzfj)nGv2k{F1C3ImZz=J-$4lrepG950oAmQW|5Z?N@_W5b{R98Tj)SiTiq%9OLXsy z4!9UOSLa##HmB6wJB4!n#dCVzZqpMMT3K+mUPNbNOl&LzpMmySBfyr`=SWr4`&BF8 z2G_TOc|ka#s%1otyK~7tPSxJfUN!Nu&3DijJz=b0)AtbEXKnhQSGlXT8X~0$ONhG7 zQ)zSFoOLd`xWQ^}KfEoWkdPA&9Cezg7TqhSQtlN!4r+O<4t^O=)%bccg#^eG% z$UhT{(w3#)FA*WB!WA}7BuQFJ#jvGi$5c9=QOu*_aA}lrUsguedhYjlw>tZ_R#erW zPnXw%i zOnLoeVCwe(<7uW=0~s-VfnpA6lJ%x2hH$6|+q4PVd$PkC2n#WhcF_wcq>r^TMO9b0 zx!(NpXj~&;f`#5&$Ql~oVRaIo*f=%**)C6M(fhQP-nT#w*xkm}bw|vW*L1(Kcl3^$J zz5@euMJl%a1rVWS;8k%w;_kbfq)R6=l1TPN#sN!fnSt-|a1s%sG=3e?RG8K?Zd#$! zoqy>jPWdET;qYK=Px-Fw?>@!FYk|BMyu8G~e4ufqsDsli6uoFL4lAYhUEarUZ6dBS zQ;kF*Y66`Z|M~MDEeZ*#AiYRDhB}R3e-Hgb2)3uyCh;#7u2M}ModS=)3uz@U(3+2%Ri4XS zqD-qQPIpQP49do9?TE6^hYQwjHbB<+u?A&~h4qFq-8Lban{&5R@!wbU=LOpLspssB zQ$?TMQEZ%;DY9ws-aRgy)k(^}KS9f^A5EW9WqjVs8qd!C~4cUG|+GX`<3}hr*ZM#3C0UXllAFHpa zm0AE7G%>$?p}(nCrBR7{Ey)jFvtnAYHPc7<+toyp6f7t7_HDdVQyh&#TlC$URij@T1HodZQ3a=HNtl=vHu&FFn`AS9@*ZR2S40jbWuy&Z%v zdB86S8@+ML3itDH)Qu8txLHP&?YmaGPg0=)jV&^f@M-m6v$8nGIBDRxz{_vTKb22F zy(IozHDF}?FA7uWrw2$9*>nHF!(r$5y;hdXQ=M#a@&;<`>#ho;`UTM~kIL!8Cm zBeHKmNo!`iWrs>K&nI4Yd5hN`v8x!-0<*dmo@e4!2W#`ksgoLpzC)9E6LSdle|M|T z4a<%o8W(_0Xp@6+#uCXfTuiLD}p}!K6@||4yb0F|)byl9x)ZnP5_y=`#>M zge7ZwqPlXr9*P%`6XBB5GHTqt5wHGFGCzdboFIrCQLs3f>hK>Dx0Cdl$j(W&_L*XN zO=Lm_0r(VMS4Dj?rFA!2^`}Sy4o$VrU2n`xlZavyInpW0wfakP)~XFOwH-V9KBdnL z`URHy=1suz!>rRDBc#79Za+??+X#!ulB*RW*V{Z7KO7L%hLSg0D0Oh^0@t z{A{YJQm8t%(p8BCOZn%i-wZ0|X0b!ndWBllBE(6u$JD6L6<4M2WqQ@`H9rYDf?P%v z+JySR*8;hz$K>-Tft3C4UTkr(D`XxN=UpnF3TcQGgT9>|@DkR0U?JlRx$%dsDA zPXs^u{7^OXCFyd@$>)}$P>7h**yqDHUDahTD?qwj>Gcs8O(=hEb?cvj#qzVwPcY!04GPk2NMJHMB=Y@+=kp5w&j1A=zY%L z{4=aKF_ckjRG;Urf1{@UWa1IS{l45YZId0t9v7vR9ump|g&bDuv2X5qnfeRQ+h{yN zoX#2XZ+&|n;+&iM;%YM#+=DZGIp+Fi3k^Wo>6}ta5Vey~Nx$IUa&Px2NqvLE9}W;G z%peG4!_&MQ)O4hdFXVUpP=Dof++lsR$0Fq3S%aikaaP3l;c-#E={jCjW4s87X!mei zvjce#4U%S6rXZt-xJNh0Aan<>IS76DqjxkS^+742xia|sGZ;@=--V^J(MC`X{{4Xe-aCXM#I-+*z=-~u ztr@8}r)SMYNf_5w)%MBDw1ZaO`TcvTw8uz3m6TESc--Kz6BV+vH@mo*hSt?Iy&aWx zXX!Lg@9Sim)^m032GW_Gzl^yNhpUe&UBlH3_6Q|IP;u4ots#OBV^uD93BgpPkyQYx zu$0!sPpug$(8STixfaD;g1v2^lqcadzs* z``-k&dJgA^L+JHk?}@f;N9v8FBh0=s9#igHCH=4b(-z)bIaju!A~sF50cnqP{d3c* z0(&mvG){2Q zyYdFg1J`*dfbB=b42zuGg!SqQ%o*E{G(6%E!8CB!oi?oVFgRftyh7JpG}(wm ztm?6xZw2S|W}v_!C}TD3qBo1rd&-bL?hVi9XQ65H$OX-XO%oo+L(9I9Kl#Zy89 zw#$```pvvc;6-enpY@;i%Swl}OgHuz@(VXP)>6(f*Y-ijG9>;*Y;lwgF zNW1P-NDquee%*iUr`7~As$EqRz-g5XZHDdDHGDtEYdaKHMi3xqsH>=oG_7!VS3R#i z%dy~V@~oyOD|}}JLP#0@%;Ke#o&Wx~2FNM<9hTUWo^WMma1(n?`{hs=DP#32`Qq_5 z+j4E%3Ra_?}!Hd`$58hUdQWxj*!S7Y}?d2~yPb|E-JWt{q zIb_x?L))=1*7R(1`2lOu&f8B};@XtIh@|k*-LO79$WRWrCB`g_MW$O51iiD?)K=AD zqQOeqyl zgt$pX$6Di?(%Ea5y>9Lc*L!1Xgln(zHAv)dW{%xN6LG1=56sgI0e})-T0?`a ztKmnhvvtG;Ap>+*Cv7c#4fD5k)f+d|vMsDL_QTSQQ-V{`SWYX8rRs;;5-o`|V(o;M z(xwDx2+k|@(KN(wY8MF;-`tKLU+Jd=d|gA zjntX=GvF0fH-)2QqrW9wsvd_YmON55zhBcWq*ZC53)z~&6300Pp|-2D=+suV52`Gx zZ5vN<=pV~)$^x&46s69nxBcIUa`$m>Kx)!$p(7xc`;*|=p!g__ohbiz8cU~7ID`+? zB`RBECc9*z!L76-I0(~5XZGj=lIJ^(*V6@o5&NCc67@S9+I|}ZkU$m)z?6stPzPM^ z9ojdOg>J~{FjG3S|B5T$cURCo^AvdBT9s(@_+4(k$9m z$E++)8&C2~9C}YM6b(D2IpOX|u`e zhjjFa$T#QiLtj7Ov>iT|)({2DLychF>UIUYbKFkUvNO3ha+Vrnr>p|-Y9{Dl3NIFV z1@Quodv_^-d7Z2U^|*P-T;8E%_ZKIe>LeQcu``XIvovvOOKJJ6b;?k{CixRE!~#&E_CuGA9i9n9NZ=AV8*_{W4mK~c@Y)c$W8l+i+?JC1_XQpS3PlfUT&vM8V?E|eOX-{J5Az`q6GaAKX!!hEN5GkOnz8x_sdLJyWT01*A5a} zf$05(O>6O?e0g)MrnYi*-74?mZLDx&3$fox0;1&#&{T8$r;LE1r$f!b=s9^ z3qWNwUaGO-Ya7+Cm$nOPd|8b#W&r%9(2(FxFKl}&>_%mCz==%RZ|{S{yu*w`&+LJT z;^^a-vXh-ITBSmQV+9V-;Hc5`ZYB_4@#HKnsY8NkQ*Y(pXLQ;{NnvGmcBL0CyO)XJ(t@6AZ0iN^kEiX5)EMEi z3aV2}wRw9%9D5Ho?n%6n5e4n{-Z5+G|2)&-UDfr<^FB)*Ahq14KC+%8Fp&nSpz@?b zSsMhqjW`S6KNY7ELJGeHAQ}Jt*9DDb$X$K5G)Ew+W4UJb`H@OxmIn7a_Ezextfcn_iqk99F z?Pj4o+c%;I&HuP2t^4mxT0heeQbi%E`Hoj1YM*Bn2CSSS`GLchY;}!XbkYDvpMBvKNAb%} zzva0L_i%-65y^qTHyf+|+ka&-v2;|g!W(MQ2qqOHKtdUq&2JsH5ivRr?<5d z%Tf8D40Le`_9?v3M_eYFm_7V&b(knM&NQc2-A{NSr`oJj9VLH5Yt|y7EC3zh=h3Pj z3|edSfenZT6}~k!Guv35%C1?pIFlOJv=tfteFb;XT0~Xd&N>Sk+GjcPTyxhjBSgPc zKcLYcd93AEI(>RN_ah!((r#SqN$AiXUtx=(vS2w#7+A|X1i}z_^}gl)@d=aaBpiio zv$u=?qfkSLQOqgkZ%wEs&Uuv)cXgWrU8AK%m-4DZq%v0*>;n4NAhwZ#6zty*_H@>d zm$LqVtWQ4*0;PTi0!>&o#69oTLqZDJ+t(iMcJI91KA#dS?-(@Btu8xhHpLYM6Lg`t zHG)Fz8gz>ro}A6v2tsIAa1npiJAK%0%9y0)0tujCqyhORPLYS7{k4Bu?ma3in z+>WaEeyG}2m|3Y5eqJE30eSb%*~Bv+%oZU)ihC>>LXFy`O?RbdeXFMRhUW5$Y$Gi{ z1uFXQx{V*!W_ESAdMsRf2IuiOtkZUNMk)6NIg88gBWcBmyJ8ZQl)8VDTMw2-wWl;61!Zff0Yp-RDqXD77a z`W4S#yv|{~PxL!OE_lEw=`FPOd*?XIRvxX#_;_}?+0KTFl$}64t~CxrUZ<5FpC`D? z_3_5d)j^2_4-6^qPZE2=hIVX>W7;aqXsqEyZTVcfb#U(iO~*M0^UeKk?+y1ZyeqYv_@9l-ZL$g_I z)(c69K+>@jX{qPRb-MwU6)82QC)+ASPkeU~?tZJ}cmML$IniTWi>tMmWMyS*V!+v{ zoSe?FVGHkQnlLnr&4VnbLxIl3;&M-^=`US#{u)hx}i+ak(+Wb;Tv~Q7_ zZn0)(kd-82!)qv|VJn#Lh3MK!R>-MU)Bg5uu4Gf9+9CegZ}I1c#sA`xM*e zWfATazuv8@*}+g3(4ucH&r^JF3_3uiz5oQLOnr+#3QVa474dx~I#e%TmVrfp z;#C%vG^fmSIa9HZB8~tiNS{)y$JLs?|$B?UQvWY?1{Ku+McrC9_vgKQI<%E ziSW_P^>);qS`WNklikM2+4PXS{x~4^v9=Qcwx$UXeO0gHEA2U>s{APOe8RT0l?u00xCYZ)L;95pYe~o|EhCJz)vWA9qB_iM#wIHvY>gv98!D72o+B5xWXq)WB8++m(lhlf#+o`LV9C)uf8 zKB&~GKxz7yKChePLl9zhgg;eX7R9*j=CVR6c`=Gf&tMf0p^Wqm&>-j+2ZapL>PBD zJmhCHL$Ke!Z3nInMOhy<}t~e2-b*(ec~1wlC1hF*KDa zRR{ucA9O_fylegzO9Pa`Y286lE~MI)>mDqPmf>eeM~||--K-RF2>_+kQs(LOgB-VF z|GAKW=qf4m-$0q3nNey)q3-Rxc1aryOU(LC;N~lAaWUPhAF=ql7dLyY-o=b zBdwvMh$ST9yCWg7#AaowP`7E7R(9%zQQ1)BtX@JtI-8>&7GR=KiDI45t&9v|lbYk1 zUD#27UbXnNQq7lGQTx7{uQ!D(r5Pv}?bR*SvJl9KSn&(UPQWVSMJwc%I8MW zmbl6c%6!;!S{`N50GM^_Kcpj3U!BW;(%&pgvvCVhMAq;2_ecy0D%e+Em#4(dvyh$m_Qii6Dr zLEF?w9zH|WVtptjNx%1NAsJ~FgYcBh)@#YkzZz@o=nKPYJ_-VUYL^}K)hDsZaWL0T z@32`V=x_VoAZ? zkfCFD*-GUTDq=HF7D@G#Y~7*@SB-k`Tu)|5DX70NHc8jFqt8qtCW|&5AhmxL|rnB24m=vOLl!KY4Kg&k2A}PMZMo1yE>ZqE*0O`Y*I! z9wGFnwd_W2NJ|IKr#EM4?pyc7F1w#>V+OttykldSjnkOV7e|>6VEHwHHjt%B^q}hi zkv)@(uHc%s5W@|}SA&gWG73usXt0>AtYVyzd}*Guq<7mu*{S!fu+xDw`A*cpwkNU5CA5I{~JgE!PWMZ(`XR?mgm6myk}~N+#f@ zP3RR{e%)Qx40aru;z9fS=3SulI;G9)e>-;xE^3f3r&`=w^#2{VG*J5 zb5)8#)Fp;`W!VG)kAaU%#fKl?_}WgWi7n?r->R!{7Tiq8SvK^^An*hDw%v5=I$CvB zwkYW=$w%gjM$*PBESNH=Noljq+aL2n`6%WE8-kjlbmdAikI7Nl+B4}Z{wtV+XC5Va z(G`5vCCSAfTl*?Qxf#_!7L)4ZNyOM+_hb!~8^m6XlDb&YODX_v$A`!V;2V%jVJ;Z} zH`ZDtI$eR*mTXOGX>~V(lt(ufvLw)bSY=PJqU}_6v3Br_d!9k+jfC320Qz@eM8d0{6+ra*_%kzI zVm+gwn7#90bZD^1zEXvAPScmMWM;NbQT?3DccCV}Uupw)n zWp%5nv&BpwA;s0Y*)B8z6;5zB$ubi`8`U@_T1*fGD9lqXzO9JoA-ud4mNq$`Q*l;* zEBx>3-P!}m%I&>iWhud4j613A=-UI6;o0GJF@Q;uQh@HE%3@HiPPrFT$H*4Ox0S0I zI&LYhda@FJ#{)%LIAYnph;0_fePVlSIHsuWGS>vvQ|i@&Wo@Z z@3Hsm$Q3TVIcCEO<*MfpLWxK0q73=~8TxEH5w$KCyCODo;d_~S#z<5>c(^`-R@vmX)8$90&vQ8=*HUk)U*9`9S9=UkDIRQYDcQ78 zKG;)PSZ8AmaNaSv9pId@`$bhn>3!x}Rr?QYFN{mockkgUi_6eQ#R9fL^&qUjCto7> z*4ucHnQayh0xf$Q_PRE)Byv)qve0mha>$vgt$#lDz8!t!w{?>r)lFL04ga}6P;N7| z@T2xC7%AH92i9VA*M9#MOxrLGl%XHw04D1Pj#RCq3~>cY@#emM_%MPo*%+(6H!R84 zwjrdHFvo@j97>Qmwm!ZyJGHEAeMqZq_yUW?E6PndYhQ8h#Gp60wHuuK52<&BEw*?# zGe3Vv4W^SWDv#+eEPL(8Tc^H(g%ac3rBhh9nE$2C*D4G8L?5b8XARyPI)mpNU z6p$oqtvZG82!*}HB>1U78nrvy%?c1~&V3qLH}%Gjlll({+y1=&1i!rZ(n?o^g(13Y zF|hOAoy$s4KHO#(Tj4TY_qe%6BzKN9x}(YnXaaYDsMaAXa>@myBupzk32!U%hB;cF ztW+)KQn~p>7pzV%y$GEbEFywq2Q{5PAaCbq3ku|Q&sgbApXopA*(=NLW{ePxCWSDh zux-v31$R%?AYE=MO4R+?AhnhiPWpOq9`nTuq8insJFDkX?$F+t%C-bbD}<=oYTW(3 zQ+BLv{$*) z9`eFOJKXSFw_)^^thLC`ck_C2vu|o}&raPA&ENqv7#WQm!g-b>pBE zg2w-;EJ7B$rVpCBpX>io*7grB#!o2343!wc20lZ1y{%PQ&D7EncnI9perW8*{r(K3 z5<24LqOJqg?{`VFLCsS?;q;O$E+54T&_()&s~#l1#W)u5Sdv_i=qj2$&GedqI;4|G zWq{wX{#2nFRm1(-WLW_m!RRYk)8vIk8o8UXd}LzKJ>0W3?f}^FRc(M(NZdJ{Yw@cme-4`SN^>wWvoz1f32j@44B{KG^Ij(hBQ79wEi}E#p$KmGRZ8pS;8;70rFpbGV?ND#E>+Q>o;7Zi$*Pc6;N)-e zCi^2=G3SfhDr_L*4nO}|a+g8Ak>!+EfxO^eN49#!hhVgz2~6RwO{85DmeK4fxjfZv zjfmyIqo``RTSeV`14_ixcGf@)-s{&?x5H3fR)=hG>;(3LwSiiKFOD8F|7OASaUzgP zdNCw9D;Km@9G{-!Egh>?`x7PqO-%ax$r1Ttwx~`Uu&9j;Kz;Ov97~0lzWtiw!@mmX z5WK7U;~!k)JM+^`GaqTGvB1T9tC*Dh)`@PUXarcpUPbPJlA3a)?BH~$l(d5HvFC}9 zXxyGss+sEt=UchKY^6uz&kY9fb9T5#Dm+iaI-0d~56;J5%GSw~oc;}mm#JPye}uK@ zQPx)1X>D?UIQkMP>;33lW{ibU19;5`k&aDGX0^8u#z@%Y)h-$ezg~M_3MhqX{EL2Dyc62ENkir!5gWhd6;HkQ)irOV5@Lq$Y z{3l!s=ASgb4d!PP~Ov)C--4EhE+3GwV!jbWK%vd4gI=7PH710ZXr* z?`{|z$cLo`7~Th+xSS>x{+R1!ze!MSJQrJ1*uUTrOyx2_tQPh^wPjruA$$;Yi?;N`%C2VKQt*GX8PG@g%mnYa%_d+p*t@^ zKi@C**uc$Vl2obbwYIJ~s0GDwxcWRKNCH(t0;Njfx3!Pc3Ob zRZXk%5S-RiyzGwOx#3dVWNGW!YG{T>dNoX$g%U`~B*D{} zp%_2u%iiIswo;=U1)U3*=EPq3#y@2A9a*(>PloT(;Lsh%3NnjhMqk`5V1qZvm2>^v z#vB>gK$NBT4W4R_#f1(p(NtM>ExKVjS*|Tydn2`$)+7k} zyM5nsx2_q@7TYc*W78-oVZGDjrixdo5VYHD^%X$D{m>#P1ZDUh$vm3Hh=#{=Q!S9% zbP}Q3z9yVJoo2QDQ@FDuLg}y8ZW)J0di0=IF|KsP8HUK(5Jl~11LeSH$uJ2l74-xe zL>qR>CA(bve@Ju;%x_2NQcx0vPK;~~h}O8e7H_ezuWA=NTxT8}YwH%%cJ)@k3$V2i z&Z5bL9SO}*%po35uf;;QkIk*Sam=hNekRQj4|_n0sS__7uZ~e-3{rSBE3Bg{GOgq+ zCQd^~@mmx%|FKAi??SDIbIGYY_BH!z1~xZu%IeZN{WzB z)MqJEen^M4%pLPLGgT!NFkA;rYpfu_^tc55%M2&=2MG;nPqHU)*-}7AE{v3Ki#gSLx%~$SDGuY?E>zX zXq6sMjbYdbn6r;3!KBeP1|CV9riAwhMDiiyNAWZ5aHDGiShm~)W zN>}g^*UpuW@dL0@0VQ%u0*B`c$E~emM9w`Ig>}*ki0gC1+`rYn_h+T+STVcS z05b&EZG=wn@%hMFDS4TqNiH0GSLO`$?&oJMC{57oVdk6CZvfaX`<5qWCQ@x!m~l~B z&l_bk*-0xW?)iL|mwD^drUt06R0Wv|I4V7zx!!625w&8(s3EOHYbS|rvIuGJ_!geo z6-EeOnx4f%>`|`0C37luR0*X_VV0yB8+-hHa)wsH=Ud4wisKQ85I$YTMdugGwJ_Nt ztauUlXU3UWZ( z5z1|B1_pJKsO`@%0v3!#96XV}YY_|oEY>z>3|_M>CkJs0u#83d@1-@0tL%$e#pY72Vu@r64JY=nd@Qw4SX1Ib z@=dkvXQD)^k3mX)qn*cbD4Ewo(R?=Vi{15l=)PG`SEUvjTc019ZRHv+Ew+%PshCOm zv1HveDLHR_x3V{ZSGVUhINDljF))M7#SqUeSKViDVUF4)qZWJ2C83?O`Mgf9lC^Zh zsEqRuvoGcofMQ$ghT668_RV-1RN5)v$KjzuvYv$0&r0PU4J^nHU`f3rSUyrYHF>@4 z`fzw5v9WciRY3|6Dle$}`9UV6$WPCd%4VC+QP@w7IPvCr3RAL>%K<#C2PeZmBnf_JqQwFpvrc3`0!FR!m(zq&}1|JS|nlU53US{u-R69c@|$JuQae}o7B4%X`EMeRVZj} z2kNaf?(qX;OX(BGcPsfOfA6&GYvTByYOW*?UicdgE(-a~EX7JfzzP9R@2P~5=f%PD zyQjYd%$l7oU03h^IFIdH>0%STQzzj$A*9$sdu0^as^~DJ%d|cUOJf&4{33pXxLwxV zm;Im00fb%re|HW3&l}qv9OH5ZpTn>tC2GjM%zn&5L(-!J%NahJne7Oq2IeFv@C>KO z^ZY~WCFMt^-AcU(3{F(0`JGYyduJoUb*Lj`xUFV6^^kHbgX&L&wB+6VKjrfwnmd6!otb@l%@j}x&>QZT5$YrKhJg;d>cU>9&QH0;+ z=wppo2lbk**^^o=B6wKs0AFKFETxf?`j31HVK}&}xmO?aV5=2W)zCZSEWuue!c#&c{am<`j|2KU%~rUkxLM zi0wb5b0aqYOW0ju7YN<;|my3eg-Dy^>Npnw}VU@$Xmo@bfbDV61Mu}N?)X} zsmJGpvgl1S$kv_cvSL>_HX%pxLkGmQ-uGe&r}@q&PZrj-@1nLbV$Pe!bX zy<~(ElWJU(;6O?_tysDAhu^BbCX##=%M1{HSrN>ZL^wW*wK0lfMj zCVK|&x9^;lhbo)b>+e*_mDQvXS5P9Ok<^A4I=D|HM1)XjS3KJFKn&j(QGI658quvY zx!z)~iNP6KW6^g$z=)iwRYNgH+#b688@P6V)I2j=-TDNl4u((-!3Oe4@Pi6558L=b z-VW8rEZ1Fz=-3hp1eak0xNHR0jGFVwM{Pp7*{@zOaR7xtHOX>TFh|>TE^z(+=?x_I z^3-1}kyRj>-Mekv@coB0AuDsa+2E6&(9_M4*AI$%9&^S@I#&yHJ$%F&_|$WL3k#)< z{~@UztLeJjH0aC5p_APg4l98)M{`YxlAID8o%QuD4gS9D{*cr?In>1jNpw0&EB0O0 zSb1YPjx5(z-LMiF9m@&?1LekqO3r7bIVFOKPrd^&F!&fnOxo?Y)f2S;HYr$;QmwoN zs@f{jexP#Nz4=>NMI&VCeczbmTP!U^cyC+gsil9rtK0-UHqoa@6iT>8e8wWnX7OVfB8|ZXw=6~b*nqL+ z8Xy(8Erz(vSaRGxc<#0Em&z-t)ei?s?nSDE2e^Yq!R$Slmvf?IqqFfs-jH<`zeyN* zh!|43gBJQRFH(N*hHy3F`MRrcJ%)Wf>Phmrivow!-0}R-BjqlpRV0<|0bFoMc#4Vr z8%xiX0f=kl9)YQW4zY$yhP2gi*Ws{rIY?d$SIVrsb87hUb+qW`y?2|353!?6)UI?Q zkPj5bu_JV3YN8C%X3Tdt)~IbtEoQb zZhBqf3izLy%QkiQe;(Z^1EJ40^>vs?}jr zw6=#tL1KU0DqXT!FotZpv__O}xy^pO7nb3kH8rX%J;Q1Rd3GWYyr3>SGw^)2X4u_` z*EHq?GLq}&p+o|neEgv%GRlzGL$ODEduwZV8}#ky;)r(Qmh|)j2_wxH6wL>bk1q@M zJ6`b|iTW6N%Qe_`>?8$>yi>h-UyRu&(*348E$3jLjjQ28WYy#Col3II5^psDaU222 z%8z&g=8F&P<4OH)S*kTcJGv71oX~P2HM(!BV`HJ?l}9 zbS2x{d2*G{72$xBH(Q~j%|GJ83E}b8DHr1*B$Xw*bUsmIH)YN(Q}4RPtuFi=N29KY>_UKum%2`e;PEQ5T zjC5s;DYV~<6{O8xmvblWS2HcvdmXG0&>GL)b7rA_7K^MihTb#wSPJ*-<6QysQnf4( z?DJhF&aj$qN;?|qgyA_7nHPq(8cQnN4Rxf0u5=o?GhdiI`R!{Cd-yXK*ZM$^?@QsD zpPTh8g47D)_E2S1>X7%XTZG*C_#_0%%;HO|k9{v1x6bea6{sx6PWKm+&$IJ(<`$`G zr5aoGe}l)7x1bi)sZ?#hD82~doEQADJ&$1AZ`r{4!tIX5ofetB-=b@^E?s=iNsPHh!rNrIxqsGPwX{Q#3mmIM zoRJtN$JF`K78w={mD|*MqJ3 zhf3dgiCp4*IMw#o(Nhtrtxw6qH1r^)xU%0I@G&KuC~E2E>H8lz$#x~xuF`Lqd;(Sx zFTjNSf@4820hw$VbuTX1)G!AFSel@E?*#`%(BBFB_S!W?wS< zDinP*{u8oiA$+YINdSGJu|v)q#8X$qj$heWvSSMD*+=Z`LKg$8#l5AHce85{p;aEPnykzY0 zi{=sbhBi}HnqG{?ep@$h5m@12Mdaevt;LNBOv{9dnHiZ?K!K=4O0sADr!$s2`z3m< zGjKxJ?`6kSj4pfo_~(}iVP@PDK?&4$-vMM~It>cQQ-D>6mP4DLuxJyuY`b4ahpdgO z9lA9dWIw3(6&gfv&68A=?}Cy?-}I)WqS2>h=+ES?xIal(}U++!;uJ25&`fKtZ5ftBB|ARAyEvi~5g6Q*Xw|(SIJ;h2B}VBJdi<(82Id zB+qhks;pI37D!Vd9l7&**Y88qvh%5WXTLI4usc6Ywh}AWu|*d04n_$CWjZwzm*M+x za*DVVv`D-Gy-^KNWEYB$Ykj|NX|zZitXO4zYYmNB{6>Vs&c%^ZnrcA(CKFcd z*|OJOOkL_IfP>(=p5MRDXru5?`mg4-Wd(3cjIcjN_49pg zJkh%KEzsr_dx#UDsw9`@jPpXiU&2H?eU~6K$wEI2KhpXeJkBZLp#6D}kR?33s>7lJ zO7izz-qdW2*(v7p5q-tA7gb}6qCiPnO7lCMsk~4%PE=W<%uN3umYTY<%l!g4KmuV-@vQB?ZbRtJADj z8B>0Oc8>|pmwbm3_7kHFR<9R2QC&R(B_{DqpKP2LI zegDm4EXLL$S~L}vHWr`p_9}FZ){gSV`8@4ktqP+659Ns0|L6Al|LdhE+7B-cGFSc*vy#CZiDH<`xG*+D;4m3-I;Yx;pyLCk} zjk~aGv(iOSNZ%@2tcY-~DaA5}zefqqp*L?KM0a#7&ck<7(e9fN80ej2xI>X~dh)KP zXGuXiejkMK6`qB9h|#Z+t!Y_#(7F9Gd0%Qb+A+EPoW6Ao)uC_U*_lJTe?MPp%s~5> zp{dND*gaAQ7Xz@O0{VL^k zbS7KvEwE0nyCRte#&%&}*&hZ|j(W+7Um}*ySy+JVgxO^Yz|;^4a4YT(CAhSuNN_C@iUoICpt!qJ+&xHf z3GS|?xD_exPATp#o%}}DtT!|NH}B2tWM$>v9Lc)5XJ?A-kx``>hP7f zZl{H_`b#u~$Qy`vt=b`r?AcVhIMp=Dp%I*x|!VMbPL_J3~28N8xoGg0k zSJ0UCiimtAu88sI?DI5H)@7#W>~msHg=W#C7y=%5{Xj9@(xJKadi$~heWonhiZ@#X z`mf)sU2T(^3zoYIh7POjw*s=BeiT*qDI439G$eIQfwBs194Rqxlh?0C7QX#hC!>ln z?*&nsA1ca9xt(tkhj5_Y$ukY4oDss~E$5VwKLnH1h{UK{P-e<)YSH9B4HFIXAvK@r z)4vTia**loe(A}c)7@5C!q3iorEeHNC7UR-{A}6LVykY~&IWAWh*_sA+Nd^-Idnnm zoT`7>JjjsAy#bHba?XH{*?X9>?HLDlW%Wfrx(=O=3-k3`a!MTCI1PM1uKJaUn^u#b zE#=|I9hU--9KJUhfziiV7}bwLdO6Nb0yDj~9JKDU_6W8>uuEh1y9j-AFT$?3AmYls z!#Lxr?^)FMt4VkB1*h+UOl(Z;{oaLxa2URXnq?;_IM4wB@GA3jT3R{9@!ZJeU%-Xs z9f&zg7};Kw<@o8n-WFzbt4Ji5Ez4_MDiEj0H6E7y%!K4Q;OkmVW;~ADvfp>!;1)N5 z*-7q%K06XQ2Xl6FJ#oD0=xF5F<)Ss+?OTE?r{fxZUq#*Pw6;Ek1{9)OWfZ5N z)l%R!;F|KcHSXebK_AwK_f&_Mv1=LgS1Q_}(>6C$dwiAMg$}q}*RPt(w)Or3OzoIK z`DtDmAyct#;#<7m1y`2E0FVG9sT+*_*mg~G1vlbjj7ocwN8$|SC368cR?Ecx6$2et z1r<39UTU0tknDOchp$BupUl)dkGYH0Inj|3RdW zO7@uTPkvK=AO4#B&>gXM#qtRC=;jqfPAPrIhu=;%)hqJ5$RkU;iQAXS`n$Nk@6;<5 zx@?nIGS%+E%XU+?Z9a9IUYs!tpReF)s1A4M*m22QA$mksL#`Y2F*@t{%xGi(?!_t>nBq zwwvB)%B=LNV*G==Z@u}(iduviQjy9`f_Z{1iz37S5z4oq1utEnu|tNE52L4;nnyBD zaKU*k{6%-Ps!c#oynC3rH}Cm#BQ)RY`OmO%ik{=zeKEO?J5e7qOKo4_^hgtS+^TZ=CBRe*rvA^hyUZcHK$(_I3utwblZ# z`5dr57obYL8a`4kXaZ&(lyG+MHRp9tudM80zDe!ARD-;ebSQm_yuxy~BvGq*`U=tK zV614Qb$%o3QY$XHU|%EXQ(8=*C_i-U@awkXk`ox;T}Ow`OtM=1#~@Tq(tVirR3iYm zp@rjiaa>s=J`AD}v8q#xMwq#qOx^~(O1k}a{_fNTrNTd47f#xF(@l={TL%4#?p`Z^ zz=l+M!9XpE6W@>MlYK(Xi{`WPP2qHuUKC_S6*A)lqot^-14pO=_negE%djZ-#!~=* zjE+=O7bCs%irE%|T(oTKS6^#IztrDMB7QyJ|90*1YfR*1eAxC8wK4E)@3Ucc_H^Y= zaTa^{mO3{-Ir$3yTrOYnM7=KFetW+o82e}A@Fz25lz^g4`EF5=hPaspC8}Rlp&#yv zhHcHQW!UyhpXvwVT(*CJdjB)&{eQJ|FqPUx9ktIH6h$mLuQqJ^lOM-*> z#gd=&yFXwH`_YjU&8Q3QJtvIOuA9=Z&M~h@>FCa~(T{F+*2ozkHES$g^vvD(BQq7K_3l zdxb3HI!Ll8r5Kh4PCjTbA_mF!Ka18{&d!a-^fxlfe|62USHscAq;^ahF*w*@47n6+ z2nIf}xnzyE&+7BcczNEM^*g5{_-+}6doHPxcViylJl;{)XG7~-{FmSbLiGhg=fY=) zL#kYCtOIHIybt|uNzn!5Eq4nmF~l%VR!|s{Y1B(_G_#ETO73V=-vl~4T7z*t<_B}U zzAWX)4_Wp>`BF6Nih7Vrr9$L>=!%akVE`_6?D$tSi`y*^8@Tnsru9j1gc&Qij{B|L zy3Nd=Mc!0XL%vZr^~HLSDw|o}+p2f;m1-uXeZ;IvF=wamTy-p)P59y+2o`|JS<7|R znAaNJsxCQ%JnDCLHTYIx9&JoL=N_E4&1<0~CkT?=Y<`jwD%~q){p1EbIwFN0M)S(* zbNYN3{Y$z&;-a!*A5e##)!#M(zPkjyBqrVduB$0Dg0b*j=p(&o5JH}vk1)zqU}aQm zRMqVuY^k{=KX0Ye(PZ}9soBG6kN^WwK*GXc#M|AvUOsAJl`Vlj*xCl$+X1gqTtX+nuxats@J2yeIQ?>}VB?@UPI#pSVUl0Hy=b!N}1SRj7I0$Nj&X7LnZl+d0 zsZGztlaC~jY*P=Ld5pjE+mgH)-`|_)ajNWh8JP#2$~v!fx{*>D^NFK*EoBlM&sKx* zdX*)gkGa*5(y5;(()iTsBvrI($S47#P~~XRx!9==@fer7K0hh>mWCo?&d2sBPYi+I zn3k-n3}i##Hq2keN^XWzhhx)fR<>>p9K`vHR__F+_*vOJFr3IeOBXBVa!CRin8`OEUWHbdnaUXI!a+hVHqU z)K*)I#9SSsHLa_QC>=3P)vGc;RP3-^HR^znuojq`i%ypr?|7&;VPIJG?O@xzRo-uw zMsX3^-=ff@i;uEs3+09cU~q8&>jbELtsLB=euxW4%sFu$a=c!fKcknGWw5;~xhsWd zH}cFnD^nJi$G0SV>*AiYT!THjQACc; z=kl$bPY*2AL`GF2s}{%BHvfU8W;ur)BXQa+mGWHItMJ8D2LmjJ0Wk5ohj?p@aBru` zFQ+Esa;SY{zIwxTq3-caTcprunR&EZxrWk6%4d2l!MT8y}#>TWqyx`NU0o8?A0G_Q4)O^UbaoDn$FkbOrXgS^$GqEMj~W3 zSO{uFhG8I;0_QV)$O#L1N!Z!_qz z3%(X_B7gh)poj{yB`-POwXHiEpWIAGs!mx}kCoMgD)P5WCH{4973eTl@M7+8yrShW zmZfr#r~t|e7D|){Ce8C2m~4r*&l1Om?JG0@2;Ezf>@XKi9DHudtjNh8%i2OE9{W|R z5>55#F&^ojt;KA}RhDf|wRx~FcUYxtUv$ssYwPxd-nm>q@)cqXOAe!Z7Jt)CstZt| z+ur{cFp^_9A=j6dk$hQEoI$?3hYV-b#H>UzejZ7<6YJFA>s^JH{Pn+qdlV{BAn*Xh zf6EsmQvHDbzlS9R*GAgD+lVN7{KDygEnTC0Gnk@s6(mTj&#f_Iok3xz?Te${;Q$h| zw_A4;&6Hc6NgiZ~k?`<@5&m2movdk16)J@B^Q|f5zyR^eF08HCu9*SK;CBV~I0VOHc7_m~jPh zQZK^H#u>kb?Ji)VcgXFo=~y;OB*{Z)P?Vh4dd7=Z>9uuCimFJvwM|EU0|2vC24mSt zLg;ROFX||H%gIAzNp$<28X^8@1IsUR6oW+%v`pRFy`bUdYM5Wl3dc5enEIK&f|b3u z;2XsVzu##p40qWrUef zZwaVZY1m1CC@G$)L8pC`?=wXbm}W(VYYGL^-+{mCCXH}IbC2A9UsC(U>lC-}cE3z| z1sN5nTK=hQ>z{2=@ItaQeUruqBZxL8N=1-YW<{aS{3s8glVU4ciMJJryx(J7DF1CxaFpcS?3h9 z>8G!A26V@jWfWd%?UtPWBO4<5UBEcL?|cq(WH`4hq!FL8;iW;L2vl4}AJD{WmmjUx z^6q53PUikhtU^=yW#taaSnY1uGJ9G-*>L>4TUVWSe&Bbh+r8jS@(ZE^3Cq2#R@vxC zhPK5XGq@5?^Vr98xt|+BYiExxUbk3Lo5MnxpI;FG;UhLN|^(O z=7)9rA{j1A;nfcIHKnGePpxS!0Fa7;{7@O3?dlLy-P4&pkBb#Z_@GcEyQbha^WOAa zLg|b%=?x@aSzm}`-+UU14wGj`l&ZhJZ%^|b#9MVw1`Ql7W&=8~pO?M9b zeN2cIJUC$mS(tXsj^85JmTU&kMZ=6erYd1+%`PE>&C~Y!#98X%Cr;eTAF;~}MwY{;k;{9?{M19y_?H`#4>2wmvHJo@_Yn)_`@5Q$ z)Dq?MUV8!p0?bZUiyq74opLSOi`tb!wC~i>hx!dls1jw>8udy+qG4yS?v^(35Gyze zOhO7dvR(U+<8`@fY}g;`*^!6X;D@Q$g=m0RrfsBh6K;=a*IaVS`fioM33S@F^PATS zqCAec%ED#g=_N73^ygMo(-x&tOgF03*KI|^oTZ8-c^`lQj`5E1q8eg8=r%CC*=S?n z*ZGlLa}8N1rs5e#Y6!`Z-qp}aWxj$n1PFo>C8G8P#e|JiKcb&BDtMFccixwMU*J1e z>q;eY~1f)UR$Gy4r+FcgGs$S(i_J*$Y#osHSdQpZ;()!J3NTmFtJP&&zSTeS90K zt;-EM$S$_l-(b1g3fG{$wZuk26qb+^xJ1k~hZtTHC*b5`kL}|P3CD15U1|$$Q0@3N z!HUh5_yzK-ZRJ}V>4PzL=V>fR3Ai_zKXpB`l3B0lQz=C)MN_=yx3$}yJZ&obF-Y!# zuxJln(6`h&T&Grr@wDk{y+3JnY8=yYgT5j_+~)Cgp7nk;Pup2@C7Qp9M#fte*4EVL zU6k40W!ciOjKUd#Z|KIbgNU#?K-%>f`A4}y)-pCY_wO z5|Q2l7wq5Jp|ro2_>&yE@I|U0dvm91b|=?_F4vBn|qxc+1!3Pj?*U4rp>qvuuj zMU@TC3=9svOb#TXJ;r2grGHLq^cBH5!s&=}CR^*-11JZyo~cCj%`8+t)EyV`SgmO$ zOsA4o&Y7qUUY z<-}Ei0Aawsd@+z%SX_kvQ1y+oX?zDj%m}!18j89uHs8@#rP(wJ6h zVx1u0RsmkQ)wizai7mmJBMe#_j1WK~SYh7`)s$BXB-QF5)7`9&*U`xFI8UwP$`QPt zi!5)ag~}ZRUcEwIcrN(iGwW=@SY?WsgVO>XRQ=)jlx*oOK{nkcrPFCWJsLy4fKw*; zskcYZ60jY=-DhliAD1N)Mar!H{kq?o)!!m%3M#C&_2Dp*qHGr)iiGp9$*T>^GfH5v z0TFUU3+GxDI@070FU!V-G*HZ(*FSRfIAI#0MOs;DVkWsStCt!KLIr*^O53364z$wG z53d7`n?p<>b&bY^afF$gR>-oupwQ2QPEvj5?Y08Dl!!2zuM7-qn!SB97}h4FTg4Q& zW3wBjO-p*p+%M_p8Rv|QuYzu7YsA)492;ibC?xkdz$u>8a-XK?>!5r@MJXY4 zER}5ZjN%u&m`ItQTz#4n6QYs7HUS1$3Ey^Rq$}xtv~}MR0D6Y6xH!>^pdN^596nrD za3nz4e_N`(1t{^aS26>01HJC&ZGa1{%x?kO7B$MQ<*q;$jmy%*TVJ-H(FCFgP6gQ< z8nx6CWte0`V%O!3akQKqrLpWicNwKnVP<>sY4kccbd z?XRxiR+X~Ki{iPIqPz|6#_TujU+o-(FsAEz@xHG(=Yrb#jx`(rz&0k>72!NGx; zQ&yCFib;+c+?%}P52p7@iYd3R^-c|3&Ft8rbU-sOGXU_uhUoj2KRy?g^bF0*MV8gH zz5U9O+citFlr;vXDmg<|PdqFkI$pS3Z?3!E<86;cHOs@^LVJCZ&zl_kz;VYF^(_sA zgqQtPq=s|%IGphdcy4V47~|jnkNF4H1m44Hq*QaM3eO<7w3^_TTRu)GX#N@QU>H2u z_Pv)L%(km=G)k_@raF=gV+E@^xal25y?@@eD@AvvB~X@XlpXv+c}UtRjws$mI&8#rA>Fja{*v(8a5sYR= znSEJhEX-=dqte7JE!o?C)q2@zdtfzJJaagtsqUmiVdH1~e6^K53vTKB?5c1|jI%|w zE*Pt#FZpeGo{hMOSNa|IF%O79y%7cHQ*<-{T@36>bYg6K$MVqTrf!d8zJoYJfjpdE zdMxh>WqhS*Clz93%80`}_&8H?ej3HMZ;;s{`@;a#z($jk42L_yD*S0oHb7VbHVSqk zjI7LlD#Cyw+CmP;4gH`)8(?q@y!6Dl#vSGYoBZ26IUf}8H&Q-XfxWv-UFh~@X_*Ze z>_rhKn<|GS%thsMM8t5`vQr+&zt^JBVf$&AI; zbZN^%I1>GU5ZP>*LI4hz*(>7b#XWw5X>{XbNlGzBFOGAX>?**M-)yD1IJ!l3ev<@sIC_WrBrp)Y* zXu{d)M9E8a*yN%m`(GWnk&@Hq%eN&rU?9;*R!k-qjLjrzIc#_Nb?9-_L|LV~w!F8C zCE2j8**;+`bY?k1Rp*vp%Gx6qVj14Rsg{Y^;%k}G%KAVuhI8mvdlb^ZDpR65hPgH`NCxSJsdLiD|PyGEuF)R3iQGws=(kvb0{l7X+sTd z=!s9aew6*G-Gq1*2V9czbm2H@@A(@!bcmRL|t4@BF8CLAv zv{->$Xq)MB2)2|z%t;;XeVoITgsV(lgQ88Ic;I$v_Y<}bCndaE1I37N*3e}+W3j*` z(Pq)+yM)$q0>PjQUh!xuTFf@>by07M{Msg;^1`nqY-7LX;jX3RM5W%II(AB=9V@tg z7LH--N$@bjgJ(`}ck-{jw{DbI`8C%(!|*nD_jqnbZ5@>8X_CW}8(eCLqW@i^<}R#4 zZ^}*M7E8WEKfdHBm4>`mz_Gt$JGQNnb5K*?(MkX^Q;;Zs37kDO ztx@F(A}+PpC@#SzyloG|S=&`x;!x@94g29WPHhK|#mAX@oqr(Gj4wt1U*j16=M&@m zSqdIgq@#WXHS!;Y8f&ffwPt#Nc_Q1^W_`&VMDc~7hOGJ!8;Neh-bIE+*DMn9q)+`( z+}&PD#97t__P;XPd*he{be9#zp4fh1y1eJ(PWNwjUDIgLJhTj;SX<4$i?Q9DYrT!S ztZpv0kMD9>CHlqKGQ!og%}s*p*A1Q?3n7B-#>1gyP0h$;Q2dG_`-ika&85~3ZO?Ot zglRSJFC!+hxD`YiTr^|!;}5(`Xg3ZxNAnVPnWyem)Q3XcO#3$sY(mjM5rjoallT=@ zQ})()NqsPQ?jp#(Fm&1Ci_|F3V$S9^zkK3YZOTq@&W5El{dPh^bL?zxlml!hS4P0+Kd4AW#TPQX}B4s@w) zAimUNE zF6FD;6NkFgHot~sv*RR3my?UIi*m~O2__#F8v8=o0Z$?HY7QL&ac%(z!ZNDQx0OkG zRUa4kYQ1J}Xx9^rTi1)GnN(sB&AB$4)n&w)tJyRfMf1N_rMUznoPA`sLJv>tW^UEl z7oEs7-gaH&<0ATl^-}6PoANW9?>g<(Hr-`ctU+yylH5h5!N3cE2Kl>9+a+X)`A~Au z*KwN9((;=P@CcuEh9J0FfO>(=5RwZ?e5b4snLWid$shCXFTkAYy}ROBob)^Vw~1yq_#eCGL1GpdM%}wP)lIfy=}5x z1ccFEcaNyf+-I0ymom1M#vW8F6gHT!C@#s5Luf0=Tu=rVrPu|2B^t?z;XLC)}U2K^JT3>IT>qze#MA zgz<|{PuoYLup)(I6APvUlburi@7b6$?#$EE(H#e1wCB;Vepa7R->%K?PVN&IIWz?V z1J`Iociw{Mvx8JYy{qQ@nbj#wshwaK6jMZeRH;azJp_)D6M6J?mWnQ$8#Ql#@}A|n zIhk1D6*RF9&|&3i@sZms7C%Zqb&4cE4ON;l7q&3Z6uiWZZb4h~EAz=@Mn-w*d@|jx zU1U=NKj@c|3mplz$UP_G(KUB7MWp#->@JF-7VboLisE(C`04Qms4JL61?stj({-$4 ztvFyU=dmil;e8A<<*dzU1;fj)Mq1r4+Ni9tLR!SF-Ga=LoVR z_CV#lJLOKwDN6o^ypxWIE2Ow~?oI>3%M;lec)iBYDdUgJzvBy_^}$eumt=<_x&$SX3KX+%NyDq9$B zSEeLJWzO@PW%3}pJCFIMaWzAnzBmT`=$QH9cV-&?rtmW290?)pv}_|g+cd&Zi7vGr)V-0+#wzb1GA^Y6YnKtlImA6m zgfR%*a6zlIFl2UA%o17Gw&CJsy2{l{Wo5&%nyw{V{(Sn>HM;#Bg@JdEicvr4rW2S- zFRts|Y&QXHcJMC|8F7B%dB_RBXNK|TgCihtf@EM)qWn2;!O_c5muF*IyAA56%tv^M z7W*7V$$=Z_*D6>qwR4{Tb5~9(@9|z%{9)Yptu@cxRBG3L;>vzPxD8Y0qN)o5V4+9@ zlbqn|DfnNno_~qSU`0N<9ds^Pipy(k{K2kL7vCRx&FSIvv_OWx!|`0oIzX_wx(TP_ zQa>zAxCxuTEYXpio0{CVRshz88w4x_rX|w*_O_%5ZxxK;>?0U!-h@Vh`KO%MEgqZ$fHap z)yiMMUU{Q$fo9~R$>g`|w!&E#oA-waT9sKh=j6nnV}reBm(7oIU?^A|BW+&rjGvO~ z2CH8M(|eKans=fmUgub2I>SgN``Aloblr0D>uM2k)Qx1R6u5Qd_#QIK!yv{P^vXtGsw#i-iH)-ul} z+Q#J%-g1-6FPpNIoSqwRRgftmM3~^x{2Z0--(!mVd4u}_DRSGxkC^->Z1suaz2j4u zWpm`}ll0b2)-U=$uPXU{#gl1HmdQQ8ur(vC8Bj8#m7!{#U6G@vYgW!J1?h~bxBu+t z%>8aLccWf(e0C-v>$WC0{vJw|l=S^730MMWWn`6QQxyPa7k<0fJ;AO|CVP)mKsj~p zIse0frej#=3uoNiRu!k`YE+O+Hgm+)4kG*pt6|~!$35_WcOd-B76jW0=j{4_W*D=C zO1bdz=@K)%BR?K~21l^5M*mT>WCJD^77{2qe_Pk}Z}iIx$MQ=0xXiWB)?=#2$Tj|e zpaLvq!-1K;+Q9jEoHUb?@j+V47$o{yp=^Ii-{Y&f|9cx>^-2kX5 zEmshYVjiXi_>m z6L3tV@1gz?bbEGb73x*f`Z5VGY7|x^_cX^guG;(X986C?*;CQ94;g52soJ3kcU?V4 z$4#gx-Hu1Ae*tU~D((zFHAV#SRSOszaEaH&P+@j#%IX9463VHO>1=0bqD)Dr=k5`8 z@7JuYFSzAJPv7n?bVgwBoo74Y8J z_MkLz7wH%EHTR3Z0MqMK2?Y6=T`L0kkWYNDrIEADE0|2yt_@+(5aKw`?<4-m*J1?Y zd*d~@a({4D z`_8`aiveEA+ys;o*K9^p->8XAa~CpkBDyblhBj}<4JCWW4?6XlKx5h*Cc(BZ_&MpV z7j+|sZ&H0Fct>MScDeU?r=de>57|aT=EfqZXt2+J@+&J$7%WUs0w!MtXt)bZIC_r_ z&t$=um6k&C|L5Yu|M&3#|09a@ADhMh?_#bD^%?x;0N`E)N_Ng{#{4`!<@&%Xr~3Er z!ru)59#}?R27rJ703g60fWONCDfrR95yby`^v^5e{}3c3WTbxt5%Hfl$o~i;5()}3 zGW>~*{Ldi&eFS(fL}Vm*tN*n8{QI!BMnZTEK*UEt!bkYq2cU(2Pb3uh;PBAn ze-{)~bR=Xn3`|6Ck&$3j$gSG z@@mg8i5VojN!~*~|JnowCZ0<<<&!e01=W!;^6;AUNPke*gceN0$E1Q^ntwYd00|jB zG9m&x{L>Hk@EPHAprIgRAi*!gKUWfdh>t@54wXPcmGJc^$FB)_MBKIAzZfJTXK2Ll zKRX2`=5N;ZoRjcMO##&yd4m2f0bU`&yWu0@1H=FuqHth{gzSI9=>C^x!~cV&@h`e$ z3)+V*O=}T8XHBQFM@eAnBvat$KC!YftWmLAXCRqgnn?#B0FiPy3{u|U>M`hF%T(0q ztofc18#e`cwAUx*vsyN?0+UHbd+p>+NO9Y*;Aresbnsu}%9ft+|nkKuKl(9rG-h(I`e&KEhG^<*g%}x1S=iHjXVQ)vkQa zmQZ^gQF&l3Qd1-zX3-Hc*oO;!R)1q3Kw9BXagTyYEu~83N+W{73fkY)LO=Qo0L5)t z@u@i1d?;yocX|3jLDoc0Ny5H(UH;@YVu%%hY3kNR;r3bene%~}_G+AB)#PQ*SKaV0 z;OLqCFW|)OFFb)C#~)6!szIHT^b_&gYAW*ytdxyO=MgWmV}44^kbF-qPD6I6KKkeU z$HP|KLp`Mc2E2LBLpAF7CzHPb;=h3Obq$Kuqh}GTov^ZFy`V5I2cV<{)p7RWcP+&m z`J(>OuMZcvJ|zjqT1{lk*&nKorhOJvj6{3&D-Eh8)UyS=mNFF-Moz-Eo&{7d85G1{Rk!ikrHx{lsy)sow-oe3b~J!jlI zV&gp&uH*|mPmLC!5A#UIb?qEXaAa!x4QFF+Ug-apN6!+z@H5)j!u@<;S>{h$$Z zdCL0igP`gaIi#BtA}sl9bKd@&;l>J6wi;%;UVHm$d?{!|dSS#ddQ+axc@NoE`=;XU zj09vnC2Mo+_Z0diCWQr4vA?VkmcdXUZW&xhXaN5ocOU;%CsfbCzz|3>lvSFMRc<6% z=?8+Ebsbv$dLyZArJ`N^nNb*NdYjwFb2!50M8zPgkkgn|-U0TaKjg@WrR++@5wgLN zOOOY*=j-inv|aeo3zk}f2Hgt|u|1X*!C$@<2PDfhcc3b_==r^)GTrNNsXVeFL3my6 zF*mcB#=Ggb&%8 z_gIpYimOX?j<%0!t~jZtShBH6NeRyvbFXjCi8YAy`({IlQyT(1eUjZB?e;l!$*Hpr ze;+?}g3l!~M3qP1SP*X`AP$Gp{J7Wr9CQ@Z&d91B#RFxyS15%j&tw*HG#^V;m*BpIu<<;(TU>Lcq}ry&5i@Jfrw^Qs@c0Itex$YW7UOs_sJq2d zLP-L{I$ivPAI_=*o?j<%@$s-7mT~|OVg6>MEZI1XX)~U+#v@Q`NN{!Tp&2R0-Y)xX zq)UJTU8M=)Y~oYI@t`&I`eegYgPuA3`Wd&OMK!Rvv||J@0(tyd#EQEB(9fFDxlj< zV?jn7)QFP80r{>TY$CLw-Zx)4ZqW%>UCGgzM>1lVp>1m}MOZ)Ta{0;8?9+K|b5rDP zoyy39@ueIP`}rC3pveWoi$X}>q|_!@GEH$2B0E*M5*y>eapB|amo3Q0cbGYr*h2^9 zRd(lmni6}2^I}|39XO&k;n}J**2zr_oL_{iZ+=$o9!8XX3|%rsnnx{%O?nXspIOr7 z7UwZcUh)0`HC&TlQ_eGO?5G;MD$w_PIF+BhE@P6AKPb%H_DfC-yM)K_mZ~6sgs2BA zy}wHwaw(u8|88DqUS3r=+wG#B31Q?K^i%{Pegy~61+@Ta-zsN8+Lo_ED=}YY_C-Wo zd~;@)C5!nP5%Oi%DJshTDu{P$%4mh@_*Yis!csQLuZJTE$(x4K8c8@yKOqsz zjm$-HNp%hu(C&fXn`ftQTdr|Oit`e0d>J!&gPt1;5jE0Lk4Ymt1#I>}Zj`RwK& zQX=3*>gQnzPT>GIc1tiI5C@&kLi>wQ*yo;^iTbCw3ZJ0F`H%?JOl}or06k5Sl1d|jw5i5#w^L)n?MlzOIpHG_0 z>rYsKPI*G~4SVVKAjq;Mih?c#Gc49wd+Ig=p|4t;i_c=r#Er~P?Pwr+v<^7r${`!u zYqqzpI|RlH#-4!@0Fay%-8_%fpHn$~mk?>7$M2U9COkI>Uon!LdJzVsl9e|fa#{_e zyKy{APSv#3q@e2>S3~z?nZ1LF>pIsS@%+Dtg=9r06bZ@Sj71o4lUg|vm#4s~Fu+_- z?=~`Gd5E@5nsW78Rua{VW_f?;+5m4^P|SMg**`XoNb1SS(MXnP4~VE4V$WH(>rVU*kOlK#~qJX}SZ(wd{{ zy=^fR-5yFuPiKSli2+~>dCSNO0HE^GKo26Tr#5G10@9Y_fm6# z{|fiO$fi^r;W_o6p;KG9N}saTezX0KL`Qqwi5%om!&kq_ftB>8ZQ8b!4NdrmskxZ@ zRBkf?h_radlufUO@<86UH$_6Dgq|=u$Xs8b12e%^F4U0fZl(sE*(E%KoW(Lk+0T8L~~*+ z-Zyk1dBmZQWS~LTGrmnFACRQpPvIzuQsGZe57b8Mecp*JD8AX69$DY?C9VGpC?sPn zyfFzwLmGf%0dyU`Lv-Kyo!QP?>&M!CUU%D2^4hRNvFeSc;`>b6$r`(9jHtF+%04lp zR-n29>a{$jNbpQxlTdCI3$%!Z~z-lED5MQVShB9(Qs)mR7VRT zjol*B@SZPv2c>}Z>dPw+&;?G1h~agMYACYqj^B@Qu4U>?&0NNi%yl)^bQd$tC)r>$_ z+WikBJ2gbXMRI2=zPRg#XoAA$3RaeEXZ^YYRMFeT8`jI0@+k>rjSAmeu0+^c9H`^A zJM~IycVu@ZC6rcW!(b%zPF0-}Wn&$M_*sKnY(p$@so`b0A-G0w@D0K)^+}NO4P)S3 z+7Kn#6fd=}gPi<_&P@hV_7NV9axXW)-$5mkwIftES(CMyA;p-;h}dtZwlV~U2fxC7 zi7H>@fK;1Od6zIlCWA|FkKkMa z1h)ViISYg*m$)dvCy!lPiip0?j*ShC4F@F4F>uN}J7At|2^CQZbvLqcke*PpL3V6I zd?O;?5C}Cxa4+~lIYP1ZZBrCYk+w4D2_fC%FR-ViX?=VuDx!=NkpKa_wDjs(OmzyD z+Sck92ag$lye%Oa-{7(VhI&V3&ziOJyZV!yO<|!}gHZz_wJzO1Q8z*DWxsr5lQ}K9 zdQ(Q)hmw{tS@&!WWVT&OP+mnx<0(is$bE^-XPQ6?N^?fG(BRT843#1pqwiI5g=Zsx zfxrHJe*|$NNTUZ%Wl*j4KHtN(*wl*hAXm&IBW$r**GA=aAs3vFPh|Hs56A{s*vh03 zZb>zaqCX-hBy*H;bT}iD*K%3tE#l@`(>`d(W>n4okU0#azk^>OXbV>3wnK_alZR8XGID&AX1{Byf+7rQyz zH}z$79MhWzB%JjgMj2KC`c+O>^A|t{8s$PX(ZA*i9Rvj-pfNF4aYqK>Ln?0_r<#e> z8TW|1Kl~Y|t~+u&!TY`HElgWA2eMr5tH5eL)Ej_*(27w$C?g(#`~qw#GCEcYyS3AQ9kQ32EJ)h7z9)e);?(#*qS}x)mhqXcHfwmo7rQ?G=V8BL!`fW8S~CSJ=@gv#V~yw z=ULDm5+&g+&6(;t_e~dPqzkO@4wcm%Ya;h1@R?OX~ zr(8qNK0s~88wj~dd?5)`9}^wic9uHk9{e>p)`vnDRT&iPvR5?7tAZyZvoXipAk#6l z>ja+vzDxIsH~w?pz%qsoGg9fHTAHs9^yfY`zQwW1?99gkw~ctv4f{96cD-+HKN7HK zg4Xz?Os^$tYsXksA*TA;MSyralC(z+OTCZ|{m1YTqu0>*c;|$y*dHDq^E}jLjo1St zcBb`=4S8%@3#u5Jcl*=NhfOrUC=hx70+fccmjNw>EMgh+2Nyy{nc!vT6^)AZepfb@vNIFl z5!Vh4Y)_w82zbqD>eZ3t_Bp`zwqywJ%!$sA)p}tIyjbdPw7qZnR4_oQHsV29&;ETj>N z)O2kRam1cGDT&CWIo?%8D|v`)k>S5Af9u#%9$el>q4ByrIcP=$P9N#GYnWJZ{#8VDm=d~-`+uN`(Bs8v=o77Tnt0bC4qZYB0g?Z>AhE?ww z2D-=r>k`NL^1CyC4=^{ip}>mqSRX1XgF%T$fH>cX)C7FDF3MCU;1a`{zOYIqYG z$E_(t=PrBm3SPqL+pGbChMaekv619xmDW)j`+5V>ouf5t+bL!P!ecG*A3bAOvSrg% zkDcmI#g}b}EySoH;m;Z9cK8<}Ew^5C1t})j5*7weL&iN>@#cTJH z4u7SJS})MW>?1*%)LmrhkHw?>hWY<5IO9^kP~3~}R@y2E{#F=Y&#H@TsSRH_-w7qs zId){sm{G#o{hi_6AuogXO(zdBSN;S~Cx}G^LTlTVYbGgA9{n(W*w$*5&sID{wjF?y zGvsS16V5fbS&3!kJ}#q%<%7D~Q^6ems*oQ5L~;#%>_RBc-TCFn{gYZUl=EL?s{H8YaVvm70@uBmxGoIER~MON=D1Uv4%O4HQ^a>)$J;#D zcwcBaLjTTNn|1Cr-#epjvG{Y9VaQ=kaWbvaD()u3^o`C6 z96|WqR_ND`f@#snsf>;A%N)yK@%Vhj!SXLAW)c>%VNg~P%MhjaDAHPApN zl8TWS#rVVOl&@!o2TW!*1l1W&w=&CdqDsV`q&>Rt1&23vWL&d8cqmY%Rc zM`}e%tDyBdcgbnB=AIc4I0Kv=)zqQ^IA;1V`&}4tOpN=~e*67znk@6BSboLiu4 zlmB%F!8Z!z4%^^K?)8c;RK?3 z-bFYcmjG#;6>N>Cw2QHrQ&R#u*_z58{doN7p2pT6{{!@A94{01K&~dU#A|IJrl~Qj7=4uSd%HOyvyLvW+*qRCIu+_^bG+=NBy1Pr_?j zisj;P=DohFS(NFFzDzN|Abl|xrhGAd1@4^n{#8rIDy&}`mo=Xy* z*BHP_i2o0;!N?n%{|BmS%jdvQaLrp>D5EGsRhl8l$|5EGN9xKV_yFb8SA%x!6!-0&cKM7D^gRW~Fzh(rwBOr@5ZOpqVh;j#Q zOJS4Kl5cYlym3M(?Wd`KRJWMnZtW7h($8q@IsCIaP$3R83R;9v)2GoC-ws215yx4a zlWFCVC-canb>U%et_zYk$fF+J)7wP@G`qWV>q1VbHN>{C_f_etl$7qSaJQugb|H@K zj5KPt)g9jV?7I+Et;?IWd0b-HlX{mH`G|vU4<(rZ$|9mzp2mIRrA-8gDh-Ks&jjFR zLfox2DR4{RxpFEF&GX4qBMDkerhKSB1;Xz3wcpODbF*g%pUu|1 zY79>h71z_uLKmj3gw9h~#A&t>9X<^B5IAc7BPkKA#2~+AV)=2u4l zCQBt5(jtQcEMG%1f0C@A32z`!PV9nX*_6c%lGy)8;`zTxzW-5$)OPxlcvOEY{S{=j z8JxzWk}4|^D^_UA4P6D*1%4zeC@5&*z(St_h4AU85IG1d3OmhVmnSxfyo9YTem4@_ zj_C}V3v|1_WVbZx7 zPE2FH=-)5wxLLl>UYc)~ac1c;0oUqGW!F+MD^UhS2j4?18QnO{^ANSm=Z8@R4`TN`sr1n3CTF06; z^7F){U_DB-Y4SJPXbBcl*^-Hm#RPKswZYdrOxl zUEMki=_+mm`Z&~3u_D*dv+4eGp5vE|k~S-R$Ohy7Pl9pI^MzI_a~%}%AggeJ&n6O< zUo4ZmzJO36w2F*?U?(%VCTUNX0hJr`4`1YrX^Xx`?}4h~TgjPn5baUWdy-8Z6fTDh z9Z4iR`$tGVsDql}=lMG3zv)~8n5_i$j~lGLcVh{X9l<|`1G=k49Z6jj51`2n#;>4Q z{x{kaN{6jfX=Y-Le5I@jgqcpII$QucXKuk?$~IoI_!EUlhHTSooL*$0^!sJObxsn) zG<%T8a8uf(OL}E)AEV(`)U(RYs?7^c%1MOt?+RiokUV>+&CY5?B$n_}&*l4X&V%7P{J93@=SNMzVW(OHQX z^RcyQV=Bjd!^VD%HqD_NE&Wy>BHKhust4%ej@6sy?+Mv)umoa@nyCk3)qM4pm(4vJXd$IL@xzCjAVO1#3)pUZeZ`t>P)%e zXj@CoTfq10dJ+~#w=~rZQG@Yne-b4eNdQrV^pzCq$SoIcEIx_o%V$uz^x{YA@B=4L)jCx z54s}XEZ%SmmIE0Jrs8xZh zVBFCgVYx6LU6VvD&2@!qro%-Z8I7ke{CQCIqbBS4>i;?LRk!XP|GC~x+Av~Bq*+9I z)>)qXeXcm|>k0XVBO3KDh%zqQtho7nHR2N%1Rkddnnd>vePQn{oRD^0dgXQ_2h>>B z;@bU1FP%dCU3~M569G>ED=v7TZi0?lC^ihRFV4)X$PHb7Zme5M#@l>+?(o=OfpS=p zW{^TG@oRfK|CaA3`$R%*IgW9)nq&u$CZru)Ra@<5@M`Me%7gnFneT;wab=honR|}K z1Vb-sV>ComtnDi1b>R~O@r7*s+4CM&Ds;xiOj!BfZ;F7|Uq;l|SB{+R5)WZ=KYzyJ zbX%z~wT?wBC&XObBVj6Qg2KOvm~aHp;)T+TM1R+!lg$h_hD*ar{OFyskwoGpFLF96 zyAvyyEoLVzYP$aJThKl>hYehUsk$9TlX6P|pg3`P0{Gz#>l|#8nSB-lcAOq@>vv`& zvByr9-@nM~1P4=#nNm^NWreU==mDc3aE2&17C1Ss&E>YGbQF}lu=1RH#WN07H>FfK zTWt7r^73lKs4}s7G7*6aifLT9!Xd-yFE*@6TqmPnKwmaf)2kw}#1_GQ=5xD|TmaOt z;^KrZQdoU(#7YQCP3TCXG&yP;VAGFIUCSgOV?usAMmsDt8Y>LGm3gy% zEZml#;Z!qv0tbxX-Mng;Uv{?Pp z?#A9IXx3QcFuz>ZvZ}MH6HQzfmg8&ch>;mw+G>N@eB>|CQ~`DO>(!&^mHmYWqPL8O zNlurw?Fa=^Ns+q%+djMP6RFVIa8z_Cq*t$2U&1&UM9ob7TK)&W**~h>p7s`{m&3(i zGZeNl^94e=}H)_+y zdb4)gNWR__+%utOxVM*mV|DDL_6V7X!DPF^m+~lVc|^3CqX%NbWF`b+Eg=Z7K@qBc zGRPDZt*km_?%i<2KfK+2cenPPz1e3wKI|285f;N2UVB`aeB{L!mtyhRIYHH3D+t~@ zEL^9zg7#Wc{&tR*+b?mLwla|NV)%IjU}aF6zTD><66U77+gG67=zo!a6JIFDyUqu@ zF?{mPCb5Pva2Gn$?N;r1jB#&p;MST{aBi|EgLq_yJbcyj0sj1?xkJh=@wB3QJ`())5jB`*Ni+BE-WQjCIS~=&<1ES1`Fv0 zH2Jd$J$_q8MrSg2C?Q1|=H(dlURPx4M-oc)g`Wz1?&6!#gT25RZ?~kUJfgQs!(*PM5*Nr@l}TZnRjtBsukg*hmpxjSMpftu_@w9(9dT=u7@>HS|RWI7_#h!PRdXX@-Jo&axqTz%@gSuk1g4j5z)h4{xq2HeCg}7d4 z4UBiM;V0R%K>LiO(y)vKYc)5B!6ol8QeLdp}&xC7~NtI8$bETKZKm2O`R#);lf^nLCE|I1k#qDpJ>cl1w8d zS;ZH z?lvk`xdbWGYc*7EN<$}?Kf$Xva0(t~N5Zy;r-t35|CH$;sRGLdE-29R^(g!yW57XXy?=Mi|9jr)b3(A8)hx`g6YWN3edKT-NthF)HF^ zbFXeE(?E{|PY?kx(Jv_4AGfq+iCJr00v{!YlN|3qfHcF?&%>|&Dm$za(}p$|$G_di zKQ00?Kj!{tmtGA*mU}sOYeTuZB}F2?Utu6{#((zw7hkAESq1Y(Jn5WKvcWguc-7}=o42&LrV1LGAWW&ApScy2 zxt^C&o^l);Pa3ngZ2eR8E^2u3q7^vjO)PEIEe+{LYa($#b_7V$;gaaCyteRoL2(q0 zhllUVO41-R+^^$ppGBuUO5bUy%euQfvwYNfn)zf)2#zbVzjcCKm)#_%2`Q}{`bma} zySe%0Jw(6j&QqZTXXX&APrXpztEH5lag3gZGcsu4dd&c}==ee;<1RXvFK>z$Nn;px zO3FysS_34`@h-vE;C#2L4?T8GMyFR?#zBT0eW2yxp817)W1*#Ey_{XIv^4}?Dh|>y zc$r_9`Ex7&K8EGkL#R;E6y2h|@X4cIrm4%)S~mQA#g&_aDC#VxgMHb~9PN{)J9=-a zdQQElIotBjZ)(GRbr=O;B=CagHu=S@A8JV}-<@4)8~ zz{Jpm(3-8ifOAlP4CC^n-ru{=MNMrhMD@ZB%2V5eo)@&|0|H(-V(Cw>UK0EeVyXE| ziTSGhzz__xHRUf%a@apWhQf`x2Q4FG~wZqI=|@K|8=nrt>jz{4m00i z#MemN*6_X!;myqc>x~ZKX0xy)DsRwcp_pS+iyu2+IZ}d$^47*l3HZ8rN2af?ah1iS z^3H?7w`C|{w!w)vA^$f4|=zE5_%s$=Z{Zc=?Mde3R(l75$!Wp z^#0DRsYBMWDs=r`t=w+P<1cGh@OzF9IQ{Gqa#EkUfQ%X1Ec%TR0=K+)P%V-TV5-R^xQXS%{CgTA7o>-zobR2^RBg>cpF zUFMlW=Pop*#bk|XVVHmbAR}ufNM1$;;k-z{Uj6MN^V)u@eYR#1Cs=~C%pNMF#FF!Zt+aK+E$SlRxbL1FA4e$T3f4!9U(tHEFpO6`RL2~9LM%w zRwtT+&kj!`S}zCYozg&6Jg?M{!B4<$2Y7%_;RGki$4=VKM2?a2@I&fq&6j=ND+hRQP}6=l?<5LS z%~X?J;fg-czHo>|!ISLz-GDLvtx?tj!H({dc5g+_T}M+RlWqfN=(<{wCn@a3T{?8HgcIPY+7f6?@xGR|E^u9KP3Eji&1JO*rhU znch)OsYPgn1kH9uNFmoH=G${rWScl#=lLK^l&2dg%KrygsK9gl%tN@(h}u7&#!dB< zIj=skNvT?r&l4}g$Yfd%_a6WQy#*3$?v>JXg@sJDjZOI=>1`TP5Ie4hwVe}9Gg!H= zbrXb@L=>*AykQ(?D-9Au%Z2FpJVK7fv(c?&%-2hQzNp*C3-*i?`2va1weH4#V5&k$ z?bjahQ>Y+_M}bB5eY`wxHja*3`TDPET^IMA9uz8F)yMb0i^q*HMU(HeaZ7 zteJv>;wM9_T7MF+ac{kIV(!2^f{QZ5&Yp)RNu&SHeWXW9zxjVSc>bq!?*H6daHk*4 zHLvO>0q*n#<>h%Odbj%>&vn%Om1(1OuC`d2bjr#I9W5OW*-FCuUtq|cB1Rd9TnfKh z4sQDN)r|hkZ8{lMMw9`@H&ev{h``p+Nd9tl_aZC8Rawtp!pPp=3i3i#o2K_QzK}W4{01K2s4oLd$|OcX522NjR#s%`;!NSzrtB>jaFLBFxpI=T zd8x5z3Gd3>t}7RYJ?}S(JV_Plygnq=DiJ3J8Crk#r)_zPit&y)NNEx;Fg?iv8O~xX ztISkBgo4iU1nrWniTAw0IKD|6c19h&`I~=jCIx@fns3?~5vXVp56ejKcx1i_sEsgH z-vm}%dDW{YUr?l}zp)i4dee58k4CD)Ot8cSbI0$MJm=ce1TLU*_N)uS56QD|sH#f) zSpKGp9}y7=%ieqQtvAN_L%B|u$8QNuDfzo;7Bk^`#_w!=Mu+@6+J<5;w{e6-+qdfp zHoBeOWbzgDXMthjPMOVpc*E~Me{k#aKBOT^;?2qveWpbmZ4mZ3eK+Q}@+~kcPHw`8 z02FuZs)o>{g=ayTb>ca#cRf2&gmkfjuT=cs@H23kt&!FtarH>#QZ@#KI6Ah6V=%8W zNAdS+?c%sHcRv>dQjDaftihr^OttrT_i9}{X`O>%_kgPAm%t`q$Ocs%4G@<;Q0A8m zMTjk~kakaT#IhKnGhj{LN&cI8E?u^Xo)2P|9j~Rz!D`?d6b|nHcoXU2J8B#g9)LuT zG84OtJxQBNFbbp{q&N#HR8&QW`|9DT(lr%x!w%_9Dnp6}w&VsH(CU@lRD1ndwrgXTsp=!nTt5Ua4O}2v!oulk zJk}aD|cnmCXaelkZ_>sves!;ZhQD*Old zCOO&D(r}7@HrTk<>8j}>e$)t74J}x;RY)wlm0r5IrX-lu-U^UV#Z9WI!OphT|HGc# z!=*txNn63-lSVqV+F#Lc z*vRPB?9lL+o2(s}*zsW?^mpn!8EDBoo$gyEmWp&p{^#Cc@-U?GN9o=4+-bIQ7ubt+ zq*yB4jqrPc_pW|_GCVQKRh3YHcW4%hn+ZNNvq1XnB z_lqhQ*Ib}C09grR?J?B*rZJjliTk%57=23R`?qkV>)Vq>*FBEs*P6M7cuQVzGL=#q7d9f1rr^;kvGh%3(-B+Ur>I=SV<+Soltm^^-g;p6)dh&-TO3)*W>DI{)59}QjNxB7Rq*+1H}r}b_m~%rVIAru%m0RRUvp>B z*F|K-Pe>S(-sA;alNn?V13jJSlXF;8#*X-XiNT&Z3)aLNDPxbM)^vj-`Lr1xzogZ8 zrg4|ZPP<%P-xtO@uPFYRO)~-MHVH)%E*sZr8>9}dNmik=G!q@c(|_x+cri5uIgsiuhBpy>0K{L(yp)hwtZ((V90~o(R*)k)Vs0kYXutYzch(6ogQ8L%H8}aK*}--XGvk_iytAKxT1box z;Na^!g0BVp44B|6umbOGboCBCdB;*Yg7s{2w4{qy%TLO7Sy?zzM;LzJAokwm)~4^` z8^#%eJ+3ly{^(*i#J*oEMmm3ML@*q6ZKCgtAZD=Z_0>TvQgQcf_uP#rQw{{w`o)i> z6YS&K_Gz`Gu83U9?n5elFmX2lhA4Vw?#3vVBqmHiz81Ews!#ZEW+%e7~v1o<$a^g6!}U4V^etc(lYX7(R}<`ebNUXE_VySS1rzDt!G7Xu!DpAO!N-OA|+J%x5dYvV@A zjy%|b5MK(K69X>&p|@9lWssaHt)d`x9Y^q;7BAAXn3o`EhM_&nxs^5GA&f|L0{mrI zMXHpal$a8&qM-q)GG-w~xd!|yt@W!83FR@4q1Txj!qbLweS?L*6>q?l1KKFGy;|ke z7dDJ_tN+^sB9EfUdZ-cD``(eeX6QjZT=^4_Iz0ygJB%bxCp_$QD3H!ED8Ch*{Tc8u znz&+d`IhJ8WaHzDewETjovaHuZwh0{GP+M zZls3cGlQJo3xfmN#?I4fR#%ptu>+ZDJdN~veokcXOK+$0;jXT?dR9%$XGEd5*?+zf z(Xn+ge-0I@t{dk+v``&fhyT4A4XL`Y5YJM$A`16R>Mszj{s-6P0bh?xJFFqann59I z6ue6Ml{XvILbyajyqN*oeiaGfG3?AUWB=JuldMd)?@&dX`12DCHQw?*jniclGt361 zmq3{a6S{k8aqA%W#p2M4M;%TmB=yw3NjX^5wNB5 z)VXn~kVfjs6x>$S9t3N8f+qO5jxNZ+*Ctf~^VSZ+h-5%@5*W{ zG5yT+l&;=kI7ezohrX?|*RHI+$vmPOPT+MCruKSKuhHW5a!+UKEfZ`%9OqSq!7o(!n!y`QZ|Hi= zQg1PgnWpZzVhOPiolyPcxyX<-tf3N+-S207B z9ugpO2kxym%EP+pXJKU1!ooedKv675qybrNH}YRf1^|N5w0TxYq`a@u?Cx;T>Xv2r zIFk`NSU(8EuaMlsUMS=jIZs&u$u%c5idn|T!}r;Y-bS_lS0%V;2f+Zn4_F@hX>Tnr z50NJA6t$rgmulBx4%BXDOQfyBdS@$*_?S)N?Wqj-t{yPXBzQWkV{wYwb7#O6S%}qu zTrl=~3(ED6<9TtKzLq`qMX<+5(01?qrRX1V(*SdD#IDA&W$$-eV(D31hC~LGYn~6h z&W;3qqdsY`94gBv9v~KmKL8fs{jI+F$OO9VULf$2^ADiK;G=TTzy9Sxd!FP)R5v76 z{N!b{k4mUY&Yr<)fIA(C4bk|P6nV!NuN}4WYcJ97TGbQ)o*X- zZpWwdh<=GrO{yrJ>H2)?jYm@#_z%#Lt@IxtcfL+}HXvQN~Ng3)hnH z7%_Nx5A@SleXS>^t>FoQ)$Q|Kkl~7+YD6w@flZDX&eUz@xB<1AZQDYVL)vn`nidXo z8!2En{uq$r#mqWM7&#`Lz^AN+S|)TlPr|YrCmj3L;(zl!Mek^KFBdgkf&Upx2u6q# zRFhc2Ck1moqV68r<$r|w8|Zfacl`&lGfA|e`0QH-NCk*wdfaZ}(B3+BrNN{0!psfM z^cH+qzz)caQ?RDJ&jSrT(`~$*;Yhcf%!wQfBQfZ(t!KGw{0HFJC->)o?ZT2av^N^U zcm(wlsr|wHJK!a^gt79Csv)dUKCrL(L}`;=wV1W%KR{o;)O8tjHTfF|<8 zF$t6VLWxB@h2BYe#FYhF(OW*=crquW!Y7r)fP|bJ`eXh|(sY&n3;tXLvm@}jQP^_T zkG!p~-6`0u){mJB&E`d)i3N9xV^1rmI$y-j4!cgIL5knki`9I7!18UJE)%`!lIg0l zw9qHBa1Xq@UzQL0PA)A)V5psu}`AvB~@u{Tr)mKf4>R`54Nmlnx>@du*^sO1t!AV`|)onYlL)TCxu_c8sYDD_s+S z2+`K0P(SQ*N$X7DX5MY)7WxcG$W*zKHbI7MuL}aUXmj|-W8VA--H@?xvGkt`=eyUE z>~21Tv6wlJ-Pm1dbx$b0Ehfs3g#)|Ao7P8XJ}ZuTHpw_TZ3z+<2A}ec>(|Ak{X^f> zZD0Fzi=08t1-c#j58&xIAhl|ja&lfE_4jMn8%W_tE~x=}+M6fP(!8N(*p=c);p?D7 z$KhKsOo0EFudDBKjW}DeA0jJ{f&$|20S}0U#HQj%M#}dZaPH?`oIRxxmFs>gSs@?} z-{9-V~w;P$X=<}ZcL0Q(??A=4<- z2ChOCD@d`suLt!vd-U9uniMn(+Q{+R#M18~z&JjqnQG&X;j%xy-$$R*7h++kFnA7o zpBED!ezBoh&I{LxyONxG2R3VG<3L#JTLGwJ)Iu>yGZqaHaqu4(LMFzE%{@IUS#;xyBt0aX~ILu*ElKoMpu;xE|j6Tol_p z*moDPGsB0t*22ef%(KX(R&0~4YIi{fFS96f zDVFn^kK8~`%lmZ|&)MvQb{#cP^!|@ESb55sUN$3Jj~G`uUPWT*w<#%x!i6Hhz?hrD6fNvDiL-@7a}Dv9``jM*uc ze8e)Qsc_#*V9YhR7(u zPE)1{^-kSIB!^!N$?B?N+F9M$ms3ucT_qQCnr!v*zG>lp$2~ufB$kaBq>smtNf(mp z9s&Z7yN3iZ1aNipTPZhSnEoWUC1aayoYIy}8p_1Tq-s$#ei?K}0P+jY}&>B}HV$o4|M-%m%exVqKQkmM z5!%Ba+=|4qOt50wiQ)!@)l*CI!OM(k+a(H_i0GHcI0?i>np8I;nsZ(*F^Sk`g*7Iv|+s2qi;wO?2Q{D*Rr`qVjNlzpBePrI)jvNtHA5j}M&5<>eu054P zjw7jwr{O{y4FqPuJI+NAIDS`m2tO|Ir13m4Xo~|Xrx)YnB%k4A-L-TJm8B)8p)8u* zmix|K9HElmVW3!UCV;`YVKoF>N$>wo`9_c3loynP|5B$rube0W#0y4O$@=(2 z>P7jX+Kc0-!`)V#3g<_^fPYdZg2+*PkeLS3}{206|E5K-nCaKaS#m7sU)JQ&&09BCv;dLSwybUKD#dI=?K`Pk7Ufm8noU( z8W*bz5b1`W-#h7qgXp1Bk#n#A0U!qDI_Sa)C+aM1g8D9wwGDhn;-l^JvgJQ&r@Uhi zrRVY|g|7v(5LnE5*=6HBp@;8v_l?8=AC5vkr>KtyTF6$fcY;GXl_IUn^u2bxaArub zE{$;RtcBL$o_UX_urYKhaIjpKYecrU%=snhV+|ecxGAm>FK9@;Rr##Sys)`sA_#%b z#LJyQp>%=0A9z)8MTGF?4m?MFX`<bQ@DHJK68mN-BT{qd!+;U%XI@&aE#@YG-(38~hL8sBJsO?O0dWD{YC=j6>fh1wxH}atP!sdZu&N5wRkE zZ|_1qOd39)?f=!kpL7$--mW_=2v@qQB4TYzVNavJbj!Cuq1)-!@|<`?d~O6sMN{aI zP{qybp)p3^7@eX1n~~<2guCpks!kbqOhW;_Okx#|W9{yhsRjET_3j`k7pRAXox{Aj zb!BIOWAT6yx5wDnYll!|ek2LIT3J}?uHU<|y^z?m_UfYU0ju68z~n)vCHj$hX0?46 zrVuYTAI$N7S>_oW0WtO+h0<_Ml2g&|GoOg;dha@{51827CgRKckis4#%n2&h0(gS^={Hhof~vCh8YIcAEK4 z@v1TiMJ3*YV{dn-w30R!m(V`}&ErMqZ+=L{;<^ok%y2=%_(OTEeFw#V^KQoVnJdF# z7kk>j3ocY(bQ8s*1p^fT+QULNwn>!GRG8;W$iL}8QjX}zYb^cB@JNojPK%t>L5^PqRo;^4jpYXL`S zL=1OzriwBrTwUg&pGqc>?`3#jqklU(+G9Fn*_jT2e1GKtDBaoYok_)lx&=EzDg(c zm6}(T3XF9^Plb8ja6%&OmGpsJkD6;b-7KV9yGXvC6}J{Gjypi$3@7)oBG@1~SN*~Z z-R8dBXk{ z{(&3Qig;PbgvdqkiNz9A?g6C{(T1F&Fh0iS$+YZ^UXOIn_e1M6eZ=nbO0>w4t(Co8 zQh^btMwCg+i{C=0S=XNUEU0A+RF^#$B@htloj2A|;SPu{4AU}2z2Sal%0aIuielwz zUdb?6&rCFxs2|t;?3mx7R%|xNc?aM5Y^|dlKUQ~^keP!t#HT!GXH{g$`jgqNGD0cyigOeO`7u@OsK9Ck3+*qlDW7JZOl&-;6dm-9j`J ze(fPJ=!i;iay?2o?HW{85)?_xkEBOw6${9Guxbq!N8(A;)nbu4;trgi-~8HXV8$xb zHrjtz$$kptx}RudXfmfyUACvnAf%Rwk?~22`WYO>K4e9(&t2 zLA8(5ZO+@a+JLeL4X2%sAxGXSnYuL51{h|?@p|}_DcpU`{ZgKMe>~5LyomV1*qy-& zTvO4mxIYzd$|HtvHumq$Ox>pnM>pJy!;|=|$kuny{{rAu^wQAD>btMROf zuhaHU9q8*Nm3JGw3oCPOG3<}6#$wwQW)Dhr(I~#+lb2Le%Il%hw!6+)Gq=qZ=9%lNDPWVy0q zT&(vO?NYL3Z=QOV~ZRtMyR5SE7jsCqKXi+ zPiN@rcZwF5hbJT}P1Zw!O9@d5wo73gzGt20&OCuW6)RU@eNmLIMSMxz0o3@^GvNL5 zE}r5>mbgwNLUL;Da+X$5+bNvGu*0jy~pcB`$%#EoA$B zGwHE7q$8^406&$^xb+@kX`2;9+U!0?H0IZv_=ec}dMp#5_dm9n4|l@`GRua5Obn-Y=HZ^nAc z^Ff1AM=6G|WJ1GTu6s=O+Tsb!+&PwJ4IJPnjgv+<2kIyMC^Y>r$9xsbG%rC{HQQe5w{) z?bh|a;b|yR6r+K$#^(Z=($~H_mo#6P;+C($sh&e=-a~i}N(t&KRMZs(HojfPLQOCi zZ&)Ofe7be1)pNC3WEC?ZlqE#taf3_?rw%Q10+$g;3Oj%{`FhmUIFmGZvaHl#QtuNP z1w_R}Q1$ij75bR!>G<`m&vfC;=!HsY3UCg94s6pNRhm>q6uiQQ4_;gk%Ac~Sk_)xU z9!eRZHj$(z!*TZjj~=+*mD`Sxk+(tOF<*rogm`b$7&Ys?KEL%>yWwyl3gImy$b8AF z;k1qV{I;te`Bm$`^!zB_3(*j^X+$J=6pz5wK!M}GuS!i4G2{8yu^K%~S{{Y?Jah#V4X(F_WLluUnLZjDf$1+Px1P3gE@ql$nHwk^;)N@d~eQ>4v0? zg`NBgj%uuFjDS4+cctjF7&ywd&3Nfuz^xB-q{L@nx6=>Xn zozI5U=eyZss1+r!lZ^D*n(akYb?iQv+LqsJtj#tNJ{c5@)4HfM(?P`y4UT*%$2$8S zTW66&oQwhhKP{>{N0j4jrwSv-V~Tj$r8xSV1e1~h$=;(Rre({5n5U|FvkFzY!7|l? zHdgA#LUUW<_D$(+ZsxJJ!P1c5CVkp6q{`(`Wt0NgQS~?nVfWUQt+3H1d=?fmmz_#C z>$tA-J%>G$qbG-2cZrW%8CzFaf#`BeASY(ioD;Di5x=ObCdpy+b@i@oakNYu&h8fZ z*+*?9bw(RVCZ_k@kndeDaGKpF2MctavT;)6vtkTLQisH)E1aDF0M%MU_TlO4CXVcP zskOEj}HUR0ha=-gid`P=#?#otP9|4(b zi+GIVlGM@^mQW#N>kTPoa1APuLlhkjDM0I6SoGSZ`IH0LGPBz;WS)7os5m>o6*#RwQZT1^d zWVbL)DJ5LZ4x0mzDHdXgQ65{=aTj)KO}Ye@^0IM53CYjh`u%jOOF2>T@T=w%fDfn2 zyI!h`*aZ1i6&wTi3ieJ(HAQE9c~FpXxw`#qWc~t_TNoRCD#fAG=bF7rv9ahn8W&8k z%&XL|lw|ZHG_7xW*Is3&8*%sDaV;>zC@wnk)Iw5(qzsZt00Frsn`?9df!D(|Kf4Ha zE8;(D-YaSAUY(zB({_s}b6VfERnk0L#gj~1Z0L4$+1EBzC9YPRL_#~I5T|*FP6Av~ z8r9DYBo3&V)&O7g{uAmtd8+DLPfjl5`PV_>k=*RYj@7-bcq_q;OQ;;ud=cRui5Ctv z>*nRNXoI9Q^c$tgxzXXhAxdZW#n4)xViRi$F1;b8sS9a`)}Fm|*KK`$W8t?6Egg{V znlG~NV-6Zxn$X-1k*O>u;JsY}-pV35eQLvjI%#d@(7VI|9i{_O!uVj39@1JDPIhzREBfPAYJFM8UM1TRX1;MtjJF$Jyw=*WhFz5wRmHS0 z@4D&OFrR><0?lP*p()wuX>F-&$SiVas5G9M)i+pHD+Cvy=-9Uv$cV$s=a_~9i?U`& z%a}@oXw_Fh)M<51-Y46U!`(CyBt?0-SLWogCFBwD zWvC3?mN`awxeiBKeAwr#tcH%3<9)+3?>M-CUjE+A8r->)=`?iovenE6<63ea>skf( zSUGmu?m3*S(Wy;UbBlY_`jYbn6B~thzf8HqZsQ=!xHi;@4m#L<(xnx+60j7qqExJ$ zoaT^dqP~b@8yf^|&W2Q(8@P6lygak-04t`#;>QlgMKk{ZXE#*#J64|q zao7nfW)};ByR@lI^R_@aNe6E+NeI+7xCJXSLuWgqn*}HGtD9hI;K7FAcVKI}q^JTNtvSyx@qT`x*qg>gZK|`-8&_*&8GxMf> z-uG@oi_u+ol;uSwe-GhFE$BN#*f8!6MR)m7>G(ca{{Tw5Ix6DAckXAikL7d)5%=bl z4S|O3cbY`|M69!#JQ6U}7OBcD$XY_q*(4KHz0s#fJQ-vYxKB1|Cgq}Ix}_;C$b|Pp zw>o-tByadrP3s<{wG!kvl_9kJL?n`=f#y6uqMWcq;na1HYGEL#jQyi7I}`k>;LpPQ zDUjYVoMx;gTkTgAl*o)5Sr|KV{&drgtnQFh8n{PU0O4KYau3#>P_cmebVmUhU; zTIj_qI>2~^!)Ag(xbxsbWL>yv8do!rTu3BjC+r%=7hMN>x00aB)_{K3FEBq*QldIx zz5=33O0&@+SwDCCRnnv6a=3)8Bw*J}t)4ucno3M2lB2B5k7kMxIRaxug|c!wj)(56 zWg*o4wwzD=xv7;qO4=vnxf!st{J|g^YD(eE2RVyrDINtQBAv&HM1A36qolxUTbx7? zqVG8!N{5E|qrLr5|~CFpBf{77k6wr}^`Z zs_7TbPy9ijoo1BqWwZS1^!P>%T(!YQi5$+TWBh`-HS~k;F581*B>RgEwW$(1tnK7# z@fw|^?i^NYHM7AeTXVXjk2I#1qi|BvoE5EIGxmU_orzJ~Tcz28Vn-NVIfU@hoGdcvQw?+etW)!qZG1bbF zLVzTXv^v&+e`!lZv97xxNw~#eJvPx2WKu$T++?LGb+gmWOUKCh*BhJ~_J{V(?6@P_ zbiTN_-7FB@?^w269&$R-f;JALY+)d7l6LD-YmUC#ZX$Mr;GOS<+*XTmarv>!DO|E{ zEfp!Xpz^F_fO0n>IIBz(P|9A)l3Q`r@8nixUx(uql0_~a!0;S5#~t1zE@`D@6At^U z!k6vq*&uwkq$`m}z9_Z2In~Hj*Oxm|#kAl9<-J4AV%w`k7Y?#^Hh+RM<4BVg@ez)j zQp0Ng5FP;TX&PVJC;ZhLZ0@Doph<&u4EfTNd!&y+y(WQ$0pzSwi$7=e>t3&HSCgL)IIs4tue8l^x^@q8U=qge5_MuZyWlrwILRNh@4>k$~q8BoYQ*Hd1(2 zC@`v)kUH{RtvrYq&%*j=dugi2ovC|K>yF#pPPJRD7S`+>B-3&kvuHgFV}{H-a+yO> zW478_WtMj;ir+Ei__2UOKqp^arTD8JQ)=N}khqCjcGq%lPOZJheD`|3YhoQV95-ZEL{7D>3VBVHbw{9lB1lKN*cnuBJbt^tp^erbC3tal75gm4$pK;t-oy z!q8n(l0fUOm9X=_A1UsVGJpZ(Kpwty&YA`eqeYm*U^rZH?YF7FAf8s#7Bg|C?|8XC zyTAd${({4aQ*(fp*5z<|RFx?S2;yAmj+2m}mD?+T5aQov_`(-maf0WkhvCS?gGW8IhK{7 zt5vnMK(?g;KL7?ic9cRs9%ZQSl1;~CaN|*nHnK+bSPO@Z!+iIgM{8AgX)BvegBnI2 zv&&jXlbz+d0qkTwjYBw2Zei2mD{{Yti0Q8k3 zgSfXAr6d0Uv7hP-Y!Kz96sYq;O5;fZ#}tj$$yVoY5ObQ&cEN7CML<(+$Yi7x6>I=L z1IOrkRBhAOMyA^0G*kC`x5DRv$x(x&vtqe1BpJE-yLh_TDo@^?u?ul z(^NIFwh<%6+Cs|mbS;KpB`hjBmEztH*TS2U_-yhrZMQO&bq%}^Df|Bb-jks5MoSn? z!UIY|a1^wxwzH2jl0OP|M&ez9LK3H#l+u(p4Fo=c{{S{dN79+vx*lYCre1G`x*g48yX<7U; zRh*rrt_UH?HpddKrP7pj{{YNAX-3sb-`dCJaFKo=3-hO(c-W|?D&1+G2ziE`=Gc`E zWuLFw`cpo3fVVtK;K@{1PT?v)4u22G)WnydG{wmU=3}88Fhhsr{kqx-ZXi}J$$~n zr$vWYw)jgE4i-KVrG25{S%P+#x!RQEdC=D)J_>v2>F*Lj$lX0~aq_HNe$Z?@7dF_h zc5x~JN=PYa9{{n{ImgR?3Xx?@Q#W>7b`YVYp`M-F&|DrZDdN+S@O=BNC&{;l^fGQAT8$-(DPOR`qjPHTw7qJLNZe0fPJMA%9B`<`LEQ!Pw>P@y#~ASMQZZE37RuQ?*9J)*P69tF zk7$*s<|Djehk_5;Q|@;mUoK-*R})jO?LQT)^~}U5kGnLeql|mf1c&PxNV{S9sRp<7 z`+FJfe1GUQl=_$ce3E|MR&T59Bul7ZRHurXvj3;~ye8onF^;{W@g+@YBK;0nc@ucP6rG;}e zqMi1^#wl7VhttWt;gaUIHccMuU3DY)g>2H78*9=~++}hyLR8)mqIcY<{VQAA=F-uV zD8?9XydfOEH6i8QZj#$AE=z&3Fj5uPm{)5Fk`$$YcF&Qk1x7U#?PzOkRb`kwt#K|l z3Lo4o$}eQ3alL0dj+hB?UkBG1KRQElz?QOkak<{OZD@0Bn7<2= zkKO?>TS*AP1ZO=(Bg-EV-=XPF`->@LDIgA*%{1LXDkrXd{A;$jJ1~=LHm+lzG5u?`;-tT_YS~I4;BS$ztEW0E=lyEjjF5b*rds)?&e49? z>Uxizepl*#(D~Pd+}!|JSv_J$y_SqW}&cf zvtMw{FTV6GMXTXz%UdBuOxq@ia}qeed2^8Baj5rQKh99LsG#yX|c`Do86q3PEroEhR}H^Spo#Yqr$7 zni(F`sJG|yt&**Wr>KRT0Vlgfo%q0uJ=a*p(YEs;$T|kz&XA88>1$LpNRE^l<~s!C zE-qP?U2$qzSttVm0ZPYmG$i?MNJ);U(V^QU++I_OwFw#KhYy3)mJ$q`W zF|mU;08bDuJ^^69(K^aE4!AL7cl(=6&YYLZ3ebY$6BMN2by6fakPgQrRtu?N+13}kX}x`W zQB!V9xLY**G8Qo*zDd&NfSl*xQ&#+vIz51QH3_tH^cW>W`HkP|A-^>*fWy;b(1V~Q z-_i;Ai!AMG)yB}`BPB{Ma|DEECw+xUJsm22`ZG#%IBb`G++{k;4W*&*6#}JhqtnO%pHo~VaV0-(NW#Y7;ut@THm_VhhZ$K)o{p^NAd(aEAcOalTREM<=PeOdry`QW z4gIc7wjVDVh#W_@CJV9>kT)a^vCHXI_sHPw)~j=Aw;8-tMUkiE$5MlL1(YP51(Nnh zu4x_UvY98EO9#-i$^QV;Sqk8V4s7g3aA}V*Dp5J=JZVM}bxq_Ox?NjEx!$er7b47Y zg%S3n% zY0I-tHroZ&ww`#;A!!Z~wgJf*13P+o(;5xB`D<4sxQ=omcn&tSxPR#fH8MDJ4m`bc zp<_*i&C(40PZGyIB1l4Hi4LKzq8DYNb?524$I`f)>QaS?*D2Q=YrsV@#@?9329#E_K_!o0+q zmlNLiYUS}($8k$c-l3=9Qq&ZYf;l`q{#3>9aW@T8QL&j`OC*B^S;+m&$OqIMeicbp z*U$d|%3Asqf`1Bgi`Bf0_ow7iYw+IfmW9EFV1jjEU% zStMv+aJYBDVn}grcJetA@<8wdAXANrlU*C6h4dulIj6Fc2*@J`?lokzw1b=@=gJ8c z!Kt;)f;_oSbc+3cK%GSmh)Gjj>iwG_CNg`BF}CDON_- z@l8vT60GF_6HJNifEF+?27M{}J*9$rk(`aGp*e%`WE>v8bnX`>RV)@Z3l&{hQ;Jt8 zIL_zw`r4XrFjJ60+tRXa!GwUVw(12kW}yJ63}l>C#4aVa3b9idYp$9vZJhYf!Rz-5 zt1UdI9$VE0e%I^PoeZ)~7p08ze9c?c%DSJOTc}`~^*3LYQ5{LDby2?>5UTUKm8ZK| zNaX;5(Ox4pICMUpg{J!`YOQ@av^9U?R}=00Ak)vtWqhBy;l%#Y-`!~B4}wZG+g#(A zVb@d3lgyY(go3o-0!axQ_3*_`?$w_4ptQdOcm~2$%J_N0)-Jk&3uP-UYAr)4>y6pR zRs8Bo6&gB03FJd4en2NXWy ztRN~PQpdV?XeVSR5Fjln&QE%wlksJt!<`E%*QNA!n6>v&^_Hj9_S>vQIG*)z`7ZpiUh6;uxC<=WqG#03 z`iVW~5>JXKqKa7}iYTIlB8n)X2&rknM#A)VpjsA{Ev-O1*1;uBb4P2tDjC2EhXTX> z?H@a<4$F=FW;pqW`ZT-cZxr{kLGSfUQH*fWDDws6wLc#{+O^I`{y zQa2^spD!b~%vUm;GSkYqaTdu5)P(of7SM7qk~_rLUHz1`TpN9o&1YJYh!Nr;vfg$= zQh)*Zgrt4dk<^g*MV7C#@di%kJaJD>H0fJ?t4pXb$`K*firoNYq!Ff3J?i6>5^)lD~ObU zv{_+kgdW8R?(j+!uu^)FW)8ZE;(N~XT)asU3lX688~&QA`9;hH4dI)3Ai(CER`kL zS2iND?{zJr;uho0rE$W)h>Cv2Z)K&=jhdd@+UvA7o_;S6tkXo^8EFfwa?udW=FkEHU=6%#Vl0>y1vz zx2LCSiI@Abm^Pg=tTg7KyULR9EEw#?yqOQBSUks`8x#3(F}GCgYoL$XYwTCUP7XPu z_>aR&HNL>t6tpvvZx)McLorRp)pdgFvJ#x*o=UGNaeTXTX8-~-qyEG^54`cB>)G$K zU?D>ZmR1gOn&~I@rMRyF%hwCI zCvGs~v!t|iYqXR$5hg?J%(}!w4TS{~(oy@d@SswXqR8BUMJCA_%3HOgIe>3~0p1-_ zysCV!u8J2ty04@QiL z?K;|(@D(<)rC{T7QC;YJ87=xdvTw5Ywl8S?C24^JS!q5WUigJ3?RrR=65{oPLmT`y zUfBy%LQ9VV-#!-)U$W{xsr49c8|`tr?j$w5fj7+e zSop3KJ7vbaaQn2!5jaII-tDE%7hhb`GN36#_)bL$3tEyf%2$xGg#fhY3rJW{5$ZOg zavmH}Jc>NZCvoRV8k1G(U3sWAj}kSl=4PYT+WS+_)%vqh+?)>FueU3dmu60w`hWnq z^Ut{AhyyBFq+W*0k3IhYr-|C6jpspIwCh2s^P{e6x-`)a^7)c;u&u>@&EK>0 zv7fXrv;P2Vodd_+6t{S{ptWtP@t}B*W7HQtKdZFN8@0MrbU7SHkkc|5i!R~l@)u!!QN6Gg<@`Q>qtw}Da^M$o#Vc_FB2-eA)#$1r?C$L>V7xgfB@*>Pz5e5)iU z$Q*R5c`#XLKfuVxP@`CzM_*LiystP^rLQYem6a3bO=i}fZd+j_j$%F)cq*%t#`s^l zbXLk)*;N>L7Adrda9&p`lD5upNLkP4S1Z%;@yv&|JqaY|@6CIc6>TV~BLsZ`stK5& zIaGJ)gRvN{I>$nm>a^LxP+f%}?D-!hf4Hh<#_#gVK7gp7%$m9~)wn9J#L6J-uC>tL zTyIBpMY}z~DDuis9Wn+_;YtnI=PMa~)&Bs?{c8T*D5b=l_~U;Xda_0mq0vJ*q}=B; z=$4I*es@fSX{(yXP+U3kJ!YOm+0NgY8o zu_f^HQt>;9+)v|fuwgA}J5&Vfi-pbP7i~**>wHzQY>K`>hZPtvyHOm8KJSiHDQIn4 z--g(6YjJrYBLMhUX1$H{H?w)(%RCcLXx=~TgzJW_uj)-tz-<+$3`oto>(99j+nv}W zC%uN-5=*YShTCc3k(T?)VN+8L9IdI5w{?gEEp9cr8f)IB=qa633!vV!H=0gF@OL0} z;&L6jE`NA5^U!SEU+n>QgtqM5HPdd{w278bW50K}Mp8j+sY(7T2yui2^dfe^kO0+x z8)X)_bpmX=ip}p>>xpj2isWMAr^bZRR`dPoZ@^z`XTtE-p#A%PkrR@fYpHG*Lxs>n=qUQ9=<#6i|dwMHC?wB>OF1BSGRc zt2DI`jZvp0+T#okQz4Z#H3dq>K;(@2Km=s1J$4lvDPvFGrRmGz z^_`0PS}JbYbZT3zjf(rVg#q{q>QA%Qo#E#aczW8z`}j_BS68wtvNTFPeRK2$H0x;@bsX z%jijM;0ACCPDkVPt#Rs$tCQx)Q^{5fhY4^Hb~|;cF|NBnr&572$qhIqpcC=)WUIol zdRx<)k(@Y|QsT$j03W-Xm4UH4%}04IGr#cCK6Kue;|K~-N>T>olYlEY zY7P;|l7+u$ee`E=Sy6GXKvH^rF;TBk*zdNBn6^(}cvk9LZ4Dts`3qXPP}&i>Qj|yl z4CIluF9c1L^$uz>vS}$=Unt9(x=q2B`^kFDFV4nE2bH#p|5*En;-jT^#!A!*Rs4#^V3r!36(QDH=B zEteI56zi%0bGWPwsQ4uyU;qWz3Bki{JmW3_Wm`$LE`IeL6SLw+4&=Y5bnTBxSgkr| zOxmGYEEYH|+ifLNhFeM=D+(?dX{#x_OnCNG5z9lG)HHR zC8h1w_~kW{6(ZVe{`bIOnfeJ*R|aqUgw9j~=Vw)>CLlRUYmt-MFJ zXbW_h&Y{G|XG+-N#gci6!jP$OW;mpRl2YMFQce^n@dDUz$!ZVXwq6AMl}iGN)flu; zja|pK;C$BK{{Uxqvvi$#?G66fOq{#!kL(rM(W^=)DmjkKZE3CAe%{MzZ9u4nT7}%4 zxUkaTHk73#o?T6Qd3!_2;zw*QGTbFe_qdvCS>E(Lg~p`&<3)>Y-PLzZE17BKZd9v) z1u6;UP{793(jTx_S!wRfp2zOjJ-IFsV!Nod-w<`b6rYIXl}M7%uv?RFuvpb0K_zV= z=9k^=k?-rk=#jz?X-#2z;@=oGHOl8X+m!iomoj9hN5uQiw!^PDuY_ewaH(oOB$|VD z6KVaHmFDG*-*@pi1M@1xDxXzRTVBy-xxzMgH-~@$D{vx0m#1!0oNz7Yr1L0epaI}N z3hmcRU9K80_H#Q|-fc16l#Nvq>7{NfilCPnw%jz`n$+{BILdjSbt=a|r5*8#;b(+z zuG*;RlFkX-oB{Rg`O$H}aj>1hDg%A?Qn6OoL&SeFoYTFUdqnntx?964*St%QqV)aELjmYkSP6P^GmXHJHN5$Eeznivwzp2l zv-aoXRLCy1A`RD4Png54VNI{RxJq!~jj{^X2Ez45I{m=p`ZHoEpcDUkojBfuKx9TCs6BoN8-9DkGmC3I6~UBFTV5iWoWjsjp(b1ImS~AbRdAA~f?dP?ap?<7Ex` zhpj_7j)}_A8`)66LTI}Qeg#`}->rLU8QUdWd7M+RQ5#V_s!2a_0;#4EN!dGkc-Nv_ zkYUYOL5;|vvD>9SV&F8MZlG=HNU`H!f^Y>ZrNkjUetXhVJ9wqy8;L==9oo~r0o!_a z!@Ku!mY#fapn+J~=^;Cl)2EeFRnw8D2R~Hfug;v(0@s34buR`o3TkQ?4(lCZr*z9h zyjAM>#1)|L%-WnC;Qs)mD!z#Qfqk4km~EYyv}X`C_XTuS<5^F!qDwc47L>)6CABt^ zR`++xmkCi{#Gpy#IV4vA{hlpNYA!x#=@PexZo4q^%2wzc&Zj5nGyecpcd+klsCrX_ z7L7e^oS3jQ-jQl63?cqhAu-~W91m4U=(VSY<&bnV+=UmT_w^XiTzDJ8afBAofW7}}$WO^iKqwz@_EkopPg~a$> zNMKOD8Ym)pyPC#>-WnCH!C6rm&xcx~$mM9CKhdwrhndU|KPvZ*R3v>*l|=<$c1^mb zvw@E~wNmX zj&Y5t$83r3vm(a;{7VWr9LE_MIPtD!a04`?4K8(ts-R@B%MG22!v_O=k+o0WBJrb5 z+PGz4b4lMW*4<%z({@`vx`n2-4C^t}=#6fZX?`5=m6S(mu?jn?Oit|&vg=84wJ7(E z#w*^9VHSwelG}(=C=T)hRIqjmQjR=^agQp*x~z}h(~ErRWV%$!R7n9pU>tej2?XGM znqc^0uH19DAE)QS`q@jiYK$|aXddt$86Q!9h|yTx^&H!jtEQyANnEoE3$vt1mg1IO zL}pKR*EZ*VL?C*RP?AIL%8>k*mCp2+l>4eZRHdk?N9swb5yZRvn?9Ff%LZy$Ua3;r zyGLc>nGQpa;}0PYB!A(!@*7akQyBRgjy0=neGr0$)kJ&d!}wc}^}nLdc8aLYQrItj z(R1GGABDY9MHE%JSCK^&P=rxM6d@E*MF>R{Q9>5XJ0)vW-LyclNO2}+lb)-3lgyRC%|Z8#r}qLrlcZL#^*r@J)jr*!8NU_mM8iK-&GVvsq= z?pAR74uQ~+wnKaLOY1#xTVROkmcmt@Vg?BDBCtKQ!~XzQWAZ(NsV`i2pL_d(@Uq>u zLbzg^KE^*c#ne6?@AiV@PCANy+JZ6R@8@r+)u(X zq$D3OD_nYF@aCDn#<_;eiH!POC?_1?5KmpYR@1m&+k=LBDhncIxu~u-kz+Xi~bM-Zf-`t}1tZxzSEJoD6eI=;?Qftf82;%W9>%d43U}Qb4B9vS+aT zZrdHFwcfhb5z_wv54b^firS>Qf~Z1Mo#U_JKV?cnJ>4natBdKqYpb*$w9e(l1pff+ z--gi>2Hh<85~Rs|`?v?;FFw2thWG=2EN@%a_9W}QMH7cto(ph}G`q^C-O+vG9;Arb zWv8wa7F=bC4gyqHhaFpNXJ)`8qy&{*He+UGsHqPm28~?ohxzbS-MQMhjUc9_H+N^3 z_+54BDB34Q*zKA_N+KjHMUpaL!-)wYO{5?M?xc(1+a! zc^PY)IU^^XWCOn`Jx?hf)GuttyzM=5yLNf(p>w!s?h&QMTXmNZAii3=>n>Bu>k!^f zIT*;naBM<;9H@mNe-x_2u=|MLyaydG+&OlYn&CKJA&X2I8#VOrJl6jJdsBO6dlB|+ zx85zXc&%&ITFs~r`-P)TDK`|h@*7_%aFqg}mGWdH5Oemc=4Zis`gn=kFJ18|YJN&? zH%(EkTU*K~a#4OX#Dy%7PJiNgyz-u>q1z`8dn#%DNyF|g>V?W;RP8aL=G=jF7haVp zH{Oy~K`J-|lb`1CHL4!Znt8ikpyHkUr46}f(z311sY@V_-XZARp(CjzBYzBdXCkFp zj2hfBW-}mk@6+bAiVc@IHYZN!o4ZroGx;s&@Y9d8xHtPh8efGmt_t_wFY$`!X_CTM z$|FRWdt z-4V22FWRKtZ*v=LB~lf0iFI6d)OwN;9Y_9Ot#W;5Y&&tkN_E2DyQ`R#-~*64)7p~% z0Bo2YKxqEZq2cKLk{*vBT;t*i1wXV5HNUBn(mvaZQWLgvr!tZG*MD8AIHwDMU$ZB8 zhi7%GWy@6Xj>Ez0XmML!9>3k~k*|HSQO&aCY7?AP{pb}Q7{sub(qpuIiC8>N;cV+!R7 zi%dI;REcFPJngCdPRK}D9~>=)P-<5PX>3!>{Qw?d8-H;gY8xGJ0+tBQZje}W0E_ZIiQl>$%aSwDjuG@ZttK5$=y*4XdMmBbz)+4O*7G5$9s`OHUkN%0(r zTGf%h6IjfSd8toOlk?bMR?fYPiqeriryZYluD6tknrDVLN&G;Xw>f!M<-Xe}#7DB`5Cr)=;uv zL2M;z@blbOJhdwY_e6lo>9k9%e5v00nDYhr6VA!NST!9KaSLd{PF_R zoru^{Lew zoadLO1x6iLbDIsftFG;z707_t>NeZP zna?PDw?RwNMYt|fUhX=4cl)dL)phU#ZEKoJ#8pD>Zya zewF$`03QQimFSY903RVsrr_?2uWcM0;FHh+I#lfVw^ibeJo?y241(#VxOPe!Q6yF*;pb|I z_MI}tlV4fxx67TWw&7bZ)|Xlm=fy&K5Q(XAKo?p_N<+!Xbs;?I3rd}L2Wy@%>U~*o zny51+*zGTg5m6QtgC10<(h#OyYE!5ntu8dBA#LZ7rNtzI4N6dKZZ_KI!7vSsefxqB zBGIYtAa>app44E{(MLRFx##X^M=@%d zBT>SG{{Rk)sb$7mb%8xda%y6{g5+e(ODbB+TJn#(4Y z^UCR@_nb*SKO|8_6tYbeQAG$v6j4GEMHEnkQAHFXFX>yq?hQ|;Z=C8tv|i%emZYSt z^0N9IP~`+<5RwXVG7dazb=HSWXUl5@C!3Um{HMfk6AYR@HTxBeRMm`g@MvIJO7ao-$ zd4-zzY3ixcz#^tSehp40J%|8MP z*3lRw#q?5)D*c!k6c+5CBvWwL3#0c~BUMqITdl*6}L z(4_$~Lt#qz-+ZJnfRvS?w&X1&0%}fsY5lMfxb3ShTnOyzs8;U|Z6#LAuC27VwpqTm z4hs;7#u-opymWoM_i4gHitf|Z$AsaXWA?HO+mm$z$KE}gyvokvp_>`RMLZ+y+H*WF z#Q11CZlRa8C)x?9J4o?X{b{gY9+O~&aCSSd!+eOdRFxE#&_TkRP6#LLt8u!1)~q0L zZu4er!-+a04w1^B%v7o2<_X3=gKEULORK3`qsLKx;UND25zO;fNEyxP8M+{ z(QnfHE!FyN>tNMPH1SWZ8DdrVZU{Gl}e5f77H$jH>jmSTe%s;rwT%aA|teo zr;OxFa_=KQnqEq$ItNtG?=`Nm@HueQWV$o+~UDF^MQ<8YM~N>=4I^mG7YdLOe>!%H^~8{;o&O-jhMY5hCH z`|L@VxgeOyjcaz*CD&4|zzIaTX*eT2+Pt>nLyde;yK%>jd~@TS__%L;VdA!+;ziUx z=XmIT`E{3abtPNp3X-9>l}N`qZV=ZnD7r%%$Shg`L zl(lr_L06yar9C)BsP!(I)t4KllexcXyGVxRtWSz@A-0`T6tI)fXOIoSrYtv*mzBJizo7Ff|3kL|p9= zrCI{xy4y%uZ6JZnKnhPUhV_SJp}UHoZA~Y*IYUba?PI7l3tv{~>f8ai97c-SM~6iv z8yjmlg@GbY8SWq0jk0O=Viuc&?OU%LjEB}6k8>c9**gTee7$8*+gKE+mqshiVCikyhvTMZ=}SwzLh9dm?MY* zbn!`V>HQyT_S6<y2wCq`r7WkRI{xGE%Q4(l6>F%lo$qvuhSyWjhuwB*GHT#~Pi{OGI$hqz^tSL{vu3 zFg7OVv;KI9j#SRBJoA{`5>$1*( z^2^DmRjb!nIHYKE%Luh}!O&DLxlLaH(@3U~(>Vg5$e0~Kmd^h#D}d}3?yK{ZyOde; z+GtO|J!0Z2ts6<1Z5d3+K2~17sCJb-detje({^V^Mml zy@cyp0(yo^X82KSmUWdwGO~EP<5@Edt21N;A5qbFl@(2)Cq&{ua~3S(mx1!)?PbXh zM(UDc(QtKQgj2@we9c*-ABT7;;BhXf`~3FVO8K-~^4DBc#N@&SWU#FA*P5;q1Mjz9 zPiYAi(K!bsaA50u6kxZThG6)*>K-l@q$U5UJrV=l>G*dhLn(G-x^>fjt+}Ymdhq27 z#hkKCj+UwKKbOlde)nNnpPd;@6js0eH4ed_iPR1#dUOWH66G+e?7Xto=KH)q zt$yt!8IPE}Ty|wCHAWZjY1WTnWjXUITaaHoaJ%I9?JObrG4A@gwMUgb&O7vCsD2UfP$QNZl)oSKlv z7hE*L*TfJr&Z8g2^{xDNbqlBs_waR&*yOk~1MC!*)7`BrXsFxfDFua|wVtR300I*Q z&F7<$0=oG}tOACA5sMN;*6u+^L|0=0yI&~3a|DsR9mH^Ayo|R^;I%vU@q))$IZ-$oBJ7$PAd1dy(j0@NMK{wYy^SJEPfG@;AMTRBnM~GN zpYdB&R0VIv%&iIu{MPqcF@z{3u&2KSs)XoDzqh2@lT&a-%Q0hBYK!5GL@68Lm!>ChVx5~@t!an}F-q4Ou zOB4wc1L^kQvKUKQpy*(oK9jrTQqYMH4c&IQ=Zzu}&Gi*4l3Nxs>yCfKtiSXI1kxzi ztA@?xz9zo9KFrwcgQQ2>KdauCc`_e3=nE^*?bF}CR_#%!9W=_Tj=$ixJhS=CKn7m* zL5YR!tw7BtC=LExYv_VU;xM|9msmzA4#9nkc$r}HY)%2E^zCgABcFG>=FI#f;nO>gs9vZ-abpx{O~PV}W zHYSaz7w`botW-A1I{OXtx45M_FVOZbn=a-nhRC?1OQE6!3JwcIH)2yYb{1z_!K@{e zCHMJO9C+k9fDYvd975scH7n$V@QI}NZKDR;X~_~ej~9ys6S~VgZkP{ zpODBWjKC{9NJA~PrdomGeq@8Q|8LPP5j6qABljWtQ@Kjl^L?N8%J-Eu^MamuhacRQ zyRQ%_ll^P_JdS!9%gbC!rP@kFMd!MFFE(B)+)f74w2^%yG^U>Oax=}j9^l~*&mRW9 zzfFWD^VUeg%a7RCFG<^9lNS&56F&F#YgoH?rhtxxx#-mnU%Y40}48%B-B{3Bmj7f5;@ zt@=dcwW1+3sgIqo8F8=7aysCHu_ z&em|cuU$@cz}Xe1lu0J>%OdhyCmqeILBAwzq=qclv_d;lp8$`2P0MlQYwlJn^-Jm9 z6U+MaF5XqS&HAomyqc#O|Hg1+<~LJw23%Jv!hna|-%4Mr-f3BY2uk z@$U!@YvS!ejp_MCHiS&5gX1i%%j3dKYY#64ouco#$Ok6jLqq909bQY41+q;d4H>D(mA1T^qLEz?>;9?{kPex78idHqMF zQQz_Ec6)r1Z{)VgmVYv}h6o-}taZ+ma<`5K^Z*mxFhuwM$WD!?R94 z&6Gl8y}$XUQP!)TlgBu^c}H8qzryHUAta2Rhym~@9Z=Dria z)@)m3lnb6imlFe4KddXtB<5cvv(xopc${&zynCa{HSS)!*#IOc@XjZi6S6Y~vjV^K z0dAPdqV0qzHuTe#B41%+SYXUsEYzL8ihHZoDQhG9tD+4Uz`g(Pmbz%NFL>W45pdY? zWe(mMRjOkB6Sr7f%s;TE9ixbyjL?ih)Yvdv2^=r!>s~@IZ|u6>!XQx=;T8{2!#Ia$ z$Sja#9F?oh$CGd#TsjWeCuIL?Sm#7FncYj-%O1HHRAyp-*1Hnmrk5FQMYL~g9mQ(w zUuE6rzb6?Qkwx*#Fiuu^mi~ zMi$hKqPn%KC%J;s(nrXKY#vyI=_n{7GsK~K|5BpYshF4tbf4wSY5oj&Db??jo*%j> zcpZad^1%bfvg>QDt<;I50BnCJlGP1#0u!mrD5W{BhAA0hxll`!(`nZST0ozNw@t!`YxiH@svBL-&tAH2*ROMB{!Yq5 zNM_Es@i!}R#W#``MJKB4r90{R9hVy#M2^`>YAQ-#`SUbfwLyMgstxOW=xbHjQlXxg zAFQ!XmzYe|X+Lz0J->GyNf^#CW5Q-)JcB;lFkc|l6q=9_>*7$)rzRR59U~5jsY?b+ zG^bbHV)QA|YsP_>j$f{>O=#Ok^{&v%_+Mt0eR)I(5!}t7Vr|+m94SlM9d^Xf4`0bg zkX_8Q-ZIPK{R+>utEwOEv7RXBbQzBWm8XX7Cz{#%WH`vs=i@PSAQoa`o^sA=CiNP$ zVw(dBPFQ4X{H|@_&G>}+gny@BgX9``Z9|jf*)#`CldG=jqBNH4)f72YgYMJv#j9+Q zh;-=@5n8XW^@_oF#o@i^U#+pZ*v)o$WlyKTQ?>yWahXl+ zzy+N!wjtzWJbp~%5paA;~MZb}FiwORZANzo7d?V>XC5;NL@H7nW;6wJvo zHIEcB%@l_;@AxqKE9HP2Ov^-|>5*9094qS_)LMs~>PcAj*G*+oul8!wM!J>NuJ$+J zl-tk+En0>)n|`gKk!EsYV`7#^Y-1w-nE3rc(vl)UdozwCGrN&Us`eQ&fjY|biUE!T z+Ys1bFsH+N`|>0tQO}U|OTY8ZcfPf0x#VMf^=bxEfbEPJ-EGvpCA(f|&g-(VV)N6g z@N2wbx^ultni8#E6k47Px))0+-f-URq|A>wlfLt9omrx$_w45dFUJ?jYh1a8x z3%z63p=9A`UfI(JxnWaD#W1p#Hk-C#-UN>Vn3!bgHm{NKAvQ%F7W2s|R<4T&2-D?` zN_NG8_lfsip=IYh?Rz+_Y=o7Im4Q3<&sx54 z*b+lTt4)NyoYQQKgtz(jF)uP+I2DHKC_F(*n)5@UI>s%|@2>Ig+g-#RHxh_s=T767 zJ*QtES`ThE5Ko$<i4B^pCMXfKB5BGAOxSHBi=(A@VVHTL|8~*8OmJoebYSV%%nZ1Z1F7c6_rZ;k5=D4)X;CvZYt*2bH#7wCc;J~^-0dvxq{i&skYEPoLtgooCYflC;NJ4{NDZo zshmRv{ha9+Nlc_lU>X8pp%?_0kQSdFaB)t^#5$?m(s8SHPVm(yOx>2uaz%xRm#d4p zyepqm7ddMY(mCRs8vG@1^R|Uw0>*gSl_GdX=-8Qyu<5u$3d5*r?csC9`?OeiB!kU z(__IWI64$#lhSWcSpFN?!I+%1-}s6xqqq;~r>UKY!{xz-zOP5q2%j#5(e!X*pkcfi zd*$|5^!W_%G_1|xAewng*oa3}!)=SAUt=F#vR!>7WJG8&1Bj+Vpp z?d|)ANV3#2W;x<}o2=o@ZS5X?y~Boz!3|x*kQ#Tct8M#ZGPc}(B6$jaQnG#L=eiT9 zlyYQ~Y@xJdE{ODrLEX7j-#n>)`)Wv--dG5dUj2QIbn|i{?_*2GUD*>+Zmm?}pr6=__9BvcA6V`UUrF@qLYPvfzK*1y^9PFcw5|>2 zn6$JACoHUM#o^nk-j<7&8^>YZ5F}qiSd9c}5XXwo!mz4ytC?ntR71DZpUrF9jl`Ob zih*OJ>MZD8NRyI#1=NUYsGuE0#AVOLwkKGfZWcYH{jgCgD2aFQu*x7mG?Y(4FQ^+k zTC=;RP&UHy0N=e5n_*=wR#>tnt2_zDCm1P)2HY*RjuO#-J7w8t2%EI_m9vwZh8N)R zN{_ZLJYJQ=(Ntj^no-a+XXpyB>Md6~X6ibybRGz6j8YByycYj-IN!v&lvXcSt*&Rk z>Wly%(u$t^?Mp7+s&q{m!2PjC8X}l)R&R#;H7YB((w+C7QvA3VW$&k(-xgtFy6x<< z34(Rxg{|9;OwJmqLix&s*JfnsYi&nRFgrSVx&OzJ(<-%FO_g(1_iV*T-fqFSt})EY zy)r|4#>OVp2X*T~QhM1lYk7+xg@yP_@z~F^&jvM)$J&<)T2^2-Jiwt6X&XV9 zg8o!;W?>CY;CSCs?efrSb-T3D61(wx;EeVvQ$lFwJ7%C7 z`d{|F%@~|HzZeMMqKu3do&n~ zjzW%D6#QgbaPyk+(t!uXpkx%u2-1}|HrwT51%F(_n`A%p)8&izzB7|&xC`^#-b_k| zu|z$H$Yk3Tm{(nu=Efs>EXRT0;t?$P~57Np+Kh$SzSy4op1WYaB7?{j{_)_eo%g_@S(K zjj4>kIB8y}4J&8XaKaS23R{@f8=vy z=9ZX3yjyzewulE_yo>Vs62k8pPpiYrn3IlDa$fnS(1mMx@P(QLZq&Rq!;5zB@l}I0 zQ`}5A8FtUcCtHD|&Th)hYHE_s%&8n&Q0VZ=-eF1-RdaySSGL&1*-?sgrcO`YD{-Ej|_z$HLDK-xk|1`TCr=x5ufv&Q=Nx_gfs=Z8~ z@D?!k5y89OxIUV!wyb$CAV8VZyTrUO;*_TGuw_*?uDqAr0#%b(Qit!MtJLtqU>_;%By)sG=%2k?zxaOz z3mMSiKb3Fg_FgztRA8cb)vtHbbVk<8*l|=yfK$fTTA_1ubc^gY<|WHvwwaK|&;W2MJe|;@%XQ-6z6z5)EpgAmiR%cy{nQYG!EGYUgw8@Fu3hO{;x|tJ+FRa3i<7p& z;3kcZzp-&a*sTBVErbsto(wC7HiL+@Pq4M?lh2Bi>l)B6^GEcb`67!$ra%L*r$Aam zm0zp$PeFdiOhNd5S4Q+*_r-Y9* zgJ^z7y)>_B;G|u?jjgM|SJcbQ!BgDMspZ;5uy;|N4w-+SE2qfWWB^&b;TLxXYagwm z;8L!1G4O&{?_tOp36Kz!Mo3(E2Y7LTn4f=GHf1Uy_YU)NW(bbHsbZipm0T2dB!wk8ZaN)uQ8BTJ`dCkC>okpcW@H=dK!+S~oWK zRP>9p28<*+I`MZ-%{aSnUZ_xQiXcpctk_7q1yl{HB1u^vPG?mGxRhWHRPF*Li_WhF ze)QYfGVDq+x|S4I1{Nv#ro9Pa`o_#+=MRrJ{xljNVjourI0W$|r>=t9cd4Tykqb-GHSSz;6y%4<0bvSbcp_HqHX#)Y0p=G2A3+ELO zmVHL>jyTtVdvUm?#$5pkBiCpqmX>_Xn zr?PyUMU90XzK(NWlk+(C)|&?n2ixkr*vo|h%+D4R4JG|hz`vSp@}@cBZ$xc=bDyew z4?xK&kR?J6N;V&itAH$9QNom#Gc4;J2dNrl5~@m2*`n27ZP{Q`FvL@iyBy&&3nfoY zRn!Nj5WmV5kf!Z_btpV&Bj@V7Sjw|h4*Txne&oMgzM{&Vjwx|n>v%Txzo4I5r<%wF zh1&lPP5h4(#s4}maNach)q$CxLkPQ|cEeLNh`G1mZlDICj0{Ulf0ksT>Ym`@Z+oSp zd05W-F@h)tz>Q#!d+?ri6f31|uqE?;MpcL+pcd^#+;l45i54r$JtQ#pTFt$dAI z+w6&qz5E+p#KbHL!{!X;o2N16?;9plEl-p zK~-StSbua}gshnFKeA6^k`9FD18b_(t4nqZ#o#>US@%Q#z9!vm#@I*A5=B%3K}l9v z0dYWUazcl2}!neI=AGmIKPu$Qk+W0ZytOA%0%+<&F@bM_QlTO8vEv0?n4FVKrbON)3JhuAIXTPsGXi z5z_cc%TTS71L(>0z8~D3M9&P4{UUt)ynNrj3QSpRQc)S%_#u8MW7dsDN^();B66&) z&oe6^4}+(&{r1yv?@-2qpSVeNc@neo!{I@jKurf9PQO>Jil~jhh6z!eG)G&5S`~#H z$8&6I{Fk72x_t}RW^Ofzckyw~jjUMo5l!ErW$|N&9;6|`?_YcO?^-ijBqfNM?(2P< z>9Y7vCWd(z-02XdFAe*;)v@fda*yee7?O7Sc-L(t9ex>4W!AN>HidX|rcNAu&!@<~ zAAO@o^zud`y`9Y@gf3B7=%+P&ErA1$ul%yUjO(4m#H7f{RvzWMuCh+!d42z+yH@P- zFJsFc)mwChQUBd>=0rt8e~VDsa*XIcgh?jaxG7XE&(L&Sa}I5D2@qa%^9KM{7UzZc zDUmfJMCk2&n*+|!rxk2tnbjXBEC3%!hIF0qI}fR@1^<~16s*k7i^-_lr<%9qXg*t= z%}QAH6`wo*fr)TiDo?g+sJL4{7%)glluIcg1O_Q3pX>u1K_sJTB!9?u-)tA~B{d1+ zkS68`EBZj*-0TRSllhjBWF^tf>=Z%R)iD0Pr}cQ4`?P37yK)xmPOguA94!#qD+{T# z{||+}g7*kOr0TiE=?QZP{?%X6Fn3j>4V_I+YF!=TYa!_*cK(G!m`Qt#l~W4{u*jJW zF2!DV_#wj4otWc_DC-fv!U#}r*4Yp!A*uShR&}OdImI;i#lS4Je>7hY8Uw)rwxveS z*EQp!r6Qt0vktf|pkN3!=YpAd&f{^Bt!J_)(wwKMKE8)FeDc>@j8Qg8Vwma`l~+RRXo9T(I~wFfeq8F*=|w0GlTAjCo1wG;N;N zXvS@V+L7)UWwr^4)?(uhqe<{E<9M|X^zL5PM%lob06Awx{=HwW=8ALrntCsLyz9z* zl8ZmzEyi}~XOC1Hm3)YYw9qvb7v*S?V)8e#Wm)tkZ+&OF9*Dy3X9(4*O^i7({Oqh^ z(m52qspb8qAdI}w1FpT=*!TTGT;>sOscb@|r)RQi(mqq+n7764n^F{$jO7>FB_Ll} zr>iK}mtIEOA~W|)Xip3ICP`K{X(41ef4d%C&!ho=Tp%N2#q=3+iFLU>e7uHM9UFbH zThIqDPV$8*MU&N!qcYnfB*Pq!^+{*>Nnu5xNk>K2m}TFU=dd0#0gw(ghe5(SXb;#?Gq<11~IPU z`S%7QYFOC`lF8U~YQS%J%YePn`cA>0X}A40>Y;s7-uIRjNKnf0S==)ctw-AdFhoC> z)91r*m*J)svJzGI(n&BG7QLG!lxgRs!llk>2kChPGj^xw26V|7M zFlwr-+d^sB?y@)*hIJpz)``%&cRcia9)(so=RYsMx9R`^x(KHi72Y6nZ1$f#f+WYk zh{&nROXCK;r~gUJdyzC7_uca=lf%=nkeHK7-JCR#M;^>8UW6=!Oi2_Pou0)Z;SM8;86s9%}%ZFKZg8>7g)^BXaC_iN$ z2|A~lF9gCeY#~Ox*Xs~}vTexWRpj)g^O?`xfPC}YE7AM~jF=8iy-7N*j0%#z9}6LN z%UJSWk8@Kjw2?*Io`4k^t&cT{LJYo6h}5XiC_Gk-N`zgGe3@t^`hCV#%3t51-ZJ6J z+{yif|EMbPBh$Fgn}qd>5rWp=#(pyr|1GmRx50p5ej1_(Rk^ zn6vFal=D*)0Y&vMcm(Nb_7sQMY1j`AjDK_o{{pJAPN&=3*FJdb{SoefBv?4u*YE#~ z9f!)0&kampKOFZbb3g_%KdB$dbDs_T1PTJ9xooE4A)C1m_gM0TE=vY7cgdG3h{3Tq zLg5lOV8RFOqiisr7|#{O>4on}j1)dr)mdZ(*QZlF+K7pU^1iMj)5nJF7W%5}h06#)f9Y zzJ}0`GavGY$P0Jk1N~%bj7p0S?lSU=OaW4}s1GTvwsYG5CT2t*&DL6vz4UC8mOu3S ze(1Alr)TI+CuX<{<`o6keMGL)esd_<)^fk1V!sbt_5HzWxK$HKnnF4s1gmtNsOzi% ztwHZ!k$ZA!wSD~zD}-hJw&gIa>KtYfybh6D_>6<=xLZnazeGWDdrk3={isvoSV^tr zXw9D6-jYtlUD{Rj-KaJ`6%UgYOA9Od7SQuESjF_JBY^&#BJK85>{y53YT9VBi4zld zJ!L|0egg{zgc+w7ghE*y)2}BDTxK`$rh#2ciFvVF*DN5&CaX(*14asyq(RP~WX)W4d0C(2991jjL1{BzVBkr~dR+G6x2A-=aBuQkkDmM zJOjTYcsi>bYX6R~h}P(5HIbqU!PuD^77@n`IExXTbGwx)8#nJZnl$BPwz&i=wCWM) z?aU3Q1IS}DI;YoQe`U*qydCWSBFuNUpVlX(Mek-QPM@KKKE{XL<0~d6>9&3n=eISV zU8DO1aH!LaVJ%^_y3L#oaoAFYhUeF8zg?v}Ck>+Mzr3@pv^i3@;wzZX3 zRBMxYt2}w?hHR=EvY!3+JI1oRd)@WkpW+Ge(upk@rZ)_{;Wv17)lH6`eB^;#mSxdfsvdyg*HB!J>Zx8 zVz&1dsDk$e9bu9w{lCL_}rXg0Fj2`L7Xunt%& zS^)t}W}itSCmzK^tLF1MT4+(wyhxgF`74Tlj)YOlv~%ZYq$%t#ini$gb64L2(1Dw6AMi&l~83z(5g{0Epdgcpa+zp;Q0C-$S`WP<2@J&Cl>WEY@*Lta}urPt@6C?K8nMliDP;%?GCdk1#Uep@U3;KwK zwMiSG@5iCuA*X~#i|3A7GfVer*H>Hpy`3GCh=hIF_th08mMVCQ9xY30;m@?&nSh0Pn&R*zaO-e3D$nW% z^+hY79dLz1!@nJkW{;3bJm)I8H8m6Sec|rFGFy<&`b4|^!YXY?>g>PNjt}=_gCd~3 zZ>Mqek87f$bC(=MH3+3$buKHQh7GHw7U=T%eFMHq?)#IozEVk%zhvbnu_C8$XnCsn zuoQkj#uY?@8dgi)UpF>+PPLaJIK*zT>Q6&V)(Wyth?8F{{B`jEmOM@}&1)`pvelo3 zNqYNNTV^KpR(udmvG?zS2WH?N)*k&JUnJBUn3!3Gq%z=3FJU_mz&GK|Fj&l&i6asH7GKAzKK*<*l@`jEaP%7q%&cq+R7K)lu z{o>1;IAXOK)na?v7>e;r)r83vzQmiBAEA{#ileF9Q}H+g*LAkMj2hJ%8nC*S6AZm@WVhBJDClkR7k zpx@29PSpH`9#>1-WbC8H{MY_Nkwq>#v;t(11IGU+yZQed_m790`uz-b;2`<=p3-0B+w=?)m-j)&@ zLdY@8q$q+53}+0qQ51c5!@pMxzu$eIU!nYuBdIu-|ki4&1oyT0m3kBu0na4ud(!cwX@1Gd2) z?(-bQe<&MCXB1=4bE0s~k}Nf*szV&0Ok!{eDhF*ID>Di!2T~tjnO@w`Soa;jk%Cmm zO5+jz>so$an>Cha@mJ%P={WbbUM`s|1697wo#SFXJb3tis- ztQ>e@X8#RJe{bdy57eUH?s4Kejpw5^o6Eaq^BpwKI#xap_Ug&jDj{2w!Zl2hiHEDN z#oiJQxv*ed#f8j)qfzpkc#YWIDDN&Do3ulkFT7*2P~j5L2G_vFx$-fa7ADB0g6hg< z&8kD$%nr*?P6%sb^*Z@vyBRKU_BvM3s?pH(qwpkP?LnYP$39}#E9R5o%$!RsSi&e% zGV8PZTkd?(*G>orKEqp~mv*b3vpS|>)&Ee6Wr-?wi1d})Iu#DW*Tci9<86|MNV+d0LvEK-2Eb^hZ{S}LS&S&~X zWOLTFt=~O#HSRS9Xm0w;R{>)3@5+c)!kpunpswVU0T9o^u}we)5-eEfKzlYiRnuK1HBtSrn1Skt|JI=f?k1G8CR zP@y(ExE*Y_p16(7&o^zRk$8A>JG%N4o!!BgcJ(q%Q_LM%{G+#QgBA)yTftuhP(pQK zHYUH%X^F=p0l!kJj_8C!6=0XjfRUN9&mfDBDMY*Ij!5nSuM4fSpBXA^j2BhGCdhop&pArv34@=S+gaiY4QZuLdV|9 zS>gD6*dT96N+iy6R`sxnVrAmo1<5ZmGISQUsq<(LNyo1B^cNvgRGKzd7WiKpj{d4o zkGz|`(C&s6VUpaFd>bC3A*ZQkN+{&O?9ha4{VQ!d@UAqNPo1M!<8}_O*)a%-+&jV6 zWej|Uaz)quq{wW&VPW#!?%e7ORRCS-5-d&NXao zc{-L`qn**uF2;-G=GWVOLs}CUUxESv#XAHC1&r@*BL}trP;eG0%!;=N?%LAS8B@se zxCt?mw&R;tzH^LvW=b>0bD#sQ@z#UmcL3q$=RZAtw@t=Tx=7egNU}=pV~w*zH%$bL z?L?F`7$rBGGWL(kzTYH3Y%=_&ND@Sm_tpKq&UlG%-&VS~Hp|S;+_s@vqnyS9(|Yor zB9GP^ZS`vX_&&O=1{E_oq=o7}jZQu5Yz=AsT{Z+xvT@QcR#7jRInrqTJ8+|g%JnLZ zhc?{Kb3q0hc@k0~tBiun7v9}{PVg(Tag_a3Ld~KgtFz+)E9aRvH*EJx^S1>?9omJf zzsKxp%gtuvi^{~dJ_iyKrI^|bQ8nt2xEw*3>nQlMOozD)sRFG3 zakdmmKGNdwa06Yrlpy^aT?R4gb8@UCJs3Mg*amSQJ#C!FzO=bn`|!Ex%t)S6$1)#D z(pBK<&(LeA?+6Fq_ge@bdEr0K`%k+uz7>8dLkcl`Qv8GQ_s>g@OV(s3nr0N9WmcHEdYIGA z&GpFmac?BvK5nPZ1+#9$KOY7xT$i3R&30abd1V6tjKJZUrevx>Cs|b+>T_5+u{@RnAg_e0ToU8!^#ZApqgPMQB}EKhmup6 zUQ$xaDfD$f(n5d6t{0#&unrvUW5@8V(XJif%xV}dG`o+KMR?W`2aFPuOd-mOg4;{T z;_3pXnM=kW;ZX9i$jzwodI5pC+-p=#BbELK6R&C; z>`v8!dZVoLA22&m2%@1+8Hv3o1#o`%B{4d31H~)2sl9Z4WluuHo8bFQet#vc5!L{Z zU8SFn3y?-GvD5uq%qd6%|AG7PQ*|4Y!a$G z%2vI_`(`Q}{gDk9@CSr#Sgx1b@8pK7u=#fG2VBMimU*#6&hiXfky?kfZCI!PP9+9Blwbc2;9PSW}pEQ^DPTWGZlVQGp z-FOzo_zRZ=PI0z={Ueks7|dsQ z4%)P3U3Ct+i1oO!r}Hoo`f|8NS8Yr2?Turu^r)GrY9zTxtp0N9HOD`aP#eS8et%OA zrq8U3v@Zv^0MTtk%zY#U)REIKf7`BN!M@+N*0$YR?CCM$sz)P)L#dkEG;W*y_Ma`> zwRT!-RuIT%wa(*SD3-r)g0_zFz#i#CUQHOWd*yP`+UNN4bNwmP%cE*a_YQg&G$RPR zJTufh@m&5nz_fn;ABx{;vmciA$|$h`ZFtI?h11}dq$CE6;PrK#z3{j z0?Fo5u^@!kbJL#K#op3DHkLRji2CcX_0&?2h?3!&B(bQ^l`GXYYpYH3tGX;6)-Msf zfz38 zB+pUNM;6}0&30J=?$A0Fydqm?08fJ7UH64uyXS8;5@$SbE~VoG;LR;05cxOR~g2Ko!AALL6*v)FJE&$cApu#e>iG3sCZDyqmO*< zpgZZA7v28E&Pims_QpAFeaG}iG4(4kg4lm4NL2Ih82emC!tI!#UPbe) z@~yLDrOIXLxLs@+#*oKz5uuLMrHkyWhGXVcBN*B(Mk^>s0iatNKnTRpI$ z>UK)OBm{EkDq6(7zrA9@qY^CdZ0m71T7mby{9dd_>qrou-%Oe; zH_=gVLM`$=G-E$wPA)0%jHfdrs{~bWIyAha*8<+ z@hCd^>WjUS{QT9HZZaGIqIshSGI^;XJbjP&?M!F_;#E7jaZlSU~Tet*#psgUtf29#Mms0~5Qhxo6!zKF_Q$e3U#aB zVMTTR`6>R~DrvJfLPUjQ$dtpzAPO{J6vAGn#K|d^=rybT_7PjGIG+YeK6=k`eR8Hv z%L|J~%Y1zddpSmtz)shbTpu%cs=}vOb21rCVPc_hYIM35)mBso%@$}9qNooG>u_2* zQlIkhWVuK-^3y6>6-PXzWRFNOMQXzVU%VUGt8&Z@)qAyItL%u$Qqta2R3|GT)@2jg zx9m(-G$;^PhL2dhAP>`1SC$kW3FEX3lgQqm*~zDLMt-<#!yd!Q5Mn>(gp7{Qy8trt zF-#R_6E+EP>%To~O%Sf1*s7d%fKID;tfhD3m+Oi^#RuupxV#G82u_0uc2{BaF)_qd zc^thNhlSm(?xZ2B)Eg;y#rx2twO^lm2S;f#wu_{V) z;Qr){_!@zdg^3zhU)RZ#u1F`3rwyFHikz2b`$3Eb%5p)`QJ%vv(9F7ybTlnZ+C7w2 zz^mq>c^>ds;)#Emz3D>^G4Yf z4c)Q4kHq}FB>ho^TTv7D0BaaJ1pwf{A5|&9jqArZf?;fo0{KF(m5+har=CpiiD`@*I5P2USOwQg|b0@!d zq)T_;vRcaW`1#;ShW#H(5?OPXXIE5LuAPtO-*yLdqveJhBgdjsxcLf>>ba7))^KO4e<1)HRbq`s(RLdIo=@Uf;PYQ4do+KTSrim**A$%#9LO_ z=%iQWq1;1u+zwLe94lno$G9II>aNvy%0*un?Qplee_gyPO?i}s44{29@shoJH?i9{ zBJrE@JtvLhWLz%8gq1hQ0bP3qGGaFTiF(JOVYg-YY%G@)q6F@~_Fa^NzGWmO(s`ruptc=nLM&2s-K>EZC$LPz+gg7 zC!}h#rxYpPGvLbc{O1s)?{vHb7qG(?%4aQFC&!*N@ed$~-m7t>dX7k}9$HG&t@wEdBBcJx0Q z$IQG3cr&7{$fyDsP3;o{U^V18;qSWBUmG$w;8AmbOG@VN0udon-2bfkMCPY(eDYb} z5^_pxg7sF>nP(Ly1D*gE2U;pXuu<_<{5tJj=iVCOGGNhwLSzngV&G5uD5+IeBU92-Mwf_z`UM0=E~`?2Ez+cx_# z2kKJFo$_5jS@l;^qIYWID}@}vkN%;8Ic0VqY+e}jHy{*-gNNT}?t1sA+tRwTfk??$ zpSU~VPEjg+=M`A!saF~`Yf~%6Y0z+Yi#F<&Em`-0X?Vtj)g|F^c$Qs(EGohC;nW*` zp$28HTK&@P^1XKP1FudKtB$i(a4ESa|6#jb%% z-h{<09Jm3N+w_%tg)QCKpGV8y6%hZac_kY@g>PBT!01q8imX{EL7+OHznByFs7C9_ zVkSq z{0??`PvhUMB0an(O5}&U@}wn-q-YNR#s+r2K2r8g39V2@nb~TP>q3Ih@gHnXWkf}% zuO(i^Fv}=IJ);!7a_#U#9pRet0wRE-kXSMdlb>@gp_P%`zin)Zzebi3axP2Ku^c6H zN=opAToWlP>d%0pSk*5}GTCD{F?Sp@QfcwMrNpiMo(`kQF^6ZrtA5II{n3FO<0`;y zY=CL@J=wEgwZ`fQ9^o3%rae&6RAkQ;FqwM3?=j!0$ zOugpy7mr%;kfU>|HeKu`~G>{r1L;+x=H%$Z}A>_spg>`7>1_50bmkQbP zI~>}adA6NQQv9~g8~tZs;>0BOxgIeJ^7}uX#8B9lDb1 z_of}xdM@NKPq;OfJ9~%0r8N?sk?>BG%)WrB_ik)d{c>OR(-{h@sfR|J0R5wDF_q{@ zi$autbS%;^JsIA*(4mV}|Iu{1o#kE?-08aIbuyAGMb?=CjkH#trPWHm0Ve+e`QBg0 zH{6rkR?F7M?H;KcKWev~H%#!0^et=`1$3Cc96gUGH4VCNZGE$vs%vgAuy4w1TrFYR zL`iSPWjjv^Td|rFV5jM;K`L&EDJkuBkKz|IF^dZb1aDyxszoH`hnXJ3HYEe4P*F_i z$HqR|QoX4nn|%^%QG(f05wW-LR?6~K;4*)QK?@+j;cuc9d+5KZB2oP*{Bx;iUMM|E zj%Ur=51-}i8!voS3@E=Jv5UB6WHf#r4xADhNY;w2fY6@Z-l{QWHEx=yK(d!&9G27c z^_0v> zth>A*AeDwT9X%5X!0p}KNb|r3%-e>cryRA>F#L3dz}eb=b0km{=cMxCNwrBqcD}lq z)JD~#iGN3Dna+-#3F;R?jb1D46{LM$?M!Hdnpz{&dC3SMAUe-Y9Px<_9&0Sp#@J}^P zxwS%ucc2xp=lv3)oGCm9eALKhCeYB}uCB58_A|@OT*^0Ut+r)+>;?yoMU9#keOBlG zr1m=IpmTU2CX)m=i`q8x>qx^})cB3iOvaIp%A{>jGI_j_=|@Hm`cCN_>(sz}ebj2d zVb684k`}l(@$KAB1YtV0Hh4Gy4Oh#Oay!GzEB5R=1*$K+qy7t=(cr|M|G1P=16&rX z7$806RI8N~nAC!5G2y67eAV}Dx9^67JGF;4SB>O?@*e6nZ(ooYgX52nzm+;kwg2tb zU$X!bSpjlMOimPE#6&p&+5L_m<30)~$|g{2eDwU9m`}p;%XO=v(s}9hF4KA|ZBICx zIoY-+yyNp7he3ku_Ll|CF8O@3RKgPbWcgP_(G_IZ<4#ugxfXCjE_FYpmK{27YUcn< zEOEk%X-`aGIvGK+@Gw)Hw=X%EgeahVvN2_Ww35-%In%4$u)71avwCI=dnz+TPLS%Gv!a&3^z0QZalEw77c zaM{X`v$g2(Bk1PIX7wqX7P+u!_-zujIuF1qSBxz`O2~E>6Wd_p#Q+2_LutYQ`{G`8 zc3m13Z-lY*DPVH~o-+^rKGV_csbP!{6=*V#EzfG}NjjNNtR3OOF0WqA&V$gkav^k| zwr`W)pia9719hfqVl2NFl*}6d{$_o5CmmZ?r3dk?V9CobtTGDX3OnF14zBDYXnHkl zKemse<-K0e2@7pDl5@zGpPC*>txWWn`JqhGp5siqXV;eR)ac%s%}B#wzM0kE@cz^>j4=< zZ~IFls2My(#p8duV`#P?d(14-=j@a;uh61&_AxUg9I16SQ6>C5bpG0VmRx+o_*2j7 zUSSk*2dl4%{NL54{-212|Diu(@H1wg9tg*zm*ekA!`nu@~m0eEP789h_pjjNR@q@FE zKHQGKkTv8pu^_&erR({uME6eC2M{JLiI=aP&>r`N!S3<1Z}Xp8wm(%jqxmnnEvp7_ z8`1|P4*BHH-KUgkBrCmt0NSI8pKcCS;dC&r-nte4VBIlq{Gh1B1?f?IcY&fc;7eLr2?^tym+ z!ghd*8)NYYg{jSBA-;+jU1A0 z?An8p1WRHf*<4rmT(Vu+8@HP`=i2OVr5^PVP-HYOy|0bVHjnt0-}q|qc%R6)e@wpS zo{pj=OiB4JhEc`;%ara!odECIK%&V`qH z&1-J6DGF3VRFThDt_;S7x?(4+CIUUf5tKrT+TK36P5o}mKc+QQJXrka=GSt;l zhd6F>HD1R%R07M&>S^un<2p7+pHQX0#CxcJ{w{}!ahQ!>#K83H^4K=JIr@YLlqzI+ zhAFi0Fq={w4avTZeYjo8E3D9x6MZX3Fw`_=6v*orJuXTKTPd{RFW^wRB)%jJEm|Yo zP{+`JQq7WcM2G!+b@C(Gmr1u)Cw@%+8e4$fdHnI~ ze1pH6JwufoL&9dO_O-BTH+FW8&1&{UB03w;+YwcS&JZg&ffWp3s4xH|0|Azw-hA1o zdVlfN(12b0ils)Pl-;&raiik$k<+|M*f#ciB60B(POUJIvS@?CTWNET+>X1pe*46z zo#KuE-7{J{M}}tRZbfM+Xs6+SfP)2XH8@15HaycFN`iq2U`S?Rp&qbuJ59^7m(kiw#4tJ)t)PSTM8gIX znNN>AwQM+Wz!J`s?|A#~pq=Vz+rMmbUGowvAKNb+zU~-~R z1CU~8C$fX11>1G%JqcO(vehD*NsnEu1JNGWh7G69-cpW>q2iZber>gN=59@-{s7ot zp5vK$AxD~E=|X`KK@_p|EJuT~;WkCX#Ta!EkUnGoUG`u*;U){cePEx!Zoyl6x^TEU z>9RRQ49ZT=knCeWSCl)+(;V$f8DIJ(A=;zW+4%-FSW{(z3eA{@@~h7S63Yt87KFdg zG1EDtS5TcMQ&=OY{GteE?7d4Jg%K&o++lrnluyl96Rl8s7{uRZXmzLEIrZ2v%xDzLS$z|FRZ7xIg zrSt++q3sW@?t_IQUQFmNACH)T(wdsJvdD#+-fC}ihQwa=94N;GV|mvHHLJkJ%X}}% z(3n{)VjWXF1Kcp745-l8f58k%IRgpt{3R8%&}5$wU~SQ+xG~vz8Qu;@=4hrOZjs2t zHJ|yV#|>dE?9_GQg)sZClfd7<)A??!VkcXPG^FUKPY}G*vONh_qhwCSONj$TN8F$O z96TiIXCn+5^>Dw+YPbEf=K!tyf>t7<(Cwa{cWICzhH@b3uY)jf(~r4A_;LD*lKM8R zY|Y&o1A+krr>Z8BNr04~n^)D0eeC8kpegvi6QT4OE}fC&E|?V6=d|DtdJfR6#jT~p z0P=2PPnE9sSww@pap?PX z8_>pnyS+pOF9B?qHsd?uNe_O^Ly&%A;58E{ILn`dkySLBi~`?>I#gTUMtXDj%)A4} z{E-E$H8TFwa7KP3ytv6(LT2e?ib1fyY66jDBvmuaa|{+VgfHnyS*cV5gCzph4A}ON z*g)w&0!VLVH}ePt-OCsankuICUv{l!XAJmE-&XsCfk1=Ls{+SFPo(TLk!Iszq8~}BX*59#Jj2RWL5al^P`cu+IPu-p*-6zm!37Jh=yFlq~kC(Y2L)Bf|b}c1ie(t46gYV#wJJTp^ zNF#8^v^h&}#tB-^F;4*}b6}3pk4X>#D+3jkZeW!Shv6 zvLznL-ULbcQUJb?%qQBad?b;*M&p<%c)O1}|MpwLD&4hMH0PfF9+>ZAF-PoiTG3uXrm_Ac8CX1yu=&iYevN*6Yq#Wpi4yxa=+n8}g zP%;$L6^)L}R~&#FRn<-SZ%?wgQ4+Pzm-Lxy_g4q_EVvaql+;D&np_yD8vG9W%Irw6 zk5dPl`<%CMjokQ4>dD9eEn9(th@>J=AoUQAlQ8oZymmY9O_KltJGrmIo8z?HY0rfv zE9bhD98FuhifJmVEjm~O!sC~+_1FUes9|i%ze-ne$MJb7+-qq;lUS=bc*&0ycKjxZ z8&un4lq`m06^13Vp)QPaymLOK-BbP8EmnWtjQRp2+A6v|b1TMY5=5ccqSy`z@Sk?| zcXfuPR#p9_;JJ~;Z|v+%1L2dH9|qLicgpKHM1ymkmOz?cv;gvfbBw$J|L95K}Vw;0vjiule`WQQum4ts(V`nTd0r3q$1f(vh0T`6ejmnqG6b^tSfvRX$i zlydEmZH`tytz|ZmB!a7Avl|_)BtN)%wG_M%;yeRU`U`DqTOMP)cPr+N)D7a<4M+4u zl9dJBKNqJ|I=)#k-j_l7&=p&Pa{4$8;b8S|>DlIEc35ZeFyF zbLn3hsn1A!UWu6RLyYKEm|+M=GTr|xI`uzYp;ALsUFUZE6iR*d-a7pIFR}4bsjzb)so{RTxxsqEp55dAGow4b6pj^(ORp^l}`_ zCq-$V#IOR0lPg@RU-T$1EA=@~@b)FpSy(__aOv8ASVcGa2iH%mr4F78^Iu6 zl0=VR*t{f9yNv#gJ(RyJl~G0?lMvbV(-NbXXHig~$--&Ls+TRFjo{3l^ftW@?+Ae z`Kc$Pqi{6yRhIJICEq^+eHBp{;MA~cX8uFXLJw`O-HAC#xl7)HR7KTZPAn`<3D#Q+ z`a6BMFW<$o3iArTxQ3UBc>F1EJuTNaz^$;%w&O|YPb*NcYJf6YUOA{Z1svLqXm#~u zq?pB4xg5*ki+9Z4|E5TdML$!z+>P%xP}u&#)PgZOQkx3fneywbVl&uTNGy&zE5Up* zSJ}z|H}!`#OL4NF|MW8~Ng@{3H*n6xRuio-7$bxSI?r0-v_*GUA5=-PXieS!1q-NQ ztLr@kN|r$W7EaqVb1ase)bMU4macaw+p`L)kuh5%kqN5yRzD|ckQ#oU{8{4La5~;4 zw`E^mX)QZvy^auKfQGch$I;=t&+3$@bQsD+tb8C>W{ooQHatLIb4bRgx_3I&Am@o| z!M19Z$w=+bAm_Wh+y_cYxmzjA%Y&1)UI7`lXZB}qDu`Si2pXuo{dc=9qFJ41cl(%A zW~z=Zi?0nPwjLKTL4l92w=?T@>1h*?-;7^r+iCcvkgh_mB=Q&uf4|{8$m=+hdbmLSgTy44=buVFTW-O_8s?xsbjyxn$Y z-NFHJqBU$?^7r%?<$94xr(X%KQFf}`CL`(X=%vzYrlVC8j)qg_C&)FDT9!w8j({VN zOj9Y4Ar{)k+E9n2JMxC)YiL&lUv6pNcpNR&6y$x&X}m2P#F`e z8p?A;+n@CvWsYuc7FdyH_Qv4&#FWOLE{R$gtoT$RjHxs3CrY#nPTVvZMVEjjech_^ zV$`ANv+(B}$0FJU)#3WjZF9sw7~lLz{eFCaq0{mUI8v9?%=Hg|g&v(S=m;iERMrwP zErYnO=F{Zet7|3qsp92Y>lJ~)0fjTfCjw|gcO)2;EA`t&uVhPZFeIOVf6(=#|K@2L zy33yVWHqFb51aK!^>8Jt241Kyvx;PE<=j5I%xJ9Sxp=i~HKgfN@Q{%)(82DJ@-i=q zZRRR79F=KBP z89i;t(fk+;sIlHiLyb}y(PIx0y*p*$;*DF=zgkZTEnK-Azsd<=)meHu6FQx$uCw=0 z*<6?-Ug>w?bly9cm=X0}2QQ3PcAjEKi?Gu>Uz}|zER`lCZ+&oEC@~WS*i*Lkul!OcUQKEOxM=gB6^riz2 zg7iiJZk{@2t)qGF>v@dnCCi&DTNXcAz4e%N*i^Z4zwH{_$8Nv-_H|K@&ZNt}u+uT3 zRnH0}PKKoWSatg@+Ijva+Nq%^q5oS1=_TgcM*12iS4;XWK*_9A^H?G(OU+D2D_3U* zmK&{ape^h@RVa+7!+dbbH3zOpz^4+`KE zZK}>pcl!FB?DxL*nO2`M&Evh-v3KvAQu#v8&^@Jbi=UbsfkIaIMM|7Z@UgNX894ZN zK0gt^D5Sx~vrdN=2mdqY!Q)S1=cQFZF+s|v@+{33zNj*@j9bBPYrA<_E4SBib294K z5LVJv38*gK3{6ty#OfIt=9r&NRzIP?XYmqy@~M=wyBr1n8~rCYV#ms(t@1-(X?onv{6`g7h7Q6Z*I zu91uln$7qYz2U!jLmCV6I3}^c$teWC$$6+~AkTDEax0^Tn1uL7scnUvhpA`JMNc7$ zQmN_B!f9_j-1-n*J)D+t%(8EgR`5j_r*WiSJj5qVz_+je(J9Hb4d|jd#JXn?BZ2kG zLz-Zch3uE&0@$~rEpVE7t==XMQb<5V!At-+5>8Q_+^gRkNxbF+1KQnX}3rRe_ z(lcg{oiT4%eb()dBlpa;zQmIw)I5y%&+FyCmWcT;w+Ityky%3Kdl@BBuwBk{RO?e{ zTe`vN+Z^(@LspwfkLs}-KtgGYe)=Ho$RdF3TrKru=VLpzt z68=W{eiA%c^n0Bm<`5inMxJ{|j2%x~DT+$t-KMniW>Y~$TV9j98a4J*j{P-( z<}h8End?{}GVmM|eH2IJ^>hng2v|Arf(5*hNa!TS25_d26}FJ3`yXC3RnZ`sXJiO1nHfYOk0j6HS{E33R3JZZ$ckFk_jZ#}!zzfW|_P-oT=*^KS*= zF!^RmXM|Vo6CWX*@~HMh%>ZE$lm#S$$QYe6&sS_}fXVW%h@9V{J#hc27qY^0f-TVx zU*ddCD%t*%jO;73@LhI0me�*9!OE+2J25ChcKRxh8pV7F-&gf`3ls@pXl4`NMUo z5utVt>f34A1(qf9u6*P!YaUfT*;2@g;Z=oDDx%Y<1pZG)+yA9Y{})%m)3m7S{9iG; z8nH?TCksZ=$k4+{=VpGcgkYW_1E6>T?XhSW=bvKhva-t9KJc&GOD9xs%H;2ws>)1C zpDqVnA+!%+AFs!4N0pFZjg`Ek@W)|r68AETHc)qPPa~4Wy{U?9k*D zvBIh~9g<~ZF^q9%d-B5`4)sc*tG!6ffrDrA)Np63Y*?#|zAsDYc`A@att{C8aagA% zDvhzPKNR6th$0shwch*SxCUBTF=jYFbP0ZEyGlXVot!_dpM}3h>n@tJ_Z91hfUQ^$ z^`<*qW$#h^K&XOFub*qUXgG=`(L`gXPRk4ZY0U~wkO>@HL zdgj8PTt=KqOEuGk8g#|9ulVM$hV3=PN9p0)`;l<%Ncvo2Cic7earg$24Ok)R)-BKzfn+?vhIn$Yp3jMcYaGic z)kJ@uH^1LQnQ^x(_X;p}8;1@!5dTN|P)KN)WxOK1HGv?(_$Yn1^P$E?U3L4J+D!Sm zc#3*!@@1-McX>tmZY7-SS>d_Mj{YA2wvMwI2#%BE49eA=gE1gjrWaI_W9yMOrO!uj zO6_g-9G;>b5!zTjj%T3{yo>ZMrR008>%Ro^^1`HiSe``QG+u~!AG`hoL=Eg(_S?e- ztRS|=b9cOcr;P#mCj@imKp39zQwnYJO?+IL2#{f+&mW#!+$g?}4> zw;*|-JOBv^06;=K0RNT&GKi)Bp&D-vW>j^+H9|2JIE1R_K^W28ktQh!B&uoje5z+K-(NH0Bkj!pzN z-{f%#PA+WdW?NG)xRDPzjoVGV^bOfM`Yx0A*)}q~56qLlo~6(>6=Tq^=}b z${=>?N?~<}iY{L)kaMz{V@{cOq@bCp9v8$%wYCyg(cm&|`^mkoM}G!Clk`wQI(2dA z6BM#h_WHQ4K!e;@ga3DGTfl1id!`>HEY6Iq<`i+^6P?9^1{Z0?X}>NsvD&I`{8_sy z-0U*P-(x?16IfN&xb`H-zRe<)$XH%5d}I|n04GJQ(Id0AxhUXX+2Esh#My zp=B(}B|VA4cusT%+174I%|5>}yW;74Bt4Ibci|-^I5GZPga^1#x9jTxnZA?1;eCL( ztA(wdh;`L0Z4o~ipB)0p#V=rw%M~5x>v>|-&$g7JZzk8JTRr8@w|HHol)Y1tUyZx?UtdZDJL zZ!)e*Zw3?&C|bl3BsAzI2rl*S3u{xyFr98~EA-9R?3Kf;l=V3lfoQS_965eO{I3num%%a5 z5st6yyEABzXIDFeE?nVbBW2qpYZTObyM{;VOG^C+)!r>VdDmqA-?I`*oO*+}-exbK z^DP=}OI96OjH+c;*lqFWb8J@=g(N*M8t%wl7AE+f${?H!2HC+_0{OHbyUHMVzQJug^+~fJJkf;=wOe zV|@WyvULak%IaLEzZ<{C#^lj`znX7hQ|3pJQ$)Fd$UAPJ?|F*rd)5F91buthS;M1X zy=@>ncUI*i610|rg?lBm?>sxH3HvH!jYU_$43m1ezCeHdBjDCCD!nM>>P8 znSibu-;zxIk`;HYEqwy0;FCv@ocaw8BbBl2i&&?-x?sq0>DC;S8;aSw`k}b4@RKoo zGU1&h`h4rC)?PfkV)1atHNl(J1FI4vTwlAXsD)i`XqLc;mDUZ4@8X+hbU?NId!7ec zcaW9c67oyTtVf8|LPHjWpN@qci<}?(H5(5Rik<=8)TdnqDn8tm_P^qheJHs+#Eoh? zOQ=3AbX{lSOI(g;BO5RC*>eu1`vm|{g|lVCr~iV{Hom02HF5vDu72vgXDbH3ihsPj ztP5XO92gH+?6c-i6!ErWixBgm|6)=B(Y^PpI({eZqNcKZH^#_cOloiuhX!7M*deqQabQc_BbtmmA;FMMqr9T2 zy-9?YJ1j>WWKW??q{XIM`XxZk9(&98U5XOuf4Cv7mb|xnW5<;BSvVW5tlB4fP_|zO z?xR|8S?a6fc1%gdaFRV0&B%GaDEaI==^}vryI>tt zb=l4)M#i$F=Uo{6*T@o9FpX;7mUDnfHdk#6Qth>Y%8G7$f8}?+87=SW&`}vAF*&(C zh5khR+(Ot59Er^MzUoVa+QzWrUvM#Y^`k{DgAfO=>bAU3mYXFdJG#~Dpn6n$jcb3F zeillklxowbkMqwaL{GqTwHrZV67aOwrQpTqyn}mxz=i%mAsnaX-o0my4&LfwUpd)U zT;zM2V=3g&Qq9P6n29EfT*B6?pKT9eNDahKimuGs4{lqR>GwFjmjAe9)`axDKRref z1{Va+h4;ctMTkJmf}cX^t8PL4m_IlD8GGtE>6xlhUr3xKhCMu;)>}2%&dHb91}AeR zwj7b3dYsoh&eRzZR2w3U{{evXzlSKX==YfYIE)!>Ryk-_?tc#GP?E*g%ALd+2^-$J ziok%RsbQrR{XzTG(R?}5pKI4rV6jPp!fQ05d$>H4w(PCG;LL9?MrDg>_*ncM`d;*N zzh)Uxva}*dyAa=>>N!bbv2fGz!;ura2fYYySXdOL^SQDE^01IG2K2z2i>Chot_ho8_B2TVj7WCcW3 zT@?t91#5FC(;vyb1GhV2Atk(bxT{+_Z}r__hZJ^Jg5$U?hDT9W#%EtUSl&teXrL1R z@cGFKH<{f21cB_JBlb`@|$tfM#{5WXN2J(@qX_$JYxgCwENHj8nf(X8meDYm7YIL6($^K}WbEYog z{+T~J`NEBznVKd%Su`F!W9ag#wlmw}R?C?_LI=~vfQziTM9%0VP$phMzNAK&R(%^KwZfmN?$tgMRPt=Of0y5Mse98nXO`6Vx?+^5`4XVtqO z5Hhc_wpKcSs*#exwA)`nvcRtKBfaC!R{|#wU{n*UWvbML zG7GHw=oXlA|17=WZ*rML<<6nKE|w5Nxs>LRpDfWZK{i<$PRo!tHt zyoT&h;gFx`JuA01uINBw@gnCO5&*3XPRLfOY@U*wyLGE}oe_rm#N?QU^PZ?}xFIZc z8_r+BZ-~lPPUyzw4_%m+cCS}Fq!aNAU#}6h3_L9=j{LszK`sC)_=YA+2Bo3 z7(lgR@EH<)?UL+Ve`cuM@#JoWwct$n3`Lh4X^gAVy~z~W$e0K zZ{jX6Rt2k_E-nZ3Xa8}2!|=9xfBd&Ugj;cP$h3cOdEierhBF5M>rwQ?Jtn zwP}sTq&80!Wyd-UCeZXAYS5MkqJ?(CCz3oGV~^7p(b*^xIwb!VNPw1 zvqrfl+O;FUasLD*u8pn?H?FJ*D~ot16jD!(Q5em#W%Ivlv-AGag!?p`#KcxH{s1=U zX-<92ivDb|$gbp9u3+X!l}@)7p}F$;Z;n2xw;46XM|Rj=7OPhd?yPcg2ZBi9<0El1L`G*1=i1pLNI*A73yFOQB{ z-@FSVrSjI$*-pX!0ms16%Cr74a^=}Mnm=PQaXqN#gyB&`u(7}WiQsu*Qe6R*?Lcoy zypp|zd7d$haGe@U+{B+s95{b!m7mj}n)KZ|Q;cH5vzaI1vz)x@R~HC)K${ospW_;nM((BRohPu-iN^Ztb>@-niT%I2G#T$}k6s`~SA`N906>V^`begkV2K5%*s zGj>aLFMt)mNe_EIz!K5yRP`_BL;b|8W)E{b%T7kD&_L0df0F1o1?fu|LX$d&>6_e2 zZbJ|gSn@|zb?F>5m(w^$0Wr;@$JQLjpFYI2B|9bWWV;Ju-X|!s9IDp3&WA+jPR3i@ zSG||6T{?Bs9dFTYnWQ!*#5`_FX*v0h0>9C+`lK1wD>%Xvw|3Q@;JtzVDh_Z3p4fo8 zFIr}YbK0%Rw0s1OG{YX#Z*2Hsx6qdN_oBw>wJO6huix_1!KagJ2C0m6AE+)Myq-LM zOtTlH-aq8V&*|l6&QML9-kqDim&{UL~v=pwPv!YuebJDRCMcRAZEg#<=~6G z-bPE{CJ7Om3P|N2Ae54-dErHiN3NlDv)ph`$VnrL#l88Ju9~>6*uadA(iqKG2&l(1 zow}?06vu#9xduz-ZS~}p_^Gsl;v4b8YJxx&k|`JGU4x|E#$02E)<#WYx3q+*HsPfs z7ANH#Iu1k2*N8Bb812T($hSOJsSF1ywvY=UhRT$bT3u06?(g1VIQ#@AYEyqQad_$P zvyuJ*xHz1}vE35>u#+&oQps$Tm~Oe)r0Y!>jMehlLy0ha)$zr*T3H6chHCq4DCofP zp`sGLWK0Si=B|Yj>~WDp2Xz zzy6sC^C2*aW%O%}`(u(N)LjaGi0QOIr#HxAzrzssNSLJUAw%i3l=XJ)=+zVS%PToG zi>$&EN&`=nBde*NC1}qYR;Iu;eL3W~G1s1gJB{gF!y$_J*J8s{gPj-b6VdmhgKCcoJRth$!4sSs$_6AlpDvGF ziS?H-)b&Vd36l2EYphBlI5{QOvaf0)qdRWN)*aXNxXfT1%f&ku;_j3W*KHa0R5?k@ zr9oB}Ep=mIC_6Z!#?7b%&0j^qG8fp^wDy;m1Ml&fL0;vp zX0(Tev)^GfVn6kDn#T>WFu_sOdRHYtk6qeqCi>xI9RhU0{)dtr2wJp5_xs|vrnoIu0FX}HHU0;r!ao^Mf7Jp%0M^y6@rbq8UF1p!}^jN zGgb*GOGqMyh&P_{K$ZsUp^Ecb&MlBneg9)cqr&xfvn z!%WgVVfklI5T9`$AFLU4nHtfh3@Fhxy2Y@)WQl!CNJFv|BK!~bGGSlK&w z+VOp$MsM4wuPX|NXHU(X{JMbbi6r0+^!M7FM%QOMZ1VaG9^T|8L>Ck@iKedDpClh; z=_`c>hIv0WM*p(!c7n3?Xk$9ow$6=68L382!7DRX%Vwx)?-CAq^>VBjW;C+A!;2D- z1@TtC7R(|7R-(#?xuE}P(hj{^)d%VApJJ51zHsQbx=x-Uc*eFzS@hgxN=a^eDZ!NX z1Rv9fDx`Zw+<4odKk0z#t2pooW9L%C-7`D;kKW%YQjuIuOE?rC*uRbPJn3z5)X#o$ zT2C9(hpmV~22SbOUfy3(RmC)9)*p-zYQhgZ&U}4d_rI%|`~Br0hVCx9gFzt)ek#?< zGLt(UZ(;X@y-5{3`zye>#ky>)d^Vjlaq6Z$LjUu-g6@C=@3wa$_J;0Mlk5t(E1yf6 zfG)x_;YrkN>g4WMo1U8-;VtJqi%f$WoM#;*8{$9YVoWaZ*)GgiA8NLqd%Ix9bt$zf zjKv&;-gfWSU$<<=5>V7Mzm_+BFH#pr`MluGuyVxN$TfA^Qf*vq#4V^$V9}Qa!YEs(1A|S|l^< zFk5iaNIY5*j@~`(7$~iY9~xSc8Wzr~WfmiL4PPxb;k!Pk?!y9xz!*j)3IuXwmob2z~gt}}s;o(0l zBTJ$w9q;eDOq3Cx7MIq9cf}Cx+8cUY0$8?^JW1q~(07%atR3vm#-e>-Fg5S^t8S0EJCKR9(~^fHi!Ld2pe-8D)-2GFzQkU7P5yy|3Q{Ro@UDAV&)@R-sMIe_+kV?3GX&NC?b)wk zJt?eR_7R+oxoP`K>iYHjff~=`SGJjbHM#^7qo=OGehkQ1%HL`6uW#K&yX&a$+?}X5 zbE5{_U%z;h2QNEK6F<{fx~zU=R>!cq zQv=XfFoJYy#lzc{Tr+>qhGfW&XN?vRSBwjqK$MFCVQB75R1ER|0Budw?u3^OTkGyN zHyq_vH+PeIQcl$(1~v`W!qNEXe>6nNnAxwk4Xm_=!*& ziw9yD-_!mB=+$cP6yMVOY<3zjO8Q%rfIuqzr2Q;ynX;4wA=z&|-j&FDf6HJ-SB37D zh$fy*f1PTi@Iq;VEz5ye|2t<{ZW!tb1>eTBK zv=Amt#NC)~Toj;SUPgxxxHVCOh<``cAvCUCErhV#1g7VyE&eaI-ukJnxBbFR;R6&X zZpEQMaat(Fr8o&5+}+)ayL+(W1rprd-Jw7sxVx3&E8hPZn^l#Jj(dcj z@$IVlzMiTQ*Di3n)(uwwg2aj5_1Mj-oIH6QA_rul+3ET$h~eFA?eDoRjNS zm!*M&67%M}G`5wocZ?r32m3br)Rcb%JpKVxpqpK_bJ+(6nff(3>lp%2?p>Qb=bPlv z*n_D~f$P0g*BtR|4SXe)<3*gGMStGLgAzl3613bq*OpExYL8>(+ma_@6X*+ZF`W(i zpy>*wku!$Hk2;3W_^L$^qPf< z+GH{4_Kq|HB3Bu^kD}s-GEg>=qQygG00}2|>elT#^xqOCD%sKL@81973;M~c57)O& z>Xy((lU;z)Zd+cQ4FhAR}9`(TRB$b ztYP%N^#I*2e=$p?Pvl(qp|8EtjAS<@VSk%{9o9T|-h_?K86DUdfU(lRU~9w$*9$VlWSP$2=jclG4HI7C4(c-sRHmsD?bNnN5 zfWJMnyzy%(9RS(6Dc9vqHpEt#`c6a;^v97ud(<|5f@G$)?hS6`q^EnAUkw~JcmRRqGZfBo^5dC4WbebG*};2o4IQTA+u zznBa+wRrsf##EuqY0-{I(tRyCf$bxi>28w0g2F$Q^Mna`SY=Q1#q z27^5>`Jj<4b^1j^M`J5S9+x8GkgAGjY#bWblNV3ek1-5n>c-}o77nX1qMTRkbzKaj zi!^1m0mUg)aG^R?I??VIP|ez(FaH1t4B)vyWygyxI^OYVC&-X1*2Y2Tk(Ad_M`hvm=86=|Sf&j>{M&t~dxE zLF=kYJJ&d?!&(XZ`HgwyAaWG@Dqa3UHrji-_5Yx!i5PDega4z|T*%BK*X$y6iinJD z817oE(!?e;gu>7zBND5hmuE;W+;Nf9C4&hPLR@gR^VJcjD?{5pn#AXC<|6E~>kC)f zX`j%RE=YBF7(f355O*y!Ll7&aA1WpPZ@CInLFoSl7cuLqYtn(bh{QI|{mn2j9p}ql z2hkvz*!UQwzqDzG!@t|%O-=ugM-&GUC>QoqBy@9s4I4 ztIfr?{Y_0(qzM@lK9eUZkj$j0W^`=khdWYixeR6?73-NmL1T*(V3dV^XJXcvH38A6 z-B#dc)I(2F(0qS02<NH#m6o(1_rXgLF)T?{c!77{tQx4l~ z&QKVbHI)*P@6-ZBRfQgC*kuGgr@X}>JMk3|P^V{w8<&Qs?8aWF+~9w9WGHCt@^u0O zFuoZo$l)j>qu(X-{DRh7Sro}X0BSsulq{2mk(4L<&oepBgT`-V>GN_t-rlPDyuTlw zA}$CENHWeUZn31?Dq&`YG-T8HSwpC z9MVvm-_Ql^(kl>aSlW~KR}0_y38Q@1pr;HHlELZAPTmjD`4cjpUc;D~%X&UJIPjoa z@iwFcOk_WMJDMv5FE_z|tc5536hni0ZDvz=;%?#8eoFdF=+rdVKi}eodL}LYgeWgG5eFQl(o26f!(&B+qQkCqn!19lsVX9QbK_%6g#mv zPaBzUWyH5kpdEdXWk0GG&h!4xBO`Zfw0YVyi!k9eKlp8Lq46iQ$e9gcP0)&Hts(gG zgo>kJJ8XW%4oogr)>I>Wabxz*oyp7-p}{FRH_CSiZG|U4+5Y)D71&ZLLIw__DYbs4 zCoJZ>Dz84xyZz}Bm4C14xwTgxX@5+`AZxE|!dWEKQG>tjEeoDaEzg(fmQ_61KGm0L zA((2)uhCy@(W|=pm>(6vnsR@!;aIXIi4{Z>{B7k!LCvzvI~`9sx;(|VSlGmH2Ql*a z8>jx-Q5z;Q^91_r??`-B?PMq2=H?MGa-SBr(XG>jq~{^3bV?qDBohCo76e>S;=QMN?0GYPiv|bhp-bDB`#sOU`0g1>}2zJKZirB z*ER}-G^6yozrF^475IjWQ0$UYf~asjWUI2+u7bbbg{LmGdgz!gz=WdLtL&uPf|}~O z&H(GsUgE30X#*Hj@%S5u0n#}`fYQHP)nCALSe~yj& z;CnUrpfk0j(^o9UO&y5`N9XtThU?=j*~OpeP4!+WyA`{@T_!Y|>jUz$P`KHmzN+r` zY;ILGa>l*r%zM8vM%)|o+jpoHBp-h> zQKipPbWFJ=us@&7T*>>e^6Q6()|c|x7XST52kj)KBFOj$;2ppjA0Nx}2(VaSU)I^5 z8wXi8RZ4}0H4}|g%G#P{oBg+Q4Hb3Y#s;i@r){~D*-4%7H$fe+!GUwcJ)_<#ID5;7 zGfd37Fi56=ca&secR1WOy^IpZzcOFwCS~0QCVgZ(F$;~{{Rz7tWO+YwmXPZCIQ#tR zx3~TeLvw9f2@hoEZ_eS5_+5EiqANs|RlfH=utKYq$+A3DWJMY#2B0x}OJ@p@{bztf=gPBh`4-AmJ(P0h19>4r|oU@FSBEoqNUHvART^~Wv- z)M>P}l9HTJtek{FeZu>zaYS$OJznLR4zIfI9K(|&tmd?DeR(Y!3X^oN6keGWWVL_F zR0jV7E@dfk_og=7C(AeN*k8k0#u>tlHvQEiOF5(s6rFHPmD1^$b@{?*WtzcGSiFCE zAW+B~ergpE=Z;xyQj1O9spqvhlWLAc6MCNMrwWClSc#J5$S2U;dJq`BJunWXMs$KmDSWo&{ZD+ZU%53e^ zAT-JIGB?uVHxtoFReFA!_jENrOyTCOwp^rheL^AG&~!8g*-HaaLDG0czwcnPzo9Xg zput;jl+umbM46!w_9R<#b07Ni7)?>h>4C-8(EPqt%A53!Q80vX#|9H^3;gD?QqrLE zO9e?xWAy$)kW1ZaUc>5p{_#&k?sjcCJ%Y>_FSbL>=8UH3x{ z)`xNR_lg1{i>?f6d*pd9khEW|M+x+Fo+Bpsa8>?^fT!RbaTlUDRyvY`3hjF{{VKJ~BQldL`>Se_TQNYmC-E%0Bsgd5=%hQ`~ z$tn+_SS`e9rmVW>ObT+q?E0O{S*>h%Tcz#i1Mjx`rHWE;cMHEx>)CUZ53zW1Fq=JZ zFOcrzIGyrOdR^7r(p277_K}&)Qvz&Jp1MCv!O=^1iM4>_xbby@4$=WRQow8jXCOF! z*fi%@X3qBH0_^#Q?*-?j?1Mc6{$<{mmYZ@Say0d_LQPr8m(jlPwvm-xW*e-IwuboZ z-JKJy8Z8dO*nk-rJDrvLQ)Qcg&e{*mw#ml zwvG~zlm;!@e4r9LK61NZN{Zc*F~OCz8e%TZH!k`BgwlIrI{Mh5O;nXR$*ba*Ll}9> z!)b7A5DEr*ncZHEj-0e;GCxX0Mw%G>4APxil0(ew>sBK^v|c`=f|pyKa2P&N-25=>OrZ z-c^cjR5c@T>xd>f^ND2IJz?6VPs|4fI#b~JMto2T5OI!$SXZ=zSLsuB{k{OzxX2z> zR5f}Groa6~bN0W!%#5cH`9j3}@hN#Ao@X2 z22>He`C<01@A7$Iw-5IXo0rDK2Z&;xgQ@4_0TYr|0~>6RGq zOQ-KHLzb?B$>=dtIiW<}1l<`(*L7bNV<1)NMTLT=(VEa6e40Lf(3Boc#<7OK;ttnD zPg0$xFy|gxg#u zgW69bs)3B9N2T@{jLq9h^VJG5F^`POb^Y@v9gH)NNYkX5D`Ok}JqwUY$id~EF*|b> zyh&|+vypaa%=u8PJfeTYcBpyw*!b-Ni3R>T0JF7HU-WsXe0E!yznC|&b|=YlS2e1J zDtN(G{!V=7*HYL*33=O{oQz?_hy7VJVfxk@qU@onSuli%?9R?d81j)8Q}hXl+Ht|{ z*_5CGv}aDQFdx;F7SH}c)U_U}R!OqFRqkkQkLS)hqB9kqTF=zf`KrA!S-3V!l{v5= z^Oex-+=*UyWR+SuSL%uX5GKXrVG>q%PAZY<*NfS*LFP3&BP3vRg`&DuC8to@^m`iz zPw;PkNZzLneRr?p+ep2e^|)5+Ed4=6N!s~ktBMi^xqDEX(lny7-^g~-{)VbeZq{s_ zUe;^B2G&ZGN-aF;Z&9jIzfHFgK`D1hSR3-BO%KOe77&Y7YqA3?kU5ZXBe&}2_dRk3 zDf{I{6StY5TIQNYc8xK&U5uUnY>cIp9Eao}=rfjlbU-z04mZ|{Eu;7YD$}nk%}aTw zXM113N9>|~xhxxdhm~f_Duk<_9Iv^K5Y4Ia5pR!4=}YaI5ZW=8Th_K9)|A8vC>UOm zd(Zf|Tyk61tQf`YFzh_^%y82r9<3IPEe0eH#^y`_{r(&s0^(S^?wt2YP>Ge*Q3#*k z?EJy*+v_B!yY%w9P;ot3I7_hd_U`^lCj$jufr}g|2u;LB3gp`$(sK`}Pk_X8t$sYg zjCjZ0xhD`Ob&}FTi__@L*uCM++h44lK~UiT)lPIW~% zINk_HSxag2k>0C0*Q{#hJJvKW)Ae+5oqrrI`t)pzc$UaA*EOhC6#MzA!hcRMn#n6SCzSpu#t#rRsN0~%dGLHV{Cw;G{*9%h>Kc>S`6@Mb*apycy* zfW?<|fBFvxrCv52-Ti*wjx{db8kbDeqg6xgaQAzKK`e|G7jf{aIru`hl9}Tdz2Y^F zcQ%!Ho;)pM;N^BsywNmmtl$dvPf%Z)Ky3B%zn>MnYw~X?-l{tCZ0pJD+KBhfG$bX8 zk>kqb@VKW%%;<^N%FpUd_S(WVv@4m5f36ufbLPW2;ekKB)r6%4^4>+O=4LGE9}5ld z7M5HrZ6XOY9a#FuQ=ui~EJRb4&q6lkl91dqKa9oJtyHu?Qt3ltUwF5WX?HvNMC`_ktpyj7+LCILM62SW>eTV;MRCehJXU43y;aSL7VCLQT5hvgZ}<~q zcT{7+rJaEU-UgXVV3-fVmGd8PZ8(@iav!y&a)04W$8T381XV?)CX&}~?;PWN--aad z%Lf)XF)Pc;RiYs8b>BSBQeDyXTQTy1Qy*s*i%NQk?wDfSPu&n|-rW{rU#+uo+x8D2rFvKp4JX3;pGAh+**Hqj z3vhz*tXTG=}Kardl_gc zXC2ddGr%kh(!Ve+gC~l|D-yYY0%aMQ$lb#5NaGZ4eLoZ#*-1JyNBxK6!z@Hb)lFO! z854ZF(Sxg0!|M60Hm5w4x=qx3xBR{ylZD*-^N+A}{C;c4KCoIU5$bMy`Wr`P;Q$;J zGXHi(?;RhUQD?`lX1yHdI~>(2zD9~tnTce$(tH#0Fll*0Us_1jh>897_01`hWY}l3 zMoJT|;G~2&O5PMROGK17GjG$40YvfVu>_6-nn%7Yo-r9W5wUB*5Y8m4Pu&8h>cw+)4PM_raS}{AN3< z3kTJb5biMCx}+=MC~y*^;~Yz+i}}!}L9n8!O1>>4j;)aa8yODCX_~s}^yccjHMDvm z>OJCJ!utT4yIe^x`AV3+h_2=L+N^O<4HDC7I!zSBIP#h-`Z4R#MSq-jT4K(*t(P0Q zD2op6w`FF$LA$Ql?~LuUU6P+)nj&pD(>eVw$>iR*zD|CKi_AX;1ZjBO5s{0!cMVBe zZ_$e$|8@;yw7)H7)E$eVybBSgzoB^3JYPWCjE@UW?h=Go@b6o(va+jsBJ5o~YUHQ#VW2vXaP5XT~DtHq`;z;draSP__Z8ZBN;LTbzMmpe2?9FU+$t;be`|EZNT4%D4#*B`gNG;iQk1pjOrT#NI*X!5b<) zf(c_S&=RxL&I;A2LP*Y%o&!de4rK9-4kTytrJYP+`dMlrn+?wSRXP~Hki+U1c&Tr) zW%;8e9s)sJe$Zgnq@ozTr2IoRQXRVUKPwW}vc1(Dof?9YV<|6!R^g{YX;vi4M9vn@ zv>xHNz5&(=@y|2~W?RjlIRbnd`fVj;AEV}&hfRuUX-cvy3oob!e(o@iXnMxWd%gbl zoz`X}LC6GT+lFoAu~c5{a>m01DRjmB{Cw2%x7C!I`FzVyMsc+#x_Y~4%bL{>igU|M zQyr_j)+zi8cN4n**S9U)l@ZL(SUyX&(2fveud`wq)t>QZ~5&)_SuotxnZCV=)f_j zlFEOUYI-?k*+fi7hzR(jwoNXAu7EU-k^wf2OU@7n+2Mn)^gON zzAT!<5%Fi$g?Y%RXdL(@_{AwnM5u2|-Dj))wQ7tKa*4?k8-~OeR3+dPTTl!Agt($! zc1D!4q}ZUam<=+ZZHd=7FM>~VP_SsxTHbGT8kIsJC*`Cp8ZOp~tI)7FD*+0n=x+AO zLzvy7+}ohfZ$$#yGQ6Wjz%bK?yW(jvI{rshkNaU&R=&yM$5-ybs`|fq{H+DQzg*9* zaS7n~R|{ktRde17ra11hbm?TX>9qlehd3V*EU#i8(;RtvJOJ&bOaPqZ(G`5yr7 z`qgbF&_yLAr*t{tJmF?fAzM&P*rB3rx2e29)jxkA@3(k?gHJ_i<3-uHlalu9jZ+NB z#*(-p<)(5)PGyzmmadGe8GyY*`d@|y=|JowMZ&AGZ0_{XEF;)u!`~S8kzphCiCg)W zXsi9hia&gQiN*{$(d1_yTeXQamY(;A6O&&Qi(8j0%?UAE3A2{GqqfV@OqD=omH)BV z*(EIfvWm}<8T2!%@!KASZ7nK$r%tC;ag6=gmlkkcurNZB6-<1CqBXx~KecpWW>3Me z{dK7c!eFBxK%h{%$N0uNjEn`5ie}}bwi9v=imz{-ob%6+r#-yxdu(U=2T*2QB(gXR z{h;UZ!QLW*GNA3-)qf$o6`#J4)T}4W3fLLrn@WaoNqpp&L+}gJQPDXp--Ay9p@DCQ z)U%-<1L?188N5byp$I6%v8yV7>gtw^oWci5((qA+fubrwqW_PRe65=bW%^j5lgnq~CN^cws;;Z9tK=%1359$xM{`{z;!-%u< zkKfMM`h`QGDNTBsktZWceZs&aq{cg@^uN9QBiL{B5mDp%n=$@<&1^sFTd4Sc+BC>f z)j&^G%1T8B+(TUlQeG*>xYA+S2_Gbf+QRO?wW^gZ33Bm$0{ZLuFS-Uli=_M7)$>?n zMxUs_b5n;*d&RZIRzyRQuaztG^@r{0?DQw6tXdlpXjz9A1aF%ypo^UuG~|+fEBvZE zbN9Y6MUl`cS^ZcxN|O8Ng>Q%0g7m4OZd;puSk83(C*Y?rd8NIN03TKry*1_;;eD%s zec#J~unMbce}c1JMCFB^(~mzT9>PrLStD201`QWAqnvJm+JOZAWOis?D%?)9dtZqx zYu*x*=lTaZ`^b2$);NU(KGw~mZqAa`om%mHCW-4NHcwGDQ$dCt%NYFH*L z)_13}9@hGA*PL;RXnN@2Y#}D=a+lp!H9j?1@hSW6MHDn<5_NN5anl(7*ER-?1~rr2 zf~-uyj+n)c2rB*ho6#kJwlbYze)DEge-P zf{%_Crc#lTcfB|n8&V}aoxF9WNMY32TmrEB;HCP#K@GTZ4P*YaXXg7_)S`O?4u7(M zW*HH(-Z;1IN4$eV5EaGGDz}1r7+*#a$Wwx)@leLVo`B0HMo||Ah4EbMDgZ2kySQ>@$BB3wNoz72L zk)zKw9;MmKI=bJ|hIYnVq1GB6vk-!i>tCo&yapJmwqZmqv!$299i`y0#t#x^$@h1t zIkt6S^d)bWYe}1k4ehR97m6oSPLMNOIQbz+m5%SK3Iy%S%gqvf<{Ijpv3PdBMs&X! zI_?W!F`A?O&0bmb4HQX9hm6>s@S@MqCH{ob@9+a3)cuRn_@OiiZA~w6;H_q^46&)+ zPhx#{VROpI2)QgTICAOVcT*5pQ$=iEU|xTBs(6jVrJk~^c3=DvqiN>%8Utr$9e81L zfGCXf37MwVBsl>W@-yheLpl)$tpt=QDX8%a!xHh9%HisBnS@MIc9$*_eB?qQa zl4BL^aQx!>?U8q-atC=15 zSMFNh&*J9+-LzOD%WQRJ70o0C=1;B@)1vLbnAtN zg@Y-{D2qDz#bPGA5T3ExBUSaJzb(IT1I*O;J-$g!SB6teIpzQ#?Kex}5+sA<Ebn zN?cqSe+66j-iH>jvn~4F3|HwPVbA=q|8mFea-m|w8E@z#GB=vaa-04=~R(VI-rVoyIi;jlU!daUQL6TKQp|L7xr*I-3 z|1g+;k7ty)6n$DKF6Mng>L)qqb*M7OjJf(O>mo5KxQXio=qW=x#dezDdjCCr{~v%= z_8%Zob26|`Kk}C-pht9K6R`-#$?Zrr-PhTlSQ8`Zv*U)XeI<+-)zqzKj@fOOQ)Jo< zIMmsp_hx7)_Rr2N{Cq7bJNitYpi?U}cyE7VRZ$07)+{`2w#3(*_tmXO`g0tA;LhT# zLMjOP(x{2q7EEW_L^g@AWIoLYfF^2(dMezje{n;o=f^~vevWj+)!%h?3tY>;j%mKx z*5Ug)@X9Y69>Q|rE?_}XjJ8hmGoR(~!L6nSf!tfB*0~z~T^n1z0(h4?3JQ4ce>s_} zeiHT-F#Y!Q_1>6)^O;nj?~E5L^b>$Xdxox1-dwi&VzVVXv#d@1^84nIMe)OvG#Ov2 znQ)<=ta{z=ery6=!@-Tn$2K8LI%K#(EX8=M(m#L)JSh1@^Dbf@s^w;p*T_JN-n5(% z2^K`5ZMfMvE-2Iy->y798y2Hp@gcGhe8PHt_Ksfp zME3m@+CtJ#2`sCIEZH4(e))L1)wXGm>HOow9dS6s?^AtP;7g;U#0DG}|Cu?#HhXi$ zgBiuN=W0|G)$B}~a37yLUf6t_;Z+znz+pntC#N?64C}u?T_hw++M$g|zJmlJ8^iPe z0UmG;=As$^N#|ikX4&dV`%ke8B0{d10}eE6A31c>UsSnvBZz^0lwMN#-9PNO(I3dF z9E{(J6i-dom%ZOeu1MeUn(zg|KeB~q3Rw7Z)>cqSsO~#}^&Zge8%>ezun$6(sz2990toN?}ONa!W={w3h?2W zk*Wn2sbE>`@S5xPAo&;kN3z_sb?D}fK}$U9ddmL>(uYKTe7dJapczUS(#7Rx%?dfi zzpYWAB^tewlf__s5uUWZv)+2?6NfZJ5Wso*T(7Ex|BD=lqqM#SCDvuTdpWr3a&0w5 z*Xo%Ld}Nh7mi_M?lB>QPXH*-?1Yw_NrH@{N`Xn-t-j|k?RPm)WhKt}7i8wBNu9<`J zJQqH}-7@hx(G=l-^Tx;*n3a|ar_=(i^!)>vS-uxZrD7%9DNEyXUF24O!0WLVlb!Tf zb(F0m2T?ov;#V!M!&0@iB>1sWcAiIjspoGf4Qav|7=ZNH9e+GZnJ6=wF+RXDs5qc6 zm5!s)AfXL&3{Xc1JKbD=bz+$kT@9v|EKCE@+7s*;_Hp&Yy7N)expojL+Se@tYp7p;#7 z(uf)65I8=3wtx&Y>)EI^HlZ_%la5IT2zUH)cbnBz{_{f&bT3&n%D-}faT+l~LSR4N z1wP{m6$mdJ^6;D7+;-9c6ORd`ULzx)TvZ0#vcJPQ()IscV=Y>(p5;GF{pqh^%W4ab z`|5CD8Y@TS-qbgpiVL!4U3PDjbR@EGVvK8JX~&&vKFQbQ0M^N!Cuuz=CH#k!M(gif zAx)LEq=%>6seA8Az5|Cu%3T@ZWY=7E`oGaq4oRA(#NTgjw(t}<2i-dBD4h}Q;hmB# z5V%iq35mCjdpW>(J;9?o(FhCQpU51#$tb_#Hh%bwb1^jR#RZC4;H_ZYze} zyH(#ChimFS#7i4ar&g{ME?x~W%P6+ab2gtBt*xyRTzK7mOuH^&*m!)K_#65^ z%o%?F0PkN7$FgL^m)`HgsDmEZNrBNdTB*QU^X&evUhQ6W<+1U8XZn|@qz>q-HwP2*r=o_(xN($f^6e;2&b%w zTSdwallOmmax8UDXB_SX-HYCf7wI#8afqfc3}14-!=FJ)-4#gT@-44NuBTi2n;zQl z{8k|uH0i>U1=5w1Dq`r0Pl4J8hWCI74gt$;kC%5AB$HpAwz;5hf9c-P>7?GFgE8Z@ zr`zi*8Gtk}#RB{+(A9Zqk8inuHfcj=^-W=$3ObHxiT!W8iR$8k@50U*RIB(xmnyU@ z0I$r^e*mjFEO!NA)|Rh`am0!I%Bu2`H`@YMQwwSj{0Cs_e(u&#)676+5Zms8)lCS4 zxlf4KShmoaS)O=S@Nwz!W$8H~UsiM1%35rQQieTu*9BkI1)b-gEvS8hE|t zuMX-WWaOgkT_~6^-hg_KhGbNFuf7_770h!xc1>WZnn98yUnMA8z#Q57#d03J+8$rr z#1%?ZIvPdE3{=s$9}?v>7%-U1!ObOb`80l;A*n+8^a+!0GI3NUTy1-LHwcdQ2twO4 zQ12SALjARK_tp37G_GltOpL3;32g)2Ad7v(61Z0pdl9wM?>a3@DldY}5I8L1ywY^^ zo<}4wH-+XaQITfz>zse1V{G_zc-(lD$hS9FEHRM+myN}??8fIl67@yj+Xt|`JRFNo zN*$(F_qz^J=6C88ML6z{WHk3}CHz+=z3BV5UaO{WecCczl`A#Excm25*mg^|oi716 zIUeu##Sh~ttR~rP7p6;qdNP$BVeW+gai^3Z*k%rE5~3$W`=_VaJ2?wcda|vYAABI% zHa?|hL=XV$2)*|!^@bW%qFProUI?1;Q%jF)r{k4Q8lIGrQn3HEf1N;&Cn6xWozEug z;x_t)QU$!>uE>Cg)?nN$Pj^DiY#!KfCo6H-eO;hqEJH<}GX}lL^fQU=jNtKwhJsZ5(To z^)w9o#_`_P@6KgR;GF9%X%)=MM@50wEXJ%Y^Ef6om|qigJ}icD-|epA@IiOQFT;-s z8D_(R-1Jg5B-8D)7RJmvsyJZze&pu4>>YgVQwI8_6E%B;clE?9K^0M5uF4l=b!neU zNKFc?HZlqmMS-w1wx08 z64$!K_ee|M8nN{?3+i?}@lM~6b>Wc4`9FU*5nySZ4RkaqKvDX-p8sL}?P}U3s^@ZB zi8XecV$wrlon?MkhW60swzTUd5e%6!n@?UM6oo5YenQ6zvuMo7Gg%X#s7m)ZAT~LU z{+~|v5NmTOng5Wxj}%Lh-!RTY@~qf$>JQ`zPu!O*tYxKKjk!@zAj{Gl$3)9A$yo17 zRvS4;!oSVg6|6%M=H!^OWaVsXL(%!RS*OdjGlBSF>S7VL-B{D(fK*SGy-yLxj^PxT zv*rbq?fQTGX^xJ-eP-yGXuDE&-L+*7^&}+~f->ZB&uQjQvRUPY;o1I-VM|%Dlf~kf zGG$0eTEtXuWr6~|k-Uv$j1314uBz#=Z9XBL48Hg=u`#1QUfJh9p!dA;S8JTv@Dw|W zU49zk$KwBc+F86(Qzv$`WG&46LiRGZ8!*_OS*6ns{sr!fEuSb34*E-YdGS;WzE8=s zd`aq={HhgObs79NQ~1CoqE|N$%GDm~^x3QPujn~O_d3P>#nqx}yKFJjRBn&Amn!jo zS8?rCDH;$OKD2InaHLHs73!g>;{e|!e6B)A!(u(kJg5LhU=bW*NwkC24x6OjZ^&Lm zJ$Hw394UKyCm6Yif*cIf(`&DaMY1T_is8@g{{ULBoR_?lR^C{@BL?<$rM0}wfbJA;_&gajep7h}`Sh3{xI&Gw-jMS8N3}N~<{!Z6 z^+QtYG-#oJT?a;(8)4TLl(@gf3Z`ykmRO(>$lmpzKI>wmByAmLw(sdi(BzKkNSxj) zC=2Oqyw0-+s7Mjjux$&3i?|pAl|_e4KUBmpu*k=Iv6(q*E#X8oMZP{MPdj<|0OZP5wy4VI9924B`h>yU&Zv z_UIe40h0}eB^*rtJ1pP$S)8(S_e&Oaiz+Mg@Uyi#4*B2w)SQrh>y*uthaUD&ho!_z zsRS9l8(K0$!K)d1QYF4{x0d==zEHbd%fTy!oj-SZmN)aG9#%R?Id!68wYjYh_Rfky zxp0DnrQ(XAU2@Mm>&vOUYE?9+z;doa9y532aM`~lCG84Ed#`+z>PSz`adbpil$kg% zvfjcIH1eiiXU6*hd&59S?uFshXDAM2{?EwIniPkAo7U8%n}}#w5wQ5`cY>r}YTj59 zMuC-(BUk{6$%}mV7!v)KX6mw2jJ-36=#KO(p z{IW`8d2HL6dDJ1 zv6~b*>$-Jzu#)v)tg(`q5>kZw$ww|FaLl&)> zv+GJ^I{xALjL`}kX@WF!26?)ErIB~rE$_u#ucyw5E*PevLAn0`T`8xrsg7~AN6UqV zKUL2c+jbxsE$p^mZuYaHQ}*N_5TQF3P(Y4n_g;b|Pn^%#eujN@>y!A#N3eGQ5?OOo zU4?Jzvn@28MT61NS8t|v$=s1puaE}DbUb7LihLn32+S@zif|AbJzp2(9NV;7r|NXi zJVw=x-ZCySJ(w+l2I+46`GKJrXR1}$FisFCyjO+18kX?-+w8I z&p+h4r?gmhFZ0}jP#Y~72Vfs4!!E0bAEIRsrix|>Qae8``4owMN@}bKZG&Ws`gN?S z6~-5?m2lQLaV5r$^nm&jt=^5z#F89Qyx^H?`JY zU66yo_=cWcWjR*mNm+9r5?nX>wv-H!(?Ojy;?{_ZMps=4h2)a-KKsRa>*?Yoigq*uKo?nc{ zFzu(lo-=7(Aa70UL$xBcCCy}gEr?93tAoy($6UJ{nr zyo%YYlaia88k$JZ^sQ>ELuk92^;vU=-XG`u_N4GeC|C2EC`;8kzt}PH%-f)6@N#{Z zNg6*>HBvLkLEa6vS%bee4s~~Diq8&M&Rxi6_KEiuooU0;@t-SaZ=$2t1I>dQbaHL7 z5;o%M&AtcSd)j}6Qjr8YIwtos?@;W%O#N3`jW$aq0Dde6b;pNMhYY*#j3~-d1hweN%d7T;t^K|b zHP$4~NUNa&hJTcY4h1%r%lnnnaL?L*38UF$m!Yl`%>lEL;Ilie8Ou5G&(wIkhMsnN zC;sj5bUuuZUQK9azxR8iWrrhg@dGYJANQtA2U5VKXlYZ>#j=_i!*KumEl5}8{M-rp zqM&hbhSLJ0-AiRlZWY9V3As1rlkhu~rlw=S)im=APa36MfZtfB1{B2v367bT#$Q8zYBVvDY9d_$XgpA&4u2$y+a%nKCK3dff5}0CzI_xt36xut+f$C z!p1?PEHTM|*qRhNIYn=;_S4b@xgziJ`<1bliZW*yG|+>O+{^PL0w1Mr^Va#%pP>S) z+xZpwrZhz9d{RCoHBEgQFV$EW!t-)N!uBVs)j)0H^C)Y7A$sl%{6I{@qqq0EI0Yy_ zoG_R8S!nV)C!onMiBqMWiIL?ods7wl$Vc^E%Z35QmxC8?weL>{F?K~Ev3MtKE4=k- zJC?RFoK*`%+)(lFLV^3(l=P^RIQevr;pW zCAIVrRJbrwPX2lEg7f)Tm2mJ9ddBO}eI3(t;P#q_{x{Kao3Q)K_<}VBazi z=srxim#Q^1{)W+Oyxo~wj|95&hyg6S>$=@Sv**%#R@Z>mO5TRcfY6TIu5Nz}&9L)z zmOs)6L-DbSRD3K14;vf$3$1_u0BWC(Q8fn{IBCOsRma{Lk7jcHF}Babl%+;HC{X(J zta|>n(@yrXr7z}iH_dHB+N;bY-eCE(*E*5uj!K1NLpomD*5_McxXCL~PX7Src%=N> z`Bti~%FBdoakdA2>bcUI_f}%&GV8JywibVOHinCM*q;)g^h%CuPLD!r2j0t?SN{Nd zM;F`3I1eSqr{aZ33nR}t^c52EYKIjis?x| z&lJqPO6fxP`FF)RroG{y?~Sohjq+hyl#p@;-RTJ1a-B-yvTvkV5cCx7ATOlxw0LO*>wAv={NKD8eG z%9n)pMbhkah1?<__Edxe`I?J8p;N8XIj+|6?Ifn(VbNL>NU*^xA|mYC2TWSzGCH^T z9*FWzcPa`bl1Ve3jHu*V{tZ+h&@+|6lw9~QZwyIXlu;kDiaH~Vgm)M)qaGT$IAA>iZo z)P*9|;xs~%CgtSy;mGZ%bksY}Pc0tL?ojoXrr>Ut;U=-v+Vf1e_F>gGZDnTG)*~Uc zJj;^hp;nK0KnhA6@CwrDZNwEc-%@(!Flup&3-2X(5FuC*mQfFcb!H>gn4jx!89#60YAWmlR(u zx4ju7!|SzA7x*~`#B~yq+Ycwx2vZFm_soOb4XYh6FK!1UjTa3qC&K>#ot2BC>}S>EGV*jG?U z>y+vlM*Y7Mlewj2XrH!SQw^jx7+5M$PjEIhVfl5|ukbI996Q&r(2(|y)evuN_`9@B zSq;8Ay+%=jJu4oA6l;rOCc}?AElNxXMDD%qx#6ytR|`*a>(1Y^?~Qz2)7-!7{cobL z+HyG48uHI-p7VCws|#dGZMjV#skc+ozND3;vh+co|O}ykQ;W`S7mN6dqpl+?mKI~F~MrbdWFQhY!>wtAj4s`yB-S>6yQis zGDB(vk)Gcw(`OpwTDXO)?%JB#B12~5B~n)eFg!L&j^RFI&-JLLVnkONOhYZK97k)w z{;a2JIzLG4JP4&CQhQ7v2a8GEc-Z$XZ#it04l+{XE)a&sPBIP!K^mRs9Gc=%k^)W! zM@g-T&9GY;3rp@Y5;j@sJtOj{;_t(qHG3|2DuD9I-=#qd&(@`B@i>F-=9O2gz$Yxr z8^!q*uhk{eqEvPsLX=@Nt&~B*J&jqb*91H+w<4v~j^m^UP=B5(HkqO4TAcXN)`Xno zWhZZusaWf2iw@)UYK689y+hWw?8P*jECFP&vUT)}==@tY!A-`3zPAx;;2O82pur?X_{8(oVx_ zIViQp#&<~h?N}%vT$PksN%NlE17Vt02)i^O3%v}%~rUq$hS*F>S@4H zx8NqHjUUCu*-L0Ebpa%7QlX4`S8pWi8byt0Hk1_Nyz=+1Y><~F$WonY2L!E>qDjw~ z{{U)(uKIrA32SO(S6fm}2^k<&@Urtdgxbx$*=Tu}55*nz2M}-%?47Bdf7MzqSGcvv zg#`|{2`WMZJD)%{sQ1r2XYU)Qa+QjbnqUM^vF}tSMU@V%NhM&P^%48275zTAuc6c_ zTPzTIw(nNvZx3wKq!rub7Lv1^6$cP9MmPTer7-oc4z5;cPD?;b%%cQ2-^4p-arsl4 zO2*9WjXLs7>+t8(v#fB_m`+|9-Xz+hw&I&hp}$e`{{W}&t5c^q{c5$esIx6Bx|O4$ zT`48e-x%N4sosW{(-p?vNd*J~2=m2rOq#=Y5J4F#@*8)ibrg`)Jc$B%OI0;H8e%HJ z>WxDiRL%G3j5!&VkA*AzWS!1UNB0dEF5s0qg0fvWN>l1~AIh9I6$#eFcxVe!FiFPa z0+p?Lf>o~d4m7B$dO9UGurLx-0@8YNb{WPurfpz`K*k+A)W);GUm&@%xLgYMOL3cw znj=nY2(g}w#;?@Y+bya)q@^x5E>LAsT|JQ604mPMVet*|-}{FC&aPcK599{prS)B^ z7OkD7^ea-erlywCR`tciVfUC|s2+qZ#dMVck^ln(W2x>Ar;fZd<*$@?t{gmaG(CT+ zblNoCvI`y}lMPo7zqn3!WaS@zvI$Yb1~ZT=cV5^|C4Y7OoZMNu+JE{+sD&F%+PdBF z)>9!)1wFR-2x&)eQC~+;;TT34SJC53nb6Gm%|RMw0qrHA@E`|i!$LyAu?niZRy;-u zrv}?QS!1hi(l6bch`{M)J4<;*2}tw<7^;%= zg8Z(4a(ceCDe*q)xwosFwXI8BsgB4iC-HTyO8#{aT8dni*0pEvKQX;zc%+d}Ur|v` z+eYWOv~p>2AbAC&Q%BT66*c}Af#?8I&5@AX3D{?+CYMRTC(u%Ly-5s!Jd!cxdGX0M}@BqN|sKR5V*ND$!PV4LV>PSD8Ga5;C&^**}`qHrg z1=4RfDbZnz)S$d)CvT9aw5J0Rh#L|y{eNCmn`VvSw3C1^Jgf5X{{ToS2V{&_0`Hdm zm$Dp@rftE}=|~yv z-j^7b8Co~o?M-%{OKIP~>x%eg*|!^nST^X=CQOp(YCKqt7vFhG*aW0*NzF4c=G{oP zP{0QjaCv$$hP;WXq=!`2i)D>R($2xfs^bO=XeS_KnT0_rI9G>*u_RqjVc#o!A=1~^ zy`}u%T5UJIBcgQ_!^)QkF1GgXF*xI`;;K__%MjF~)GbpL7u=avRP@v-!GR2wta4S! zct->{y~plnwG5sc@D#w0Yqzy#jJ9~4#7q1Yq4>IAPq!(77_H??N~OM~DKW$)4wbD7 zOLv1x=!W??;nW^J@!6;r&R{NjQa+O8^Oji7H8w9Uwp2Gh+XGPCEhbBWo4jTjjMEBv zEg z+og2tigq+71CGT@_nWYNsLFdOV2nFmeLb#Lu3fKs_f9dQZB|=jmV0_HnvU;pa!lSN zaTicY4M>q6P~2s*ed6THav4S1M$I=NuMG$;G$V)x>CFxAh8hbgs3{SKppZMIEUeE8)`!aWgD>dPcg`4t1#wu1=sagho`^ zI3=i7=#GWs{{XBO2VwHe4D(Nd2BsE2hC+YFqSzn*&~bLU=8#5kD+lM zNTP}=)~e{DiYP)Vapl)pHKRDCWsx#V5iOV2oYPl15;7ZU5=s`qE64}}OEG$uuZ1Y; zCmqBcMK!IYj=qjsDSj8UwD(+E{v&XmP}RvnSru$Q6C4~n>~`=w6}`I+(GjJ}Y@jJ! z1Qd_Ntk(qDHu-Xt+pjqp(t40qG1K%vok1K0)^qi@4=nnI^y=KcTj#rEpK^6s7e%qs zrrmSQEp52iQk8(UrDS7zo^M)d`}7}uv#X|SDeHD3wpMZ7Bg`D^Yv!t|SK*cNQPdkf zq_mzI9sCOVMmgJw(8pU!F2^)D4mKcZ;x;Kx-+E@%ggtd>_Q!Oo;G#$CT(?a{rKGa8 zHFjzouAe30B>MNN`ZQD<#P?#$yWBMO(I*Zt`-%)YeN&USpXp1Hct3czs6QU-3hu{$ z3G}Fi50a8d&*@ygC1cJ}FQghgWg=Rfmk_no@$HO-m0S{W74152z-WTKC3>L#afD@!cn=;v}JcTl}4p%EnjC@Zs}!T!?AIoLKXR(*TZ~AN^$Q{1`t7Gtt)PHp01(HcxqqNuueuXFS)0pupH)%9>DTKH#DH+X6HgVs& zuFP=)*7gBf5>IfTr2hWYsNS%&um1qv7zh6VzEAtp+Tp<1ZW5$2f_$(BMK&McO2&LN zI6Uy2if|^w->7|)BL+7Xj*J!f-l4WTvSu`M=(LgiYb7(FyZ{ffy!jFhBCCN{6&x}o z1CHfN10StqN8kAt9o2GJ{{Zn6Yanv}03ib(X*x(9!8A6ik(*8Iy^@a*mwI1u`6dfZ zMM}0?Kmq{k-DE=g+}fMkL;`4dZbE7ku001(?)l>ySS5K80*)S=tH^&mv$ zzR& zk&huuD7uN)wi$XGEjAVu9&q3*e%Ps<8Y&btsEEy_AZPIW0;lA#cfIN7 zo42KyinvFT(!-59w!+@Rlhf9<0y`StR}%FH0QtV;s`INf<<`ZicwczZ?>}z3%y1Z1 z$Ba_gORN2bHn|Ohk}z>zQM^asey3?7YD3H#GY`T@AUF}Ogxp-HN11&xjVHvtbEn!$P{o&4 zTy2baXDz9=WjxzuBpeV@l#oH}MOV9YZw+D0rYy5tAoT|DsV#d^gb5w?&{Qe_PrT?on&b*-5XO< zkn7JiE;(>4b)mQ2=|&xn(T~^e{{Y0zX~zw9t@!@{$8Aq3QPf?!+^60jepG8D7iFc! z<3&QlicE(bbquuAdC4hlAcATA&PI$~o0={t*k@cGyFt>r+I@wqYXBjYNso4y6@{@G zEujf6Bf<>?q!1n;0i0DH=BrwLpFY{b4LLEBZqkuhnXHAq^tlG@e{rCv5T_He(FL~> z%2BXOs(&D;6&n0lNW&&|C>E5G9C=vwt>>qC^H&<2NLMi84)`?6I2(@0K3ewxc#xp3 zCGl3_#I7OA)VGEbiyfs1iKjHcbzb9Uw#UF~D9KRkaVQFT+-1jHad^QA7q?y5BDbrr zP~Vc(zC4{um?@G}5{T_cl2+rOorrCf6_ess{TmX}7U*Lrf%ATU{(aBfA_a?#Yo z(PI%NV|_ge3d=1z09txVhzi1TMXctZR?E}ce~UNY2&CEc>zZQQi4Mf-xL?$4X>|nv z?$j@}UqDeAR8V~hl8T7b%F1X*7PrmBHNN_l869s?9JMpL`;*Si1wOXRIg(0|5BcTy3%mA(a>MIeO-yegp>?1lTt?me8rh%043o)QH zcmZMTv6<$Qrgzj!@i>uY_$Lz=>1jFl&) zEr#M-6}iUXnGR=ick&pkufvO*M&P?#=Nw{GbB4o!rAkhJVb0DZ`W^P%1HEhCmMN}7 z(y`Q_w8#GXT#&a5cxh#DEZ+!UnNL6@d36KlSCNNQ8`~ zGvaNOwiX{i^BLc_*V2%!+)=pNLrhGBB%!4AsYEFfPBz@{`ry;@+r|47kd(|~Ts4!q zPfV02>-bOTDvn!-z%0v_`ul%HdM?4Ljo)DZ07L8jRBdw88q(elSw+o+oGEeMEXe%R z+dq{@^H9fEhjh0((z^Fl>t9eGN1MXGJXN!2Ug!b4;e?*h;$YlQj$DDW@JLGPu(yjLCC{i0pc`GF) z49i5k4>94n(!b+OYrhY){O1W&bwQA$@Ve3$3Ebnz9B22{)wpoWNZopt)OMRu{{Ylr zh2Z++5#E{8xH~DJud*+4QiIw%iVJIhB9(3YY2-MJK=xi*d;b769X<_GMV}aW?);DD zsZ^Z{scpGcs^E$2rvx)CC2PPvg1hFht@^(2W}b*sl=ZS}Yr||#QFa8ufCvjeg!)yb zy72o}TLE>*j6Bj6lJtMLbzO(y{0Ha;`KbQ&rY)Do7ZT+WCGE$9DWb!mk&K~7vGeaz zaaT4$_m*>cjnov_TjDp0>~|x39|FECx0@aO1|(wFbO0$$IG~Wc_bEBS6yjaB;ShDS zq|0Zx{h~+6)C+UcmyJ8(7``>u*1~*3!q?GrwW6(j{54E+986>1JL#PJk(ZmReCrS4)oM;MdppRzqLnIT;}T0H~bQ7kSsypOoXb3;e0m)(Qo> z&gW1;K1)`5N7VY#O7B{Q@%I*M+rdL1y*WS;^XaGJf#I!BPQVDkLWgnxudzqQLF~BwFC{<9 zpk(Q-VDJiZ_he|1_!7!;KR%;h3DP>ytdwdiDF^mc5(RqNT6X^c?hn_J;nkI|-Xm|< zdY0tEvr1N1JuaN>_vy#!OBT4+$T(AS9Kb!>Sy(v#0GD%6<5n$M4E4WwvpAIQq@<($ z>Bnx=$+ftIT|*9FfL6-a8XBtJB)%6XMwty3aP1+~jdtdLTsmf1-k zuKxh`r>2dy>3G++Ce4z+a%Ir#vAVtz0nXo`sHVZJG^~JKBlv2Z8~GYhDe@AOBn%z? zWcKvUSAK8!HK({&DkMl3+g;9VhLWY2P9jRU)i zrd458lGZj@WV~YJi(dEnSyR1HWuGN#B&lczBg}f#bvoMQa>_zFRyQLUtBrrti;E0A z87nCmP{!t?gz0#fH5VOhw50X~5T5kb3_x35f@fKSI6lnWsP@v)L{z0m2c#YSYn6El zBR*KCoa+Lk0va7C9(c&wnO7AEsZm+M9fA4Mf>y|G3T|M0AP0njHL#+svQ_fQuiIob zEzyJ%zTUK+siD_8LCDW=aZX55TVV<4-D>wZ>tTS@btL{I<2X4L z7;008T>5{#N-QXH#CqZo<9_$@zUNy?9ZzN>*@~7%EHTF)uGLOAcInFwWBlD>Ob@l6i4=%R&`9rrYYZ6C{l2WuH99K@q ztG|fjXCQvZakVpa>tO}Op25E3^Q^m@Zc4M-nvU6Z$0fY+Z8+*$l>3dG{{Zc29sNH# zZXIfn?n(0jG>#vx3uo_f{{a609C)uQi&~Q4(-SRRK4XcRs&ny_^clL4M1d5!CAQJl zrjv1)g{#9(RG=`ElbU4xg%>Gz3)HC+?oubpc3i3Rx>YK3j=HxL`-m9{aeY9j1uJrX zBUu)dJ*GHkc70&5&aaXzk(~EFv`A*m!&7Dk2B+0d$1d@C;d`ZCyviuK`!`l^_ z1g%-5Ejp$~r?GvdU|q%cdSSTZk|OxYNLCbDeTPwkJGMub=rS2`O8Kg#mnbJ!Sf2B+ zzOE+y>ReA96&y5zJkA2(Tn<2Qri}oO9 z%vUXZHMY+!lna)nopNpe0Eib-lt+osKW7OsR(9X-4stPzA*VQip(Z;J980gZu$RC& zDNaDBcHae?FAwxZvO1bl8PTvV&N$OSj<;^HlXP>dbCo2_4V8KLdBD#|=HW9%`;3ZENsYXH?>XldlCjnla3IIURR zbbQEROOHJ&0PNb*kfZCefdl^lnvmCTys)0H_;n8=m6Rxd@|u(NCyFJl3C~ASCmRm* z(2|GzHDD2s){_n<*_Wg=8#d{xi;e07zAG{wY2;)j$n%O^N3J~S-D~20uz}&F*W8@S z1`Bhd`^Q)O&VU>}zs*r5q7wqu;RSUM!Uyl9s|AAbc9w@rkH$-C-Nsg?*Yn(NJ9&Ci z?xluCW|r3P39~T@n5D@EYxfmyE!<>^vD0<4$YCS_;zV#rLj06E78CRHK9u5B%Y}Nm zu*`{3ZPQeow({6qFoT1D;3L8#AZKu`wouJO&~)P{VJ*J5pI=A{amNbJZ#?Heo@v>m zcvj~SuWHk}c1sQ213hga!~}A1aG=B`wK~#iyA46+aduU0~VR*Mq=? z9%}nDmdVOXZm}^jfiYcWLR5Jy6O1Kb{AgA{!8>GQ%Qdr8>A6-LyLy93LzuXC9IokP zQwt@P&}g?ycdzr*}zf2nvC5gi!fz_PVlbnv} zC)S_(4~IH`Rp|aFi@Q@{UbKv8S9?RzP#%u4B)E|o?~|VaO0%&^8!tT;@%B_!G)C@B`|KuUTds@%sSw|3QQaRfk^v&IoSk_KODR+8TDAct zSw3F0=G1z^!(x`W?y&2VIs>i5Xa&Bct34$ko$^1OBU?DBqohCJNwwT!NmHH|TbBN? zvycGl0Q%IJe4u7Ak~k{!EY0Xk&saETB!1|JwkuDo=D3uX_ zK}p4N+#*>l@?W z+!SMIW;9@gS}g_wO1f1dV>z0k{%?!6b~|rR_^#U7XeMJ*rbt=p>17Tq6ZP$i_>Xb7 zb%eH*6cy*MV(Px0l_Oa0)+RcA@tEl8#up|za1p-eAc|o$y4~lm*avXNKP7>R&Ox$D z{{RE**Yn%KTWimJeiQv-mToC5V#S1hyb=$&b91IpF@rQRsg)12d_k$v<|~g(Uv~qXc~^!wA15rNjptM{-s%ihet0v&BIS zMrj>8q=v@dDo=Hwq!cuyBx4xH)x)Y9{TSOWTSp@g-oEF#H7?G?Q(ha04ycS}Lu!oY zw!>;yhT0HwlYyMniFJtUNy)G5BY9%TIM^3vap5%lBnB_s9!0JU1KPV_CaQ}NeFxqo4Ybe4xx{7Tlo^pvhD zZI)CSN<+yc1tI5C9fFgw@wW%?n5vnCEqsT7zp|Xe;4_%v8@Pe$Le1v)PBp^|{5}xI zaYXRDPg?Z--3pW9FYSxGH0le=1ASOZqsq8B1zkBG`Eo``0ESaZl_QDVFwhn${_?37 z>lTuN^mkVK7Sv9XsaF>P0YxD%O_<`&4~7ew1E&K6SY7WNb>l7C`*BZ?KU(WKTAuKT z%=9pqrOA24CA5G(1SP+GBW}|Avs3Z0v?Ug95@`mlwtsbHD{gh#Y$e(d z(*EzEX-R%Wg1(?ov@_f(bpHSk%LO0a9ZvoHPwSnMHH?y@5HdsXw17DQus)wv4f9#V zD|6S*DC+A$TpM%pWV2;*427)ysBqg)$8`uPLYk8;$8t#7rTkq=0<{}fgO7TGTNaHk zrIRZy+>qv~xU|cmD0i*bTaFz-^9m9O>K%ee+Ze0$qV!6X!-krvJ~>HukkEVF`KoV8 zYJ~N|1`9QU-e%uR4x{p!> zR>OECl1E2D2PbT9Y3Iwfo|C9GJ2sf@l|3?2BcK72I=V)GEa&p1CnF+v5BPC9B2wXh zhSrv4hPO&xjTA${+>G?cY@B0tZUN0+A7>VUV^HzB!SBo^$j!`Q3Tjt!Xju5uj2`@ZFyt0uh z>K8Pr{o~D)3pnZJli1ZYYQ;*BmrHy%WjOFg)QlZiBE9oQCBoEz+jhvehl2o+k=TNM3 z+|WvpmL@Ufsiy9pjOvP(fK~hHRu#G}y^WHVkQ0?C;AXQPxWQ!#ac(5^4CBnxNl)B$ zB-BBIg@)W%LV7_vXBnk{k@`63n!Boq-J`Tp+;!YF6~(J9g{3&-%MG~l6Oe#=l4WwhDaV&~4UG8XirX1_6Pyd}~T+EaH_$C~;O zZc16oSTYjg8D*uVV6gMfxR8aiwM$_%4y>qeXR&`>bv^_7C_a$l@!^z(q2GK*55s+c z?<-5b)t(1)Ex`U3a?`}VIipY9?A%4uE!wz4tmC}IEpvRfd{X2=)Hd*-w92<7_ygY3 z9BM;%HdKYAg|yYP_7d{%!@g}esl=`p@l}%TuUPWO169I}9$|?s*_wX&8L=pg0#KDt zwYarz7F3{iUsY890PPlYpssFxp>p|u;hfamI9JMAlfX?MYPLFt?K8D9UTwWf`zXRt zg{Ej~*Rd^>SeQ^FCbp^loIVK1_IkCryLLwJIVnJyVS7^N4t^O!Gem{3n2Ys=u=xlMHqp~*+Vim9Cd{5vbd z==exb3fSiq(kg~YNe*GFw)5tf`!vS3M=`>~es|LLQ|AUbSmKg7Z{kli7o8`294q1V zfyW_g1j16ITxVrX{n5xO4Jis*loF(bq>^xz3e|bmbFVMYxj5p>vL=@j;=8LV>d)`4 z_n+D|;!`}AdnkEf^G zmW!?=s39ZIWT=uh01T0u*UqL;X>m}cU?Ari-9(iC04&#V9xeMA^rsB{oIE+_>y`dJ z>Iqg&QNgPZ5Ve;JbqQwe1;?(@pr%7siA*pZD{0veC1`w{bO1jIDq$WC9Yju;3)me2 zvDo`*uacB+NTj8xWgN#x5HD--8hD%O=CnC<(eUjqE;)8O*2y8@(!zoj<}x<@DGfFR zIMI;aRM8|Pg$?oF10BCQhc#ZSyoOuxW+)+UrB8H{oQ&=X^r>$|>IP)OL}wP2w4{YH zqIMbb{r>>Qt8>954C@7r)xwsto~C0Bh_XkTm{C{ZI++MR=1N8@Hs4`x>N=uMLJ1iO zbzLeucKkHwzgZD2l{nb)%1EfrJlR$`ohm9yLa=whRV2$xA7J*Ai9X^`B^P1hov!Hn zqeO%_m4V$zeJ4MbLH*R8<$~(b*>5NF>QC#_SwmM9BPC}bWP(j6yQ~IC>&87zc-GIv zFI@Uv!s^ z_ot@(BMQjIalLxxI@fbT@shNht$AFDI)%(;Qr3ImC#(5a*SlZA>IKqqzuk}asanF2 z;{j4xY?O`4+XRE?Da{7u0wl)5+K#T3f)KWlw48YmMn76^9@6ZkspnAQ-1*c9;JK*< zGZ5mCJD+z156=|Tx*K~aQqNC`jD)E~e=6BabF};zcI{VTg9aVm17XM5b~=k3Qlx=BqVWtwlXRhDff@;=bNruLV%o0TS_M&e_zU! zr=rNr;XzhnhG}}UvU$ERpg&q{Tn|EmyA-Q`>+`2ugR7-Se1LZC>-_1Rd{;^6O1>p4 z1NEgwrpw42Ly1n?L!s6Q$lPOX>mKy3mQRr>+}ACIpAH&Sd#luTr0qcH>A*SpSCKaI zBx;;8T`|_Ik_T-5wf4vOiL5m!sGOa%pGxG8=iUT^lbi~WQ8(82Qf-VVFus)h9Y7Tm zfG|JnR&Ris<#tUm%qE<+MGL&^9ve9dJ=i*!#?cPkU7K*q!n{tGn@B=JQbBbs1$2*z zHI=@&c19GPl><@ME%BXBRGhWqmddhvl@O3I+p~W$KF*#^t`-ePtTk^qTsGp55wzNV(zDrk zX{LqKMp&Rl>vX`9;#B8`hg4Duol?PCoIV4({c zW9#TtsS&L$fP^yI)P$$rA8X+XP&t1meW-$^mGhQSgKLJ3jrO+3LQed3Po||bG{Muj zYvMQfiMSU4X?>Qsc;j<3c#(d$A!%|hmU&uI84SG{X-qd9OQ~CK9Hl|!z6eMO$k-pm zVmeW~-L4nwwbJ`{lBt(l)y4a@&SKD(*DgetRP)Z1qy&PctxCc`13LgII=6~SaZ5`b zGj?l0^a~lQoYd6GP=668%YgD4B8n)d3A!kviV%t@qJ$!fD4`2v{0DX}q~PwGN>rz$ z*rZLc&dNek+S4ggnn(b7GcG>?S(Y zg7RGMo`B(2K?L-Ho$E^+r0Vor^(FU4OL-`dsUaqPxhql0l@q9~4UXAcD{*T1MIWBU z+=}c*;M}38q1fdvq@!gdf(TIgf(2ncB4hBblFY{r!`+;BhiXTy$CBInKK5cg9)_kf z_ly}2Fk7dstnW43x7vft9;V?=z2K$d$E)URP7`YDPrT{*(p*cips8*&pn&RjP;r%q z5~Xj_v$@Sd9N+OGXAigmYSOEO{0Ht9^s>vo8TWZ<=`6LiP>KPYnzYS2>(lYK+)gogtnQXL{Ql%0|4PhBQlG1)cquoQysN#;8vGD%@ zh{kyCk~@4UJNb&Dil2 z{$_$(ZGu9)A_*ObbDZFR04hV}Ba+TweW1K+wQ$#lI(}{0=?^tB{{VS?rv{(WHuX4C zW>0*4DF+S)+sIRe3+cj8kY96!nlgHCcb6tKe#k>HkB(5VuZ4LCDkxXM(v>OG(2|As#??CV_n~-c#LZ!3 zjK+uI2QJ(Wzg@Uv1V?e3&Hnb(1;TFp`oEA-_C}r zc3dcOEIbT#sIZiLCS6+HQ?Vf&fBajlt)dTbz4Mb=6%{lT>}@%ErnFC3fu4*1p1KB2dm8vg*9ZF70!!AjXHxi@N+b&X@O+uTyp61Jai z9Jve=gp^*;a*(ViqmM6Ie)ltnnwR^!B0ccEwc;U1W8YWbbI3<~vsP)miE@13`v?p*?H70T#cIKC7S?AN9l6E+9&`rfi9l zKGIw-8big`!%awikfp1r{70;kHr-jpY(tYY2Y9c;xcDTd3yQ{mC3Qkd2*yTp)r@)O zwCi_G!u5HTsh{y*E?rz&LCirjaz9wYkOn;u+rtABjGL9bxg zJTh{Xhf8TGKcUF3+eq0arl%SV%^u+^O<3kSqM^f52_EZnf7;m9^QCbolkOHgnM_-F zccCvg2qxP8Y7N=ats)Uir7mDO0m#^=cB-F z4I_#?%W$7VL}_oke%7|@S{Z2`D&6Xm+KPHWImiTK=U#&T+x{gdmYz-YCkXWQ)I+@K zjuzRtOBIL`J=NQE*4nnrygJ&E*-o_8sHlu!yq{2N$I+PS*+o$`NwY%@&4DGYW1K*~ z#Jofa7B(boN{YrGE9;Cs)r_IVjZ&KfxEg(vkd}#zAB|T*2MI+FY+L|{j5$X;$Iv#BG zA!*yI=~>9i_{>jN=Luk(R7b=0Wo7jJ{kcu1G=&4yFbO}3xHUeTZeuEWl;q>66x0u= zbpwn#n6gw`bq5Jjjx&zcV6^t2YGYz7l>(wLl23Yto(I#(ovPJKRTXSG9-%oFnbFDV z3c%ZZgY%};$dmfA5J#>_-mP4V1bG=!QV3T601o-j%8(@K7Su^f5J=w`#Vs9UMY9c4 zd9b%T;c~9AAj?{k6rAVK6I1Smv#cSv936nj$A8MR;%P?GtoUfho@x03hHde}M@mQ- z_(lySQ&c2wR)oC`3!!*)g(*mN5hEx!fUINC)OhTb+~ z&JmdiaHOoMVF^x0%~f`_9ppo@$mmcVY>*N@hN#4=kJx&yE&1mBXCTi+#+xJ#wY0FX zPJUxQkgJXmbHp<$7fIiiK)|-?&vzhv5#=+Lo?ms9r;2*NUU5&0nn}G$tF)!!G#0Gd z8B32H(H)r$q&oVS;;lqDlz4q1KN$*9(WRgzPcjlP6#41%z~5@U{K#`Ds<`K&blSBN z;91_$d-UTo4+HnXo|> z1Z(8U7W-Y-Pu?`-iP3HiTAzw%Tc3{FlO@D0wv<++r7pOYA+;$gP$@|UAknrzwx>F` z3c6fbM^Xk=)!)CT@A`KNcN+_Khp&XK#+!Zvo*Gm4XDV6{LU-7JRCeFBL_Z|0bvZhb z^Hx{{)b5V0qTmtj`nQ^&d4T2y^J}>~r1ZY7kt)Guwju?O?E7WD+Vc^vQEl>_Ov!9E z9g#i9BeJKL*WtEfqoF82cFwo>rFmcXa@`E1vi0WRxel_ml{}WC1mv&Rt;aKyx$wI(hz80RO9C;}3 zTfEZ}qUsAe9fu(@8Gb8w2oIo;i7dL1q^M`fK}jPx?^-0SpK_zGp1bI1@Fu<%8>iG4!Y75 z??E28-l6NfaQh|X{7t@+I)Ls7$o{@{DR3{1%i$cvm!e0L8BZa{n~=|o))G$1J=2`| ze5)r7H7prEC8u0cO_p2aSEGXZGhXTI{k{3t3$^A8PNi-{@YbeOHrYuj>HU2w)ALQu zKAeTZX_h-T58~RcknQV_B66ZfDT)w|l@g>QAx8uZ`KZ;J<-6O7%I^mBTT!*&FSZ-} zs8LFtob<#?l^~>S65NK06QA^>Z1+BTFZP@JS)uc(e4A_0JU7z3DA27qrlCNvM`|RO z8!IaNp~sqN)czfE>!z=YRB0E;JPI_dQW=o%Nobf^= z%$)0rb*M>FTSr0`kU-}vI#?y;z!Du zO7NhP=}t;bbt(4M`+U7sP+M>Ku1$*-FBB;b#ogVV1TF5gPznSB1b250?p6qpV#OVb zyHniV-R-yefAgK}*|YcQI?PPgdfw-~@9X;EPCDjBC#pV~g_2r!QoqV@q0!ULG|OeK z&z^cjksBk@qw%eVdWV1UlsoBzI}Av;%~A|At98p4#OSH8z4^Bn(P}nB#2~(wu`{II z|8*w2JgC&ZM6j13P3@V#+7Ixo9_Ku+x^!&q z38y~da$n%ljb1c7BD!AXZ1Q#8ACQqaBf z7|jGuf}b`SMB87S|L^3Hna^x0+i7(<`V3Xdvy`L9jW<=JQe_|#H(66xs^zQF9un$4LcTMAHmIOH_Jb^8VgMah*S!L{9q0FVJl4C!TpvnDUn=dms^CKTJ8pqhGNAtux+^f%=6J}ZKjji>uHa1> zvYa}sW?SoBUN}k+IA7HjbMJ@*oHuLd{_;CAbi7@^h&}3)upZ~WVki1panT6zu?f-H zOY_mti)5Y50NH%df0p{R(irXkX&=g8F4wCM!aP81VqubyR=9*+D3Q#`u66%>v_I5j zMc+dE(SKpQsygGv_6BXW>BNRh@3-lznA1fvyi6)G25}&$)u$tnZDI zL2)6#M~Ys*MYw8i?E$t?qD?&3@M_gRgUAQxeK8Gs-Xhzt6Z_)UO0N4Vdwzf4xNZ?` zfvrmpiSdS&_=4j-1dZ9&J>(d0ULp*PuPOD3ki$Rja(4*{qzXN+!siK^Yc!}^i@oDA zqT3Lq5Tyn{!fWhC99H?GT_2sWu~&(Fz@wyyvYWmzeMn2b*d@ZT^N{Ri_{rKXb^ zY^3H{i47aIT*v6HgP-sN$|YEb&eFS~QB+gByT(rg$R(+nY{Jsj3H)pJLrK4!hZS0y z{NJu|kS*t?`I23t)5}xWp_^en>L1V_&7j`~6(Tm8JJ75I8BNp+coUk_0}@VAZ<3q?>k9AtMwo2l@z9?K(E2bh>PxU4XwvdftnrR;%2{; zPBN7BQJnFaSZsHC7|g3iS$=9MBrg>O56keof`@Z&bbhYMCU;H|c>obPTUHG0+=++GS_xvv9HtqBl_Q|9C=>lG8Z+*@+KXmCbmw z%z}>iaf>&T`zTddT~d{+P64viME1Q};PPuP^B1~KIc9@5B8lh}xu(>L(9!aS4Fk!} zju0)`^92AeN2FAugJ6hifrHHlNXc*`CNe`!!?)wEWKWeJ zW@NYzV6x8BQAk<4ft{E-3Rp+P&VOOmT919AwUuyq`8Qac|2dv4VbkHbV20<3>9T+4 z*?PK(;SXh_M`tKn#@ykpulf@ifmpC1pvEcZT z>fTh8N;cy>OZVUn?QIcz6LpYdk)hSWRg?VVuXSBIE5P708va7`tl}6zBr$8Zv@{INgMO_ji?c4u~ugsxKnc__@a9tg3GI3Lo- z&SwD(5qbtl&m_ZGfB@;LDI=2cba67F;+ZzSFGrB3q3F~^n{*o^f_{xh$Ki22b;9Tb zZ|+)(psDr+5GSUYT~T!`_bs5ufogsYy5&^td)PH%kA{Cat*tmK%vCkD9u?hiAIHh= zRflm)pXoUHt1+UlrF@e;x6a{qiEtW*_k)weAXRf2e@n-m|9>(H5m-6z8NH~zXKysc@=(24&y_}c$u3f{0SQqAy|*FRP6Q9UiPUQ=HK z4b_?@*4gyO-ibd3MB4{+bhn9>A`Y{SItW(UMJF?Txv;__dd+oasN5Io!Jnb*`W-o$NAAu!?W?59okTbkxoH(FcnGP{4sy1}ns`#h2Dd zX+GY!A@5KT>`8~FHIIO$m5P8fH2hV8C~q6nS1RvV)bD9aES?r!JM7L;<(mg=ZY(F4 z>ldlwdvrVQmEuRghaxnFlA9Qq2bsUp<{L4HxHuh`YNUimn9u?2FBFA3r4@xfi;e13 z8R>u)miI(7o3;fJ%I_(#2=K9-LdM_q>f|VJW(0gBX^?XzQ^eH@`Ay3QPf4AS zLemEj1OB3lYqMSnjr3If5Cn9t5@m`id5KC0h=eU-mD{*#&T$}=(-Poc7jniXATThr zsmEx-_9UxifwXDzj;(xTl=uk}ru#ZN(3&I5Z`G_RhO7Cq3W(o_c~MWTJ(v!V>T3hv zsVZmyt|*x+<;Wn|&4^~sFCL}d|9D3JL#Un!G+=uqt2Kn)e%lv%49gw=`5IaM8$aT< z+yg^@`Aa$)`1Xsw?OjyN7%&s)MHfu7`4y=&Uu2IO^+_q?*Esy)a;pm*WdWSNGbBt& zDoP=kJtpVwkHr~f7p{#z%r$8D?QCO?@P0XDr(G`KHgjAUR9Vt(-Ln45S^4Q>Z^G9D zYG$yi^uCxF^>~DZ-eH&LhL@~+jpG&(iF5E8wToRbLA!vq6oRc@F#~toma`MI0ZyjxDVX zcR`X)>YWl0Wi7qpnWA$P2i7Eb>wIN-f;PL+9)%L!X393Xhg2Ov3S8W74<*(^Hg=+9 z`x6{9Qw&9*4KOBuyPL)y(Q8z+_)F2kL!68fq49cA5TBHNCs=XhJMkj(A3|rxEvU@s zvvTs^f1-Yyd@XMR#n9d66c@~>(Mb!MTjMAg<@fH`EG3!^TJ+rRLaVa)h8PhkR~RqOuZn+JE~IhVyd3FS0pW*_ zYf(t=)lKZC=4~HM;b8$OR#HO&6$ne=+f;_{@>Yyo-Ece~ixr%X1zJB-XW8(YAnu2y zI_+H8mkud5f-K-}y0*A38@>9^1uo2)c}-ob$O^bK7GV`(@TYRqKexCG+=Mcyn_74RUl}et>&p zN1|Qf@%?$h1{D!&+Fn8<;A|GAh=b$u3bwDcP0UN^ul?cEfvnfXOa`jL?KyeV{~>&} z-k)nkcPT=&VeF2+WmG4PfAN^1ovyil9(PS4G)EQIPt0Cg`v&4?($^Zc-M;;W=CFY1 z-)dpmpYBpMfV=x%BQdy90O)^(zu|K~M~D>s9orlOu?`(NI_ke1I<@)ei(G8x^8p@} zYJw^@f{K5=hkTroFbd-fZB4!vk8C`2(& zQj)f{gojubAK>vH^J@S4 zu(}lDL>0QkSB-vSzOw~eOM>a>j2Ue4Uu-t9ws`}+xvxN!cszmpr^vqaSoJ5gO~l)D zJGrqe5g(Yv-52vNp}v=glU_@|>!udXWwHWG3S9!A@j)@IN7&=A%Dc=O^%XYcdfCRxX4xGb3r-dg(9UGAmueW}U7+S~>4VEZgeYOTe$ zhW`$|ai3FZyi?1dQCN#=1-4do)Sns+GLIzq|MDzE3Lh?y&IV-3EzcwWi zx`^`OBn$m{vP217fVioDE}^# z1rH9SwVV1B@8#Iq>{xtc3KP`4EqOca|G?#Fi_yjaUkWi6k%vNUD7>h7b-K)d3lrjK z#6|z|I%&9qlMF-Nr3~S}v&H;&+skwICnX(S4?vCz`y(%oJ5RY{%8xqR6y3LsO87oN zP{a*Cs~k_k`7lEUzX{wdy^Ff(2N0G5W`{7zQgXz^J^phor5O=k#@?UBQ3ws^p^(C& zV^3zA)hMeZm;GM5K?_ZskwgZL+LbF6NY9fCo=TiDXUFPo))>CQw5;B$C7O|R|Hs(% z|2+VBlV;!g;n%YCz{UCV%~sCc#BY_AeQ;ueF6j$^<8`XW6$jv^dhVTOFP==&EO;v3 z`mxk$?icZ2ng6lCDa^B0t<%)x%Wmm`N(z|HxNuc$`1&QwJglK&H)QF z*S~}Kbz3_)n{#0Nn@LhH<)eBh`kVrop(#Wp(w9?x2L@V>2@^Z*d2inHA5SDS8WxDp8W-q?$1S6)+~2KR0PaOBTp4KQz0zodKp6lSUH3Te zdW*oUEsaDVc$s|zmDAg7w(CG!ta$uVhPLW)wOm+#sYV(N{S7=4&?~7SKNl-I7%ZpCVHg zl}7QL!M-1*G5Azm1{=J4AErdC{v#_@d(G*JcXGyaaSKk%lmzE2|8bq4GOiY$bvx#z zrIb#)N5lJV8J?nq%s6&LjQ!W)IWV)9Ffet*9_oWndBCEs_RHd$ndTr=39~l2ikqTWMKI~cYsxe5DR1##!;*KCw0OZ($z+GC z_#uz#ScDU_et=Xs$>2{QewKT1&OCo*sIF26P7`ljKDB&nhwCo;e+ZDKrFUCJe- zq{$hJvwX9OPK_M%C(VXrmfnYt5Wv~m+^g$sJ!QMpx{6>c>~p<&zSJ97e;15#ZdN9p zIIseek$@1{*#0wY9KZBZV?IH!Q*Z4z8&rQHi9ce|(WFE)8Os~ zC`EluTZkLg+?_AhdQq|#c(e>54|_8 zHe60xIyIx!riIl{<&jvl=3?~NT3Dl_hi3?fDIesZd~KLH=ud4+j!Y>^hjJ&!3PsGW zu9^^D8R@We3+MqgesKS+@;}6D{iWgMQansKGHtG{XV4@Mxy=OVQF;cy#Zu>{Cjt}~ zgH&UX%PQFyjUX#LUku|6moy_aXSd=1sK1&by-y`&q%Ays2Uw#@?XfN&w!q=fD->P( zdIhW&Sb97L3CpL^9c>CTH5x6JsIW=Sh52~~l_!vgUoQT23055KE9lk5w97B$96Zk! zO@&cF_iFrGyDqzjMcXahZPz{tzMXSYO|qNDw1b}3aHK&`tQtF0YeN3`5ASeyM(*kz zOIA;qfK1jj#g%Jy-Sgjz?p2D&ccbEulFB_gZGz+vTqnXCqjvKrX^P?YOFKAi$*2s1 z>YC9mbS$*a<)#$fE9RB%H^Xb3t-tq+4RU);P)ux>*Bv(_@SX)|R#^qyE5s0xo)yFB z{zGt!V|e$y)9ri)-RPiV&(l)syg0^)r`GtSUZ>1cAd18#GvrLNHMe@XLD84fWjE8J zJw!f}Knc=-C?%3VksrcHt|9FGiTLk&&rj9)c<}b6Objg333f*t!P@+5_{V5xD0)Z{#9IaZi1Q7w2-m)6W7YgP z?RrjQCNzI2iWP2vf-_|h@p*R0?d=79bxA{(C&vH{JQaJ>sma848{KKfouKyMk#*g4E;qv1 z==8rbP=6`#n!@Ei{WOEY^=ayjn-jM`Ju#*%s0MKPMv0jOQy`w70i*4-HaQsyq0^a5 zXhufcpGJso(okG`_0j%bW2j-h}|+mtSpGP5uPcA4o~ ztF=z$AB6Z=6qlQmjmja(x1>mWQ>ww&m=Eag%fuK!e?*@U&g61wIFf}gAms;z-TCe556D(H7ZOzIh1b4_{t=;=`nfO zdg=27ZRuz^H>pOTf;#a@8+REeq(t3cz}^K%T9sLY1-rglVM7&gS!9xK)#8_O(21tg ze~_q3OnsPzrd$|O4*yQ}3WysCHk+785G|C-g8FT{1p2+W=z(UPw4VOh3x5JM;%*u^ zhj)wsEV~oQpK696Y;1B=P#XEbbz*ho8*`)*ZOwAGf-)~o1J?moTOTx9FJ^jvJqSRF ze|nCwqis?SUu!Dzf6B_Z|C@FE|9=otJ8XO9w|*PiPW|_4e14;f+FHz5t$GQvMrn$R zu{4xJ;@K6!Vu4)%um212J4EYzx$l+DYEyZ#@xRz8g~=!%5fe^vg&?)o7h^t0KwBv* zVfrs31X$9^v;nzD)Pm#@h!48spQlv_eB`Jm(8%rIJKwT+c4jOtTG^2I(SO3TJDT|pT-ijp7Ku<%8AJ}WA<$P?-I$VjwEXWJkjPA-XF+0}1@n<-N<->`_ z*R)I20X|WD<(TB^&-ubwgPX;>H?oG~STy}$;7?7@So{d(gybD)gi1LO74hYM2(o_n&MvFc%9#91P zPWLOGm_3wURIkS?rgOgmRRcc(|5u;pl26}!r9-FUP+z-RNN~$ISg@q1I){R_w?ojbUmi_^a9f{rw;w5SVVqGj?rmb`Akmg$xOf&i{0TP$( zO8q+bn&`R!Z_6dgW(%EYCkKgfQ0sLyZ?=7RLA#k3-8+XyoO~W zcnjdM#Hu$>=Ggt2#=Mu)_vy5oCZv1J`aAI<0eon`q3i-mcAlu>+`LysO6rkR%0N;; zs{8}#3rogWw`&^34UOB(f&8Bco%;!wi@$ zbNx(FhxLh^rn#m%BY8BY%@VKX7ckx>ezOE#GN`MeQQ5a~C7}jPbtiE8IoG#>EUXSJ z;QLL3s!{zO;Sh%K}*EWdH~v-0z);vPttPCdjoKGgb9o>T=*&Jvtj&Xb$?6u z`v5#M@>Uv@7RtY7r8_qb=~JPkeXq-&5l&H$4$QO4Wy>Dc{zq>+DiOK0TO7+^NY^uy zagtfEp%hlKC(~5d2rQ)6EP*H&=ImJ0;-nE@m1F`z^ce==v$miru+2Rr%iNyI4}t=F zWnbMo!czKuV;kIpRob>`mj_}AU^?#}18AxUetZuABiGElTPb@;)b82>d0S_?mNrnU zvM*nzWd&oV>T5)dzpfehN5rskHSVi)&_U8Kc_Ylp^VoeV%0A6D&d~>H7^2Gr!O>}` z8Fn7G@Q0fA=kmnPzD_Cqa8AhO+Q}_q@(LxIq()?jh{)q1~^=W{LeE#U;vq6GJ~*Y9aXgT%O*wS&U8e~ z(pfc_Fo)maNY`5bFvev%6%FX9-F!k^m{eXJ0om?MCpHFXs+QLU&iIFTc$qpcxeNXN3L?U+|eow-jrWEwy%vammv zQYJVGz3bE}WpM$3&w>Nxh`;VENYxW_q#H| zUDFx{>|{yp+4WzVl`jyrtcZm(9^9t+>%sg-F`WxlaB8ci~0mKG|92S@h*N+ z1mwZn_N(vRtF8|z?M`32hG`Z}{`I{5mTFZ)(cyQ3jx>K#v?74g8mUIoc+=vXlqBYK z`a&NyN_bS6@p(x3R}4Ne#$k{HcVxmJmyAS&x>DH6N)%R3?wP z1^2uw(npCi9>{47&U&HkrvpZ4c9w#nP>yc|fkC}Ov&EhDMld*I4)n9XjfW47k)f1^ffzOiOO`pG zaiyUdm{HI%{26Z{dYCfk@vg1QLe0Ir9~H_w)x@s~=r4KD%u!P_xLEReu|_fT43L06 z!>>Rsw39B@h;IRkUpG>S+DPS=6dCuXy`*rk-oi%0Fe?%keTT$A4e8CEYJG4%Ke9v`NR!0$TpGrbU#H^7fxDGM*iA zM(WLd8p-w%zfGoHy_3zC%QpB+ejwWkr-v?9)uYFD*GXv)T#YHZ%&i(^dFbUEKz(p9 zoL3|z{bJtrFTW#KpKPdL0i|3LSbI@`r2a#=jO_OGQKjmS>YGAod6l>@G?fBj-cx9{ zU}Tu%+ zgciclfJ;e1xqS&a34S!Dt>UQ^E5C9LBLNq*g2_w@-L%iGV~!}Rb;dRd3(lL;>0T$s zmR1N%`Svx+P0Q?`vebeoSCgh4*N{!oy+Ws-6oe>(D3gH(UMjW2qrb>3I@qNH@eUI= z2YeI|X}9jM8Y*na&;%^#jY2U#h9c>_2WnNt`{PDqzjTDy3P?(=-!Wy0)?DF?(8UNh z=p6Fr#{ac@FAS6S3b*SQr(B#12~6&<>31(=`bGdWw6Xq-<}fw#qfX-n*Rb^*!AYXR zu;`R?s{0oHN0b)y!SDww!J4a zbN}!t28DUb-^As!bL0E>{`Xs|20L;#dJRs7)|9K_rWUQx2ECg=x#HDMAdG2SudYvW?vKt+h19MnFg z*?Bc#6YV)>ZfK8}RycuT>e=kyB^`>4Hi){cBPfbWP3>omP8MPUbfYFJ7soYPv;ou2 zPI~g~eX)xa8nRH0EjY94`_`*V0@q4=cI`)C>l1#>CuJ7H;HbGOFu2n!?7U zo!V<}*|TVz+midETqGZT;)+6sF7whf<$jCd;eRv-bRJ(ErjX%C@S7_;Rs6vwnu6ttPN?`FH!9f96d?J?z zoxbEpEQdF!Bz0orDh`Lk6Iak<^|n2YBUH~MBqaxZ8AgQ_IQx*#?9`hCPx{}#$%Zj) z1}ml2j_GB-4GC6=J9K7g^Jl5N10>bH`S%H$DmC?r-0vNiL6;PbU*}=PTau9TsgF%q z1Wd3SByGN$8~kQlj0gmqzYvDM);+k1BO;s{{YS5h>PA4Yb|8_BCPaC)_+p zHwLTQQc#LP*TiM}-pWV?U{Nz?;Qlp*UdZA{>xR? z##niL44CdT-7!RT!=Jdzfh4M&|M(fm-f5)anf?G;Pux4V#!t>%KzO{EL5N}0ylgZNJVjC&sTIQHdJTQ&`QYDkU}Dh3jK?{ zD8LdMW^CNGN`U4mXYgQ1M{3ZA=%v>fUzFOoY~@_v;&idnZm7I}8cI%aIovyIJgz|~ z$+R51^+2LB4G(%*%PcPJmqAmCv{jIJ{4RUUvqIy5lP2DTShH5&JzwLznmRuFIe-Z zOCU~c-!Qo6x_vS6FlYUB>*3pXJu}h97|!CEh}-dI>-ArRTjmanZIGBa*q7%zOme$8 zyVMsiSOK@jkTOZ%DcMtN14X2BZKq08|F3-g@WZYp;{OmZpWDQ&&we*bfaZihtPqgH zh9el3bEv6=F1EVWCFVSXj+-O;$#E?NmCC(8n7FEwdcJ_>9PTuVkCp1`dbfe$_!BxC z*!&uWB`;h`8pRs-;_5LldRtr|88aCXE6ICZ3xWH zQjBhWUU+iFXXkBKn0|d}hxH;!^$?P!Iy*2sG8+D1rBK};0(O<|JfIc_om$UP3@v&B zP-%9QboR@Ci>T63Q(K|;=WOv7spI;`2Si%1jzJ~`BeTnYnh}xL3!5|15+LyRvJa;w zA?54O`x;VNLyGF_!nz zo-MZoM{ZQ?p^t^w@$K>t<72T&k2>ZheGU?5dco_TA`b*@!!kAp0aWDe&ihr3o)bJx zmqk@VLVZkgMT^WXv_We$Hx;z^0HwOWFfmhFE?cZUZ1KWBxw&77-(v7i9`T%w=Eo0{ zW3u)u6|LYl4BH93GN4?QtuQPx8gZjFDIgvi;(ZtentM5X0@dg3FhWDhu-C%dLx*sXOlf3DPc$% zYy*N4Q2UZOC#indhnN7CoVIxk6aO^gFD`t38rXS5W~NkAE-JfL6s2Z@_m5t5nx2F` zcnLnf!C_w{pA*%>XX%Vt*+#5j1uH7oXMh=NtO(WIS47CHBzw-B8)=-$;sh(9#nZ77TtYY62}9d z1tx`g045%xTjMbpA!OoOZi!~mmtRa>dhR0lk3>;s(36h;)fPR=(n*DOSC*lqyI9Ts zhd|-JQrh^`W3z{U)3xx^qVq%jK{nqzae^S}g>l0%hB_Op9ThO!f!`=13-gwa#uEBFLjFIV06DQ0~KNBBhzH)Sw8H((R z(D)aIFOmx_@A49A%M|T(Qt70yY8>v$M9Rz#3dkUCGZbG=Vp(;`8nF8%Gdm2D#y83M zSLX&$>6d>?Y}PNKLuP0Xrj_KLq;Cl73M+e|P|0grkGZnDYPA3ZiBt+n57`ZsE9Hgq zR6FYPTV2Y=02Jppa@H<(!7_dQ)q%w3J$my3VJ=Y_ol0RLPFPX5nw;_@T8JbPZju`w z+S{Gq2NFLn)WEV1+!EOD*rMDml&!yZqJ3e_N2BkJQ=V^@$0Lu9TPZcNzE5bA-*$xo zq4Em|#Z(Vw)pjJsn)2Bc=;alF=!B#WCd^>o0l`5Anucs6dyoKSndeik-OswQgvokx zrk@=Uk{<`Ig5|tZpLmlZrqF&+|9Uz@HTL-%SZoUE*U{Qs)~IWOY?X|`kMwZibo zl(@fA|KW*`ZO?iDM~-j7N)pB}M+DjE=40>;#AQfhD)@viHg>uP^_lM6e23%FQfHR6 zYqhCWa{TwHD6$@1O9I6cjStPpa-MXC?M)5DHsn(G7?{b~Vqa*3l3nMw7^;z5VqF`{ z6jN~&t2~pgi9Xl$b(m=i4ObL5gQ zee22%@29}uy)X$UDxgWh*TFC}G@!J!Bm%kt2`FV*(J`RzX0FlK@0AbU!?^8mm^o|e zWhFZH8o7K#y3LqU;y~h(>t^=ln}U+fp_#C}nlvi(P$M}`JHd^1W^YheNYr%OGU`z` zj*Kqzz001mc&(UOD|c~O!@U}vV!VCE$3l_y<`DdZ;c&er4ARIsY4&zJ(`h2b8ojKT zrF3?KEW=3EEnD*|@`IHEj^AnBv;7g8BkxyrJM{23{*0>-vo^X5bQ~U(mNKz0Bhn)D zZP+-F^>w-(@BD|bq~N+|@H1rdHoQt$YJmyyG-?{JG)!_Tg>P&GoXbHis_f(BMou5Eir z|3ffUT#E8LmFum4rMFvhXxy%j_QN5k>^;MMlZ>SuJXc<9pJlA7eG=^cy9CbIE4n%T zHFalW{7RFel#`ouCBWG5wu!86Jgo;vC#>sB0meLAbfr0L)v6O72HRVc`*S`lS{#aN zxMxDNyT%>se|mXyW-@`k){g6JQ!5>vlM4Y5>eUP!ya=DbFFDI{n{(I|Sspu)FHTd> zU#H5mWgPz)oMJ?Q{@Fw#?)AjvVyTvKXR%_p79$G1uZ=s7yZt9WL(-w{NP0pMV%6c0 z8U-dt#=9!h(+U@MJa$6Xc`D#wyykpEmoow<)ay-ul;G7-q5Nw^A&C5bJ~h?UXDzpA zY(o^Y1+Mow`Q|GUkWUr98h0H=)(wd$rVjm3Mr&?IF`KPV-z*eM)I`Web;(k8GOb$P zWlyN>u1m;m`kiJY0Y!C-^x=owz$kZSQz%C~CEHU+>q}3{hXY1Ekr%1K&MQh8!|~gO zC!y7C(m3i>N&)BQbJXxb?W@qcCUQ6YrT357zW=^hNm}px!Czc*p}mh5A4*CpEvHcx zE(P|s^cc^s#$jus_WRT)CVUvY_=vLSdvJyHd_+-Nl!{&ILZCNe>k-rtzTF;J2oJ;i z1@=K}d@CnDhky0`rCAS_OwBZa_Jp7=3Eew7s_lci_iY9}N$vUfdI~rGVhi-)?Cd?x z(82SgV3DGU(`Q@>@0-1LL_SKWttmZoWIO^lMHRcGr_j!Vf}RhUTtcdGBH%zrQgw3) zjO3hM7H#=CBZQ4>p=@?zXSON1)Lt6)w2GvZ1YarDQcBHz7R}~_>C=$&Pv^VQ{mkwaHO1OB5<_zHChmG33 zGsRzIolG2CV`r{&h{M%PoK|NY$HxrRM#VP~->63G;M!Cpb**7Ep27y5Si9xR(Rr@s z;~e|)0{1r|1EROOzROKkblgx?Cu&uNYzb1XDYNP}#njh^_R{s7?YVapE!#hvun*BL zNi!bwPOf|1S8YmJi8QmG>v>b|KcI>|A81eeSC$LdVMA5XPI3*jFfutX{Qp7R(@n<( zmu3r%x&2dyixH^FEos0Z@?7{j>wwGUnb_e?+5@DXevR9f1u+h*;<|yN! z?bIpId%HB4>rE3enu=Z9d%#En5Dw6NF{YQXaU`=5%TKk_C8A(Lg;8Ky6qY=cc|fsf zch92la=r_tZYdDi+ZK^FHyA5xSIjRa71^c?012ODkzDXR&84GoqxbwiWYI`r17GHg9{P(5fD(Aw9x>|MwW@BoDm?;O_LBhJ9fffOcn7`(Q{1COAl;A|VETD4#d5 z;9tydADY_2Lya7o`co?yhL=ngwEIC_BHNn2{^A#him5Y2bc?J**}&AFq|4^68Cn7I z`X96za2}4mSvK@dgUVhu+BqT&51w`-&1=#|=Eko745; zRQ+3hxicyG5OaB}fyLEMJ~*27SB76l=%iQ)8q(0SRyaE9Hp(82DcJ_3w@tTa={3EE zjcAx6+?ro8!;=Ng$Vb7Eqwot+GmMS}-6xEGKx0YM2K1h$q@ee!(b13uiN$$XVAjM? zHK)aqD&77Q1Nt>DZ!uhLg~9Z5PBK{_UP{5@PAjaW5Mgc;DY8biXB50K zgd4bh#AfgG7S<+l`mIsu1=R>=quoH$N8sqhI5?z@#G)?FlK?xk4E!Op?|IZWwuw=t zQRSRpu{s5aEn1L2uBrW+eHmhhX?J~X>G4|&jJit6uO`f&ttf~IANz2FziOklQinD9 z<|{k&m`k3DtwWhWoq54V7!>no0JT1*s!6sLDaB`=GptZ*>)jyYwpd-} z$=_Kt4=i_&7tKSpXipMsjX8hw6hFP4`!p`LxUi=)E045^1mt%{<11U-I;Mv9p4fci z2X@sW7Iif)`r}$LHUu!(1RCAQRf_m6(=!X5-W3O`q07sHe6lPVn%S3y&fn@GZA#>a}UBlou-c1?M&m((~k|bhQA^z6Rb#Z9NR>CXwuG#uLBF;4? zy9~D#&{>3Qwj88MtwYr%BEim)h+er+4SX}?GQC;ei+LYbT1Ek*wVW+YT2h%3&1vG_ z^JXu*LBRiTGf$I^0RaArkkP3WBNFRo;}gWE+}KgM7v0wr3HljKC~kqZ zO`6xR;=fu*CLE(djBt3bOfkwzaC#DtnpUeS$n+amvOvatcMh2j(vn7DWKX?G(Ldsw z7IWRkh(N>5GpVd8dw4vly|*mNtnZ?u+p*P(B&gfWq}LNq;Pken7!)>O0nN9vDNQ*Z z+JN9Cjc3ZZvf*7uE}iLNschJ9B%Jr@^=(>FefjmQiavAENz^6`eOf%({~-XYJw2I8 zTSuTnO5bcDRbQ#>6@|@1`Ad1{rw#w;?TC>`8)K)>5t)!P2)<)S@@^Qc;cmM3U!{f955b<1=qT>N$@lHN{zj|C6cczbiEXHtImKR=+wbS`1AkK)@e9`Zx6 zIG+P7Gu`vr{(V?nrU$bSg2&uG)O z`%JnX(~=$fFOzYI${<~W>zMoj(B1-IKq5kn)~){n|I+T^*4xil9k>Cf z=6**GSTl1w$-a9a8IJ6&FpM^01K8&uGs6FTkQ#IF;eU0BPp8FADE)h7^Q1T032T<T1*>y-W}}0`uwUj-B?na(?R9-{2#)Z2ByG*t`YKahu9992{-bOFVaNw(GQyB z55F~Y(F92?dGl=&jJ%OQ{ps6Ha>A<6MUf;=7KUOwJtpqSq$5gj47E==#$We(i}+`~ zYC-=TR}4-aFx_m?OlX2U$8~Tj-of_99lcwg4?0fA)w0s!r*t-xP`f+SW>bIOG1Uw% z{M6eJ<2Nv{AQl>$Rp<)XRZ&bKHM}dWb)~7_F04K@>$a#RsF3-stBM!DocO1(xRnJF zb0KeIIBNt=wb*e;b?@dx$1gR9{=me9kJgTBrCiue7c@qRQYk7hA)L;xSPe3kELKlb zTTZv%a>T@mbsEJB9=wz7yU>3l&HBUyTFU_bh~!Ax`S6qJTC5oTh*8`aIj5}rl_q#} zCd$*{;Fh|8DLgtH;JSNiun{JWo2?E1A>U@4LC)UzE`sP-#1O77J@t|!se$sZXpEmT zy!GeiwiW@t{HDuGFacCYn!S38#~;P@vb0~s2;@s`Bc|P>V(#ksQ1(_NNiXM9xs}1< z`f}#nr0nW^U<0nDD}>LjxpXDbF(T`sA-;#3aw>w`#UM@f{#Z0o&B<8)p8krhqll;s zB4*_)=)<>*Sp`ZMp2=uaj%QVp@jVV{|O@7{CIoV&kdGH;Sk@8o&jXZ_dutc-5RRJx0f|#b@!@oPr+%l}x^dq{9*_wHoG5e*ox1u!kx=ZEB zqu7gn7RRDuT1l-)jL!{3tk~h_KdK4+IWNf){(xvUi@THMi>|xP51!(Xwa4^D9do`D zSs!R9FJ9g+xW)?>!?#!StoJ2X-{s%?xwH%&DiyXEtVexw@OTyT)LrTUGtTkyQAckX z zRSxplLprM{iGIx9Qjz6}4&t=8mrEXDOItOs^7QNdRURh!z=6$mrPM)Y9-1yK_6H__ zxx)H-V_>NSsYeeV_5%0&iruI3?j5|ha4{(y=vF=YWEZ#CBk_roD{z2$!IqICk(pjV22Rt%{VhPNJU5mepbXxVv>+w01K#ybPI|eL@zSdA4sbU_=W4GXf zwYES|bO1AKQtmmg!)=E|?{mAk{LX_)?x=1yoZoFn87@@WOv zI9A4Mco%}|B!chq9?UTlcyt-TycsnO+nqh-nF9_D^UVP{eo{Gqv` zGPaXy;kUl8(3sMYPd(A?Oje{i1}Q!1&jDZFGTt!<{jd)+C+4w8d=^|f!c>1S23*G) zyd*@S9S1V?%@b41(*oT6*s|myZd-gQjjbgOpV8LrO6~Z)qgVWb5w}cw^#Y3VY7%GA z)2qdLY~}ACj1tQQ`SuzeLwe~F-ppFG56sUk1Q=Dmm-o1vDe(p|YlXleh-61a2?`IA zR(Uga4kZ^PDEAHThLd)$1{A-K(OD_KTe8c@uot1!_3&>4E2Nct1q>})tu0NdzKzWf zcqvRwc+{G0SM7st5pZz*@Xk(V!ycNUdhJ$p{jgnp>nXUusqO_kS89X_WS9mA?syP` zs&&pCZy8*q5-FRY_6W)yP;hNljHPh+Q~nihZ+S+Id*aU+`Qj{dlDFke>8V7`1j)vr z_+D!BK!W&u33?`DB?`57qWUrQamcRizx=h{v;9Nxk!M^U*Xf%fILKvA5#{8D?W>uy z*zcDPk{_vFO8Bs4_okl2hrDn~D2%u#(Lc7DL3X*&#N>^(#-217k%1-c&j>)%# zBlE?*s;!-$75ga_Ny>DB)!JJl&UUm|H|@Bo5O5Z@9eo}8tRd&I+sTcUTVRc!9#vkK zDW2?LzM{bqD!K+#1W&v%b0E3|urW5iPnC3hrMjy);1QRd2Oh~UG@ zUDeVP`pev0vE#nkH0A6c%_u!LjLOgL$Jw}+rH<^XOAa9ENZFhp<6%h%ESl3P4mDD7 zUh7lmLLyaHZX>Q$zbHx5xPg~W5_)ko_u?>HAysQ#-We((0{adi{LinYJbfvnacFZv zllM0&4qnF4Y@0bXxSyg!8BaL_g>2y_ERBCzNcHS7g}&V85V0=TThXbMdmw~s-#f_kUjS5wC=-IQUKqv%KJb6Q|@q2M=sf_oyGgf z4#)pFT`RSA>&|9S&6f7S#+UpLAjyCrTMqN_Tc|=`u1l=3y*17Tg|+jZK#AqaL}mNY zu3kY?rKq2dcECoN_wzyi;Yb|maZ_=P{N)va%Y16=$i?-0FtX2C{?(FSW zG2X1?c9J)|w*~gFQfyw#F{~0}nfbPro+o(RTw^QUMR*taq-OmVTOu^Q`)SH*VbZ>6 z%Fe<;C$+56dU>}O#mr=t%=FWbPSC=6pzQ0XN;j1jkd!}2lJxzWXr)Ag5i*pj(-66P zZ4QrA{PP4%OpKL>;xfN22Lv}P+#jse%Am-jpD097QJm}17OqkTS-C9-hPaZSFY5O# zOueC@gUhCI$A5~V-SDEqeZHS*1VXK@ucRr%4YGedq*EfU=o zOc0NODf&g{=~97&QBcgHWpZ?Gt7|jR)rR5jeOs6DQ#TL#Y7VR7`U(DS;L25;uv@03IK)8SL_@ZN=NkZrEl(DZ zU0O3=oYlI8SAFJ_6I>Kc^lDgu@WPY}?_SW9?^fCVCo1|l5gQB?1_w8Ya|ksI@pgR0 zbi)r(GfDx9NbQ4hbv>YQCf-24ol26F8XP>bCAzhd8fJ#Uy&nI`(J79E>}t?;l4bQ5 z6xI4vc$bD33vRzHhZT3}gBf0u9||cEwqhg&~^xU2d7}%ygAC&B^fO32uY>y8VW6BwFglN(#*q{ z)~=68p>XwN4vNT2<1yg<578RsJwLF?#lC@VOHe_cWrpEOMGmI*r%eaV)|foZM8cAQ z+23;^s75Yy{jA6(m>Fqpc~M^9^lU)kk5aE>reo81M~HXmLv{N1(0pj#uTeOI#i*`F z$hE0mQCYAeMSzL_YXpO)ctrSKqhM#nPIVL92x?o{9n#Zclr>q)ieB>ndlsCX2e+5< zzXws3A#59B6AsKhZR+ZYGbC5$3C4k{A_{+hTOVRysANnegwK$%1Zx! zAA25Sf9etkQq`8oms{{Y&8vQ@>l@l$s?=B2%4>abAQc3e> zL<}Skn1Q0Er>IR&)t#5%Zj~8<|c|oN~yQRPui!O!*1DD3i1$^;7k2FOh zx@No%B4+Q;30egal;cOfR2SQkcU_VX6dWjG{aZ9W1l zqOar~7V5MpojW&zwnSo+XOdlHDGY%$++1TdPV(uJT_JP7&TT#ISJjOVUI3`yJTb#e z$y1Q+lizpC^ut>=m!Yk)e=NUwEBa z5?mov;T&^U<)0p>f2lKfMi6uByKt*La?GvooK#X?iKX-mdaWB9ev@}6=)c{S z)xyu~S*%v1$4FPokJZq6B&AXTL)WVYfRufpa!%3TI$#AQ>D2jEuH%ys9)jb%XIp5- zNdqJzKj0Gdq}tNF;Odj=ZD8SYE8q|b{z!f->3|kIounCNqYvDr(EFT41)3zjZYRoC z_!$1N1po3$_;w9(cBRP+|Lh{ipgQ*HeG`6Hp-lT|m;LBT+%=3uz=0@exv-j^TAO#4 zUd~J2qiMRbCPNM{9>9NT9p4=Bjnp~;0Yfxg+@q&m#N1{^N_9RxcWe>D7*%hw9G{q-)@#DeP$UE&r;?BrAA9{o5ofO1?=MPhq551Y>u5TUZy%GRJW zjc=x9FQW#$#h@MnXuhUyF*w|pAUnctb^>2U-=g_dswvT07=GVN!*ajiPBTA&eP%r7 z%|8?k9bOl;^qDa-_2rUX4pNPcy4`Z3DxOQtF9ypbp{we5QS0oM(^CyeaX-Gen4J7W zSi;#?Z~PT?7UIaPL?Qpg6I!Gen`wq5f#NoGNksibu9?AIN%Ie(R9sXvDZ^nns|3n~ zb6@vVeWeaJn~HDEX7KWj+M}zZoYHE0&r|4}(^JTTL6M0Z5{=+iJ>2G(h!rXAQ1Mzh z_{aZ%gtVd#Gf4u-s;evK6gRNjU1__VGG*xnfRs4CLWOboa7z1X@KNDh4(Tr_@b}c-3a(- zK`gwvcjeabdXfjrJqx#cIn(Q%KdA#zl>`A62godpqTkW4){4#u{@~`e?0YE2g|_vn zuNDJ5V@~<(mjHPSIQ$?3~=Gx)S+9Y%BztD7xJWuag1yn@M-kFP&1ZiPYH*N z2Er-u1jdGhXVVB;0tUtC4Sy)mSqH!p%D+iBG@~Q_7-*UczSofw+r@@4DmF>Q0sCoO zwhhU2+QfDX_1RJe5-~W{7>RF9hcE#c7lH8HMm{9sEl>3ZB03$Zq+~BW92EMagL<@; zh1L}TeXFI$CO)b|Ya!nRo(Kn#syFj*%^J^k)+w^DcUz=Ax*K>V=7i|WD=O>4L=WGs z%Y~;H7@xKUIueH<2|@F-^OH-;WPVQxS~rf6eH8(`bLY0AZ$I>W6|wbC*wN^2)uftk}Fk-Jl+( zJGHf~dT*@>8tAZH6)6=B#a&NQji z<{C}qG$u6h$pSuQsmR(c*PqWbhu!NWyx+J{iiE^Y0Tges{RfvD;p z{DQB=wc@KvV8Pc90k9dU1?LL-FcEmPg%*Is*4&6_;8nVM!q^*I1ti0BE#fCr$gIt`wU; zbFwWLf7Sm(a7yx{dwo^^2&(*BnYu3Qx3r7%TZX8Jh5SD`!~b0XWX=!%e=ej8Pz^9% z3~9Pwfmh*oGw;_+=^0ra6zLdc(qeKc0fU(HwU}eJ9q~v>gjv-!$8J$hAEkUnT8^V5 zI2rmp@ZT$%nS+-dn(@J!uboI{Z?9n){#+=@E9fvMR53 z+~P9P^lfZ6U%6Kn+l$LAH_jereLA_(+f!!z5xWoDqgn4$p>`LY-s1vXR^5Xt1RP5D z55IiSKKmq(O?PbecQsR9!R2|!Lb2_Q6tR#J#9kJC5|zKzbUQY3lepbU#ma`$de;6F zhu?wN3y!(jQ51eL*$3#Y!2wY)y&_(g<_S7$R@$A|%^NIMReKaUi)8XJ>&81|V)r}c z;^I^AscCS~*5ZqCp1-&cn4J|S|9Z}+ca-ZhxzZJJ;h9K0nML6V>U=SItaQ7W|6ya+ z*MiTZR2+e8XpT!j;GCToy>bvz*PNwS!{D5n*9H?i8qF^SILIGEL?pLZ3?hD3;a!e$ z+3LTWv011-3;8=3-Yq|wXO)XYLM?4>QLM+#r>6z!vw(QZAZ{@;%Bft)g;4^-&x$rC zVU0?c@uoiE42<05Xr(W;+ z0~EI(ILX;zOgF_YBz)7dMffumSb%$2qhhcY)R(Urj%`yC02CNl4ZP$?!aEPU1rUauJa`Ag_ zqlNw-L<83h&+9O}4eqj21!arlkh%vdd}TGvKD#tVhBkkY<`=0zdmPsZZJnnX$MSwG zdCk8$*agdmHhU|n&Ty_|H&3Zwb@^BTcPTmTdv%|ca;zskc+QO~h3@m#{N?72qVmEn z2}k2S9`LriGbR4a8>g=Ac#W{sT7TSF)9wn~Z!kiz-Dp z8wX9fKWsb=AfU^S6R{dYJp-L$uOGt-Y{u&ds0og3Xw7!|9c&Prv&BqqDg%_79ZPMD z=hC+{>$|E8@@%3|cdbiuH|aQ{B9{lz1(E*-i_-WV`+Od0403u16y(7T|Vk$!Ct`-ENp(@`+uDnqTeXqVHU0;mw;T)M|vc zB}vZvSJkNkTBR;4g}Mz|IA@ckw(h7c#BQ38GwK9zLI{GO$}-t`?5wGo6IS0}VOS+W zuOhddCXo7>?zo-xJ_4mKJ1L;<4I({u>|c2IKLjFglLS<}O{;Jr;FmwVNW`moX0Lhb#Kj=n2V#*`3cIg7phD9; z&(WE^Z0NNaD0ZwVLJLMo7_bGj$#IfI?T3zL;Sz>iH^CS|q(b6K7CYU}X#i%=q2j27 zEV}nXw%kaW*bVSH!q+xAB9mf9V{W1*AN!8>N6Qt1~u zKP*sh;ssYQLlQ%LKH}Sl3!6Hcuc)CE;q|>N7i33Tfl&2=*+2vqL557+$rdwp_6fEy zP736yw9TD19`07oU5GV>F7Oz*E#uu&@c_STl zuiogH7#ZV~!M>u@UBv=K>y@@~Sii=i6$_8?>JNtbC&f?ug#ZM4ke>}|%d0p5s#F zuS$hU1H>_9drXWUw(sFdb>Say46mDgQPR7jX;b$*+@%h3YuFqD` zZL)?TNwB9%unVi`RqV`3=VD+r4p2Ox29b36wLA>Q(}*0Uz=StEx*~>;HgC7Dy!cUD zmt39a!bQ<*jYqYA1Q6d$ZMXf|w~!VazSZtWv#BWDkVsBz%sQTCQmW0=Z&49q`sk9g zs>~=!Jf`m*YWiv}*RhCK*Mu>8C7aj=f|UMdC)S`4(7?h>CzFa(4D7RJU%@xSo}QQ~ zVIQ#rD`&nFPqgY2Q)n$|z4=uG=`-}B>%|4*XH8maG%B?p$#>SvA7bfeWUcMf5&tzs zXG=8$>ntF=@eW|PMP$edD4ITDnMG_@SHID(`k@a^xa3+K0{dlwi2oJ{;S2~36;#n3 zHx)Oa>-K358awQ?6UzhD=76jY4IN`N_~|KIo(ctXzsBw5cj^#dElJHE2_9!XP~`M7 z5WBfo#EQdm#Yrx$;Fo&MdesSyIHfK_?>yV}2w_VVGO1anLm>>T`5>o){=3k+Up9*O zRyvR~SO!WD-8z6-%+SZAtOaQ@0lhF+2Cl17`q03_Z zOq9ewMM)tp!q+?{DAjKw6{gAVG+2k5<91aCP7ORm-2Wl)p@MX+%x!5tf4`gg?s$KL zHS|^L@_J>y1~Kc9r4A!*0OaZIE%@grkyguzx_h1|kxtC;XU~ed) z$c3zgAkwt<8;YUPvSLbwp#J5D#22Pk-9U%w7n(&p5sqbFoVc8-hjL}9xaT>;7w(t6 zlGwz52v384KHaB|5w9}ZbTan;T}JzlwD)>66gm)4zVjETbTso7%7u=VonbRrWA4bQo=SC2zF1NPgh)j;ePD+bW& zde=`F!lyLZ?=BR$fI5M{uq0cy*%Z`9+XO2BE>~6wE%mJ`eGVLFEVW!`VKtNSST8T3 zB(KZFniHB&_GP`GNylc60KQWF-!C=lM$4s=Di9x5bX}qL$II!N>shW}v{md_+qcQd z$Y()B_>8Si`>b z!$7euK5?MlUn%&K24(Ttr24X?URDI}bVelJ%~{0E_@NSAx7GG{^e=6#=1$>D7&8Xc zfrPy)*c0+TO8wB#Rf}zMu*$(GI33w!IqubIWHHaGKkTUEm(bhwelXRsQ*WWQ*~+7y z+Dp{>W54mQEVZz>nfu`dH#1cN>%djnewugokxgNSTkIe)09550;>bfYZnPb zgBRYKbNERqNzi1Q1dY)LUn+qa1ZZ4e~P=5O!RB2c+-71T@3b--cSsD=6A zVqle^C)U`x^E_%rG~vxsO2bK5MVsqx$ruN@QkYPbjw<9vwA|gx zDabC!^_z8g{22~V9rP}RzLAaR&ysE=A)hJ)$H)8GDl~Ae&U_+$16`ywXpN6WCi&fK zgJZKM6#aY;mqX6^cS}7V3K|23G8j6hbL{v!7|h|~FA^aWk?3es!%-|lan9}98K_|6 z3RroPejE^6Y8p;MR58_`sVL4ZHD=Wf8;^WwuwZS+5u_qPZO7hmSAOMF-ABp#q0`a6 zcvS0scwHJe&e5F(*Wl7YUXefHYUfI$&P6w32Yr|qpF`LcWqdq_R&$NsWi_D*t6i#m zUqPbQ(UI>V-8F4Fj(~(;BI}F*4|Sg7!45Or=>xU83(>_XkQP_H_knvI$<(1qK%fOf z)(WF^SD$cDqPA{El&kPt)4uvaX`3ehF`$isEi<;iUhw|3@iF*0TSw_DkFakGLzV^# zdwnL)y5VoYDm6vCe{?a`=rVdz3c5wJeXe~&p?^VA;Z97O++0d7FFwJZn(9zw=iK(| z?Eh+=7xL{Adf%K0k+!BANJdaL&MGI%X8uz2F;@YhWE*`n_U5q9l9KlqgI?_KPtpE~ z8`Z*EgVJUnVJtVO5{2_vZD|;zq*3vSe_6@IiH)x7*(Sg$Xkk0UUlz1k){o`qsYu)`Y1=!NenhNt z08r3GZf{Cn$#x%XC0qGR#RwEWmd*e!;9Uez%ytIsKT1m6jU1PTKjhigvbgifErt`c z0S|#LIu5t86{C}PLPdEGx_oGm?P2Vfpx+*1d{j_U zy|kfWoIiesJQ04`Tk${6*a2W1l|=+0hyCgGn<95A?6&R50|`d3jsQJ8J>iDl2h+!w zwcKe-4T?Ls`RLclG|?r>W;_s@Mgc?E@J*&PsU5+qQSw~r0dcl!&$kCzs%6t`G9gox z%8eGFb};FaS^(89^*mUTg4vpqo6uQpSSdo@CCu)oYqd_O4=HFrPZUDe7KLF zar z^C8kA1{?qqkjV2|&uyEuSfsi)jo&5j3xZP*xOe{)N2gFFGHu$eF;Xp>{zC|(bi?}M zT1?b7JpQQ^m&QH4Be^55P8=Sv1DG~@$2TdIOnvlyX3RBqc>8fHy;9e}ltUjD_5pam zqRIU`F+1Tfa>FAx^8~Oh$Pi*eGpuHOO>qo3uHdEiy0K(Vs5 z%%RSC9M>kuOBPUpL=?>V?3+viygxtR7T?O*vec-J4aZXbhrqPEl%H_9wk{T%v&9;Y zP(KWsIlAvnVUvFQqEi+%C{sB}e}u}8X(QRfjG^+Aj_)7>+!c%8m}otC<}_u?6?L%(>(Ie4Y6ksVShD6kpmUeeH8EE_?s~ zuMYgjH<}nnLuSiwgENW>1wsT(Ix9n$j!~`a*)Xt~qjyk+&)pZ0f7ydD2d`RLHgS^n zK89rWU$8<**(|e|@>jO@abNKQd?!Ix5Z~Fr5rO;6=*BiNhZnD#^IiN^w=l=<_0!j=qdpZt@-r?bku z&mYvae(A)+d(M)Z8ViGV6pdB^BQkKIlwL`zc1=o32?qDQmvZNWLCdZz<~q>U zFKeFNly%OZMh;e~Yy1~93Lg$F{(`sjtA2y?fu_}cuL1VLfQzh%NzR2Q-b#6m!ELPY zrsb8HPBMq8iAh5h06@>yW#`4~+#t*7O1kKq1(jr9mNL$pip|gp4y78955RF3#vq(b z3@_;7Qu2&AD+o%^{nh9=ZM5~B6z7NkkBQ|o0>lW>0mddsNTs%@@8`G3S7j%pW7?)f z(I-m}Vek5>FN%)aJ~7~RW2BsY7zn#)4?v4j+IS#pH=sII3LDRP!&A+XJ|uV8{#5nu zf<*7wT=!)wxU-ZkAIHDLVvl}#zSUY__4nHrF}wyO93YS!dYfQhhlbGVyBnpU!*RO8 z;6NfJGdum2?<&fm*3E*X7&6)mMW8=<$;Su&UD-L0BB*Kw*+DbJ@m!!)5v}#*Ep#P3 z(i}2B7`dt3NKXMQOir;Sn^bpY-%o|N-pzXpZhVLjzepO4`JLh=l(NVXzC}o8sf)ox zkJ(Z|)&2b@snCb8A-?IoJcz;22PmSBZG%G}IsqA3hDw$q+s)1uEVZnk)e~?Ky*wsY zVtCyD#)^z1C^z+&7<>tBG8s|EXq>0IiB0=O?sO_YSkU_3xu{Jgk^SeJwVfM=8)LvC zqM#~*sb>AxK8v(U(ntt#%PDPX;~hYpWnHWOJES0>dp-Npuv)@o8vKHNP7s?5<|5xI zFb%=q>baK;A>YZnC@;yy=}+Jdfy3v%*2wVRdQ_dCH8-3a2f-a1pRqcYPc6|q7s(@`^$H+#u>FMz z3{;(phjnryF5>I-VqiKkSt@+S;4;JiFQ*EW7kV*JE zPjno%S!#{!A;X)It@aGpV+$K}Ob7Ps^O^}Gz2e^KN6#zIR-Q19X2bi}U~j@XCs!(l znr|2tz3_vtt-CJL-x6v|20r3^jpXXWq@wy8Hyi?(by?fmD*lRv?TBybSq}e z>gVgT9Rol{MU-GMzrjmrS@@|7TMIiYB>ZibRc2I z*E3-AA!zavvhm9syod0p`Q5%{0hRWn%8*_cq3Ssfa&YijypPo-q_At#4D*tK*{qlU zv%Tw3kwvB!f%2yn(^91gA3?nUMg#iVpEoZwKmWpP)a*d=nk`57k@^{e{}2LsOiLxZ z-|ce-GcjO4UA$33{C2;HH!iBS@C^!kp!5!WGEOn#gO%KLbk2cBW4?1+x9EH7JFvu& zS`)r9mZYDNAJS7A&T<--q(3HA*({%#`sDs096hbdEd_s8A(j=2`aYm?%$TdT83JH* z)c=4VLdX-ZwDGkdN1c2-N&o64(pHFaoNOXv>`E2OHHEezcL_-q;VYdpFN$V57)1MKnU1A>a2NRHiGq8}I z)<@Ip(toO)2uFIbp*Bd82@DsVG}Y&*E@jEu4qka> z)dCaMf?2JN{0t{E8&_tmqia-8S6A@4T&dLqD7JiPc)umv85@9^nt+5kHj)lACQdVN z#D#n(=-XmA7;jljn{cA6!kSlof4s>zUng4KeMRVMJ-!fe3{Vj_EBRe3{X_U`NgH{^ zrj+_#I>MqTGSg)?JBbc}0`>h-MT=6~gRSL);!?XF=zhemMI(C{LBfQo#kuoiZedq~ zBpblUL~WtGrMaekRi+_iU7j?eg;7=d;6$UIhRe3A#BN%Wv%Wl<`8co9T~;;f4KQ#1 ztlX|=k}wTlV7Mt29MX+oczlb?@?Eq1_c*1obJ{MA_p`z3NSD6XEIoODjE}7L)M~Tj z`uK~%aDF69e_q1>3558+6ZQY~ zsHuR}mOl!)PToEKbZuU*2)U&Oxg zja^)F(;p8VJ33T4Vh_15l}k?tR`%O-hs|YKR9|0lR@+I!mwq=f2@A1(XJFxR%ed?> zN;^FIq6=`QM+Ga{W7Z_bIB#QcZX?0+C*t*~$wFi8B5K^y=RHXxTJLp&?V` z)+ie88IRfbd|;b|AoX&!en!wSLxY&f*fGSVTE$Y4(;>#O36!u&DM~IcFKQEeKQ&r0 zkJpMau0|KN6L7pUAm=Kgg`HT|Ems18Cq<|@VmnZhX#QZ2?iG?lQ@IYL=pv&nduKcvj(CP ztQ^pU?ks7p?+I?AiXcS-YUHmi`?=tn2F6M#re18FI67GJL#Bd7a_Wx=Or&gI>42tR zOP-QUR1+*qY5sj6uQkm-s`n~!y#+T{Jl)Sb2CXc8n9v=a6iWR zTt3`lVQj&$RojQCu;E)~>}=7EXO#74_x$sIY?Wag{$k@oB;$egZJ(*W+DWB;N@Qt| z;4RVe@bo&<7)C3DM2SVMTd}By4#bozP>+5q3r);^66TDuu|EPb@<&Ze4@VP@#Sc~! z(mwwX+*6X7!`CWz`(huL zcq(=JSH->jZFG^wkk7XleMYxZ$0OcIK~u9W8o1#mE&fMhsO;^OOAa1`#fDHTdK!Zd z;IC{v-Em=4N4Zoaxr?&_{A4hD>y*KaIH%4^|3^~Y_`2n{JnC3eZF<^ZMC46KQehsJ z?l+72O1#|OI_=8*d9&bYzl%}_Two3z_BDrkGki%z3xoBLk(Mvyx)3+K^y}V!ct6AI zNLS(WJMFLB=uuRma4x*iUq}!xa4f=W9TX)LWCjARU%zxqs&XmcrlL_%j2#ufFSH?W zJUe4#mvrGkl0q0V;(zHVPu`H4R8sP7$g=uE6gNd!N^6TFR(wD0$XmNrXhK`VJf``H zt3G!0!w&~vBBKXCp`;sW1H}-NHp!_R%cx)3VZa+rz^>ql4riIs$2K*J;y(k7BX&;B zH_v{U>T;Vz(U07j9*~WNRqljlVnqvf6DAs6+i^R9$_-WfUN(ecn4U&i$X4FU>@D@0 z;rvac{g9ysg)q25Q-l;bv+H{S|0n4VpgP7VVnx$nafzB>Z+V%cXa=ZRr0Taj~(l%=1~K)enIv3O?U z9hQ0vX!X8KIsTjL8@X-LUr1%xm>T4)S{$z)+^b*Pu^Kd#|L@`6|GJ|DYmDuFjA_my zDXUE9Jx(gQC{|Eg(si*!A-c$=6lo|yoNLtJsc0eCUD}swU0&DM zxjnR*3ISBOCuG0Mq{ReTb;*njJ}msieZ~VN4EaB7dBl6qaH!Fiwj-gv4rKOa_s8#r zke4Wz`#s{ksIeN(g7NEgO%Bd&xD+8~Bn$U8GzOT86}(A01+5xITT7?Kd;5 zCP$0(j7Z}bxIN}7q_fm`9M0{-VM|IXU3fTBcB=CXedDBCxp7WrovAqu<7c*BcHxCl zk+|28z#n}HQGl_5-5s%YI7l_yR=QAF3ld?gPosXCwYYWqOv^Ksr7oejrk5E9o+LO_ zR;u^k5#F^hnuOz9lo*iDgeG#BuT;|HK4xr|wdLJOP&8d($KOYxyjsAwzBmP&83B7D zmmM-A(_0&Ve$n6>j!mhYyUAC%=%w`df=8uLDr2cl&*axJ^;@dEDqmyi*AJXtGqAc# z@sJ9T1Aq>}P+k8;?x%BOg}*T*b{#acroJATOlXQz7_a>72iE(9*ILu?rftQQ{z`Eh z$N9uXdc;W}Tkem})pn2G8hvv_DL_=RZbJ%V>hx_;OsQbY?c!NwvZ7ipw!f;2A$!D7 z7IQZzzKSOikH9)TBc;gxb6V599KVt1zMF~$Kd*UayPSTQ!8y?DZukLmUBjb5d52szLLM1L z8l^`@Lh%pbUadWnXGIgwubY2hkpZM*cooGY+l9%V18Rv5LQOM4bC^Bez{FHW5P%k=0c_#FpR^ zU)hw_qkI@wsD250hyCEqIbE~$Ml1jNvw^6XUO4p)7bMeHJvcdp8Gy}xLnqL4g!8U0 zg#A#FmmE!h2$H&A%78Wsl$Qv>_4mLhf@`eAG@5$H9URBa;G>d7NnsBj{ZXcqWQ%aRU~bTGpgm)Z!MFltS|z2R#Os^H+;kz z1}V%&b7rvGjw3PK3}|%iMY!UQirz1G}!4_^&1gIAPG z@Rw=UeVwL$zf*IbQm_1VA(wZsWYwMXOv-m-NdMg?{Ci$Qc4_p|{0{qt<7(LZiGRu= zQ(clZ7sl_~|L3KfF;UEWtgv}s*=K~SkgalFUkeg9?1{L;iWA8yYo$9F`bir*umoRU zKGXJfZlzV;|G%eKsxs*RvsE8|Eo(+A2H+m%Q>*BRJ&KiO-LW{Ti8E@`e+wbxN@h5b ztjx97iw9Y)8?Wi10{eJ>;h8CBCGhQOQO;< z;|jq1rq3i7JtBTF{{{@zkA3vBz``KA0%1Ua5J;Zpp}6ekkVXB_w;3MFs{N;`vmJLT zk06VKDbTl`GND$Eqwnw1I^r(*yMH`MD}A;-*5{`lLoLr_1|6_qc{d%Uxx2UlzC8cD zdXpC;&o%c{!nH7~rN}KNZ(%D^8q4mwk3Mo}Ut9_}UAc~lbBZ3;l@1qji(dIiGDc7+ z()Z=it+6AwG{pk|grwPf1fnx*lj;J6DTC)H9HE_pgyn8@O6(O`wf=c8H=)zhif^l6 zWfs;I4pspx)X)DA$`;GZ-g{A~fj17af9);Xl1J%10-6;kIyi*#EGasn*P~$yR55adjR(WoDW!=33R8xnaVnnXT zXJLEs`kFXD1qEnWE-zhdxjrqoeEgaOqA>C8+*yGQ8n0}Y5T~*mVaKNCZ6wO6JKYv;%~qE$gL4mIE#-%w3!1 z@`)S99)CF_Fn6=F0x|!13dgVmIDmg6Ub5Co|uvB{5ms zU5`|Mv0na2Pt30@%*6#y@-l(vu9`~=g%l$qW1?i<_J$~@T;HqAbc=GiKSOlPF zWNTdgq9YnA3!D%QCHtOSD*@ln@+V;$ksH6yiyq+)(&cAZK|tOsLrw~9+HVV#y85ftm$a=kw&BPlNp`mwSkAe;_$B(*wS7Wt60$xuiIW)YoZqP z>GK(kw-zw$?n|Jd8UM;^S{E$&(#R2a&0peV#c7WfnwJreoItwGc6>K({%5Oh~K&qi~ zw}NMnPCfz+Sz}(YyX^#3p?8by8Ru-kD+Zi@2oeCz{s&8Gue0QUKj$i8*!SJAYQDJo zYJz-=<34mmg%#7+DXKfumf4N5@aY9}2$H=}?TpzlE^YVRbc8OU=W9D7afsc@yR|x& zN6a=dLsV0=r-TfcC-YrK!@gN z%I3DpM(8dMnS$UKj!20MBksGGYN0A@O5F;m>yLSqx}Qg}Vg}ECm8H}d>uMlP?ntd* zM|k34khUA4i=6hgSXxy^9!Rv=4r&5psHP5^%ydY+Xc7f}NPxygKRb$qUU!mu+r-gz z0+>)Tr6aut<(_Dj9}{JfcMC1wblVH;?M4Y-kiVn~R{I0#oA}=1l@7`tQ0v)dlS?%tkhf zF)l+A+v0OJxWrv8ZsaB0J)??T%`^Mc=mcn_gN}7>Z+sT1gDEw63Qs`G*7J-VCwWJ# zfwp7SWX3EL(Cng2(m%rL#x7vp*DVwzg$He{w8W4?7-7in!Bqo20k?|+Hn$8T>{~w^ zdxO!5DTJn3z7lc?8LEh~o#99gYdtDjO-Jb4&FV|*B{*gfg@9Fvf8dmtftC8!3>K>G z77>`7YRf;M{#MW;wom-1h4Exd5w}axzPpxtnVq=#LruYKaqopV=Z-3Ds#Pgdb`NRR zl#5+gxTnKlnX%Y567iTvI@)IulbR(|X?p_&d$xse@5ZP7h&AX=e&&H6qmEd!*;GL5 zcg~`e7bCq9ekKA!PhmQ%N$)30anvYwR@+t3|qz>xu|FZh2T)6&^|LH+#iLJ ztf_+|AU(~a_^O9b;5REFImf38Z>y|g(RWzrI z(U=*^28lKc4!utoPo(R}flG1{fE5Jlg;o`2Qo7NAf15eh{k=?~ioL235Ed8V<{i|%M;%6gJqa93h@qyhS4nQHip*dwK6^1`1Y1voVRtS_}pO^3I!OT!7R?B zw~-pgC^U~sB+xxGR6b)cg5FhgX=5;bl>-lXJ|~yE=%4&OE1u!zUSF$*n0{}5Nbx~C z0JJ`5sK3eq4>rwr*w5TPkjm%0>BjE+qJIc$G{Qc_7w=c-1}wm-96aiDU5#b(2WIHX zr7ZNw`+th~s^%W?S#k1h>){D0%N}};yl-W*5N<^o$Ilbu3|Zi#D|%(D4pt79Px88v zGxndj6use>zT;wkeNK_O)qC&zzwi5f_y2kP&SUTW>|yP-*IsMwz1DsnRge0IFQ?Bd zmAKHfUT?izbc6rXc?v`uNusW8z*I%YDdAJ2uV`m%FR)8qtU;KNJR(VmH?!%Ps6mM| zjJdHrW?7QF(-_$J{x>0-mcs|Nu#S33O2I%bu_)bMl}tb|smxsea~kg7GI9Reu%CFli!40y6pn%$9F}a-ux9rI`2)@i&P-h)_bCrY?f?%uVD|_!@{efg3pli9_3_ zSU_--7!kOWzS<4$n~Ct%;XuL`NDPt#ZPP=R5F9cAKm4_G3SSspzbipxQ*We*AX3uT zTEUZLiE)Zsm~~|-w&iWYK~W$bU#A2iD@EHQDcY$JkoJe1xMti(Xy-X8St*E!n23mt zhz&H}yE-kd z&8+cJ2<%_+3v%)aa-E{*;t}K)5ai|pWl0_peQpkOh4BAdT!J)^iW`S02z}BM zmxG9K6VMJq3^Mv1UlP{_U56;PY}vAP3&qy06uY*OZ`-wxl7fPAAJv{c`}XXi+C@RQ zzWn1QC<0KHLcrZ6YEe-b74F zws{LF2?Y;$xQk@dk=u$ipuZ|dxOXQi0#$J}@p^tQh5Q*3r|L;swbv4dA| zT+X}3fq4OGbrZ*%A@R8-O@ruN5HT@;b`t?6vdyG?1Q3pJ?cM|+xN>w4Dfd=LRFK6to0gW&w|&SjED&^0TTwq!(kAIE*kp#O zw1~j&!H}Zfdw5r{Co<0)@pqk%$jISEp~W^0_q_mK#HQ{ZSuu?+bTYXnig~D1-8U0Y za<@{XV2$OfMCCE0dNC%$mPxG(^3&Ql$fqb2IC=pODOcbUXx=IWEk;EDGdE3f2bkL0IBP16RqKD^>m=+G+S!~VDdeDqT5 zo%X!}P?;?A+_OWK`8F9{f&R~x6*>&VnuNU29_3-^aroe}`pr-9R6R}X6Z^p0{Lswy zbB7v@E*G}7Qn^=UZGA8LWL~u1ByRFt*HqV(NAF$#i)zA}8k74KU1?xyI}VlH9dp8F zT?)9{=qrzzUCIWV)YU85j@W?nSmzbcp*$08YXJ_DW#dSRQns`{Z!37_p!U5U+S_?4 ztqbFMDH5Y>IMt;mj4y*9laob(`blh<4o&A!+oqoC{ zd0?Rz!lvS&c5vRzN(UUo2#(ut&F{g=Jxw>FXf)=w|9!26W6sN_mE-9Q`QcY4GJV1` zTOVo~8d2F@Y~t5u*Y%&{!9jbRkaJy_W%KiSCmm0^WnS;4ntEGNyS?L`u+Fmp*#nZe zn$M)@q_@yAipmzrdU#N;fF?HggXK=`(NmM<$eBw`E>4ZeZrB)7!=+ef&l6*N?aOzx zd>+(sj#6fN`?g>m(CS)KlLH(S!Jn7on5;_Mp1GL%p)~db7Z+~ zGOZv$xyjw) zk#ZQRo{n5;eM{D_t151X>Pbz@;lcJbXNykXU&;VuFpH{A#zD>@5rc|Bb9+WnL+2v} z-FwQna$1!*MfiGDp<>@Gc$j$>HEln4@O`$$(xh4fDz+xCfxGNZxWwX3(ZeBN zTyfA;4%YKiREmppS5GbuI^ZsV1xI#r(CNsRjy<_# zvVsJJFe!UMcjVcbRuP?f$Ck$p?Etn&zB#!Z}I%J;N*+Dg3*fTB-ciVjG zGDe?1FmrZ~`gG6?%@`xv`?S_0quUF>z}Yt9WHo0E-lF@-U{WO6UbIE8XE|hEj)re${)5C zRfvm@-x$V0m$-(Dmr~~~9mt0s)##|^dS&<;QoX}Ls*jHg&2ko>mUeo3uLp54BeYQ@ z*PstZwcYA25?@SxjbR^X3a! zS)|(06iB#?rH!;$$y)_Ae;5#s*`F6B~LZr9H39lU$V-nxj9q%+EA@WoV8oNpX1bK>r*+BF-2!uaoE0^&!iao0{_7NKT)k zyjrQ1rhqE!0aZ}}*Vrestol!dhoW?jiFj2cWi)c3Vnv0KO-OJlbxVDozfRm@E~VSs<*qP-u&GPtzN=P zG7a5g^rr&0su8DCOv2T}^E&rOMqXEy7KXD#lU6ORh{>i7=NpY$x+md+bHZQZ5rwgYQP^Vt8v$Q(q z>mJmmp7qHi78#kf)Tp+ftkF6sw81j%&Mv*HHe@#b_iUAjGMhM>c#%Ji+1mAQvBVW$^0s;w696eZ7ab54y6cbUM@lP&g* z*pT5Sb&^C_n-$w=Xoz8t2A8N=AzGA1-(g?Qhc>IUa@rg7croQaTvWK|5iGi(CwJ`L z8}H5CTV6(-8$09u=99BReXGV_&84guM`=ygx`)~$RVK<%BLk#)0xL-+>TzQG zNel%}DH{69IiZ^eYlg9rYbl~w3LWgHxm7mv~(HANt71UWby z9UV{V)eG`}z+}27T1m$Glwq`DHYlOa~63kAB1D_uh`%?VJ9v7BIv~ zLtB_W0&crnW~-1L0#tAEeRCkmO5YkZ337hPLB92u6`LVoR${ic`p#dg*2hNyV4&bC zXg{grUv~~)2>{(vM1Wg}gAl;i`%8!nEzMxoh&6CP=D*U{U)OB~Hd&JZhk@D(^^6tgh&4pUONP+LCR9!WPPn*=wVwR)YkDa;#!h zh+`Gapq)QUKk~MC)aWC?q*!fiZHRtIeg7Ql`9at4bh3&(u5a+CBYk@&@e^7ObC_ zyK6lAFVQX-K3Tx4!A6Gyo^fB)xB9x${>sgMNcgL4;ZJhglQvc-72tLVWkXvt8^F@P z?sfcf2LI1F?ytItr`9ikSnIP}!VqBN=^M~~&9wfo@3B_f_j^h|@BFV@_!V2^VdoTJ z=j2l15&(N2f;{}+Y=8U`slR56e^|KxPf1JFTK~Tz(f=Qyv0wD{C#-Qptp8~H?tehP zf0J1M$~V@JDMAQX{)B>mBE^4_ydm6yap2b+_;03Q8ylnl9|Zi*y17os zt18o9*bwq~E63j=-_j1ofwyh_swl$QW}V{tW9t(z?0wJo3KX!9fcl^GWzpCX2 zofKN@aElw^6?D;%X0tI0yz&5psgwybt1Tx5?nrke{U!8Z@3BE z1j%M%B@z?T6C@ad1MKS4X5teBr%@wN61c9C5FBfP=gw!BT|#yEo9Pyan&=)ON>8}| z@J4`PobYJp7gt)~#tY)0HiF$5Zxn~19fUjKCi*+{*&@B25XHOW9wy|Z{x(iBONehJ z+`*0Lb1C4rOo$L-OrP!9b z_SQyr@&@L3kiR@vGDP70t_cWG0Y2K6aBC9~CtMd`#)$Rtvk17==lEwZluS&&JSTK` zvz?`xAGPV`MXq=aW68SfTPMu^BttgD;M#1?LE^G(ub;AvoDW(~8pw*qA- zB$e^C0~;$y1M%(p_6WE%%o=73I3#}ZK`MadeaTGzIWs;5|3ucxgdY6+Pxqh1-qun@ zQbPqawGR2;rpVcuz`jY@tZ#`>(Kq=fZHFPu(ozNHgpjq9QIWe~0Eb)RE8Mc0{7vSq zrf^#qF-tR(RZLNS?mTeR_?!$%k{Q8__3bSYAh^{57{h*$9d8IAB!8QIn}LZq+!AiP z4!OHN*MC-e?ExqPU4&cXalI7*w~@C;*umBl4!I>Dq(7um7{C#Lp#G4)4GgjA_t^<^ z^8~&jhywhGM5hSh&vO=k7~wMslMwRZb3haf;D$%rBk)rL!H*F1_&1PF22lZL{cny+ zY`FJtxc6_k_iwoOZ@Bkwxc6_k_iwoOuN~~#aPQx6@859m|KIE0|9Smz1gsDsNE!Ty z@Cyb?uv9k!3v>er2GK(bkSPcwz|W2l0-F|K5&P>L^x!l&p}NoYf8HG+14pk3E#SJT z$iDdPTicz~#~+d=xa~XX+i>7L`yp_2z(ybMGf!^-1FKzOrpW>n6TO*{Fq1l;9H*R( zILy>c#>Ez<>~c}X(8a>=v=I~jB!QElla-AX453dCP99j>2|5Wg5h@o1VSF+N6Fngd z!a|ryLr#Gn0oIikW(az4s)3#R6dS#P@%1nv7nNK)R*c&Oqgli zc>_nDlW6#rzkS$cXQd{mIIj#UO2hl%iVpXNQyFTj18Pl)6D zXQ1}a`4!BZV3ryZW>zq3{2s5!Del$W-#_`bi00QKyu9En0igjxk#$c1E;#U=Ux$qU z0D^4Rjpa9k0v-VL@Nj@p`R@R-`f`9D50}mA<8@=UmL@0zj<&#UokhSN?rOfZwEqtH z2s7iK5E}l;I-v1U!F2}&@b-p3q~Xbhkf;GXmEo55_(KvRJe-^ytC`oQuVvQ!N#^zG zYni|1Rkb!lhyW@iH27Wee+PMh-~D*hR~aFm2UXf}Gs1$HB^qzz+yRAtxs&0XMV-W8n)+jS zKeKNjHh}=;SQE*3O8(DZ8;$%W9B-g&16_X!1Ai&=26b(q>n~y8FJ<1Kt_^hkB@Fzf z%p26Tfv&%Vfxnb_gSs}*^_MX4mojfq*9N-&5(fTK=6{#E$iHst!>qwhz9ZPO$Mq2Z zCMzzkr=TP+C3``VV0|Fw6q7hBNen#rtgI2XO44WPH8i#8$*O^iAqg-afJ@)d&PGf@ z;Q~Hv{n_gZA6$3MH-2_Nt7FI4weG>636dMy*y0_$TM*u1@;O|O4;y?A_u<2~pc5d^CwzVrLYNqD4B2b&IeZ8o zMgWI5@E;O~+c*X3Eas0JN1Iy)1ZxlC2GV)#>jueE3q(uFo0q7&`$9 zo?<4X{*5>MIDD>dR*`^TqWzU$)4n!jXm9KAB}PQd13~{P{s)7#H;Cl z`aj_vv_$zNr%8ywOIyFbgVq$hgZ2pkb2Bk`kLub*wq-NvrmZC8#6-|Gki3}$w7>Qc zJR%_@-a@n$BHy+XA|@gMZ=of@LqxoJt345TKkY8k-J6e)?Kui<;o2+4&9HB);@SQB zj64UFu3V)u@INO0IAiKKuPr(Cs~SG0Ze{*!(*aK;RO}?B1f&g5sH&+S%zRzjGh^h5 z2)qu9&U#bV%Y4ds)}H0Gpp5J}fN&F2Gjj(=Cuf%%UN>*u_P!q!9P%JEEG9NCJ|Qvb zS$0nD^Su1G#qUZ=%gXB;8k?G1TKoD328V`6KF!Ue7Z#U5_wjGd-9$pVY15|7n@Ozz z$h*K>b4j^2Lr3?BDUxyP@4d3+>{SN;eM*lF_VaAbV0=|0Zaa0L`x-BJc`lWq#PpNQ z<9yUA{E|jYp{Zv(&nLs)3Tao&bLDo^U7L=7g+?)X_>othb85gw~j1*>j&4>+m(;jMNbqq z6)vaSPkM}YxNao;Gw^}Leb^Yie=PALaWxyG_YWSu+Ktis2ajIe#_0WnN3VWk^!~x4 z*RU~q|KQPU+!(!o@aQ#djNU(Z^fuOe|J=QajrHC?d1ncH7G#5S{)0K^#(M9c%sDsK zd;jFo+gR`Y>CyW@GNazx*}BNp;GC9SJt%PULrUW2T+2!Kh~Tt06FQHdKk`<2Tu~!0 zt}bOUytiB_$;)KfA=eS=EA1=sIZfHdSRzMZFiGD<6*DFZm;BfQnBYi zsSve1!b-(v%MkbqT3lKm__%3y3u@`Gbrd##8LikgR}qebhLhS+V{z~$%5>x(vgl&- z?2s#b+950V!56#4<|aQiv`5X(7YN`W@v1uTVO~9t(XOVGa8P@)Ee^^IMGc7*V#5jo zu^vsvIB3W@AGtI-+2Oj>4~lhI!RR+><0m%2bnwSF7~ z<3WCKcU|FgWWubZ0RTVDB5=@L6QGX`#QZtLJT8%|=95>LQ#QW5xh$_og)LjOUAovE?%|{V`Vg%>i<<$M-S@*vbmYpOr=- zj*fP&H07gF_7jDGVA5UDx_>eO_aE8=aeFQrE{|cBU-UYUd4)YUo_<4*8BL~)F&mXz z)NY`)yVm9^pPY4{x_|U{{f3oDy$V8)S?!pkH$ zND?iBoKFX|T^k6d#_JGN#PODnWp!H^)@-7x|90DQAX#|16~(~o;pa~al4-rmYMUCz zU%YsZ&5lp^JMb_r-dxM;n#{nibH&tJZ(Y;v=VBMCX2>qPr7ocBL>cpQ3TWCh%kcJF zW$`D>O6*)D@rsN9Wyz=?BB2R2#K@kqb@_f}&@92{m^ z+tQEB^6;Tf@K3lNc#z(5raDc~H`>g4goV5`iDkaC&xb67Q}fM@D&=V9dcJ-3`wS$H zm@;`O1aRb|_2iNLj+hD;*2Q=?%~l-5AZVU=h5A7&du}_es-DhvwZW0Y6|pg1ZaEE= z+>A^|ZYRr<8q=Ndk2x)5nNb!;-S{Lds>3yz`d^yxwd9en{ZZXg;o&{TeQ-}y#o*I~ z=_m#p=W~Kx_uRX0J#K3Y4v$yzPh=g+4>VUc$;j&{3>>@g(qe*oAU;5dlz#6yItE3B zE5Jp-Tn@12Bgiv)%het)aZrtWE!|4;3f_NUY3sH{(1}jhc`~fe#69rwOg;SELVl3Z zd*6he?RqNuNe^)o2Z8Tzf_mHqQ2t#=2OLx`->*8gj5;&xs_r0QJ0fTneM8UCSOMPVG{z(9Gie!)$W7ZQ`(9dv8=w%zjiXtg}hMk=VL`(hLq_PiSn z_7auI&_aA`o^|BdQhGq4ex|vAHO-zJJH7xb%Zd82Buox{%|zvKM6Sti7>f$tyUMJU#)*~E^}MbDNis(F7TyM>+zOTx+^6E2j&O7F z!R~j)RLxt-2?@v7ckL|*r=ZF+= z29wxmrJ7^S7`J3L^(6KZy$oka}1B%z&@ra?+r;1ZVwGHv9Vlo8wciliJW41c<6dNJWmgDwju2%v8R} ztDJw!9WZr?p4h_7OzsL785yxmm6GJEedHC zcgh(!CJ~beKHAx)xAZh(YthPwz`r2uzG(sXAJ{)ujH*5}coqk7!25${#9vIcq<<`o ze$L-AoaPfu9etAt8?vl+u&^L^W&zF`W825SpEmQ%qsL6DBIMev;S7K>r(J%?`)YEr zyKZ7$`eKGf2C+Ke>Nb9CPzOHc6|iUQZ4?r?p_S9KD^BPebUn*fA;o zbfs3UbKd1zQT7u>@AP(wXdxWmbNIR2%~$hmwml~R%^>)kI#(H5OMD&?} z8e5j!jgD}2_Px*SKl!=uksAG##Pw`&A7KrJ4;s9qbEz@_Lgz%8Uh zR+{R0Hj_=>zqCHHcgnq5T<)Uq71-gMr&$A8`%PHrkzg>rMX5woF|Lc@b<6M~4{nFJ zrt$Y_9lQL+pXW3vhhACS5+IQJ()tp+kxE`wVm_CL>OQB+AU<|`F8#jS;>;qW9aQoF z7e92=lSK6k6h|g5IyRivO&-6X9u{n6-)3T`5X1a@UaD6{mqoZZ*W#G;RD*c>g%8;u zQ+|KO!^*I0vP0Tq(ABUUJ7!zh#5yaPYRG45tRQ4zmM9r~TxiS3a#tg*=xdZ(0+@mY z$F?qtWp4MYEej}q4*G^{*FEmN28KC~6U1SUB)Byav&&60d0)#EI|w@LQ{k4$_mpJZ zBc~tvJa(ewnOoZ!4&oMhQ<>9{b1zH#(xVlcgsXASPS^HCzrF4Iylh_*_n9D3*Aey~ zQ|dRo=!dk7&r#&J!VFrmNEDr>wiI3IzoI+b^Z^GQ2Wm!CdDN#=pcE%>{SZFcu~qQT zRrrVH0qQ^Dc{i&8s5%TYMVmYm9bdHBvK@xT2{WR_8v*q+$)+? zdn>St8GeW z6zA3U-|eH!Tk>&`KHfYw2Hn^%k&u$mN_{RdLCC-SY2U}Vheu39K+Sqq9T|BxXR58n z$Gfv_pE-A==TA9BROHM)SafT~yeB&&CV&4;zp3%lnVP;UbBa}awCjB-!B9jA`g>lk-hlB!MO<9LDn%U$^K+nGQ z$zh60w8f^a0jqKIc z6u~NJ^n2AqNp$uN)>g+56C=Ve|1jS2s96*(D6lInSzk2)XlS9EeQw16uJtJzF%LiQDyYxy6o%>O!7~o2~AldE7Kv zu5k8ZwT943ofgNA=fV7MX_%P~>#M}a#9lRweG=m>=)~Yl6)g#vI?wmm(lbn7kegh| zWBn+NWx&3|L0w&~hXHFWzz>4?4IH$M5eMZ;k5^-~v0*?%V9Le2{m#7ozMg;W0jnmB z$wY?fm2>p#bn(&_Por(iG;_EcsFqH43|r1!s&3MG^DHqbI?U~)$ITKY&gE-i^n(W? zqwm^kBt|^ryby((Og&{+!IPbn)2VzPUs<*42dBMXBK(8788T<$c6SUCKfMj(^=d16? zx$>n!w%37`^$2USNHKDn99CqlC6qjp^tXI3q534I;(hLbR=LaeWZo`+eycjM+1H) zr=RF}B7NRw1S)HFu=ww*{0(!y4}6jw}wk zRiO_gDXTa7V$sb-0jvsE1qa1irLSmQyx!$8B>V3+@Hcz1emLKyQ(_*t6t(p*1FDYH!Z!$6lwkt1tC`#P*U7@cx4+CXwIZ zQ9)5h&!qQ7!Bm{l)lLq^Q)7j1Z}Z5>`6YKaC%uT#xM0UE+52XE>2&YoCwGprsobA_ zl9cqja8o`pVHNu$hUE@4ylyagDkc%oo`;wuxAe~2BQ7MZ045hH% zPVBT8yN;qKU0rx&&J*c&75_&U?2V#|yK5}3+ZTc5x6Clhu*I-ha)PN%aeS zBTtuP*2k?j zW!i`GUA4$eoz{zC&I%+qx^`+yb&aLBWxd>9-ZCm?!KmHWiwI5W(az$at-oV02oFnZ z_AF!xoSPtzh56Zk5-^yIxUG4XTBh)DeQK5U;f#7Jug#YzVs=>!GlDsjeRmOTO>Zfj z6e%b%&aIxoOg@Br7@RnglEW`M#B;w91x-62MwdV%u7T)AOc+Ty~oV7wig&i%s@D znB=_M^ccB8!qr-h&|Z7PiNX(d>z7Q={rbW&O<=7w6S0WQT|P%WtJ&ojahspR*ezs~ z&24OY;;xsuv6fuR&63id0J)XMpnWraHZuZu2bGomcqB>PCcs2qX0X(mes)FxW_7q^ zbiCwtC(RzD)x-TWEv{K4>a-qvY{zw~?!;Ao&W4MN6G##>@obko)(P{^`+%8cL0h8$tH0?gPZx(IM zie%uMK~`pqBi9;uGbTNXqjpj3c%PxFWMHeX&;P({8ws6?Xn0Urqps2*bz<7J0NI-p*O`!}>QgMf zLydSQCQAYkX+0~0Z>a(IzUGJ7+l@JxeNqxjj56{Lnk8gXjosK=EvG52Bdz4GqNJvz zB2iPZ7m#V98gvcMRw%zPy@mngYe&%sJF$9nmA!F}4#V&H8Dh_r!xpAH#)ZX8ydSl8 z+zx#ACdV;SOxJ0cxx1OxQ`WnzzJXho?bNN&=v%rDWIz$kFafIfnsoVQVHL)NVUNaE zjQ03pSx7~(SdSXOyBZ(p0$H$rUaXN)ZX*u5o&#)T@)Lc_G>iIf?>p}}tX!%uFzKFz zPq+-n1#a_CP4T7BE3s<3AIYrIZ4sBm`i#{)PNgI>jYcuv&4{-XNTw}#R(J`kfk^=b zcfEtCx$9Vw1pJ_IP{WFuXF>%m`B*?uW=rMGyG`4l@dxwACEXcB$BmY5dQ#lm>#v)X zrmCGZVvm=^$ z421%xW4y9#`Vp*stg4FpSy;?jw2<}_NwYr^F$5L4c@(<`$S>=23xLnx!a+}wX!QI| zfX%dJP)6%9@^zW$c+IjM4%!bamMHY?al9h#mVqC`)pe0}5%TpB)L0_c2HAs}o5W%? zSMY+v?MFIogD6q}+1D@~viJ;9Xx%=>CcL9`k@VTqJjzcDGjybW(Kj8(#$Jo5E8b~y zjY~8;p4hRX>|b8(7QEjU!4@DdevI8X>?#mGr2_pX#YIC4+B4g-inuY?TC=QnG>qIW z79p`QEDO72eJ&!}H+O43f8$vf7v<2_Gr3!p<^7A*QcSZEd|a}z=l2~R?KqGQx`G$B z1WeR|?Y38#;u+zV>8vbN2-;}SxO5Wfvwa74I5d;bR;8(LX`AZ+V|?X!Ges(&#Ir)x z<{)qH8NnD8ns7Q<;w_16MWY?oAwOfh1OkIRVO9Nwk`eb#tZt_3RC_nLgWZz5(<80K430LXoJI}U1 zC%ZKx)5Ad&(j9u7kt)LCx0l}66g^qF!&ZR2KD|JLg9LW~18t3;KMooZbxj;0#X-Nv zH+L=m25i@7%O$lHTw7_H>O$TOEGJn@}H_=LN6|0vyY%$R)CLQtOt+0!2m>l74O^t4mwWi_Nmmcb+6y;POmXEZG_UHj0ZC3YLt{vFimBj}7q68GW4 z^nQ6W_g5{8c7Z(+{AKf|X&UE`1iettE4Y2jfb@U_v!7O!NHS&T(z~=jFrWX%CeGjN z6!tD1yO(S>#tnlt#X(1w1xOxPmZ;2mX?h4F?k6hEomzAmO|-Dp2+eA~O(Va2yQ^R# zS>XBbyIU>#6;Gbm$3)prB*MSUrn)%Fts(7sDN^li3$2y!Tt)AfbaOtq<3_1^ue^UI z`-(#Em1n#)n**L?=4T?j85J};em@iiW~2K{WN`Xh3h9@qYe*_AQ}5AeEufKO_%?q^ zc|09#jGupu+(q${4)-&>9V;ANx#_c}8@0x^;#0fmRsr13_J21uT#*Q^Dy!pZ* zZQqp$@tGwrJ^uo#n%ZZlUU*EjQwxS2?r)uz*~g4s@_G6(iu3XfHNi_B9=D;xKqfTN zt?~oF!0qP+0rQ?ia&j!#RQCtfwvE~iqVAyeF4Xz?MU2hy9d;`;o*zxI=BMDFDhu)5 z%EEGnQoqq4i|2jDEgA-Ob#fj)pw5wU)`W(yCemE}f=2SIT{g!IiT4c0s8WdmNgy$IJO$Udtx8 zpYlc)J)3)K1PcTzv9f5CVa;#eGpzZtm?Zko<-WKZoF7ax}60qZUqJoy7Ob^hi{GbEFo`JKV8nN zyR51Tn>0H>lkK=!n>Nz;&Zs8W3CoXET|j}!!i(HL@DO}L44v`3$E)E&zvpKdvd|Zq zj4dNFq%7=CV=A!+wGbyW#N;W=)0K7n(-Q5y!h$yiJV|oYcp~i|B%jYPa1qv=Ck{gm zoP@RaWVNIQssxmpKC*!*f*lxHj$WI1%aUk7re)*SjWyOr4}_SH-;K&f`dI4uof00+ z?IO(#i#05Rv*Zi)^C(ReV(RZ0B&Hav1_T~FtaZWuz9(CE5)Go{k{3F8@<`EgNfnKC zP4+^L&{fhtDOQ)732LK*Ci!*O+R4S$eAyHV8pZRw3hi5Tf7nNYH4k_-EhrpV36|GF z_GAJ-rzQ8Qi8pEIRxqgH$(cbcD=?4Ghd;NM@<2E4`Qv2z&+ifaeLkEjZJ6aECxIC> zRwL?&t0Peec30b(s&(3?kzu=2&(29?Wa3g|KoydNXyVu-^1>FL*#3Sd>@vM%h`BFR>hse3LDn ztW0sgBg(&|pW$j+!(I*Zf^7`kfQ08t@hWi!YAQMXYSql-qS3_Ro>nJkZk>#&C@$4b zC(36sVfneqEQyIWE5kP^S?)bp5{@So8F4v=tQ^?DKp{t*kZbhE^w z`%n)MQPhrcS4;){2Cz(YO;<`Z6`p=DSZ=e(k!Gq3<(#c&ydsz9E6$vwbRyc!f^`-_ zAAXh{^s)hOR$Jqit87q@SAIcTdL^W(m=2>tj$Fa4M1xt9%DJAmXiI*goM9?+o5D(I ziw~fS?~pnu_gBk1ggEt}Q96b~b3EutC9C#Iz6`_p0hSXc0r5FG^6j$6Sx#JlhdnYg zwc=AUjK?N$>h+Iz(N$LW z?=M{_`LK|qg=w!DI78ymSSzcTogb2#V8Kk^zH&Ri!z4!i@tZd)iRY!Vq!sU%o+sT) zRwbz2;Tp|_nG-oMM>(^I)eo=hF_C^1fbE%sD`Ajvr!5;U&4pGq<@30UKFeyWb{;Sa zGwby{Rv;jCE-C+DuZPw!|oV z$sGz++ia9n)Hdzh0xIpM%y(!sG`4mx$wF^uRT!L)bLGg%y3gUR;(TZS+2{j-u@*N3 z6GzQ-C`s^pdvU7*M~RtbB!MLnYz>;9NKQyPLf9HSXP$H}$!!1Ut-<5ho@~7*D7dry zOTT7Pus4SyAV&`C_OTVABv%_rYVwT-`tF&EWmtLfwRijdRRL1&YSZqks zJ1J}Xu_9-%-FUHf5mj_yQ7XBWRxH;-OUJX}e#1MLgPUdg<7onIt9Og-cXVug#p4wb zSS(H9MQ*RkUB>4n*vnL;yD}?Uc&4-9$^64u>$&XA?W&h{^F#>2EM%D>n9`9CP`#r~wc#BuOI&L!=0C9XXLy6%4I*TV z(Of*1^(0t@bj7!KjtTaqcU52`!Q4RhqBzriR%$R*DThvgFn`f`}-nw$pJ7 zrgv}tQ04xvV&QRCoudQ$F~$kzk%EHUjOXodRW!HMgoS0wg*VjnXa&nR$@9Au?J-Qi zZ_8X*Wo-mF>#MQ5$)*BVLg4*xLKeC5rf`s9a}+PS|KfB^WL)_83?~AmB_Gt{4ii%d zRF+oB=;x_=K6`&=>%oH$Jq!XQ6e|RPuaW_N6EMnV9CLX5r3vu0eA_#_Y+G9!<~h>}cu;-)?LX?!bwR(L@#46COn zSQd+T?wc{j(%Y10z7Q*$dq8F47BkvJeK1Vj%rGG-t%W-2h=yT+igzK?^*pE6&e4vY z>0eYo`8I8YHLZW%{J^Ky)86BS`SV_`yYl(pA*s3I%PymLkQ|W@em%f7w{7HF0Zl-R zx9LOMOnOm2P}==DG6)A%JtUjmv2bj79^&YdVS+Cdlf1&TEy_>*e)oC{!bUO1>N+(8e^M&^o~ zn8mx(Bmo1|4H+CnpZ-yKGJU{(s=`=%tLibS{>7_xZH9F34re;YM{&(?nDst>80eE0 ztYXz6E_+d=QO@}Zg?vCTC9n`P{Agd~L&x-+-gFzxv&kK~3&S5=d5)o$EwUZ=(!fo} zQw(UT6l&zO{mYF;ZcQ0DOmw_eQZeGTpS>Sf(mQON5E^_U;wCT|=y&z?W8wr|7tgur zl-Tospz3Jqa2+{xvTu>LJ)?G0+L#<#T3WE!=dFtT`SbUpM|J#;OC^QC70xBpi1Rim zb9Aby765@Un+dvj8QC`OAq5DG;P?5M1o>DKZGFJjJ|F0tu>_NN+w*Sk06 zr^DA1M62T>)r3}R6Xua$gFP|UXve)n6fCAT{6BjQ^J z*7uRC%fLhFcncf{LX4^lU3ceYgj-Mx8)=iIPB#R~=j0qd8uL0;PC8A{F0e{nT8>7& zFZS;7lpx7qs@(^jQkxD4ccT5mg?k5>I-RfC9d4uH%zh?yoW`_@^ZCKP%S6G(L^1lm z-`dT0LKj^xR~v4GgGvUUA*Tjk;-HDfz)rs%cXHs1Y*u=+bq6r+E=$U;>3UMaKV`a& zQ8;Mo5yvuHB#;2buol$vr{(aDo0o!?7m;;c{nZ$?ao|rYU^8-OWisXXALYl;f8PD? z?{R!5Mlu!*8oFsO;2>b^VkkJ7J~mG$V;?y)HvYciXo<4w-IfKG_KKd2S3#AFcj})d zOG}a`mkD2*e&_vuBpxtVFI1_=Y!{O0OxJS{2?u*4`;My}5&kdE2sl)bJy4Vk?L1xH z-l4jgo4G$s%Tk1`k=*>$`KQ-{sd^9LcR4-?;2AWSkVCKB6c)x`U@y6a3`O0EaJ#!Q zF)32pQfTF!yzH2ClOjBd@4Q$5@Is4bICQb;ZJCHvM)rwwTAEb%NLRo_M{^EilUm&O z)vuV;MqKf^#GyBL_*JX0MdlS2db&6BX{9eeSiRWJ8fMD;$oa`TL&M#I@2+-^$LMwf zWog%{fHgG%J{j^0v=|dpH)pKDG6!WE%0xway5L0;v(iMH9-n$hhmLTb1;bs{-BH`~ z%z2!`!a~>?17Oo1un!tL!EFA7hXp^c@r0#aihRw9dT?+|cVHr_zq)8vm$snezP#j5l)(th$->YPQ%2&r- z7u9_PH9yc1f`fdBI=hx%6ayhTYGR&$PHRak?BIyGOY6Z_=S0>MBi+7n!D+#9{9aGO z;v!*ACh?I6P7HlaW~RS}_ZceEikgZQ?c-6!6cx}MnI-FKtWOB(mbS1KU+HN(b&D~< zr&rq0n!Lxbb#ABF1^?dsKnEk1YgS1CRfk0q9$pyW!JJM8jH-UU*AC)QtE;lzWK~Tr zzf^hK;@zef0v>kzavai{+M1VAa$K)iAL>U?we#=U?(@XkywX>h`Cg(g75(jlvM`&Z ztqcGmdYY39^6;6{Kzk}jMT40ZV$<_<*>jN6-fC(8*x1sFuhQX&*6gEEN91d1m{{c$ zwWS#ms{S#{H;+j(`Edn!^Qs32c;BrCLqv<01${oig&XjR+*SFlc0i}Rn0@9U?BJX$(RMXCT{E0Y32Q{t^@Q5e(5d+ zwD-J1u1pHuQ4?o9BdOLbmnFuUm{wLn;s0CFty=S&-dlx8U2eMfqtk`i*_9j!tMp;2v}fa)ItjWWSmEoo$J%l02GpA$rY1_gSk@BUnd~{ zCNFU_yt^9rVm0=*2faPrtJLVAsfo!T?N^S~Ffn<)zL;U%$g*DBda9A30GU|N<^I;p zp17F6rbGT#ZHD#@Fp2$l zmqYSTWS(+q_vL@wP;17YtD=2(+M^_=NP(WUH(jBE9Kk-x>1si0|>Fj@_GQ<{j zf`cz7F4UoI+71Jfi{#vW#8B)E(}m*pVU7_4(N zGn_V`i?@ZNTT>m0hWea?q6i7I|ncZa3M=iV8HUraq$}FU5f`@U_smFIUUM| zwh+3b>Td4M%U+&u_{Z9t-6AOXs3HeDsq$|h-5J&KQh(&&R^G;j260)i2R69M&5LAE zQz?|o?&+mn7-<|t3w&NnE&V{pE$}Mw+H_y0MZSh3$IJAHMW^ZJDY01W2Y}{=F1*lC z;aJdQTFDo+M)q`lYQjzn6ZQ^*nbz+dI#w@82&@E&zNf^fV}Xsb%SRM1RQ)0W#jFVx zd}VkN!Y5p#yC+IC8}vm=NR6uDVXw3E$;mc z=WLUj3?@TpMIN*k=&>G-e7{$|3CTmq>o{nqp!5;hV>`|#cyJ<^H2ayEG=iTTN-G(u zO3ul=mi~G_e~P6Szc>$N6SFY}%z&Xf{4EVrvq-5veZH5@+;KqEN_k=|_-)DfT=7R% z*4Pq-Mwo!^R9hPpwXpkzozXMWPRG>B3?}X2~QsgA+$`Vn%T_DE9B1;$0&A$6}PmcHc>cNJX{QnTD-O#x|nX~ zn%Zd>Z25oKd+(?wv$kCv$5BQ_85K}KU<3haBGROfA|N0ly$MlzM|vj;3Q83aqzDlZ zLhleDl8E#U(g^|SErbpU3GwW>zIWEln)f?jnfcz|S?72DVX?Bp!}ILt-gmj~>%KPs z)#9YtTbN6#+Kddxm}OP3@a?05fAiG;f2bt>9x0;$b7=a0PrE{r=Jrh@$WS8Do6f~! zwY@vc{V@!|#zzLRS|)Lg=H&zgJr|UI%0DHbc=18Y3bESc>X8cojR^d`2m5ymvp?`+ zAu0+4W#R3krhpt!-%hSWOu9))DkxbB$dqL9@h?W|>3gytbgR%>I!!qKQXt3Pf}40F z#beH*>@?m%AN@1d2rGaneDX$6)XpHo4nR@>t zVmtu4GAZ6<4;(a-gVU?fKdXquK`+GcMR9M#nJpXkj9mkXmbkB384S^YoDJ$Sc4TO{BMOsmAJsU(R;74LN25vxTFmqA zn#_~w`Q#t87t56OGJ9q^WotgBNFPrD(@Xg>?k@;R0WqVjp)@n>f?o+yMx14*hQg}9ni&}(O{Jsd; zQu;p_Qi1c51zCyF(|!WelqtgLGH(Wj<%szNeSs%l*CfJidlVhWUSng^uM^>yE$x;} z%DpKkQ(09$+0yKHUa^3lq61+n2m+Pi4URAcHqPd6G#5UvJFkyR zX^`%=u`BEtl-j43l8lYSkN&*5J2}+8M8E8-#>@Sb8r19lVO;t)+u@+Ta3zDE9U$PK zM+yURuB)u5eFZ{{JZL=((jHC}9`vVT>tqtqqWZmwL#UJ*?AFg0Wg|JToc58Y2swP>VDyo3itgRpQY=@xV9?DT3 z0)WGLiZbARCbxI;;Is3eFz|l`{o}9eFRP+AGC0zXepT73Ceorej7q*9mSB>~HZj?j zp|;a)Dkzd!7dL)Iue8s1kLgQrKenj>@pJYM#Mgfsp8vEo)DH@d zQS>1RxG}4bx9b_6UfGpPWfxkB2`Y@-hMlAD2LSA>$Q3GLQwmPXH{?ImLB8H z`8TQzM)t-=9U`w(KqN+CWL#XoB0{mB@Ytfnj9#a-ffvnqIpn*R`w4~1$_k87Sy zY#ma*=P4$2DG+Gtb8c+ba8Z*LcnL^b{x0YB?^{toEOgqCV~+%hMH6BuGGKJ!^%y(Y zC?mALcMji4CX)bZjzj$jol(GX93CEKP}c|rocnMtV1H_oJc58jYep}Z9M1TEzi+`m z6b9?Cjh8MYe&{<6Ldl^&uvI1~c)&mox!)lxzuC7Tq+60$OtzxvrqRZ(MdNz37yap_ z6l3Ab&Y_>@bC*f9h<&9SDlFQwc5}vgPfR4w>u8-{sM!9rcSK`UUlPnkM z;#8-f%a#cCUMT@%FXq1wUoP{2#9c=*+nqrJa=t$0bD`l>SzCZRVQ=iDhPM8YhR&;= z{c8s;fuD5f#7?M2Vs<=BY0rxh!_C{wV<8{|eJ=^Df@)p)T@+Wy9$q09LIhC#{=sfc zeYBi~_v9iN#$24>IC%Pv2AKde7WGFw)c7rpr2Zj1trl`z;K^6FgxiW5QC%~uD?h5S z>l|bAU_AG7u>APzR_4+xKS1SozjUKKs?cS%iKt8NTr94cr93d{Gl?i1=-X!$kh|@ZyC-5Mw1lrJ!Lz6Stp?m5V4l4m+FG%yb!gl_;!XZsHpr+f%A1VT> z-`pOAqUDVyaYs4c|5^&0nG8FlNL2aALF4A46Y{{ad>@Jz{s2;LkREOHU3n##05J3~Tr44*sN}>k)N#`%3JG z!cDb2u(>k;>GL5p9ewz>kVF;e6-e*vsZQ$PSSxWA z43p3So9-gZg8oA=)i6@j)M#doZ zZ1*ESG-<<*s7ALtc|_?w*Tn=SV>@*X!O~Y<_{RnRGc5Ij5%LvD$^-_uh|Nbbm~S-R zNocU3j)%Z;{Z@VN|Kp0kuaN&mmAe-`L5XP*<8Lv4p*wk>XS!i+iNB7%WI88RD)D_& zvlhSCCH&?s?m#7Jbxt_9ZXB&Vh=m7&(CqXAAhY#$1jtY^JM~g(skc70Y?J?uW^o?a zGbPl-9SBiTGfYK1^v%@8Jxwe$fTFx3-%n!kC@7+A@9je#$@e5`ZhMMDn!Qi+Vg}ID zlO0fMl+`0nar7dI3ISdj?RqXT>DaTi0|F1@>_XqQ zQ{p-U4VpqtTX*ttD1dC7-kzl}CEvOxAYS&3=Iw>ni4Rh0b$)dhWftcm8GgQYc|OPR z0&k_Ci=)+6>72vm6o8S##gp%zosPkaxMzJ-2LU_^!WpFI-P>t4G7&htrC#M7=DJtC z8hggVXI(b7xQJwErk~k3V>_c3pg)1}$q?mc5@yp>kIr~WSpND-5Cxw4$KQu>6>p+X zz-fHUg3=bUNM6t*QQG3|q|}w7N&gmmz7@bc(%-GVk(q{wv2;%6vdxM(k8s_lrxT*i z^Q&tp9ua4JPyj4%?>zyrS(1-pC;P4lM+R~|ryLnN6fWOP6?M>R-&=zivHcPU7pkeK zVyN7CZ7Hd|)-$AM)+_xj-GBu51KcwzlV1obsOr4s`{FazdFZGWP`q2b~ zjgfMc-QGN{8Lo!6*(tz5$5Mu)6rSn#?piY@PWI_w58a#15gWHq+A!7_BPQe826OFn z{#Vl@+EW!leeN6|14fQFRB$O(D=T8LjD=qP=iJmM&*uBKcS}SA4J4+>3i(mhbj6UVgzDd^J;T z7vp?u?wax5NTLKqXWm4Z*72!sd@}dzXT^5uArH%c7H6TM(fu_yKfekWR5Qj_TQ13K zvZst`!DADUuH`co1iC_HW8-lnwK{2OF;521O3$+&28XVH^kk?y`=LzwZg?a1(l))Y z;9g-Ph5J8YyUtNi{I0-fqA=G(c9l;;WG`9|h#X zF0N&F*DIZSiqo`Bsj8jPc69Jiyqo3}|5FdSA9~)`(R{u;TSV`_dP({Z?&V+5ul-95 z_rB9x@pIQ&3CWwSNXk90JDuzuOOrshBq1#XpP7~0sZ>=uWW+Crj7qmmIOE_xXCB6O zJB2N~F#i>!QPOvGFmKYd9TjxPTft#}#Ci@Lv3J33k7omiU5f(`4 zvwiBXyYWJeu{lkTMHoaXINOcl+Vz#_)b1XeI0ewbRXi^l6~y~Uo-W`jp?_1-`LHn7 z1FpMFCF;0b6-p~bzdPpwPtH?fV@r0r`dX%yEXGi4xLkquV-{2zZD9BC~_GRX?v zyQ}pjJd7(okLPAnS0ETEi~fCtDG{ZduO)v9+ageG*hGthde3LrDtSUYzRVCKc05x3^2>LA?_34@dWxvG_kc?eG1{ z_s9QN!ZH8UyZxzT>`x_xZLH53^q{uJ(QK6KyC@)=A?$hgOSl>X!>C5tvz)|>TgXO# zXa1<0McEY_!5-q`yKyQ%`*MXUaNp@`1ariYhp@Q@^1C_sJ3HK>i*9;nrDZQw|%WHt{B}-FV9ph$k*e3r$}43Z@~BaWTLQl zkrB*>%@V=SH!$O)fpD)@V0N66x7A`KKKEPaj0CHg3-a=oybAe?s?b$|A#*fDn)m){%ygZY4=>-F$)g*l88%>K@IU#w_=S=1* zop%IVBm~)mKUrgEpzv{@`}QyGfJCaN!En2P%g{nM3feuOqjKr&5r(_R{MJUQ(=l#S zRRQqF9RXD?>OL)bR*z6ZO--lW?|nLbe~{+PPtUY$^J$e?r|LL%srJO_&rvL);_MjJ zK71Hky@^CvIZrs&6jF`~oJ~xuPSh@rj*eneVsm1{W#9j{W}wl zofu(p95UwGHWQX@vfGMu4#OIO8OOe)`W-0QcL=KK@Xy_PgmdbSbn}`+-bjA-bs2q zvEE;#KF}2Y%De5Y+gT?!C1VM31r7IKf9QD6M*nL??zN}a<8H1hP9C(L`R!%>3!M62 zV$u)4;n=7E`j5kqiw728<$JmWWm4yIX6_HJ0iH&AmDr)wkZ-tAbs`t9a&)AvH^RR8 zw3Td__UgC}cd@e^@LLtX_gmGVn0}rU!2ONJx{;WR3+kTmi9xSwh9ZODa}s{`FJ+U6 zq;sLgmuS^yejJB1B;`yoAE{Y(rm@6`p8j=|1E3%k)V%Z$VR7>CZ>2?5)FTwH|h56nQ;E%H8mt*W7s7UE)+&-a7`XQTVjQ4@%HPI62;>!PEr z*P=NB!j97H?{llabCT(=F(`{*-wVFq<$8beh9m74D2&g((YRC*S-(%E&Y~&A(^PtQ z(UZV`%Q>kY{_hY;_}@ng&bYXIRDMcmXi8>vU3DglnzZy?%e?%8{Jhx5@SGg@3p2YF z-sI1mzX*2yN)u1L!PIXwiIQaQ_{G*9{;ms;yeSvBH!5a}?hNY1)o2!V7J!o{?=3++tNh>V#tplB-`QtB<%En*C@`+#xL_xnHl14c$I zHJ5@2Lz@Lv^7?x@7xL;-Pr6CHd&TG*P;Z#XR$nQxbEBDE#T_3I>8f^Bgy9FhO9I_m zq91;~65oEwsW>csg5=)KzU;09;i>#_;CJrZ_2a{T)H>4)Gsk(59{KRlnheZOXIw=GhU5-34UhfW6PI% z`)zD?it%v0*X%gNUdmydUAJl;1$i#saB@VF``5%3Kdlb|aSSXkGk+{peX7pnCC+|0 z2>XNi-A!*@jf%yja=Ce;EuB6(uZ@`?Sg#2vJnd+*$}Y-&Q;?OFrJ|)`qN2s3p`mlC zRZCrqMg9DTmxXfulGnHPI=lU^&31llMyPmKn6_vezSA?(#PN6hYUz17_Nmq7r(CKr z3&P|&N%Ut^y!%DhIBfkfq??XPnfKu9SN5e<+OO;{Sgu>cU-2#Nv$08wz;jQr$?KbY)dP3|BK(RzqF(&WK~XruT?~S+dpAL4{OJK65nVQULSg+O8UU6%D(fzkDiRe+ z*ywJ3*jEUWHI$l7Hv>O8|{HVM{SF+5XD$$+WqSG*TjpwcC=J+qber zz#cgsPQ47^*%~9AFIi~E73YtUBG|-N_!iEBCfCIE4=I+>LLF!O*^H=;s^SmKhTjK< z-vFCFUJ4_WoPtu`AL+OcBPMJN%&uE`CqkLXwzR|}VXoz&>%jL(|9n3hqBR4869N5&K(5?%OARM>cUSs}Odl0My^hI+w;mAA@U zHC=%->!VT`jltr7Mo?%1#)&T5nzPnBgyv1iNB>1Tr;>=iwE)WO%4GcnYvb9l3H9;A zSBWk*E9xo3QMR`LNSn4I%eu`)!B#s$DypN zfWnYX2AExvO1tL5^yFb}AIE9=JNxv8Hr1NS{f`lgX1hU)6C@K}qu>>`te0InTGk?O zMEeIdB0ID?HE$H0zf@M9PVIN)x=@(ai8av4+8_vM8^lab9Xfo+NT=VRQ^O8d--4G# zd3m_@jb`|J>G{vUJw!`9wM%d7A-oksFdYo+FZDJs*bC|$lNpcj!pW_L6=Fzm=V1e{ z{m1i5%jE<=!gOIq3j9KBa0cTbQ@GXR26hlr5Y!jp@EEj6a|mNoQ~c1x`?Q59Nss-< z-q6Rlw!-oecQB$w5pZx6p28kb@4v_3 zpWi9^zw}&x%eSrJ6jf+3mbQIg^UnzC7D5NvObAEZ|yeg}TYRrmh z_UOfqj?XWz==vS_sNFoS=a36<`elk3*iKvr3P*KrB@*4YWy)o)3I}HvSb1D)`Q&+D ziuYy9dQ9FVX|km9hHv3Rd|~;=i;;5bcbb$puF4xgqA>M`cTUk2$`n*M7TxQD6CMfmF{8Vcu??w{zBOEr^7C12nw<)Dx;ZV%+PPFTSw)fR zT7ui1+72U5^~rlSiGj)UZ^rgK&bypH=76kzaHZxoeeWGUZO)hHem{R zUMv17#r(gmc>Gs%%l@9pjX%AL{~JFT@`Z{=C45Al|Edsx!=uMdQUjfFtq0dAXRExt zXa#Eb*>wm|_uXM_G{KAhgsN$LG3k;O-H@nHrVGQ*AEPXlxh!HH&`w5JPfCT17WS4GQdnWCgqtXeb*??~}M8H=yh1P#Vys&@}~0GjM~@!YL$3IMiz6Df4g9 zyICdBKV1u?5C30Z3cgmfA+QjQn@D0SQ{8kyi-?spy&OnvuwN7ur}%#0-@x)8Fx9*iZ|mKC{n3VLw6=9;@GQvJtncw&_{G~&$ zzrQ~#H>)TsH;N}G@5O9xc5W2+t1ox-*_Tq2eEqE!>fgG~Pnu)0kYmNOe1iA+3*mc= zR=?bke%cZE*V zn;rk?=(LLigU6y_0-DSzKgV$^$;mw{d1y&$IGmC!v6d_;sNB3pJcqw6RD8EUxdpyl zY)fOLdo*K-$@5s>@pCHdD{Op!lu}+Dv6T87l|%mr^yL2pSO32cerpT#)l$+#a+UJ7#eRTy?QE}O1^=+Qek=WcpECXPZ~RZlbpJnV`m;6tk7NP= z@4(dm5;F3J*xMk$TrP2hV9W ze?oZYDVD$}E`Cmh?&p>sT>b|DmOqVtO^n$*KR0Y36->Zx!DpduvXi5&1M`S$tRG}r z3;iJih%&tdp6Gbqcda`Hz^xK#eRo0FP%xobcn+8;x$M*riA{$KNrZ-1R0 z_IK{|UxnLa;_J_DtmjC^vt4%#5}eOIpNXc^r2GJAbAKwti3SIhK- zQA#`0NkPxka!OVYyO?f{PELYzMKrhkDNNIquB@p7&j|h-NbY)xZbseL7D!&S|0xno z-u|ZLX4O45)AH-YgK&P9BJSlmm>c)4S8qBsPOU@*j?{4{0qq~}?(u*$F=YHSAjCQr zvl*sz(DA4vBq;Yi%E||<3ii_%vOheU(jL_LLE*djgW3KT;C;S$LS`pE`?$BLMUESj zDtUegt8>WRAo)un_q}8Sc9b1N^g+KtL(yP7cDnk7b!&b}E+VSJC;XwV^k@0Is5F3g zIE6>YakjGxWaZaMU$^vl#B5}wN>_Ng;SxA~!v8xx=|6Vp|MVLXt(`ra`2Y@+nfpf5 zuEvJc{3w8u3-HDlZ)T0_`SM*KL}nJ`)nVM$#{-c%Z$o3aB=}*H5;Qt;YC1iAg4s>Z z2C4uONKtqV-)_c2dRz`udez6d|u%3WMpyye@U*?an z@eG}7TI;D89b4fL)I(bM@3Wa6pUZ+{85qNVDaiOdBl=|)ZuGv0WS?vN4xpvQ)&Qw~ zQA6%2=v0^JBsgtG90}&Xb8)S|M#jK|it{>&JI`&GE@@aJbIJgw`KIKiP% zHk6yt&y#m*yPO5)dmHAnFcnoSR)~>SvsS+e)b%3_o&yhdT`V7HYcDYA+a!twV(*y$ z#KoiC0!|=Ub)R~nAVU!VnmWa)@7EPx9TvU7b-xwtpRL$=P)I16E=631tA$5pkIE=q zc|*j)Yx1;q1wGIHWdC(QM^#AaN~|X6y+4E|X&$~7?g5fi^l?+91<4YC3sv3*rO$s! zCh2<;zzgdVK**@PN1X_0#8cukqmc;d_*ombJzi5K2|m%XTS%|y&pkHR$M~MOwF(;L zZZdkP>km3dC*0;Z&qsF)JkmluIZGi8v28zv?gCSQ3r$#<5Hc0H=j}_5Tj{A2cd8zL<@9IAJIb|_Wm zf<`~q1&jXWmxk#%oXcx$Nky5=l;@)NI}a@=ThXX)YBk*uufCIHTQXAwTbQx$G0r9d zo1#2}Jg6tW$ON2zwj{Lvya;15kW~luUh8^eeJT2=hi6V_@3g>-m8ETgtIT$~}*mb5U_pN|wes6-}jQ zV0=(rtAXV|c9vT=;2pc!u9=*T*_>9E&anRq&m>9b_I3de zqrOPLeS4)O7{UXHl_M=Z9b+=7;s)dfe|2w9iJqyOk?EW<$3{}aoUNtbI$Q8!b$x$G z@EnwhP?)%Q;9+ll{GAe4eRCMtW(5PpWB`Sxqke#1D{h{sr;lh|cXvbh=%$Z7JmEii4VIT=*GBm>2XN_@~#@5IRFk3LADr|N#%M)SllQ$Z@)d~UZvnBXXePCElV>aDRA zzxyKu#VOVcPMumBmx%SRMoF|4Zg2Wj7Z}BPkEFKjI-WZ$JNr7~p|O&Ud|Y_Be~D-1 zRD_y&m>yX&dq5O8;GLi4ft#jwvdhY4 z@U)f^slBWr(62k#%6bz>YmpY$yMz!M^fR_nN5g)4t@qqcIwr#!)wNK7zLkt!O@;x zF@}9L$mSlA$y!mpUq~vko$+?kAHZNV8Tn5Z<_ts#v+OB8#H?8k z9Z*kgGI1k=QG^$EWFI18t1**u)yd@*TW`4}z3+OsM$9X0^5J^f)=fu7JySL(^AXFd zWqn1S8qz{%waZ?QJf_}61mzKVgwVLb3wM)S+d@`Xf1}ay#4=hMrm%Enj#yTt!k-K_ z$Z4>TjQJa!QjeWTMY`z?eCg!>@<6-yipQq9EK1rZJ3$VJv1HYur=8Ik_a-eaD*?HI zX$}vd9GPhM=tH*`)W#7Xa}O4t{}T!i<3Q|9`REPw4eIz>J@1{(y=-B0`BfU(Y!z#{ z)JrglX<-{m%V-UFNzj?VioPgFx}{a)*ID5O^KXsZl3ivqbrzMZI=GEeyZH1~j@akS z3_VyYU14}RFna{Lc|8HjA#bxYIljIgnU+;ea>+*+q+AM`$5h-ee=vV_m@5{8i8=i` zI7X@pq0HOMfwgcG8yu>fxnmP4kR=HyLBhm*sOV%lMOTh>D2<3Qq4#jXW{oLuN~rv* z$u!h%zFB3W?=)K}bKbYJ{)W&S6}1U@dgc*5PJ17fbme5RKzd-iAf7B(knt!W*1(T* zW{Q|&BKA0=MzA$v6RE0a0eP^A9h> za25rAzOi6cON8gCJw(S=alhc4%ow@yY9XGpKpUy7dQDHXQJlw}_Enq3CWD?xTLJ?kDLB1c*i;fcVpS`M zmtD}$;IPpJTGN4dn(8y*Al9K?n0ogIau3P`dckx&*7bISh9COR7&v)OnXL&W zAVwIkxZWl-H#!w6i(V30XSkZf!4a8%wdyG-M~B=44k>r1IuXP$$I}f6e}nfD*P3y4 z<17tTlwWswhCeyVe;qff)k}%tlYkz(rNl&N8PF9KopIlsEBkW7(lVNF%mxGjl=~DN zGHXtl%*#RSwf0M`+CO&3|CGa?GAmsE-Yl?ZPxhWQ&6reF0c!##tpX^-i6IJ`oC4O^ z@eNXZrmDPe*#yg4bxaw6w+U2)CW(H4(NJ7eK`lgOflPMB~P(SARQ@M;v&r89S-4d41{*Wdvd=xAj}6i<*EpNKzvv$IfA(S2N!HM(Wi zuAo8+w`aqp!zg}6IygP2t~%#V_)lr0fQY>^Ceun`THhRSz#C7vw8n%4R!#Uj$JH)B zp1{H|7>i7+b{)k9m3E5_L$;_%JppwselDGC-O7Q=bM}chujo+Cw${UjEHpBkzC1DL z(;Le{i?qn`!s^*zI_so65!EC9s!{M*&a;*R8%FhEUl^Sk_gS5fDn|X5 zEVJ7z9F~_0Hg{uHkKGf|V0{m$Q?}lB`#;1coMlYIj`DL}73}J2I;Qu-TsjSS-NU6E zz;A+c^g4BBn6`U&U5t4j1vKDH5k^{(U4tI4F>kO+;hhf#Q~b!LnofAZN(SGKmx5}& zh_bP9TC1x=S3iNX5r(LZ`RONEK8gF$f?%AGv?l1xym0DuN#lOcK#%3J9nM9Fod;1Y zu`A@!Q22wK(~Z|IB@rB8^qrq#qR=Z$41|jLnmCYyaFNx6_>_lE_aR)H`!%j&slrvW z&3&!&#T}3A>~17u;i$4otpe2t1i@l8K|`n|B3p9aA-#eu?H&50g|>ZCgiMlD|)`FigMFi%pY34HL&j`Y2^{b$}M-T zJN}UT#wBr#)q=SWM(Sz7v%D`1BjZcJes_9_kIho$;^!2QL6+*?d0>>B{PJY}v3A)b zRHtu-0^>rTE1-$6rohFt6-trD;r4}6FRaIC7uH1;>YXPIy%6^ykTGc+gN)#2JU*9l zqftqDqIJ==u%U10%1a$!y?Rw(==?>a$H%dghTG82#YzzZ{B`*FghAliy_VbQLV}84 zX88{=$25$1N{_!Scxo75@O=e;p%`=Y>U^c$zMq>nE_VvGjS)bKjE>zPvOmQ?G?TH} z^BAo&G&UxqhGW>0Cs<8_%w1m`<_CtQg!05oi7@F1CT+X!M*fIP({ z%~W%IN{Hlrex&AO(~yUWu)X%cApTk_&avpEPL-MPW5;{9b#2_c?>O)^TNy^nI*aKx z?N*8Pw^4RGs%lB^ zf!Vpur=2XrgAY@gOdwzxZo9M!6O5-CoepbUeH7x*jHH6uqT_0|%kW87QO~b3`wm~( zZ>JQv_cc6QIh=F7UR=H&)i{@rXAly#=LQZQ1B7{G3i41&o}sZOyNF&sT!WgX>a^?d$9krBkGHErWe#QzWS;1b(N8`~}Dj`t2{# zjsFL#$`XQpZwviv4i;!~i7`~9K0zhLtbXm1rj})OnAPl3l$mIW|7wO^S@Y@CotK!K?sln%QAhP4CojM$x(7DcSy^tOqGEKwg<<;d+(oDLn;{WijqT{5;zW&LnnZ;$Bow}UVeOZp?*De|Q%90sR&B30lVraWWym z4m1l$B{kd7Pd)*Da(?wAb;FAkru`aGe@z849HBqnKKxjceY`86W#S@TkGwU!&0N&S ze(ELjCH?!M9=o@UZkcLaD!VyvdW7r`tf~ok2v_Lqsiq?A#{MJnJ`p)6<2|?TPlh>; zm^*!>^|LUaBC%TR9^Rkr(*AlwoK?UT`ZFeV#M?`kAp%y^Vg0`C?wg@EeFNDtMV1M` zC7D3Ce*#GZ2n<5#Bn9^Uo|YA=jM=Hp)Vk%p9_y@J8G{VzPCJjeQK4PNOWR+MZ#3-= z3phXaE*>gw7kpwcFqgMtX{^eY_aWFbS`Q>P3#w$abj6%a*R`z`^t{M3oKtt%LB$-j z11RbGE7(GMV=!ZQK-L-#@%B3V8Of=)SgmO|v}hxyeD{6ZV4t=i?zFgUDOl@W+oj$) z2XeObsbYzJ6Tq>23cDz|dySSuT~&T#T|Q+Mzl95IHKDs@zikrczvqRWNKW2jR*T#2 zJT0m{JMFzWpri9C_A`k5c7S$v5Sw}7%bfTv?0=+>EY-C1Lo;?B&8OSzbC90Oo8lSt_2pr8kM zg|`YF0@JN_E&=t*-a%jYiLk{hmRvW=2zLb46H>-nvSz>;ySf< zJn3cW$~Tzg4@c_yTZsoQ>{yB&bmM&*azoMC**;$ba1#Y`gE&38h3@IOJ=!z1-Vd?0 zBEia5OEu)g^cV**1#+fBf%lAUia)O%{8UxmKm!3WzMk-w91TsFYNV8Z^2B!#eEaKP zB(<8`<$BZG?|U2L@RMtD%duw%F6EerASD-Ar3@m&L?HM0O_(DXZu)tjEY)s$`5qvW zAnd9W`N6TZE^jbLMN9q9PfND0)dB6VaJnGUihS8vn&KGA%!o-jyUnSdSbE*(-jM9* zN}lZIfNqt(w9&DAzMQCZD)zRBB%{r7Q*$7soxFvCGUQB&Cy*pc=6EIuS?HCOF;_!W z^KwjVLAB+IQ$Ny{D=$1eIE$HyFiy&T`MO!jWnm*1M4TPJt7tx2L|JNDYCm zuLBDOmTL z(V?|Wasqi5@7#b%4WZX!GZU6lK_ddqpgx_6@AF?-hG*I@bE{l94FxxJVSVw|hRk%B zeE>J*5t@g@HA}0y4tj@6b(UUdc5cSh27O#|I($1iCaAnr@FAX0$*6Mc zO|0&NyK%>J62&dcs6@p9DCOL-4a^LzlhR7;jUuXSuIKshg_z^gUlxrG1{RcWU^-xq z!!{N58OQD6rx$#W;|kPK42Tp*s$9b4)J7Kl zVnH;avvfb(OD20Wu;^o*MOJ@0{Bp%XZ{|U5c>*>SD-fpoI3v~7<>UR{!d|tlN>9dt z&Zwqj@)K=-@D_L22_fV+=tRxWX|JA*9qMfI!uNUn&#N#V?(Y9z&dUs#lM zSb0xwHO_6_T%U0Z;p#IFl{tG#B8iXlR|a66tN}#I?Ws?97Oc_yI~oHnY)ED#Rh3Qj;j524qFO#xOK0R-M*ptZvcAb+*$<19fPP* zNCJf9Yk($kR#AWqP?Iu(tuMaggB?wNHI7Ebyb z1n%*ug`%YSJNU!H7o6a=wtU8cezG31?;mJI01GRZ^mmHdEr-TWxjFXq#U+|`jVpAT zl3%E7i5!+g1GPuSAj z+l<^(SgzH|72Xy3wXF_>AZlPJ(p;zj)Lb;-#Ma_$nALEAD*-!%WdM8dM@=W z6Y;a6))BQXPZg_0No5%(E9F!2oG^j=x3;i>pcx9=NJA4eU@cDToAJf+?qtep8!6Ru zKbk!?UsBGYY#6FgFn+4ruXXlWU`*~p6!LIX5r~dph zSgLV|50s~OUJ@nIqhe=`P6YW;zM#H#Lhg$F9<-Ica24Clpurr8lJUc_RaGMrISbTX z<+uaRAK#@NJVNc8_ev5spnOq{$;3;B-(I2FH{#C*}{9*`Q_(xXnNn|7D- zzMr5qAHw^^2qGhB<67JIYg8SY62#w#?GAco!q?1l3P7_d%X_PXm>LQE|51t<8JUrp z-E8UaUGgYzGD(ezC*ml;>v-eF*kCVOiEN9M^U+fz7tS|ALfLUI6}f1>3se(F!6O)< z*T^85ye_W`Nb&vD;xGz54S{xr_>qkXslyQZI(JV?3HT#&Qz6!Aj2U-aS&eRi_q~Le zPrg$tf-5iEwqUbtFK2c_tcJ)Fu4G)OEW@Y7S*dqT4p_EuOQ+PsHd_m%_uZAwD_aOhPaWGcpHSM!mcuGdt{VW&Y- zK=Im&bLXnyB#*}YNckfFW1ER2Q!n+JT;a{LB*zGaN4 zzF{#73iXKsi@j+2N!El4u`652(=o#Mr89(a-;Tl1I8=UlctA57 zcS?8;*TpEXQ-%sC=eV{Vs^o8ySJxEgp%_o*dtUwcizF7b3+`U`9Svc#fW&3vljCdi zDvBJ5ckL8DB5CdBm$%BA@H_xvD5t*{ISF7ioDR0{&Pd>|NC0_ zE_>e!suGV4sXeHukzne_;j1T;#za_4EL;kYi@L8lHAE*QbYIgs^)@FzBj0c#$}%ch zyqRC{rQQ%#3#Xv9BZi<7v(*G7Pz~I6tf%q4uS`O?wB&SsG@@#4Nf+|JrWd~AhmexT zbZY}gG%mhl3QZ4l>(d%2jAFUXb@qzcDpvcg9oY0j6njr=ZH=)_u0`Po>yABVLls>H z*JUqQ1o%wy$vUooZL!+3vT^yMJs11K%N+ZTyC33rD^In7s<6zO;sP%47WDd1s~Ed2 z7|_yw`=yFmscF`n$e6^zbD-d>q&edkAaUxW$QZe0d(7x)w7%HQwtXg^{HxDKeqBC6 zrKwC}z+{Dld_2WjfyEMET-B`SDF1nk+1?a3DJPZKrWD`l*|M3JDZX>A---*K#TsFW z&%ZjC+c^K@&w-ypeXd0F=Nl(wfla8_OL(|=_yrV|!ZtuHjCwSo37GNXd{;|qhLObsJ_8ar&!dk9b3{C)jK?<#zUep^fOdM zmzkcR!*<%#lHER%!-l-kG4o-on`3;Wd*l%FJTCC;-B-b=U=AaI4B(i&fCA z%M{~4Y$UONYsz8=)l77#mE?w4I~Fy*Y`_a)w=M+W$8SQPcY}jkdoa76RZc9>PX--(3CL`ov3v#W%Bc!Qa2i%lp1)4GU-CTiQyA zbuXELuw4RbkNL{443&;eC3X9Es-Xmfux-ftcz7K>7^UsZb7S|)&3l4j@VyNj17Pp~3W3ewUed;=T; zZfxtDDk3!!^3Z&DQ^nX%{Z3tr5S?9IRiG!5lex>$%_-7}F7|N4&i?TiyrFn6$p6(e z3ECG9YXuh36fO!1Xc|uqQB$`Z7s8#;qimWRum$#|R~M}+IQU#Io*bi(QJk%w(s2@u z7Gmmu<*A}mS8xJZKK3FwO{spQ4od~*?i?kSK{18sWE;v=+O8N1tyv2dTup*(glQ5} zU|s6pi@a8j!zB`wYBd`HPq9*RQGJJF^-p4Ex^R>%T-3nJ_=jaa;7B0r1-C)^xo5K} za*Vn!J-GzvbAS2H_;_8i#YnM|J4?fn;d!TidDIVPluW>X`loe; zhYxgGz{H(3grdUn^OncePQ8!rQ&+s%t&;5qRpYXWQW%mluOi*qyDQg8#<4B}>fD1* z8-4&}BhS)BkZ}J-UYV}~t!(i|ee-WLsk~+*x=HtBVx|oqSi8>fT6<=NRFY<0Zsux- zbEU3th`xSbx|twZ`wO_p4rV!gTo$J3sjSYSbK2^-Vv(1S6A&th5R%hlGaG5{)zJAd zU#*>Pqph&;CjTw)Zu=6b>qW(`&aElLb6k=Z<&JFhwrOLJUBg%z0M z_fXR*N;y|+prc6MN1Wzn*wX$ovJ3CH7w9BQXC9g#dMWD6ZGP1(b%B9a)97Hm+k)&2 z3VQ5dzZgP4_j^|bc@r}{hI?)dUgI(kxW3v9&x-&2h$32xbV0g}Ii`u+IWIhEp~H56 z1^27HOfCyGW*=DXMmIKkLQFi@4V~KTmaF$4ItIc^H*|O2tf{IWXSID~E3tQt#a<=1 zz~0y=*R?H=IZ->DW_Y+3xHng@@I{Y6OT~=!6!S-gcSO@3VJg zM(0R-gvO;HAMY%h*UL*~SjX8*6i$8V=)P`r>`r+uyZG%ufO1}-oa+Y6#Dz}i^s_BE zrJ4#zTvM2~AhI=}(5cXSjwiihlm%vZHJ#FG?+&!H3Cu|vxOnT|wjYn-`uIRsPj8+x zRFzTpB41_=x2inIJ8pV~4u8fu!K?P}Ph=aj)mK#G&pSM_jkQq9`n*PVlHk3dRzUaU zbAhI!Dhtiae44LET7kj8F$2q(N53#cPOsx2q8-^YMop(j(=vujJ$g1KSkX=kewDbv zj^WPQ(#lcC98qo_{5UE0xcr?A_?w?(ue6_B9kCh!#;3HUIBPvlF;>`sO(lGzVUZ4V z#}{D{e!^c79f4()`_{W}86>SV_c4xM^4brJmG2!FWqc(*nzFVm@GECd)X9d6kM3uJ zbs-YL#s)HisUxkB`4i&`S7e0i{UWN6D%=<(tp(0BRcpukAxk(IXN6*bDXGvj2@V@Z0}c196aRYcIBY z=im)!f)3NyaoAEb)J_cPDT?Y>)r=Pn)8s zR76@RQd%Sx?SxAEE+p-XHtiJIQ;`r^5)u&=p;VG=Aw+2xk*t-9Hf{gcDc$S(-21to z<$nI(&-eTD?(uxjH1BzzIdkUBoMq-c)AZ?5;JDWhn?@HT9Cdr*X_I=fX9nMqUA=Jy z(c5-UJ5^#AQHV0rgkEn%>&6S@yOTWC6A{TqPGGg~q*NoT}Rn5D+!ss6fLVHxp{L}1iqtBb7w>%9y zaqlZrx@6G&GiQ3tuD(|p7o0iafaoZB<15Owg|FI}rkjcH*xH8daU4IX9zS=0_~W{y zqAHY8+O(K`k$*p^zt*Yu67IyPsV;!0UMaU1V<*{#JMW^hwB%?DIxc!5+>-|gC+cl@ zMoC}={UG^Ys6{QcYwEx7EUehJpVur;IXADfqpqMyrnGx}?Ulxpo`Rl|Zx!R_g|55v zDL(DR$0K_M*Q6gSY#4L>Jvfx?J8Y~YbmSdXdD3N&ZvE{}8a2;U+1C2<2mW$2dcY1a#} z{*}F+f->rxqWRyyd*^!QRnm!*$r1B!vnb3SIccWW#3;#>txWIKkf+<0^!wU;zI071 z?8dIF%%;kHU*>wIUhFsRb$)+eKTX}vWQ3M{X+&9HNS-4f+b5R!C7+&+F-=g4>Zs;7 zj%s^|WbO}ZNs{gHwJHwl)$YS-h5Y=peF)fCxFsU2N5ppDi>|D8;hs0jxwM9pfSvZ; zhA>6ho`AT|IPHC#bnhM@*FRQ1$C{V2_jA1;Ao6D25xB#07h1G=!rpW*f5%-VFl+CH zoKNf9n?e&N3U+368a_yk>kM<>>%a2j`F*q2KR9pjZd>-Q<4>-<+(>)=Y^R5H83Y;h zx)u)*C5~d8NIJ4^a(Q05LEhJ_+_h1jjfT&vyKG7~*7UVkWcTIfO-z$q-k|#QOZErP z^zz)j6PVHtimfdjyQzfWDE3tmw`-LMn~vO4A$tqwyn4h3NGi=GoxQW-+K`{}e0w!< zqkiFxu&)&;Oj1@h;?g%{=KG;by5H~Ua?-eAcNe0)vF zopndzDj(Y`?UOVs)r!6OCQE_YV(f-f+pbOE&NJabP^UP%mS*+k6dgk*4*QCJvW*oD zRzsP%cWPn(Gm{pyIb>in=j-v9p5F8Q5$iLObL-V!pZnTZu5pFt-g#`GJ~o}bQe%=* zg1$R%*Mn2aIWiAFN{+~lb-NgQ(4a;n;|zPWlC%$fe85qS7|sW{KG~|2Sx!bv7H(gxQv{Y)vE8~s!GaD)vpWNYwD;yq% zVB66R+pQON<7~f9{d&hRrLM0*rzT{ThOYhiJijY_A?}xxd@r-1d1-BJc9wJVjh9JD zv&yU*E*w65{(a`tFRwR_Gvl7Ev+?rP1Qd!qI7NNvOIBO-rxo$K^=AxE^)Ekiq??>f!zu57D7^lc~X|&r=BBn`zsUsh)VR=~IF*U&wXiRQ2ag!jZ)lm)cjC zZm*b}lM{4VDQ%UHu2g+LvxQlmN*JqvZES>tupaFXInH{c|7$_$iLPC(XI~pWyRUWN zPLQlld*%RHdnI{sc$D-N#Z$8``q+Q8o^W-I$Fy}Rr_b7ZFX!`bTXcQaZp7_`Jl;~Z z^Itlt^=CBsJ*B?i4 zX8r;1LZN!zi`tnzR<8nQxR;jeSSOyT&9kaj+bUDPX@vTgr8c>h{A2H`@04)(+C}%_ z^j53)Dt2`A?u3L$gPJV4ZjWsf7wpk>Ihl6-^@nN4 zQ<7u5->0~}jx-iq#Dt?f&Du)~QKQ&9K;q->ayH1G@1L=2$Le+&t&EW3pg^nEtKM#& z9+}O_;STN10;|^D4piSYI=ACoWp`4sx1xABT(xK7cDI@B_6dtSdG6lE zeNX6x)Wf?gcz=-WI;5 zKJ%9KX-Uz|(gzAY1-rk|3E#6=Uq5=?%q;A;S!j@NGwnCQEtk`5w+nw2?J&YGvFU;I zQ98rJIE@Q%u@heU5TzF#IwByd0Qzo%nwYR!GIP;Y@TFNUE=&=m3 z_@%)__u7AA!e8_#E?STHD>}KBE(p7km>(0is`o;zOZWC(>1w`ZJy%xuXme-wFZi;b z@zC6$Fh@H@FI9)Ye3!;inwBU0ygl|KZH(+$8$;pnlD?0iM3+)b_ zIV792_4B2kWiyt>ww%F1Y|=vsixG3$$6otbYa;%crGMSg2jSgs%wP5M^safgwmJLb zm^%+mCa9}?(e8}9)T43vRH5UPyY;7Y#lubsv&uL)H{CxlId%UieRX!8NiluTweQDh zx?zQCYx;R^_9nKyxF7cN%`%=E@$n{Yaj(_=I4cFe%*-C;aZTJsYvb{>!uC(5^?v3Y zm5q%d?1Bfe;+~T)`d6TwRi;mX%Ixbm%kTIo z+mMV4D;Qc{&;l!M9gZAfG%vTIAl}l6=W*&;Xmo}3;&T1xW|?{Tpk0OL!{2|30(wb) z@3AyxqTTm#zoUb_do&K+(eB>e>rwFf`1>RE&vSR>D=*7x?OA`qr_p9#u8L5;giZch z(Mxp;X0Du^9_R10+T6d)?0R->mepG2%@%z2CWt_=4JWz?Jh~3XR?m6S;j(^mFD_GW zmgE*%>96L!v?Jk3+P#Gxcgupy8wFcSv*RsBua;jd(ZH8sYCYw%xy?zTkF`9X;_&1x z;eEo&7e4nc?l%+W&NXuCu=O;1+H^ogC@K2xC!8I5Is4$8uSIE@c;4-n%Iv!$F(01= z%vH^A`MO5P)jsibq~tqnpwpaj!uQTz4BIEv(rpNsr#jb?s~w%a(k1FZs+p1%3Yv^OBN6GupL+-zMCM$;X4f z)KG&EZtujCzS5D_Wtw3(a6iSyjq9!Ol&_~@pALMW%^R-}lsmW`VotJmXTDxXr*?DU z9<{U2@@(_JCi`AB(N;Z^)x+uTlo{>xYMcF(LkkO?#UxYTI~35n7}`!dy8WoQx*Hbg zkbj`Uwdqm$`{|wXPhWn>sk!vELM`ULXKMPhb*qG4op|WE;?W0#J|Wr320g_)dv+); zd0cUmmv5hcfPaLsbM#S^eGk+*5KzW7@zCep!cT<9`GoOb(`p=3^vU3*QO4>j)imwY zi@5^c4erO%&qgL@$?Ilc=>GaF_*7!MYH)0fiW{3IeU5O_t}c_fHm7c_R;xGDmUUka zWh(HNioRF;snL6Fpx6on0Nt!L~euam0%@wyXfuXVHpUv!j z{VZ-TjWJc5fv2oJIo=h3T(a_`E4n5}ZtQ;B>T*%wf=^eMt8d@V)@?R%S7si5o{|tR z+nSy8;zFnQ3c-EW){?ufBqu+5{XS~{9_~?mr*IA_UVTN_jmotJ_s)8@0He=SySCN{kInVfy%2n)Z|AAB>X1j9_DDV`ULL6aJl;uBz3=8c zsn|D(9^;&+^7$vaj?kN+V8MQWw|OqE+r8!}z_T88b>S{O?;_9I?derT+846Q7w_e} zBG(f)dVj6(`1PiqHo0aohrPWEN&U0n&S$(|vbQhf z2|E!#M!>5s5I@`-fAGYnyf?+>w;qX|hD97 zMg5n$w|&^}oM5dBI~vq>%IHmA%P#Tq8kyxQX1w+`a+Xvvs=wwf`Pj_(b&!RkWa4JE z@-^{C7F=qrM+?ZsuF_ON?{17qgT%WT(<(;KxPyG?db>9xEWzrL>}$a*okt7O(OD!I zQ_lzYde*gj?0o?KeuhkvW9(Zn-qLT&b7kGs+)nO3B)Rj& zmUAzvw!e2sW!tpyhRW3i*S4oVY|Ce-{1!a>a)2z;rnNjA9Ji7%iG%18enpU1G~j`afdgCs?KCS?GsaQ@J_u`!h%!LzBsNu`PA(Y zrfw9kaW^4NAgfVhEvheS0#z1k)}L#-7W=^Y?Aw%LqY9O9>CKOx7-f9! zp6h&nlEp%f%IdG#D^fOP?rr|yOz%_H9TbMk?q3-Ql^r^}vUf)J_$xvAHOG?+y!u|2 zA69WcbSgP;_q5vJrG4#jOM_ExoOZggf6uHXDKps+mGX>9wx0#DUIqh1?woVO-KN_$ zJ@UL)cAh=(EO?Tl=URbRF4`uJZ||9#4iMh-Lr#ypJrXO-%WfMeShacT6f0FcG*vNT|VaA?qDJgunELNVy?rN!#pcb&=W9`!7J7HbRtO_SK z?c9;v9nmU&RWaSs#NlOfQNw!0ryfGLszP>&kG;OvX}Zsm!`Hs1D_nf{amoEx5g#ua z7@V|fc7AHDR*}Q7J~Zq`iCjq5IVJUiejEI9u1CPmduM6HncF6v>37`}4W?P8Z}n7t zS~kJ+Y}qn-rOG){kKQDWjc}FBu)cHrWWvl+V~dmZD6XGsbS>W1w*1pG?{!GU*`MN; z>G^r+uV7-&WxdmMw$k6?OWx+n+@cGsCvc2--Ta_KWv)l2iu;qMRfH0 zUe}hX67TKyXQ6p|j5ay`)yh6Sviuj`^5ltrH+zfxOQRx*oi6umBW)OJt5zGv#xxt= z{*ZU%O6NMk**+6pUlw{#e5ThN@3DH`dlMt;aWO2ZcHRNa5mzG)`P!m?c0pcC`WEAmY zoVsyXKz>zRS1Eqn^IE%8xa&pdj6P-m7dC+}IyHJ8_KNlt_LcYJG~7enNvXdjEa;tj zPm`)fP{-_kn-%|PKVnS#7(jLrJ)T)?M-uq{V)t6XxF zlV4Wcj=s<=YI5YP+Qo`|p|5+LI;>M_MXIo~&$@U+aEO_x0Gg zF%<}6@PVn~&4ydwz1SVHNIk!swN%jPdCizfx5vEeSi(X}271fxqySDG|NO#-hdGyj5jSoR(+Ox&oS!dkbU`_M zrKjQLs!QF=Pb6il#;Z6u+xuM6$(S&~!7{;VgRVSTzDErSlk=#~XIV0PY|Y`L>?lJ* z=4zSjc(~H<$_LeJ<7IcA+j;zKVT0TnHuveiyb8t_bf@fB+W9o*Iz4Y=>D<__gNGR^ zt$l0e>!K0oeS3Oag!!r^p3SFfa#bdn7#DLyw_lMyZnUYu>fA0Ov)4=~+PabcNahSrPq6?*cA0L?Jd~*B#t8U1~`vrHG+ju@ZEUHnyF0Ue2`10ENfYQ zJ4P&X4_*CkMO@baxqPu|GoE$4Dk&$|q1}*4;plAhE2Z&8cA3-InWFE$8Kb;yR9N;Q zrNcKzO-r3ludJR;4-#}&8PStmpQRbPyT*r}fXSQublv;QZb=F52Dvr0ewS2)M{Ajw zUJz?H=Wlwky{P1|rOtWrPxH@ApPr=flp7W9l^;197WQ6NwhC+VD*Irx*>-~R+YCi@ zQ`P6iF9fvCC?@dud7is!QpB-FN^xnFFrUq6`-SqS_b75O3DfG)StcAipOEHV4Mx3} z*K56*B@mab&K|n_dCggAvCmGOJFN^n&RKpbGBQ)OkT=@*d=7`@48PYY6N4|06h9ke zd--uL%c%{fw_mn#>dlJm9HspC}Ho#vEDfmWPa*{gd(*4g=8iBv1l z-u|e<^!BnzGt2}P99w5>IkXV5j1^q=w9ooU4G&9Mo<#YPu+l!K%edNgfCT1zJR9is z>|8EAQ1^ycE!t(`EGapgmeioODmJ zeAB=1=)Io62ImJ2VR1osMlH?0dgx`1+M0zK7xZ4AIi2D?hTTPP;|;UwrTf|IlWn-S z?DU*C1=oZul1J}<+siKYR@g&Tznhy!AJJnt-sGadH>x-mB$pMiUC9m9- z4r{+Md++}0)3{X( zS9~UCdsj%$qR(z{NcownrV={2Id zYMLYHiHJoS-}+)B`DSOAC zTKDo&X0)i!Wpy+{u3u7^=&n(_5p6Diw?4cv1?As9x>I<1i+_#x>$t-HL!aUW8K26? z3)dW3bxCD}l!^ua!v&SvwfsBcD;J-c$m^{jsx{rwl%J0oJEac#7~AIb8;7_kO{=?u z(+2sGWeRQjF7E3J$|`MYwu~ubH@8%~n6pX9ooS+y6)K`J*}gkROM== zcQnhodZ?Yv>@Y07VHT+`Q&Bxf)w!nTN~Fcqt%|ZEx1CJ9^Vn>g*p^7KWk-{7REtf( zF<^$Eb&Ksw@kQPhO@@2A0$LrCL(~_CrivZeRdy7`N_y7ElD7t*V~ejU?tgO2Yh3b! zqg~^+oiNbuIj@8ucG7O8sJH8S^}4d#j*i#e)-BOmlhpH8IC|%++Y4*fIbF>9a>Z%S zJgIP2>ujIyi4Vkfi9B7gM`s0|R)&ak$7|#2CL@0RJQ=SjJe14*P{tmYgz3ILGkOZP z2kjPHwDjDFwOLa)rf!i6*Y`8iop_k*SjukfwQ=o*R_)1#o>I=&Kgi@(=2=~snQ||@ z%4YSY^8&(d_9i#BEytSA>0L2#;}Vf8k-Q^re#Kt%J^+WEG?|DgvwbCVlrxl-w`nh8 zv9?~qb^m(h=E1u%r^%G{8|B|G&1q}z3C~bx2sMA`C3RWzY*DjRkU?W#@|9Wb8><(c zD|)NAUWsAfeapp5i=`Ko=uX*cIn_cF3$QNHxL?!l)9d}PzEfMLSE#F?q9&Icoq~C* z)s!;avmQw&+JES3YTAG6b&w6mjt-e8mNRrL^mvYY;!yY*$HTvWf#9F_zuFG``;WB! z7fz-B{K~(24eD<;Y1n_+Ez5orxxeZJ!2j7m!~Vr%X*TkoISdOvUB{TE#v@jsC9!u|`pi~rqL(EmU({zvL0e;(-1 zJ7oVQ4X-~>=>NzZKihl%ySLtd*WGsi-#P026+7e4_TK;Qeed6UUM9Uz>Sw3r|5OeL z`!Dj-?J!Gg&ca<$N}U~EGq87Iat zUW`H4nNDZePsrpz!syB%ig$f(WlMI#xZi_}@+bH$CQtcH%rn4D=llnUyd9XCPmw{P zoP{tl>2v#(^U|+=^UK&8|L2pe$ zPADb=@VN`|C3cwGb#M+pOwmDfO^F$%cw@ROLhOV8$SRCSz*GJv%65pTD86#rVd2Y3N#uCw?FFP`DGxV!}Ka z?&7~2?(D&EnSUED)0m-fC()?VIR5%tK<2G%8#s<~kAr1+>Nx!8M4XWt0Z31Oq=hlY zY5DnUDJnu1A)?h$5!$iTs9-&7>t2CIYcg!&%~W@AfKGm zeTk`~eiH+2tbyBLqgjb4TXK?rp&^QxaU$H=!~$u?z%YAo+0Jg^m`3x@8q_14uoREM zJhW;97J(!9f_=Y#?FSM@md!cX;gfd@}!^d?4 z*?^^sARkPjOUIgCvEe~DBL>6qMvBno6EYfQ@aQ{igt3n6`eX*WKgbXX%|s%{AoJa~ z*ax?(%eUg^8ip z?;aEzcds%d*`lXYzr=k0X_0XrQdRPu2`crzdBUuhZytzGUYy=Ge}>pc0d1R;FO-a` zQY|AkPUKg$JIQ(AOU|{c)0M(E=tdkeJsI-G$3;IwEjq?mI3}s&>m0@+g}`YW`ZkPt z7+~^@|6|1NIraCnDjJwF&kHV5Yi{U1AoeQeQjUhA;km_HY@07$-}AKbboZir`f->q;`c%pFnxkwxPjy;_la-ded;`; z)}I#D{WA8g$hbo(BW}LZ(kOC$8K{;Yw&~v1q~xh=%YuEjod~J9YM z$4ZXYR5a9YR(kY;x9qUqXlto>*3pqp4`sGzwS-C~3!JXjnRHvq<7FY=oA<%|_b%<^ zd7*pP&t#owS?&ms!N=+6wN3ZjUb143Vr68iy4cw6`knzH z;WK9|nhQAu$4-_os$S9O`%p`)b&clU^G&rv9kQuwbR^@M543K%lqa$K`Q@FRFLEO* zEEd>rTDfjY#p;@<*u@ob`;$0tE?MzLLU*OtgM~Zzu15MuaCNc0yW`=OZMn=QQqDj% zwvPYq^NG987(F)L`$f_BmD-5(h&^ksyVxJo<#E|sFoHE;XN*~u6QiJgdB+B$>$|qS zzShQd)3jhg&Dn!Tvo5U;7@6)8bztfF%u8wB>#K4+=J}lW2#)kIpPAYzkUC=-%Q~i& z?m`tG+jH{P&MPM8KW#o`xqsHfMPaGW@44;Q>{y);m{opGVR>jo|NZy}sfNj=9!?oc z5=S@+3;1l+v;7PhPJalPXyK z$>k~g-2)e!7I#g&Ug16=blWD^>4|z5`9Cj^j=YRVd?a#`(T+==FrRT-e5W#edh@Gb zvFYU;Ey@KaC#bwG%AWj?UDx)p`QQgC@;YzIC}ykfGtksNi+J#oWPM5fO=e@j;1|49&iel$V`m`9IfO2`og2kdn4hORDnOo7PrKD?!6dm(enZ|dy7PHU{CYRUjB08&{ZJVY_jQw= zy5&2Wg@XDs3}z*XiXU>0%5>vcf6($hM}MHl#SqqjIcH1OMor4mxjX8CYAr?WA)Olf{(={9W-KCxf1!CR$H*VXz<$hE~tgca9mE$n5ogZ zM(HE6+}>@U&CaDJ&&_x3s^Jx${LK;q4)%*j^9Cea7S8U@z436mxmVH4SEH0-?~k|D zNQ>$5l&(5_KE$HoK}W>=Jhq?=)u3#)cQv+0vRcHdL}R!(Tqdatq-OyzqfspSNhF!X-Z7^PXAJoAJXmWo%G~_KMcoS-BMMs5br}NvZS?LqygHk4QBSlw zutQ%0t?)#zv6o~xJBw(~$i)#?W& zY%UF!$*u|a#(9l0oxFL?j0n~oi~C-&D*2Mr8f10$`SK4Gn?LCp`Aq#Bb2XFt^3m)& z{7+p{lQF+_eAG$q_8!KGtY#`AOY7E;KQ;Mu-KOf^@vn^svgW$D9k{ejE2%np@>t#u zQNEG$JB~>me5bN?iCRsrlIK8Sa<#~-7@4VB8-S_Nc*sL-k ztT|-=yc5Psa~neaB&{!WR!{0mRuMk@;8^Uka09KqHThf@TsfU{Q*6BVzYX!W=2nwi zb#dYvOLDQq^6~wWeuaf|-de7jQ67J%=;87?Ew8TLnYm>40*PmnC-<>-Xh?=S=LfzU z9dNhvc;=L@;NubVDmBe*Gj_6;u#}96KDIhzv*Ll-6054u1(aA8DSc#b_GiB)z9V(2 zN>qNaTVvu}zpA;}!MpD~l4`81j+UOS5ZvJydE@aMjl2AX2Z|jVWUWK}IVa_@yx^Fo zugjy~a%Az!cgI<$af)ZTQHA)5_2>Yp9rAX7XP7a8>)>A7Si7p&);e% z2BU7wi=IkqP^a4-H)Gn=>)OMOJv6 zO~1)JzpAY)(-ZGJs1rS$qR)JPSx(Na7r(4J1EVw=n}1YY#cbcbey8$ktoPdheyqR! z`t6xW&+lq;KYsDY`p~amoPdhrclDy7I?{K^|6@o$R!)8msr>gs8my}P7{-s8;MXuR zM*cQ7eA>#?AYM4N6b#0G1hic^b(sA`~UBogT4>*wa}r8Y%QX66(TCoczYM>j7Q zwJ8?ni=^jF5%Kf4^K!KF@b+?2o3h5qZ;FQc=uxV6$_^gB26jFo2*Arv*-mYWtG~aG zvaGD111gVpelp%ZPG0!T+1uCC&L98!y2v{E+65tCPY>ByGiNHwdfK^pO%btokyD%E z;V(Bu#6K8gj;k>M1>RKXnIMuw;0^Pwrf%p*TMMSggm*~3$2 z4^L4To}w^3MR9nF;uH~A4>zw>SR*=^BI4}rp))jLcx;NS`cPU9o}opnaj0)AF<|iY zEBy$s0ldZz_L2NJmFIV-^8W5rzHd`$XupO#G&b~38{>3i4#xu3;BPN%X1tKk@Io^l zui-EVp>aj4zHMmg&~!Qv%_J0Z)?jOzw&sV?ZgacuIAWYOE#E-_s@{u52q~3BmPBXD z97RHE=Mu71jgT5mLY`<5vQ?Xqr}~6wn-X%<99{5B(5qmB)-eKIkH9uK(d_vQY*Ag;q9pVleSoAzVuxM)&w9~PC&;tW71S2p3EDq-tu*btn zum=ag;?S!?yXy)1DF|Bq1U)DOZGS?r=)smZ?N7m?(Hnpl*0USzkPy0pgvg2#vJD4r z4JAUP=41V^&}fK*V{is8K|b7va(D&Jz-)mw{R%=FvEF$uNDHj9k{2NgSa1dwnum4O z`L?c_STuqkJQuPMLnI^71tcYU3zPNcO?z;7$z7@y{51s08gW4e`?f4`>20BoNI{du@3K_~Ln% z;C;j3`Tcs$}RpN^O{dh%){~ zk<8AFsIwnthzt|eYx{N(O~t}>a4|8@;di(#UJ z-Gk$M2FFtd$1yJ>{%90_xE_U0!NI8o3mQy5x<)H8K75_aXneqkCW|CJajNU45>lWgKkci0=mV2FFoXl zB4R?{|13@BAr3SyJxE%b<9BaWFZ?F9^m#N z`3xNBu)WT}$jFGCI|BRVV6QLHz-DG5VMt_jcz?To>)XEbU7p?`gZ+UQOZp+*P*e`? zM>IxsKl(o2v{Lb7ycz#A-t=34O}yif_h`HYME+j9X@~u9<4vnQKgOHsPvcF$_1DDP z2>Emq;$1p}kd1$s-b{ZJZ+eveG2YC78gKfozb4+S(nIMTh04bt=M(0^c+W@99M0c^ z*A7I`y4 z2!u&vF%7ceIy{3n&YuF93a0E`lIB7xz!2ry`3YNldh=pU23}G@u`_5Jj zx5IHrf;aF9#-nmP5d=X5=7K7Wnu%Ht2!I$^!AjUOi;#n0sfY?I>_Fa*g(pxAe5kz$ z!4!}NZ8R{9z(fUk1@^!pxDAhCoGRvry=sIcKpS+!XmxBh@PiQ80=wWfyaj6wR8Zlb zCLty8cpf2Duo63x1NgyOShf)JK?rOCQPj+(U^8q378I zyaM|G2!JTKLojTF2zU(7;VpauMO&l;7=Q)DLke7kTwqvXcn)vj19X729hLZfjBroAml?COmM?-6%;@fJRt;%;2Eg9W8L5cq(VAmzz67oK44o#h#h#rF*pI| zAQ!rT%>&aQ9SYzPFnS_x;0ZyH3D;q|H`Wp4K^dIE2ZCTd6hR5RgHIshgJUn8g$$^J zxA0;$A@5;{FX9EUa2WF77SM+C96#g>hygv6c~&qr0O}ug6v%)q$iXa71~t%z zaM%vVfR>@GI8*zd!~AcA&GPNL!^8h%Jb#A$YaaNk)BCRu??1h*{*&=#`fh)qV>}4Ke5jGZ11JSrbELJ#XYdAQk4Mc5nxF+%O~4Tf z_ytg#g1M7$)C4U-l%~Kbh9eyunu;1OSj|AG2E5WJwIE3awF(%n!LTkusRGj4IO@P~ z&BRp~%L1XrIGRHRRD+>D;sdV?P&w>M|UqVK-_O^+0PC5PU zm&0%=D~(cBA7}|%3$%2d4zyHV2Rq;{(9-oe(9%^8hD+Bg7=H`2WL5fBf{sLqNxPs` zzy|E#2Hb{9cn<6+4aa~nN;X>R{UfE=-`;Pwa{b->=P2-CPoaB`J*)wK>>0F9nuxuC z?h%UE6DYbz%z^dTBNBnZ6GsLR!X7XSGT|u<*Y8wNx3d9SzZ=hhE4o@9Ls)O0dQk~JHSZNHY2^>SL zOgV`w9~YUljEmfoVNTVDY436hyB1xbsWAaP}xf_Cf_ zQWr9X1nP*ArQV{1ce)t4>?=mzGEOCYTvJKO^r@uSekxH|Kb2%VOhdn%I63PlPNK}F z6LE71^443Dj2D_gX0Mz0~+>ZC|Vot*U4AdjUq z$s#vRVxT&YOtYUy9;}&1Zn(}Ts;mphE!Kr(mF7Zn!Dt~Vuv|!b{T7mq`isbGQ*ENQ zRGU2Z)+VRcYLf$FbV!?-4)LT z;=G;gOw3tb$V^!mvU;rx;^9i_^;}7(tQ#>=b0?EIRuK;a57MaNNlrO?k+|93#Ksdp z2n_KdT)wMGG^;O>)b}N0aHjbx2_SaD0i<|!0MU^TA{*p`$queH#Cp;i5-qfb6sxZx zCswW@VnS=lZJQ9nAsb5YxC5de7D@!htV6-Jj^y!%kpb=vemJ2&C2(E7os{!Ok_6F6qR0|O?#o7zPQ@K$ zjnz&PqZ3W+mqe2S+h|-#5krhsV~Cc*Zepann}{0jCI=jLlcZ^Th@Q_LGDT=FkyYG_ zXFKjCs-}BM;HX%_FS(E8&)P>GY3w5v)Ao~Bs{4ujf;i$}7)PRv<4C!89Le^HBX9lV zNGj_AQUL3?4iE)~gJg-%K{Ap35U~_IL=3bJkqqm2vRM8IdB&1J*7F`CBgKvpO`~IE zk@#_Pl_im^Uz|v`uTLboq9=%<-3c<^8TUH?2<-n@ML#)S5G7K7I|_KRtyk3QoaxJ4=e@pCbiEsbsfJ zDp|{#Mnp%ak<-)CNTO*P`8+nARL@N(&SvSvf7yBBV03{*ufIUbnKQ_lNf|_6GlQ@N zUL<~#FA>eqOC(6*GPy2unON9dCVmc=NeRg!t?F6CT`!Bgvblm<{}r;`;|ls`Fs_wN z6oRwKvynMO$t8zqN#vrhJC}TzoJUqjUn3P7*NCx1K3O>WI+>tM%Btf!( zycW4hp7Y-#$tt&q7SnCQJmU`0HYy}Rf_F)&>0Ls95E8*(MA#*Z$ODfe(zmvV)J=Rq z{EZ%vNS6mB#quE;J^m39(SJlVCKi+WCB>*4J|+!I9+O>0rKC^$DfwXhlx*>NN}?u~ zk%K~IM3=jqOfjz@$<9^e(2QzQG@*uU)u<(PTD4^U{O6>|^*O0ytRtShbqJ%5wAmc9v{g0k&Pr)r;${vH<7tcO+-YonRJh6Ax|Y+@spA^lEwa+cnN+cnL3|| z+_KN4E95iI<$WPZCSS-A|8^oizJnzAcaTkHon-l%PBKrki%4j95f!s8qF~oW++Dhe z$>?rUE%24-DSah2i@%aZHebm>-5#=Nbq`_Z?j?ePz2w-GKJ2S~w&@2Z@B(M|3NWG1~i#AV91M63a`QQQ{Tpir!ms11bxvH zRj3hiq1^p;T8b6d$avv;7cZQ=55hY=Sw#!m;n&c~D>^r=5P!Q;ueMMO;=sr_ zf{BHhg^`JQK$6tW3nte`ehXyq{1?W}i5sq}p+6B8A%++RVQ7lw(qF`(-bfS>4z8A9 zVPIrn9l^-L`t9q(k*EJ|pl@dQ4HNwpkoVxVN%As-OJ^U!jMK`DjDt(p`kkfEL*?BK zOG3?+Sa8wr{Q4TIaQ*uK@Q1&~cqqQV#?~0Ikj5@g}Pps12?O zE7M3uMixfqKU@CTZ>G{I^tF+Z3|`FgEy_a^ zf4={NDZs{hjO7x!L^f`mHT$<;`RI=m8u0JDXa#=g#U{Vmgl;D`(%bikTZ&Bwha6Pl zTLw58*cdc$LJ>83T(}wbM`*7%st(E^{S@JQ&iWDqSw!dxS8gpJ@fyJK=J3Z6`00K$=_W^x@ruj??hn z-Td4fy?xO=`TL(6(reK@WE{QyJ%0&T-`f=vy}YDEjGg?Qe18d7PH89%euQP<=HTn? z=k4q-V&v@X=HMh^6$_^VRjkJ|sVea%?* zuq<9ifNO6Y+W%7BX$vro<%elHXp1ugZC_(B_*+@pX7{1 zLY)KJ{-u2ev~7PC#=$M1eE|=EhW!SZrzOJF3+2AzVk1-F^Ph%$9FG9nicR!;;+Fvpp zE*;V|6$W%a{BRr5;XA52pg+zLJ$IfM(p!}d-D8a2vXoAh9sHIj`s!r|KMBS=?LnvK zB5ZNGcBuc4_T~9tip(!_V{wDarRzaoG%lm?3t~E?squSpoPz0p#jQ^1`hLG$T%a(x zJi5%^Tdu_4EO$6<{++wc{&xMbh@Y>YDeyA|ex|_B6!@6}KU3gm3j9ogpDFM&1%9T$ z|Ed(A?JC+XrR^v*LkHWJv^_`9+tYLQwEaoX(bKj%ZM)JoIc*!$Ha=~)(>6VAv(mOZ zZIkl>ZNJktK0P;%-=vX=AON^Dg$M#|LDM#!2uudrP80<(mm#4)l7R(J%%$ zfeW}{Ebss?@WD735Bx9zCIY=f=_C*YArJ-;m<&@u6vSXEOauCJvgsfJk}w14bwbi0 z1F|p^vQ zdAI->a1k!SWypjqxB}Ub1G#V&^57ce!*wWt8*meD!ELw$g>V<{!F?!#2k;OcK`}gr zCr|>V@D$3R94ep^s-PNb;2G4yb9e!D@Dg4@J-mhncmr?Y9lVDR@DUoJ37X*(v_LDg z!Dsja?a%?8&;{M_6?&i-`k)^MfEN7p(mzIE0%l-=5x@%cIWHq&6wpU|almL81DwDG z+%Oh+fEV~+9E=D0j2L=D+=(Cn^tlp(AOyl70+V41h=LeQg=ruT^tn9}APF-7zj7ne zAOo^66XakP$ir+<07X!OIWQNLK?PJn4b*|&XiXF5!FMVUHTZ%b_(K2$LJ$PQ8dwV<5DM!6zZ4{4umLv0CfE#HU@L5caM%tJ5D8JR19n0* z?1C8B4SQfO#KJz<4{>k+4#FWg4DoOT65uEtgX540Cm;z*&av&G3LLOX$e7Ft;a070_Ew~MLpb+lDJ-81=@BkjdBPfQ) z@B~Vr6rMsEltTqnLKRd)4LpNdcn&Y14qn2m|F6A!`Dr2u;5c6F16rj(Rn!W)3L-uz zDoR@fQlyx0;F0v;8A!M_Dyb&k{1g0Jy!oei76l)mVtt{te1E%bc2feGa&em%*;tPeBZXj^ z|4GVU$T&xOK<#S;QkGD6Uo|SMI!l+6V*kfD`K!i*FwI{_eD*q^fctNVVNY{|xh%|8Tv&8ffCx_eY%fPwi*7 zMcZ)4wrEg`l}-*YH^Y#XeYo@_&wLB^{|0Arier=grq+6*8lOn{is_e+y)Eu={eP-~ E9am*TivR!s diff --git a/Gems/ImageProcessing/External/CubeMapGen/VectorMacros.h b/Gems/ImageProcessing/External/CubeMapGen/VectorMacros.h deleted file mode 100644 index b752d0b3c1..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/VectorMacros.h +++ /dev/null @@ -1,176 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -//-------------------------------------------------------------------------------------- -// VectorMacros.h -// -// Fast operations on vectors, stored as arrays of floats -// -//-------------------------------------------------------------------------------------- -// (C) 2001-2005 ATI Research, Inc. All rights reserved. -//-------------------------------------------------------------------------------------- -// modifications by Crytek GmbH - -//disable warning about doubles being converted down to float -#pragma warning (disable : 4244 ) - -#define VM_LARGE_FLOAT 3.7e37f - -#define VM_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define VM_MAX(a, b) (((a) > (b)) ? (a) : (b)) - -//clamping macros -#define VM_CLAMP(d, s, mn, mx){(d) = ((s)<(mx))?( ((s)>(mn))?(s):(mn) ):(mx); } - -#define VM_CLAMP2_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx);} -#define VM_CLAMP2(d, s, mn, mx) VM_CLAMP2_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx)) - -#define VM_CLAMP3_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx); VM_CLAMP(d[2], s[2], mn, mx);} -#define VM_CLAMP3(d, s, mn, mx) VM_CLAMP3_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx)) - -#define VM_CLAMP4_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx); VM_CLAMP(d[2], s[2], mn, mx); VM_CLAMP(d[3], s[3], mn, mx);} -#define VM_CLAMP4(d, s, mn, mx) VM_CLAMP4_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx)) - - -//set vectors -#define VM_SET2_UNTYPED(d, f) { d[0]=f; d[1]=f;} -#define VM_SET2(d, f) VM_SET2_UNTYPED(((float *)(d)), ((float)(f))) - -#define VM_SET3_UNTYPED(d, f) { d[0]=f; d[1]=f; d[2]=f; } -#define VM_SET3(d, f) VM_SET3_UNTYPED(((float *)(d)), ((float)(f))) - -#define VM_SET4_UNTYPED(d, f) { d[0]=f; d[1]=f; d[2]=f; d[3]=f; } -#define VM_SET4(d, f) VM_SET4_UNTYPED(((float *)(d)), ((float)(f))) - - -//copy vectors -#define VM_COPY2_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1];} -#define VM_COPY2(d, s) VM_COPY2_UNTYPED(((float *)(d)), ((float *)(s))) - -#define VM_COPY3_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; } -#define VM_COPY3(d, s) VM_COPY3_UNTYPED(((float *)(d)), ((float *)(s))) - -#define VM_COPY4_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3]; } -#define VM_COPY4(d, s) VM_COPY4_UNTYPED(((float *)(d)), ((float *)(s))) - - -//add two vectors -#define VM_ADD2_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; } -#define VM_ADD2(d, sa, sb) VM_ADD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - -#define VM_ADD3_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; d[2]=sa[2]+sb[2]; } -#define VM_ADD3(d, sa, sb) VM_ADD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - -#define VM_ADD4_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; d[2]=sa[2]+sb[2]; d[3]=sa[3]+sb[3]; } -#define VM_ADD4(d, sa, sb) VM_ADD4_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - - -//subtract two vectors -#define VM_SUB2_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; } -#define VM_SUB2(d, sa, sb) VM_SUB2_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - -#define VM_SUB3_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; d[2]=sa[2]-sb[2]; } -#define VM_SUB3(d, sa, sb) VM_SUB3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - -#define VM_SUB4_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; d[2]=sa[2]-sb[2]; d[3]=sa[3]-sb[3]; } -#define VM_SUB4(d, sa, sb) VM_SUB4_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - - -//multiply all elements of a vector by a scalar -#define VM_SCALE2_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; } -#define VM_SCALE2(d, s, f) VM_SCALE2_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) ) - -#define VM_SCALE3_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; d[2]=s[2]*f; } -#define VM_SCALE3(d, s, f) VM_SCALE3_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) ) - -#define VM_SCALE4_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; d[2]=s[2]*f; d[3]=s[3]*f; } -#define VM_SCALE4(d, s, f) VM_SCALE4_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) ) - - -//add a scalar to all elements of a vector -#define VM_BIAS2_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; } -#define VM_BIAS2(d, s, f) VM_BIAS2_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f))) - -#define VM_BIAS3_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; d[2]=s[2]+f; } -#define VM_BIAS3(d, s, f) VM_BIAS3_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f))) - -#define VM_BIAS4_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; d[2]=s[2]+f; d[3]=s[3]+f; } -#define VM_BIAS4(d, s, f) VM_BIAS4_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f))) - - -//3D cross product -#define VM_XPROD3_UNTYPED(d, sa, sb) { d[0]=sa[1]*sb[2]-sa[2]*sb[1]; d[1]=sa[2]*sb[0]-sa[0]*sb[2]; d[2]=sa[0]*sb[1]-sa[1]*sb[0]; } -#define VM_XPROD3(d, sa, sb) VM_XPROD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - - -//dot products -#define VM_DOTPROD2_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1]) -#define VM_DOTPROD2(sa, sb) VM_DOTPROD2_UNTYPED(((float *)(sa)), ((float *)(sb))) - -#define VM_DOTPROD3_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1]+ sa[2]*sb[2]) -#define VM_DOTPROD3(sa, sb) VM_DOTPROD3_UNTYPED(((float *)(sa)), ((float *)(sb))) - -#define VM_DOTPROD4_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1]+ sa[2]*sb[2] + sa[3]*sb[3]) -#define VM_DOTPROD4(sa, sb) VM_DOTPROD4_UNTYPED(((float *)(sa)), ((float *)(sb))) - - -//dp3 then and add 4th component from second arguement -#define VM_DOTPROD3ADD_UNTYPED(pt, pl) (pt[0]*pl[0]+ pt[1]*pl[1]+ pt[2]*pl[2] + pl[3]) -#define VM_DOTPROD3ADD(pt, pl) VM_DOTPROD3ADD_UNTYPED(((float *)(pt)), ((float *)(pl))) - - -//normalize vectors -#define VM_NORM3_UNTYPED(d, s) {double __idsq; __idsq=1.0/sqrt(VM_DOTPROD3_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; } -#define VM_NORM3_UNTYPED_F32(d, s) {float __idsq; __idsq=1.0/sqrt(VM_DOTPROD3_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; } -#define VM_NORM3(d, s) VM_NORM3_UNTYPED_F32(((float *)(d)), ((float *)(s))) - -#define VM_NORM4_UNTYPED(d, s) {double __idsq; __idsq=1.0/sqrt(VM_DOTPROD4_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; d[3]=s[3]*__idsq; } -#define VM_NORM4_UNTYPED_F32(d, s) {float __idsq; __idsq=1.0/sqrt(VM_DOTPROD4_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; d[3]=s[3]*__idsq; } -#define VM_NORM4(d, s) VM_NORM4_UNTYPED_F32(((float *)(d)), ((float *)(s))) - - -//safely normalize vectors, deal with 0 length case -#define VM_SAFENORM3_UNTYPED(d, s) {float __idsq, __dp; __dp = VM_DOTPROD3_UNTYPED(s,s); \ - __idsq=( (__dp > 0.0f)?(1.0/sqrt(__dp)):0.0f ) ; d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; } -#define VM_SAFENORM3(d, s) VM_NORM3_UNTYPED_F32(((float *)(d)), ((float *)(s))) - - - -//absolute value -#define VM_ABS2_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); } -#define VM_ABS2(d, s) VM_ABS2_UNTYPED(((float *)(d)), ((float *)(s)) ) - -#define VM_ABS3_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); d[2] = fabs(s[2]); } -#define VM_ABS3(d, s) VM_ABS3_UNTYPED(((float *)(d)), ((float *)(s)) ) - -#define VM_ABS4_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); d[2] = fabs(s[2]); d[3] = fabs(s[3]); } -#define VM_ABS4(d, s) VM_ABS4_UNTYPED(((float *)(d)), ((float *)(s)) ) - - -//projection of a vector onto another vector (assumes vector v is normalized) -// computes d, which is the parallel component of s onto vector v -#define VM_PROJ3_UNTYPED(d, s, v) { double __dp; __dp = VM_DOTPROD3_UNTYPED(s, v); VM_SCALE3_UNTYPED(d, s, __dp); } -#define VM_PROJ3(d, s, v) VM_PROJ3_UNTYPED(((float *)(d)), ((float *)(s)), ((float *)(v)) ) -#define VM_PROJ3_F64(d, s, v) VM_PROJ3_UNTYPED(((double *)(d)), ((double *)(s)), ((double *)(v)) ) - - -//compute component of a vector perpendicular to another vector -// d is perpendicular component of s onto vector v -// this macro first computes the parallel projection, then subtracts off from the original vector -// to obtain the perpendicular component -#define VM_PERP3_UNTYPED(d, s, v) {double __proj[3]; VM_PROJ3_UNTYPED(__proj, s, v); VM_SUB3_UNTYPED(d, s, __proj); } -#define VM_PERP3(d, s, v) VM_PERP3_UNTYPED(((float *)(d)), ((float *)(s)), ((float *)(v)) ) -#define VM_PERP3_F64(d, s, v) VM_PERP3_UNTYPED(((double *)(d)), ((double *)(s)), ((double *)(v)) ) - - diff --git a/Gems/ImageProcessing/External/CubeMapGen/license.txt b/Gems/ImageProcessing/External/CubeMapGen/license.txt deleted file mode 100644 index aa663d5ba7..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/license.txt +++ /dev/null @@ -1,19 +0,0 @@ -Modified BSD License (2009): - -Copyright (c) 2011, Advanced Micro Devices, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export laws, including but not limited to the U.S. Export Administration Regulations (“EAR”), (15 C.F.R. Sections 730 through 774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000. Further, pursuant to Section 740.6 of the EAR, you hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in Country Groups D:1, E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) export to Country Groups D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774 of EAR). For the most current Country Group listings, or for additional information about the EAR or your obligations under those regulations, please refer to the U.S. Bureau of Industry and Security’s website at http://www.bis.doc.gov/. - - - diff --git a/Gems/ImageProcessing/External/CubeMapGen/readme.txt b/Gems/ImageProcessing/External/CubeMapGen/readme.txt deleted file mode 100644 index 8026674cc4..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/readme.txt +++ /dev/null @@ -1,5 +0,0 @@ -Cropped version of CubeMapGen-1.4-Source.zip - -More detail and download access: -https://gpuopen.com/archive/gamescgi/cubemapgen/ - diff --git a/Gems/ImageProcessing/gem.json b/Gems/ImageProcessing/gem.json deleted file mode 100644 index f211bad1e3..0000000000 --- a/Gems/ImageProcessing/gem.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "gem_name": "ImageProcessing", - "GemFormatVersion": 4, - "Uuid": "eeffbd9211cf4ce0b5cc73696b427cbe", - "Name": "ImageProcessing", - "DisplayName": "Image Processing", - "Version": "0.1.0", - "Summary": "Contains ImageBuilder for Asset Processor processing image files and UI for texture property editing", - "Tags": ["Image Builder", "Texture Property Editor"], - "IconPath": "preview.png", - "IsRequired": false, - "Modules": [ - { - "Name": "Editor", - "Type": "EditorModule" - } - ], - "Dependencies": [ - { - "Uuid": "5a149b6b3c964064bd4970f0e92f72e2", - "VersionConstraints": [ - "~>0.1" - ], - "_comment": "Texture Atlas" - } - ] -} diff --git a/Gems/ImageProcessing/preview.png b/Gems/ImageProcessing/preview.png deleted file mode 100644 index 2f1ed47754..0000000000 --- a/Gems/ImageProcessing/preview.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d6204c6730e5675791765ca194e9b1cbec282208e280507de830afc2805e5fa -size 41127 From ccfb232e93bf0c9298a8d2852496862aff794efd Mon Sep 17 00:00:00 2001 From: moudgils Date: Mon, 10 May 2021 15:19:37 -0700 Subject: [PATCH 078/225] Missed a change --- Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp index 08d8fca9b3..6b16110c12 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp @@ -333,7 +333,7 @@ namespace AZ const uint32_t endRow = AZStd::min(startRow + rowsPerSplit, subresourceLayout.m_rowCount); // Calculate the blocksize for BC formatted images; the copy command works in texels. - const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; + uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight; // Copy subresource data to staging memory. { From a2cadb1d4056459bd133e50f80e5472851bc50d8 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 10 May 2021 17:47:10 -0500 Subject: [PATCH 079/225] Restructuring DistanceBetweenFilter tests to allow for further debugging --- ...errides_InstancesPlantAtSpecifiedRadius.py | 25 +++++++++---------- ...nFilter_InstancesPlantAtSpecifiedRadius.py | 24 +++++++++--------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py index 85a16056f5..d0c6fc3c5a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py @@ -87,30 +87,29 @@ class TestDistanceBetweenFilterComponentOverrides(EditorTestHelper): spawner_entity.add_component("Vegetation Distance Between Filter") spawner_entity.get_set_test(3, "Configuration|Allow Per-Item Overrides", True) spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Override Enabled", True) - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 2), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 2), 5.0) and \ - self.test_success + num_expected = 16 * 16 + initial_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected), 5.0) + self.test_success = self.test_success and initial_success # 6) Change Radius Min to 1.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 1.0) - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) and \ - self.test_success + point_a_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) + point_b_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) + point_c_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) + self.test_success = self.test_success and point_a_success and point_b_success and point_c_success # 7) Change Radius Min to 2.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 2.0) - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) and \ - self.test_success + point_a_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) + point_b_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) + point_c_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) + self.test_success = self.test_success and point_a_success and point_b_success and point_c_success # 8) Change Radius Min to 16.0, refresh, and verify instance counts are accurate, only a single instance should plant spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 16.0) num_expected_instances = 1 final_check_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected_instances), 5.0) - self.test_success = final_check_success and self.test_success + self.test_success = self.test_success and final_check_success test = TestDistanceBetweenFilterComponentOverrides() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py index 59fbca205f..d342afd7ca 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py @@ -82,24 +82,24 @@ class TestDistanceBetweenFilterComponent(EditorTestHelper): # 5) Add a Vegetation Distance Between Filter and verify initial instance counts are accurate spawner_entity.add_component("Vegetation Distance Between Filter") - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 2), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 2), 5.0) and \ - self.test_success + num_expected = 16 * 16 + num_expected = 16 * 16 + initial_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected), 5.0) + self.test_success = self.test_success and initial_success # 6) Change Radius Min to 1.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 1.0) - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) and \ - self.test_success + point_a_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) + point_b_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) + point_c_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) + self.test_success = self.test_success and point_a_success and point_b_success and point_c_success # 7) Change Radius Min to 2.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 2.0) - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) and \ - self.test_success + point_a_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) + point_b_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) + point_c_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) + self.test_success = self.test_success and point_a_success and point_b_success and point_c_success # 8) Change Radius Min to 16.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 16.0) From 64d53d1fabc4aa9d2fcad9c7506ce9dc78b26ec8 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Mon, 10 May 2021 15:53:11 -0700 Subject: [PATCH 080/225] Fix View::GetCameraTransform --- Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp index 85216707a8..21a46693d5 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp @@ -112,10 +112,10 @@ namespace AZ AZ::Transform View::GetCameraTransform() const { - const Quaternion zUpToYUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi); + static const Quaternion yUpToZUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi); return AZ::Transform::CreateFromQuaternionAndTranslation( - Quaternion::CreateFromMatrix4x4(m_worldToViewMatrix) * zUpToYUp, - m_worldToViewMatrix.GetTranslation() + Quaternion::CreateFromMatrix4x4(m_viewToWorldMatrix) * yUpToZUp, + m_viewToWorldMatrix.GetTranslation() ).GetOrthogonalized(); } @@ -127,7 +127,7 @@ namespace AZ // is in a Z-up world and an identity matrix means that it faces along the positive-Y axis and Z is up. // An identity view matrix on the other hand looks along the negative Z-axis. // So we adjust for this by rotating the camera world matrix by 90 degrees around the X axis. - AZ::Matrix3x4 zUpToYUp = AZ::Matrix3x4::CreateRotationX(AZ::Constants::HalfPi); + static AZ::Matrix3x4 zUpToYUp = AZ::Matrix3x4::CreateRotationX(AZ::Constants::HalfPi); AZ::Matrix3x4 yUpWorld = cameraTransform * zUpToYUp; float viewToWorldMatrixRaw[16] = { From b5d54450d8511893da4663d84c93f4e95c9eb7ca Mon Sep 17 00:00:00 2001 From: catdo Date: Mon, 10 May 2021 15:55:31 -0700 Subject: [PATCH 081/225] added prefabnautomated test --- .../PrefabLevel_OpensLevelWithEntities.py | 78 ++++++++ .../PythonTests/prefab/TestSuite_Active.py | 39 ++++ .../Gem/PythonTests/prefab/__init__.py | 10 + .../PrefabLevel_OpensLevelWithEntities.prefab | 171 ++++++++++++++++++ .../tags.txt | 12 ++ 5 files changed, 310 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py create mode 100644 AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Active.py create mode 100644 AutomatedTesting/Gem/PythonTests/prefab/__init__.py create mode 100644 AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab create mode 100644 AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/tags.txt diff --git a/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py new file mode 100644 index 0000000000..45f44474e1 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py @@ -0,0 +1,78 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt:off +class Tests (): + find_empty_entity = ("Entity: 'EmptyEntity' found", "Entity: 'EmptyEntity' *not* found in level") + empty_entity_pos = ( + "'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position") + find_pxentity = ("Entity: 'EntityWithPxCollider' found", "Entity: 'EntityWithPxCollider' *not* found in level") + pxentity_component = ( + "Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' has *not* a Physx Collider") + +# fmt:on + +def PrefabLevel_OpensLevelWithEntities (): + """ + Opens the level that contains 2 entities, "EmptyEntity" and "EntityWithPxCollider". + This test makes sure that both entities exist after openning the level and that: + - EmptyEntity is at Position: (10, 20, 30) + - EntityWithPxCollider has a PhysXCollider component + """ + + import os + import sys + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + + import editor_python_test_tools.hydra_editor_utils as hydra + + import azlmbr.legacy.general as general + import azlmbr.bus + from azlmbr.math import Vector3 + + EXPECTED_EMPTY_ENTITY_POS = Vector3 (10.00, 20.0, 30.0) + + helper.init_idle () + helper.open_level ("prefab", "PrefabLevel_OpensLevelWithEntities") + + class EmptyEntity (): + value = None + + def find_empty_entity (): + EmptyEntity.value = general.find_editor_entity ("EmptyEntity") + return EmptyEntity.value.IsValid () + + helper.wait_for_condition (find_empty_entity, 5.0) + Report.result (Tests.find_empty_entity, EmptyEntity.value.IsValid ()) + + empty_entity_pos = azlmbr.components.TransformBus (azlmbr.bus.Event, "GetWorldTranslation", EmptyEntity.value) + is_at_position = empty_entity_pos.IsClose (EXPECTED_EMPTY_ENTITY_POS) + Report.result (Tests.empty_entity_pos, is_at_position) + if not is_at_position: + Report.info (f'Expected position: {EXPECTED_EMPTY_ENTITY_POS.ToString ()}, actual position: {empty_entity_pos.ToString ()}') + + pxentity = general.find_editor_entity ("EntityWithPxCollider") + Report.result (Tests.find_pxentity, pxentity.IsValid ()) + + pxcollider_id = hydra.get_component_type_id ("PhysX Collider") + hasComponent = azlmbr.editor.EditorComponentAPIBus (azlmbr.bus.Broadcast, 'HasComponentOfType', pxentity, + pxcollider_id) + Report.result (Tests.pxentity_component, hasComponent) + + +if __name__ == "__main__": + + from editor_python_test_tools.utils import Report + Report.start_test (PrefabLevel_OpensLevelWithEntities) + PrefabLevel_OpensLevelWithEntities () \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Active.py new file mode 100644 index 0000000000..3cd0a0d43d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Active.py @@ -0,0 +1,39 @@ +""" + All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + its licensors. + + For complete copyright and license terms please see the LICENSE at the root of this + distribution (the "License"). All use of this software is governed by the License, + or, if provided, by the license below or the license accompanying this file. Do not + remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + """ + +# This suite consists of all test cases that are passing and have been verified. + +import pytest +import os +import sys + +from ly_test_tools import LAUNCHERS + +sys.path.append (os.path.dirname (os.path.abspath (__file__)) + '/../automatedtesting_shared') + +from base import TestAutomationBase + + +@pytest.mark.SUITE_main +@pytest.mark.parametrize ("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize ("project", ["AutomatedTesting"]) +class TestAutomation (TestAutomationBase): + + def _run_prefab_test (self, request, workspace, editor, test_module): + self._run_test (request, workspace, editor, test_module, + ["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]) + + def test_PrefabLevel_OpensLevelWithEntities (self, request, workspace, editor, launcher_platform): + from . import PrefabLevel_OpensLevelWithEntities as test_module + + + self._run_prefab_test (request, workspace, editor, test_module) \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/prefab/__init__.py b/AutomatedTesting/Gem/PythonTests/prefab/__init__.py new file mode 100644 index 0000000000..6ed3dc4bda --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/prefab/__init__.py @@ -0,0 +1,10 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" \ No newline at end of file diff --git a/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab b/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab new file mode 100644 index 0000000000..0776f25935 --- /dev/null +++ b/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab @@ -0,0 +1,171 @@ +{ + "Source": "Levels/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab", + "ContainerEntity": { + "Id": "Entity_[403811863694]", + "Name": "Level", + "Components": { + "Component_[10582285743525614098]": { + "$type": "SelectionComponent", + "Id": 10582285743525614098 + }, + "Component_[12253783095375428046]": { + "$type": "EditorInspectorComponent", + "Id": 12253783095375428046 + }, + "Component_[13764860261821571747]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 13764860261821571747, + "Parent Entity": "" + }, + "Component_[15844324401733835865]": { + "$type": "EditorEntitySortComponent", + "Id": 15844324401733835865 + }, + "Component_[1605854641405361768]": { + "$type": "EditorLockComponent", + "Id": 1605854641405361768 + }, + "Component_[17698173984524983803]": { + "$type": "EditorOnlyEntityComponent", + "Id": 17698173984524983803 + }, + "Component_[3444251662966224826]": { + "$type": "EditorPendingCompositionComponent", + "Id": 3444251662966224826 + }, + "Component_[4231768881195179982]": { + "$type": "EditorVisibilityComponent", + "Id": 4231768881195179982 + }, + "Component_[4722360315410084479]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 4722360315410084479 + }, + "Component_[7614719100624882952]": { + "$type": "EditorPrefabComponent", + "Id": 7614719100624882952 + }, + "Component_[9585901769691795481]": { + "$type": "EditorEntityIconComponent", + "Id": 9585901769691795481 + } + }, + "IsDependencyReady": true + }, + "Entities": { + "Entity_[438171602062]": { + "Id": "Entity_[438171602062]", + "Name": "EntityWithPxCollider", + "Components": { + "Component_[11161653124805884473]": { + "$type": "EditorPendingCompositionComponent", + "Id": 11161653124805884473 + }, + "Component_[13116773315299882093]": { + "$type": "EditorOnlyEntityComponent", + "Id": 13116773315299882093 + }, + "Component_[15820915681461536711]": { + "$type": "EditorVisibilityComponent", + "Id": 15820915681461536711 + }, + "Component_[2222061938345834243]": { + "$type": "SelectionComponent", + "Id": 2222061938345834243 + }, + "Component_[3861913165076405600]": { + "$type": "EditorEntitySortComponent", + "Id": 3861913165076405600 + }, + "Component_[7118587015611303204]": { + "$type": "EditorLockComponent", + "Id": 7118587015611303204 + }, + "Component_[7751174327125555504]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 7751174327125555504 + }, + "Component_[8304730147756374057]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 8304730147756374057, + "Parent Entity": "Entity_[403811863694]", + "Transform Data": { + "Translate": [ + 0.0, + 20.0, + 34.0 + ] + } + }, + "Component_[8866353210615920259]": { + "$type": "EditorEntityIconComponent", + "Id": 8866353210615920259 + }, + "Component_[8988181228601932779]": { + "$type": "EditorInspectorComponent", + "Id": 8988181228601932779 + }, + "Component_[7103333782129541775]": { + "$type": "EditorColliderComponent", + "Id": 7103333782129541775 + } + }, + "IsDependencyReady": true + }, + "Entity_[532660882574]": { + "Id": "Entity_[532660882574]", + "Name": "EmptyEntity", + "Components": { + "Component_[16437814751543997955]": { + "$type": "EditorEntitySortComponent", + "Id": 16437814751543997955 + }, + "Component_[16751517102089557119]": { + "$type": "EditorPendingCompositionComponent", + "Id": 16751517102089557119 + }, + "Component_[16773275259304187949]": { + "$type": "EditorInspectorComponent", + "Id": 16773275259304187949 + }, + "Component_[17283539636910567200]": { + "$type": "SelectionComponent", + "Id": 17283539636910567200 + }, + "Component_[250004123617033400]": { + "$type": "EditorLockComponent", + "Id": 250004123617033400 + }, + "Component_[2791138963683667073]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 2791138963683667073, + "Parent Entity": "Entity_[403811863694]", + "Transform Data": { + "Translate": [ + 10.0, + 20.0, + 30.0 + ] + } + }, + "Component_[3296942400051129145]": { + "$type": "EditorEntityIconComponent", + "Id": 3296942400051129145 + }, + "Component_[3422076964671342434]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3422076964671342434 + }, + "Component_[3431895414183121731]": { + "$type": "EditorVisibilityComponent", + "Id": 3431895414183121731 + }, + "Component_[7072085777705148766]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 7072085777705148766 + } + }, + "IsDependencyReady": true + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/tags.txt b/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/tags.txt new file mode 100644 index 0000000000..0d6c1880e7 --- /dev/null +++ b/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/tags.txt @@ -0,0 +1,12 @@ +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 From 333fe5232c6c3d77fa6ed92018616cf6b6192857 Mon Sep 17 00:00:00 2001 From: catdo Date: Mon, 10 May 2021 15:59:12 -0700 Subject: [PATCH 082/225] added prefab to cmakelists --- AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 31afab87ed..b3d74055f9 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -122,6 +122,22 @@ endif() # ) #endif() +## Prefab ## + if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::PrefabTests + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/prefab/TestSuite_Active.py + TIMEOUT 3600 + RUNTIME_DEPENDENCIES + Legacy::Editor + Legacy::CryRenderNULL + AZ::AssetProcessor + AutomatedTesting.Assets + ) + endif() + ## Editor Python Bindings ## if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_pytest( From cf0d3af78e55d3d4f18292d0f856e4dcc7744865 Mon Sep 17 00:00:00 2001 From: guthadam Date: Mon, 10 May 2021 18:02:26 -0500 Subject: [PATCH 083/225] ATOM-15128 replacing material editor icon --- .../Source/Window/Icons/materialeditor.svg | 20 +++++++++++++++ .../Code/Source/Window/MaterialEditor.qrc | 1 + .../Source/Window/MaterialEditorWindow.cpp | 2 +- Gems/Atom/Tools/MaterialEditor/preview.svg | 25 +++++++++++++------ 4 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 Gems/Atom/Tools/MaterialEditor/Code/Source/Window/Icons/materialeditor.svg diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/Icons/materialeditor.svg b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/Icons/materialeditor.svg new file mode 100644 index 0000000000..31b0b304a1 --- /dev/null +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/Icons/materialeditor.svg @@ -0,0 +1,20 @@ + + + Icons / Application Icons / Material Editor + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditor.qrc b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditor.qrc index 4f93770096..cde48079ac 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditor.qrc +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditor.qrc @@ -1,6 +1,7 @@ MaterialEditor.qss + Icons/materialeditor.svg Icons/material.svg Icons/materialtype.svg Icons/mesh.svg diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index 6e47de189c..d87d3b81e3 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -58,7 +58,7 @@ namespace MaterialEditor { AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral(":/MaterialEditor.qss")); - QApplication::setWindowIcon(QIcon(":/Icons/materialtype.svg")); + QApplication::setWindowIcon(QIcon(":/Icons/materialeditor.svg")); AZ::Name apiName = AZ::RHI::Factory::Get().GetName(); if (!apiName.IsEmpty()) diff --git a/Gems/Atom/Tools/MaterialEditor/preview.svg b/Gems/Atom/Tools/MaterialEditor/preview.svg index 56c1ead3c1..31b0b304a1 100644 --- a/Gems/Atom/Tools/MaterialEditor/preview.svg +++ b/Gems/Atom/Tools/MaterialEditor/preview.svg @@ -1,9 +1,20 @@ - - Icons / Project Configurator / Gems / Material Editor - - - - + + Icons / Application Icons / Material Editor + + + + + + + + + + + + + + + - + \ No newline at end of file From 757a26825ac5a4e09892a9af817c45a13eb44552 Mon Sep 17 00:00:00 2001 From: jromnoa Date: Mon, 10 May 2021 16:27:30 -0700 Subject: [PATCH 084/225] adds new HOST_OS_GENERIC_EXECUTABLE constant and adds error handling if the executable doesn't exist in the path provided --- Tools/LyTestTools/ly_test_tools/__init__.py | 1 + .../_internal/pytest_plugin/test_tools_fixtures.py | 4 ++-- .../ly_test_tools/launchers/launcher_helper.py | 2 +- .../launchers/platforms/win/launcher.py | 13 +++++++++++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/__init__.py b/Tools/LyTestTools/ly_test_tools/__init__.py index febb89b541..d534f5e0d2 100755 --- a/Tools/LyTestTools/ly_test_tools/__init__.py +++ b/Tools/LyTestTools/ly_test_tools/__init__.py @@ -37,6 +37,7 @@ if WINDOWS: HOST_OS_PLATFORM = 'windows' HOST_OS_EDITOR = 'windows_editor' HOST_OS_DEDICATED_SERVER = 'windows_dedicated' + HOST_OS_GENERIC_EXECUTABLE = 'windows_generic' import ly_test_tools.mobile.android from ly_test_tools.launchers import ( AndroidLauncher, WinLauncher, DedicatedWinLauncher, WinEditor, WinGenericLauncher) diff --git a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py index c3a9ffdc22..dc2e92f518 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py @@ -29,7 +29,7 @@ import ly_test_tools.environment.file_system import ly_test_tools.launchers.launcher_helper import ly_test_tools.launchers.platforms.base import ly_test_tools.environment.watchdog -from ly_test_tools import ALL_PLATFORM_OPTIONS, HOST_OS_PLATFORM +from ly_test_tools import ALL_PLATFORM_OPTIONS, HOST_OS_PLATFORM, HOST_OS_GENERIC_EXECUTABLE logger = logging.getLogger(__name__) @@ -287,7 +287,7 @@ def generic_launcher(workspace, request, crash_log_watchdog): # type: (...) -> ly_test_tools.launchers.platforms.base.Launcher return _generic_launcher( workspace=workspace, - launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_PLATFORM), + launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_GENERIC_EXECUTABLE), exe_file_name=get_fixture_argument(request, 'exe_file_name', '')) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/launcher_helper.py b/Tools/LyTestTools/ly_test_tools/launchers/launcher_helper.py index 63b1eac1d3..45f5e6e73f 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/launcher_helper.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/launcher_helper.py @@ -75,5 +75,5 @@ def create_generic_launcher(workspace, launcher_platform, exe_file_name, args=No :param args: List of arguments to pass to the launcher's 'args' argument during construction :return: Launcher instance. """ - launcher_class = ly_test_tools.LAUNCHERS.get(launcher_platform, ly_test_tools.HOST_OS_PLATFORM) + launcher_class = ly_test_tools.LAUNCHERS.get(launcher_platform, ly_test_tools.HOST_OS_GENERIC_EXECUTABLE) return launcher_class(workspace, exe_file_name, args) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py index 492af0e612..ebb3566806 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py @@ -210,12 +210,21 @@ class WinGenericLauncher(WinLauncher): def __init__(self, build, exe_file_name, args=None): super(WinGenericLauncher, self).__init__(build, args) self.exe_file_name = exe_file_name + self.expected_executable_path = os.path.join( + self.workspace.paths.build_directory(), f"{self.exe_file_name}.exe") + + if not os.path.exists(self.expected_executable_path): + raise ProcessNotStartedError( + f"Unable to locate executable '{self.exe_file_name}.exe' " + f"in path: '{self.expected_executable_path}'") def binary_path(self): """ Return full path to the .exe file for this build's configuration and project + Relies on the build_directory() in self.workspace.paths to be accurate :return: full path to the given exe file """ - assert self.workspace.project is not None - return os.path.join(self.workspace.paths.build_directory(), f"{self.exe_file_name}.exe") + assert self.workspace.project is not None, ( + 'Project cannot be NoneType - please specify a project name string.') + return self.expected_executable_path From 01b2798fe17a6307131a3c1b6ba74f78b826865b Mon Sep 17 00:00:00 2001 From: Vicky <55564570+VickyAtAZ@users.noreply.github.com> Date: Mon, 10 May 2021 16:46:25 -0700 Subject: [PATCH 085/225] Integrate from 1.0 to main: LYN-3436 AutomatedTesting.GameLauncher crashes at launch if assets are not all processed (#612) * Atom/qingtao/lyn 3436 (#558) * LYN-3436 AutomatedTesting.GameLauncher crashes at launch if assets are not all processed Change RPISystem so that the application would exit if the RPI system couldn't load critical assets. Added code to avoid the GetLayout crash when layout for each platforms were not ready. Added LoadCriticalAsset function to force compile and load critical assets. Added default value to viewport size for ViewportContext. * Change RPISystem asset initialization order so it returns earlier when those critical assets are not ready --- .../Code/Source/BootstrapSystemComponent.cpp | 13 +++++ .../Code/Include/Atom/RHI/CpuProfilerImpl.h | 2 + .../RHI/Code/Source/RHI/CpuProfilerImpl.cpp | 6 +++ Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp | 9 ++-- .../DX12/Code/Source/RHI/AsyncUploadQueue.cpp | 10 ++-- .../Code/Source/RHI/CommandQueueContext.cpp | 5 +- .../Atom/RPI.Public/Buffer/BufferSystem.h | 2 + .../Atom/RPI.Public/Image/ImageSystem.h | 2 + .../Atom/RPI.Public/Pass/PassLibrary.h | 2 +- .../Include/Atom/RPI.Public/Pass/PassSystem.h | 2 +- .../RPI.Public/Pass/PassSystemInterface.h | 2 +- .../Code/Include/Atom/RPI.Public/RPISystem.h | 1 + .../Atom/RPI.Public/RPISystemInterface.h | 3 ++ .../Atom/RPI.Reflect/Asset/AssetUtils.h | 27 +++++++++- .../Source/RPI.Public/Buffer/BufferSystem.cpp | 11 ++++ .../Source/RPI.Public/Image/ImageSystem.cpp | 7 +++ .../Source/RPI.Public/Pass/PassLibrary.cpp | 5 +- .../Source/RPI.Public/Pass/PassSystem.cpp | 4 +- .../RPI/Code/Source/RPI.Public/RPISystem.cpp | 52 +++++++++++-------- .../Source/RPI.Public/ViewportContext.cpp | 1 + .../Shader/ShaderResourceGroupAsset.cpp | 6 ++- 21 files changed, 134 insertions(+), 38 deletions(-) diff --git a/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp b/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp index ddf0ae9274..e3bdb28046 100644 --- a/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp +++ b/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -166,6 +167,18 @@ namespace AZ RPI::RPISystemInterface::Get()->InitializeSystemAssets(); + if (!RPI::RPISystemInterface::Get()->IsInitialized()) + { + AZ::OSString msgBoxMessage; + msgBoxMessage.append("RPI System could not initialize correctly. Check log for detail."); + + AZ::NativeUI::NativeUIRequestBus::Broadcast( + &AZ::NativeUI::NativeUIRequestBus::Events::DisplayOkDialog, "O3DE Fatal Error", msgBoxMessage.c_str(), false); + AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::ExitMainLoop); + + return; + } + // In the case of the game we want to call create and register the scene as a soon as we can // because a level could be loaded in autoexec.cfg and that will assert if there is no scene registered // to get the feature processors for the components. So we can't wait until the tick (whereas the Editor wants to wait) diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/CpuProfilerImpl.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/CpuProfilerImpl.h index 777a20ada9..30523194b6 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/CpuProfilerImpl.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/CpuProfilerImpl.h @@ -124,6 +124,8 @@ namespace AZ // This lock will only be contested when the CpuProfiler's Shutdown() method has been called AZStd::shared_mutex m_shutdownMutex; + + bool m_initialized = false; }; }; // namespace RPI diff --git a/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp b/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp index 28c3ef6a7b..8242c89886 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp @@ -82,10 +82,15 @@ namespace AZ void CpuProfilerImpl::Init() { Interface::Register(this); + m_initialized = true; } void CpuProfilerImpl::Shutdown() { + if (!m_initialized) + { + return; + } // When this call is made, no more thread profiling calls can be performed anymore Interface::Unregister(this); @@ -97,6 +102,7 @@ namespace AZ // Cleanup all TLS m_registeredThreads.clear(); m_timeRegionMap.clear(); + m_initialized = false; } void CpuProfilerImpl::BeginTimeRegion(TimeRegion& timeRegion) diff --git a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp index f92d2621b1..95e0a33981 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp @@ -200,9 +200,12 @@ namespace AZ m_platformLimitsDescriptor = nullptr; m_pipelineStateCache = nullptr; - m_device->PreShutdown(); - AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count()); - m_device = nullptr; + if (m_device) + { + m_device->PreShutdown(); + AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count()); + m_device = nullptr; + } m_cpuProfiler.Shutdown(); } diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp index f816a7ae04..22849f7236 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp @@ -90,12 +90,16 @@ namespace AZ void AsyncUploadQueue::Shutdown() { - m_copyQueue->Shutdown(); + if (m_copyQueue) + { + m_copyQueue->Shutdown(); + m_copyQueue = nullptr; + } m_commandList = nullptr; - for (size_t i = 0; i < m_descriptor.m_frameCount; ++i) + for (auto& framePacket : m_framePackets) { - m_framePackets[i].m_fence.Shutdown(); + framePacket.m_fence.Shutdown(); } m_framePackets.clear(); m_uploadFence.Shutdown(); diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp index 4c133084ac..a31e105b19 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp @@ -109,7 +109,10 @@ namespace AZ AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender); for (uint32_t hardwareQueueIdx = 0; hardwareQueueIdx < RHI::HardwareQueueClassCount; ++hardwareQueueIdx) { - m_commandQueues[hardwareQueueIdx]->WaitForIdle(); + if (m_commandQueues[hardwareQueueIdx]) + { + m_commandQueues[hardwareQueueIdx]->WaitForIdle(); + } } } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Buffer/BufferSystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Buffer/BufferSystem.h index 91d60bcb36..c4b6aa74b4 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Buffer/BufferSystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Buffer/BufferSystem.h @@ -45,6 +45,8 @@ namespace AZ private: RHI::Ptr m_commonPools[static_cast(CommonBufferPoolType::Count)]; + + bool m_initialized = false; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Image/ImageSystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Image/ImageSystem.h index 67f33758dc..b8f52a532e 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Image/ImageSystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Image/ImageSystem.h @@ -80,6 +80,8 @@ namespace AZ Data::Asset m_defaultStreamingImageControllerAsset; AZStd::fixed_vector, static_cast(SystemImage::Count)> m_systemImages; + + bool m_initialized = false; }; } } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h index e61b90d55a..283cea7c0a 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h @@ -82,7 +82,7 @@ namespace AZ void RemovePassFromLibrary(Pass* pass); //! Load pass templates which are list in an AssetAliases - void LoadPassTemplateMappings(const AZStd::string& templateMappingPath); + bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath); bool LoadPassTemplateMappings(Data::Asset mappingAsset); //! Returns a list of passes found in the pass name mapping using the provided pass filter diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h index acbb914dfa..d37868025c 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h @@ -66,7 +66,7 @@ namespace AZ // PassSystemInterface functions... void ProcessQueuedChanges() override; - void LoadPassTemplateMappings(const AZStd::string& templateMappingPath) override; + bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath) override; void WriteTemplateToFile(const PassTemplate& passTemplate, AZStd::string_view assetFilePath) override; void DebugPrintPassHierarchy() override; bool IsBuilding() const override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h index 93754c2229..82d52ab5a2 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h @@ -65,7 +65,7 @@ namespace AZ virtual void ProcessQueuedChanges() = 0; //! Load pass templates listed in a name-assetid mapping asset - virtual void LoadPassTemplateMappings(const AZStd::string& templateMappingPath) = 0; + virtual bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath) = 0; //! Writes a pass template to a .pass file which can then be used as a pass asset. Useful for //! quickly authoring a pass template in code and then outputting it as a pass asset using JSON diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystem.h index 80b9022f0d..ff3c784a51 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystem.h @@ -70,6 +70,7 @@ namespace AZ void Shutdown(); // RPISystemInterface overrides... + bool IsInitialized() const override; void InitializeSystemAssets() override; void RegisterScene(ScenePtr scene) override; void UnregisterScene(ScenePtr scene) override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h index 27b381257d..c2ceca73a9 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h @@ -40,6 +40,9 @@ namespace AZ //! Note: can't rely on the AzFramework::AssetCatalogEventBus's OnCatalogLoaded since the order of calling handlers is undefined. virtual void InitializeSystemAssets() = 0; + //! Was the RPI system initialized properly + virtual bool IsInitialized() const = 0; + //! Register a created scene to RPISystem. Registered scene will be simulated and rendered in RPISystem ticks virtual void RegisterScene(ScenePtr scene) = 0; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h index 527bae7e1f..5a169a9e61 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h @@ -15,6 +15,8 @@ #include #include +#include + namespace AZ { namespace RPI @@ -48,6 +50,12 @@ namespace AZ //! @return a null asset if the asset could not be found or loaded. template Data::Asset LoadAssetById(Data::AssetId assetId, TraceLevel reporting = TraceLevel::Warning); + + //! Loads a critial asset using a file path (both source and product path should be same), on the current thread. + //! If the asset wasn't compiled, wait until the asset is compiled. + //! @return a null asset if the asset could not be compiled or loaded. + template + Data::Asset LoadCriticalAsset(const AZStd::string& assetFilePath, TraceLevel reporting = TraceLevel::Error); template bool LoadBlocking(AZ::Data::Asset& asset, TraceLevel reporting = TraceLevel::Warning); @@ -89,7 +97,7 @@ namespace AZ assetId, AZ::Data::AssetLoadBehavior::PreLoad); asset.BlockUntilLoadComplete(); - if (!asset.Get()) + if (!asset.IsReady()) { AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not load '%s'", productPath).c_str()); return {}; @@ -117,7 +125,7 @@ namespace AZ ); asset.BlockUntilLoadComplete(); - if (!asset.Get()) + if (!asset.IsReady()) { AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not load '%s'", assetId.ToString().c_str()).c_str()); return {}; @@ -126,6 +134,21 @@ namespace AZ return asset; } + template + Data::Asset LoadCriticalAsset(const AZStd::string& assetFilePath, TraceLevel reporting) + { + AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; + AzFramework::AssetSystemRequestBus::BroadcastResult(status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilePath); + + if (status != AzFramework::AssetSystem::AssetStatus_Compiled) + { + AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not compile asset '%s'", assetFilePath.c_str()).c_str()); + return {}; + } + + return LoadAssetByProductPath(assetFilePath.c_str(), reporting); + } + template bool LoadBlocking(AZ::Data::Asset& asset, TraceLevel reporting) { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp index 491f57deec..9a9254b0d6 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp @@ -61,10 +61,16 @@ namespace AZ Data::InstanceDatabase::Create(azrtti_typeid(), handler); } Interface::Register(this); + + m_initialized = true; } void BufferSystem::Shutdown() { + if (!m_initialized) + { + return; + } for (uint8_t index = 0; index < static_cast(CommonBufferPoolType::Count); index++) { m_commonPools[index] = nullptr; @@ -72,6 +78,7 @@ namespace AZ Interface::Unregister(this); Data::InstanceDatabase::Destroy(); Data::InstanceDatabase::Destroy(); + m_initialized = false; } RHI::Ptr BufferSystem::GetCommonBufferPool(CommonBufferPoolType poolType) @@ -87,6 +94,10 @@ namespace AZ bool BufferSystem::CreateCommonBufferPool(CommonBufferPoolType poolType) { + if (!m_initialized) + { + return false; + } auto* device = RHI::RHISystemInterface::Get()->GetDevice(); RHI::Ptr bufferPool = RHI::Factory::Get().CreateBufferPool(); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Image/ImageSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Image/ImageSystem.cpp index ac7ba1e3cc..f7cdc2ff71 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Image/ImageSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Image/ImageSystem.cpp @@ -148,10 +148,16 @@ namespace AZ CreateDefaultResources(desc); Interface::Register(this); + + m_initialized = true; } void ImageSystem::Shutdown() { + if (!m_initialized) + { + return; + } Interface::Unregister(this); m_defaultStreamingImageControllerAsset.Release(); @@ -167,6 +173,7 @@ namespace AZ Data::InstanceDatabase::Destroy(); m_activeStreamingPools.clear(); + m_initialized = false; } void ImageSystem::Update() diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp index d8f6416abc..6c1f96e414 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp @@ -327,14 +327,15 @@ namespace AZ } } - void PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) + bool PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) { - Data::Asset mappingAsset = AssetUtils::LoadAssetByProductPath(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error); + Data::Asset mappingAsset = AssetUtils::LoadCriticalAsset(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error); bool success = LoadPassTemplateMappings(mappingAsset); if (success) { Data::AssetBus::MultiHandler::BusConnect(mappingAsset->GetId()); } + return success; } bool PassLibrary::LoadPassTemplateMappings(Data::Asset mappingAsset) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp index 55b71c6962..706d759231 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp @@ -100,9 +100,9 @@ namespace AZ m_rootPass->m_flags.m_partOfHierarchy = true; } - void PassSystem::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) + bool PassSystem::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) { - m_passLibrary.LoadPassTemplateMappings(templateMappingPath); + return m_passLibrary.LoadPassTemplateMappings(templateMappingPath); } void PassSystem::WriteTemplateToFile(const PassTemplate& passTemplate, AZStd::string_view assetFilePath) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp index 52c39d2204..5cd6f93715 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp @@ -334,7 +334,6 @@ namespace AZ void RPISystem::InitializeSystemAssets() { - AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; if (m_systemAssetsInitialized) { AZ_Warning("RPISystem", false , "InitializeSystemAssets should only be called once'"); @@ -344,36 +343,47 @@ namespace AZ //[GFX TODO][ATOM-5867] - Move file loading code within RHI to reduce coupling with RPI AZStd::string platformLimitsFilePath = AZStd::string::format("config/platform/%s/%s/platformlimits.azasset", AZ_TRAIT_OS_PLATFORM_NAME, GetRenderApiName().GetCStr()); AZStd::to_lower(platformLimitsFilePath.begin(), platformLimitsFilePath.end()); - // Wait for the platformlimits asset to be compiled (if it exists) - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, platformLimitsFilePath); - Data::Asset platformLimitsAsset = RPI::AssetUtils::LoadAssetByProductPath(platformLimitsFilePath.c_str(), RPI::AssetUtils::TraceLevel::Error); - m_descriptor.m_rhiSystemDescriptor.m_platformLimits = RPI::GetDataFromAnyAsset(platformLimitsAsset); + + Data::Asset platformLimitsAsset; + platformLimitsAsset = RPI::AssetUtils::LoadCriticalAsset(platformLimitsFilePath.c_str(), RPI::AssetUtils::TraceLevel::None); + // Only read the m_platformLimits if the platformLimitsAsset is ready. + // The platformLimitsAsset may not exist for null renderer which is allowed + if (platformLimitsAsset.IsReady()) + { + m_descriptor.m_rhiSystemDescriptor.m_platformLimits = RPI::GetDataFromAnyAsset(platformLimitsAsset); + } + + m_viewSrgAsset = AssetUtils::LoadCriticalAsset( m_descriptor.m_viewSrgAssetPath.c_str()); + if (!m_viewSrgAsset.IsReady()) + { + return; + } + m_sceneSrgAsset = AssetUtils::LoadCriticalAsset(m_descriptor.m_sceneSrgAssetPath.c_str()); + if (!m_sceneSrgAsset.IsReady()) + { + return; + } m_rhiSystem.Init(m_descriptor.m_rhiSystemDescriptor); m_imageSystem.Init(m_descriptor.m_imageSystemDescriptor); m_bufferSystem.Init(); m_dynamicDraw.Init(m_descriptor.m_dynamicDrawSystemDescriptor); - // Wait for the assets be compiled - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_viewSrgAssetPath); - AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile view SRG at '%s'", m_descriptor.m_viewSrgAssetPath.c_str()); - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_sceneSrgAssetPath); - AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile scene SRG at '%s'", m_descriptor.m_sceneSrgAssetPath.c_str()); - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_passTemplatesMappingPath); - AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile pass template mapping at '%s'", m_descriptor.m_passTemplatesMappingPath.c_str()); - - m_viewSrgAsset = AssetUtils::LoadAssetByProductPath(m_descriptor.m_viewSrgAssetPath.c_str(), AssetUtils::TraceLevel::Error); - m_sceneSrgAsset = AssetUtils::LoadAssetByProductPath(m_descriptor.m_sceneSrgAssetPath.c_str(), AssetUtils::TraceLevel::Error); - // Have pass system load default pass template mapping - m_passSystem.LoadPassTemplateMappings(m_descriptor.m_passTemplatesMappingPath); + bool passSystemReady = m_passSystem.LoadPassTemplateMappings(m_descriptor.m_passTemplatesMappingPath); + if (!passSystemReady) + { + return; + } + m_systemAssetsInitialized = true; } + bool RPISystem::IsInitialized() const + { + return m_systemAssetsInitialized; + } + void RPISystem::InitializeSystemAssetsForTests() { if (m_systemAssetsInitialized) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp index b5d3f815fe..4bccd48b66 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp @@ -26,6 +26,7 @@ namespace AZ , m_windowContext(AZStd::make_shared()) , m_manager(manager) , m_name(name) + , m_viewportSize(1, 1) { m_windowContext->Initialize(device, nativeWindow); AzFramework::WindowRequestBus::EventResult( diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderResourceGroupAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderResourceGroupAsset.cpp index d372e1442d..d8f8c7d1ce 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderResourceGroupAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderResourceGroupAsset.cpp @@ -41,7 +41,11 @@ namespace AZ const RHI::ShaderResourceGroupLayout* ShaderResourceGroupAsset::GetLayout() const { - AZ_Assert(m_currentAPITypeIndex < m_perAPILayout.size(), "Invalid API Type index"); + AZ_Error("RHI::ShaderResourceGroupLayout", m_currentAPITypeIndex < m_perAPILayout.size(), "Invalid API Type index"); + if (m_currentAPITypeIndex >= m_perAPILayout.size()) + { + return nullptr; + } return m_perAPILayout[m_currentAPITypeIndex].second.get(); } From d26c4614ba270c32357ef6f2fd2a4e02c54a72fd Mon Sep 17 00:00:00 2001 From: jromnoa Date: Mon, 10 May 2021 16:48:38 -0700 Subject: [PATCH 086/225] add unit tests for WinGenericLauncher class --- .../tests/unit/test_launcher_win.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Tools/LyTestTools/tests/unit/test_launcher_win.py b/Tools/LyTestTools/tests/unit/test_launcher_win.py index 193589f457..37e04ac99e 100755 --- a/Tools/LyTestTools/tests/unit/test_launcher_win.py +++ b/Tools/LyTestTools/tests/unit/test_launcher_win.py @@ -184,3 +184,31 @@ class TestDedicatedWinLauncher(object): launcher.workspace.build(dedicated=True) mock_workspace.build.assert_called_once_with(dedicated=True) + + +class TestWinGenericLauncher(object): + + @mock.patch('ly_test_tools.launchers.platforms.win.launcher.os.path.exists') + def test_BinaryPath_DummyPathExeExists_AddPathToExe(self, mock_os_path_exists): + dummy_path = "dummy_workspace_path" + dummy_executable = 'SomeCustomLauncher.exe' + mock_os_path_exists.return_value = True + mock_workspace = mock.MagicMock() + mock_workspace.paths.build_directory.return_value = dummy_path + launcher = ly_test_tools.launchers.WinGenericLauncher(mock_workspace, dummy_executable, ["some_args"]) + + under_test = launcher.binary_path() + + assert dummy_executable in under_test, f"executable named {dummy_executable} not found" + assert dummy_path in under_test, "workspace path unexpectedly missing " + + @mock.patch('ly_test_tools.launchers.platforms.win.launcher.os.path.exists') + def test_BinaryPath_DummyPathExeDoesNotExist_RaiseProcessNotStartedError(self, mock_os_path_exists): + dummy_path = "dummy_workspace_path" + dummy_executable = 'SomeCustomLauncher.exe' + mock_os_path_exists.return_value = False + mock_workspace = mock.MagicMock() + mock_workspace.paths.build_directory.return_value = dummy_path + + with pytest.raises(ly_test_tools.launchers.exceptions.ProcessNotStartedError): + ly_test_tools.launchers.WinGenericLauncher(mock_workspace, dummy_executable, ["some_args"]) From 43f87d1541a3d810c782845935e14e57739d14ed Mon Sep 17 00:00:00 2001 From: mnaumov Date: Mon, 10 May 2021 17:58:12 -0700 Subject: [PATCH 087/225] another attempt fixing the artifacts --- .../Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl | 3 ++- Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl | 2 +- .../Materials/Types/StandardMultilayerPBR_ForwardPass.azsl | 3 ++- .../Assets/Materials/Types/StandardPBR_ForwardPass.azsl | 5 +++-- .../Features/LightCulling/LightCullingTileIterator.azsli | 6 +++--- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index 367b2e379c..34c57db974 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -163,6 +163,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float { DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, IN.m_shadowCoords); } + IN.m_position.w = mul(ViewSrg::m_viewProjectionMatrix, IN.m_worldPosition).z; } } @@ -268,7 +269,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float LightingData lightingData; // Light iterator - lightingData.tileIterator.Init(IN.m_position.xy, IN.m_position.z, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); // Directional light shadow coordinates diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl index c81d96d552..84095ac163 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl @@ -324,7 +324,7 @@ PbrLightingOutput SkinPS_Common(VSOutput IN) LightingData lightingData; // Light iterator - lightingData.tileIterator.Init(IN.m_position.xy, IN.m_position.z, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); // Directional light shadow coordinates diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl index 5c527998c1..9cc0047b72 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl @@ -195,6 +195,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float { DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, IN.m_shadowCoords); } + IN.m_position.w = mul(ViewSrg::m_viewProjectionMatrix, IN.m_worldPosition).z; } } @@ -303,7 +304,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float LightingData lightingData; // Light iterator - lightingData.tileIterator.Init(IN.m_position.xy, IN.m_position.z, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); // Directional light shadow coordinates diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl index dc20f89a75..8621865f54 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl @@ -125,7 +125,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // ------- Depth & Parallax ------- - depth = IN.m_position.w; + depth = IN.m_position.z; bool displacementIsClipped = false; @@ -147,6 +147,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float { DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, IN.m_shadowCoords); } + IN.m_position.w = mul(ViewSrg::m_viewProjectionMatrix, IN.m_worldPosition).z; } } @@ -210,7 +211,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float LightingData lightingData; // Light iterator - lightingData.tileIterator.Init(IN.m_position.xy, IN.m_position.z, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); + lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData); lightingData.Init(surface.position, surface.normal, surface.roughnessLinear); // Directional light shadow coordinates diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli index 314a8951a4..001f672631 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli @@ -17,13 +17,13 @@ // This class is used by forward shaders to iterate through lights (and decals) that are visible at this pixel position class LightCullingTileIterator { - void Init(float2 screenPos, float depth, StructuredBuffer lightListRemapped, Texture2D tileLightDataTex) + void Init(float4 svPosition, StructuredBuffer lightListRemapped, Texture2D tileLightDataTex) { m_lightListRemapped = lightListRemapped; - uint2 tileId = ComputeTileId(screenPos); + uint2 tileId = ComputeTileId(svPosition.xy); - float viewz = abs(depth); + float viewz = abs(svPosition.w); // https://jira.agscollab.com/browse/ATOM-4198 // Replace GetDimensions() with a cbuffer uint read. Reading it from a cbuffer should be faster From 36911723c2b9054468db629a23fa5cc9b1dfbc8d Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 18:17:39 -0700 Subject: [PATCH 088/225] Addressed PR feedback --- .../AzCore/Asset/AssetJsonSerializer.cpp | 24 ++++++++++--- .../AzCore/AzCore/Asset/AssetJsonSerializer.h | 14 ++++++++ .../AzCore/Asset/SerializedAssetTracker.cpp | 34 ------------------- .../AzCore/Asset/SerializedAssetTracker.h | 34 ------------------- .../AzCore/AzCore/azcore_files.cmake | 2 -- .../Prefab/PrefabDomUtils.cpp | 9 +++-- .../AzToolsFramework/Prefab/PrefabDomUtils.h | 14 ++++---- 7 files changed, 44 insertions(+), 87 deletions(-) delete mode 100644 Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp delete mode 100644 Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp index 6968b51025..0078abf2d1 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -112,8 +111,8 @@ namespace AZ AssetId id; JSR::ResultCode result(JSR::Tasks::ReadField); - SerializedAssetTracker** assetIdTracker = - context.GetMetadata().Find(); + SerializedAssetTracker* assetTracker = + context.GetMetadata().Find(); { Data::AssetLoadBehavior loadBehavior = instance->GetAutoLoadBehavior(); @@ -168,9 +167,9 @@ namespace AZ "The asset hint is missing for Asset, so it will be left empty.")); } - if (assetIdTracker && *assetIdTracker) + if (assetTracker) { - (*assetIdTracker)->AddAsset(*instance); + assetTracker->AddAsset(*instance); } bool success = result.GetOutcome() <= JSR::Outcomes::PartialSkip; @@ -181,5 +180,20 @@ namespace AZ "Not enough information was available to create an instance of Asset or data was corrupted."; return context.Report(result, message); } + + void SerializedAssetTracker::AddAsset(Asset& asset) + { + m_serializedAssets.emplace_back(asset); + } + + const AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() const + { + return m_serializedAssets; + } + + AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() + { + return m_serializedAssets; + } } // namespace Data } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h index 3d5271035c..dca12df21b 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h @@ -13,6 +13,7 @@ #pragma once #include +#include #include namespace AZ @@ -37,5 +38,18 @@ namespace AZ private: JsonSerializationResult::Result LoadAsset(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context); }; + + class SerializedAssetTracker + { + public: + AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}"); + + void AddAsset(Asset& asset); + AZStd::vector>& GetTrackedAssets(); + const AZStd::vector>& GetTrackedAssets() const; + + private: + AZStd::vector> m_serializedAssets; + }; } // namespace Data } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp deleted file mode 100644 index bdd89683f6..0000000000 --- a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -namespace AZ -{ - namespace Data - { - void SerializedAssetTracker::AddAsset(Asset& asset) - { - m_serializedAssets.emplace_back(asset); - } - - const AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() const - { - return m_serializedAssets; - } - - AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() - { - return m_serializedAssets; - } - } -} diff --git a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h b/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h deleted file mode 100644 index ad80a077fe..0000000000 --- a/Code/Framework/AzCore/AzCore/Asset/SerializedAssetTracker.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -namespace AZ -{ - namespace Data - { - class SerializedAssetTracker - { - public: - AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}"); - - void AddAsset(Asset& asset); - AZStd::vector>& GetTrackedAssets(); - const AZStd::vector>& GetTrackedAssets() const; - - private: - AZStd::vector> m_serializedAssets; - }; - } -} diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index c6ad90200b..5357ed66a6 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -35,8 +35,6 @@ set(FILES Asset/AssetSerializer.h Asset/AssetTypeInfoBus.h Asset/AssetInternal/WeakAsset.h - Asset/SerializedAssetTracker.cpp - Asset/SerializedAssetTracker.h Casting/lossy_cast.h Casting/numeric_cast.h Component/Component.cpp diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index 9163b681de..0bffd26be0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include @@ -132,15 +132,13 @@ namespace AzToolsFramework entityIdMapper.SetEntityIdGenerationApproach(InstanceEntityIdMapper::EntityIdGenerationApproach::Random); } - AZ::Data::SerializedAssetTracker assetTracker; - AZ::JsonDeserializerSettings settings; // The InstanceEntityIdMapper is registered twice because it's used in several places during deserialization where one is // specific for the InstanceEntityIdMapper and once for the generic JsonEntityIdMapper. Because the Json Serializer's meta // data has strict typing and doesn't look for inheritance both have to be explicitly added so they're found both locations. settings.m_metadata.Add(static_cast(&entityIdMapper)); settings.m_metadata.Add(&entityIdMapper); - settings.m_metadata.Add(&assetTracker); + settings.m_metadata.Create(); AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Load(instance, prefabDom, settings); @@ -155,8 +153,9 @@ namespace AzToolsFramework return false; } + AZ::Data::SerializedAssetTracker* assetTracker = settings.m_metadata.Find(); - referencedAssets = AZStd::move(assetTracker.GetTrackedAssets()); + referencedAssets = AZStd::move(assetTracker->GetTrackedAssets()); return true; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index 6778c236ee..c7c2827770 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -43,7 +43,7 @@ namespace AzToolsFramework /** * Stores a valid Prefab Instance within a Prefab Dom. Useful for generating Templates * @param instance The instance to store - * @param prefabDom the prefabDom that will be used to store the Instance data + * @param prefabDom The prefabDom that will be used to store the Instance data * @return bool on whether the operation succeeded */ bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom); @@ -61,8 +61,8 @@ namespace AzToolsFramework /** * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. * @param instance The Instance to load. - * @param prefabDom the prefabDom that will be used to load the Instance data. - * @param shouldClearContainers whether to clear containers in Instance while loading. + * @param prefabDom The prefabDom that will be used to load the Instance data. + * @param shouldClearContainers Whether to clear containers in Instance while loading. * @return bool on whether the operation succeeded. */ bool LoadInstanceFromPrefabDom( @@ -72,8 +72,8 @@ namespace AzToolsFramework * Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances. * @param instance The Instance to load. * @param referencedAssets AZ::Assets discovered during json load are added to this list - * @param prefabDom the prefabDom that will be used to load the Instance data. - * @param shouldClearContainers whether to clear containers in Instance while loading. + * @param prefabDom The prefabDom that will be used to load the Instance data. + * @param shouldClearContainers Whether to clear containers in Instance while loading. * @return bool on whether the operation succeeded. */ bool LoadInstanceFromPrefabDom( @@ -85,8 +85,8 @@ namespace AzToolsFramework * @param instance The Instance to load. * @param newlyAddedEntities The new instances added during deserializing the instance. These are the entities found * in the prefabDom. - * @param prefabDom the prefabDom that will be used to load the Instance data. - * @param shouldClearContainers whether to clear containers in Instance while loading. + * @param prefabDom The prefabDom that will be used to load the Instance data. + * @param shouldClearContainers Whether to clear containers in Instance while loading. * @return bool on whether the operation succeeded. */ bool LoadInstanceFromPrefabDom( From 12fb07c3e32289707616bf66563b95a79b66b46e Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 18:56:29 -0700 Subject: [PATCH 089/225] Fix for failing AssetJsonSerializer conformity tests --- Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp | 2 +- Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp index 0078abf2d1..17b0cba09d 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp @@ -129,7 +129,7 @@ namespace AZ if (it != inputValue.MemberEnd()) { ScopedContextPath subPath(context, "assetId"); - result = ContinueLoading(&id, azrtti_typeid(), it->value, context); + result.Combine(ContinueLoading(&id, azrtti_typeid(), it->value, context)); if (!id.m_guid.IsNull()) { *instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), instance->GetAutoLoadBehavior()); diff --git a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp index a494207850..bacbc3649d 100644 --- a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp @@ -130,6 +130,7 @@ namespace JsonSerializationTests auto instance = AZStd::make_shared(); instance->Create(id, false); instance->SetHint("TestFile"); + instance->SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad); return instance; } @@ -153,6 +154,7 @@ namespace JsonSerializationTests "guid": "{BBEAC89F-8BAD-4A9D-BF6E-D0DF84A8DFD6}", "subId": 1 }, + "loadBehavior": "PreLoad", "assetHint": "TestFile" })"; } From 5cff7994bfce1a1ddce2f6199ff9e1775786458e Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 19:00:24 -0700 Subject: [PATCH 090/225] Small update to AssetJsonSerializer result assignment --- Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp index 17b0cba09d..555eedf034 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp @@ -117,10 +117,10 @@ namespace AZ { Data::AssetLoadBehavior loadBehavior = instance->GetAutoLoadBehavior(); - result.Combine( + result = ContinueLoadingFromJsonObjectField(&loadBehavior, azrtti_typeid(), - inputValue, "loadBehavior", context)); + inputValue, "loadBehavior", context); instance->SetAutoLoadBehavior(loadBehavior); } From 286a1aafa984519cb67eda776216362796ec2bb1 Mon Sep 17 00:00:00 2001 From: sconel Date: Mon, 10 May 2021 19:11:51 -0700 Subject: [PATCH 091/225] Clang build fix --- Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h index dca12df21b..780066cd42 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h @@ -39,7 +39,7 @@ namespace AZ JsonSerializationResult::Result LoadAsset(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context); }; - class SerializedAssetTracker + class SerializedAssetTracker final { public: AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}"); From fcbdd9e418fd85a1c69ff48c0dcc552e05e36acb Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Mon, 10 May 2021 19:34:54 -0700 Subject: [PATCH 092/225] Added RHI feature flag for unbounded arrays --- Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/DeviceFeatures.h | 3 +++ Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp | 2 ++ Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp | 1 + 3 files changed, 6 insertions(+) diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/DeviceFeatures.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/DeviceFeatures.h index 246db1522a..94d1cbd9ae 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/DeviceFeatures.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/DeviceFeatures.h @@ -76,6 +76,9 @@ namespace AZ //! Whether Ray Tracing support is available. bool m_rayTracing = false; + //! Whether Unbounded Array support is available. + bool m_unboundedArrays = false; + /// Additional features here. }; } diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp index 2c47a5a443..af94aef3fb 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp @@ -166,6 +166,8 @@ namespace AZ m_features.m_rayTracing = false; #endif + m_features.m_unboundedArrays = true; + m_limits.m_maxImageDimension1D = D3D12_REQ_TEXTURE1D_U_DIMENSION; m_limits.m_maxImageDimension2D = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; m_limits.m_maxImageDimension3D = D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp index ff7eb7f4c0..76662ebc6e 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Device.cpp @@ -720,6 +720,7 @@ namespace AZ StringList deviceExtensions = physicalDevice.GetDeviceExtensionNames(); StringList::iterator itRayTracingExtension = AZStd::find(deviceExtensions.begin(), deviceExtensions.end(), VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); m_features.m_rayTracing = (itRayTracingExtension != deviceExtensions.end()); + m_features.m_unboundedArrays = true; const auto& deviceLimits = physicalDevice.GetDeviceLimits(); m_limits.m_maxImageDimension1D = deviceLimits.maxImageDimension1D; From 8ddfcabae7f40a68abf8dddebf09ba1c6ec7f718 Mon Sep 17 00:00:00 2001 From: Terry Michaels <81711813+tjmichaels@users.noreply.github.com> Date: Mon, 10 May 2021 22:02:30 -0500 Subject: [PATCH 093/225] Removed unneeded comments (#673) --- ...8977329_NvCloth_AddClothSimulationToMesh.py | 1 - ...977330_NvCloth_AddClothSimulationToActor.py | 1 - .../C28798177_WhiteBox_AddComponentToEntity.py | 1 - .../C28798205_WhiteBox_SetInvisible.py | 1 - .../C29279329_WhiteBox_SetDefaultShape.py | 1 - ...ScriptCanvas_SetKinematicTargetTransform.py | 2 +- .../C3510644_Collider_CollisionGroups.py | 1 - .../C6321601_Force_HighValuesDirectionAxes.py | 2 +- .../physics/TestSuite_InDevelopment.py | 2 +- .../physics/UtilTest_Physmaterial_Editor.py | 2 +- .../AssetEditor_CreateScriptEventFile.py | 1 - .../scripting/AssetEditor_NewScriptEvent.py | 1 - .../Debugging_TargetMultipleEntities.py | 1 - .../Debugging_TargetMultipleGraphs.py | 1 - .../Gem/PythonTests/scripting/Docking_Pane.py | 1 - .../PythonTests/scripting/EditMenu_UndoRedo.py | 2 -- .../Entity_AddScriptCanvasComponent.py | 1 - .../PythonTests/scripting/FileMenu_New_Open.py | 2 -- .../scripting/GraphClose_SavePrompt.py | 2 -- .../scripting/Graph_ZoomInZoomOut.py | 2 -- .../scripting/NodeCategory_ExpandOnClick.py | 1 - .../scripting/NodeInspector_RenameVariable.py | 1 - .../scripting/NodePalette_ClearSelection.py | 1 - .../scripting/NodePalette_SelectNode.py | 1 - ...nEntityActivatedDeactivated_PrintMessage.py | 1 - .../scripting/Opening_Closing_Pane.py | 2 -- .../scripting/Pane_RetainOnSCRestart.py | 2 -- .../Gem/PythonTests/scripting/Resizing_Pane.py | 1 - .../scripting/ScriptCanvas_ChangingAssets.py | 1 - .../scripting/ScriptCanvas_TwoComponents.py | 1 - .../scripting/ScriptCanvas_TwoEntities.py | 1 - .../ScriptEvents_SendReceiveAcrossMultiple.py | 1 - .../ScriptEvents_SendReceiveSuccessfully.py | 1 - .../scripting/Toggle_ScriptCanvasTools.py | 5 ----- .../scripting/UnDockedPane_CloseSCWindow.py | 2 -- .../VariableManager_CreateDeleteVars.py | 2 -- .../AtomCore/Serialization/Json/JsonUtils.cpp | 2 +- .../AzToolsFramework/Slice/SliceUtilities.cpp | 2 +- .../Editor/Core/LevelEditorMenuHandler.cpp | 2 +- .../ShaderLib/Atom/Features/BlendUtility.azsli | 2 -- .../LightCullingTileIterator.azsli | 2 +- .../Shaders/LightCulling/LightCulling.azsl | 18 +++++++++--------- .../LightCulling/LightCullingHeatmap.azsl | 2 +- .../LightCulling/LightCullingRemap.azsl | 2 +- .../LightCulling/LightCullingTilePrepare.azsl | 2 +- .../PostProcessing/DepthOfFieldBlurBokeh.azsl | 5 ----- .../PostProcessing/DepthOfFieldComposite.azsl | 1 - .../DirectionalLightFeatureProcessor.cpp | 1 - .../Source/CoreLights/LightCullingRemap.cpp | 2 +- .../DepthOfField/DepthOfFieldSettings.cpp | 3 +-- .../DepthOfField/DepthOfFieldSettings.h | 1 - .../DepthOfFieldBokehBlurPass.cpp | 1 - .../PostProcessing/DepthOfFieldPencilMap.h | 2 -- .../Editor/Scripts/bootstrap.py | 2 +- .../SDK/Maya/Scripts/userSetup.py | 2 +- .../azpy/dev/ide/wing/readme.txt | 4 ++-- .../azpy/shared/common/core_utils.py | 2 +- .../azpy/shared/common/envar_utils.py | 2 +- .../Code/Tests/MorphSkinAttachmentTests.cpp | 4 ++-- .../XmlBuilderWorker/XmlBuilderWorker.cpp | 4 ++-- .../Code/Editor/UiEditorEntityContext.cpp | 2 +- .../Interpreted/ExecutionInterpretedAPI.cpp | 4 ++-- .../ScriptCanvas/Grammar/AbstractCodeModel.cpp | 2 +- ...shot_comparison_atomsampleviewer_windows.py | 2 +- .../product_dependency_tests/TestFixtures.py | 4 ++-- scripts/build/tools/email_to_lionbridge.py | 2 +- 66 files changed, 40 insertions(+), 98 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py index 625c9772bd..5cfc57fd5f 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py @@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C18977329 # Test Case Title : Add cloth simulation to a Mesh -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/18977329 # fmt: off class Tests: diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py index 9b3135cd2b..c21df8ea4c 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py @@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C18977330 # Test Case Title : Add cloth simulation to an Actor -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/18977330 # fmt: off class Tests: diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798177_WhiteBox_AddComponentToEntity.py b/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798177_WhiteBox_AddComponentToEntity.py index dabc04575f..86a27e588e 100755 --- a/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798177_WhiteBox_AddComponentToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798177_WhiteBox_AddComponentToEntity.py @@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C28798177 # Test Case Title : White Box Tool Component can be added to an Entity -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/28798177 # fmt:off diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798205_WhiteBox_SetInvisible.py b/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798205_WhiteBox_SetInvisible.py index 18a5c3164e..7a2a08a8ce 100755 --- a/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798205_WhiteBox_SetInvisible.py +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798205_WhiteBox_SetInvisible.py @@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C28798205 # Test Case Title : From the White Box Component Card the White Box Mesh can be set to be invisible in Game View -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/28798205 # fmt:off diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/C29279329_WhiteBox_SetDefaultShape.py b/AutomatedTesting/Gem/PythonTests/WhiteBox/C29279329_WhiteBox_SetDefaultShape.py index e892285dde..635c804914 100755 --- a/AutomatedTesting/Gem/PythonTests/WhiteBox/C29279329_WhiteBox_SetDefaultShape.py +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/C29279329_WhiteBox_SetDefaultShape.py @@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C29279329 # Test Case Title : White Box mesh shape can be changed with the Default Shape dropdown on the Component -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/29279329 # fmt:off diff --git a/AutomatedTesting/Gem/PythonTests/physics/C14976308_ScriptCanvas_SetKinematicTargetTransform.py b/AutomatedTesting/Gem/PythonTests/physics/C14976308_ScriptCanvas_SetKinematicTargetTransform.py index c76c5cab80..8400364626 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C14976308_ScriptCanvas_SetKinematicTargetTransform.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C14976308_ScriptCanvas_SetKinematicTargetTransform.py @@ -68,7 +68,7 @@ def C14976308_ScriptCanvas_SetKinematicTargetTransform(): the script deactivates Signal, Sphere's transform will update to that of Transform_Target. NOTE: There is a known bug (LY-107723) which causes the rotation to update to a value that is not sufficiently close to the expected result when using Set Kinematic Target which will cause the test to fail: - https://jira.agscollab.com/browse/LY-107723 + LY-107723 Test Steps: 1) Open level and enter game mode diff --git a/AutomatedTesting/Gem/PythonTests/physics/C3510644_Collider_CollisionGroups.py b/AutomatedTesting/Gem/PythonTests/physics/C3510644_Collider_CollisionGroups.py index 4ae10288bd..e714da9de7 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C3510644_Collider_CollisionGroups.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C3510644_Collider_CollisionGroups.py @@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C3510644 # Test Case Title : Check that the collision layer and collision group of the terrain can be changed # and the collision behavior of the terrain changes accordingly -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/3510644 # fmt: off diff --git a/AutomatedTesting/Gem/PythonTests/physics/C6321601_Force_HighValuesDirectionAxes.py b/AutomatedTesting/Gem/PythonTests/physics/C6321601_Force_HighValuesDirectionAxes.py index 4b0b036970..08083a7868 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C6321601_Force_HighValuesDirectionAxes.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C6321601_Force_HighValuesDirectionAxes.py @@ -239,7 +239,7 @@ def C6321601_Force_HighValuesDirectionAxes(): force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force) # Wait for 3 secs, because there is a known bug identified and filed in - # JIRA https://jira.agscollab.com/browse/LY-107677 + # JIRA LY-107677 # The error "[Error] Huge object being added to a COctreeNode, name: 'MeshComponentRenderNode', objBox:" # will show (if occured) in about 3 sec into the game mode. helper.wait_for_condition(has_physx_error, 3.0) diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_InDevelopment.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_InDevelopment.py index 8f098941ea..8986c1024a 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_InDevelopment.py +++ b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_InDevelopment.py @@ -50,7 +50,7 @@ class TestAutomation(TestAutomationBase): unexpected_lines = ["Assert"] self._run_test(request, workspace, editor, test_module, expected_lines, unexpected_lines) - # BUG: https://jira.agscollab.com/browse/LY-107723") + # BUG: LY-107723") def test_C14976308_ScriptCanvas_SetKinematicTargetTransform(self, request, workspace, editor): from . import C14976308_ScriptCanvas_SetKinematicTargetTransform as test_module diff --git a/AutomatedTesting/Gem/PythonTests/physics/UtilTest_Physmaterial_Editor.py b/AutomatedTesting/Gem/PythonTests/physics/UtilTest_Physmaterial_Editor.py index 5f24f41083..b6d7c610e3 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/UtilTest_Physmaterial_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/physics/UtilTest_Physmaterial_Editor.py @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ''' This unittest might have to be refactored once changes to Physmaterial_Editor.py are made. These changes will occur after the but, reverence below is resloved. -Bug: https://jira.agscollab.com/browse/LY-107392 +Bug: LY-107392 ''' class Tests: opening_bad_file = ("Bad file could not be opened", "Bad file was opened") diff --git a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py index dcbbf47f0c..b844f9e4af 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92569013 Test Case Title: Script Event file can be created -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569013 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py index 1f801d4eeb..e4fec76fe2 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py @@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92568942 Test Case Title: Clicking the "+" button and selecting "New Script Event" opens the Asset Editor with a new Script Event asset -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568942 """ from PySide2 import QtWidgets diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py index a26cb4f923..0947b0bb51 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py @@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92568856 Test Case Title: Multiple Entities can be targeted in the Debugger tool -URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568856 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py index 4aa5c822a7..8d2c39f288 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py @@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92569137 Test Case Title: Multiple Graphs can be targeted in the Debugger tool -URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569137 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py index 4fa1e1257f..537b4d817a 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: C1702824 Test Case Title: Docking -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702824 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py index a87d9e9be9..38ceb8335b 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py @@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92569049 Test Case Title: Edit > Undo undoes the last action -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569049 Test case ID: T92569051 Test Case Title: Edit > Redo redoes the last undone action -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569051 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py b/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py index fd8e9b1173..47bbb955ec 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92562978 Test Case Title: Script Canvas Component can be added to an entity -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562978 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py index f72ac8ea01..3206590a8d 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py @@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92569037 Test Case Title: File > New Script creates a new script -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569037 Test case ID: T92569039 Test Case Title: File > Open opens the Open... dialog -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569039 """ import os diff --git a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py index ce610b159b..ec8f0c8fb6 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py @@ -11,11 +11,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92563070 Test Case Title: Graphs can be closed by clicking X on the Graph name tab -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563070 Test case ID: T92563068 Test Case Title: Save Prompt: User is prompted to save a graph on close after creating a new graph -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563068 """ import os diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py b/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py index a93b6e61d1..d2765bfdf7 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py @@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92569079 Test Case Title: View > Zoom In zooms the graph in -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569079 Test case ID: T92569081 Test Case Title: View > Zoom In zooms the graph out -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569081 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodeCategory_ExpandOnClick.py b/AutomatedTesting/Gem/PythonTests/scripting/NodeCategory_ExpandOnClick.py index 00a19d1715..141cdbea8d 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodeCategory_ExpandOnClick.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodeCategory_ExpandOnClick.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92562988 Test Case Title: Left-click/double click expands and collapses node categories -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562988 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py index 33d3f4137a..550969e32a 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92568982 Test Case Title: Renaming variables in the Node Inspector -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568982 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py index de30e46767..979bcff02e 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92562993 Test Case Title: Clicking the X button on the Search Box clears the currently entered string -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562993 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py index 2ab76071a6..374dc4e1a0 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py @@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92568940 Test Case Title: Categories and Nodes can be selected -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568940 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py b/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py index 51b63c4268..00893d6acb 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92569253 // T92569254 Test Case Title: On Entity Activated // On Entity Deactivated -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569253 // https://testrail.agscollab.com/index.php?/tests/view/92569254 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py index 666f052240..48c40eb05e 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py @@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: C1702834 // C1702823 Test Case Title: Opening pane // Closing pane -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702834 and - https://testrail.agscollab.com/index.php?/cases/view/1702823 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py index fa5e9e6068..adf9b5f35a 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py @@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: C1702821 // C1702832 Test Case Title: Retain visibility, size and location upon Script Canvas restart -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702821 and - https://testrail.agscollab.com/index.php?/cases/view/1702832 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py index 180f577953..bbae3afefd 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: C1702829 Test Case Title: Resizing pane -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702829 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py index 38d60ad871..bb4de4a6c9 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py @@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92562986 Test Case Title: Changing the assigned Script Canvas Asset on an entity properly updates level functionality -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562986 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py index 896bee96e5..6187ac81ba 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92563190 Test Case Title: A single Entity with two Script Canvas components works properly -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563190 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py index 401e6c0271..9453c31488 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92563191 Test Case Title: Two Entities can use the same Graph asset successfully at RunTime -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563191 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py index d671229cdf..a2913d3468 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92567321 Test Case Title: Script Events: Can send and receive a script event across multiple entities successfully -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567321 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py index b5e26d14ae..388e2bb7c0 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py @@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92567320 Test Case Title: Script Events: Can send and receive a script event successfully -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567320 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py b/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py index 4024e28277..42cc42de0d 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py @@ -13,11 +13,6 @@ Test Case Title: Tools > Node Palette toggles the Node Palette Tools > Node Inspector toggles the Node Inspector Tools > Bookmarks toggles the Bookmarks Tools > Variable Manager toggles the Variable Manager - -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/92569165 - https://testrail.agscollab.com/index.php?/cases/view/92569167 - https://testrail.agscollab.com/index.php?/cases/view/92569168 - https://testrail.agscollab.com/index.php?/cases/view/92569170 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py b/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py index 875f28ec95..da33a8ab80 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py @@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: C1702825 // C1702831 Test Case Title: Undocking // Closing script canvas with the pane floating -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702825 & - https://testrail.agscollab.com/index.php?/cases/view/1702831 """ diff --git a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py index 6facc324d4..8b5c78fa87 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py @@ -10,10 +10,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Test case ID: T92564789 Test Case Title: Each Variable type can be created -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92564789 Test case ID: T92568873 Test Case Title: Each Variable type can be deleted -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568873 """ diff --git a/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp b/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp index dbc0be55f9..dc7d26577b 100644 --- a/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp +++ b/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp @@ -189,7 +189,7 @@ namespace AZ if (!WasLoadSuccess(result.GetOutcome())) { // This if is a hack around fault in the JSON serialization system - // Jira: https://jira.agscollab.com/browse/LY-106587 + // Jira: LY-106587 if (message != "No part of the string could be interpreted as a uuid.") { deserializeError.append(message); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Slice/SliceUtilities.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Slice/SliceUtilities.cpp index 75070d9b41..4b73166b3d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Slice/SliceUtilities.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Slice/SliceUtilities.cpp @@ -1353,7 +1353,7 @@ namespace AzToolsFramework // Iterate over the entities left in the instance and if none of them have this // asset entity as its ancestor, then we want to remove it. // \todo - Investigate ways to make this non-linear time. Tricky since removed entities - // obviously aren't maintained in any maps. (https://jira.agscollab.com/browse/LY-88218) + // obviously aren't maintained in any maps. (LY-88218) bool foundAsAncestor = false; for (const AZ::Entity* instanceEntity : instanceEntities) { diff --git a/Code/Sandbox/Editor/Core/LevelEditorMenuHandler.cpp b/Code/Sandbox/Editor/Core/LevelEditorMenuHandler.cpp index 869fa2fe25..1bb8dc37c7 100644 --- a/Code/Sandbox/Editor/Core/LevelEditorMenuHandler.cpp +++ b/Code/Sandbox/Editor/Core/LevelEditorMenuHandler.cpp @@ -514,7 +514,7 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe /* * The following block of code is part of the feature "Isolation Mode" and is temporarily * disabled for 1.10 release. - * Jira: https://jira.agscollab.com/browse/LY-49532 + * Jira: LY-49532 // Isolate Selected QAction* isolateSelectedAction = editMenu->addAction(tr("Isolate Selected")); diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/BlendUtility.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/BlendUtility.azsli index 631a1403d7..5fac839088 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/BlendUtility.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/BlendUtility.azsli @@ -37,8 +37,6 @@ float3 TextureBlend_Overlay(float3 target, float3 blend) //! @return the resulting blended color float3 ApplyTextureBlend(float3 color, float3 blendColor, float factor, TextureBlendMode blendMode) { - // More info to help understand some of these blend modes: https://wiki.agscollab.com/pages/viewpage.action?pageId=15764930 - if(blendMode == TextureBlendMode::Multiply) { return factor * color * blendColor; diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli index 001f672631..e27cbc2195 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/LightCullingTileIterator.azsli @@ -25,7 +25,7 @@ class LightCullingTileIterator float viewz = abs(svPosition.w); - // https://jira.agscollab.com/browse/ATOM-4198 + // ATOM-4198 // Replace GetDimensions() with a cbuffer uint read. Reading it from a cbuffer should be faster uint tileWidth, tileHeight; tileLightDataTex.GetDimensions(tileWidth, tileHeight); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl index 0327a723d6..d08c572867 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCulling.azsl @@ -17,7 +17,7 @@ #include #include -enum QuadLightFlag // Copied from QuadLight.azsli. See https://jira.agscollab.com/browse/ATOM-3731 +enum QuadLightFlag // Copied from QuadLight.azsli. See ATOM-3731 { None = 0x00, EmitsBothDirections = 0x01, // 1 << 0, // Quad should emit light from both sides @@ -33,7 +33,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass { // Figure out how to remove duplicate struct definitions. // These are also defined in View.srg - // https://jira.agscollab.com/browse/ATOM-3731 + // ATOM-3731 struct SimplePointLight { @@ -372,7 +372,7 @@ void CullDecals(uint groupIndex, TileLightData tileLightData, float3 aabb_center float3 decalPosition = WorldToView_Point(decal.m_position); // just wrapping a bounding sphere around a cube for now to get a minor perf boost. i.e. the sphere radius is sqrt(x*x + y*y + z*z) - // https://jira.agscollab.com/browse/ATOM-4224 - try AABB-AABB and implement depth binning for the decals + // ATOM-4224 - try AABB-AABB and implement depth binning for the decals float maxHalfSize = max(max(decal.m_halfSize.x, decal.m_halfSize.y), decal.m_halfSize.z); float boundingSphereRadiusSqr = maxHalfSize * maxHalfSize * 3; @@ -380,7 +380,7 @@ void CullDecals(uint groupIndex, TileLightData tileLightData, float3 aabb_center if (potentiallyIntersects) { // Implement and profile fine-grained light culling testing - // https://jira.agscollab.com/browse/ATOM-3732 + // ATOM-3732 MarkLightAsVisibleInSharedMemory(decalIndex, 0xFFFF); } } @@ -393,7 +393,7 @@ void CullPointLight(uint lightIndex, float3 lightPosition, float invLightRadius, if (potentiallyIntersects) { // Implement and profile fine-grained light culling testing - // https://jira.agscollab.com/browse/ATOM-3732 + // ATOM-3732 uint inside = 0; float2 minmax = ComputePointLightMinMaxZ(rsqrt(invLightRadius), lightPosition); @@ -434,7 +434,7 @@ void CullSimpleSpotLights(uint groupIndex, TileLightData tileLightData, float3 a if (potentiallyIntersects) { // Implement and profile fine-grained light culling testing - // https://jira.agscollab.com/browse/ATOM-3732 + // ATOM-3732 uint inside = 0; float2 minmax = ComputeSimpleSpotLightMinMax(light, lightPosition); @@ -479,7 +479,7 @@ void CullDiskLights(uint groupIndex, TileLightData tileLightData, float3 aabb_ce if (potentiallyIntersects) { // Implement and profile fine-grained light culling testing - // https://jira.agscollab.com/browse/ATOM-3732 + // ATOM-3732 uint inside = 0; float2 minmax = ComputeDiskLightMinMax(light, lightPosition); @@ -507,7 +507,7 @@ void CullCapsuleLights(uint groupIndex, TileLightData tileLightData, float3 aabb if (potentiallyIntersects) { // Implement and profile fine-grained light culling testing - // https://jira.agscollab.com/browse/ATOM-3732 + // ATOM-3732 uint inside = 0; float2 minmax = ComputeCapsuleLightMinMax(light, lightMiddleView, lightFalloffRadius); @@ -522,7 +522,7 @@ void CullCapsuleLights(uint groupIndex, TileLightData tileLightData, float3 aabb void CullQuadLights(uint groupIndex, TileLightData tileLightData, float3 aabb_center, float3 aabb_extents) { // Implement and profile fine-grained light culling testing - // https://jira.agscollab.com/browse/ATOM-3732 + // ATOM-3732 for (uint lightIndex = groupIndex ; lightIndex < PassSrg::m_quadLightCount ; lightIndex += TILE_DIM_X * TILE_DIM_Y) { diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingHeatmap.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingHeatmap.azsl index 14a5f810cf..eae2acc0bc 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingHeatmap.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingHeatmap.azsl @@ -242,7 +242,7 @@ PSOutput MainPS(VSOutput IN) // Set this value to > 0 to actually see this pass. It is currently always active. OUT.m_color.w = PassSrg::m_heatmapOpacity; - // https://jira.agscollab.com/browse/ATOM-3682 (improve heatmap integration with the pass system) + // ATOM-3682 (improve heatmap integration with the pass system) return OUT; } diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingRemap.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingRemap.azsl index abef44f1fd..f56721b614 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingRemap.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingRemap.azsl @@ -186,7 +186,7 @@ void InitWriteIndices(uint3 groupID, uint baseBin, out uint writeIndices[NVLC_MA // light indices until it hits an END_OF_X marker // Note that this code could probably be made faster with wave intrinsics -// https://jira.agscollab.com/browse/ATOM-4104 +// ATOM-4104 [numthreads(NUM_THREADS, 1, 1)] void MainCS( uint3 dispatchThreadID : SV_DispatchThreadID, diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingTilePrepare.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingTilePrepare.azsl index 7279864b09..fba2175c9b 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingTilePrepare.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/LightCulling/LightCullingTilePrepare.azsl @@ -181,7 +181,7 @@ void WriteTileLightDataToMainMemory(uint groupIndex, uint3 groupID, float2 minma // Note that Nvidia Light Culling framework has some additional code to better calculate this ratio // See cb_perFrame.fRangeThreshold in their framework. This code might be something we want to port over. - // https://jira.agscollab.com/browse/ATOM-5554 + // ATOM-5554 float ratio = tileZ / 1.0f; float logMaxBins = clamp(log2(ratio), 0.0, LOG_MAX_BINS); uint ulogMaxBins = uint(logMaxBins + 0.5); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/DepthOfFieldBlurBokeh.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/DepthOfFieldBlurBokeh.azsl index b014f4e3cb..60951ebeb5 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/DepthOfFieldBlurBokeh.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/DepthOfFieldBlurBokeh.azsl @@ -41,7 +41,6 @@ ShaderResourceGroup PassSrg : SRG_PerDraw // The number of points to sample. // Sample 6 points around center pixel. // Similarly, sample around it as 12,18,24 points. -// Please refer to “https://wiki.agscollab.com/display/ATOM/Pencil+Map” for details. option enum class SampleNumber { Sample6, // 6 @@ -52,7 +51,6 @@ option enum class SampleNumber o_sampleNumber = SampleNumber::Sample6; // Get CocRadius from dofFactor. -// Please refer to https://wiki.agscollab.com/display/ATOM/Pencil+Map for CocRadius. inline float GetCocRadius(float dofFactor) { float cocRadius = dofFactor * ViewSrg::m_dof.m_cocToScreenRatio * 0.5f; @@ -61,14 +59,12 @@ inline float GetCocRadius(float dofFactor) } // Calculate the texcoord U of the pencil map from cocRadius. -// Please refer to https://wiki.agscollab.com/display/ATOM/Pencil+Map for the pencil map. inline float GetPencilMapTexcoordU(float cocRadius) { return cocRadius * ViewSrg::m_dof.m_pencilMapTexcoordToCocRadius + ViewSrg::m_dof.m_pencilMapFocusPointTexcoordU; } // Get the color from the coordinate array. -// Please refer to https://wiki.agscollab.com/display/ATOM/Pencil+Map for details of coordinates. inline float4 SampleColorAndDofFactor(float2 centerTexCoord, float cocRadius, int sampleIndex) { float2 sampleTexcoordOffset = PassSrg::m_sampleTexcoordsRadius[sampleIndex].xy * cocRadius; @@ -78,7 +74,6 @@ inline float4 SampleColorAndDofFactor(float2 centerTexCoord, float cocRadius, in } // Load the pencil map. Since the colors are square rooted, they are decoded (linearized). This is for accuracy. -// Please refer to https://wiki.agscollab.com/display/ATOM/Pencil+Map for the pencil map. inline float4 SamplePencilMap(float lensCoordX, float radius) { float2 bokehTexcoord = float2(lensCoordX, radius); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/DepthOfFieldComposite.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/DepthOfFieldComposite.azsl index 5c1973d3b1..0fd89e475e 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/DepthOfFieldComposite.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/DepthOfFieldComposite.azsl @@ -77,7 +77,6 @@ PSOutput MainPS(VSOutput IN) float3 colorSum = (float3)0; // Combine from the back buffer to the front. - // Please refer to https://wiki.agscollab.com/pages/viewpage.action?spaceKey=ATOM&title=Dof+factor+and+Buffer+composition for details //////////////////////////////////////////////////////////////////////// // Background diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp index 27bac09a63..ade4b5b592 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp @@ -1487,7 +1487,6 @@ namespace AZ float depthNear, float depthFar) const { - // For calculation, refer https://wiki.agscollab.com/display/ATOM/Cascaded+Shadowmaps // This calculates the center of bounding sphere for a camera view frustum. // By this, on the camera view (2D), the bounding sphere's center // shifts to the remarkable point. diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.cpp index eb3e87dcd1..42882cec6e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.cpp @@ -34,7 +34,7 @@ namespace AZ const size_t NumBins = 8; const size_t MaxLightsPerTile = 256; // TODO convert this to R16_UINT. It just needs RHI support - // https://jira.agscollab.com/browse/ATOM-3975 + // ATOM-3975 const RHI::Format LightListRemappedFormat = RHI::Format::R32_UINT; RPI::Ptr LightCullingRemap::Create(const RPI::PassDescriptor& descriptor) diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcess/DepthOfField/DepthOfFieldSettings.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcess/DepthOfField/DepthOfFieldSettings.cpp index bad6afbc16..1baa3d072b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcess/DepthOfField/DepthOfFieldSettings.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcess/DepthOfField/DepthOfFieldSettings.cpp @@ -50,7 +50,7 @@ namespace AZ static constexpr Quality QualitySet[DepthOfField::QualityLevelMax] = { - // It is the radial division count of blur kernel. See "https://wiki.agscollab.com/display/ATOM/Pencil+Map" for details. + // It is the radial division count of blur kernel. {2, 3, 4}, {4, 4, 4} }; @@ -205,7 +205,6 @@ namespace AZ float scaledDiameter = ScreenApertureDiameter * 0.25f; // This is the conversion factor for calculating the blend ratio from DofFactor. - // Please refer to "https://wiki.agscollab.com/display/ATOM/Dof+factor+and+Buffer+composition" for blending of DofFactor and buffer. // coc0 : Confusion circle diameter screen ratio // coc1 : Confusion circle diameter screen ratio of one lower blur level; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcess/DepthOfField/DepthOfFieldSettings.h b/Gems/Atom/Feature/Common/Code/Source/PostProcess/DepthOfField/DepthOfFieldSettings.h index eeb1726cfb..6e59b6aa33 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcess/DepthOfField/DepthOfFieldSettings.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcess/DepthOfField/DepthOfFieldSettings.h @@ -139,7 +139,6 @@ namespace AZ float m_minBokehRadiusDivision8 = 0.0f; // Radial division count of bokeh blur kernel. - // See "https://wiki.agscollab.com/display/ATOM/Pencil+Map" for details. uint32_t m_sampleRadialDivision2 = 0; uint32_t m_sampleRadialDivision4 = 0; uint32_t m_sampleRadialDivision8 = 0; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.cpp index e51bca5fde..4a4a8a8b76 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.cpp @@ -194,7 +194,6 @@ namespace AZ // calculate sampling texcoords. // sample 6 points around center pixel. // Similarly, sample around it as 12,18,24 points. - // Please refer to "https://wiki.agscollab.com/display/ATOM/Pencil+Map" for details. AZ_Assert(radialDivisionCount >= 1 && radialDivisionCount <= 4, "DepthOfFieldBokehBlurPass : radialDivisionCount is illegal value."); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldPencilMap.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldPencilMap.h index 585df1d4da..23a8cf9f51 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldPencilMap.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldPencilMap.h @@ -18,8 +18,6 @@ namespace AZ { namespace PencilMap { - // Please refer to "https://wiki.agscollab.com/display/ATOM/Pencil+Map" for details. - // PencilMap 35mm Film static constexpr unsigned int TextureWidth = 128; static constexpr unsigned int TextureHeight = 64; diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/Editor/Scripts/bootstrap.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/Editor/Scripts/bootstrap.py index d1c1921ee5..6fd8b03e9e 100755 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/Editor/Scripts/bootstrap.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/Editor/Scripts/bootstrap.py @@ -16,7 +16,7 @@ with Lumberyard. Note: this boostrap is only designed fo be py3 compatible. If you need DCCsi access in py27 (Autodesk Maya for instance) you may need to implement your own boostrapper module. Currently this is boostrapped from add_dccsi.py, as a temporty measure related to this Jira: -https://jira.agscollab.com/browse/SPEC-2581""" +SPEC-2581""" # standard imports import sys import os diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/userSetup.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/userSetup.py index c615311f3c..0a206245c0 100755 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/userSetup.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/SDK/Maya/Scripts/userSetup.py @@ -25,7 +25,7 @@ the provided env and launcher bat files. If you are developing for the DCCsi you can use this launcher to start Maya: DccScriptingInterface\Launchers\Windows\Launch_Maya_2020.bat" -To Do: https://jira.agscollab.com/browse/ATOM-5861 +To Do: ATOM-5861 """ __project__ = 'DccScriptingInterface' diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/dev/ide/wing/readme.txt b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/dev/ide/wing/readme.txt index 80c950d10b..2d32541c40 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/dev/ide/wing/readme.txt +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/dev/ide/wing/readme.txt @@ -43,7 +43,7 @@ Note: to get this to work unfortunatley each user must configure the wingide pre (there is no shared project / data-driven way that I know of to set this up otherwise) Note: lumberyard is not currently generating __init__.pyi files in that package structure: -https://jira.agscollab.com/browse/SPEC-3315 +SPEC-3315 The workaround is to create them yourself (they can be empty) and needs to be in the root of each package folder, like this: dev\Cache\AtomTechArt\pc\user\python_symbols\azlmbr\__init__.pyi @@ -63,4 +63,4 @@ You might need to reboot wing. Then you should have auto-complete for the lumbe Note: the entirety of azlmbr api does not generate .pyi files currently, all of the "Behaviour Context" based classes do non-BC modules such as azlmbr.paths currently do not -https://jira.agscollab.com/browse/SPEC-3316 +SPEC-3316 diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/shared/common/core_utils.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/shared/common/core_utils.py index 6404f3ee07..958d3f688d 100755 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/shared/common/core_utils.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/shared/common/core_utils.py @@ -40,7 +40,7 @@ Module Documentation: To Do: - https://jira.agscollab.com/browse/ATOM-5859 + ATOM-5859 ''' # ------------------------------------------------------------------------- diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/shared/common/envar_utils.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/shared/common/envar_utils.py index 4e59f86063..acc24f3f79 100755 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/shared/common/envar_utils.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/shared/common/envar_utils.py @@ -22,7 +22,7 @@ Module: \azpy\shared\common\config_utils.py To Do: - https://jira.agscollab.com/browse/ATOM-5859 + ATOM-5859 ''' # ------------------------------------------------------------------------- diff --git a/Gems/EMotionFX/Code/Tests/MorphSkinAttachmentTests.cpp b/Gems/EMotionFX/Code/Tests/MorphSkinAttachmentTests.cpp index 42c2cc2110..d69aa02fc6 100644 --- a/Gems/EMotionFX/Code/Tests/MorphSkinAttachmentTests.cpp +++ b/Gems/EMotionFX/Code/Tests/MorphSkinAttachmentTests.cpp @@ -168,8 +168,8 @@ namespace EMotionFX // The skin attachment should now receive morph values from the main actor. const Pose& attachPose = *m_attachmentActorInstance->GetTransformData()->GetCurrentPose(); ASSERT_EQ(attachPose.GetNumMorphWeights(), 4); - EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(0), 0.0f); // Once we auto register missing morphs this should be 0.5. See https://jira.agscollab.com/browse/LY-100212 - EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(1), 0.0f); // Once we auto register missing morphs this should be 0.6. See https://jira.agscollab.com/browse/LY-100212 + EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(0), 0.0f); // Once we auto register missing morphs this should be 0.5. See LY-100212 + EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(1), 0.0f); // Once we auto register missing morphs this should be 0.6. See LY-100212 EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(2), 0.1f); EXPECT_FLOAT_EQ(attachPose.GetMorphWeight(3), 0.2f); }; diff --git a/Gems/LmbrCentral/Code/Source/Builders/CopyDependencyBuilder/XmlBuilderWorker/XmlBuilderWorker.cpp b/Gems/LmbrCentral/Code/Source/Builders/CopyDependencyBuilder/XmlBuilderWorker/XmlBuilderWorker.cpp index f50526c67f..636aa72013 100644 --- a/Gems/LmbrCentral/Code/Source/Builders/CopyDependencyBuilder/XmlBuilderWorker/XmlBuilderWorker.cpp +++ b/Gems/LmbrCentral/Code/Source/Builders/CopyDependencyBuilder/XmlBuilderWorker/XmlBuilderWorker.cpp @@ -471,7 +471,7 @@ namespace CopyDependencyBuilder [[maybe_unused]] const AZStd::string& watchFolderPath) const { // Check the existing schema info stored in the asset database - // https://jira.agscollab.com/browse/LY-99056 + // LY-99056 return SchemaMatchResult::NoMatchFound; } @@ -526,7 +526,7 @@ namespace CopyDependencyBuilder { case SchemaMatchResult::MatchFound: // Update the LastUsedSchema info stored in the asset database - // https://jira.agscollab.com/browse/LY-99056 + // LY-99056 AZ_Printf("XmlBuilderWorker", "Schema file %s found for source %s.", schemaFilePath.c_str(), sourceFilePath.c_str()); return matchResult; case SchemaMatchResult::NoMatchFound: diff --git a/Gems/LyShine/Code/Editor/UiEditorEntityContext.cpp b/Gems/LyShine/Code/Editor/UiEditorEntityContext.cpp index 3be0b3cddf..d4de0b59c8 100644 --- a/Gems/LyShine/Code/Editor/UiEditorEntityContext.cpp +++ b/Gems/LyShine/Code/Editor/UiEditorEntityContext.cpp @@ -943,7 +943,7 @@ void UiEditorEntityContext::InitializeEntities(const AzFramework::EntityList& en // Because we automatically add the EditorOnlyEntityComponent if it doesn't exist, we can encounter a situation // where an entity has duplicate EditorOnlyEntityComponents if an old canvas is resaved and an old slice it uses - // is also resaved. See https://jira.agscollab.com/browse/LY-90580 + // is also resaved. See LY-90580 // In the main editor this is handled by disabling the duplicate components, but the UI Editor doesn't use that // method (the world editor allows the user to manually add incompatible components and then disable and enable // them in the entity, the UI Editor still works how the world editor used to - it doesn't allow users to add diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp index f0cea19645..9e061135fc 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp @@ -582,7 +582,7 @@ namespace ScriptCanvas int SetExecutionOut(lua_State* lua) { // \note Return values could become necessary. - // \see https://jira.agscollab.com/browse/LY-99750 + // \see LY-99750 AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); AZ_Assert(lua_isnumber(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOut is not a number"); @@ -605,7 +605,7 @@ namespace ScriptCanvas int SetExecutionOutResult(lua_State* lua) { // \note Return values could become necessary. - // \see https://jira.agscollab.com/browse/LY-99750 + // \see LY-99750 AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOutResult is not userdata (Nodeable)"); AZ_Assert(lua_isnumber(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOutResult is not a number"); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 5e11b17c54..8dff6da9b1 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -3114,7 +3114,7 @@ namespace ScriptCanvas /// NOTE: after basic iteration works correctly /// \todo when subsequent input (from nodes connected to the break slot) looks up the slot from the node with key or the value, /// it is going to have to find the output of the get/key value functions in BOTH the child outs of break and loop - /// https://jira.agscollab.com/browse/LY-109862 may be required for this + /// LY-109862 may be required for this ExecutionTreePtr lastExecution = forEachLoopBody; diff --git a/Tests/Atom/windows/screenshot_comparison_atomsampleviewer_windows.py b/Tests/Atom/windows/screenshot_comparison_atomsampleviewer_windows.py index 7d05046b7e..fca50c9901 100755 --- a/Tests/Atom/windows/screenshot_comparison_atomsampleviewer_windows.py +++ b/Tests/Atom/windows/screenshot_comparison_atomsampleviewer_windows.py @@ -86,7 +86,7 @@ # return final_path -# # Commenting out debug due to https://jira.agscollab.com/browse/ATOM-1677 +# # Commenting out debug due to ATOM-1677 # @pytest.mark.parametrize("platform,configuration,project,spec,sample", [ # pytest.param("win_x64_vs2017", "profile", "BaseViewer", "all", "RPI/BistroBenchmark", # marks=pytest.mark.skipif(not WINDOWS, reason="Only supported on Windows hosts")), diff --git a/Tests/pipeline/product_dependency_tests/TestFixtures.py b/Tests/pipeline/product_dependency_tests/TestFixtures.py index c7feab76f3..91151748a5 100755 --- a/Tests/pipeline/product_dependency_tests/TestFixtures.py +++ b/Tests/pipeline/product_dependency_tests/TestFixtures.py @@ -52,8 +52,8 @@ def HeliosProjectFixture(request): # These tests are run on Jenkins after other tests, to minimize time spent on Jenkins jobs. # Verify that the correct project has been set before this test starts. - # Temporarily disabling while https://jira.agscollab.com/browse/LY-103017 is not in Helios branch - # Creating a task to revert this change later: https://jira.agscollab.com/browse/LY-103334 + # Temporarily disabling while LY-103017 is not in Helios branch + # Creating a task to revert this change later: LY-103334 # Run asset processor once to process all assets, so the tests themselves can run at consistent speeds. SubprocessUtils.SubprocessWithTimeout([buildInfo.assetProcessorBatch], engineRoot, 120) diff --git a/scripts/build/tools/email_to_lionbridge.py b/scripts/build/tools/email_to_lionbridge.py index c2edcbe9f2..7f522bb564 100755 --- a/scripts/build/tools/email_to_lionbridge.py +++ b/scripts/build/tools/email_to_lionbridge.py @@ -10,7 +10,7 @@ # """ -This script will be used in https://jenkins.agscollab.com/view/%7ESandbox/job/PACKAGE_COPY_S3/ +This script will be used in the Sandobx Jenkins job PACKAGE_COPY_S3 PACKAGE_COPY_S3 is a downstream job of nightly packaging job, it copies the nightly packages from Infra S3 bucket to Lionbridge S3 bucket based on the INCLUDE_FILTER passed from packaging job """ import os From f21d3da9eee54f5a6720abdf01449e710c4a92d5 Mon Sep 17 00:00:00 2001 From: darapan Date: Tue, 11 May 2021 01:30:39 -0700 Subject: [PATCH 094/225] "Fixing review Comments" --- .../PythonTests/scripting/TestSuite_Active.py | 4 ++-- ...ariableManager_UnpinVariableType_Works.py} | 20 ++++++------------- 2 files changed, 8 insertions(+), 16 deletions(-) rename AutomatedTesting/Gem/PythonTests/scripting/{VariableManager_UnpinVariableType.py => VariableManager_UnpinVariableType_Works.py} (91%) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index 7bfcca97df..cad6431fef 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -183,8 +183,8 @@ class TestAutomation(TestAutomationBase): from . import ScriptEvents_SendReceiveSuccessfully as test_module self._run_test(request, workspace, editor, test_module) - def test_VariableManager_UnpinVariableType(self, request, workspace, editor, launcher_platform): - from . import VariableManager_UnpinVariableType as test_module + def test_VariableManager_UnpinVariableType_Works(self, request, workspace, editor, launcher_platform): + from . import VariableManager_UnpinVariableType_Works as test_module self._run_test(request, workspace, editor, test_module) # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method diff --git a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType_Works.py similarity index 91% rename from AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py rename to AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType_Works.py index 5d097de2f8..7076f60385 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType_Works.py @@ -1,7 +1,6 @@ """ All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or its licensors. - For complete copyright and license terms please see the LICENSE at the root of this distribution (the "License"). All use of this software is governed by the License, or, if provided, by the license below or the license accompanying this file. Do not @@ -19,14 +18,12 @@ class Tests(): # fmt: on -def VariableManager_UnpinVariableType(): +def VariableManager_UnpinVariableType_Works(): """ Summary: Unpin variable types in create variable menu. - Expected Behavior: The variable unpinned in create variable menu remains unpinned after reopening create variable menu. - Test Steps: 1) Open Script Canvas window (Tools > Script Canvas) 2) Get the SC window object @@ -36,12 +33,10 @@ def VariableManager_UnpinVariableType(): 6) Unpin Boolean by clicking the "Pin" icon on its left side 7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu 8) Restore default layout and close SC window - Note: - This test file must be called from the Open 3D Engine Editor command terminal - Any passed and failed tests are written to the Editor.log file. Parsing the file or running a log_monitor are required to observe the test results. - :return: None """ @@ -94,15 +89,12 @@ def VariableManager_UnpinVariableType(): table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") # Make sure Boolean is pinned - result = helper.wait_for_condition( - lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is not None, GENERAL_WAIT - ) + is_boolean = model_index.siblingAtColumn(0) + result = helper.wait_for_condition(lambda: is_boolean.data(Qt.DecorationRole) is not None, GENERAL_WAIT) Report.result(Tests.variable_pinned, result) # Unpin Boolean and make sure Boolean is unpinned. - pyside_utils.item_view_index_mouse_click(table_view, model_index.siblingAtColumn(0)) - result = helper.wait_for_condition( - lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is None, GENERAL_WAIT - ) + pyside_utils.item_view_index_mouse_click(table_view, is_boolean) + result = helper.wait_for_condition(lambda: is_boolean.data(Qt.DecorationRole) is None, GENERAL_WAIT) Report.result(Tests.variable_unpinned, result) # 7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu @@ -126,4 +118,4 @@ if __name__ == "__main__": from utils import Report - Report.start_test(VariableManager_UnpinVariableType) + Report.start_test(VariableManager_UnpinVariableType_Works) From a82d22a71841d07a1bb110305fc81e63c850c05d Mon Sep 17 00:00:00 2001 From: darapan Date: Tue, 11 May 2021 01:39:14 -0700 Subject: [PATCH 095/225] "Resolving merge conflicts" --- .../PythonTests/scripting/TestSuite_Active.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index cad6431fef..963693b54c 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -182,9 +182,22 @@ class TestAutomation(TestAutomationBase): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import ScriptEvents_SendReceiveSuccessfully as test_module self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptEvents_ReturnSetType_Successfully(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptEvents_ReturnSetType_Successfully as test_module + self._run_test(request, workspace, editor, test_module) + + def test_NodeCategory_ExpandOnClick(self, request, workspace, editor, launcher_platform): + from . import NodeCategory_ExpandOnClick as test_module + self._run_test(request, workspace, editor, test_module) - def test_VariableManager_UnpinVariableType_Works(self, request, workspace, editor, launcher_platform): - from . import VariableManager_UnpinVariableType_Works as test_module + def test_NodePalette_SearchText_Deletion(self, request, workspace, editor, launcher_platform): + from . import NodePalette_SearchText_Deletion as test_module self._run_test(request, workspace, editor, test_module) # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method @@ -255,4 +268,4 @@ class TestScriptCanvasTests(object): expected_lines, auto_test_mode=False, timeout=60, - ) \ No newline at end of file + ) From 805f447d41276f09c98c3cb013ac3a31009b921a Mon Sep 17 00:00:00 2001 From: darapan Date: Tue, 11 May 2021 01:41:52 -0700 Subject: [PATCH 096/225] "Resolving merge conflicts" --- .../Gem/PythonTests/scripting/TestSuite_Active.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index 963693b54c..dda75f0a0c 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -200,6 +200,10 @@ class TestAutomation(TestAutomationBase): from . import NodePalette_SearchText_Deletion as test_module self._run_test(request, workspace, editor, test_module) + def test_VariableManager_UnpinVariableType_Works(self, request, workspace, editor, launcher_platform): + from . import VariableManager_UnpinVariableType_Works as test_module + self._run_test(request, workspace, editor, test_module) + # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method # fails because of pyside_utils import @pytest.mark.SUITE_periodic From d49135659feec489138f59dedac3760dbb7ede4f Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Tue, 11 May 2021 12:19:56 +0200 Subject: [PATCH 097/225] [LYN-2520] Added link and tag widgets (#663) --- .../ProjectManager/Source/LinkWidget.cpp | 52 ++++++++++ Code/Tools/ProjectManager/Source/LinkWidget.h | 42 ++++++++ .../Tools/ProjectManager/Source/TagWidget.cpp | 98 +++++++++++++++++++ Code/Tools/ProjectManager/Source/TagWidget.h | 52 ++++++++++ .../project_manager_files.cmake | 4 + 5 files changed, 248 insertions(+) create mode 100644 Code/Tools/ProjectManager/Source/LinkWidget.cpp create mode 100644 Code/Tools/ProjectManager/Source/LinkWidget.h create mode 100644 Code/Tools/ProjectManager/Source/TagWidget.cpp create mode 100644 Code/Tools/ProjectManager/Source/TagWidget.h diff --git a/Code/Tools/ProjectManager/Source/LinkWidget.cpp b/Code/Tools/ProjectManager/Source/LinkWidget.cpp new file mode 100644 index 0000000000..fddc4cd8c9 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/LinkWidget.cpp @@ -0,0 +1,52 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include +#include +#include +#include + +namespace O3DE::ProjectManager +{ + LinkLabel::LinkLabel(const QString& text, const QUrl& url, QWidget* parent) + : QLabel(text, parent) + , m_url(url) + { + SetDefaultStyle(); + } + + void LinkLabel::mousePressEvent([[maybe_unused]] QMouseEvent* event) + { + QDesktopServices::openUrl(m_url); + } + + void LinkLabel::enterEvent([[maybe_unused]] QEvent* event) + { + setStyleSheet("font-size: 9pt; color: #94D2FF; text-decoration: underline;"); + } + + void LinkLabel::leaveEvent([[maybe_unused]] QEvent* event) + { + SetDefaultStyle(); + } + + void LinkLabel::SetUrl(const QUrl& url) + { + m_url = url; + } + + void LinkLabel::SetDefaultStyle() + { + setStyleSheet("font-size: 9pt; color: #94D2FF;"); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/LinkWidget.h b/Code/Tools/ProjectManager/Source/LinkWidget.h new file mode 100644 index 0000000000..7055dce2af --- /dev/null +++ b/Code/Tools/ProjectManager/Source/LinkWidget.h @@ -0,0 +1,42 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QEvent) +QT_FORWARD_DECLARE_CLASS(QMouseEvent) +QT_FORWARD_DECLARE_CLASS(QWidget) + +namespace O3DE::ProjectManager +{ + class LinkLabel + : public QLabel + { + public: + LinkLabel(const QString& text, const QUrl& url = {}, QWidget* parent = nullptr); + + void SetUrl(const QUrl& url); + private: + void mousePressEvent(QMouseEvent* event) override; + void enterEvent(QEvent* event) override; + void leaveEvent(QEvent* event) override; + void SetDefaultStyle(); + + private: + QUrl m_url; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/TagWidget.cpp b/Code/Tools/ProjectManager/Source/TagWidget.cpp new file mode 100644 index 0000000000..3e80944204 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/TagWidget.cpp @@ -0,0 +1,98 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include + +namespace O3DE::ProjectManager +{ + TagWidget::TagWidget(const QString& text, QWidget* parent) + : QLabel(text, parent) + { + setFixedHeight(35); + setMargin(5); + setStyleSheet("font-size: 12pt; background-color: #333333; border-radius: 4px;"); + } + + TagContainerWidget::TagContainerWidget(QWidget* parent) + : QWidget(parent) + { + m_layout = new QVBoxLayout(); + m_layout->setAlignment(Qt::AlignTop); + m_layout->setMargin(0); + setLayout(m_layout); + } + + void TagContainerWidget::Update(const QStringList& tags) + { + QWidget* parentWidget = qobject_cast(parent()); + int width = 250; + if (parentWidget) + { + width = parentWidget->width(); + } + + if (m_widget) + { + // Hide the old widget and request deletion. + m_widget->hide(); + m_widget->deleteLater(); + } + + QVBoxLayout* vLayout = new QVBoxLayout(); + m_widget = new QWidget(this); + m_widget->setLayout(vLayout); + m_layout->addWidget(m_widget); + + vLayout->setAlignment(Qt::AlignTop); + vLayout->setMargin(0); + + QHBoxLayout* hLayout = nullptr; + int usedSpaceInRow = 0; + const int numTags = tags.count(); + + for (int i = 0; i < numTags; ++i) + { + // Create the new tag widget. + TagWidget* tagWidget = new TagWidget(tags[i]); + const int tagWidgetWidth = tagWidget->minimumSizeHint().width(); + + // Calculate the width we're currently using in the current row. Does the new tag still fit in the current row? + const bool isRowFull = width - usedSpaceInRow - tagWidgetWidth < 0; + if (isRowFull || i == 0) + { + // Add a spacer widget after the last tag widget in a row to push the tag widgets to the left. + if (i > 0) + { + QWidget* spacerWidget = new QWidget(); + spacerWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + hLayout->addWidget(spacerWidget); + } + + // Add a new row for the current tag widget. + hLayout = new QHBoxLayout(); + hLayout->setAlignment(Qt::AlignLeft); + hLayout->setMargin(0); + vLayout->addLayout(hLayout); + + // Reset the used space in the row. + usedSpaceInRow = 0; + } + + // Calculate the width of the tag widgets including the spacing between them of the current row. + usedSpaceInRow += tagWidgetWidth + hLayout->spacing(); + + // Add the tag widget to the current row. + hLayout->addWidget(tagWidget); + } + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/TagWidget.h b/Code/Tools/ProjectManager/Source/TagWidget.h new file mode 100644 index 0000000000..5597b302c7 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/TagWidget.h @@ -0,0 +1,52 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QVBoxLayout) + +namespace O3DE::ProjectManager +{ + // Single tag + class TagWidget + : public QLabel + { + Q_OBJECT // AUTOMOC + + public: + explicit TagWidget(const QString& text, QWidget* parent = nullptr); + ~TagWidget() = default; + }; + + // Widget containing multiple tags, automatically wrapping based on the size + class TagContainerWidget + : public QWidget + { + Q_OBJECT // AUTOMOC + + public: + explicit TagContainerWidget(QWidget* parent = nullptr); + ~TagContainerWidget() = default; + + void Update(const QStringList& tags); + + private: + QVBoxLayout* m_layout = nullptr; + QWidget* m_widget = nullptr; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index b206cf1456..073e220810 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -34,6 +34,10 @@ set(FILES Source/EngineSettings.h Source/EngineSettings.cpp Source/EngineSettings.ui + Source/LinkWidget.h + Source/LinkWidget.cpp + Source/TagWidget.h + Source/TagWidget.cpp Source/GemCatalog/GemCatalog.h Source/GemCatalog/GemCatalog.cpp Source/GemCatalog/GemInfo.h From 619f71cc19880c1a18a46975db5cc415898dbd09 Mon Sep 17 00:00:00 2001 From: greerdv Date: Tue, 11 May 2021 11:39:14 +0100 Subject: [PATCH 098/225] fixing some bugs with debug draw not taking entity scale into account --- .../AtomDebugDisplayViewportInterface.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp index 7a8d6b7494..1039a12622 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp @@ -931,13 +931,14 @@ namespace AZ::AtomBridge { if (m_auxGeomPtr) { + const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement(); const AZ::Vector3 worldCenter = ToWorldSpacePosition(center); const AZ::Vector3 worldAxis = ToWorldSpaceVector(axis); m_auxGeomPtr->DrawCylinder( worldCenter, worldAxis, - radius, - height, + scale * radius, + scale * height, m_rendState.m_color, AZ::RPI::AuxGeomDraw::DrawStyle::Line, m_rendState.m_depthTest, @@ -957,13 +958,14 @@ namespace AZ::AtomBridge { if (m_auxGeomPtr) { + const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement(); const AZ::Vector3 worldCenter = ToWorldSpacePosition(center); const AZ::Vector3 worldAxis = ToWorldSpaceVector(axis); m_auxGeomPtr->DrawCylinder( worldCenter, worldAxis, - radius, - height, + scale * radius, + scale * height, m_rendState.m_color, drawShaded ? AZ::RPI::AuxGeomDraw::DrawStyle::Shaded : AZ::RPI::AuxGeomDraw::DrawStyle::Solid, m_rendState.m_depthTest, @@ -1067,10 +1069,10 @@ namespace AZ::AtomBridge { if (m_auxGeomPtr) { - + const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement(); m_auxGeomPtr->DrawSphere( ToWorldSpacePosition(pos), - radius, + scale * radius, m_rendState.m_color, AZ::RPI::AuxGeomDraw::DrawStyle::Line, m_rendState.m_depthTest, @@ -1161,12 +1163,13 @@ namespace AZ::AtomBridge { if (m_auxGeomPtr) { + const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement(); const AZ::Vector3 worldPos = ToWorldSpacePosition(pos); const AZ::Vector3 worldDir = ToWorldSpaceVector(dir); m_auxGeomPtr->DrawDisk( worldPos, worldDir, - radius, + scale * radius, m_rendState.m_color, AZ::RPI::AuxGeomDraw::DrawStyle::Shaded, m_rendState.m_depthTest, From 27d6e5b8489bea7a02b8ff655e7f8fd48b16af30 Mon Sep 17 00:00:00 2001 From: greerdv Date: Tue, 11 May 2021 11:41:33 +0100 Subject: [PATCH 099/225] formatting tidy up --- .../Code/Source/AtomDebugDisplayViewportInterface.cpp | 8 ++++++-- .../Code/Source/AtomDebugDisplayViewportInterface.h | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp index 1039a12622..482bd21972 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp @@ -1523,7 +1523,9 @@ namespace AZ::AtomBridge { AZStd::vector transformedPositions; transformedPositions.resize_no_construct(positions.size()); - AZStd::transform(positions.begin(), positions.end(), transformedPositions.begin(), [this](const AZ::Vector3& position){ return ToWorldSpacePosition(position); }); + AZStd::transform(positions.begin(), positions.end(), transformedPositions.begin(), [this](const AZ::Vector3& position) { + return ToWorldSpacePosition(position); + }); return transformedPositions; } @@ -1531,7 +1533,9 @@ namespace AZ::AtomBridge { AZStd::vector transformedVectors; transformedVectors.resize_no_construct(vectors.size()); - AZStd::transform(vectors.begin(), vectors.end(), transformedVectors.begin(), [this](const AZ::Vector3& vector) { return ToWorldSpaceVector(vector); }); + AZStd::transform(vectors.begin(), vectors.end(), transformedVectors.begin(), [this](const AZ::Vector3& vector) { + return ToWorldSpaceVector(vector); + }); return transformedVectors; } diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h index 5edd1f0a02..18d280ef88 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h @@ -249,10 +249,10 @@ namespace AZ::AtomBridge //! Convert direction to world space (translation is not considered) AZ::Vector3 ToWorldSpaceVector(const AZ::Vector3& v) const { return m_rendState.m_transformStack[m_rendState.m_currentTransform].Multiply3x3(v); } - //! Convert position to world space. + //! Convert positions to world space. AZStd::vector ToWorldSpacePosition(const AZStd::vector& positions) const; - //! Convert direction to world space (translation is not considered) + //! Convert directions to world space (translation is not considered) AZStd::vector ToWorldSpaceVector(const AZStd::vector& vectors) const; void CalcBasisVectors(const AZ::Vector3& n, AZ::Vector3& b1, AZ::Vector3& b2) const; From 591ad7f824d86e664c8710e3de58e2a385963d75 Mon Sep 17 00:00:00 2001 From: AMZN-AlexOteiza <82234181+AMZN-AlexOteiza@users.noreply.github.com> Date: Tue, 11 May 2021 12:44:27 +0100 Subject: [PATCH 100/225] Added xml output for tests (#664) Added test reporting information for jenkins --- scripts/build/Jenkins/Jenkinsfile | 30 ++++++++++++++++--- .../build/Platform/Windows/build_config.json | 18 +++++++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile index f85b0b5ef4..ae2779eba8 100644 --- a/scripts/build/Jenkins/Jenkinsfile +++ b/scripts/build/Jenkins/Jenkinsfile @@ -60,7 +60,7 @@ def palRm(path) { } else { def win_path = path.replace('/','\\') bat label: "Removing ${win_path}", - script: "del ${win_path}" + script: "del /Q ${win_path}" } } @@ -354,6 +354,16 @@ def TestMetrics(Map pipelineConfig, String workspace, String branchName, String } } +def ExportTestResults(Map options, String platform, String type, String workspace, Map params) { + catchError(message: "Error exporting tests results (this won't fail the build)", buildResult: 'SUCCESS', stageResult: 'FAILURE') { + def o3deroot = "${workspace}/${ENGINE_REPOSITORY_NAME}" + dir("${o3deroot}/${params.OUTPUT_DIRECTORY}") { + junit testResults: "Testing/**/*.xml" + palRmDir("Testing") + } + } +} + def PostBuildCommonSteps(String workspace, boolean mount = true) { echo 'Starting post-build common steps...' @@ -396,6 +406,14 @@ def CreateTestMetricsStage(Map pipelineConfig, String branchName, Map environmen } } +def CreateExportTestResultsStage(Map pipelineConfig, String platformName, String jobName, Map environmentVars, Map params) { + return { + stage("${jobName}_results") { + ExportTestResults(pipelineConfig, platformName, jobName, environmentVars['WORKSPACE'], params) + } + } +} + def CreateTeardownStage(Map environmentVars) { return { stage('Teardown') { @@ -511,11 +529,15 @@ try { } } finally { - if (env.MARS_REPO && platform.value.build_types[build_job_name].PARAMETERS.containsKey('TEST_METRICS') && platform.value.build_types[build_job_name].PARAMETERS.TEST_METRICS == 'True') { - def output_directory = platform.value.build_types[build_job_name].PARAMETERS.OUTPUT_DIRECTORY - def configuration = platform.value.build_types[build_job_name].PARAMETERS.CONFIGURATION + def params = platform.value.build_types[build_job_name].PARAMETERS + if (env.MARS_REPO && params && params.containsKey('TEST_METRICS') && params.TEST_METRICS == 'True') { + def output_directory = params.OUTPUT_DIRECTORY + def configuration = params.CONFIGURATION CreateTestMetricsStage(pipelineConfig, branchName, envVars, build_job_name, output_directory, configuration).call() } + if (params && params.containsKey('TEST_RESULTS') && params.TEST_RESULTS == 'True') { + CreateExportTestResultsStage(pipelineConfig, platform.key, build_job_name, envVars, params).call() + } CreateTeardownStage(envVars).call() } } diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index ff57e007cc..ee34bae3e3 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -106,7 +106,8 @@ "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo", "CTEST_OPTIONS": "-L \"(SUITE_smoke|SUITE_main)\" -LE \"(REQUIRES_gpu)\" -T Test", - "TEST_METRICS": "True" + "TEST_METRICS": "True", + "TEST_RESULTS": "True" } }, "profile_vs2019": { @@ -154,7 +155,8 @@ "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo", "CTEST_OPTIONS": "-L \"(SUITE_smoke|SUITE_main)\" -LE \"(REQUIRES_gpu)\" -T Test", - "TEST_METRICS": "True" + "TEST_METRICS": "True", + "TEST_RESULTS": "True" } }, "test_gpu_profile_vs2019": { @@ -174,7 +176,8 @@ "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo", "CTEST_OPTIONS": "-L \"(SUITE_smoke_REQUIRES_gpu|SUITE_main_REQUIRES_gpu)\" -T Test", - "TEST_METRICS": "True" + "TEST_METRICS": "True", + "TEST_RESULTS": "True" } }, "asset_profile_vs2019": { @@ -211,7 +214,8 @@ "CMAKE_TARGET": "TEST_SUITE_periodic", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo", "CTEST_OPTIONS": "-L \"(SUITE_periodic)\" -T Test", - "TEST_METRICS": "True" + "TEST_METRICS": "True", + "TEST_RESULTS": "True" } }, "sandbox_test_profile_vs2019": { @@ -232,7 +236,8 @@ "CMAKE_TARGET": "TEST_SUITE_sandbox", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo", "CTEST_OPTIONS": "-L \"(SUITE_sandbox)\" -T Test", - "TEST_METRICS": "True" + "TEST_METRICS": "True", + "TEST_RESULTS": "True" } }, "benchmark_test_profile_vs2019": { @@ -250,7 +255,8 @@ "CMAKE_TARGET": "TEST_SUITE_benchmark", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo", "CTEST_OPTIONS": "-L \"(SUITE_benchmark)\" -T Test", - "TEST_METRICS": "True" + "TEST_METRICS": "True", + "TEST_RESULTS": "True" } }, "release_vs2019": { From b5e5a3bfee78b8ef089e2f9fc2457704f9f42454 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Tue, 11 May 2021 13:38:09 +0100 Subject: [PATCH 101/225] More camera fixes for the new CameraInput system (#667) * use new ViewportContext interface to set camera transform on load * WIP fixes for camera viewport handler callbacks * disable synchonization with old camera when new camera system is enabled * further updates to camera-input * ensure event is signalled when camera transform is set * updates to ModernViewportCameraController * fix for right click menu appearing with camera * updates following review feedback * convert std:: usage to AZStd:: --- Code/Framework/AzCore/AzCore/std/math.h | 33 ++++-- .../AzFramework/Viewport/CameraInput.cpp | 102 +++++++++++------- .../AzFramework/Viewport/CameraInput.h | 24 +++-- .../AzFramework/Viewport/ScreenGeometry.h | 9 +- .../Tests/Viewport/ViewportScreenTests.cpp | 9 ++ Code/Sandbox/Editor/CryEditDoc.cpp | 11 +- Code/Sandbox/Editor/EditorViewportWidget.cpp | 7 +- .../Editor/ModernViewportCameraController.cpp | 18 +++- .../Editor/ModernViewportCameraController.h | 12 +-- .../Source/RPI.Public/ViewportContext.cpp | 1 + 10 files changed, 144 insertions(+), 82 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/std/math.h b/Code/Framework/AzCore/AzCore/std/math.h index 0ad7c93aca..9e9be7944a 100644 --- a/Code/Framework/AzCore/AzCore/std/math.h +++ b/Code/Framework/AzCore/AzCore/std/math.h @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once @@ -17,4 +17,15 @@ namespace AZStd { using std::abs; -} + using std::acos; + using std::asin; + using std::atan; + using std::atan2; + using std::cos; + using std::exp2; + using std::fmod; + using std::round; + using std::sin; + using std::sqrt; + using std::tan; +} // namespace AZStd diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index e9dace3433..4c95865938 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -29,14 +29,14 @@ namespace AzFramework AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(float, ed_cameraSystemDefaultOrbitDistance, 60.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 100.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); + AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 60.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemRotateSpeed, 0.005f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemPanSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(bool, ed_cameraSystemPanInvertX, true, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(bool, ed_cameraSystemPanInvertY, true, nullptr, AZ::ConsoleFunctorFlags::Null, ""); + AZ_CVAR(float, ed_cameraSystemLookDeadzone, 2.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR( AZ::CVarFixedString, ed_cameraSystemTranslateForwardKey, "keyboard_key_alphanumeric_W", nullptr, AZ::ConsoleFunctorFlags::Null, ""); @@ -125,22 +125,22 @@ namespace AzFramework { if (orientation.GetElement(2, 0) > -1.0f) { - x = std::atan2(orientation.GetElement(2, 1), orientation.GetElement(2, 2)); - y = std::asin(-orientation.GetElement(2, 0)); - z = std::atan2(orientation.GetElement(1, 0), orientation.GetElement(0, 0)); + x = AZStd::atan2(orientation.GetElement(2, 1), orientation.GetElement(2, 2)); + y = AZStd::asin(-orientation.GetElement(2, 0)); + z = AZStd::atan2(orientation.GetElement(1, 0), orientation.GetElement(0, 0)); } else { x = 0.0f; y = AZ::Constants::Pi * 0.5f; - z = -std::atan2(-orientation.GetElement(2, 1), orientation.GetElement(1, 1)); + z = -AZStd::atan2(-orientation.GetElement(2, 1), orientation.GetElement(1, 1)); } } else { x = 0.0f; y = -AZ::Constants::Pi * 0.5f; - z = std::atan2(-orientation.GetElement(1, 2), orientation.GetElement(1, 1)); + z = AZStd::atan2(-orientation.GetElement(1, 2), orientation.GetElement(1, 1)); } return {x, y, z}; @@ -150,31 +150,35 @@ namespace AzFramework { const auto eulerAngles = AzFramework::EulerAngles(AZ::Matrix3x3::CreateFromTransform(transform)); - camera.m_lookAt = transform.GetTranslation(); camera.m_pitch = eulerAngles.GetX(); camera.m_yaw = eulerAngles.GetZ(); + // note: m_lookDist is negative so we must invert it here + camera.m_lookAt = transform.GetTranslation() + (camera.Rotation().GetBasisY() * -camera.m_lookDist); + } + + static ScreenVector CursorDelta(const AZStd::optional& currentPosition, const AZStd::optional& lastPosition) + { + return currentPosition.has_value() && lastPosition.has_value() ? currentPosition.value() - lastPosition.value() + : ScreenVector(0, 0); } bool CameraSystem::HandleEvents(const InputEvent& event) { - if (const auto& cursor_motion = AZStd::get_if(&event)) + if (const auto& cursor = AZStd::get_if(&event)) { - m_currentCursorPosition = cursor_motion->m_position; + m_currentCursorPosition = cursor->m_position; } else if (const auto& scroll = AZStd::get_if(&event)) { m_scrollDelta = scroll->m_delta; } - return m_cameras.HandleEvents(event); + return m_cameras.HandleEvents(event, CursorDelta(m_currentCursorPosition, m_lastCursorPosition), m_scrollDelta); } Camera CameraSystem::StepCamera(const Camera& targetCamera, const float deltaTime) { - const auto cursorDelta = m_currentCursorPosition.has_value() && m_lastCursorPosition.has_value() - ? m_currentCursorPosition.value() - m_lastCursorPosition.value() - : ScreenVector(0, 0); - + const auto cursorDelta = CursorDelta(m_currentCursorPosition, m_lastCursorPosition); if (m_currentCursorPosition.has_value()) { m_lastCursorPosition = m_currentCursorPosition; @@ -192,18 +196,18 @@ namespace AzFramework m_idleCameraInputs.push_back(AZStd::move(cameraInput)); } - bool Cameras::HandleEvents(const InputEvent& event) + bool Cameras::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) { bool handling = false; for (auto& cameraInput : m_activeCameraInputs) { - cameraInput->HandleEvents(event); + cameraInput->HandleEvents(event, cursorDelta, scrollDelta); handling = !cameraInput->Idle() || handling; } for (auto& cameraInput : m_idleCameraInputs) { - cameraInput->HandleEvents(event); + cameraInput->HandleEvents(event, cursorDelta, scrollDelta); } return handling; @@ -215,8 +219,8 @@ namespace AzFramework { auto& cameraInput = m_idleCameraInputs[i]; const bool canBegin = cameraInput->Beginning() && - std::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(), - [](const auto& input) { return !input->Exclusive(); }) && + AZStd::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(), + [](const auto& input) { return !input->Exclusive(); }) && (!cameraInput->Exclusive() || (cameraInput->Exclusive() && m_activeCameraInputs.empty())); if (canBegin) @@ -271,7 +275,7 @@ namespace AzFramework } } - void RotateCameraInput::HandleEvents(const InputEvent& event) + void RotateCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto& input = AZStd::get_if(&event)) { @@ -279,14 +283,27 @@ namespace AzFramework { if (input->m_state == InputChannel::State::Began) { - BeginActivation(); + m_tryingToBegin = true; + m_moveAccumulator = 0.0f; } else if (input->m_state == InputChannel::State::Ended) { + m_tryingToBegin = false; EndActivation(); } } } + + if (m_tryingToBegin) + { + // only allow the action to begin if the mouse has been moved a small amount + m_moveAccumulator += ScreenVectorLength(cursorDelta); + if (m_moveAccumulator > ed_cameraSystemLookDeadzone) + { + BeginActivation(); + m_tryingToBegin = false; + } + } } Camera RotateCameraInput::StepCamera( @@ -298,7 +315,7 @@ namespace AzFramework nextCamera.m_pitch -= float(cursorDelta.m_y) * ed_cameraSystemRotateSpeed; nextCamera.m_yaw -= float(cursorDelta.m_x) * ed_cameraSystemRotateSpeed; - const auto clampRotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); }; + const auto clampRotation = [](const float angle) { return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); }; nextCamera.m_yaw = clampRotation(nextCamera.m_yaw); // clamp pitch to be +-90 degrees @@ -307,7 +324,8 @@ namespace AzFramework return nextCamera; } - void PanCameraInput::HandleEvents(const InputEvent& event) + void PanCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto& input = AZStd::get_if(&event)) { @@ -382,7 +400,8 @@ namespace AzFramework return TranslationType::Nil; } - void TranslateCameraInput::HandleEvents(const InputEvent& event) + void TranslateCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto& input = AZStd::get_if(&event)) { @@ -478,7 +497,7 @@ namespace AzFramework m_boost = false; } - void OrbitCameraInput::HandleEvents(const InputEvent& event) + void OrbitCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) { if (const auto* input = AZStd::get_if(&event)) { @@ -497,7 +516,7 @@ namespace AzFramework if (Active()) { - m_orbitCameras.HandleEvents(event); + m_orbitCameras.HandleEvents(event, cursorDelta, scrollDelta); } } @@ -509,8 +528,10 @@ namespace AzFramework if (Beginning()) { float hit_distance = 0.0f; - if (AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight)) - .CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance)) + AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight)) + .CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance); + + if (hit_distance > 0.0f) { hit_distance = AZStd::min(hit_distance, ed_cameraSystemMaxOrbitDistance); nextCamera.m_lookDist = -hit_distance; @@ -539,7 +560,8 @@ namespace AzFramework return nextCamera; } - void OrbitDollyScrollCameraInput::HandleEvents(const InputEvent& event) + void OrbitDollyScrollCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto* scroll = AZStd::get_if(&event)) { @@ -557,7 +579,8 @@ namespace AzFramework return nextCamera; } - void OrbitDollyCursorMoveCameraInput::HandleEvents(const InputEvent& event) + void OrbitDollyCursorMoveCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto& input = AZStd::get_if(&event)) { @@ -584,7 +607,8 @@ namespace AzFramework return nextCamera; } - void ScrollTranslationCameraInput::HandleEvents(const InputEvent& event) + void ScrollTranslationCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto* scroll = AZStd::get_if(&event)) { @@ -610,7 +634,7 @@ namespace AzFramework Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const float deltaTime) { - const auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); }; + const auto clamp_rotation = [](const float angle) { return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); }; // keep yaw in 0 - 360 range float targetYaw = clamp_rotation(targetCamera.m_yaw); @@ -621,7 +645,7 @@ namespace AzFramework // ensure smooth transition when moving across 0 - 360 boundary const float yawDelta = targetYaw - currentYaw; - if (std::abs(yawDelta) >= AZ::Constants::Pi) + if (AZStd::abs(yawDelta) >= AZ::Constants::Pi) { targetYaw -= AZ::Constants::TwoPi * sign(yawDelta); } @@ -629,12 +653,12 @@ namespace AzFramework Camera camera; // note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent // article by Scott Lembcke: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php - const float lookRate = std::exp2(ed_cameraSystemLookSmoothness); - const float lookT = std::exp2(-lookRate * deltaTime); + const float lookRate = AZStd::exp2(ed_cameraSystemLookSmoothness); + const float lookT = AZStd::exp2(-lookRate * deltaTime); camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookT); camera.m_yaw = AZ::Lerp(targetYaw, currentYaw, lookT); - const float moveRate = std::exp2(ed_cameraSystemTranslateSmoothness); - const float moveT = std::exp2(-moveRate * deltaTime); + const float moveRate = AZStd::exp2(ed_cameraSystemTranslateSmoothness); + const float moveT = AZStd::exp2(-moveRate * deltaTime); camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT); camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveT); return camera; @@ -655,7 +679,7 @@ namespace AzFramework const auto* position = inputChannel.GetCustomData(); AZ_Assert(position, "Expected PositionData2D but found nullptr"); - return CursorMotionEvent{ScreenPoint( + return CursorEvent{ScreenPoint( position->m_normalizedPosition.GetX() * windowSize.m_width, position->m_normalizedPosition.GetY() * windowSize.m_height)}; } else if (inputChannelId == InputDeviceMouse::Movement::Z) diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h index 6ccd7c43eb..6475753017 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h @@ -70,7 +70,7 @@ namespace AzFramework void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform); - struct CursorMotionEvent + struct CursorEvent { ScreenPoint m_position; }; @@ -86,7 +86,7 @@ namespace AzFramework InputChannel::State m_state; //!< Channel state. (e.g. Begin/update/end event). }; - using InputEvent = AZStd::variant; + using InputEvent = AZStd::variant; class CameraInput { @@ -147,7 +147,7 @@ namespace AzFramework ResetImpl(); } - virtual void HandleEvents(const InputEvent& event) = 0; + virtual void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) = 0; virtual Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) = 0; virtual bool Exclusive() const @@ -170,7 +170,7 @@ namespace AzFramework { public: void AddCamera(AZStd::shared_ptr cameraInput); - bool HandleEvents(const InputEvent& event); + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta); Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime); void Reset(); @@ -201,11 +201,13 @@ namespace AzFramework { } - void HandleEvents(const InputEvent& event) override; + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; private: InputChannelId m_rotateChannelId; + float m_moveAccumulator = 0.0f; + bool m_tryingToBegin = false; }; struct PanAxes @@ -243,7 +245,7 @@ namespace AzFramework , m_panChannelId(panChannelId) { } - void HandleEvents(const InputEvent& event) override; + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; private: @@ -285,7 +287,7 @@ namespace AzFramework : m_translationAxesFn(AZStd::move(translationAxesFn)) { } - void HandleEvents(const InputEvent& event) override; + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; void ResetImpl() override; @@ -354,7 +356,7 @@ namespace AzFramework class OrbitDollyScrollCameraInput : public CameraInput { public: - void HandleEvents(const InputEvent& event) override; + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; }; @@ -364,7 +366,7 @@ namespace AzFramework explicit OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId) : m_dollyChannelId(dollyChannelId) {} - void HandleEvents(const InputEvent& event) override; + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; private: @@ -374,14 +376,14 @@ namespace AzFramework class ScrollTranslationCameraInput : public CameraInput { public: - void HandleEvents(const InputEvent& event) override; + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; }; class OrbitCameraInput : public CameraInput { public: - void HandleEvents(const InputEvent& event) override; + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; bool Exclusive() const override { diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/ScreenGeometry.h b/Code/Framework/AzFramework/AzFramework/Viewport/ScreenGeometry.h index d3ae4e16f3..c48b1a5878 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/ScreenGeometry.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/ScreenGeometry.h @@ -134,11 +134,16 @@ namespace AzFramework return !operator==(lhs, rhs); } + inline float ScreenVectorLength(const ScreenVector& screenVector) + { + return aznumeric_cast(AZStd::sqrt(screenVector.m_x * screenVector.m_x + screenVector.m_y * screenVector.m_y)); + } + inline ScreenPoint ScreenPointFromNDC(const AZ::Vector3& screenNDC, const AZ::Vector2& viewportSize) { return ScreenPoint( - aznumeric_caster(std::round(screenNDC.GetX() * viewportSize.GetX())), - aznumeric_caster(std::round((1.0f - screenNDC.GetY()) * viewportSize.GetY()))); + aznumeric_caster(AZStd::round(screenNDC.GetX() * viewportSize.GetX())), + aznumeric_caster(AZStd::round((1.0f - screenNDC.GetY()) * viewportSize.GetY()))); } inline AZ::Vector2 NDCFromScreenPoint(const ScreenPoint& screenPoint, const AZ::Vector2& viewportSize) diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportScreenTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportScreenTests.cpp index 8b3a564c4d..8f4133de63 100644 --- a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportScreenTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportScreenTests.cpp @@ -211,6 +211,15 @@ namespace UnitTest EXPECT_EQ(screenPoint, ScreenPoint(45, 170)); } + TEST(ViewportScreen, ScreenVectorLengthReturned) + { + using AzFramework::ScreenVector; + + EXPECT_NEAR(AzFramework::ScreenVectorLength(ScreenVector(1, 1)), 1.41421f, 0.001f); + EXPECT_NEAR(AzFramework::ScreenVectorLength(ScreenVector(3, 4)), 5.0f, 0.001f); + EXPECT_NEAR(AzFramework::ScreenVectorLength(ScreenVector(12, 15)), 19.20937f, 0.001f); + } + TEST(ViewportScreen, CanGetCameraTransformFromCameraViewAndBack) { const auto screenDimensions = AZ::Vector2(1024.0f, 768.0f); diff --git a/Code/Sandbox/Editor/CryEditDoc.cpp b/Code/Sandbox/Editor/CryEditDoc.cpp index 83f7b482ae..64c830474f 100644 --- a/Code/Sandbox/Editor/CryEditDoc.cpp +++ b/Code/Sandbox/Editor/CryEditDoc.cpp @@ -579,14 +579,13 @@ void CCryEditDoc::SerializeViewSettings(CXmlArchive& xmlAr) view->getAttr(viewerAnglesName.toUtf8().constData(), va); } - CViewport* pVP = GetIEditor()->GetViewManager()->GetView(i); + Matrix34 tm = Matrix34::CreateRotationXYZ(va); + tm.SetTranslation(vp); - - if (pVP) + auto viewportContextManager = AZ::Interface::Get(); + if (auto viewportContext = viewportContextManager->GetViewportContextById(i)) { - Matrix34 tm = Matrix34::CreateRotationXYZ(va); - tm.SetTranslation(vp); - pVP->SetViewTM(tm); + viewportContext->SetCameraTransform(LYTransformToAZTransform(tm)); } // Load grid. diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index 3803867870..db37653cf1 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -453,8 +453,11 @@ void EditorViewportWidget::Update() } m_updatingCameraPosition = true; - auto transform = LYTransformToAZTransform(m_Camera.GetMatrix()); - m_renderViewport->GetViewportContext()->SetCameraTransform(transform); + if (!ed_useNewCameraSystem) + { + m_renderViewport->GetViewportContext()->SetCameraTransform(LYTransformToAZTransform(m_Camera.GetMatrix())); + } + AZ::Matrix4x4 clipMatrix; AZ::MakePerspectiveFovMatrixRH( clipMatrix, diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.cpp b/Code/Sandbox/Editor/ModernViewportCameraController.cpp index 1c2771514f..f5df8d48ca 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraController.cpp +++ b/Code/Sandbox/Editor/ModernViewportCameraController.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -64,17 +65,20 @@ namespace SandboxEditor } } - ModernViewportCameraControllerInstance::ModernViewportCameraControllerInstance(const AzFramework::ViewportId viewportId, ModernViewportCameraController* controller) + ModernViewportCameraControllerInstance::ModernViewportCameraControllerInstance( + const AzFramework::ViewportId viewportId, ModernViewportCameraController* controller) : MultiViewportControllerInstanceInterface(viewportId, controller) { controller->SetupCameras(m_cameraSystem.m_cameras); if (auto viewportContext = RetrieveViewportContext(GetViewportId())) { - auto handleCameraChange = [this](const AZ::Matrix4x4& matrix) { - UpdateCameraFromTransform( - m_targetCamera, - AZ::Transform::CreateFromMatrix3x3AndTranslation(AZ::Matrix3x3::CreateFromMatrix4x4(matrix), matrix.GetTranslation())); + auto handleCameraChange = [this, viewportContext](const AZ::Matrix4x4&) { + if (!m_updatingTransform) + { + UpdateCameraFromTransform(m_targetCamera, viewportContext->GetCameraTransform()); + m_camera = m_targetCamera; + } }; m_cameraViewMatrixChangeHandler = AZ::RPI::ViewportContext::MatrixChangedEvent::Handler(handleCameraChange); @@ -124,6 +128,8 @@ namespace SandboxEditor { if (auto viewportContext = RetrieveViewportContext(GetViewportId())) { + m_updatingTransform = true; + if (m_cameraMode == CameraMode::Control) { m_targetCamera = m_cameraSystem.StepCamera(m_targetCamera, event.m_deltaTime.count()); @@ -155,6 +161,8 @@ namespace SandboxEditor viewportContext->SetCameraTransform(current); } + + m_updatingTransform = false; } } diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.h b/Code/Sandbox/Editor/ModernViewportCameraController.h index b1ff8d1039..edc034a78a 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraController.h +++ b/Code/Sandbox/Editor/ModernViewportCameraController.h @@ -20,14 +20,13 @@ namespace SandboxEditor { class ModernViewportCameraControllerInstance; - class ModernViewportCameraController - : public AzFramework::MultiViewportController + class ModernViewportCameraController : public AzFramework::MultiViewportController { public: using CameraListBuilder = AZStd::function; + //! Sets the camera list builder callback used to populate new ModernViewportCameraControllerInstances void SetCameraListBuilderCallback(const CameraListBuilder& builder); - //! Sets up a camera list based on this controller's CameraListBuilderCallback void SetupCameras(AzFramework::Cameras& cameras); @@ -35,9 +34,9 @@ namespace SandboxEditor CameraListBuilder m_cameraListBuilder; }; - class ModernViewportCameraControllerInstance final - : public AzFramework::MultiViewportControllerInstanceInterface - , private AzFramework::ViewportDebugDisplayEventBus::Handler + class ModernViewportCameraControllerInstance final + : public AzFramework::MultiViewportControllerInstanceInterface, + private AzFramework::ViewportDebugDisplayEventBus::Handler { public: explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId, ModernViewportCameraController* controller); @@ -65,6 +64,7 @@ namespace SandboxEditor AZ::Transform m_transformEnd = AZ::Transform::CreateIdentity(); float m_animationT = 0.0f; CameraMode m_cameraMode = CameraMode::Control; + bool m_updatingTransform = false; AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraViewMatrixChangeHandler; }; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp index 4bccd48b66..cc25fb39ba 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp @@ -205,6 +205,7 @@ namespace AZ { const auto view = GetDefaultView(); view->SetCameraTransform(AZ::Matrix3x4::CreateFromTransform(transform.GetOrthogonalized())); + m_viewMatrixChangedEvent.Signal(view->GetWorldToViewMatrix()); } void ViewportContext::SetDefaultView(ViewPtr view) From b185a94519c22d9b91749e826d25e65a90f03b70 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Tue, 11 May 2021 14:09:09 +0100 Subject: [PATCH 102/225] Remove all references to old CGrid system (#672) * add overload to ActionManager to support capturing an AZStd::function * move snapping settings to new settings registry * remove unneeded reference in ViewportSettings * move viewport setting function implementations to .cpp file * add more sensible default values for snapping * fix variable name for angle snapping * remove const from function prototype value parameters * add import/export api for free functions * change from std::bind to a lambda * remove redundant const for constexpr string_view * add AZStd alias for std::abs * restore grid and angle snapping * add overload to ActionManager to support capturing an AZStd::function * remove old legacy CGrid code * fix build after merge * review feedback changes - remove 1.0f multiplies --- Code/Sandbox/Editor/2DViewport.cpp | 8 +- .../Editor/Core/LevelEditorMenuHandler.cpp | 3 - Code/Sandbox/Editor/CryEdit.cpp | 10 - Code/Sandbox/Editor/CryEdit.h | 1 - Code/Sandbox/Editor/CryEditDoc.cpp | 14 - Code/Sandbox/Editor/Grid.cpp | 150 ------ Code/Sandbox/Editor/Grid.h | 74 --- Code/Sandbox/Editor/GridSettingsDialog.cpp | 169 ------ Code/Sandbox/Editor/GridSettingsDialog.h | 65 --- Code/Sandbox/Editor/GridSettingsDialog.ui | 505 ------------------ Code/Sandbox/Editor/MainWindow.cpp | 59 +- Code/Sandbox/Editor/MainWindow.h | 2 - Code/Sandbox/Editor/Objects/AxisGizmo.cpp | 4 +- Code/Sandbox/Editor/Objects/BaseObject.cpp | 6 - .../Sandbox/Editor/Objects/SelectionGroup.cpp | 3 +- Code/Sandbox/Editor/RenderViewport.cpp | 96 +--- Code/Sandbox/Editor/Resource.h | 1 - Code/Sandbox/Editor/Settings.h | 5 - Code/Sandbox/Editor/ViewManager.cpp | 2 - Code/Sandbox/Editor/ViewManager.h | 6 - Code/Sandbox/Editor/Viewport.cpp | 4 +- Code/Sandbox/Editor/editor_lib_files.cmake | 5 - 22 files changed, 19 insertions(+), 1173 deletions(-) delete mode 100644 Code/Sandbox/Editor/Grid.cpp delete mode 100644 Code/Sandbox/Editor/Grid.h delete mode 100644 Code/Sandbox/Editor/GridSettingsDialog.cpp delete mode 100644 Code/Sandbox/Editor/GridSettingsDialog.h delete mode 100644 Code/Sandbox/Editor/GridSettingsDialog.ui diff --git a/Code/Sandbox/Editor/2DViewport.cpp b/Code/Sandbox/Editor/2DViewport.cpp index a511be0e2a..9eab4df16d 100644 --- a/Code/Sandbox/Editor/2DViewport.cpp +++ b/Code/Sandbox/Editor/2DViewport.cpp @@ -660,9 +660,7 @@ void Q2DViewport::Draw(DisplayContext& dc) ////////////////////////////////////////////////////////////////////////// void Q2DViewport::DrawGrid(DisplayContext& dc, bool bNoXNumbers) { - CGrid* pGrid = GetIEditor()->GetViewManager()->GetGrid(); - float gridSize = pGrid->size; - + float gridSize = 1.0f; if (gridSize < 0.00001f) { return; @@ -693,8 +691,6 @@ void Q2DViewport::DrawGrid(DisplayContext& dc, bool bNoXNumbers) pixelsPerGrid = gridSize * fScale; while (pixelsPerGrid <= 5 && griditers++ < 20) { - m_fGridZoom *= pGrid->majorLine; - gridSize = gridSize * pGrid->majorLine; pixelsPerGrid = gridSize * fScale; } } @@ -743,7 +739,7 @@ void Q2DViewport::DrawGrid(DisplayContext& dc, bool bNoXNumbers) ////////////////////////////////////////////////////////////////////////// // Draw Major grid lines. ////////////////////////////////////////////////////////////////////////// - gridSize = gridSize * pGrid->majorLine; + gridSize = gridSize * 1.0f; if (m_bAutoAdjustGrids) { diff --git a/Code/Sandbox/Editor/Core/LevelEditorMenuHandler.cpp b/Code/Sandbox/Editor/Core/LevelEditorMenuHandler.cpp index 1bb8dc37c7..0ce3fa55f5 100644 --- a/Code/Sandbox/Editor/Core/LevelEditorMenuHandler.cpp +++ b/Code/Sandbox/Editor/Core/LevelEditorMenuHandler.cpp @@ -729,9 +729,6 @@ QMenu* LevelEditorMenuHandler::CreateViewMenu() viewportViewsMenuWrapper.AddAction(ID_WIREFRAME); viewportViewsMenuWrapper.AddSeparator(); - viewportViewsMenuWrapper.AddAction(ID_VIEW_GRIDSETTINGS); - viewportViewsMenuWrapper.AddSeparator(); - if (CViewManager::IsMultiViewportEnabled()) { viewportViewsMenuWrapper.AddAction(ID_VIEW_CONFIGURELAYOUT); diff --git a/Code/Sandbox/Editor/CryEdit.cpp b/Code/Sandbox/Editor/CryEdit.cpp index c762244d38..6e33d32c6e 100644 --- a/Code/Sandbox/Editor/CryEdit.cpp +++ b/Code/Sandbox/Editor/CryEdit.cpp @@ -95,7 +95,6 @@ AZ_POP_DISABLE_WARNING #include "Core/QtEditorApplication.h" #include "StringDlg.h" #include "NewLevelDialog.h" -#include "GridSettingsDialog.h" #include "LayoutConfigDialog.h" #include "ViewManager.h" #include "FileTypeUtils.h" @@ -400,7 +399,6 @@ void CCryEditApp::RegisterActionHandlers() ON_COMMAND(ID_WIREFRAME, OnWireframe) - ON_COMMAND(ID_VIEW_GRIDSETTINGS, OnViewGridsettings) ON_COMMAND(ID_VIEW_CONFIGURELAYOUT, OnViewConfigureLayout) ON_COMMAND(IDC_SELECTION, OnDummyCommand) @@ -3459,14 +3457,6 @@ void CCryEditApp::OnUpdateWireframe(QAction* action) action->setChecked(nWireframe == R_WIREFRAME_MODE); } - -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnViewGridsettings() -{ - CGridSettingsDialog dlg; - dlg.exec(); -} - ////////////////////////////////////////////////////////////////////////// void CCryEditApp::OnViewConfigureLayout() { diff --git a/Code/Sandbox/Editor/CryEdit.h b/Code/Sandbox/Editor/CryEdit.h index 9599062d3f..2e71ca6a58 100644 --- a/Code/Sandbox/Editor/CryEdit.h +++ b/Code/Sandbox/Editor/CryEdit.h @@ -366,7 +366,6 @@ private: void OnWireframe(); void OnUpdateWireframe(QAction* action); - void OnViewGridsettings(); void OnViewConfigureLayout(); // Tag Locations. diff --git a/Code/Sandbox/Editor/CryEditDoc.cpp b/Code/Sandbox/Editor/CryEditDoc.cpp index 64c830474f..a6c5f73c7f 100644 --- a/Code/Sandbox/Editor/CryEditDoc.cpp +++ b/Code/Sandbox/Editor/CryEditDoc.cpp @@ -587,15 +587,6 @@ void CCryEditDoc::SerializeViewSettings(CXmlArchive& xmlAr) { viewportContext->SetCameraTransform(LYTransformToAZTransform(tm)); } - - // Load grid. - auto gridName = QString("Grid%1").arg(useOldViewFormat ? "" : QString::number(i)); - XmlNodeRef gridNode = xmlAr.root->newChild(gridName.toUtf8().constData()); - - if (gridNode) - { - GetIEditor()->GetViewManager()->GetGrid()->Serialize(gridNode, xmlAr.bLoading); - } } } else @@ -621,11 +612,6 @@ void CCryEditDoc::SerializeViewSettings(CXmlArchive& xmlAr) auto viewerAnglesName = QString("ViewerAngles%1").arg(i); view->setAttr(viewerAnglesName.toUtf8().constData(), angles); } - - // Save grid. - auto gridName = QString("Grid%1").arg(i); - XmlNodeRef gridNode = xmlAr.root->newChild(gridName.toUtf8().constData()); - GetIEditor()->GetViewManager()->GetGrid()->Serialize(gridNode, xmlAr.bLoading); } } } diff --git a/Code/Sandbox/Editor/Grid.cpp b/Code/Sandbox/Editor/Grid.cpp deleted file mode 100644 index 50702f8cb2..0000000000 --- a/Code/Sandbox/Editor/Grid.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "Grid.h" - -// Editor -#include "Settings.h" -#include "Objects/SelectionGroup.h" - -////////////////////////////////////////////////////////////////////////// -CGrid::CGrid() -{ - scale = 1; - size = 1; - majorLine = 16; - bEnabled = true; - rotationAngles = Ang3(0.0f, 0.0f, 0.0f); - translation = Vec3(0.0f, 0.0f, 0.0f); - - bAngleSnapEnabled = true; - angleSnap = 5; -} - -////////////////////////////////////////////////////////////////////////// -Vec3 CGrid::Snap(const Vec3& vec) const -{ - if (!bEnabled || size < 0.001) - { - return vec; - } - Vec3 snapped; - snapped.x = floor((vec.x / size) / scale + 0.5) * size * scale; - snapped.y = floor((vec.y / size) / scale + 0.5) * size * scale; - snapped.z = floor((vec.z / size) / scale + 0.5) * size * scale; - return snapped; -} - -////////////////////////////////////////////////////////////////////////// -Vec3 CGrid::Snap(const Vec3& vec, double fZoom) const -{ - if (!bEnabled || size < 0.001f) - { - return vec; - } - - Matrix34 tm = GetMatrix(); - - double zoomscale = scale * fZoom; - Vec3 snapped; - - Matrix34 invtm = tm.GetInverted(); - - snapped = invtm * vec; - - snapped.x = floor((snapped.x / size) / zoomscale + 0.5) * size * zoomscale; - snapped.y = floor((snapped.y / size) / zoomscale + 0.5) * size * zoomscale; - snapped.z = floor((snapped.z / size) / zoomscale + 0.5) * size * zoomscale; - - snapped = tm * snapped; - - return snapped; -} - -////////////////////////////////////////////////////////////////////////// -double CGrid::SnapAngle(double angle) const -{ - if (!bAngleSnapEnabled) - { - return angle; - } - return floor(angle / angleSnap + 0.5) * angleSnap; -} - -////////////////////////////////////////////////////////////////////////// -Ang3 CGrid::SnapAngle(const Ang3& vec) const -{ - if (!bAngleSnapEnabled) - { - return vec; - } - Ang3 snapped; - snapped.x = floor(vec.x / angleSnap + 0.5) * angleSnap; - snapped.y = floor(vec.y / angleSnap + 0.5) * angleSnap; - snapped.z = floor(vec.z / angleSnap + 0.5) * angleSnap; - return snapped; -} - -////////////////////////////////////////////////////////////////////////// -void CGrid::Serialize(XmlNodeRef& xmlNode, bool bLoading) -{ - if (bLoading) - { - // Loading. - xmlNode->getAttr("Size", size); - xmlNode->getAttr("Scale", scale); - xmlNode->getAttr("Enabled", bEnabled); - xmlNode->getAttr("MajorSize", majorLine); - xmlNode->getAttr("AngleSnap", angleSnap); - xmlNode->getAttr("AngleSnapEnabled", bAngleSnapEnabled); - if (size < 0.01) - { - size = 0.01; - } - } - else - { - // Saving. - xmlNode->setAttr("Size", size); - xmlNode->setAttr("Scale", scale); - xmlNode->setAttr("Enabled", bEnabled); - xmlNode->setAttr("MajorSize", majorLine); - xmlNode->setAttr("AngleSnap", angleSnap); - xmlNode->setAttr("AngleSnapEnabled", bAngleSnapEnabled); - } -} - -////////////////////////////////////////////////////////////////////////// -Matrix34 CGrid::GetMatrix() const -{ - Matrix34 tm; - - if (gSettings.snap.bGridUserDefined) - { - Ang3 angles = Ang3(rotationAngles.x * gf_PI / 180.0, rotationAngles.y * gf_PI / 180.0, rotationAngles.z * gf_PI / 180.0); - - tm = Matrix33::CreateRotationXYZ(angles); - } - else if (GetIEditor()->GetReferenceCoordSys() == COORDS_LOCAL) - { - tm.SetIdentity(); - } - else - { - tm.SetIdentity(); - } - - return tm; -} diff --git a/Code/Sandbox/Editor/Grid.h b/Code/Sandbox/Editor/Grid.h deleted file mode 100644 index dd761ad058..0000000000 --- a/Code/Sandbox/Editor/Grid.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITOR_GRID_H -#define CRYINCLUDE_EDITOR_GRID_H - -#pragma once - -/** Definition of grid used in 2D viewports. -*/ -class SANDBOX_API CGrid -{ -public: - //! Resolution of grid, it must be multiply of 2. - double size; - //! Draw major lines every Nth grid line. - int majorLine; - //! True if grid enabled. - bool bEnabled; - //! Meters per grid unit. - double scale; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - Ang3 rotationAngles; - Vec3 translation; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - //! If snap to angle. - bool bAngleSnapEnabled; - double angleSnap; - - ////////////////////////////////////////////////////////////////////////// - CGrid(); - - //! Snap vector to this grid. - Vec3 Snap(const Vec3& vec) const; - Vec3 Snap(const Vec3& vec, double fZoom) const; - - //! Snap angle to current angle snapping value. - double SnapAngle(double angle) const; - //! Snap angle to current angle snapping value. - Ang3 SnapAngle(const Ang3& angle) const; - - //! Enable or disable grid. - void Enable(bool enable) { bEnabled = enable; } - //! Check if grid enabled. - bool IsEnabled() const { return bEnabled; } - - //! Enables or disable angle snapping. - void EnableAngleSnap(bool enable) { bAngleSnapEnabled = enable; }; - - //! Return if snapping of angle is enabled. - bool IsAngleSnapEnabled() const { return bAngleSnapEnabled; }; - //! Returns ammount of snapping for angle in degrees. - double GetAngleSnap() const { return angleSnap; }; - - void Serialize(XmlNodeRef& xmlNode, bool bLoading); - - //! Get transformation matrix of gird. - Matrix34 GetMatrix() const; -}; - - -#endif // CRYINCLUDE_EDITOR_GRID_H diff --git a/Code/Sandbox/Editor/GridSettingsDialog.cpp b/Code/Sandbox/Editor/GridSettingsDialog.cpp deleted file mode 100644 index ecabdc4e6a..0000000000 --- a/Code/Sandbox/Editor/GridSettingsDialog.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "GridSettingsDialog.h" - -// Editor -#include "Settings.h" -#include "Objects/SelectionGroup.h" -#include "ViewManager.h" - - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - -// CGridSettingsDialog dialog - -CGridSettingsDialog::CGridSettingsDialog(QWidget* pParent /*=NULL*/) - : QDialog(pParent) - , ui(new Ui::CGridSettingsDialog) -{ - ui->setupUi(this); - - setWindowTitle(tr("Grid/Snap Settings")); - - OnInitDialog(); - - connect(ui->m_userDefined, &QCheckBox::clicked, this, &CGridSettingsDialog::OnBnUserDefined); - connect(ui->m_getFromObject, &QCheckBox::clicked, this, &CGridSettingsDialog::OnBnGetFromObject); - - auto doubleSpinBoxValueChanged = static_cast(&QDoubleSpinBox::valueChanged); - - connect(ui->m_angleX, doubleSpinBoxValueChanged, this, &CGridSettingsDialog::OnValueUpdate); - connect(ui->m_angleY, doubleSpinBoxValueChanged, this, &CGridSettingsDialog::OnValueUpdate); - connect(ui->m_angleZ, doubleSpinBoxValueChanged, this, &CGridSettingsDialog::OnValueUpdate); - - connect(ui->m_gridSize, doubleSpinBoxValueChanged, this, &CGridSettingsDialog::OnValueUpdate); - connect(ui->m_gridScale, doubleSpinBoxValueChanged, this, &CGridSettingsDialog::OnValueUpdate); - connect(ui->m_CPSize, doubleSpinBoxValueChanged, this, &CGridSettingsDialog::OnValueUpdate); - - connect(ui->m_displayCP, &QCheckBox::clicked, this, &CGridSettingsDialog::OnValueUpdate); - connect(ui->m_getFromObject, &QCheckBox::clicked, this, &CGridSettingsDialog::OnValueUpdate); - - connect(ui->m_buttonBox, &QDialogButtonBox::accepted, this, &CGridSettingsDialog::accept); - connect(ui->m_buttonBox, &QDialogButtonBox::rejected, this, &CGridSettingsDialog::reject); -} - -CGridSettingsDialog::~CGridSettingsDialog() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CGridSettingsDialog::OnInitDialog() -{ - CGrid* pGrid = GetIEditor()->GetViewManager()->GetGrid(); - - ui->m_userDefined->setChecked(gSettings.snap.bGridUserDefined); - ui->m_getFromObject->setChecked(gSettings.snap.bGridGetFromSelected); - - ui->m_angleX->setValue(pGrid->rotationAngles.x); - ui->m_angleY->setValue(pGrid->rotationAngles.y); - ui->m_angleZ->setValue(pGrid->rotationAngles.z); - - ui->m_translationX->setValue(pGrid->translation.x); - ui->m_translationY->setValue(pGrid->translation.y); - ui->m_translationZ->setValue(pGrid->translation.z); - - ui->m_gridSize->setValue(pGrid->size); - ui->m_gridScale->setValue(pGrid->scale); - ui->m_snapToGrid->setChecked(pGrid->IsEnabled()); - - ui->m_angleSnap->setChecked(pGrid->IsAngleSnapEnabled()); - ui->m_angleSnapScale->setValue(pGrid->GetAngleSnap()); - ui->m_displayCP->setChecked(gSettings.snap.constructPlaneDisplay); - - ui->m_CPSize->setValue(gSettings.snap.constructPlaneSize); - ui->m_displaySnapMarker->setChecked(gSettings.snap.markerDisplay); - ui->m_snapMarkerSize->setValue(gSettings.snap.markerSize); - - ui->m_snapMarkerColor->SetColor(gSettings.snap.markerColor); - - EnableGridPropertyControls(gSettings.snap.bGridUserDefined, gSettings.snap.bGridGetFromSelected); -} - -////////////////////////////////////////////////////////////////////////// -void CGridSettingsDialog::accept() -{ - UpdateValues(); - gSettings.Save(); - QDialog::accept(); -} - -void CGridSettingsDialog::OnBnUserDefined() -{ - EnableGridPropertyControls(ui->m_userDefined->isChecked(), ui->m_getFromObject->isChecked()); - OnValueUpdate(); -} - -void CGridSettingsDialog::OnBnGetFromObject() -{ - EnableGridPropertyControls(ui->m_userDefined->isChecked(), ui->m_getFromObject->isChecked()); -} - -void CGridSettingsDialog::EnableGridPropertyControls(const bool isUserDefined, const bool isGetFromObject) -{ - ui->m_getFromObject->setEnabled(isUserDefined == true); - - ui->m_angleX->setEnabled(isUserDefined == true && isGetFromObject == false); - ui->m_angleY->setEnabled(isUserDefined == true && isGetFromObject == false); - ui->m_angleZ->setEnabled(isUserDefined == true && isGetFromObject == false); - ui->m_translationX->setEnabled(isUserDefined == true && isGetFromObject == false); - ui->m_translationY->setEnabled(isUserDefined == true && isGetFromObject == false); - ui->m_translationZ->setEnabled(isUserDefined == true && isGetFromObject == false); - ui->m_getAnglesFromObject->setEnabled(isUserDefined == true && isGetFromObject == false); - ui->m_getTranslationFromObject->setEnabled(isUserDefined == true && isGetFromObject == false); -} - -////////////////////////////////////////////////////////////////////////// -void CGridSettingsDialog::UpdateValues() -{ - CGrid* pGrid = GetIEditor()->GetViewManager()->GetGrid(); - - pGrid->Enable(ui->m_snapToGrid->isChecked()); - pGrid->size = ui->m_gridSize->value(); - pGrid->scale = ui->m_gridScale->value(); - - gSettings.snap.bGridUserDefined = ui->m_userDefined->isChecked(); - gSettings.snap.bGridGetFromSelected = ui->m_getFromObject->isChecked(); - pGrid->rotationAngles.x = ui->m_angleX->value(); - pGrid->rotationAngles.y = ui->m_angleY->value(); - pGrid->rotationAngles.z = ui->m_angleZ->value(); - pGrid->translation.x = ui->m_translationX->value(); - pGrid->translation.y = ui->m_translationY->value(); - pGrid->translation.z = ui->m_translationZ->value(); - - pGrid->bAngleSnapEnabled = ui->m_angleSnap->isChecked(); - pGrid->angleSnap = ui->m_angleSnapScale->value(); - - gSettings.snap.constructPlaneDisplay = ui->m_displayCP->isChecked(); - gSettings.snap.constructPlaneSize = ui->m_CPSize->value(); - - gSettings.snap.markerDisplay = ui->m_displaySnapMarker->isChecked(); - gSettings.snap.markerSize = ui->m_snapMarkerSize->value(); - gSettings.snap.markerColor = ui->m_snapMarkerColor->Color(); - - NotificationBus::Broadcast(&Notifications::OnGridValuesUpdated); -} - - -////////////////////////////////////////////////////////////////////////// -void CGridSettingsDialog::OnValueUpdate() -{ - UpdateValues(); - GetIEditor()->UpdateViews(eRedrawViewports); -} - -#include diff --git a/Code/Sandbox/Editor/GridSettingsDialog.h b/Code/Sandbox/Editor/GridSettingsDialog.h deleted file mode 100644 index fe5934ec7e..0000000000 --- a/Code/Sandbox/Editor/GridSettingsDialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITOR_GRIDSETTINGSDIALOG_H -#define CRYINCLUDE_EDITOR_GRIDSETTINGSDIALOG_H - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#endif - -// CGridSettingsDialog dialog - -namespace Ui { - class CGridSettingsDialog; -} - -class CGridSettingsDialog - : public QDialog -{ - Q_OBJECT -public: - - class Notifications - : public AZ::EBusTraits - { - public: - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - virtual void OnGridValuesUpdated() {} - }; - - using NotificationBus = AZ::EBus; - - CGridSettingsDialog(QWidget* pParent = nullptr); // standard constructor - virtual ~CGridSettingsDialog(); - -private slots: - void accept() override; - void OnBnUserDefined(); - void OnBnGetFromObject(); - void OnValueUpdate(); - -private: - void EnableGridPropertyControls(const bool isUserDefined, const bool isGetFromObject); - - void OnInitDialog(); - void UpdateValues(); - - QScopedPointer ui; -}; - -#endif // CRYINCLUDE_EDITOR_GRIDSETTINGSDIALOG_H diff --git a/Code/Sandbox/Editor/GridSettingsDialog.ui b/Code/Sandbox/Editor/GridSettingsDialog.ui deleted file mode 100644 index f77abbece7..0000000000 --- a/Code/Sandbox/Editor/GridSettingsDialog.ui +++ /dev/null @@ -1,505 +0,0 @@ - - - CGridSettingsDialog - - - - 0 - 0 - 307 - 707 - - - - - - - - - Grid - - - - - - Snap to Grid - - - - - - - Grid Lines Every: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0.010000000000000 - - - 1024.000000000000000 - - - 0.010000000000000 - - - - - - - units - - - - - - - Units Per Meter: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0.010000000000000 - - - 1024.000000000000000 - - - 0.010000000000000 - - - - - - - meters - - - - - - - User Defined Grid - - - - - - - Get Angles And Trans. From Selected - - - - - - - Rotation by X: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.010000000000000 - - - - - - - degrees - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Rotation by Y: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.010000000000000 - - - - - - - degrees - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Rotation by Z: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.010000000000000 - - - - - - - degrees - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Translation by X: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0.010000000000000 - - - - - - - Translation by Y: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0.010000000000000 - - - - - - - Translation by Z: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0.010000000000000 - - - - - - - Get Angles From Selected - - - - - - - Get Translation From Selected - - - - - - - - - - Angle Snapping - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 80 - 0 - - - - degrees - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Angle Snap - - - - - - - Angle Snap: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 0 - - - - - - - - - - - Construction Plane - - - - - - Size: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Display - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0.010000000000000 - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 80 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - m_displayCP - m_CPSize - - - - - - Snap Marker - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 0.010000000000000 - - - - - - - Display - - - - - - - - 80 - 0 - - - - Color - - - - - - - Size: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - ColorButton - QToolButton -

    QtUI/ColorButton.h
    - - - - - diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index 5abb780bac..b1d85c2999 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -66,7 +66,6 @@ AZ_POP_DISABLE_WARNING #include "AssetImporter/AssetImporterManager/AssetImporterDragAndDropHandler.h" #include "CryEdit.h" #include "Controls/ConsoleSCB.h" -#include "Grid.h" #include "ViewManager.h" #include "CryEditDoc.h" #include "ToolBox.h" @@ -97,7 +96,6 @@ AZ_POP_DISABLE_WARNING #include "AzAssetBrowser/AzAssetBrowserWindow.h" #include "AssetEditor/AssetEditorWindow.h" -#include "GridSettingsDialog.h" #include "ActionManager.h" // uncomment this to show thumbnail demo widget @@ -123,12 +121,6 @@ static const char* g_openLocationAttributeName = "OpenLocation"; //Indicates whe static const char* g_assetImporterName = "AssetImporter"; -static const char* g_snapToGridEnabled = "mainwindow/snapGridEnabled"; -static const char* g_snapToGridSize = "mainwindow/snapGridSize"; -static const char* g_snapAngleEnabled = "mainwindow/snapAngleEnabled"; -static const char* g_snapAngle = "mainwindow/snapAngle"; -static const char* g_terrainFollow = "mainwindow/terrainFollow"; - class CEditorOpenViewCommand : public _i_reference_target_t { @@ -308,10 +300,8 @@ namespace class SnapToWidget : public QWidget - , public CGridSettingsDialog::NotificationBus::Handler { public: - typedef AZStd::function SetValueCallback; typedef AZStd::function GetValueCallback; @@ -335,12 +325,13 @@ public: m_spinBox->setEnabled(defaultAction->isChecked()); m_spinBox->setMinimum(1e-2f); - OnGridValuesUpdated(); + { + QSignalBlocker signalBlocker(m_spinBox); + m_spinBox->setValue(m_getValueCallback()); + } QObject::connect(m_spinBox, QOverload::of(&AzQtComponents::DoubleSpinBox::valueChanged), this, &SnapToWidget::OnValueChanged); QObject::connect(defaultAction, &QAction::changed, this, &SnapToWidget::OnActionChanged); - - CGridSettingsDialog::NotificationBus::Handler::BusConnect(); } void SetIcon(QIcon icon) @@ -348,14 +339,6 @@ public: m_toolButton->setIcon(icon); } - void OnGridValuesUpdated() override - { - // Blocking signals to not trigger the valueChanged callback when we set the value on the spin box. - QSignalBlocker signalBlocker(m_spinBox); - double value = m_getValueCallback(); - m_spinBox->setValue(value); - } - protected: void OnValueChanged(double value) @@ -543,7 +526,6 @@ void MainWindow::Initialize() RegisterStdViewClasses(); InitCentralWidget(); - LoadConfig(); InitActions(); // load toolbars ("shelves") and macros @@ -673,31 +655,8 @@ void MainWindow::closeEvent(QCloseEvent* event) QMainWindow::closeEvent(event); } -void MainWindow::LoadConfig() -{ - CGrid* grid = gSettings.pGrid; - Q_ASSERT(grid); - bool terrainValue; - - ReadConfigValue(g_snapAngleEnabled, grid->bAngleSnapEnabled); - ReadConfigValue(g_snapAngle, grid->angleSnap); - ReadConfigValue(g_snapToGridEnabled, grid->bEnabled); - ReadConfigValue(g_snapToGridSize, grid->size); - ReadConfigValue(g_terrainFollow, terrainValue); - GetIEditor()->SetTerrainAxisIgnoreObjects(terrainValue); -} - void MainWindow::SaveConfig() { - CGrid* grid = gSettings.pGrid; - Q_ASSERT(grid); - - m_settings.setValue(g_snapAngleEnabled, grid->bAngleSnapEnabled); - m_settings.setValue(g_snapAngle, grid->angleSnap); - m_settings.setValue(g_snapToGridEnabled, grid->bEnabled); - m_settings.setValue(g_snapToGridSize, grid->size); - m_settings.setValue(g_terrainFollow, GetIEditor()->IsTerrainAxisIgnoreObjects()); - m_settings.setValue("mainWindowState", saveState()); QtViewPaneManager::instance()->SaveLayout(); if (m_pLayoutWnd) @@ -941,7 +900,6 @@ void MainWindow::InitActions() .SetStatusTip(tr("Render in Wireframe Mode.")) .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateWireframe); - am->AddAction(ID_VIEW_GRIDSETTINGS, tr("Grid Settings...")); am->AddAction(ID_SWITCHCAMERA_DEFAULTCAMERA, tr("Default Camera")).SetCheckable(true) .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateSwitchToDefaultCamera); am->AddAction(ID_SWITCHCAMERA_SEQUENCECAMERA, tr("Sequence Camera")).SetCheckable(true) @@ -1479,15 +1437,6 @@ MainStatusBar* MainWindow::StatusBar() const return static_cast(statusBar()); } -void MainWindow::OnUpdateSnapToGrid(QAction* action) -{ - Q_ASSERT(action->isCheckable()); - bool bEnabled = gSettings.pGrid->IsEnabled(); - action->setChecked(bEnabled); - - action->setText(QObject::tr("Snap To Grid")); -} - KeyboardCustomizationSettings* MainWindow::GetShortcutManager() const { return m_keyboardCustomization; diff --git a/Code/Sandbox/Editor/MainWindow.h b/Code/Sandbox/Editor/MainWindow.h index adf271b383..ca8cc11677 100644 --- a/Code/Sandbox/Editor/MainWindow.h +++ b/Code/Sandbox/Editor/MainWindow.h @@ -191,9 +191,7 @@ private: void InitToolActionHandlers(); void InitToolBars(); void InitStatusBar(); - void OnUpdateSnapToGrid(QAction* action); void OnViewPaneCreated(const QtViewPane* pane); - void LoadConfig(); template void ReadConfigValue(const QString& key, TValue& value) diff --git a/Code/Sandbox/Editor/Objects/AxisGizmo.cpp b/Code/Sandbox/Editor/Objects/AxisGizmo.cpp index ef2b91685a..8e10d03080 100644 --- a/Code/Sandbox/Editor/Objects/AxisGizmo.cpp +++ b/Code/Sandbox/Editor/Objects/AxisGizmo.cpp @@ -18,7 +18,6 @@ // Editor #include "Viewport.h" #include "GizmoManager.h" -#include "Grid.h" #include "ViewManager.h" #include "Settings.h" #include "RenderHelpers/AxisHelper.h" @@ -244,7 +243,8 @@ Matrix34 CAxisGizmo::GetTransformation(RefCoordSys coordSys, IDisplayViewport* v break; case COORDS_USERDEFINED: { - Matrix34 userTM = GetIEditor()->GetViewManager()->GetGrid()->GetMatrix(); + Matrix34 userTM; + userTM.SetIdentity(); userTM.SetTranslation(m_object->GetWorldTM().GetTranslation()); return userTM; } diff --git a/Code/Sandbox/Editor/Objects/BaseObject.cpp b/Code/Sandbox/Editor/Objects/BaseObject.cpp index 6819bb5469..4c76f68f2f 100644 --- a/Code/Sandbox/Editor/Objects/BaseObject.cpp +++ b/Code/Sandbox/Editor/Objects/BaseObject.cpp @@ -1268,12 +1268,6 @@ int CBaseObject::MouseCreateCallback(CViewport* view, EMouseEvent event, QPoint& if (event == eMouseWheel) { double angle = 1; - - if (view->GetViewManager()->GetGrid()->IsAngleSnapEnabled()) - { - angle = view->GetViewManager()->GetGrid()->GetAngleSnap(); - } - Quat rot = GetRotation(); rot.SetRotationXYZ(Ang3(0, 0, rot.GetRotZ() + DEG2RAD(flags > 0 ? angle * (-1) : angle))); SetRotation(rot); diff --git a/Code/Sandbox/Editor/Objects/SelectionGroup.cpp b/Code/Sandbox/Editor/Objects/SelectionGroup.cpp index 98e00645ee..a2c88c7302 100644 --- a/Code/Sandbox/Editor/Objects/SelectionGroup.cpp +++ b/Code/Sandbox/Editor/Objects/SelectionGroup.cpp @@ -342,7 +342,8 @@ void CSelectionGroup::Rotate(const Matrix34& rotateTM, int referenceCoordSys) if (referenceCoordSys == COORDS_USERDEFINED) { - Matrix34 userTM = GetIEditor()->GetViewManager()->GetGrid()->GetMatrix(); + Matrix34 userTM; + userTM.SetIdentity(); Matrix34 invUserTM = userTM.GetInvertedFast(); ToOrigin = invUserTM * ToOrigin; diff --git a/Code/Sandbox/Editor/RenderViewport.cpp b/Code/Sandbox/Editor/RenderViewport.cpp index 49064b5bc5..f199590e4f 100644 --- a/Code/Sandbox/Editor/RenderViewport.cpp +++ b/Code/Sandbox/Editor/RenderViewport.cpp @@ -1993,28 +1993,27 @@ AzFramework::CameraState CRenderViewport::GetCameraState() bool CRenderViewport::GridSnappingEnabled() { - return GetViewManager()->GetGrid()->IsEnabled(); + return false; } float CRenderViewport::GridSize() { - const CGrid* grid = GetViewManager()->GetGrid(); - return grid->scale * grid->size; + return 0.0f; } bool CRenderViewport::ShowGrid() { - return gSettings.viewports.bShowGridGuide; + return false; } bool CRenderViewport::AngleSnappingEnabled() { - return GetViewManager()->GetGrid()->IsAngleSnapEnabled(); + return false; } float CRenderViewport::AngleStep() { - return GetViewManager()->GetGrid()->GetAngleSnap(); + return 0.0f; } AZ::Vector3 CRenderViewport::PickTerrain(const AzFramework::ScreenPoint& point) @@ -3890,94 +3889,13 @@ void CRenderViewport::ActivateWindowAndSetFocus() ////////////////////////////////////////////////////////////////////////// void CRenderViewport::RenderConstructionPlane() { - DisplayContext& dc = m_displayContext; - - int prevState = dc.GetState(); - dc.DepthWriteOff(); - // Draw Construction plane. - - CGrid* pGrid = GetViewManager()->GetGrid(); - - RefCoordSys coordSys = COORDS_WORLD; - - Vec3 p = m_constructionMatrix[coordSys].GetTranslation(); - Vec3 n = m_constructionPlane.n; - - Vec3 u = Vec3(1, 0, 0); - Vec3 v = Vec3(0, 1, 0); - - - if (gSettings.snap.bGridUserDefined) - { - Ang3 angles = Ang3(pGrid->rotationAngles.x * gf_PI / 180.0, pGrid->rotationAngles.y * gf_PI / 180.0, pGrid->rotationAngles.z * gf_PI / 180.0); - Matrix34 tm = Matrix33::CreateRotationXYZ(angles); - - u = tm * u; - v = tm * v; - } - - float step = pGrid->scale * pGrid->size; - float size = gSettings.snap.constructPlaneSize; - - dc.SetColor(0, 0, 1, 0.1f); - - float s = size; - - dc.DrawQuad(p - u * s - v * s, p + u * s - v * s, p + u * s + v * s, p - u * s + v * s); - - int nSteps = int(size / step); - int i; - // Draw X lines. - dc.SetColor(1, 0, 0.2f, 0.3f); - - for (i = -nSteps; i <= nSteps; i++) - { - dc.DrawLine(p - u * size + v * (step * i), p + u * size + v * (step * i)); - } - // Draw Y lines. - dc.SetColor(0.2f, 1.0f, 0, 0.3f); - for (i = -nSteps; i <= nSteps; i++) - { - dc.DrawLine(p - v * size + u * (step * i), p + v * size + u * (step * i)); - } - - // Draw origin lines. - - dc.SetLineWidth(2); - - //X - dc.SetColor(1, 0, 0); - dc.DrawLine(p - u * s, p + u * s); - - //Y - dc.SetColor(0, 1, 0); - dc.DrawLine(p - v * s, p + v * s); - - //Z - dc.SetColor(0, 0, 1); - dc.DrawLine(p - n * s, p + n * s); - - dc.SetLineWidth(0); - - dc.SetState(prevState); + // noop } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::RenderSnappingGrid() { - // First, Check whether we should draw the grid or not. - CGrid* pGrid = GetViewManager()->GetGrid(); - if (pGrid->IsEnabled() == false && pGrid->IsAngleSnapEnabled() == false) - { - return; - } - - DisplayContext& dc = m_displayContext; - - int prevState = dc.GetState(); - dc.DepthWriteOff(); - - dc.SetState(prevState); + // noop } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Sandbox/Editor/Resource.h b/Code/Sandbox/Editor/Resource.h index ddc9ff2359..31fc9909f1 100644 --- a/Code/Sandbox/Editor/Resource.h +++ b/Code/Sandbox/Editor/Resource.h @@ -79,7 +79,6 @@ #define ID_EDIT_HIDE 32898 #define ID_EDIT_UNHIDEALL 32899 #define ID_RELOAD_TERRAIN 32902 -#define ID_VIEW_GRIDSETTINGS 32904 #define ID_VIEW_CONFIGURELAYOUT 32906 #define ID_TOOLS_LOGMEMORYUSAGE 32908 #define ID_TERRAIN_EXPORTBLOCK 32909 diff --git a/Code/Sandbox/Editor/Settings.h b/Code/Sandbox/Editor/Settings.h index 93e61bc1ed..b4609555df 100644 --- a/Code/Sandbox/Editor/Settings.h +++ b/Code/Sandbox/Editor/Settings.h @@ -40,8 +40,6 @@ #include -class CGrid; - struct SGizmoSettings { float axisGizmoSize; @@ -393,9 +391,6 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING //! Keeps the editor active even if no focus is set int keepEditorActive; - //! Pointer to currently used grid. - CGrid* pGrid; - SGizmoSettings gizmo; // Settings of the snapping. diff --git a/Code/Sandbox/Editor/ViewManager.cpp b/Code/Sandbox/Editor/ViewManager.cpp index 334e78a826..8bb14a3aca 100644 --- a/Code/Sandbox/Editor/ViewManager.cpp +++ b/Code/Sandbox/Editor/ViewManager.cpp @@ -49,8 +49,6 @@ bool CViewManager::IsMultiViewportEnabled() ////////////////////////////////////////////////////////////////////// CViewManager::CViewManager() { - gSettings.pGrid = &m_grid; - m_zoomFactor = 1; m_origin2D(0, 0, 0); diff --git a/Code/Sandbox/Editor/ViewManager.h b/Code/Sandbox/Editor/ViewManager.h index d617b5c54e..e2b42573d5 100644 --- a/Code/Sandbox/Editor/ViewManager.h +++ b/Code/Sandbox/Editor/ViewManager.h @@ -20,7 +20,6 @@ #pragma once #include "Cry_Geo.h" -#include "Grid.h" #include "Viewport.h" #include "Include/IViewPane.h" #include "QtViewPaneManager.h" @@ -67,10 +66,6 @@ public: void SetUpdateRegion(const AABB& updateRegion) { m_updateRegion = updateRegion; }; const AABB& GetUpdateRegion() { return m_updateRegion; }; - /** Retrieve Grid used for viewes. - */ - CGrid* GetGrid() { return &m_grid; }; - /** Get 2D viewports origin. */ Vec3 GetOrigin2D() const { return m_origin2D; } @@ -137,7 +132,6 @@ private: AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING AABB m_updateRegion; - CGrid m_grid; //! Origin of 2d viewports. Vec3 m_origin2D; //! Zoom of 2d viewports. diff --git a/Code/Sandbox/Editor/Viewport.cpp b/Code/Sandbox/Editor/Viewport.cpp index cc278b18b0..da4a389aa0 100644 --- a/Code/Sandbox/Editor/Viewport.cpp +++ b/Code/Sandbox/Editor/Viewport.cpp @@ -1182,12 +1182,12 @@ float QtViewport::GetZoomFactor() const ////////////////////////////////////////////////////////////////////////// Vec3 QtViewport::SnapToGrid(const Vec3& vec) { - return m_viewManager->GetGrid()->Snap(vec, m_fGridZoom); + return vec; } float QtViewport::GetGridStep() const { - return m_viewManager->GetGrid()->scale * m_viewManager->GetGrid()->size; + return 0.0f; } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index 5f6c1ed2bd..4832e2b8c2 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -437,9 +437,6 @@ set(FILES GotoPositionDlg.cpp GotoPositionDlg.h GotoPositionDlg.ui - GridSettingsDialog.cpp - GridSettingsDialog.h - GridSettingsDialog.ui InfoBar.cpp InfoBar.qrc InfoBar.h @@ -835,8 +832,6 @@ set(FILES WelcomeScreen/WelcomeScreenDialog.qrc 2DViewport.cpp 2DViewport.h - Grid.cpp - Grid.h LayoutWnd.cpp LayoutWnd.h EditorViewportWidget.cpp From 8e90e87bc83774d767cda5124871dd40df8c8642 Mon Sep 17 00:00:00 2001 From: greerdv Date: Tue, 11 May 2021 16:17:23 +0100 Subject: [PATCH 103/225] fixing bug with shape collider editor body not being deleted when it is recreated --- .../Source/EditorShapeColliderComponent.cpp | 34 ++++++++++++++----- .../Source/EditorShapeColliderComponent.h | 1 - 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp index 0a8bca33ea..2c86a18301 100644 --- a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp @@ -267,8 +267,14 @@ namespace PhysX if (m_sceneInterface) { + //remove the previous body if any + if (m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) + { + m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorBodyHandle); + m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; + } + m_editorBodyHandle = m_sceneInterface->AddSimulatedBody(m_editorSceneHandle, &configuration); - m_editorBody = azdynamic_cast(m_sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorBodyHandle)); } AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); @@ -676,7 +682,6 @@ namespace PhysX { m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorBodyHandle); m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; - m_editorBody = nullptr; } } @@ -747,21 +752,31 @@ namespace PhysX bool EditorShapeColliderComponent::IsPhysicsEnabled() const { - return m_editorBody != nullptr && m_editorBody->m_simulating; + return m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle; } AZ::Aabb EditorShapeColliderComponent::GetAabb() const { - if (m_editorBody) + if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { - return m_editorBody->GetAabb(); + if (auto* body = m_sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorBodyHandle)) + { + return body->GetAabb(); + } } return AZ::Aabb::CreateNull(); } AzPhysics::SimulatedBody* EditorShapeColliderComponent::GetSimulatedBody() { - return m_editorBody; + if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) + { + if (auto* body = m_sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorBodyHandle)) + { + return body; + } + } + return nullptr; } AzPhysics::SimulatedBodyHandle EditorShapeColliderComponent::GetSimulatedBodyHandle() const @@ -771,9 +786,12 @@ namespace PhysX AzPhysics::SceneQueryHit EditorShapeColliderComponent::RayCast(const AzPhysics::RayCastRequest& request) { - if (m_editorBody) + if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { - return m_editorBody->RayCast(request); + if (auto* body = m_sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorBodyHandle)) + { + return body->RayCast(request); + } } return AzPhysics::SceneQueryHit(); } diff --git a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.h b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.h index bcf5ac4eba..7b7fab789a 100644 --- a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.h +++ b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.h @@ -143,7 +143,6 @@ namespace PhysX DebugDraw::Collider m_colliderDebugDraw; //!< Handles drawing the collider based on global and local AzPhysics::SceneInterface* m_sceneInterface = nullptr; AzPhysics::SceneHandle m_editorSceneHandle = AzPhysics::InvalidSceneHandle; - StaticRigidBody* m_editorBody = nullptr; //!< Body in the editor physics scene if there is no rigid body component. AzPhysics::SimulatedBodyHandle m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; //!< Handle to the body in the editor physics scene if there is no rigid body component. bool m_shapeTypeWarningIssued = false; //!< Records whether a warning about unsupported shapes has been previously issued. PolygonPrismMeshUtils::Mesh2D m_mesh; //!< Used for storing decompositions of the polygon prism. From 704443ac89eeb0774c489ddacbbf6289caa63a7f Mon Sep 17 00:00:00 2001 From: mbalfour Date: Tue, 11 May 2021 10:25:03 -0500 Subject: [PATCH 104/225] Fix up incorrect autoDelete use and handling. Several UI property handlers were incorrectly using the autoDelete feature by calling UnregisterPropertyType and deleting the pointer themselves, which caused double-delete crashes on application shutdown. PropertyManagerComponent now gracefully handles that condition but also explicitly asserts explaining how the code should be changed, and the "known offenders" have been fixed up to use autoDelete correctly. --- .../PropertyManagerComponent.cpp | 33 +++++++++++++++++-- .../Source/UI/GradientPreviewDataWidget.cpp | 23 +++++-------- .../Source/UI/GradientPreviewDataWidget.h | 3 -- .../Code/Editor/SystemComponent.cpp | 8 +---- .../Code/Editor/SystemComponent.h | 1 - .../ScriptEventsSystemEditorComponent.cpp | 8 +---- .../ScriptEventsSystemEditorComponent.h | 2 -- .../EditorVegetationSystemComponent.cpp | 5 +-- .../Editor/EditorVegetationSystemComponent.h | 3 -- 9 files changed, 41 insertions(+), 45 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyManagerComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyManagerComponent.cpp index 21f3b7d1c6..bd61e6ceed 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyManagerComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyManagerComponent.cpp @@ -63,23 +63,40 @@ namespace AzToolsFramework void PropertyManagerComponent::Deactivate() { + // Delete all remaining auto-delete or built-in handlers. for (auto it = m_builtInHandlers.begin(); it != m_builtInHandlers.end(); ++it) { - UnregisterPropertyType(*it); +#ifdef AZ_DEBUG_BUILD + // For debug builds, we'll take the extra time to delete each handler that we're deleting from m_Handlers. + // We loop through m_Handlers below to ensure that we don't have any other handlers still registered after + // we've deleted these. + AZStd::erase_if(m_Handlers, [it](const auto& item) { + auto const& [key, value] = item; + return (key == (*it)->GetHandlerName()) && (value == (*it)); + }); +#endif + delete *it; } m_builtInHandlers.clear(); - #ifdef _DEBUG +#ifdef AZ_DEBUG_BUILD + // Loop through all the remaining registered handlers (if any) and print out an error, as these all are probably memory + // leaks. UnregisterPropertyType should have been called on these already, and their pointers should have been deleted + // by the caller. auto it = m_Handlers.begin(); while (it != m_Handlers.end()) { AZ_Error("PropertyManager", false, "Property Handler 0x%08x is still registered during shutdown", it->first); ++it; } - #endif +#endif + + m_Handlers.clear(); + m_DefaultHandlers.clear(); + PropertyTypeRegistrationMessages::Bus::Handler::BusDisconnect(); } @@ -142,6 +159,16 @@ namespace AzToolsFramework } ++defaultIt; } + + if (pHandler->AutoDelete()) + { + m_builtInHandlers.erase(AZStd::remove(m_builtInHandlers.begin(), m_builtInHandlers.end(), pHandler), + m_builtInHandlers.end()); + AZ_Assert(false, + "Handlers with AutoDelete set should not call UnregisterPropertyType. To fix, do one of the following:\n" + " 1. Set AutoDelete to false in the handler, call UnregisterPropertyType, and the caller should delete the handler.\n" + " 2. Set AutoDelete to true in the handler and do NOT call UnregisterPropertyType or delete the handler."); + } } diff --git a/Gems/GradientSignal/Code/Source/UI/GradientPreviewDataWidget.cpp b/Gems/GradientSignal/Code/Source/UI/GradientPreviewDataWidget.cpp index 14f21c105d..d0f45be56d 100644 --- a/Gems/GradientSignal/Code/Source/UI/GradientPreviewDataWidget.cpp +++ b/Gems/GradientSignal/Code/Source/UI/GradientPreviewDataWidget.cpp @@ -25,8 +25,6 @@ namespace GradientSignal // GradientPreviewDataWidgetHandler // - GradientPreviewDataWidgetHandler* GradientPreviewDataWidgetHandler::s_instance = nullptr; - AZ::u32 GradientPreviewDataWidgetHandler::GetHandlerName() const { return AZ_CRC("GradientPreviewer", 0x1dbbba45); @@ -92,23 +90,18 @@ namespace GradientSignal { using namespace AzToolsFramework; - if (!s_instance) - { - s_instance = aznew GradientPreviewDataWidgetHandler(); - PropertyTypeRegistrationMessages::Bus::Broadcast(&PropertyTypeRegistrationMessages::Bus::Events::RegisterPropertyType, s_instance); - } + // Property handlers are set to auto-delete by default, which means that we're handing off ownership of the pointer to the + // PropertyManagerComponent, where it will get cleaned up on system shutdown. + auto propertyHandler = aznew GradientPreviewDataWidgetHandler(); + AZ_Assert(propertyHandler->AutoDelete(), + "GradientPreviewDataWidgetHandler is no longer set to auto-delete, it will leak memory."); + PropertyTypeRegistrationMessages::Bus::Broadcast( + &PropertyTypeRegistrationMessages::Bus::Events::RegisterPropertyType, propertyHandler); } void GradientPreviewDataWidgetHandler::Unregister() { - using namespace AzToolsFramework; - - if (s_instance) - { - PropertyTypeRegistrationMessages::Bus::Broadcast(&PropertyTypeRegistrationMessages::Bus::Events::UnregisterPropertyType, s_instance); - delete s_instance; - s_instance = nullptr; - } + // We don't need to call UnregisterPropertyType here because it's an autoDelete handler. } // diff --git a/Gems/GradientSignal/Code/Source/UI/GradientPreviewDataWidget.h b/Gems/GradientSignal/Code/Source/UI/GradientPreviewDataWidget.h index b5ee732ed7..cb5c0f8f20 100644 --- a/Gems/GradientSignal/Code/Source/UI/GradientPreviewDataWidget.h +++ b/Gems/GradientSignal/Code/Source/UI/GradientPreviewDataWidget.h @@ -76,8 +76,5 @@ namespace GradientSignal static void Register(); static void Unregister(); - - private: - static GradientPreviewDataWidgetHandler* s_instance; }; } diff --git a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp index 7d9cb176a3..60e8e5f23a 100644 --- a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp @@ -134,7 +134,7 @@ namespace ScriptCanvasEditor PopulateEditorCreatableTypes(); - m_propertyHandlers.emplace_back(AzToolsFramework::RegisterGenericComboBoxHandler()); + AzToolsFramework::RegisterGenericComboBoxHandler(); SystemRequestBus::Handler::BusConnect(); ScriptCanvasExecutionBus::Handler::BusConnect(); @@ -177,12 +177,6 @@ namespace ScriptCanvasEditor SystemRequestBus::Handler::BusDisconnect(); AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); - for (auto&& propertyHandler : m_propertyHandlers) - { - AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::UnregisterPropertyType, propertyHandler.get()); - } - m_propertyHandlers.clear(); - m_jobContext.reset(); m_jobManager.reset(); m_assetTracker.Deactivate(); diff --git a/Gems/ScriptCanvas/Code/Editor/SystemComponent.h b/Gems/ScriptCanvas/Code/Editor/SystemComponent.h index 07ea44e482..f2ebad38cd 100644 --- a/Gems/ScriptCanvas/Code/Editor/SystemComponent.h +++ b/Gems/ScriptCanvas/Code/Editor/SystemComponent.h @@ -147,7 +147,6 @@ namespace ScriptCanvasEditor AZStd::unique_ptr m_jobManager; AZStd::unique_ptr m_jobContext; - AZStd::vector> m_propertyHandlers; AZStd::unordered_set m_creatableTypes; AssetTracker m_assetTracker; diff --git a/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.cpp b/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.cpp index 5a4bc33550..f895517f8d 100644 --- a/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.cpp +++ b/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.cpp @@ -236,17 +236,11 @@ namespace ScriptEventsEditor moduleConfiguration->RegisterAssetHandler(); } - m_propertyHandlers.emplace_back(AzToolsFramework::RegisterGenericComboBoxHandler()); + AzToolsFramework::RegisterGenericComboBoxHandler(); } void ScriptEventEditorSystemComponent::Deactivate() { - for (auto&& propertyHandler : m_propertyHandlers) - { - AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::UnregisterPropertyType, propertyHandler.get()); - } - m_propertyHandlers.clear(); - using namespace ScriptEvents; ScriptEventsSystemComponentImpl* moduleConfiguration = nullptr; ScriptEventModuleConfigurationRequestBus::BroadcastResult(moduleConfiguration, &ScriptEventModuleConfigurationRequests::GetSystemComponentImpl); diff --git a/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.h b/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.h index d80dcffcf9..a5d34a9a9e 100644 --- a/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.h +++ b/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.h @@ -90,8 +90,6 @@ namespace ScriptEventsEditor void Deactivate() override; //////////////////////////////////////////////////////////////////////// - AZStd::vector> m_propertyHandlers; - // Script Event Assets AZStd::unordered_map> m_scriptEvents; diff --git a/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.cpp index 00849ed94b..17174fa132 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.cpp @@ -58,14 +58,11 @@ namespace Vegetation void EditorVegetationSystemComponent::Activate() { // This is necessary for the m_spawnerType in Descriptor.cpp to display properly as a ComboBox - m_propertyHandler = aznew AzToolsFramework::GenericComboBoxHandler(); - AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::RegisterPropertyType, m_propertyHandler); + AzToolsFramework::RegisterGenericComboBoxHandler(); } void EditorVegetationSystemComponent::Deactivate() { - AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::UnregisterPropertyType, m_propertyHandler); - delete m_propertyHandler; } } diff --git a/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.h b/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.h index 76ac881f7c..2b45303672 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.h +++ b/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.h @@ -35,9 +35,6 @@ namespace Vegetation void Activate() override; void Deactivate() override; - - private: - AzToolsFramework::PropertyHandlerBase* m_propertyHandler{ nullptr }; }; } // namespace Vegetation From 3defbce31b42452f8cd598acdce37f95472fb0ed Mon Sep 17 00:00:00 2001 From: bosnichd Date: Tue, 11 May 2021 09:31:02 -0600 Subject: [PATCH 105/225] Remove legacy serialization and QPropertyTree (#684) Remove: - CryCommon/CryExtension/* - CryCommon/Serialization/* - Sandbox/Plugins/EditorCommon/QPropertyTree/* - All related CryCommon interfaces - All CrySystem implementations - Various related Editor classes --- Code/CryEngine/CryCommon/AnimTime.h | 173 - Code/CryEngine/CryCommon/Bezier.h | 321 -- .../CryExtension/CryCreateClassInstance.h | 96 - .../CryCommon/CryExtension/CryGUID.h | 123 - .../CryCommon/CryExtension/CryTypeID.h | 29 - .../CryCommon/CryExtension/ICryFactory.h | 41 - .../CryExtension/ICryFactoryRegistry.h | 56 - .../CryCommon/CryExtension/ICryUnknown.h | 224 -- .../CryCommon/CryExtension/Impl/ClassWeaver.h | 461 --- .../CryCommon/CryExtension/Impl/Conversion.h | 109 - .../CryExtension/Impl/CryGUIDHelper.h | 67 - .../Impl/ICryFactoryRegistryImpl.h | 58 - .../CryExtension/Impl/RegFactoryNode.h | 52 - .../CryCommon/CryExtension/Impl/TypeList.h | 236 -- Code/CryEngine/CryCommon/CryPool/Allocator.h | 207 -- Code/CryEngine/CryCommon/CryPool/Container.h | 655 ---- Code/CryEngine/CryCommon/CryPool/Defrag.h | 65 - Code/CryEngine/CryCommon/CryPool/Fallback.h | 81 - Code/CryEngine/CryCommon/CryPool/Inspector.h | 203 -- Code/CryEngine/CryCommon/CryPool/List.h | 366 -- Code/CryEngine/CryCommon/CryPool/Memory.h | 70 - Code/CryEngine/CryCommon/CryPool/PoolAlloc.h | 55 - Code/CryEngine/CryCommon/CryPool/STLWrapper.h | 148 - Code/CryEngine/CryCommon/CryPool/ThreadSafe.h | 58 - Code/CryEngine/CryCommon/CryPool/example.h | 287 -- .../CryEngine/CryCommon/GeomCacheFileFormat.h | 202 -- Code/CryEngine/CryCommon/IEngineModule.h | 53 - Code/CryEngine/CryCommon/IRemoteCommand.h | 763 ---- Code/CryEngine/CryCommon/IServiceNetwork.h | 344 -- Code/CryEngine/CryCommon/ISystem.h | 22 - Code/CryEngine/CryCommon/Mocks/IConsoleMock.h | 1 - Code/CryEngine/CryCommon/Mocks/ISystemMock.h | 8 - .../CryCommon/Serialization/Assert.h | 46 - .../CryCommon/Serialization/BitVector.h | 39 - .../CryCommon/Serialization/BitVectorImpl.h | 88 - .../CryCommon/Serialization/BlackBox.h | 93 - .../CryCommon/Serialization/BoostSharedPtr.h | 102 - .../CryCommon/Serialization/CRCRef.h | 30 - .../CryCommon/Serialization/CRCRefImpl.h | 100 - .../CryCommon/Serialization/Callback.h | 184 - .../CryCommon/Serialization/ClassFactory.h | 376 -- .../Serialization/ClassFactoryImpl.h | 47 - .../CryEngine/CryCommon/Serialization/Color.h | 55 - .../CryCommon/Serialization/ColorImpl.h | 53 - .../CryCommon/Serialization/CryExtension.h | 44 - .../Serialization/CryExtensionImpl.h | 281 -- .../CryCommon/Serialization/CryName.h | 26 - .../CryCommon/Serialization/CryNameImpl.h | 61 - .../CryCommon/Serialization/CryStrings.h | 36 - .../CryCommon/Serialization/CryStringsImpl.h | 74 - .../Serialization/Decorators/ActionButton.h | 89 - .../Serialization/Decorators/BitFlags.h | 64 - .../Serialization/Decorators/BitFlagsImpl.h | 67 - .../Serialization/Decorators/ColorPicker.h | 43 - .../Decorators/ColorPickerImpl.h | 33 - .../Serialization/Decorators/JointName.h | 19 - .../Serialization/Decorators/JointNameImpl.h | 19 - .../Serialization/Decorators/LocalFrame.h | 117 - .../Serialization/Decorators/LocalFrameImpl.h | 89 - .../Serialization/Decorators/OutputFilePath.h | 49 - .../Decorators/OutputFilePathImpl.h | 32 - .../Serialization/Decorators/Range.h | 63 - .../Serialization/Decorators/RangeImpl.h | 50 - .../Decorators/ResourceFilePath.h | 59 - .../Decorators/ResourceFilePathImpl.h | 32 - .../Decorators/ResourceFolderPath.h | 43 - .../Decorators/ResourceFolderPathImpl.h | 34 - .../Decorators/ResourceSelector.h | 100 - .../Serialization/Decorators/Resources.h | 67 - .../Serialization/Decorators/ResourcesAudio.h | 31 - .../Serialization/Decorators/ResourcesImpl.h | 44 - .../Serialization/Decorators/Slider.h | 88 - .../Serialization/Decorators/SliderImpl.h | 47 - .../Serialization/Decorators/Sprite.h | 44 - .../Serialization/Decorators/SpriteImpl.h | 35 - .../Serialization/Decorators/TagList.h | 49 - .../Serialization/Decorators/TagListImpl.h | 40 - .../CryCommon/Serialization/DynArray.h | 27 - .../CryCommon/Serialization/DynArrayImpl.h | 28 - Code/CryEngine/CryCommon/Serialization/Enum.h | 170 - .../CryCommon/Serialization/EnumImpl.h | 248 -- .../CryCommon/Serialization/IArchive.h | 446 --- .../CryCommon/Serialization/IArchiveHost.h | 153 - .../CryCommon/Serialization/IClassFactory.h | 85 - .../Serialization/ITextInputArchive.h | 46 - .../Serialization/ITextOutputArchive.h | 55 - .../CryCommon/Serialization/IXmlArchive.h | 175 - .../Serialization/IntrusiveFactory.h | 99 - .../CryCommon/Serialization/KeyValue.h | 37 - Code/CryEngine/CryCommon/Serialization/Math.h | 166 - .../CryCommon/Serialization/MathImpl.h | 207 -- .../Serialization/NetScriptSerialize.h | 27 - .../CryCommon/Serialization/Object.h | 153 - Code/CryEngine/CryCommon/Serialization/STL.h | 52 - .../CryCommon/Serialization/STLImpl.h | 251 -- .../CryCommon/Serialization/Serializer.h | 268 -- .../CryCommon/Serialization/SerializerImpl.h | 95 - .../CryCommon/Serialization/SmartPtr.h | 31 - .../CryCommon/Serialization/SmartPtrImpl.h | 73 - .../CryCommon/Serialization/StringList.h | 301 -- .../CryCommon/Serialization/StringListImpl.h | 126 - .../CryCommon/Serialization/Strings.h | 32 - .../CryCommon/Serialization/TypeID.h | 290 -- .../CryCommon/Serialization/TypeInfo.h | 46 - .../CryCommon/Serialization/TypeInfoImpl.h | 245 -- .../CryEngine/CryCommon/crycommon_files.cmake | 100 - Code/CryEngine/CryCommon/platform_impl.cpp | 16 +- Code/CryEngine/CrySystem/DllMain.cpp | 9 +- .../CryFactoryRegistryImpl.cpp | 359 -- .../ExtensionSystem/CryFactoryRegistryImpl.h | 128 - .../TestCases/TestExtensions.cpp | 955 ----- .../TestCases/TestExtensions.h | 126 - Code/CryEngine/CrySystem/RemoteCommand.cpp | 191 - Code/CryEngine/CrySystem/RemoteCommand.h | 459 --- .../CrySystem/RemoteCommandClient.cpp | 756 ---- .../CrySystem/RemoteCommandHelpers.cpp | 361 -- .../CrySystem/RemoteCommandHelpers.h | 307 -- .../CrySystem/RemoteCommandServer.cpp | 832 ----- .../CrySystem/Serialization/ArchiveHost.cpp | 239 -- .../CrySystem/Serialization/ArchiveHost.h | 21 - .../CrySystem/Serialization/BinArchive.cpp | 839 ----- .../CrySystem/Serialization/BinArchive.h | 180 - .../CrySystem/Serialization/JSONIArchive.cpp | 1525 -------- .../CrySystem/Serialization/JSONIArchive.h | 95 - .../CrySystem/Serialization/JSONOArchive.cpp | 828 ----- .../CrySystem/Serialization/JSONOArchive.h | 102 - .../CrySystem/Serialization/MemoryReader.cpp | 92 - .../CrySystem/Serialization/MemoryReader.h | 56 - .../CrySystem/Serialization/MemoryWriter.cpp | 236 -- .../CrySystem/Serialization/MemoryWriter.h | 72 - .../Serialization/Test_ArchiveHost.cpp | 492 --- .../CryEngine/CrySystem/Serialization/Token.h | 89 - .../CrySystem/Serialization/XmlIArchive.cpp | 297 -- .../CrySystem/Serialization/XmlIArchive.h | 62 - .../CrySystem/Serialization/XmlOArchive.cpp | 213 -- .../CrySystem/Serialization/XmlOArchive.h | 60 - Code/CryEngine/CrySystem/ServiceNetwork.cpp | 2035 ----------- Code/CryEngine/CrySystem/ServiceNetwork.h | 475 --- Code/CryEngine/CrySystem/System.cpp | 5 - Code/CryEngine/CrySystem/System.h | 9 - Code/CryEngine/CrySystem/SystemInit.cpp | 172 - Code/CryEngine/CrySystem/XConsole.cpp | 1 - .../CryEngine/CrySystem/crysystem_files.cmake | 29 - .../CrySystem/crysystem_test_files.cmake | 1 - .../Editor/Controls/CurveEditorCtrl.cpp | 821 ----- .../Sandbox/Editor/Controls/CurveEditorCtrl.h | 112 - Code/Sandbox/Editor/EditorViewportWidget.cpp | 8 - Code/Sandbox/Editor/IEditorImpl.cpp | 3 - .../Editor/Include/IResourceSelectorHost.h | 26 - Code/Sandbox/Editor/ResourceSelectorHost.cpp | 10 - Code/Sandbox/Editor/Serialization.h | 26 - .../Editor/Serialization/VariableIArchive.cpp | 283 -- .../Editor/Serialization/VariableIArchive.h | 71 - .../Editor/Serialization/VariableOArchive.cpp | 416 --- .../Editor/Serialization/VariableOArchive.h | 83 - Code/Sandbox/Editor/SettingsBlock.cpp | 177 - Code/Sandbox/Editor/SettingsBlock.h | 76 - Code/Sandbox/Editor/editor_lib_files.cmake | 9 - .../ComponentEntityEditorPlugin.cpp | 1 - .../Plugins/EditorCommon/BatchFileDialog.cpp | 357 -- .../Plugins/EditorCommon/BatchFileDialog.h | 77 - .../Plugins/EditorCommon/CMakeLists.txt | 3 - .../Plugins/EditorCommon/CurveEditor.cpp | 2459 ------------- .../Plugins/EditorCommon/CurveEditor.h | 233 -- .../Plugins/EditorCommon/CurveEditorContent.h | 155 - .../EditorCommon/CurveEditorContent_38.h | 84 - .../EditorCommon/CurveEditorContent_impl.h | 20 - .../EditorCommon/CurveEditorControl.cpp | 352 -- .../Plugins/EditorCommon/CurveEditorControl.h | 150 - .../Plugins/EditorCommon/CurveEditor_38.cpp | 1825 ---------- .../Plugins/EditorCommon/CurveEditor_38.h | 154 - .../EditorCommon/DisplayViewportAdapter.cpp | 194 -- .../EditorCommon/DisplayViewportAdapter.h | 64 - .../EditorCommon/DockTitleBarWidget.cpp | 17 +- .../EditorCommon/DrawingPrimitives/Ruler.cpp | 6 +- .../Plugins/EditorCommon/EditorCommon.qrc | 15 - .../EditorCommon/Events/EventManager.cpp | 144 - .../EditorCommon/Events/EventManager.h | 204 -- .../EditorCommon/ListSelectionDialog.cpp | 224 -- .../EditorCommon/ListSelectionDialog.h | 73 - .../QPropertyTree/Unicode_UnixLike.cpp | 29 - .../Platform/Linux/platform_linux_files.cmake | 14 - .../Platform/Mac/platform_mac_files.cmake | 14 - .../Windows/QPropertyTree/Unicode_Windows.cpp | 41 - .../Windows/platform_windows_files.cmake | 14 - .../QAbstractQVariantTreeDataModel.cpp | 75 - .../QAbstractQVariantTreeDataModel.h | 87 - .../Plugins/EditorCommon/QParentWndWidget.cpp | 309 -- .../Plugins/EditorCommon/QParentWndWidget.h | 67 - .../Plugins/EditorCommon/QPropertyCtrl.h | 49 - .../EditorCommon/QPropertyTree/Color.cpp | 123 - .../EditorCommon/QPropertyTree/Color.h | 66 - .../QPropertyTree/ConstStringList.cpp | 58 - .../QPropertyTree/ConstStringList.h | 46 - .../EditorCommon/QPropertyTree/ContextList.h | 76 - .../EditorCommon/QPropertyTree/Factory.h | 156 - .../EditorCommon/QPropertyTree/MathUtils.h | 54 - .../QPropertyTree/PropertyDrawContext.cpp | 466 --- .../QPropertyTree/PropertyDrawContext.h | 98 - .../QPropertyTree/PropertyIArchive.cpp | 377 -- .../QPropertyTree/PropertyIArchive.h | 80 - .../QPropertyTree/PropertyOArchive.cpp | 487 --- .../QPropertyTree/PropertyOArchive.h | 112 - .../QPropertyTree/PropertyRow.cpp | 1906 ---------- .../EditorCommon/QPropertyTree/PropertyRow.h | 575 --- .../QPropertyTree/PropertyRowActionButton.cpp | 168 - .../QPropertyTree/PropertyRowBool.cpp | 116 - .../QPropertyTree/PropertyRowBool.h | 50 - .../QPropertyTree/PropertyRowColor.cpp | 241 -- .../QPropertyTree/PropertyRowColor.h | 75 - .../QPropertyTree/PropertyRowColorPicker.cpp | 158 - .../QPropertyTree/PropertyRowColorPicker.h | 56 - .../QPropertyTree/PropertyRowContainer.cpp | 439 --- .../QPropertyTree/PropertyRowContainer.h | 96 - .../QPropertyTree/PropertyRowField.cpp | 84 - .../QPropertyTree/PropertyRowField.h | 39 - .../QPropertyTree/PropertyRowIconXPM.cpp | 119 - .../QPropertyTree/PropertyRowImpl.h | 48 - .../QPropertyTree/PropertyRowLocalFrame.cpp | 152 - .../QPropertyTree/PropertyRowLocalFrame.h | 70 - .../QPropertyTree/PropertyRowNumber.cpp | 43 - .../QPropertyTree/PropertyRowNumber.h | 237 -- .../QPropertyTree/PropertyRowNumberField.cpp | 287 -- .../QPropertyTree/PropertyRowNumberField.h | 75 - .../QPropertyTree/PropertyRowObject.cpp | 42 - .../QPropertyTree/PropertyRowObject.h | 51 - .../PropertyRowOutputFilePath.cpp | 205 -- .../QPropertyTree/PropertyRowOutputFilePath.h | 74 - .../QPropertyTree/PropertyRowPointer.cpp | 346 -- .../QPropertyTree/PropertyRowPointer.h | 95 - .../PropertyRowResourceFilePath.cpp | 177 - .../PropertyRowResourceFilePath.h | 79 - .../PropertyRowResourceFolderPath.cpp | 159 - .../PropertyRowResourceFolderPath.h | 76 - .../PropertyRowResourceSelector.cpp | 425 --- .../PropertyRowResourceSelector.h | 100 - .../QPropertyTree/PropertyRowSlider.cpp | 521 --- .../QPropertyTree/PropertyRowSprite.cpp | 299 -- .../QPropertyTree/PropertyRowSprite.h | 70 - .../QPropertyTree/PropertyRowString.cpp | 87 - .../QPropertyTree/PropertyRowString.h | 114 - .../PropertyRowStringListValue.cpp | 42 - .../PropertyRowStringListValue.h | 303 -- .../QPropertyTree/PropertyRowTagList.cpp | 132 - .../QPropertyTree/PropertyRowTagList.h | 51 - .../QPropertyTree/PropertyRowToggleButton.cpp | 205 -- .../QPropertyTree/PropertyTreeMenuHandler.h | 45 - .../QPropertyTree/PropertyTreeModel.cpp | 445 --- .../QPropertyTree/PropertyTreeModel.h | 208 -- .../QPropertyTree/PropertyTreeOperator.cpp | 53 - .../QPropertyTree/PropertyTreeOperator.h | 65 - .../QPropertyTree/QPropertyDialog.cpp | 227 -- .../QPropertyTree/QPropertyDialog.h | 76 - .../QPropertyTree/QPropertyTree.cpp | 3083 ----------------- .../QPropertyTree/QPropertyTree.h | 528 --- .../QPropertyTree/QPropertyTreeStyle.h | 90 - .../QPropertyTree/Serialization.h | 29 - .../EditorCommon/QPropertyTree/SlicerEdit.cpp | 56 - .../EditorCommon/QPropertyTree/SlicerEdit.h | 46 - .../QPropertyTree/SlicerManipulator.cpp | 143 - .../QPropertyTree/SlicerManipulator.h | 58 - .../EditorCommon/QPropertyTree/SlicerView.cpp | 25 - .../EditorCommon/QPropertyTree/SlicerView.h | 34 - .../QPropertyTree/SpriteBorderEditor.cpp | 175 - .../QPropertyTree/SpriteBorderEditor.h | 41 - .../SpriteBorderEditorCommon.cpp | 120 - .../QPropertyTree/SpriteBorderEditorCommon.h | 78 - .../EditorCommon/QPropertyTree/Strings.h | 29 - .../EditorCommon/QPropertyTree/Unicode.h | 24 - .../QPropertyTree/ValidatorBlock.h | 172 - .../EditorCommon/QPropertyTree/error.xpm | 126 - .../EditorCommon/QPropertyTree/file_open.xpm | 142 - .../EditorCommon/QPropertyTree/file_save.xpm | 168 - .../EditorCommon/QPropertyTree/gear.xpm | 24 - .../QPropertyTree/wWidgets_NOTICES.txt | 49 - .../EditorCommon/QPropertyTree/warning.xpm | 134 - .../Plugins/EditorCommon/QViewport.cpp | 913 ----- Code/Sandbox/Plugins/EditorCommon/QViewport.h | 193 -- .../Plugins/EditorCommon/QViewportConsumer.h | 37 - .../Plugins/EditorCommon/QViewportEvents.h | 96 - .../Plugins/EditorCommon/QViewportSettings.h | 269 -- .../Plugins/EditorCommon/Serialization.cpp | 15 - .../Plugins/EditorCommon/Serialization.h | 44 - .../EditorCommon/Serialization/BinArchive.cpp | 839 ----- .../EditorCommon/Serialization/BinArchive.h | 183 - .../Decorators/EditorActionButton.h | 76 - .../Serialization/Decorators/IGizmoSink.h | 49 - .../Decorators/INavigationProvider.h | 43 - .../Serialization/Decorators/IconXPM.h | 100 - .../Serialization/Decorators/ToggleButton.h | 50 - .../Decorators/ToggleButtonImpl.h | 44 - .../Serialization/JSONIArchive.cpp | 1522 -------- .../EditorCommon/Serialization/JSONIArchive.h | 103 - .../Serialization/JSONOArchive.cpp | 828 ----- .../EditorCommon/Serialization/JSONOArchive.h | 108 - .../Serialization/MemoryReader.cpp | 92 - .../EditorCommon/Serialization/MemoryReader.h | 62 - .../Serialization/MemoryWriter.cpp | 275 -- .../EditorCommon/Serialization/MemoryWriter.h | 80 - .../EditorCommon/Serialization/Pointers.h | 265 -- .../EditorCommon/Serialization/PointersImpl.h | 140 - .../Plugins/EditorCommon/Serialization/Qt.cpp | 393 --- .../Plugins/EditorCommon/Serialization/Qt.h | 33 - .../EditorCommon/Serialization/QtImpl.h | 24 - .../EditorCommon/Serialization/Token.h | 93 - .../Serialization/yasli_NOTICES.txt | 49 - .../Sandbox/Plugins/EditorCommon/Timeline.cpp | 2728 --------------- Code/Sandbox/Plugins/EditorCommon/Timeline.h | 216 -- .../Plugins/EditorCommon/TimelineContent.cpp | 20 - .../Plugins/EditorCommon/TimelineContent.h | 154 - .../EditorCommon/UnsavedChangesDialog.cpp | 117 - .../EditorCommon/UnsavedChangesDialog.h | 42 - .../EditorCommon/editorcommon_files.cmake | 132 - Code/Sandbox/Plugins/EditorCommon/moc.cpp | 21 - .../Android/AudioEngineWwise_Traits_Android.h | 1 - .../Linux/AudioEngineWwise_Traits_Linux.h | 1 - .../Mac/AudioEngineWwise_Traits_Mac.h | 1 - .../Windows/AudioEngineWwise_Traits_Windows.h | 1 - .../iOS/AudioEngineWwise_Traits_iOS.h | 1 - .../AudioEngineWwiseGemSystemComponent.cpp | 11 - .../Source/Editor/AudioSystemEditor_wwise.h | 11 - .../Source/Engine/AudioSystemImpl_wwise.cpp | 7 - .../Code/Source/Engine/Common_wwise.h | 14 - .../Code/Include/Editor/IAudioConnection.h | 6 - .../Code/Source/Editor/AudioControl.h | 1 + .../Source/Editor/AudioResourceSelectors.cpp | 1 - .../Code/Source/Editor/ConnectionsWidget.ui | 28 - .../Code/Source/Editor/QConnectionsWidget.cpp | 17 - Gems/GameEffectSystem/preview.png | 3 - Gems/LyShine/Code/Editor/ViewportWidget.cpp | 1 - .../Code/Source/Cinematics/CryMovie.cpp | 79 - .../Code/Source/Cinematics/CryMovie.def | 3 - .../Maestro/Code/Source/Cinematics/CryMovie.h | 40 - .../Code/Source/Cinematics/CryMovie.rc | 111 - Gems/SVOGI/preview.png | 3 - .../ConsoleFrontendConfig.in | 1 - .../Windows/package_filelists/atom.json | 1 - .../commit_validation/pal_allowedlist.txt | 1 - 338 files changed, 16 insertions(+), 63358 deletions(-) delete mode 100644 Code/CryEngine/CryCommon/AnimTime.h delete mode 100644 Code/CryEngine/CryCommon/Bezier.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/CryCreateClassInstance.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/CryGUID.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/CryTypeID.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/ICryFactory.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/ICryFactoryRegistry.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/ICryUnknown.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/Impl/ClassWeaver.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/Impl/Conversion.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/Impl/CryGUIDHelper.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/Impl/ICryFactoryRegistryImpl.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/Impl/RegFactoryNode.h delete mode 100644 Code/CryEngine/CryCommon/CryExtension/Impl/TypeList.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/Allocator.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/Container.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/Defrag.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/Fallback.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/Inspector.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/List.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/Memory.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/PoolAlloc.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/STLWrapper.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/ThreadSafe.h delete mode 100644 Code/CryEngine/CryCommon/CryPool/example.h delete mode 100644 Code/CryEngine/CryCommon/GeomCacheFileFormat.h delete mode 100644 Code/CryEngine/CryCommon/IEngineModule.h delete mode 100644 Code/CryEngine/CryCommon/IRemoteCommand.h delete mode 100644 Code/CryEngine/CryCommon/IServiceNetwork.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Assert.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/BitVector.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/BitVectorImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/BlackBox.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/BoostSharedPtr.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/CRCRef.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/CRCRefImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Callback.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/ClassFactory.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/ClassFactoryImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Color.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/ColorImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/CryExtension.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/CryExtensionImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/CryName.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/CryNameImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/CryStrings.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/CryStringsImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ActionButton.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/BitFlags.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/BitFlagsImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ColorPicker.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ColorPickerImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/JointName.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/JointNameImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrame.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrameImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/OutputFilePath.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/OutputFilePathImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/Range.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/RangeImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePath.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePathImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPath.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPathImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ResourceSelector.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/Resources.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesAudio.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/Slider.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/SliderImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/Sprite.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/SpriteImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/TagList.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Decorators/TagListImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/DynArray.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/DynArrayImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Enum.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/EnumImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/IArchive.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/IArchiveHost.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/IClassFactory.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/ITextInputArchive.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/ITextOutputArchive.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/IXmlArchive.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/IntrusiveFactory.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/KeyValue.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Math.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/MathImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/NetScriptSerialize.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Object.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/STL.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/STLImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Serializer.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/SerializerImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/SmartPtr.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/SmartPtrImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/StringList.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/StringListImpl.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/Strings.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/TypeID.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/TypeInfo.h delete mode 100644 Code/CryEngine/CryCommon/Serialization/TypeInfoImpl.h delete mode 100644 Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.cpp delete mode 100644 Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.h delete mode 100644 Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.cpp delete mode 100644 Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.h delete mode 100644 Code/CryEngine/CrySystem/RemoteCommand.cpp delete mode 100644 Code/CryEngine/CrySystem/RemoteCommand.h delete mode 100644 Code/CryEngine/CrySystem/RemoteCommandClient.cpp delete mode 100644 Code/CryEngine/CrySystem/RemoteCommandHelpers.cpp delete mode 100644 Code/CryEngine/CrySystem/RemoteCommandHelpers.h delete mode 100644 Code/CryEngine/CrySystem/RemoteCommandServer.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/ArchiveHost.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/ArchiveHost.h delete mode 100644 Code/CryEngine/CrySystem/Serialization/BinArchive.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/BinArchive.h delete mode 100644 Code/CryEngine/CrySystem/Serialization/JSONIArchive.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/JSONIArchive.h delete mode 100644 Code/CryEngine/CrySystem/Serialization/JSONOArchive.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/JSONOArchive.h delete mode 100644 Code/CryEngine/CrySystem/Serialization/MemoryReader.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/MemoryReader.h delete mode 100644 Code/CryEngine/CrySystem/Serialization/MemoryWriter.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/MemoryWriter.h delete mode 100644 Code/CryEngine/CrySystem/Serialization/Test_ArchiveHost.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/Token.h delete mode 100644 Code/CryEngine/CrySystem/Serialization/XmlIArchive.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/XmlIArchive.h delete mode 100644 Code/CryEngine/CrySystem/Serialization/XmlOArchive.cpp delete mode 100644 Code/CryEngine/CrySystem/Serialization/XmlOArchive.h delete mode 100644 Code/CryEngine/CrySystem/ServiceNetwork.cpp delete mode 100644 Code/CryEngine/CrySystem/ServiceNetwork.h delete mode 100644 Code/Sandbox/Editor/Controls/CurveEditorCtrl.cpp delete mode 100644 Code/Sandbox/Editor/Controls/CurveEditorCtrl.h delete mode 100644 Code/Sandbox/Editor/Serialization.h delete mode 100644 Code/Sandbox/Editor/Serialization/VariableIArchive.cpp delete mode 100644 Code/Sandbox/Editor/Serialization/VariableIArchive.h delete mode 100644 Code/Sandbox/Editor/Serialization/VariableOArchive.cpp delete mode 100644 Code/Sandbox/Editor/Serialization/VariableOArchive.h delete mode 100644 Code/Sandbox/Editor/SettingsBlock.cpp delete mode 100644 Code/Sandbox/Editor/SettingsBlock.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/BatchFileDialog.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/BatchFileDialog.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditor.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditor.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditorContent.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditorContent_38.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditorContent_impl.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditorControl.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditorControl.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditor_38.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/CurveEditor_38.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/DisplayViewportAdapter.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/DisplayViewportAdapter.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/EditorCommon.qrc delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Events/EventManager.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Events/EventManager.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/ListSelectionDialog.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/ListSelectionDialog.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Platform/Common/UnixLike/QPropertyTree/Unicode_UnixLike.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Platform/Linux/platform_linux_files.cmake delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Platform/Mac/platform_mac_files.cmake delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Platform/Windows/QPropertyTree/Unicode_Windows.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Platform/Windows/platform_windows_files.cmake delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QAbstractQVariantTreeDataModel.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QAbstractQVariantTreeDataModel.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QParentWndWidget.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QParentWndWidget.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyCtrl.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Color.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Color.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ConstStringList.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ConstStringList.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ContextList.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Factory.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/MathUtils.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyDrawContext.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyDrawContext.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyIArchive.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyIArchive.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyOArchive.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyOArchive.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRow.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRow.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowActionButton.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowBool.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowBool.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColor.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColor.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColorPicker.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColorPicker.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowContainer.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowContainer.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowField.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowField.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowIconXPM.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowImpl.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowLocalFrame.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowLocalFrame.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumber.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumber.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumberField.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumberField.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowObject.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowObject.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowOutputFilePath.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowOutputFilePath.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowPointer.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowPointer.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFilePath.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFilePath.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFolderPath.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFolderPath.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceSelector.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceSelector.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSlider.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSprite.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSprite.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowString.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowString.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowStringListValue.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowStringListValue.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowTagList.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowTagList.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowToggleButton.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeMenuHandler.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeModel.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeModel.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeOperator.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeOperator.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyDialog.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyDialog.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTree.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTree.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTreeStyle.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Serialization.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerEdit.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerEdit.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerManipulator.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerManipulator.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerView.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerView.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditor.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditor.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditorCommon.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditorCommon.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Strings.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Unicode.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ValidatorBlock.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/error.xpm delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/file_open.xpm delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/file_save.xpm delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/gear.xpm delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/wWidgets_NOTICES.txt delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QPropertyTree/warning.xpm delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QViewport.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QViewport.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QViewportConsumer.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QViewportEvents.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/QViewportSettings.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/BinArchive.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/BinArchive.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/EditorActionButton.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/IGizmoSink.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/INavigationProvider.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/IconXPM.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/ToggleButton.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/ToggleButtonImpl.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/JSONIArchive.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/JSONIArchive.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/JSONOArchive.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/JSONOArchive.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryReader.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryReader.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryWriter.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryWriter.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Pointers.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/PointersImpl.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Qt.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Qt.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/QtImpl.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/Token.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Serialization/yasli_NOTICES.txt delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Timeline.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/Timeline.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/TimelineContent.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/TimelineContent.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/UnsavedChangesDialog.cpp delete mode 100644 Code/Sandbox/Plugins/EditorCommon/UnsavedChangesDialog.h delete mode 100644 Code/Sandbox/Plugins/EditorCommon/moc.cpp delete mode 100644 Gems/GameEffectSystem/preview.png delete mode 100644 Gems/Maestro/Code/Source/Cinematics/CryMovie.cpp delete mode 100644 Gems/Maestro/Code/Source/Cinematics/CryMovie.def delete mode 100644 Gems/Maestro/Code/Source/Cinematics/CryMovie.h delete mode 100644 Gems/Maestro/Code/Source/Cinematics/CryMovie.rc delete mode 100644 Gems/SVOGI/preview.png diff --git a/Code/CryEngine/CryCommon/AnimTime.h b/Code/CryEngine/CryCommon/AnimTime.h deleted file mode 100644 index 8bd0b9d442..0000000000 --- a/Code/CryEngine/CryCommon/AnimTime.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __animtime_h__ -#define __animtime_h__ - -#include -#include -#include - -struct SAnimTime -{ - static const uint numTicksPerSecond = 6000; - - // List of possible frame rates (dividers of 6000). Most commonly used ones first. - enum EFrameRate - { - // Common - eFrameRate_30fps, eFrameRate_60fps, eFrameRate_120fps, - - // Possible - eFrameRate_10fps, eFrameRate_12fps, eFrameRate_15fps, eFrameRate_24fps, - eFrameRate_25fps, eFrameRate_40fps, eFrameRate_48fps, eFrameRate_50fps, - eFrameRate_75fps, eFrameRate_80fps, eFrameRate_100fps, eFrameRate_125fps, - eFrameRate_150fps, eFrameRate_200fps, eFrameRate_240fps, eFrameRate_250fps, - eFrameRate_300fps, eFrameRate_375fps, eFrameRate_400fps, eFrameRate_500fps, - eFrameRate_600fps, eFrameRate_750fps, eFrameRate_1000fps, eFrameRate_1200fps, - eFrameRate_1500fps, eFrameRate_2000fps, eFrameRate_3000fps, eFrameRate_6000fps, - - eFrameRate_Num - }; - - SAnimTime() - : m_ticks(0) {} - explicit SAnimTime(int32 ticks) - : m_ticks(ticks) {} - explicit SAnimTime(float time) - : m_ticks(aznumeric_caster(std::lround(static_cast(time) * numTicksPerSecond))) {} - - static uint GetFrameRateValue(EFrameRate frameRate) - { - const uint frameRateValues[eFrameRate_Num] = - { - // Common - 30, 60, 120, - - // Possible - 10, 12, 15, 24, 25, 40, 48, 50, 75, 80, 100, 125, - 150, 200, 240, 250, 300, 375, 400, 500, 600, 750, - 1000, 1200, 1500, 2000, 3000, 6000 - }; - - return frameRateValues[frameRate]; - } - - static const char* GetFrameRateName(EFrameRate frameRate) - { - const char* frameRateNames[eFrameRate_Num] = - { - // Common - "30 fps", "60 fps", "120 fps", - - // Possible - "10 fps", "12 fps", "15 fps", "24 fps", - "25 fps", "40 fps", "48 fps", "50 fps", - "75 fps", "80 fps", "100 fps", "125 fps", - "150 fps", "200 fps", "240 fps", "250 fps", - "300 fps", "375 fps", "400 fps", "500 fps", - "600 fps", "750 fps", "1000 fps", "1200 fps", - "1500 fps", "2000 fps", "3000 fps", "6000 fps" - }; - - return frameRateNames[frameRate]; - } - - float ToFloat() const { return static_cast(m_ticks) / numTicksPerSecond; } - - void Serialize(Serialization::IArchive& ar) - { - ar(m_ticks, "ticks", "Ticks"); - } - - // Helper to serialize from ticks or old float time - void Serialize(XmlNodeRef keyNode, bool bLoading, const char* pName, const char* pLegacyName) - { - if (bLoading) - { - int32 ticks; - if (!keyNode->getAttr(pName, ticks)) - { - // Backwards compatibility - float time = 0.0f; - keyNode->getAttr(pLegacyName, time); - *this = SAnimTime(time); - } - else - { - m_ticks = ticks; - } - } - else if (m_ticks > 0) - { - keyNode->setAttr(pName, m_ticks); - } - } - - int32 GetTicks() const { return m_ticks; } - - static SAnimTime Min() { SAnimTime minTime; minTime.m_ticks = std::numeric_limits::lowest(); return minTime; } - static SAnimTime Max() { SAnimTime maxTime; maxTime.m_ticks = (std::numeric_limits::max)(); return maxTime; } - - SAnimTime operator-() const { return SAnimTime(-m_ticks); } - SAnimTime operator-(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks -= r.m_ticks; return temp; } - SAnimTime operator+(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks += r.m_ticks; return temp; } - SAnimTime operator*(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks *= r.m_ticks; return temp; } - SAnimTime operator/(SAnimTime r) const { SAnimTime temp; temp.m_ticks = static_cast((static_cast(m_ticks) * numTicksPerSecond) / r.m_ticks); return temp; } - SAnimTime operator%(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks %= r.m_ticks; return temp; } - SAnimTime operator*(float r) const { SAnimTime temp; temp.m_ticks = aznumeric_caster(std::lround(static_cast(m_ticks) * r)); return temp; } - SAnimTime operator/(float r) const { SAnimTime temp; temp.m_ticks = aznumeric_caster(std::lround(static_cast(m_ticks) / r)); return temp; } - SAnimTime& operator+=(SAnimTime r) { *this = *this + r; return *this; } - SAnimTime& operator-=(SAnimTime r) { *this = *this - r; return *this; } - SAnimTime& operator*=(SAnimTime r) { *this = *this * r; return *this; } - SAnimTime& operator/=(SAnimTime r) { *this = *this / r; return *this; } - SAnimTime& operator%=(SAnimTime r) { *this = *this % r; return *this; } - SAnimTime& operator*=(float r) { *this = *this * r; return *this; } - SAnimTime& operator/=(float r) { *this = *this / r; return *this; } - - bool operator<(SAnimTime r) const { return m_ticks < r.m_ticks; } - bool operator<=(SAnimTime r) const { return m_ticks <= r.m_ticks; } - bool operator>(SAnimTime r) const { return m_ticks > r.m_ticks; } - bool operator>=(SAnimTime r) const { return m_ticks >= r.m_ticks; } - bool operator==(SAnimTime r) const { return m_ticks == r.m_ticks; } - bool operator!=(SAnimTime r) const { return m_ticks != r.m_ticks; } - - // Snap to nearest multiple of given frame rate - SAnimTime SnapToNearest(const EFrameRate frameRate) - { - const int sign = sgn(m_ticks); - const int32 absTicks = abs(m_ticks); - - const int framesMod = numTicksPerSecond / GetFrameRateValue(frameRate); - const int32 remainder = absTicks % framesMod; - const bool bNextMultiple = remainder >= (framesMod / 2); - return SAnimTime(sign * ((absTicks - remainder) + (bNextMultiple ? framesMod : 0))); - } - -private: - int32 m_ticks; - - friend bool Serialize(Serialization::IArchive& ar, SAnimTime& animTime, const char* name, const char* label); -}; - -inline bool Serialize(Serialization::IArchive& ar, SAnimTime& animTime, const char* name, const char* label) -{ - return ar(animTime.m_ticks, name, label); -} - -inline SAnimTime abs(SAnimTime time) -{ - return (time >= SAnimTime(0)) ? time : -time; -} - -#endif diff --git a/Code/CryEngine/CryCommon/Bezier.h b/Code/CryEngine/CryCommon/Bezier.h deleted file mode 100644 index fa1cf60d49..0000000000 --- a/Code/CryEngine/CryCommon/Bezier.h +++ /dev/null @@ -1,321 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __BEZIER_H__ -#define __BEZIER_H__ - -#include -#include -#include - -struct SBezierControlPoint -{ - SBezierControlPoint() - : m_value(0.0f) - , m_inTangent(ZERO) - , m_outTangent(ZERO) - , m_inTangentType(eTangentType_Auto) - , m_outTangentType(eTangentType_Auto) - , m_bBreakTangents(false) - { - } - - enum ETangentType - { - eTangentType_Custom, - eTangentType_Auto, - eTangentType_Zero, - eTangentType_Step, - eTangentType_Linear, - }; - - void Serialize(Serialization::IArchive& ar) - { - ar(m_value, "value", "Value"); - - if (ar.IsOutput()) - { - bool breakTangents = m_bBreakTangents; - ar(breakTangents, "breakTangents", "Break Tangents"); - } - else - { - bool breakTangents = false; - ar(breakTangents, "breakTangents", "Break Tangents"); - m_bBreakTangents = breakTangents; - } - - if (ar.IsOutput()) - { - ETangentType inTangentType = m_inTangentType; - ar(inTangentType, "inTangentType", "Incoming tangent type"); - } - else - { - ETangentType inTangentType = eTangentType_Auto; - ar(inTangentType, "inTangentType", "Incoming tangent type"); - m_inTangentType = inTangentType; - } - - ar(m_inTangent, "inTangent", (m_inTangentType == eTangentType_Custom) ? "Incoming Tangent" : NULL); - - if (ar.IsOutput()) - { - ETangentType outTangentType = m_outTangentType; - ar(outTangentType, "outTangentType", "Outgoing tangent type"); - } - else - { - ETangentType outTangentType = eTangentType_Auto; - ar(outTangentType, "outTangentType", "Outgoing tangent type"); - m_outTangentType = outTangentType; - } - - ar(m_outTangent, "outTangent", (m_outTangentType == eTangentType_Custom) ? "Outgoing Tangent" : NULL); - } - - float m_value; - - // For 1D Bezier only the Y component is used - Vec2 m_inTangent; - Vec2 m_outTangent; - - ETangentType m_inTangentType : 4; - ETangentType m_outTangentType : 4; - bool m_bBreakTangents : 1; -}; - -struct SBezierKey -{ - SBezierKey() - : m_time(0) {} - - void Serialize(Serialization::IArchive& ar) - { - ar(m_time, "time", "Time"); - ar(m_controlPoint, "controlPoint", "Control Point"); - } - - SAnimTime m_time; - SBezierControlPoint m_controlPoint; -}; - -namespace Bezier -{ - inline float Evaluate(float t, float p0, float p1, float p2, float p3) - { - const float a = 1 - t; - const float aSq = a * a; - const float tSq = t * t; - return (aSq * a * p0) + (3.0f * aSq * t * p1) + (3.0f * a * tSq * p2) + (tSq * t * p3); - } - - inline float EvaluateDeriv(float t, float p0, float p1, float p2, float p3) - { - const float a = 1 - t; - const float ta = t * a; - const float aSq = a * a; - const float tSq = t * t; - return 3.0f * ((-p2 * tSq) + (p3 * tSq) - (p0 * aSq) + (p1 * aSq) + 2.0f * ((-p1 * ta) + (p2 * ta))); - } - - inline float EvaluateX(const float t, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - const float p0 = 0.0f; - const float p1 = p0 + start.m_outTangent.x; - const float p3 = duration; - const float p2 = p3 + end.m_inTangent.x; - return Evaluate(t, p0, p1, p2, p3); - } - - inline float EvaluateY(const float t, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - const float p0 = start.m_value; - const float p1 = p0 + start.m_outTangent.y; - const float p3 = end.m_value; - const float p2 = p3 + end.m_inTangent.y; - return Evaluate(t, p0, p1, p2, p3); - } - - // Duration = (time at end key) - (time at start key) - inline float EvaluateDerivX(const float t, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - const float p0 = 0.0f; - const float p1 = p0 + start.m_outTangent.x; - const float p3 = duration; - const float p2 = p3 + end.m_inTangent.x; - return EvaluateDeriv(t, p0, p1, p2, p3); - } - - inline float EvaluateDerivY(const float t, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - const float p0 = start.m_value; - const float p1 = p0 + start.m_outTangent.y; - const float p3 = end.m_value; - const float p2 = p3 + end.m_inTangent.y; - return EvaluateDeriv(t, p0, p1, p2, p3); - } - - // Find interpolation factor where 2D bezier curve has the given x value. Works only for curves where x is monotonically increasing. - // The passed x must be in range [0, duration]. Uses the Newton-Raphson root finding method. Usually takes 2 or 3 iterations. - // - // Note: This is for "1D" 2D bezier curves as used in TrackView. The curves are restricted by the curve editor to be monotonically increasing. - // - inline float InterpolationFactorFromX(const float x, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - float t = (x / duration); - - const float epsilon = 0.00001f; - const uint maxSteps = 10; - - for (uint i = 0; i < maxSteps; ++i) - { - const float currentX = EvaluateX(t, duration, start, end) - x; - if (fabs(currentX) <= epsilon) - { - break; - } - - const float currentXDeriv = EvaluateDerivX(t, duration, start, end); - t -= currentX / currentXDeriv; - } - - return t; - } - - inline SBezierControlPoint CalculateInTangent( - float time, const SBezierControlPoint& point, - float leftTime, const SBezierControlPoint* pLeftPoint, - float rightTime, const SBezierControlPoint* pRightPoint) - { - SBezierControlPoint newPoint = point; - - // In tangent X can never be positive - newPoint.m_inTangent.x = std::min(point.m_inTangent.x, 0.0f); - - if (pLeftPoint) - { - switch (point.m_inTangentType) - { - case SBezierControlPoint::eTangentType_Custom: - { - // Need to clamp tangent if it is reaching over last point - const float deltaTime = time - leftTime; - if (deltaTime < -newPoint.m_inTangent.x) - { - if (newPoint.m_inTangent.x == 0) - { - newPoint.m_inTangent = Vec2(ZERO); - } - else - { - float scaleFactor = deltaTime / -newPoint.m_inTangent.x; - newPoint.m_inTangent.x = -deltaTime; - newPoint.m_inTangent.y *= scaleFactor; - } - } - } - break; - case SBezierControlPoint::eTangentType_Zero: - // Fall through. Zero for y is same as Auto, x is set to 0.0f - case SBezierControlPoint::eTangentType_Auto: - { - const SBezierControlPoint& rightPoint = pRightPoint ? *pRightPoint : point; - const float deltaTime = (pRightPoint ? rightTime : time) - leftTime; - if (deltaTime > 0.0f) - { - const float ratio = (time - leftTime) / deltaTime; - const float deltaValue = rightPoint.m_value - pLeftPoint->m_value; - const bool bIsZeroTangent = (point.m_inTangentType == SBezierControlPoint::eTangentType_Zero); - newPoint.m_inTangent = Vec2(-(deltaTime * ratio) / 3.0f, bIsZeroTangent ? 0.0f : -(deltaValue * ratio) / 3.0f); - } - else - { - newPoint.m_inTangent = Vec2(ZERO); - } - } - break; - case SBezierControlPoint::eTangentType_Linear: - newPoint.m_inTangent = Vec2((leftTime - time) / 3.0f, - (pLeftPoint->m_value - point.m_value) / 3.0f); - break; - } - } - - return newPoint; - } - - inline SBezierControlPoint CalculateOutTangent( - float time, const SBezierControlPoint& point, - float leftTime, const SBezierControlPoint* pLeftPoint, - float rightTime, const SBezierControlPoint* pRightPoint) - { - SBezierControlPoint newPoint = point; - - // Out tangent X can never be negative - newPoint.m_outTangent.x = std::max(point.m_outTangent.x, 0.0f); - - if (pRightPoint) - { - switch (point.m_outTangentType) - { - case SBezierControlPoint::eTangentType_Custom: - { - // Need to clamp tangent if it is reaching over next point - const float deltaTime = rightTime - time; - if (deltaTime < newPoint.m_outTangent.x) - { - if (newPoint.m_outTangent.x == 0) - { - newPoint.m_outTangent = Vec2(ZERO); - } - else - { - float scaleFactor = deltaTime / newPoint.m_outTangent.x; - newPoint.m_outTangent.x = deltaTime; - newPoint.m_outTangent.y *= scaleFactor; - } - } - } - break; - case SBezierControlPoint::eTangentType_Zero: - // Fall through. Zero for y is same as Auto, x is set to 0.0f - case SBezierControlPoint::eTangentType_Auto: - { - const SBezierControlPoint& leftPoint = pLeftPoint ? *pLeftPoint : point; - const float deltaTime = rightTime - (pLeftPoint ? leftTime : time); - if (deltaTime > 0.0f) - { - const float ratio = (rightTime - time) / deltaTime; - const float deltaValue = pRightPoint->m_value - leftPoint.m_value; - const bool bIsZeroTangent = (point.m_outTangentType == SBezierControlPoint::eTangentType_Zero); - newPoint.m_outTangent = Vec2((deltaTime * ratio) / 3.0f, bIsZeroTangent ? 0.0f : (deltaValue * ratio) / 3.0f); - } - else - { - newPoint.m_outTangent = Vec2(ZERO); - } - } - break; - case SBezierControlPoint::eTangentType_Linear: - newPoint.m_outTangent = Vec2((rightTime - time) / 3.0f, - (pRightPoint->m_value - point.m_value) / 3.0f); - break; - } - } - - return newPoint; - } -} - -#endif diff --git a/Code/CryEngine/CryCommon/CryExtension/CryCreateClassInstance.h b/Code/CryEngine/CryCommon/CryExtension/CryCreateClassInstance.h deleted file mode 100644 index 1d1a4805d4..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/CryCreateClassInstance.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H -#define CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H -#pragma once - - -#include "ICryUnknown.h" -#include "ICryFactory.h" -#include "ICryFactoryRegistry.h" -#include // <> required for Interfuscator - - -template -bool CryCreateClassInstance(const CryClassID& cid, AZStd::shared_ptr& p) -{ - p = AZStd::shared_ptr(); - ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry(); - if (pFactoryReg) - { - ICryFactory* pFactory = pFactoryReg->GetFactory(cid); - if (pFactory && pFactory->ClassSupports(cryiidof())) - { - ICryUnknownPtr pUnk = pFactory->CreateClassInstance(); - AZStd::shared_ptr pT = cryinterface_cast(pUnk); - if (pT) - { - p = pT; - } - } - } - return p.get() != NULL; -} - - -template -bool CryCreateClassInstance(const char* cname, AZStd::shared_ptr& p) -{ - p = AZStd::shared_ptr(); - ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry(); - if (pFactoryReg) - { - ICryFactory* pFactory = pFactoryReg->GetFactory(cname); - if (pFactory != NULL && pFactory->ClassSupports(cryiidof())) - { - ICryUnknownPtr pUnk = pFactory->CreateClassInstance(); - AZStd::shared_ptr pT = cryinterface_cast(pUnk); - if (pT) - { - p = pT; - } - } - } - return p.get() != NULL; -} - - -template -bool CryCreateClassInstanceForInterface(const CryInterfaceID& iid, AZStd::shared_ptr& p) -{ - p = AZStd::shared_ptr(); - ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry(); - if (pFactoryReg) - { - size_t numFactories = 1; - ICryFactory* pFactory = 0; - pFactoryReg->IterateFactories(iid, &pFactory, numFactories); - if (numFactories == 1 && pFactory) - { - ICryUnknownPtr pUnk = pFactory->CreateClassInstance(); - AZStd::shared_ptr pT = cryinterface_cast(pUnk); - if (pT) - { - p = pT; - } - } - } - return p.get() != NULL; -} - - -#endif // CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H diff --git a/Code/CryEngine/CryCommon/CryExtension/CryGUID.h b/Code/CryEngine/CryCommon/CryExtension/CryGUID.h deleted file mode 100644 index a779e91bd2..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/CryGUID.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_CRYGUID_H -#define CRYINCLUDE_CRYEXTENSION_CRYGUID_H -#pragma once - -#include "Serialization/IArchive.h" -#include "Random.h" - -#include - -struct CryGUID -{ - uint64 hipart; - uint64 lopart; - - // !!! Do NOT turn CryGUID into a non-aggregate !!! - // It will prevent inlining and type list unrolling opportunities within - // cryinterface_cast() and cryiidof(). As such prevent constructors, - // non-public members, base classes and virtual functions! - - //CryGUID() : hipart(0), lopart(0) {} - //CryGUID(uint64 h, uint64 l) : hipart(h), lopart(l) {} - - static CryGUID Construct(const uint64& hipart, const uint64& lopart) - { - CryGUID guid = {hipart, lopart}; - return guid; - } - - static CryGUID Create() - { - uint64 lopart = 0; - uint64 hipart = 0; - while (lopart == 0 || hipart == 0) - { - const uint32 a = cry_random_uint32(); - const uint32 b = cry_random_uint32(); - const uint32 c = cry_random_uint32(); - const uint32 d = cry_random_uint32(); - lopart = (uint64)a | ((uint64)b << 32); - hipart = (uint64)c | ((uint64)d << 32); - } - - return Construct(lopart, hipart); - } - - static CryGUID Null() - { - return Construct(0, 0); - } - - bool operator ==(const CryGUID& rhs) const {return hipart == rhs.hipart && lopart == rhs.lopart; } - bool operator !=(const CryGUID& rhs) const {return hipart != rhs.hipart || lopart != rhs.lopart; } - bool operator <(const CryGUID& rhs) const {return hipart == rhs.hipart ? lopart < rhs.lopart : hipart < rhs.hipart; } - - void Serialize(Serialization::IArchive& ar) - { - if (ar.IsInput()) - { - uint32 dwords[4]; - ar(dwords, "guid"); - lopart = (((uint64)dwords[1]) << 32) | (uint64)dwords[0]; - hipart = (((uint64)dwords[3]) << 32) | (uint64)dwords[2]; - } - else - { - uint32 guid[4] = { - (uint32)(lopart & 0xFFFFFFFF), (uint32)((lopart >> 32) & 0xFFFFFFFF), - (uint32)(hipart & 0xFFFFFFFF), (uint32)((hipart >> 32) & 0xFFFFFFFF) - }; - ar(guid, "guid"); - } - } -}; - -// This is only used by the editor where we use C++ 11. -namespace std -{ - template<> - struct hash - { - public: - size_t operator()(const CryGUID& guid) const - { - std::hash hasher; - return hasher(guid.lopart) ^ hasher(guid.hipart); - } - }; -} - -namespace AZStd -{ - template<> - struct hash - { - public: - size_t operator()(const CryGUID& guid) const - { - std::hash hasher; - return hasher(guid); - } - }; -} - -#define MAKE_CRYGUID(high, low) CryGUID::Construct((uint64) high##LL, (uint64) low##LL) - - -#endif // CRYINCLUDE_CRYEXTENSION_CRYGUID_H diff --git a/Code/CryEngine/CryCommon/CryExtension/CryTypeID.h b/Code/CryEngine/CryCommon/CryExtension/CryTypeID.h deleted file mode 100644 index 16ae05b448..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/CryTypeID.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H -#define CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H -#pragma once - - -#include "CryGUID.h" - - -typedef CryGUID CryInterfaceID; -typedef CryGUID CryClassID; - - -#endif // CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H diff --git a/Code/CryEngine/CryCommon/CryExtension/ICryFactory.h b/Code/CryEngine/CryCommon/CryExtension/ICryFactory.h deleted file mode 100644 index a1a7344198..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/ICryFactory.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H -#define CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H -#pragma once - - -#include "CryTypeID.h" -#include - -struct ICryUnknown; -DECLARE_SMART_POINTERS(ICryUnknown); - -struct ICryFactory -{ - virtual const char* GetName() const = 0; - virtual const CryClassID& GetClassID() const = 0; - virtual bool ClassSupports(const CryInterfaceID& iid) const = 0; - virtual void ClassSupports(const CryInterfaceID*& pIIDs, size_t& numIIDs) const = 0; - virtual ICryUnknownPtr CreateClassInstance() const = 0; - -protected: - // prevent explicit destruction from client side (delete, shared_ptr, etc) - virtual ~ICryFactory() {} -}; - -#endif // CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H diff --git a/Code/CryEngine/CryCommon/CryExtension/ICryFactoryRegistry.h b/Code/CryEngine/CryCommon/CryExtension/ICryFactoryRegistry.h deleted file mode 100644 index f97c0780a1..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/ICryFactoryRegistry.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H -#define CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H -#pragma once - - -#include "CryTypeID.h" - - -struct ICryFactory; - - -struct ICryFactoryRegistry -{ - virtual ICryFactory* GetFactory(const char* cname) const = 0; - virtual ICryFactory* GetFactory(const CryClassID& cid) const = 0; - /** - * Iterates all factories implementing the interface specified by \p iid. - * \param[in] iid ID of the interface to iterate. Often procured using cryiidof<...>(). - * \param[out] pFactories A pointer of the array of factories to fill in. May be nullptr (see below). - * \param[in] Size (in elements) of the pFactories array [out] Number of elements actually written to pFactories or, when pFactories is null, the number of elements that would be written if sufficient storage was available. - * - * Example: - * \code{.cpp} - * size_t factoryCount = 0; - * // Assigns the number of found factories to factoryCount - * factoryRegistry->IterateFactories(cryiidof(), 0, factoryCount); - * // Allocate an array of the proper length on the stack - * ICryFactory** factories = static_cast(alloca(sizeof(ICryFactory*) * factoryCount); - * // Fill in factories with factoryCount results. - * factoryRegistry->IterateFactories(cryiidof(), factories, factoryCount); - * \endcode - */ - virtual void IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const = 0; - -protected: - // prevent explicit destruction from client side (delete, shared_ptr, etc) - virtual ~ICryFactoryRegistry() {} -}; - -#endif // CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H diff --git a/Code/CryEngine/CryCommon/CryExtension/ICryUnknown.h b/Code/CryEngine/CryCommon/CryExtension/ICryUnknown.h deleted file mode 100644 index 0de018305b..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/ICryUnknown.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H -#define CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H -#pragma once - - -#include "CryTypeID.h" -#include - - -struct ICryFactory; -struct ICryUnknown; - -namespace InterfaceCastSemantics -{ - template - const CryInterfaceID& cryiidof() - { - return T::IID(); - } - -#define _BEFRIEND_CRYIIDOF() \ - template \ - friend const CryInterfaceID&InterfaceCastSemantics::cryiidof(); - - - template - Dst* cryinterface_cast(Src* p) - { - return static_cast(p ? p->QueryInterface(cryiidof()) : 0); - } - - template - Dst* cryinterface_cast(const Src* p) - { - return static_cast(p ? p->QueryInterface(cryiidof()) : 0); - } - - namespace Internal - { - template - struct cryinterface_cast_shared_ptr_helper; - - template - struct cryinterface_cast_shared_ptr_helper - { - static AZStd::shared_ptr Op(const AZStd::shared_ptr& p) - { - Dst* dp = cryinterface_cast(p.get()); - return dp ? AZStd::shared_ptr(p, dp) : AZStd::shared_ptr(); - } - }; - - template - struct cryinterface_cast_shared_ptr_helper - { - static AZStd::shared_ptr Op(const AZStd::shared_ptr& p) - { - ICryUnknown* dp = cryinterface_cast(p.get()); - return dp ? AZStd::shared_ptr(*((const AZStd::shared_ptr*) & p), dp) : AZStd::shared_ptr(); - } - }; - - template - struct cryinterface_cast_shared_ptr_helper - { - static AZStd::shared_ptr Op(const AZStd::shared_ptr& p) - { - const ICryUnknown* dp = cryinterface_cast(p.get()); - return dp ? AZStd::shared_ptr(*((const AZStd::shared_ptr*) & p), dp) : AZStd::shared_ptr(); - } - }; - } // namespace Internal - - template - AZStd::shared_ptr cryinterface_cast(const AZStd::shared_ptr& p) - { - return Internal::cryinterface_cast_shared_ptr_helper::Op(p); - } - -#define _BEFRIEND_CRYINTERFACE_CAST() \ - template \ - friend Dst * InterfaceCastSemantics::cryinterface_cast(Src*); \ - template \ - friend Dst * InterfaceCastSemantics::cryinterface_cast(const Src*); \ - template \ - friend AZStd::shared_ptr InterfaceCastSemantics::cryinterface_cast(const AZStd::shared_ptr&); -} // namespace InterfaceCastSemantics - -using InterfaceCastSemantics::cryiidof; -using InterfaceCastSemantics::cryinterface_cast; - - -template -bool CryIsSameClassInstance(S* p0, T* p1) -{ - return static_cast(p0) == static_cast(p1) || cryinterface_cast(p0) == cryinterface_cast(p1); -} - -template -bool CryIsSameClassInstance(const AZStd::shared_ptr& p0, T* p1) -{ - return CryIsSameClassInstance(p0.get(), p1); -} - -template -bool CryIsSameClassInstance(S* p0, const AZStd::shared_ptr& p1) -{ - return CryIsSameClassInstance(p0, p1.get()); -} - -template -bool CryIsSameClassInstance(const AZStd::shared_ptr& p0, const AZStd::shared_ptr& p1) -{ - return CryIsSameClassInstance(p0.get(), p1.get()); -} - - -namespace CompositeQuerySemantics -{ - template - AZStd::shared_ptr crycomposite_query(Src* p, const char* name, bool* pExposed = 0) - { - void* pComposite = p ? p->QueryComposite(name) : 0; - pExposed ? *pExposed = pComposite != 0 : 0; - return pComposite ? *static_cast*>(pComposite) : AZStd::shared_ptr(); - } - - template - AZStd::shared_ptr crycomposite_query(const Src* p, const char* name, bool* pExposed = 0) - { - void* pComposite = p ? p->QueryComposite(name) : 0; - pExposed ? *pExposed = pComposite != 0 : 0; - return pComposite ? *static_cast*>(pComposite) : AZStd::shared_ptr(); - } - - template - AZStd::shared_ptr crycomposite_query(const AZStd::shared_ptr& p, const char* name, bool* pExposed = 0) - { - return crycomposite_query(p.get(), name, pExposed); - } - - template - AZStd::shared_ptr crycomposite_query(const AZStd::shared_ptr& p, const char* name, bool* pExposed = 0) - { - return crycomposite_query(p.get(), name, pExposed); - } - -#define _BEFRIEND_CRYCOMPOSITE_QUERY() \ - template \ - friend AZStd::shared_ptr CompositeQuerySemantics::crycomposite_query(Src*, const char*, bool*); \ - template \ - friend AZStd::shared_ptr CompositeQuerySemantics::crycomposite_query(const Src*, const char*, bool*); \ - template \ - friend AZStd::shared_ptr CompositeQuerySemantics::crycomposite_query(const AZStd::shared_ptr&, const char*, bool*); \ - template \ - friend AZStd::shared_ptr CompositeQuerySemantics::crycomposite_query(const AZStd::shared_ptr&, const char*, bool*); -} // namespace CompositeQuerySemantics - -using CompositeQuerySemantics::crycomposite_query; - - -#define _BEFRIEND_MAKE_SHARED() \ - template \ - friend class AZStd::Internal::sp_ms_deleter; \ - template \ - friend AZStd::shared_ptr AZStd::make_shared(); \ - template \ - friend AZStd::shared_ptr AZStd::allocate_shared(A const& a); - -// prevent explicit destruction from client side -#define _PROTECTED_DTOR(iname) \ -protected: \ - virtual ~iname() {} - - -// Befriending cryinterface_cast() and crycomposite_query() via CRYINTERFACE_DECLARE is actually only needed for ICryUnknown -// since QueryInterface() and QueryComposite() are usually not redeclared in derived interfaces but it doesn't hurt either -#define CRYINTERFACE_DECLARE(iname, iidHigh, iidLow) \ - _BEFRIEND_CRYIIDOF() \ - _BEFRIEND_CRYINTERFACE_CAST() \ - _BEFRIEND_CRYCOMPOSITE_QUERY() \ - _BEFRIEND_MAKE_SHARED() \ - _PROTECTED_DTOR(iname) \ - \ -private: \ - static const CryInterfaceID& IID() \ - { \ - static const CryInterfaceID iid = {(uint64) iidHigh##LL, (uint64) iidLow##LL}; \ - return iid; \ - } \ -public: - - -struct ICryUnknown -{ - CRYINTERFACE_DECLARE(ICryUnknown, 0x1000000010001000, 0x1000100000000000) - - virtual ICryFactory * GetFactory() const = 0; - -protected: - virtual void* QueryInterface(const CryInterfaceID& iid) const = 0; - virtual void* QueryComposite(const char* name) const = 0; -}; - -DECLARE_SMART_POINTERS(ICryUnknown); - - -#endif // CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/ClassWeaver.h b/Code/CryEngine/CryCommon/CryExtension/Impl/ClassWeaver.h deleted file mode 100644 index c3b5bb340c..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/ClassWeaver.h +++ /dev/null @@ -1,461 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H -#pragma once - -#include "TypeList.h" -#include "Conversion.h" -#include "RegFactoryNode.h" -#include "../ICryUnknown.h" -#include "../ICryFactory.h" -#include - -namespace CW -{ - namespace Internal - { - template - struct InterfaceCast; - - template - struct InterfaceCast - { - template - static void* Op(T* p) - { - return (Dst*) p; - } - }; - - template <> - struct InterfaceCast - { - template - static void* Op(T* p) - { - return const_cast(static_cast(static_cast(p))); - } - }; - } - - template - struct InterfaceCast; - - template <> - struct InterfaceCast - { - template - static void* Op(T*, const CryInterfaceID&) - { - return 0; - } - }; - - template - struct InterfaceCast > - { - template - static void* Op(T* p, const CryInterfaceID& iid) - { - if (cryiidof() == iid) - { - return Internal::InterfaceCast::Op(p); - } - return InterfaceCast::Op(p, iid); - } - }; - - template - struct FillIIDs; - - template <> - struct FillIIDs - { - static void Op(CryInterfaceID*) - { - } - }; - - template - struct FillIIDs > - { - static void Op(CryInterfaceID* p) - { - *p++ = cryiidof(); - FillIIDs::Op(p); - } - }; - - namespace Internal - { - template - struct PickList; - - template - struct PickList - { - typedef TL::BuildTypelist<>::Result Result; - }; - - template - struct PickList - { - typedef typename S::FullCompositeList Result; - }; - } - - template - struct ProbeFullCompositeList - { - private: - typedef char y[1]; - typedef char n[2]; - - template - static y& test(typename S::FullCompositeList*); - - template - static n& test(...); - - public: - enum - { - listFound = sizeof(test(0)) == sizeof(y) - }; - - typedef typename Internal::PickList::Result ListType; - }; - - namespace Internal - { - template - struct CompositeQuery; - - template <> - struct CompositeQuery - { - template - static void* Op(const T&, const char*) - { - return 0; - } - }; - - template - struct CompositeQuery > - { - template - static void* Op(const T& ref, const char* name) - { - void* p = ref.Head::CompositeQueryImpl(name); - return p ? p : CompositeQuery::Op(ref, name); - } - }; - } - - struct CompositeQuery - { - template - static void* Op(const T& ref, const char* name) - { - return Internal::CompositeQuery::ListType>::Op(ref, name); - } - }; - - inline bool NameMatch(const char* name, const char* compositeName) - { - if (!name || !compositeName) - { - return false; - } - size_t i = 0; - for (; name[i] && name[i] == compositeName[i]; ++i) - { - } - return name[i] == compositeName[i]; - } - - template - void* CheckCompositeMatch(const char* name, const AZStd::shared_ptr& composite, const char* compositeName) - { - typedef TC::SuperSubClass Rel; - COMPILE_TIME_ASSERT(Rel::exists); - return NameMatch(name, compositeName) ? const_cast(static_cast(&composite)) : 0; - } -} // namespace CW - - -#define CRYINTERFACE_BEGIN() \ -private: \ - typedef TL::BuildTypelist < ICryUnknown - -#define CRYINTERFACE_ADD(iname) , iname - -#define CRYINTERFACE_END() > ::Result _UserDefinedPartialInterfaceList; \ -protected: \ - typedef TL::NoDuplicates<_UserDefinedPartialInterfaceList>::Result FullInterfaceList; - -#define _CRY_TPL_APPEND0(base) TL::Append::Result -#define _CRY_TPL_APPEND(base, intermediate) TL::Append::Result - -#define CRYINTERFACE_ENDWITHBASE(base) > ::Result _UserDefinedPartialInterfaceList; \ -protected: \ - typedef TL::NoDuplicates<_CRY_TPL_APPEND0(base)>::Result FullInterfaceList; - -#define CRYINTERFACE_ENDWITHBASE2(base0, base1) > ::Result _UserDefinedPartialInterfaceList; \ -protected: \ - typedef TL::NoDuplicates<_CRY_TPL_APPEND(base0, _CRY_TPL_APPEND0(base1))>::Result FullInterfaceList; - -#define CRYINTERFACE_ENDWITHBASE3(base0, base1, base2) > ::Result _UserDefinedPartialInterfaceList; \ -protected: \ - typedef TL::NoDuplicates<_CRY_TPL_APPEND(base0, _CRY_TPL_APPEND(base1, _CRY_TPL_APPEND0(base2)))>::Result FullInterfaceList; - -#define CRYINTERFACE_SIMPLE(iname) \ - CRYINTERFACE_BEGIN() \ - CRYINTERFACE_ADD(iname) \ - CRYINTERFACE_END() - -#define CRYCOMPOSITE_BEGIN() \ -private: \ - void* CompositeQueryImpl(const char* name) const \ - { \ - (void)(name); \ - void* res = 0; (void)(res); \ - -#define CRYCOMPOSITE_ADD(member, membername) \ - COMPILE_TIME_ASSERT((sizeof(membername) / sizeof(membername[0])) > 1); \ - if ((res = CW::CheckCompositeMatch(name, member, membername)) != 0) { \ - return res; } - -#define _CRYCOMPOSITE_END(implclassname) \ - return 0; \ - }; \ -protected: \ - typedef TL::BuildTypelist::Result _PartialCompositeList; \ - \ - template \ - friend struct CW::Internal::PickList; - -#define CRYCOMPOSITE_END(implclassname) \ - _CRYCOMPOSITE_END(implclassname) \ -protected: \ - typedef _PartialCompositeList FullCompositeList; - -#define _CRYCOMPOSITE_APPEND0(base) TL::Append<_PartialCompositeList, CW::ProbeFullCompositeList::ListType>::Result -#define _CRYCOMPOSITE_APPEND(base, intermediate) TL::Append::ListType>::Result - -#define CRYCOMPOSITE_ENDWITHBASE(implclassname, base) \ - _CRYCOMPOSITE_END(implclassname) \ -protected: \ - typedef _CRYCOMPOSITE_APPEND0 (base) FullCompositeList; - -#define CRYCOMPOSITE_ENDWITHBASE2(implclassname, base0, base1) \ - _CRYCOMPOSITE_END(implclassname) \ -protected: \ - typedef TL::NoDuplicates<_CRYCOMPOSITE_APPEND(base1, _CRYCOMPOSITE_APPEND0(base0))>::Result FullCompositeList; - -#define CRYCOMPOSITE_ENDWITHBASE3(implclassname, base0, base1, base2) \ - _CRYCOMPOSITE_END(implclassname) \ -protected: \ - typedef TL::NoDuplicates<_CRYCOMPOSITE_APPEND(base2, _CRYCOMPOSITE_APPEND(base1, _CRYCOMPOSITE_APPEND0(base0)))>::Result FullCompositeList; - -template -class CFactory - : public ICryFactory -{ -public: - virtual const char* GetName() const - { - return T::GetCName(); - } - - virtual const CryClassID& GetClassID() const - { - return T::GetCID(); - } - - virtual bool ClassSupports(const CryInterfaceID& iid) const - { - for (size_t i = 0; i < m_numIIDs; ++i) - { - if (iid == m_pIIDs[i]) - { - return true; - } - } - return false; - } - - virtual void ClassSupports(const CryInterfaceID*& pIIDs, size_t& numIIDs) const - { - pIIDs = m_pIIDs; - numIIDs = m_numIIDs; - } -public: - virtual ICryUnknownPtr CreateClassInstance() const - { - AZStd::shared_ptr p = AZStd::make_shared(); - return cryinterface_cast (p); - } - - CFactory() - : m_numIIDs(0) - , m_pIIDs(0) - , m_regFactory() - { - static CryInterfaceID supportedIIDs[TL::Length < typename T::FullInterfaceList > ::value]; - CW::FillIIDs::Op(supportedIIDs); - m_pIIDs = &supportedIIDs[0]; - m_numIIDs = TL::Length::value; - new(&m_regFactory)SRegFactoryNode(this); - } - -protected: - CFactory(const CFactory&); - CFactory& operator =(const CFactory&); - - - size_t m_numIIDs; - CryInterfaceID* m_pIIDs; - SRegFactoryNode m_regFactory; -}; - -template -class CSingletonFactory - : public CFactory -{ -public: - CSingletonFactory() - : CFactory() - , m_csCreateClassInstance() - { - } - - virtual ICryUnknownPtr CreateClassInstance() const - { - CryAutoLock lock(m_csCreateClassInstance); - // override the allocator. These function static instances are being destroyed after the AZ alloctor has been deleted. - // On win, TerminateProcess() prevents these destructors from being called, but that is not the case on OSX. - static typename AZStd::aligned_storage,SingletonAllocator>), AZStd::alignment_of::value>::type m_storage; - static ICryUnknownPtr p = AZStd::allocate_shared(SingletonAllocator(AZStd::addressof(m_storage))); - return p; - } - - mutable CryCriticalSection m_csCreateClassInstance; - - struct SingletonAllocator - { - SingletonAllocator(void* ptr) : - m_data(ptr) - {} - void* allocate(size_t /*byteSize*/, size_t /*alignment*/, int /*flags*/ = 0) - { - return m_data; - } - void deallocate(void* /*ptr*/, size_t /*byteSize*/, size_t /*alignment*/) - { - // nothing to see here - } - void* m_data; - }; -}; - -#define _CRYFACTORY_DECLARE(implclassname) \ -private: \ - friend class CFactory; \ - static CFactory s_factory; - -#define _CRYFACTORY_DECLARE_SINGLETON(implclassname) \ -private: \ - friend class CFactory; \ - friend void* Get##implclassname##Factory(); \ - static CSingletonFactory s_factory; - -#define _IMPLEMENT_ICRYUNKNOWN() \ -public: \ - virtual ICryFactory* GetFactory() const \ - { \ - return &s_factory; \ - } \ - \ -protected: \ - virtual void* QueryInterface(const CryInterfaceID&iid) const \ - { \ - return CW::InterfaceCast::Op(this, iid); \ - } \ - \ - template \ - friend struct CW::Internal::CompositeQuery; \ - \ - virtual void* QueryComposite(const char* name) const \ - { \ - return CW::CompositeQuery::Op(*this, name); \ - } - -#define _ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow) \ -public: \ - static const char* GetCName() \ - { \ - return cname; \ - } \ - static const CryClassID& GetCID() \ - { \ - static const CryClassID cid = {(uint64) cidHigh##LL, (uint64) cidLow##LL}; \ - return cid; \ - } \ - static AZStd::shared_ptr CreateClassInstance() \ - { \ - ICryUnknownPtr p = s_factory.CreateClassInstance(); \ - return AZStd::shared_ptr(*static_cast*>(static_cast(&p))); \ - } \ - \ -protected: \ - implclassname(); \ - virtual ~implclassname(); - -#define _BEFRIEND_OPS() \ - _BEFRIEND_CRYINTERFACE_CAST() \ - _BEFRIEND_CRYCOMPOSITE_QUERY() \ - _BEFRIEND_MAKE_SHARED() - -#define CRYGENERATE_CLASS(implclassname, cname, cidHigh, cidLow) \ - _CRYFACTORY_DECLARE(implclassname) \ - _BEFRIEND_OPS() \ - _IMPLEMENT_ICRYUNKNOWN() \ - _ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow) - -#define CRYGENERATE_SINGLETONCLASS(implclassname, cname, cidHigh, cidLow) \ - _CRYFACTORY_DECLARE_SINGLETON(implclassname) \ - _BEFRIEND_OPS() \ - _IMPLEMENT_ICRYUNKNOWN() \ - _ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow) - - -#define CRYREGISTER_CLASS(implclassname) \ - CFactory implclassname::s_factory; - -#define DECLARE_CRYREGISTER_SINGLETON_CLASS(implclassname) \ - void* Get##implclassname##Factory(); - -#define CRYREGISTER_SINGLETON_CLASS(implclassname) \ - CSingletonFactory implclassname::s_factory; \ - void* Get##implclassname##Factory() { \ - return &implclassname::s_factory; \ - } - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/Conversion.h b/Code/CryEngine/CryCommon/CryExtension/Impl/Conversion.h deleted file mode 100644 index bd729f259e..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/Conversion.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H -#pragma once - - -namespace TC -{ - //template - //struct Conversion - //{ - //private: - // typedef char y[1]; - // typedef char n[2]; - // static y& Test(U); - // static n& Test(...); - // static T MakeT(); - - //public: - // enum - // { - // exists = sizeof(Test(MakeT())) == sizeof(y), - // sameType = false - // }; - //}; - - //template - //struct Conversion - //{ - //public: - // enum - // { - // exists = true, - // sameType = true - // }; - //}; - - //template - //struct CheckInheritance - //{ - // enum - // { - // exists = Conversion::exists && !Conversion::sameType - // }; - //}; - - //template - //struct CheckStrictInheritance - //{ - // enum - // { - // exists = CheckInheritance::exists && !Conversion::sameType - // }; - //}; - - - template - struct SuperSubClass - { - private: - typedef char y[1]; - typedef char n[2]; - - template - static y& check(const volatile Derived&, T); - static n& check(const volatile Base&, int); - - struct C - { - operator const volatile Base&() const; - operator const volatile Derived&(); - }; - - static C getC(); - - public: - enum - { - exists = sizeof(check(getC(), 0)) == sizeof(y), - sameType = false - }; - }; - - template - struct SuperSubClass - { - enum - { - exists = true - }; - }; -} // namespace TC - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/CryGUIDHelper.h b/Code/CryEngine/CryCommon/CryExtension/Impl/CryGUIDHelper.h deleted file mode 100644 index 53ee4352fc..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/CryGUIDHelper.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H -#pragma once - - -#include "../CryGUID.h" -#include "../../CryString.h" - - -namespace CryGUIDHelper -{ - string Print(const CryGUID& val) - { - char buf[39]; // sizeof("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}") - - static const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - char* p = buf; - *p++ = '{'; - for (int i = 15; i >= 8; --i) - { - *p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)]; - } - *p++ = '-'; - for (int i = 7; i >= 4; --i) - { - *p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)]; - } - *p++ = '-'; - for (int i = 3; i >= 0; --i) - { - *p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)]; - } - *p++ = '-'; - for (int i = 15; i >= 12; --i) - { - *p++ = hex[(unsigned char) ((val.lopart >> (i << 2)) & 0xF)]; - } - *p++ = '-'; - for (int i = 11; i >= 0; --i) - { - *p++ = hex[(unsigned char) ((val.lopart >> (i << 2)) & 0xF)]; - } - *p++ = '}'; - *p++ = '\0'; - - return string(buf); - } -} - - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/ICryFactoryRegistryImpl.h b/Code/CryEngine/CryCommon/CryExtension/Impl/ICryFactoryRegistryImpl.h deleted file mode 100644 index 051c33fc33..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/ICryFactoryRegistryImpl.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H -#pragma once - - -#include "../ICryFactoryRegistry.h" - - -struct SRegFactoryNode; - - -struct ICryFactoryRegistryCallback -{ - virtual void OnNotifyFactoryRegistered(ICryFactory* pFactory) = 0; - virtual void OnNotifyFactoryUnregistered(ICryFactory* pFactory) = 0; - -protected: - virtual ~ICryFactoryRegistryCallback() {} -}; - - -struct ICryFactoryRegistryImpl - : public ICryFactoryRegistry -{ - virtual ICryFactory* GetFactory(const char* cname) const = 0; - virtual ICryFactory* GetFactory(const CryClassID& cid) const = 0; - virtual void IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const = 0; - - virtual void RegisterCallback(ICryFactoryRegistryCallback* pCallback) = 0; - virtual void UnregisterCallback(ICryFactoryRegistryCallback* pCallback) = 0; - - virtual void RegisterFactories(const SRegFactoryNode* pFactories) = 0; - virtual void UnregisterFactories(const SRegFactoryNode* pFactories) = 0; - - virtual void UnregisterFactory(ICryFactory* const pFactory) = 0; - -protected: - // prevent explicit destruction from client side (delete, shared_ptr, etc) - virtual ~ICryFactoryRegistryImpl() {} -}; - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/RegFactoryNode.h b/Code/CryEngine/CryCommon/CryExtension/Impl/RegFactoryNode.h deleted file mode 100644 index 8209ae9728..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/RegFactoryNode.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H -#pragma once - -struct ICryFactory; -struct SRegFactoryNode; - -extern SRegFactoryNode* g_pHeadToRegFactories; - -struct SRegFactoryNode -{ - SRegFactoryNode() - { - } - - SRegFactoryNode(ICryFactory* pFactory) - : m_pFactory(pFactory) - , m_pNext(g_pHeadToRegFactories) - { - g_pHeadToRegFactories = this; - } - - static void* operator new(size_t, void* p) - { - return p; - } - - static void operator delete(void*, void*) - { - } - - ICryFactory* m_pFactory; - SRegFactoryNode* m_pNext; -}; - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/TypeList.h b/Code/CryEngine/CryCommon/CryExtension/Impl/TypeList.h deleted file mode 100644 index 231283fc19..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/TypeList.h +++ /dev/null @@ -1,236 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_TYPELIST_H -#define CRYINCLUDE_CRYEXTENSION_TYPELIST_H -#pragma once - - -namespace TL -{ - // typelist terminator - class NullType - { - }; - - - // structure for typelist generation - template - struct Typelist - { - typedef T Head; - typedef U Tail; - }; - - - // helper structure to automatically build typelists containing n types - template - < - typename T0 = NullType, typename T1 = NullType, typename T2 = NullType, typename T3 = NullType, typename T4 = NullType, - typename T5 = NullType, typename T6 = NullType, typename T7 = NullType, typename T8 = NullType, typename T9 = NullType, - typename T10 = NullType, typename T11 = NullType, typename T12 = NullType, typename T13 = NullType, typename T14 = NullType, - typename T15 = NullType, typename T16 = NullType, typename T17 = NullType, typename T18 = NullType, typename T19 = NullType - > - struct BuildTypelist - { - private: - typedef typename BuildTypelist::Result TailResult; - - public: - typedef Typelist Result; - }; - - template <> - struct BuildTypelist<> - { - typedef NullType Result; - }; - - // typelist operation : Length - template - struct Length; - - template <> - struct Length - { - enum - { - value = 0 - }; - }; - - template - struct Length > - { - enum - { - value = 1 + Length::value - }; - }; - - - // typelist operation : TypeAt - template - struct TypeAt; - - template - struct TypeAt, 0> - { - typedef Head Result; - }; - - template - struct TypeAt, index> - { - typedef typename TypeAt::Result Result; - }; - - - // typelist operation : IndexOf - template - struct IndexOf; - - template - struct IndexOf - { - enum - { - value = -1 - }; - }; - - template - struct IndexOf, T> - { - enum - { - value = 0 - }; - }; - - template - struct IndexOf, T> - { - private: - enum - { - temp = IndexOf::value - }; - public: - enum - { - value = temp == -1 ? -1 : 1 + temp - }; - }; - - - // typelist operation : Append - template - struct Append; - - template <> - struct Append - { - typedef NullType Result; - }; - - template - struct Append - { - typedef Typelist Result; - }; - - template - struct Append > - { - typedef Typelist Result; - }; - - template - struct Append, T> - { - typedef Typelist::Result> Result; - }; - - - // typelist operation : Erase - template - struct Erase; - - template - struct Erase - { - typedef NullType Result; - }; - - template - struct Erase, T> - { - typedef Tail Result; - }; - - template - struct Erase, T> - { - typedef Typelist::Result> Result; - }; - - - // typelist operation : Erase All - template - struct EraseAll; - - template - struct EraseAll - { - typedef NullType Result; - }; - - template - struct EraseAll, T> - { - typedef typename EraseAll::Result Result; - }; - - template - struct EraseAll, T> - { - typedef Typelist::Result> Result; - }; - - - // typelist operation : NoDuplicates - template - struct NoDuplicates; - - template <> - struct NoDuplicates - { - typedef NullType Result; - }; - - template - struct NoDuplicates > - { - private: - typedef typename NoDuplicates::Result L1; - typedef typename Erase::Result L2; - public: - typedef Typelist Result; - }; -} // namespace TL - -#endif // CRYINCLUDE_CRYEXTENSION_TYPELIST_H diff --git a/Code/CryEngine/CryCommon/CryPool/Allocator.h b/Code/CryEngine/CryCommon/CryPool/Allocator.h deleted file mode 100644 index cc751e68f1..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Allocator.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_ALLOCATOR_H -#define CRYINCLUDE_CRYPOOL_ALLOCATOR_H -#pragma once - - -namespace NCryPoolAlloc -{ - template - class CFirstFit - : public TPool - { - public: - ILINE CFirstFit() - { - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - //fastpath? - if (TPool::m_pEmpty && TPool::m_pEmpty->Available(Size, Align)) - { - TItem* pItem = TPool::Split(TPool::m_pEmpty, Size, Align); - if (!pItem) - { - return 0; - } - pItem->InUse(Align); - TPool::AllocatedMemory(pItem->MemSize()); - - //not fully occupied empty space? - TPool::m_pEmpty = pItem != TPool::m_pEmpty ? TPool::m_pEmpty : 0; - return TPool::Handle(pItem); - } - - TItem* pBestItem; - for (pBestItem = TPool::m_Items.First(); pBestItem; pBestItem = pBestItem->Next()) - { - if (pBestItem->Available(Size, Align)) // && (!pBestItem || pItem->MemSize()MemSize())) - { - break; - } - } - if (!pBestItem) - { - return 0; //out of mem - } - TItem* pItem = TPool::Split(pBestItem, Size, Align); - if (!pItem) //no free node - { - return 0; - } - pItem->InUse(Align); - TPool::AllocatedMemory(pItem->MemSize()); - - //not fully occupied empty space? - TPool::m_pEmpty = pItem != pBestItem ? pBestItem : 0; - return TPool::Handle(pItem); - } - template - ILINE bool Free(T Handle, bool ForceBoundsCheck = false) - { - return Handle ? TPool::Free(Handle, ForceBoundsCheck) : false; - } - }; - - template - class CWorstFit - : public TPool - { - public: - ILINE CWorstFit() - { - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - TItem* pBestItem = 0; - for (TItem* pItem = TPool::m_Items.First(); pItem; pItem = pItem->Next()) - { - if (pItem->IsFree() && (!pBestItem || pItem->MemSize() > pBestItem->MemSize())) - { - pBestItem = pItem; - } - } - if (!pBestItem || !pBestItem->Available(Size, Align)) - { - return 0; //out of mem - } - TItem* pItem = Split(pBestItem, Size, Align); - if (!pItem) //no free node - { - return 0; - } - pItem->InUse(Align); - AllocatedMemory(pItem->MemSize()); - return Handle(pItem); - } - }; - - template - class CBestFit - : public TPool - { - public: - ILINE CBestFit() - { - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - TItem* pBestItem = 0; - for (TItem* pItem = TPool::m_Items.First(); pItem; pItem = pItem->Next()) - { - if ((!pBestItem || pItem->MemSize() < pBestItem->MemSize()) && pItem->Available(Size, Align)) - { - if (pItem->MemSize() == Size) - { - pItem->InUse(Align); - AllocatedMemory(pItem->MemSize()); - return (T)Handle(pItem); - } - pBestItem = pItem; - } - } - if (!pBestItem) - { - return 0; //out of mem - } - TItem* pItem = Split(pBestItem, Size, Align); - if (!pItem) //no free node - { - return 0; - } - pItem->InUse(Align); - AllocatedMemory(pItem->MemSize()); - return (T)Handle(pItem); - } - }; - - - template - class CReallocator - : public TAllocator - { - public: - - template - ILINE bool Reallocate(T* pData, size_t Size, size_t Alignment) - { - //special cases - if (!Size) //just free? - { - TAllocator::Free(*pData); - *pData = 0; - return true; - } - - if (!*pData) //just alloc? - { - *pData = TAllocator::template Allocate(Size, Alignment); - return *pData != 0; - } - - //same size, nothing to do at all? - if (TAllocator::Item(*pData)->MemSize() == Size) - { - return true; - } - - if (TAllocator::ReSize(pData, Size)) - { - return true; - } - - T pNewData = TAllocator::template Allocate(Size, Alignment); - if (!pNewData) - { - return false; - } - memcpy(TAllocator::template Resolve(pNewData), - TAllocator::template Resolve(*pData), min(TAllocator::Item(*pData)->MemSize(), Size)); - TAllocator::template Free(*pData); - *pData = pNewData; - return true; - } - }; -} - - -#endif // CRYINCLUDE_CRYPOOL_ALLOCATOR_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Container.h b/Code/CryEngine/CryCommon/CryPool/Container.h deleted file mode 100644 index 82ea2735bc..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Container.h +++ /dev/null @@ -1,655 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_CONTAINER_H -#define CRYINCLUDE_CRYPOOL_CONTAINER_H -#pragma once - - -namespace NCryPoolAlloc -{ - template - class CPool - : public CMemoryStatic - { - class CPoolNode; - class CPoolNode - : public CListItem - { - }; - CList m_List; - public: - ILINE CPool() - { - CPoolNode* pPrev = 0; - CPoolNode* pNode = 0; - for (size_t a = 1; a < TElementCount; a++) //skip first element as it would be counted as zero ptr - { - uint8* pData = &CMemoryStatic::Data()[a * sizeof(TElement)]; - pNode = reinterpret_cast(pData); - pNode->Prev(pPrev); - if (pPrev) - { - pPrev->Next(pNode); - } - else - { - m_List.First(pNode); - } - pPrev = pNode; - // m_List.AddLast(pNode); - } - if (pPrev) - { - pPrev->Next(0); - m_List.Last(pPrev); - } - } - ILINE uint8* Allocate([[maybe_unused]] size_t Size, [[maybe_unused]] size_t Align = 1) - { - CPoolNode* pNode = m_List.PopFirst(); - return reinterpret_cast(pNode); - } - - template - ILINE void Free(T* pData) - { - if (pData) - { - CPoolNode* pNode = reinterpret_cast(pData); - m_List.AddLast(pNode); - } - } - - ILINE TElement& operator[](uint32 Idx) - { - uint8* pData = &CMemoryStatic::Data()[Idx * sizeof(TElement)]; - return *reinterpret_cast(pData); - } - - ILINE const TElement& operator[](uint32 Idx) const - { - const uint8* pData = &CMemoryStatic::Data()[Idx * sizeof(TElement)]; - return *reinterpret_cast(pData); - } - }; - - template - class CInPlace - : public TMemory - { - protected: - CList m_Items; - size_t m_Allocated; - CListItemInPlace* m_pEmpty; - - - ILINE void AllocatedMemory(size_t S) - { - m_Allocated += S + sizeof(CListItemInPlace); - } - ILINE void FreedMemory(size_t S) - { - m_Allocated -= S + sizeof(CListItemInPlace); - } - ILINE void Stack(CListItemInPlace* pItem) - { - } - public: - ILINE CInPlace() - : m_Allocated(0) - { - } - - ILINE void InitMem(const size_t S = 0, uint8* pData = 0) - { - TMemory::InitMem(S, pData); - if (!TMemory::MemSize()) - { - return; - } - pData = TMemory::Data(); - CListItemInPlace* pFirst = reinterpret_cast(pData); - CListItemInPlace* pFree = pFirst + 1; - CListItemInPlace* pLast = reinterpret_cast(pData + TMemory::MemSize()) - 1; - m_Items.~CList(); - new (&m_Items)CList(); - m_Items.AddLast(pFirst); - m_Items.AddLast(pFree); - m_Items.AddLast(pLast); - - pFirst->InUse(0); //static first item - pFree->Free(); - pLast->InUse(0); //static last item - m_pEmpty = pFree; - m_Allocated = 0; - } - - ILINE size_t FragmentCount() const - { - return m_Items.Count(); - } - - ILINE CListItemInPlace* Split(CListItemInPlace* pItem, size_t Size, size_t Align) - { - size_t Offset = reinterpret_cast(pItem->Data()); - Offset += pItem->MemSize(); //ptr to end - Offset -= Size; //minus size - Size += Offset & (Align - 1); //adjust size to fit required alignment - Offset -= Offset & (Align - 1); - size_t TSize = sizeof(CListItemInPlace); - Offset -= TSize; //header - - if (Offset <= reinterpret_cast(pItem + 1)) //not enough space for splitting? - { - return pItem; - } - - CListItemInPlace* pItemNext = reinterpret_cast(Offset); - - const size_t Offset2 = reinterpret_cast(pItemNext->Data()); - CPA_ASSERT(!(Offset2 & (Align - 1))); - m_Items.AddBehind(pItemNext, pItem); - //pItemNext->Prev(pItem); - //pItemNext->Next(pItem->Next()); - - // if(pItem->Next()) - // pItem->Next()->Prev(pItemNext); - - // pItem->Next(pItemNext); - pItemNext->Free(); - return pItemNext; - } - - ILINE void Merge(CListItemInPlace* pItem) - { - //merge with next if possible - CListItemInPlace* pItemNext = pItem->Next(); - if (pItemNext->IsFree()) - { - if (m_pEmpty == pItemNext) - { - m_pEmpty = pItem; - } - m_Items.Remove(pItemNext); - //pItem->Next(pItemNext->Next()); - //pItem->Next()->Prev(pItem); - } - //merge with prev if possible - CListItemInPlace* pItemPrev = pItem->Prev(); - if (pItemPrev->IsFree()) - { - if (m_pEmpty == pItem) - { - m_pEmpty = pItemPrev; - } - m_Items.Remove(pItem); - //pItemPrev->Next(pItem->Next()); - //pItem->Next()->Prev(pItemPrev); - pItem = pItemPrev; - } - } - template - ILINE T Resolve(void* rItem) const - { - return reinterpret_cast(rItem); - } - - template - ILINE size_t Size(const T* pData) const - { - const CListItemInPlace* pItem = Item(pData); - return pItem->MemSize(); - } - - bool InBounds(const void* pData, const bool Check) const - { - return !Check || ( - reinterpret_cast(pData) >= reinterpret_cast(TMemory::Data()) && - reinterpret_cast(pData) < reinterpret_cast(TMemory::Data()) + TMemory::MemSize()); - } - - template - ILINE bool Free(T* pData, bool ForceBoundsCheck = false) - { - if (pData && InBounds(pData, BoundsCheck | ForceBoundsCheck)) - { - CListItemInPlace* pItem = Item(pData); - FreedMemory(pItem->MemSize()); - pItem->Free(); - Merge(pItem); - return true; - } - return false; - } - - ILINE bool Beat(){return false; }//dummy beat in case no defragmentator is wraping - ILINE size_t MemFree() const{return TMemory::MemSize() - m_Allocated; } - ILINE size_t MemSize() const{return TMemory::MemSize(); } - - ILINE uint8* Handle(CListItemInPlace* pItem) const - { - return pItem->Data(); - } - template - ILINE CListItemInPlace* Item(T* pData) - { - return reinterpret_cast(pData) - 1; - } - template - ILINE const CListItemInPlace* Item(const T* pData) const - { - return reinterpret_cast(pData) - 1; - } - ILINE static bool Defragmentable(){return false; } - - template - ILINE bool ReSize(T* pData, size_t SizeNew) - { - //special cases - CListItemInPlace* pItem = Item(*pData); - const size_t SizeOld = pItem->MemSize(); - - //reduction - if (SizeOld > SizeNew) - { - if (pItem->Next()->IsFree()) - { - CListItemInPlace* pNextNext = pItem->Next()->Next(); - size_t Offset = reinterpret_cast(pItem->Data()); - Offset += SizeNew; //Offset to next - CListItemInPlace* pItemNext = reinterpret_cast(Offset); - pItem->Next(pItemNext); - pNextNext->Prev(pItemNext); - pItemNext->Prev(pItem); - pItemNext->Next(pNextNext); - pItemNext->Free(); - return true; - } - - if (SizeOld - SizeNew <= sizeof(CListItemInPlace)) - { - return true; //header is bigger than the amount of freed memory - } - //split - size_t Offset = reinterpret_cast(pItem->Data()); - Offset += SizeNew; //Offset to next - CListItemInPlace* pItemNext = reinterpret_cast(Offset); - m_Items.AddBehind(pItemNext, pItem); - pItemNext->Free(); - return true; - } - - //SizeOldNext(); - CListItemInPlace* pNextNext = pNext->Next(); - const size_t SizeNext = pNext->IsFree() ? pNext->MemSize() + sizeof(CListItemInPlace) : 0; - if (SizeNew <= SizeNext + SizeOld) - { - if (SizeNew + sizeof(CListItemInPlace) + 1 < SizeNext + SizeOld) - { - size_t Offset = reinterpret_cast(pItem->Data()); - Offset += SizeNew; //Offset to next - CListItemInPlace* pItemNext = reinterpret_cast(Offset); - pItem->Next(pItemNext); - pNextNext->Prev(pItemNext); - pItemNext->Prev(pItem); - pItemNext->Next(pNextNext); - pItemNext->Free(); - } - else - { - pItem->Next(pNextNext); - pNextNext->Prev(pItem); - } - return true; - } - return false; //no further in-place realloc possible - } - }; - - template - class CReferenced - : public TMemory - { - typedef CPool tdNodePool; - - protected: - tdNodePool m_NodePool; - CList m_Items; - size_t m_Allocated; - CListItemReference* m_pEmpty; - - ILINE void AllocatedMemory(size_t S) - { - m_Allocated += S; - } - ILINE void FreedMemory(size_t S) - { - m_Allocated -= S; - } - ILINE void Stack(CListItemReference* pItem) - { - m_Items.Validate(pItem); - CListItemReference* pItem2 = 0; - CListItemReference* pNext = pItem->Next(); - uint8* pData = pItem->Data(pNext->Align()); - if (pData != pItem->Data()) //needs splitting 'cause of alignment? - { - pItem2 = reinterpret_cast(m_NodePool.Allocate(1, 1)); - if (!pItem2) //no free node found for splitting? - { - return; //failed to stack -> return - } - } - - memmove(pData, pNext->Data(), pNext->MemSize()); - - if (pItem2) //was not aligned? - { - //then keep the current ITem - const size_t SizeItem = pItem->MemSize(); - const size_t SizeNext = pNext->MemSize(); - m_Items.AddBehind(pItem2, pNext); - pItem2->Data(pData + SizeNext); - pNext->Data(pData); - pItem2->MemSize(pItem2->Next()->Data() - pItem2->Data()); - pNext->MemSize(SizeNext); - pItem->MemSize(pNext->Data() - pItem->Data()); - m_Items.Validate(pItem); - m_Items.Validate(pItem2); - m_Items.Validate(pNext); - } - else - { - const size_t SizeItem = pItem->MemSize(); - const size_t SizeNext = pNext->MemSize(); - m_Items.Remove(pItem); - m_Items.AddBehind(pItem, pNext); - pItem->Data(pNext->Data()); - pNext->Data(pData); - pNext->MemSize(SizeItem); - pItem->MemSize(SizeNext); - m_Items.Validate(pItem); - m_Items.Validate(pNext); - } - } - public: - ILINE CReferenced() - : m_Allocated(0) - { - } - - ILINE void InitMem(const size_t S = 0, uint8* pData = 0) - { - TMemory::InitMem(S, pData); - if (!TMemory::MemSize()) - { - return; - } - pData = TMemory::Data(); - CListItemReference* pItem = reinterpret_cast(m_NodePool.Allocate(1, 1)); - CListItemReference* pLast = reinterpret_cast(m_NodePool.Allocate(1, 1)); - m_Items.AddFirst(pItem); - m_Items.AddLast(pLast); - pLast->Init(pData + TMemory::MemSize(), 0, pItem, 0); - pLast->InUse(0); - pItem->Init(pData, TMemory::MemSize(), 0, pLast); - pItem->Free(); - m_pEmpty = pItem; - m_Allocated = 0; - } - - ILINE size_t FragmentCount() const - { - return m_Items.Count(); - } - - ILINE CListItemReference* Split(CListItemReference* pItem, size_t Size, size_t Align) - { - size_t Offset = reinterpret_cast(pItem->Data()); - if (!(Offset & (Align - 1))) //perfectly aligned? - { - if (pItem->MemSize() != Size) //not perfectly fitting? - { //then split - CListItemReference* pItemPrev = reinterpret_cast(m_NodePool.Allocate(1, 1)); - if (!pItemPrev) - { - return 0; - } - const size_t OrgSize = pItem->MemSize(); - m_Items.AddBefore(pItemPrev, pItem); - pItemPrev->Data(pItem->Data()); - pItem->Data(pItem->Data() + Size); - pItem->MemSize(OrgSize - Size); - pItemPrev->MemSize(Size); - pItem = pItemPrev; - } - return pItem; - } - - //not aligned to block start - //then lets try to align to block end - Offset += pItem->MemSize(); //ptr to end - Offset -= Size; //minus size - if (!(Offset & (Align - 1))) //perfectly aligned? - { - CListItemReference* pItemPrev = reinterpret_cast(m_NodePool.Allocate(1, 1)); - if (!pItemPrev) - { - return 0; - } - const size_t OrgSize = pItem->MemSize(); - m_Items.AddBefore(pItemPrev, pItem); - pItemPrev->Data(pItem->Data()); - pItem->Data(reinterpret_cast(Offset)); - pItemPrev->MemSize(OrgSize - Size); - pItem->MemSize(Size); - pItemPrev->Free(); - return pItem; - } - //last resort, fragment it into 3 parts - - //Size +=Offset&(Align-1); //adjust size to fit required alignment - Offset -= Offset & (Align - 1); - - CListItemReference* pItemPrev = reinterpret_cast(m_NodePool.Allocate(1, 1)); - CListItemReference* pItemNext = reinterpret_cast(m_NodePool.Allocate(1, 1)); - if (!pItemPrev || !pItemNext) - { - return 0; - } - const size_t OrgSize = pItem->MemSize(); - - m_Items.AddBefore(pItemPrev, pItem); - m_Items.AddBehind(pItemNext, pItem); - - pItemPrev->Data(pItem->Data()); - pItem->Data(reinterpret_cast(Offset)); - pItemNext->Data(pItem->Data() + Size); - pItemPrev->MemSize(pItem->Data() - pItemPrev->Data()); - pItemNext->MemSize(OrgSize - pItemPrev->MemSize() - Size); - pItem->MemSize(Size); - - pItemPrev->Free(); - pItemNext->Free(); - return pItem; - } - - ILINE void Merge(CListItemReference* pItem) - { - m_Items.Validate(pItem); - - //merge with next if possible - CListItemReference* pItemNext = pItem->Next(); - if (pItemNext && pItemNext->IsFree()) - { - if (m_pEmpty == pItemNext) - { - m_pEmpty = pItem; - } - const size_t OrgSize = pItem->MemSize(); - const size_t NextSize = pItemNext->MemSize(); - m_Items.Remove(pItemNext); - pItem->MemSize(OrgSize + NextSize); - m_NodePool.Free(pItemNext); - } - //merge with prev if possible - CListItemReference* pItemPrev = pItem->Prev(); - if (pItemPrev && pItemPrev->IsFree()) - { - if (m_pEmpty == pItem) - { - m_pEmpty = pItemPrev; - } - const size_t OrgSize = pItem->MemSize(); - const size_t PrevSize = pItemPrev->MemSize(); - m_Items.Remove(pItem); - pItemPrev->MemSize(PrevSize + OrgSize); - m_NodePool.Free(pItem); - } - } - - template - ILINE T Resolve(const uint32 ID) - { - CPA_ASSERT(ID); //0 is invalid - return reinterpret_cast(Item(ID)->Data()); - } - - ILINE uint32 AddressToHandle(void* pData) - { - for (CListItemReference* pItem = m_Items.First(); pItem; pItem = pItem->Next()) - { - if (pItem->Data() == pData) - { - return Handle(pItem); - } - } - return 0; - } - - template - ILINE size_t Size(T ID) const - { - CPA_ASSERT(ID); //0 is invalid - return Item(ID)->MemSize(); - } - template - bool InBounds([[maybe_unused]] T ID, [[maybe_unused]] const bool Check) const - { - //boundscheck doesn't work for Referenced containers - return true; - } - - template - ILINE bool Free(T ID, bool ForceBoundsCheck = false) - { - IF (!ID, false) - { - return true; - } - IF (!InBounds(ID, BoundsCheck | ForceBoundsCheck), false) - { - return false; - } - - CListItemReference* pItem = Item(ID); - FreedMemory(pItem->MemSize()); - pItem->Free(); - Merge(pItem); - return true; - } - - ILINE bool Beat(){return false; }//dummy beat in case no defragmentator is wraping - - ILINE size_t MemFree() const{return TMemory::MemSize() - m_Allocated; } - - ILINE size_t MemSize() const{return TMemory::MemSize(); } - - ILINE uint32 Handle(CListItemReference* pItem) const - { - return static_cast(pItem - &m_NodePool[0]); - } - ILINE CListItemReference* Item(uint32 ID) - { - return &m_NodePool[ID]; - } - ILINE const CListItemReference* Item(uint32 ID) const - { - return &m_NodePool[ID]; - } - ILINE static bool Defragmentable(){return true; } - - - - template - ILINE bool ReSize(T* pData, size_t SizeNew) - { - CListItemReference* pItem = Item(*pData); - const size_t SizeOld = pItem->MemSize(); - - //reduction - if (SizeOld > SizeNew) - { - if (pItem->Next()->IsFree()) - { - CListItemReference* pNext = pItem->Next(); - const size_t NextSize = pNext->MemSize(); - pNext->Data(pNext->Data() + SizeNew - SizeOld); - pNext->MemSize(NextSize - SizeNew + SizeOld); - pItem->MemSize(SizeNew); - return true; - } - - //split - CListItemReference* pItemNext = reinterpret_cast(m_NodePool.Allocate(1, 1)); - m_Items.AddBehind(pItemNext, pItem); - pItemNext->Data(pItem->Data() + SizeNew); - pItem->MemSize(SizeNew); - pItemNext->MemSize(SizeOld - SizeNew); - pItemNext->Free(); - return true; - } - - //SizeOldNext(); - const size_t SizeNext = pNext->IsFree() ? pNext->MemSize() : 0; - if (SizeNew <= SizeNext + SizeOld) - { - if (SizeNew == SizeNext + SizeOld) - { - m_Items.Remove(pNext); - m_NodePool.Free(pNext); - } - else - { - pNext->Data(pNext->Data() + SizeNew - SizeOld); - pNext->MemSize(SizeNext - SizeNew + SizeOld); - } - pItem->MemSize(SizeNew); - return true; - } - return false; //no further in-place realloc possible - } - }; -} - - - - - - - -#endif // CRYINCLUDE_CRYPOOL_CONTAINER_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Defrag.h b/Code/CryEngine/CryCommon/CryPool/Defrag.h deleted file mode 100644 index 51fe6fabfb..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Defrag.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_DEFRAG_H -#define CRYINCLUDE_CRYPOOL_DEFRAG_H -#pragma once - - -namespace NCryPoolAlloc -{ - template - class CDefragStacked - : public T - { - template - ILINE bool DefragElement(TItem* pItem) - { - T::m_Items.Validate(); - if (pItem) - { - for (; pItem->Next(); pItem = pItem->Next()) - { - if (!pItem->IsFree()) - { - continue; - } - if (pItem->Next()->Locked()) - { - continue; - } - if (!pItem->Available(pItem->Next()->Align(), pItem->Next()->Align())) - { - continue; - } - T::m_Items.Validate(pItem); - Stack(pItem); - T::m_Items.Validate(pItem); - Merge(pItem); - T::m_Items.Validate(); - return true; - } - } - return false; - } - public: - ILINE bool Beat() - { - return T::Defragmentable() && DefragElement(T::m_Items.First()); - }; - }; -} - - -#endif // CRYINCLUDE_CRYPOOL_DEFRAG_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Fallback.h b/Code/CryEngine/CryCommon/CryPool/Fallback.h deleted file mode 100644 index 4a2babce1a..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Fallback.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_FALLBACK_H -#define CRYINCLUDE_CRYPOOL_FALLBACK_H -#pragma once - - -namespace NCryPoolAlloc -{ - enum EFallbackMode - { - EFM_DISABLED, - EFM_ENABLED, - EFM_ALWAYS - }; - template - class CFallback - : public TAllocator - { - EFallbackMode m_Fallback; - public: - ILINE CFallback() - : m_Fallback(EFM_DISABLED) - { - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - if (EFM_ALWAYS == m_Fallback) - { - return reinterpret_cast(CPA_ALLOC(Align, Size)); - } - T pRet = TAllocator::template Allocate(Size, Align); - if (!pRet && EFM_ENABLED == m_Fallback) - { - return reinterpret_cast(CPA_ALLOC(Align, Size)); - } - return pRet; - } - - template - ILINE bool Free(T Handle) - { - if (!Handle) - { - return true; - } - if (EFM_ALWAYS == m_Fallback) - { - CPA_FREE(Handle); - return true; - } - - if (EFM_ENABLED == m_Fallback && TAllocator::InBounds(Handle, true)) - { - CPA_FREE(Handle); - return true; - } - return TAllocator::template Free(Handle); - } - - void FallbackMode(EFallbackMode M){m_Fallback = M; } - EFallbackMode FallbaclMode() const{return m_Fallback; } - }; -} - - -#endif // CRYINCLUDE_CRYPOOL_FALLBACK_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Inspector.h b/Code/CryEngine/CryCommon/CryPool/Inspector.h deleted file mode 100644 index 1d16095828..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Inspector.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_INSPECTOR_H -#define CRYINCLUDE_CRYPOOL_INSPECTOR_H -#pragma once - - -namespace NCryPoolAlloc -{ - template - class CInspector - : public TAllocator - { - enum - { - EITableSize = 30 - }; - size_t m_Allocations[EITableSize]; - size_t m_Alignment[EITableSize]; - char m_LogFileName[1024]; - size_t m_AllocCount; - size_t m_FreeCount; - size_t m_ResizeCount; - size_t m_FailAllocCount; - size_t m_FailFreeCount; - size_t m_FailResizeCount; - - void WriteOut(const char* pFileName, uint32 Stack, const char* pFormat, ...) const - { - /* - if(!pFileName) - { - if(!*m_LogFileName) - return; - pFileName = m_LogFileName; - } - FILE* File = fopen(pFileName,"a"); - if(File) - { - - char Buffer[1024]; - for(uint32 a=0;a>= 1; - while (C) - { - Count++; - C >>= 1; - } - return Count >= EITableSize ? EITableSize - 1 : Count; - } - public: - CInspector() - { - for (size_t a = 0; a < EITableSize; a++) - { - m_Allocations[a] = m_Alignment[a] = 0; - } - - m_LogFileName[0] = 0; - m_AllocCount = 0; - m_FreeCount = 0; - m_ResizeCount = 0; - m_FailAllocCount = 0; - m_FailFreeCount = 0; - m_FailResizeCount = 0; - } - - bool LogFileName(const char* pFileName) - { - const size_t Size = strlen(pFileName) + 1; - if (Size > sizeof(m_LogFileName)) - { - m_LogFileName[0] = 0; - return false; - } - memcpy(m_LogFileName, pFileName, Size); - WriteOut(0, "[log start]\n"); - return true; - } - void SaveStats(const char* pFileName) const - { - WriteOut(pFileName, 0, "stats:\n"); - - WriteOut(pFileName, 1, "Counter calls|fails\n"); - WriteOut(pFileName, 2, "Alloc: %6d|%6d\n", m_AllocCount, m_FailAllocCount); - WriteOut(pFileName, 2, "Free: %6d|%6d\n", m_FreeCount, m_FailFreeCount); - WriteOut(pFileName, 2, "Resize:%6d|%6d\n", m_ResizeCount, m_FailResizeCount); - - WriteOut(pFileName, 1, "Allocations:\n"); - for (size_t a = 0; a < EITableSize; a++) - { - WriteOut(pFileName, 2, "%9dByte: %8d\n", 1 << a, m_Allocations[a]); - } - - WriteOut(pFileName, 1, "Alignment:\n"); - for (size_t a = 0; a < EITableSize; a++) - { - WriteOut(pFileName, 2, "%9dByte: %8d\n", 1 << a, m_Alignment[a]); - } - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - m_AllocCount++; - m_Allocations[Bit(Size)]++; - m_Alignment[Bit(Align)]++; - T pData = TAllocator::template Allocate(Size, Align); - WriteOut(0, 0, "[A|%d|%d|%d]", (int)pData, Size, Align); - if (!pData) - { - m_FailAllocCount++; - WriteOut(0, 0, "[failed]", Size, Align); - } - return pData; - } - - - template - ILINE bool Free(T pData, bool ForceBoundsCheck = false) - { - m_FreeCount++; - const bool Ret = TAllocator::Free(pData, ForceBoundsCheck); - WriteOut(0, 0, "[F|%d|%d|%d]", (int)pData, (int)ForceBoundsCheck, (int)Ret); - m_FailFreeCount += !Ret; - return Ret; - } - //template - //ILINE bool Free(T pData) - // { - // m_FreeCount++; - // const bool Ret = TAllocator::Free(pData); - // WriteOut(0,0,"[F|%d|%d|%d]",(int)pData,(int)-1,(int)Ret); - // m_FailFreeCount+=!Ret; - // return Ret; - // } - - template - ILINE bool Resize(T** pData, size_t Size, size_t Alignment) - { - m_ResizeCount++; - const bool Ret = TAllocator::Resize(pData, Size, Alignment); - WriteOut(0, 0, "[R|%d|%d|%d]", (int)*pData, (int)-1, (int)Ret); - m_FailResizeCount += !Ret; - return Ret; - } - - template - ILINE size_t FindBiggest(const T* pItem) - { - size_t Biggest = 0; - while (pItem) - { - if (pItem->IsFree() && pItem->MemSize() > Biggest) - { - Biggest = pItem->MemSize(); - } - pItem = pItem->Next(); - } - return Biggest; - } - - ILINE size_t BiggestFreeBlock() - { - return FindBiggest(TAllocator::m_Items.First()); - } - - ILINE uint8* FirstItem() - { - return TAllocator::m_Items.First()->Data(); - } - }; -} - - - - -#endif // CRYINCLUDE_CRYPOOL_INSPECTOR_H - diff --git a/Code/CryEngine/CryCommon/CryPool/List.h b/Code/CryEngine/CryCommon/CryPool/List.h deleted file mode 100644 index 5c4588d40c..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/List.h +++ /dev/null @@ -1,366 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_LIST_H -#define CRYINCLUDE_CRYPOOL_LIST_H -#pragma once - -namespace NCryPoolAlloc -{ - class CListItemInPlace; - class CListItemReference; - - template - class CListItem - { - TItem* m_pPrev; - TItem* m_pNext; - public: - - ILINE TItem* Prev(){return m_pPrev; } - ILINE TItem* Next(){return m_pNext; } - ILINE const TItem* Prev() const{return m_pPrev; } - ILINE const TItem* Next() const{return m_pNext; } - ILINE void Prev(TItem* pPrev){ m_pPrev = pPrev; } - ILINE void Next(TItem* pNext){ m_pNext = pNext; } - - //debugging - void Validate(); - }; - - template - class CListItemFlagged - : public CListItem - { - enum - { - ELIF_INUSE = (1 << 0), - ELIF_LOCKED = (1 << 1), - }; - uint32 m_Flags : 8; - uint32 m_Align : 24; - public: - ILINE CListItemFlagged() - : m_Flags(0) - { - } - ILINE bool IsFree() const{return (m_Flags & ELIF_INUSE) != ELIF_INUSE; } - ILINE void Free(){m_Flags &= ~ELIF_INUSE; } - ILINE void InUse(uint32 A){m_Flags |= ELIF_INUSE; m_Align = A; } - ILINE bool Locked() const{return ELIF_LOCKED == (m_Flags & ELIF_LOCKED); } - ILINE void Lock(){m_Flags |= ELIF_LOCKED; } - ILINE void Unlock(){m_Flags &= ~ELIF_LOCKED; } - ILINE uint32 Align() const{return m_Align; } - }; - - class CListItemInPlace - : public CListItemFlagged - { - public: - ILINE void Init([[maybe_unused]] uint8* pData, [[maybe_unused]] size_t Size, CListItemInPlace* pPrev, CListItemInPlace* pNext) - { - Prev(pPrev); - Next(pNext); - CPA_ASSERT(Size == MemSize()); - } - - ILINE bool Available(size_t Size, size_t Align) const - { - size_t Offset = reinterpret_cast(Data()); - if (Offset & (Align - 1)) //not aligned? - { - Size += sizeof(CListItemInPlace) + Align - 1; //then an intermedian node needs to fit - } - return Size <= MemSize() && IsFree(); - } - ILINE uint8* Data(){return reinterpret_cast(this) + sizeof(CListItemInPlace); } - ILINE const uint8* Data() const{return reinterpret_cast(this) + sizeof(CListItemInPlace); } - ILINE size_t MemSize() const - { - const uint8* pNext = reinterpret_cast(Next()); - const uint8* pThis = reinterpret_cast(this); - const size_t ESize = sizeof(CListItemInPlace); - size_t Delta = pNext - pThis; - Delta -= ESize; - return Delta; - } - }; - - class CListItemReference - : public CListItemFlagged - { - uint8* m_pData; - // size_t m_Size; - public: - ILINE void Init(uint8* pData, size_t Size, CListItemReference* pPrev, CListItemReference* pNext) - { - Data(pData); - Prev(pPrev); - Next(pNext); - MemSize(Size); - } - ILINE bool Available(size_t Size, size_t Align) const - { - size_t Offset = reinterpret_cast(Data()); - if ((Offset & (Align - 1))) - { - Size += Align - (Offset & (Align - 1)); - } - return Size <= MemSize() && IsFree(); - } - ILINE void Data(uint8* pData){m_pData = pData; } - ILINE uint8* Data(size_t Align) - { - Align--; - size_t Offset = reinterpret_cast(m_pData); - Offset = (Offset + Align) & ~Align; - return reinterpret_cast(Offset); - } - ILINE uint8* Data(){return m_pData; } - ILINE const uint8* Data() const{return m_pData; } - ILINE void MemSize([[maybe_unused]] size_t Size) { } - ILINE size_t MemSize() const - { - const size_t T = reinterpret_cast(Data()); - const size_t N = Next() ? reinterpret_cast(Next()->Data()) : T; - return N - T; - } - //ILINE void MemSize(size_t Size){m_Size=Size;} - //ILINE size_t MemSize()const{return m_Size;} - }; - - template - class CList - { - TItem* m_pFirst; - TItem* m_pLast; - size_t m_Count; - public: - ILINE CList() - : m_pFirst(0) - , m_pLast(0) - , m_Count(0) - { - } - - ILINE void First(TItem* pItem){m_pFirst = pItem; } - ILINE TItem* First(){return m_pFirst; } - ILINE void Last(TItem* pItem){m_pLast = pItem; } - ILINE TItem* Last(){return m_pLast; } - ILINE bool Empty() const{return m_pFirst == 0; } - - ILINE TItem* PopFirst() - { - Validate(); - - if (!m_pFirst) - { - return 0; - } - - TItem* pRet = m_pFirst; - - m_pFirst = m_pFirst->Next(); - - if (m_pFirst) //if any element exists - { - m_pFirst->Prev(0); //set prev ptr of this element to 0 - } - else - { - m_pLast = 0; //set ptr to last element to 0 if ptr to first is zero as well - } - Validate(); - m_Count--; - return pRet; - } - - ILINE TItem* PopLast() - { - Validate(); - - if (!m_pLast) - { - return 0; - } - - TItem* pRet = m_pLast; - - m_pLast = m_pLast->Prev(); - - if (m_pLast) //if any element exists - { - m_pLast->Next(0); //set prev ptr of this element to 0 - } - else - { - m_pFirst = 0; //set ptr to last element to 0 if ptr to first is zero as well - } - Validate(); - m_Count--; - return pRet; - } - - ILINE void AddFirst(TItem* pItem) - { - CPA_ASSERT(pItem); //ERROR AddFirst got 0 pointer - - Validate(); - - pItem->Prev(0); - pItem->Next(m_pFirst); - if (!m_pFirst) - { - m_pLast = pItem; - } - else - { - m_pFirst->Prev(pItem); - } - m_pFirst = pItem; - - m_Count++; - Validate(); - } - - ILINE void AddLast(TItem* pItem) - { - CPA_ASSERT(pItem); //ERROR AddLast got 0 pointer - - Validate(); - - pItem->Prev(m_pLast); - pItem->Next(0); - if (!m_pLast) - { - m_pFirst = pItem; - } - else - { - m_pLast->Next(pItem); - } - m_pLast = pItem; - - m_Count++; - Validate(); - } - ILINE void AddBefore(TItem* pItem, TItem* pItemSuccessor) - { - CPA_ASSERT(pItem); - CPA_ASSERT(pItemSuccessor); - - Validate(); - - pItem->Next(pItemSuccessor); - pItem->Prev(pItemSuccessor->Prev()); - pItemSuccessor->Prev(pItem); - - if (pItemSuccessor == m_pFirst) - { - m_pFirst = pItem; - } - else - { - pItem->Prev()->Next(pItem); - } - - m_Count++; - Validate(); - } - ILINE void AddBehind(TItem* pItem, TItem* pItemPredecessor) - { - CPA_ASSERT(pItem); - CPA_ASSERT(pItemPredecessor); - - Validate(); - - pItem->Next(pItemPredecessor->Next()); - pItem->Prev(pItemPredecessor); - pItemPredecessor->Next(pItem); - - if (pItemPredecessor == m_pLast) - { - m_pLast = pItem; - } - else - { - pItem->Next()->Prev(pItem); - } - - m_Count++; - Validate(); - } - - ILINE void Remove(TItem* pItem) - { - CPA_ASSERT(pItem); //ERROR releasing empty item - - if (pItem == m_pFirst) - { - PopFirst(); - return; - } - if (pItem == m_pLast) - { - PopLast(); - return; - } - - Validate(pItem); - - pItem->Prev()->Next(pItem->Next()); - pItem->Next()->Prev(pItem->Prev()); - - m_Count--; - Validate(); - } - - //debug - ILINE void Validate(TItem* pReferenceItem = 0) - { - if (!VALIDATE) - { - return; - } - - //one-sided empty? - CPA_ASSERT((!First() && !Last()) || (First() && Last())); //ERROR validating item-list, just one end is 0 - - // endles linking? - TItem* pPrev = 0; - TItem* pItem = First(); - while (pItem) - { - if (pReferenceItem == pItem) - { - pReferenceItem = 0; - } - CPA_ASSERT(pPrev == pItem->Prev()); //ERROR validating item-list, endless linking NULL - pPrev = pItem; - pItem = pItem->Next(); - } - - CPA_ASSERT(pPrev == Last()); //ERROR validating item-list, broken list, does not end at specified Last item - CPA_ASSERT(!pReferenceItem); //ERROR reference item not found in the item-list - } - ILINE size_t Count() const{return m_Count; } - }; -} - - - - - - -#endif // CRYINCLUDE_CRYPOOL_LIST_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Memory.h b/Code/CryEngine/CryCommon/CryPool/Memory.h deleted file mode 100644 index 43daaaeada..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Memory.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_MEMORY_H -#define CRYINCLUDE_CRYPOOL_MEMORY_H -#pragma once - -namespace NCryPoolAlloc -{ - class CMemoryDynamic - { - size_t m_Size; - uint8* m_pData; - - protected: - ILINE CMemoryDynamic() - : m_Size(0) - , m_pData(0){} - - public: - ILINE void InitMem(const size_t S, uint8* pData) - { - m_Size = S; - m_pData = pData; - CPA_ASSERT(S); - CPA_ASSERT(pData); - } - - ILINE size_t MemSize() const{return m_Size; } - ILINE uint8* Data(){return m_pData; } - ILINE const uint8* Data() const{return m_pData; } - }; - - template - class CMemoryStatic - { - uint8 m_Data[TSize]; - - protected: - ILINE CMemoryStatic() - { - } - public: - ILINE void InitMem(const size_t S, uint8* pData) - { - } - ILINE size_t MemSize() const{return TSize; } - ILINE uint8* Data(){return m_Data; } - ILINE const uint8* Data() const{return m_Data; } - }; -} - - - - - - - -#endif // CRYINCLUDE_CRYPOOL_MEMORY_H - diff --git a/Code/CryEngine/CryCommon/CryPool/PoolAlloc.h b/Code/CryEngine/CryCommon/CryPool/PoolAlloc.h deleted file mode 100644 index 23eda51a2a..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/PoolAlloc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#if defined(POOLALLOCTESTSUIT) -//cheat just for unit testing on windows -#include "BaseTypes.h" -#define ILINE inline -#endif - -// Traits -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(CryPool/PoolAlloc_h) -#elif defined(APPLE) || defined(LINUX) -#define POOLALLOC_H_TRAIT_USE_MEMALIGN 1 -#endif - - -#if POOLALLOC_H_TRAIT_USE_MEMALIGN -#define CPA_ALLOC memalign -#define CPA_FREE free -#else -#define CPA_ALLOC _aligned_malloc -#define CPA_FREE _aligned_free -#endif -#define CPA_ASSERT assert -#define CPA_ASSERT_STATIC(X) {uint8 assertdata[(X) ? 0 : 1]; } -#define CPA_BREAK __debugbreak() - -#include "List.h" -#include "Memory.h" -#include "Container.h" -#include "Allocator.h" -#include "Defrag.h" -#include "STLWrapper.h" -#include "Inspector.h" -#include "Fallback.h" -#if !defined(POOLALLOCTESTSUIT) -#include "ThreadSafe.h" -#endif - -#undef CPA_ASSERT -#undef CPA_ASSERT_STATIC -#undef CPA_BREAK diff --git a/Code/CryEngine/CryCommon/CryPool/STLWrapper.h b/Code/CryEngine/CryCommon/CryPool/STLWrapper.h deleted file mode 100644 index cb06ced1a4..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/STLWrapper.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_STLWRAPPER_H -#define CRYINCLUDE_CRYPOOL_STLWRAPPER_H -#pragma once - -namespace NCryPoolAlloc -{ - //namespace CSTLPoolAllocWrapperHelper - //{ - // inline void destruct(char *) {} - // inline void destruct(wchar_t*) {} - // template - // inline void destruct(T *t) {t->~T();} - //} - - //template - //struct CSTLPoolAllocWrapperStatic - //{ - // static PoolAllocator * allocator; - //}; - - //template - //struct CSTLPoolAllocWrapperKungFu : public CSTLPoolAllocWrapperStatic - //{ - //}; - - template - class CSTLPoolAllocWrapper - { - private: - static TCont* m_pContainer; - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - static TCont* Container(){return m_pContainer; } - static void Container(TCont* pContainer){m_pContainer = pContainer; } - - - template - struct rebind - { - typedef CSTLPoolAllocWrapper other; - }; - - CSTLPoolAllocWrapper() throw() - { - } - - CSTLPoolAllocWrapper(const CSTLPoolAllocWrapper&) throw() - { - } - - template - CSTLPoolAllocWrapper(const CSTLPoolAllocWrapper&) throw() - { - } - - ~CSTLPoolAllocWrapper() throw() - { - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate(size_type n = 1, const_pointer hint = 0) - { - TCont* pContainer = Container(); - uint8* pData = pContainer->TCont::template Allocate(n * sizeof(T), sizeof(T)); - return pContainer->TCont::template Resolve(pData); - // return Container()?Container()->Allocate(n*sizeof(T),sizeof(T)):0 - } - - void deallocate(pointer p, size_type n = 1) - { - if (Container()) - { - Container()->Free(p); - } - } - - size_type max_size() const throw() - { - return Container() ? Container()->MemSize() : 0; - } - - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } - - void destroy(pointer p) - { - p->~T(); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const CSTLPoolAllocWrapper&) {return true; } - bool operator!=(const CSTLPoolAllocWrapper&) {return false; } - }; -} - -#endif // CRYINCLUDE_CRYPOOL_STLWRAPPER_H - diff --git a/Code/CryEngine/CryCommon/CryPool/ThreadSafe.h b/Code/CryEngine/CryCommon/CryPool/ThreadSafe.h deleted file mode 100644 index 5ae7dbd4bc..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/ThreadSafe.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_THREADSAFE_H -#define CRYINCLUDE_CRYPOOL_THREADSAFE_H -#pragma once - - -#include - -namespace NCryPoolAlloc -{ - template - class CThreadSafe - : public TAllocator - { - CryCriticalSection m_Mutex; - public: - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - CryAutoLock lock(m_Mutex); - return TAllocator::template Allocate(Size, Align); - } - - - template - ILINE bool Free(T pData, bool ForceBoundsCheck = false) - { - CryAutoLock lock(m_Mutex); - return TAllocator::Free(pData, ForceBoundsCheck); - } - - template - ILINE bool Resize(T** pData, size_t Size, size_t Alignment) - { - CryAutoLock lock(m_Mutex); - return TAllocator::Resize(pData, Size, Alignment); - } - }; -} - - - - -#endif // CRYINCLUDE_CRYPOOL_THREADSAFE_H - diff --git a/Code/CryEngine/CryCommon/CryPool/example.h b/Code/CryEngine/CryCommon/CryPool/example.h deleted file mode 100644 index e17d5abee2..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/example.h +++ /dev/null @@ -1,287 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_EXAMPLE_H -#define CRYINCLUDE_CRYPOOL_EXAMPLE_H -#pragma once - - -//The documentation is split up into 3 main parts, so strg+f for -// -Theory -// -Building blocks -// -Usage -// -FAQ -// -Realloc/Resize - -///////////////////////////////////////////////////////////////////////// -// -Theory -///////////////////////////////////////////////////////////////////////// - - -//this includes the 3 major parts of the allocate suite -//1. the memory location templates -//2. container types -//3. some allocator version -//addtional you get -//4. a simple stack based defragmentation template -//5. helper - -//1. memory location templates -// There are two types of them, static and dynamic -//1.1 CMemoryStatic allows you do define on compile time what size -// it should have, suitable for pool you know that they won't grow or -// shrink -//1.2 CMemoryDynamic, this one has no template parameter, it has just one -// indirection via ptr to the memory location and size, that you will -// set during initialization. - -//2. Container types -// We have also two container types, one so called "In Place" -// and one "Referenced". -//2.1 "In Place" means that a header is placed above every allocation, -// this is the usual way most allocators work. -//2.2 "Referenced", has an extra pool of headers that point to the actual -// memory. This is suitable for -// - external memory locations that are not directly accessable by the -// cpu. E.g. pools on disk, networks, rsx memory.. -// - defragmentation, because you don't save a ptr to the real memory -// location, just a "handle" of the referencing item. -// - big alignments, having 4kb of alignment would waste also -// - 4kb for ever "In Place" header, you might not want that. - -//3. Allocators -// This time we have 3 of them, "BestFit", "WorstFit" and "FirstFit" -//3.1 FirstFit just seeks for any location big enought to fit your -// requested size of memory. Internally it also saves the last used -// free memory area to speed up allocations. -// Use this also if you have just one particular allocation size. -//3.2 WorstFit, although it might sound illogical, WorstFit can reduce -// memory fragmentation in a cases with very random allocation sizes, -// because it gives smaller free blocks the chance to concatenate to -// bigger free blocks again while filling up those previously -// generated big blocks. The bad side is that it takes quite some time -// to find the biggest block as this needs to be done every time you -// allocate, so use this just when having a low amount of allocations -// or you're really desperately looking for mem. -//3.3 BestFit, it's best used if you don't have just one allocation size, -// but still very few varying sizes. Previously released blocks of -// the currently allocating sizes will be seeked and reused, this -// strongly helps to reduce fragmentation. While this might be slow -// in some cases, it can save you from doing any defragmentation. - -//4. Defragmentation -// At the moment just one defragmentation algorithm is implemented: -// "Stack defragmentator" -// If you don't want some block to be moved, "Lock" it using your -// memory handle. -//4.1 Stack based -// To reduce fragmentation, holes are filled up with the next used, -// memory area. This defragmentation sheme is useful when you have -// some long living locations as well as very short living ones. -// At some point all long live memory will end up at the bottom of -// the stack, while leaving empty memory areas at the top for short -// living allocations. - -//5. Helper -// this should be filled up with some handy helper tools for this -// pool suite. -// The first tool is a wrapper for the usage with stl -//5.1 Wrapper for STL -// As you know, you can pass your own allocator as the last -// parameter of stl containers, with this helper you can use a pool -// created with this suite and wrap it for the stl. - - -///////////////////////////////////////////////////////////////////////// -// -Building blocks -///////////////////////////////////////////////////////////////////////// - -//That's the theory, so how does it work? -//It's pretty simple, you compose the pool of your dreams by cascading -//templates. -//Lets start with an exmaple -//Per level you want to allocate a fixed amount of memory for your -//textures. -CMemoryDynamic -//- They are placed in some memory you can access directly with the cpu: -CInPlace -//- and you don't want to defragmentate, so you prefer an allocation -// sheme that reduces fragmentation. - CBestFit -//now you combine them -typedef CBestFit, CListItemInPlace> TMyOwnPool; - -//Yes, it's that simple. -//ok, ok, texture memory is usually nothing you want to access directly -//with your cpu, so let's create a referencing pool. Therefor you need -//to also specify how many nodes that can reference your pool will have. -//We won't have more than 4000 textures, so let's start with -{ - enum TEXTURE_NODE_COUNT = 4096 -}; -//and now our referencing pool -typedef CBestFit < CReferenced TMyOwnPool; - -//But yeah, you're right, texture memory has also a fixed size, lets -//assume it's 128MB. -{ - enum TEXTURE_MEMORY_SIZE = 128 * 1024 * 1024 -}; -//and our fixed sized memory pool -typedef CBestFit < CReferenced, TEXTURE_NODE_COUNT> TMyOwnPool; - -//ok, but you don't trust the best fit allocator in all cases, you prefer -//a fast one and you accept the slow down for defragmentation incase the -//allocation fails. -//So lets created a straight First Fit allocator with defragmentation: -typedef CDefragStacked < CFirstFit, TEXTURE_NODE_COUNT> > TMyOwnPool; - -//here you see how simple you can add defragmentation, but be careful, it -//works of course just on Reference based memory containers, if you have -//Direct pointers to In Place allocation, we cannot shuffle them around. - - -///////////////////////////////////////////////////////////////////////// -// -Usage -///////////////////////////////////////////////////////////////////////// - - -//it all starts by including the meain header -#include "PoolAlloc.h" - -//Define your dream allocator, preferably using a typedef (or macro) -typedef CBestFit, CListItemInPlace> TMyOwnPool; -//also typedef (or macro) your handle -typedef uint8* TMyHandle; //in case of "In Place" allocations -typedef uint32 TMyHandle; //in case of "Referenced" - -//Instantiate it -TMyOwnPool g_MyMemory; - -//now you need to initialize it, -g_MyMemory.InitMem(pMemoryArea, MemorySize); //in case you use "CMemoryDynamic" -g_MyMemory.InitMem(); //in case you use "CmemoryStatic, -//altough you could pass the same -//parameters, they'd be ignored. -//Use this also to flush the pool -//quickly - - -//now allocate -TMyHandle MemID = g_MyMemory.Allocate(Size); -//optionally alignment can be passed as 2nd parameter -TMyHandle MemID = g_MyMemory.Allocate(Size, Align); - -//free it simply by calling -g_Memory.Free(MemID); - -//you might want to call the beat function to defragment the memory -//on regular base -g_Memory.Beat(); -//you might also want to call it just when an allocation failed to -//defragmentate the memory as good as possible -if (!(MemID = g_Memoery.Allocate(Size))) -{ - while (g_Memory.Beat()) - { - ; - } - MemID = g_Memoery.Allocate(Size); -} - -//To acquire the pointer to your data, you need to resolve the handle -MyObject* pObject = g_Memory.Resolve(MemID); - -///////////////////////////////////////////////////////////////////////// -// -Realloc/Resize -///////////////////////////////////////////////////////////////////////// - -// The Containers provide a "resize" function. This one does nothing else -// than the name suggest, it is freeing some memory at the end of your -// allocation or, if free memory is available, allocates some memory to -// the end of your buffer. But it may also fail, if not enough memory -// available to allocate. -// "Realloc" on the other side requires an extra template that you wrap -// around your existing one like: -typedef CReallocator TMyOwnPoolWithReallocation; -// This one will first try to use resize, but in case it fails, it will -// allocate a seperate memory area, copy the data and free the old one. -// -// But this may fail as well, therefor the result is not a pointer to the -// allocation, but true/false. -// There for you need to pass a pointer to your pointer to the memory area -// or handle you deal with. -Handle = rMemory.Allocate(10, 1); -if (!rMemory.Reallocate(&Handles, 11, 1)) -{ - //handle realloc failure -} - - -///////////////////////////////////////////////////////////////////////// -// -FAQ -///////////////////////////////////////////////////////////////////////// - -//"DO I HAVE TO ALWAYS RESOLVE?" -//if you use "In Place" memory, not at all, all resolve does is to -//cast your handle to your object ptr and returns it. -//if you use "Referenced" memory and you don't defragmentate, you -//can do it once and keep the ptr, but you also need to keep the -//handle to free the memory later on. - -//"any reason I should resolve?" -//Yes, first of all, it makes it very easy to switch between various -//pool configuration for testing, you simply change some params of -//your typedef (or macro) and it should work out of the box. -//second, for defragmentation it's the only way to go and for future -//things it might be needed as well - -//"but isn't resolving just overhead?" -//in case of "In Place": no, the resolve function just returns the -//pointer, casting to your wanted type -//in case of "Referenced": it cost you one indirection. - - -//"How do I flush the whole pool without freeing all items?" -g_Memory.InitMem() -//yes, you can call "InitMem" once again, you need to pass the mem -//ptr and size if using CMemoryDynamic e.g. -g_Memory.Init(g_Memory.Size(), g_Memory.Data()); - -//"How do I lock the allocated memory to avoid any reallocation" -g_Memory.Item(ptr)->Lock(); - - -//"How do I get the size of a memory block?" -g_Memory.Item(ptr)->MemSize(); - - - - -//"Is there any example?" -//for a real life example check PAUnitTest.cpp used to validate all -//functions of this pool. - - -//bug reports? questions? support? -//just ask me :) (michael kopietz) - - - - - - - - -#endif // CRYINCLUDE_CRYPOOL_EXAMPLE_H - diff --git a/Code/CryEngine/CryCommon/GeomCacheFileFormat.h b/Code/CryEngine/CryCommon/GeomCacheFileFormat.h deleted file mode 100644 index a8328e8a14..0000000000 --- a/Code/CryEngine/CryCommon/GeomCacheFileFormat.h +++ /dev/null @@ -1,202 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H -#define CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H -#pragma once - -#include "CryExtension/CryGUID.h" - -#if !defined(LINUX) -#pragma pack(push) -#pragma pack(1) -#define PACK_GCC -#else -#define PACK_GCC __attribute__ ((packed)) -#endif - -namespace GeomCacheFile -{ - // Important: The enums are serialized, don't change the values - // without increasing the file version, conversion code etc! - - typedef Vec3_tpl Position; - typedef Vec2_tpl Texcoords; - typedef Vec4_tpl QTangent; - typedef uint8 Color; - - // ASCII "CAXCACHE" - const uint64 kFileSignature = 0x4548434143584143ull; - - // The smallest 'UVmax' we'll support - this avoids division by zero when encoding/decoding UVs - const float kMinUVrange = .01f; - - // Bit Precision of tangents quaternions - const uint kTangentQuatPrecision = 10; - - // Current file version GUID. Files with other GUIDs will not be loaded by the engine. - const CryGUID kCurrentVersion = MAKE_CRYGUID(0x1641defe440af501, 0x7ec5e9164c8c2d1c); - - // Mesh prediction look back array size - const uint kMeshPredictorLookBackMaxDist = 4096; - - // Number of frames between index frames. Needs to be <= g_kMaxBufferedFrames. - const uint kMaxIFrameDistance = 30; - - enum EFileHeaderFlags - { - eFileHeaderFlags_PlaybackFromMemory = BIT(0), - eFileHeaderFlags_32BitIndices = BIT(1) - }; - - enum EBlockCompressionFormat - { - eBlockCompressionFormat_None = 0, - eBlockCompressionFormat_Deflate = 1, // zlib - eBlockCompressionFormat_LZ4HC = 2, // LZ4 HC - eBlockCompressionFormat_ZSTD = 3, //ZStandard - }; - - enum EStreams - { - eStream_Indices = BIT(0), - eStream_Positions = BIT(1), - eStream_Texcoords = BIT(2), - eStream_QTangents = BIT(3), - eStream_Colors = BIT(4) - }; - - enum ETransformType - { - eTransformType_Constant, - eTransformType_Animated - }; - - enum ENodeType - { - eNodeType_Transform = 0, // Transforms all sub nodes - eNodeType_Mesh = 1, - eNodeType_PhysicsGeometry = 2, - }; - - // Common frame - enum EFrameType - { - eFrameType_IFrame = 0, - eFrameType_BFrame = 1 - }; - - // Common frame flags - enum EFrameFlags - { - eFrameFlags_Hidden = BIT(0) - }; - - // Flags for mesh index frames - enum EMeshIFrameFlags - { - eMeshIFrameFlags_UsePredictor = BIT(1) - }; - - struct SHeader - { - SHeader() - : m_signature(0) - , m_version(kCurrentVersion) - , m_blockCompressionFormat(0) - , m_flags(0) - , m_numFrames(0) {} - - uint64 m_signature; - CryGUID m_version; - uint16 m_blockCompressionFormat; - uint32 m_flags; - uint32 m_numFrames; - uint64 m_totalUncompressedAnimationSize; - float m_aabbMin[3]; - float m_aabbMax[3]; - } PACK_GCC; - - struct SFrameInfo - { - uint32 m_frameType; - uint32 m_frameSize; - uint64 m_frameOffset; - float m_frameTime; - } PACK_GCC; - - struct SCompressedBlockHeader - { - uint32 m_uncompressedSize; - uint32 m_compressedSize; - } PACK_GCC; - - struct SFrameHeader - { - uint32 m_nodeDataOffset; - float m_frameAABBMin[3]; - float m_frameAABBMax[3]; - uint32 m_padding; - } PACK_GCC; - - struct STemporalPredictorControl - { - uint8 m_acceleration; - uint8 m_indexFrameLerpFactor; - uint8 m_combineFactor; - uint8 m_padding; - } PACK_GCC; - - struct SMeshFrameHeader - { - uint32 m_flags; - STemporalPredictorControl m_positionStreamPredictorControl; - STemporalPredictorControl m_texcoordStreamPredictorControl; - STemporalPredictorControl m_qTangentStreamPredictorControl; - STemporalPredictorControl m_colorStreamPredictorControl[4]; - } PACK_GCC; - - struct SMeshInfo - { - uint8 m_constantStreams; - uint8 m_animatedStreams; - uint8 m_positionPrecision[3]; - float m_uvMax; - uint8 m_padding; - uint16 m_numMaterials; - uint32 m_numVertices; - uint32 m_flags; - float m_aabbMin[3]; - float m_aabbMax[3]; - uint32 m_nameLength; - uint64 m_hash; - } PACK_GCC; - - struct SNodeInfo - { - uint8 m_type; - uint8 m_bVisible; - uint16 m_transformType; - uint32 m_meshIndex; - uint32 m_numChildren; - uint32 m_nameLength; - } PACK_GCC; -} - -#undef PACK_GCC - -#if !defined(LINUX) -#pragma pack(pop) -#endif - -#endif // CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H diff --git a/Code/CryEngine/CryCommon/IEngineModule.h b/Code/CryEngine/CryCommon/IEngineModule.h deleted file mode 100644 index 7835cde26e..0000000000 --- a/Code/CryEngine/CryCommon/IEngineModule.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Defines the extension interface for the CryEngine modules. - - -#ifndef CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H -#define CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H -#pragma once - -#include -#include -#include -#include - -struct SSystemInitParams; - -// Base Interface for all engine module extensions -struct IEngineModule - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IEngineModule, 0xf899cf661df04f61, 0xa341a8a7ffdf9de4); - - // - // Retrieve name of the extension module. - virtual const char* GetName() const = 0; - - // Retrieve category for the extension module (CryEngine for standard modules). - virtual const char* GetCategory() const = 0; - - // This is called to initialize the new module. - virtual bool Initialize(SSystemGlobalEnvironment& env, const SSystemInitParams& initParams) = 0; - // - - // This is called to register any AZ console vars declared within this engine module - virtual void RegisterConsoleVars() - { - AZ::ConsoleFunctorBase*& deferredHead = AZ::ConsoleFunctorBase::GetDeferredHead(); - AZ::Interface::Get()->LinkDeferredFunctors(deferredHead); - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H diff --git a/Code/CryEngine/CryCommon/IRemoteCommand.h b/Code/CryEngine/CryCommon/IRemoteCommand.h deleted file mode 100644 index 03adb89b44..0000000000 --- a/Code/CryEngine/CryCommon/IRemoteCommand.h +++ /dev/null @@ -1,763 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Service network interface - - -#ifndef CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H -#define CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H -#pragma once - -#include -#include - -//----------------------------------------------------------------------------- -// Helpers for writing/reading command data stream from network message packets. -// Those interfaces automatically handle byteswapping for big endian systems. -// The native format for data inside the messages is little endian. -//----------------------------------------------------------------------------- - -/// Write stream interface -struct IDataWriteStream -{ -public: - virtual ~IDataWriteStream() {}; - -public: - // Virtualized write method for general data buffer - virtual void Write(const void* pData, const uint32 size) = 0; - - // Virtualized write method for types with size 8 (support byteswapping, a little bit faster than general case) - virtual void Write8(const void* pData) = 0; - - // Virtualized write method for types with size 4 (support byteswapping, a little bit faster than general case) - virtual void Write4(const void* pData) = 0; - - // Virtualized write method for types with size 2 (support byteswapping, a little bit faster than general case) - virtual void Write2(const void* pData) = 0; - - // Virtualized write method for types with size 1 (a little bit faster than general case) - virtual void Write1(const void* pData) = 0; - - // Get number of bytes written - virtual const uint32 GetSize() const = 0; - - // Convert to service network message - virtual struct IServiceNetworkMessage* BuildMessage() const = 0; - - // Save the data from this writer stream to the provided buffer - virtual void CopyToBuffer(void* pData) const = 0; - - // Destroy object (if dynamically created) - virtual void Delete() = 0; - -public: - IDataWriteStream& operator<<(const uint8& val) - { - Write1(&val); - return *this; - } - - IDataWriteStream& operator<<(const uint16& val) - { - Write2(&val); - return *this; - } - - IDataWriteStream& operator<<(const uint32& val) - { - Write4(&val); - return *this; - } - - IDataWriteStream& operator<<(const uint64& val) - { - Write8(&val); - return *this; - } - - IDataWriteStream& operator<<(const int8& val) - { - Write1(&val); - return *this; - } - - IDataWriteStream& operator<<(const int16& val) - { - Write2(&val); - return *this; - } - - IDataWriteStream& operator<<(const int32& val) - { - Write4(&val); - return *this; - } - - IDataWriteStream& operator<<(const int64& val) - { - Write8(&val); - return *this; - } - - IDataWriteStream& operator<<(const float& val) - { - Write4(&val); - return *this; - } - - // Bool is saved by writing an 8 bit value to make it portable - IDataWriteStream& operator<<(const bool& val) - { - const uint8 uVal = val ? 1 : 0; - Write1(&uVal); - return *this; - } - -public: - // Write C string to stream - void WriteString(const char* str); - - // Write string to stream - void WriteString(const string& str); - - // Write int8 value to stream - void WriteInt8(const int8 val) - { - Write1(&val); - } - - // Write int16 value to stream - void WriteInt16(const int16 val) - { - Write2(&val); - } - - // Write int32 value to stream - void WriteInt32(const int32 val) - { - Write4(&val); - } - - // Write int64 value to stream - void WriteInt64(const int64 val) - { - Write8(&val); - } - - // Write uint8 value to stream - void WriteUint8(const uint8 val) - { - Write1(&val); - } - - // Write uint16 value to stream - void WriteUint16(const uint16 val) - { - Write2(&val); - } - - // Write uint32 value to stream - void WriteUint32(const uint32 val) - { - Write4(&val); - } - - // Write uint64 value to stream - void WriteUint64(const uint64 val) - { - Write8(&val); - } - - // Write float value to stream - void WriteFloat(const float val) - { - Write4(&val); - } -}; - -//----------------------------------------------------------------------------- - -/// Read stream interface -/// This interface should support endianess swapping -struct IDataReadStream -{ -public: - virtual ~IDataReadStream() {}; - -public: - // Destroy object (if dynamically created) - virtual void Delete() = 0; - - // Skip given amount of data without reading it - virtual void Skip(const uint32 size) = 0; - - // Virtualized read method (for general buffers) - virtual void Read(void* pData, const uint32 size) = 0; - - // Virtualized read method for types with size 8 (a little bit faster than general method, supports byte swapping for BE systems) - virtual void Read8(void* pData) = 0; - - // Virtualized read method for types with size 4 (a little bit faster than general method, supports byte swapping for BE systems) - virtual void Read4(void* pData) = 0; - - // Virtualized read method for types with size 2 (a little bit faster than general method, supports byte swapping for BE systems) - virtual void Read2(void* pData) = 0; - - // Virtualized read method for types with size 1 (a little bit faster than general method, supports byte swapping for BE systems) - virtual void Read1(void* pData) = 0; - - // Optimization case - get direct pointer to the underlying buffer - virtual const void* GetPointer() = 0; - -public: - IDataReadStream& operator<<(uint8& val) - { - Read1(&val); - return *this; - } - - IDataReadStream& operator<<(uint16& val) - { - Read2(&val); - return *this; - } - - IDataReadStream& operator<<(uint32& val) - { - Read4(&val); - return *this; - } - - IDataReadStream& operator<<(uint64& val) - { - Read8(&val); - return *this; - } - - IDataReadStream& operator<<(int8& val) - { - Read1(&val); - return *this; - } - - IDataReadStream& operator<<(int16& val) - { - Read2(&val); - return *this; - } - - IDataReadStream& operator<<(int32& val) - { - Read4(&val); - return *this; - } - - IDataReadStream& operator<<(int64& val) - { - Read8(&val); - return *this; - } - - IDataReadStream& operator<<(float& val) - { - Read4(&val); - return *this; - } - - // Bool is saved by writing an 8 bit value to make it portable - IDataReadStream& operator<<(bool& val) - { - uint8 uVal = 0; - Read1(&uVal); - val = (uVal != 0); - return *this; - } - -public: - // Read string from stream - string ReadString(); - - // Skip string data in a stream without loading the data - void SkipString(); - - // Read int8 from stream - int8 ReadInt8() - { - int8 val = 0; - Read1(&val); - return val; - } - - // Read int16 from stream - int16 ReadInt16() - { - int16 val = 0; - Read2(&val); - return val; - } - - // Read int32 from stream - int32 ReadInt32() - { - int32 val = 0; - Read4(&val); - return val; - } - - // Read int64 from stream - int64 ReadInt64() - { - int64 val = 0; - Read8(&val); - return val; - } - - // Read uint8 from stream - uint8 ReadUint8() - { - uint8 val = 0; - Read1(&val); - return val; - } - - // Read uint16 from stream - uint16 ReadUint16() - { - uint16 val = 0; - Read2(&val); - return val; - } - - // Read uint32 from stream - uint32 ReadUint32() - { - uint32 val = 0; - Read4(&val); - return val; - } - - // Read int64 from stream - uint64 ReadUint64() - { - uint64 val = 0; - Read8(&val); - return val; - } - - // Read float from stream - float ReadFloat() - { - float val = 0.0f; - Read4(&val); - return val; - } -}; - -//----------------------------------------------------------------------------- - -/// Remote command class info (simple RTTI) -struct IRemoteCommandClass -{ -public: - virtual ~IRemoteCommandClass() {}; - - // Get class name - virtual const char* GetName() const = 0; - - // Create command instance - virtual struct IRemoteCommand* CreateObject() = 0; -}; - -/// Remote command interface -struct IRemoteCommand -{ -protected: - virtual ~IRemoteCommand() {}; - -public: - // Get command class - virtual IRemoteCommandClass* GetClass() const = 0; - - // Save to data stream - virtual void SaveToStream(struct IDataWriteStream& writeStream) const = 0; - - // Load from data stream - virtual void LoadFromStream(struct IDataReadStream& readStream) = 0; - - // Execute (remote call) = 0; - virtual void Execute() = 0; - - // Delete the command object (can be allocated from different heap) - virtual void Delete() = 0; -}; - -//----------------------------------------------------------------------------- - -// This is a implementation of a synchronous listener (limited to the engine tick rate) -// that processes and responds to the raw messages received from clients. -struct IRemoteCommandListenerSync -{ -public: - virtual ~IRemoteCommandListenerSync() {}; - - // Process a raw message and optionally provide an answer to the request, return true if you have processed the message. - // Messages is accessible via the data reader. Response can be written to a data writer. - virtual bool OnRawMessageSync(const class ServiceNetworkAddress& remoteAddress, struct IDataReadStream& msg, struct IDataWriteStream& response) = 0; -}; - -//----------------------------------------------------------------------------- - -// This is a implementation of a asynchronous listener (called from network thread) -// that processes and responds to the raw messages received from clients. -struct IRemoteCommandListenerAsync -{ -public: - virtual ~IRemoteCommandListenerAsync() {}; - - // Process a raw message and optionally provide an answer to the request, return true if you have processed the message. - // Messages is accessible via the data reader. Response can be written to a data writer. - virtual bool OnRawMessageAsync(const class ServiceNetworkAddress& remoteAddress, struct IDataReadStream& msg, struct IDataWriteStream& response) = 0; -}; - -//----------------------------------------------------------------------------- - -/// Remote command server -struct IRemoteCommandServer -{ -protected: - virtual ~IRemoteCommandServer() {}; - -public: - // Execute all of the received pending commands - // This should be called from a safe place (main thread) - virtual void FlushCommandQueue() = 0; - - // Suppress command execution - virtual void SuppressCommands() = 0; - - // Resume command execution - virtual void ResumeCommands() = 0; - - // Register/Unregister synchronous message listener (limited to tick rate) - virtual void RegisterSyncMessageListener(IRemoteCommandListenerSync* pListener) = 0; - virtual void UnregisterSyncMessageListener(IRemoteCommandListenerSync* pListener) = 0; - - // Register/Unregister asynchronous message listener (called from network thread) - virtual void RegisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) = 0; - virtual void UnregisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) = 0; - - // Broadcast a message to all connected clients - virtual void Broadcast(IServiceNetworkMessage* pMessage) = 0; - - // Do we have any clients connected ? - virtual bool HasConnectedClients() const = 0; - - // Delete the client - virtual void Delete() = 0; -}; - -//----------------------------------------------------------------------------- - -/// Connection to remote command server -struct IRemoteCommandConnection -{ -protected: - virtual ~IRemoteCommandConnection() {}; - -public: - // Are we connected ? - // This returns false when the underlying network connection has failed (sockets error). - // Also, this returns false if the remote connection was closed by remote peer. - virtual bool IsAlive() const = 0; - - // Get address of remote command server - // This returns the full address of the endpoint (with valid port) - virtual const ServiceNetworkAddress& GetRemoteAddress() const = 0; - - // Send raw message to the other side of this connection. - // Raw messages are not buffer and are sent right away, - // they also have precedence over internal command traffic. - // The idea is that you need some kind of bidirectional signaling - // channel to extend the rather one-directional nature of commands. - // Returns true if message was added to the send queue. - virtual bool SendRawMessage(IServiceNetworkMessage* pMessage) = 0; - - // See if there's a raw message waiting for us and if it is, get it - // Be aware that messages are reference counted. - virtual IServiceNetworkMessage* ReceiveRawMessage() = 0; - - // Close connection - // - pending commands are not sent - // - pending raw messages are sent or not (depending on the flag) - virtual void Close(bool bFlushQueueBeforeClosing = false) = 0; - - // Add internal reference to object (Refcounting interface) - virtual void AddRef() = 0; - - // Release internal reference to object (Refcounting interface) - virtual void Release() = 0; -}; - -//----------------------------------------------------------------------------- - -/// Remote command client -struct IRemoteCommandClient -{ -protected: - virtual ~IRemoteCommandClient() {}; - -public: - // Connect to remote server, returns true on success, false on failure - virtual IRemoteCommandConnection* ConnectToServer(const class ServiceNetworkAddress& serverAddress) = 0; - - // Schedule command to be executed on the all of the remote servers - virtual bool Schedule(const IRemoteCommand& command) = 0; - - // Delete the client object - virtual void Delete() = 0; -}; - -//----------------------------------------------------------------------------- - -/// Remote command manager -struct IRemoteCommandManager -{ -public: - virtual ~IRemoteCommandManager() {}; - - // Set debug message verbose level - virtual void SetVerbosityLevel(const uint32 level) = 0; - - // Create local server for executing remote commands on given local port - virtual IRemoteCommandServer* CreateServer(uint16 localPort) = 0; - - // Create client interface for executing remote commands on remote servers - virtual IRemoteCommandClient* CreateClient() = 0; - - // Register command class (will be accessible by both clients and server) - virtual void RegisterCommandClass(IRemoteCommandClass& commandClass) = 0; -}; - -//----------------------------------------------------------------------------- - -/// Class RTTI wrapper for remote command classes -template< typename T > -class CRemoteCommandClass - : public IRemoteCommandClass -{ -private: - const char* m_szName; - -public: - CRemoteCommandClass(const char* szName) - : m_szName(szName) - {} - - virtual const char* GetName() const - { - return m_szName; - } - - virtual struct IRemoteCommand* CreateObject() - { - return new T(); - } -}; - -#define DECLARE_REMOTE_COMMAND(x) \ -public: static IRemoteCommandClass& GetStaticClass() { \ - static IRemoteCommandClass* theClass = new CRemoteCommandClass(#x); return *theClass; } \ -public: virtual IRemoteCommandClass* GetClass() const { return &GetStaticClass(); } \ -public: virtual void Delete() { delete this; } \ -public: virtual void SaveToStream(IDataWriteStream & writeStream) const { const_cast(this)->Serialize(writeStream); } \ -public: virtual void LoadFromStream(IDataReadStream & readStream) { Serialize(readStream); } - -//----------------------------------------------------------------------------- - -/// CryString serialization helper (read) -inline IDataReadStream& operator<<(IDataReadStream& stream, string& outString) -{ - const uint32 kMaxTempString = 256; - - // read length - uint32 length = 0; - stream << length; - - // load string - if (length > 0) - { - if (length < kMaxTempString) - { - // load the string into temporary buffer - char temp[kMaxTempString]; - stream.Read(&temp, length); - temp[length] = 0; - - // set the string with new value - outString = temp; - } - else - { - // allocate temporary memory and load the string - std::vector temp; - temp.resize(length + 1, 0); - stream.Read(&temp[0], length); - - // set the string with new value - outString = &temp[0]; - } - } - else - { - // empty string - outString.clear(); - } - - return stream; -} - -/// CryString serialization helper (write) -inline IDataWriteStream& operator<<(IDataWriteStream& stream, const string& str) -{ - // write length - const uint32 length = static_cast(str.length()); - stream << length; - - // write string data - if (length > 0) - { - stream.Write(str.c_str(), length); - } - - return stream; -} - -//------------------------------------------------------------------------ - -/// Vector serialization helper (reading) -template< class T > -IDataReadStream& operator<<(IDataReadStream& ar, std::vector& outVector) -{ - // Load item count - uint32 count = 0; - ar << count; - - // Adapt the vector size (exact fit) - outVector.resize(count); - - // Load items - for (uint32 i = 0; i < count; ++i) - { - ar << outVector[i]; - } - - return ar; -} - -/// Vector serialization helper (writing) -template< class T > -IDataWriteStream& operator<<(IDataWriteStream& ar, const std::vector& vec) -{ - // Save item count - const uint32 count = vec.size(); - ar << count; - - // Save items - for (uint32 i = 0; i < count; ++i) - { - ar << const_cast(vec[i]); - } - - return ar; -} - -//------------------------------------------------------------------------ - -inline void IDataWriteStream::WriteString(const char* str) -{ - string tempString(str); - *this << tempString; -} - -inline void IDataWriteStream::WriteString(const string& str) -{ - *this << str; -} - -inline string IDataReadStream::ReadString() -{ - string ret; - *this << ret; - return ret; -} - -inline void IDataReadStream::SkipString() -{ - // read length - uint32 length = 0; - *this << length; - Skip(length); -} - - -//------------------------------------------------------------------------ - -// Helper class for using the data reader and writer classes -// The only major differce betwen auto_ptr is that we call Delete() instead of operator delete -template -class TAutoDelete -{ -public: - T* m_ptr; - -public: - TAutoDelete(T* ptr) - : m_ptr(ptr) - { - } - - ~TAutoDelete() - { - if (NULL != m_ptr) - { - m_ptr->Delete(); - m_ptr = NULL; - } - } - - operator bool() - { - return (NULL != m_ptr); - } - - operator T& () - { - return *m_ptr; - } - - T* operator->() - { - return m_ptr; - } - -private: - TAutoDelete(const TAutoDelete& other) - : m_ptr(NULL){}; - TAutoDelete& operator=(const TAutoDelete& other) { return *this; } -}; - -//------------------------------------------------------------------------ - - -#endif // CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H diff --git a/Code/CryEngine/CryCommon/IServiceNetwork.h b/Code/CryEngine/CryCommon/IServiceNetwork.h deleted file mode 100644 index 3df3f79abd..0000000000 --- a/Code/CryEngine/CryCommon/IServiceNetwork.h +++ /dev/null @@ -1,344 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Service network interface - - -#ifndef CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H -#define CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H -#pragma once - - -#include -//----------------------------------------------------------------------------- -// -// Service network is a simple abstract interface for connecting between instances -// of the editor and game running on various platforms. It implements it's own -// small message based communication layer and shall not be used for raw communication -// with anything else. -// -// Features currently implemented by the service network: -// - Completely thread safe (so can be used from within other threads) -// - Completely asynchronous (only one thread) -// - Message based approach (both on the send and receive ends) -// - Automatic and transparent reconnection -// - Debug-friendly (will not time-out easily when one of the endpoints is being debugged) -// - Easy to use -// -// Usage case (server) -// - Create listener (IServiceListener) on some pre-defined port -// - Poll the incoming connections by calling Accept() method -// - Service the traffic by calling connection's ReceiveMessage()/SendMessage() methods -// - Close() and Release() connections -// - Close() and Release() listener -// -// Usage case (client) -// - Connect to a remote listener by calling Connect() method -// - Service the traffic by calling connection's ReceiveMessage()/SendMessage() methods -// - Close() and Release() connection -// -// Both sending and receiving is asynchronous. Calling the SendMessage()/ReceiveMessage() methods -// only pushes/pops the message buffers to/from the queue. -// NOTE: Message buffers are internally reference counted by the network system and they are kept around -// untill they are sent (in case of outgoing traffic) or untill they are polled by ReceiveMessage(). -// Be aware that this can cause memory spikes, especially when incoming traffic is not serviced fast enough. -// There are customizable limits (around 1MB) on the amount of data that can be buffered internally by -// the service network before the new messages are rejected. -// It's up to the higher layer to ensure damage control in such situation. -// -// NOTE: connection is also a reference counted object, make sure to call Close() before calling Release(). -// -//----------------------------------------------------------------------------- - -/// Network address abstraction -class ServiceNetworkAddress -{ -public: - struct StringAddress - { - char m_data[32]; - - ILINE const char* c_str() const - { - return m_data; - } - }; - - struct Address - { - uint8 m_ip0; - uint8 m_ip1; - uint8 m_ip2; - uint8 m_ip3; - uint16 m_port; - - ILINE Address() - : m_ip0(0) - , m_ip1(0) - , m_ip2(0) - , m_ip3(0) - , m_port(0) - {} - }; - -private: - Address m_address; - -public: - // By default creates ("invalid address") - ILINE ServiceNetworkAddress() - { - } - - // Copy (with optional port change) - ILINE ServiceNetworkAddress(const ServiceNetworkAddress& other, uint16 newPort = 0) - : m_address(other.m_address) - { - if (newPort != 0) - { - m_address.m_port = newPort; - } - } - - // Initialize from ip:host pattern (if you want to initialize from host name use the DebugNetwork interface) - ILINE ServiceNetworkAddress(uint8 ip0, uint8 ip1, uint8 ip2, uint8 ip3, uint16 port) - { - m_address.m_ip0 = ip0; - m_address.m_ip1 = ip1; - m_address.m_ip2 = ip2; - m_address.m_ip3 = ip3; - m_address.m_port = port; - } - - // Set new port value - ILINE void SetPort(uint16 port) - { - m_address.m_port = port; - } - - // Is this a valid address - ILINE bool IsValid() const - { - return (m_address.m_ip0 != 0) && - (m_address.m_ip1 != 1) && - (m_address.m_ip2 != 1) && - (m_address.m_ip3 != 1) && - (m_address.m_port != 0); - } - - // Convert to human readable string - ILINE StringAddress ToString() const - { - // format the string buffer - StringAddress ret; - sprintf_s(ret.m_data, sizeof(ret.m_data), - "%d.%d.%d.%d:%d", - m_address.m_ip0, m_address.m_ip1, m_address.m_ip2, m_address.m_ip3, - m_address.m_port); - - // return as managed string - return ret; - } - - // Get the literal data - ILINE const Address& GetAddress() const - { - return m_address; - } - -public: - // Compare base address (IP only) of two connections - static bool CompareBaseAddress(const ServiceNetworkAddress& a, const ServiceNetworkAddress& b) - { - return (a.m_address.m_ip0 == b.m_address.m_ip0) && - (a.m_address.m_ip1 == b.m_address.m_ip1) && - (a.m_address.m_ip2 == b.m_address.m_ip2) && - (a.m_address.m_ip3 == b.m_address.m_ip3); - } - - // Compare full address (IP+port) of two connections - static bool CompareFullAddress(const ServiceNetworkAddress& a, const ServiceNetworkAddress& b) - { - return (a.m_address.m_ip0 == b.m_address.m_ip0) && - (a.m_address.m_ip1 == b.m_address.m_ip1) && - (a.m_address.m_ip2 == b.m_address.m_ip2) && - (a.m_address.m_ip3 == b.m_address.m_ip3) && - (a.m_address.m_port == b.m_address.m_port); - } -}; - -//----------------------------------------------------------------------------- - -/// Message buffer used by the network system -struct IServiceNetworkMessage -{ -protected: - IServiceNetworkMessage() {}; - virtual ~IServiceNetworkMessage() {}; - -public: - // Get unique message ID (message ID is used just once) - virtual uint32 GetId() const = 0; - - // Get the size of message buffer - virtual uint32 GetSize() const = 0; - - // Get pointer to the message data - virtual void* GetPointer() = 0; - - // Get pointer to the message data - virtual const void* GetPointer() const = 0; - - // Create reader interface for reading message data, returned object is not - // reference counted but it will hold a reference to the message. - virtual struct IDataReadStream* CreateReader() const = 0; - - // Add reference (buffer is internally refcounted) - virtual void AddRef() = 0; - - // Release reference - virtual void Release() = 0; -}; - -//----------------------------------------------------------------------------- - -/// General network TCP/IP connection -struct IServiceNetworkConnection -{ -protected: - IServiceNetworkConnection() {}; - virtual ~IServiceNetworkConnection() {}; - -public: - static const uint32 kDefaultFlushTime = 10000; // ms - - // Get the unique connection ID (is shared between host and client) - virtual const CryGUID& GetGUID() const = 0; - - // Get remote endpoint address - virtual const ServiceNetworkAddress& GetRemoteAddress() const = 0; - - // Get local endpoint address - virtual const ServiceNetworkAddress& GetLocalAddress() const = 0; - - // Add a message buffer to the connection send queue. - // Connection can refuse to send the buffer if it's full or invalid. - // If a message is rejected this function returns false. - virtual bool SendMsg(IServiceNetworkMessage* message) = 0; - - // Get a message from connection receive queue. - // If there are no pending messages a NULL is returned. - // Since message is a ref-counted you need to call Release() when you are done with the buffer. - virtual IServiceNetworkMessage* ReceiveMsg() = 0; - - // Checks if connection is still alive. - // Returns false only if connection has been damaged beyond repair. - virtual bool IsAlive() const = 0; - - // Get number of messages sent by this connection so far - virtual uint32 GetMessageSendCount() const = 0; - - // Get number of messages received by this connection so far - virtual uint32 GetMessageReceivedCount() const = 0; - - // Get size of data sent by this connection so far - virtual uint64 GetMessageSendDataSize() const = 0; - - // Get size of data received by this connection so far - virtual uint64 GetMessageReceivedDataSize() const = 0; - - // Request connection to be closed but not before sending out all of the pending messages. Incoming messages are ignored. - // Processing and sending the messages is done on the networking thread so this function will not block. - // As an option, connection can be forcefully closed after given amount of time (in ms). - virtual void FlushAndClose(const uint32 timeoutMs = kDefaultFlushTime) = 0; - - // Synchronous wait for the connection to send all outgoing messages - virtual void FlushAndWait() = 0; - - // Request connection to be closed now. All pending messages are discarded. - virtual void Close() = 0; - - // Add reference (connection is an internally reference counted object) - virtual void AddRef() = 0; - - // Release reference - virtual void Release() = 0; -}; - -//----------------------------------------------------------------------------- - -/// General listening socket (async) -struct IServiceNetworkListener -{ -protected: - IServiceNetworkListener() {}; - virtual ~IServiceNetworkListener() {}; - -public: - // Get the local address - virtual const ServiceNetworkAddress& GetLocalAddress() const = 0; - - // Get number of active connections handled by this listener - virtual uint GetConnectionCount() const = 0; - - // Accept incoming connection (asynchronously) - // Will return NULL if there's nothing to accept - // Will return new IDebugNetworkConnection if something was received - virtual IServiceNetworkConnection* Accept() = 0; - - // Is listener able to accept connections ? - virtual bool IsAlive() const = 0; - - // Request listener to be closed (closes the socket) - virtual void Close() = 0; - - // Add reference (listener is an internally reference counted object) - virtual void AddRef() = 0; - - // Release reference - virtual void Release() = 0; -}; - -//----------------------------------------------------------------------------- - -/// General service (background) network interface -struct IServiceNetwork -{ -public: - virtual ~IServiceNetwork() {}; - - // Set verbosity level of debug messages that got printed to log, levels 0-3 are commonly used - virtual void SetVerbosityLevel(const uint32 level) = 0; - - // Allocate empty message buffer of given size, message buffer is a reference counted object - virtual IServiceNetworkMessage* AllocMessageBuffer(const uint32 size) = 0; - - // Create general message writer stream, object is not reference counted - virtual struct IDataWriteStream* CreateMessageWriter() = 0; - - // Create general message reader stream and initialize it with data - virtual struct IDataReadStream* CreateMessageReader(const void* pData, const uint32 dataSize) = 0; - - // Translate host address (string:port) to network address - virtual ServiceNetworkAddress GetHostAddress(const string& addressString, uint16 optionalPort = 0) const = 0; - - // Create network listener on given local port, listening and accepting connections is done on network thread - virtual IServiceNetworkListener* CreateListener(uint16 localPort) = 0; - - // Connect to remote address (will block until connection is made or refused) - virtual IServiceNetworkConnection* Connect(const ServiceNetworkAddress& remoteAddress) = 0; -}; - -//----------------------------------------------------------------------------- - -#endif // CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H diff --git a/Code/CryEngine/CryCommon/ISystem.h b/Code/CryEngine/CryCommon/ISystem.h index 93de0008b0..86c2b57464 100644 --- a/Code/CryEngine/CryCommon/ISystem.h +++ b/Code/CryEngine/CryCommon/ISystem.h @@ -91,7 +91,6 @@ struct IAVI_Reader; class CPNoise3; struct IVisualLog; struct ILocalizationManager; -struct ICryFactoryRegistry; struct ISoftCodeMgr; struct IZLibCompressor; struct IZLibDecompressor; @@ -99,8 +98,6 @@ struct ILZ4Decompressor; class IZStdDecompressor; struct IOutputPrintSink; struct IThreadManager; -struct IServiceNetwork; -struct IRemoteCommandManager; struct IWindowMessageHandler; struct IImageHandler; class IResourceCompilerHelper; @@ -798,8 +795,6 @@ struct SSystemGlobalEnvironment IRenderer* pRenderer; IMaterialEffects* pMaterialEffects; ISoftCodeMgr* pSoftCodeMgr; - IServiceNetwork* pServiceNetwork; - IRemoteCommandManager* pRemoteCommandManager; ILyShine* pLyShine; IResourceCompilerHelper* pResourceCompilerHelper; SharedEnvironmentInstance* pSharedEnvironment; @@ -1244,10 +1239,6 @@ struct ISystem // Retrieves access to XML utilities interface. virtual IXmlUtils* GetXmlUtils() = 0; - // Summary: - // Interface to access different implementations of Serialization::IArchive in a centralized way. - virtual Serialization::IArchiveHost* GetArchiveHost() const = 0; - virtual void SetViewCamera(CCamera& Camera) = 0; virtual CCamera& GetViewCamera() = 0; @@ -1368,10 +1359,6 @@ struct ISystem // Retrieves system update counter. virtual uint64 GetUpdateCounter() = 0; - // Summary: - // Gets access to all registered factories. - virtual ICryFactoryRegistry* GetCryFactoryRegistry() const = 0; - ////////////////////////////////////////////////////////////////////////// // Error callback handling @@ -1491,15 +1478,6 @@ struct ISystem virtual const IImageHandler* GetImageHandler() const = 0; - // Summary: - // Loads a dynamic library, creates and initializes an instance of the module class - - virtual bool InitializeEngineModule(const char* dllName, const char* moduleClassName, const SSystemInitParams& initParams) = 0; - - // Summary: - // Unloads a dynamic library as well as the corresponding instance of the module class - virtual bool UnloadEngineModule(const char* dllName, const char* moduleClassName) = 0; - // Summary: // Gets the root window message handler function // The returned pointer is platform-specific: diff --git a/Code/CryEngine/CryCommon/Mocks/IConsoleMock.h b/Code/CryEngine/CryCommon/Mocks/IConsoleMock.h index 31509ca6ba..3d4327116e 100644 --- a/Code/CryEngine/CryCommon/Mocks/IConsoleMock.h +++ b/Code/CryEngine/CryCommon/Mocks/IConsoleMock.h @@ -13,7 +13,6 @@ #define CRYINCLUDE_CRYCOMMON_ICONSOLEMOCK_H #pragma once -#include #include #include diff --git a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h index 9e5182ebcf..1e28937764 100644 --- a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h +++ b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h @@ -164,8 +164,6 @@ public: XmlNodeRef(const char*, bool)); MOCK_METHOD0(GetXmlUtils, IXmlUtils * ()); - MOCK_CONST_METHOD0(GetArchiveHost, - Serialization::IArchiveHost * ()); MOCK_METHOD1(SetViewCamera, void(CCamera & Camera)); MOCK_METHOD0(GetViewCamera, @@ -223,8 +221,6 @@ public: CPNoise3 * ()); MOCK_METHOD0(GetUpdateCounter, uint64()); - MOCK_CONST_METHOD0(GetCryFactoryRegistry, - ICryFactoryRegistry * ()); MOCK_METHOD1(RegisterErrorObserver, bool(IErrorObserver * errorObserver)); MOCK_METHOD1(UnregisterErrorObserver, @@ -287,10 +283,6 @@ public: bool()); MOCK_CONST_METHOD0(GetImageHandler, const IImageHandler * ()); - MOCK_METHOD3(InitializeEngineModule, - bool(const char* dllName, const char* moduleClassName, const SSystemInitParams&initParams)); - MOCK_METHOD2(UnloadEngineModule, - bool(const char* dllName, const char* moduleClassName)); MOCK_METHOD0(GetRootWindowMessageHandler, void*()); MOCK_METHOD1(RegisterWindowMessageHandler, diff --git a/Code/CryEngine/CryCommon/Serialization/Assert.h b/Code/CryEngine/CryCommon/Serialization/Assert.h deleted file mode 100644 index a1ce890dc8..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Assert.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H -#pragma once - -#ifdef SERIALIZATION_STANDALONE -#include -#else -#include -#endif - -#ifdef YASLI_ASSERT -# undef YASLI_ASSERT -#endif - -#ifdef YASLI_VERIFY -# undef YASLI_VERIFY -#endif - -#ifdef YASLI_ESCAPE -# undef YASLI_ESCAPE -#endif - -#ifdef SERIALIZATION_STANDALONE -#define YASLI_ASSERT(x) assert(x) -#define YASLI_ASSERT_STR(x, str) assert(x && str) -#define YASLI_ESCAPE(x, action) if (!(x)) { YASLI_ASSERT(0 && #x); action; }; -#else -#define YASLI_ASSERT(x) CRY_ASSERT(x) -#define YASLI_ASSERT_STR(x, str) CRY_ASSERT_MESSAGE(x, str) -#define YASLI_ESCAPE(x, action) if (!(x)) { YASLI_ASSERT(0 && #x); action; }; -#endif // SERIALIZATION_STANDALONE - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H diff --git a/Code/CryEngine/CryCommon/Serialization/BitVector.h b/Code/CryEngine/CryCommon/Serialization/BitVector.h deleted file mode 100644 index 06cb3b956a..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/BitVector.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2012 Crytek GmbH -// Authors: Evgeny Andreeshchev, Alexander Kotliar -// Based on: Yasli - the serialization library. -// Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H -#pragma once - - -namespace Serialization{ - -class IArchive; -template -class BitVector -{ -public: - BitVector(int value = 0) : value_(value) {} - - operator int&() { return value_; } - operator int() const { return value_; } - - BitVector& operator|= (Enum value) { value_ |= value; return *this; } - BitVector& operator|= (int value) { value_ |= value; return *this; } - BitVector& operator&= (int value) { value_ &= value; return *this; } - - void Serialize(IArchive& ar); -private: - int value_; -}; - -template -bool Serialize(Serialization::IArchive& ar, Serialization::BitVector& value, const char* name, const char* label); - -} - -#include "BitVectorImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H diff --git a/Code/CryEngine/CryCommon/Serialization/BitVectorImpl.h b/Code/CryEngine/CryCommon/Serialization/BitVectorImpl.h deleted file mode 100644 index 1d5c02342c..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/BitVectorImpl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H -#pragma once - -#include "Serialization/BitVector.h" -#include "Serialization/IArchive.h" -#include "Serialization/Enum.h" - -namespace Serialization { - struct BitVectorWrapper - { - int* valuePointer; - int value; - const CEnumDescription* description; - - explicit BitVectorWrapper(int* _value = 0, const CEnumDescription* _description = 0) - : valuePointer(_value) - , description(_description) - { - if (valuePointer) - { - value = *valuePointer; - } - } - BitVectorWrapper(const BitVectorWrapper& _rhs) - : value(_rhs.value) - , description(0) - , valuePointer(0) - { - } - - ~BitVectorWrapper() - { - if (valuePointer) - { - * valuePointer = value; - } - } - BitVectorWrapper& operator=(const BitVectorWrapper& rhs) - { - value = rhs.value; - return *this; - } - - - void Serialize(IArchive& ar) - { - ar(value, "value", "Value"); - } - }; - - template - void BitVector::Serialize(IArchive& ar) - { - ar(value_, "value", "Value"); - } -} - -template -bool Serialize(Serialization::IArchive& ar, Serialization::BitVector& value, const char* name, const char* label) -{ - using namespace Serialization; - CEnumDescription& desc = getEnumDescription(); - if (ar.IsEdit()) - { - return ar(BitVectorWrapper(&static_cast(value), &desc), name, label); - } - else - { - return desc.serializeBitVector(ar, static_cast(value), name, label); - } -} - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/BlackBox.h b/Code/CryEngine/CryCommon/Serialization/BlackBox.h deleted file mode 100644 index 7efbbf7ece..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/BlackBox.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H -#pragma once - -#include // for malloc and free - -namespace Serialization -{ - // Black box is used to store opaque data blobs in a format internal to - // specific Archive. For example it can be used to store sections of the JSON - // or binary archive. - // - // This is useful for the Editor to store portions of files with unfamiliar - // structure. - // - // We store deallocation function here so we can safely pass the blob - // across DLLs with different memory allocators. - struct SBlackBox - { - const char* format; - void* data; - size_t size; - typedef void(* FreeFunction)(void*); - FreeFunction freeFunction; - - SBlackBox() - : format("") - , data(0) - , size(0) - , freeFunction(0) - { - } - - SBlackBox(const SBlackBox& rhs) - : format("") - , data(0) - , size(0) - , freeFunction(0) - { - *this = rhs; - } - - void set(const char* _format, const void* _data, size_t _size) - { - if (_data && freeFunction) - { - freeFunction(this->data); - this->data = 0; - this->size = 0; - freeFunction = 0; - } - this->format = _format; - if (_data && _size) - { - this->data = CryModuleMalloc(_size); - memcpy(this->data, _data, _size); - this->size = _size; - freeFunction = &Free; - } - } - - SBlackBox& operator=(const SBlackBox& rhs) - { - set(rhs.format, rhs.data, rhs.size); - return *this; - } - - ~SBlackBox() - { - set("", 0, 0); - } - - static void Free(void* ptr) - { - CryModuleFree(ptr); - } - }; -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H diff --git a/Code/CryEngine/CryCommon/Serialization/BoostSharedPtr.h b/Code/CryEngine/CryCommon/Serialization/BoostSharedPtr.h deleted file mode 100644 index 7d1d8591d0..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/BoostSharedPtr.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -#include "ClassFactory.h" - -template -class BoostSharedPtrSerializer - : public Serialization::IPointer -{ -public: - BoostSharedPtrSerializer(AZStd::shared_ptr& ptr) - : m_ptr(ptr) - { - } - - const char* registeredTypeName() const override - { - if (m_ptr) - { - return factoryOverride().getRegisteredTypeName(m_ptr.get()); - } - else - { - return ""; - } - } - - void create(const char* registeredTypeName) const override - { - CRY_ASSERT(!m_ptr || m_ptr.use_count() == 1); - if (registeredTypeName && registeredTypeName[0] != '\0') - { - m_ptr.reset(factoryOverride().create(registeredTypeName)); - } - else - { - m_ptr.reset(); - } - } - - Serialization::TypeID baseType() const override - { - return Serialization::TypeID::get(); - } - - virtual Serialization::SStruct serializer() const override - { - return Serialization::SStruct(*m_ptr); - } - - void* get() const - { - return reinterpret_cast(m_ptr.get()); - } - - const void* handle() const - { - return &m_ptr; - } - - Serialization::TypeID pointerType() const override - { - return Serialization::TypeID::get >(); - } - - Serialization::ClassFactory* factory() const override - { - return &factoryOverride(); - } - - virtual Serialization::ClassFactory& factoryOverride() const - { - return Serialization::ClassFactory::the(); - } - -protected: - AZStd::shared_ptr& m_ptr; -}; - -namespace AZStd -{ - template - bool Serialize(Serialization::IArchive& ar, AZStd::shared_ptr& ptr, const char* name, const char* label) - { - BoostSharedPtrSerializer serializer(ptr); - return ar(static_cast(serializer), name, label); - } -} diff --git a/Code/CryEngine/CryCommon/Serialization/CRCRef.h b/Code/CryEngine/CryCommon/Serialization/CRCRef.h deleted file mode 100644 index b26195dd99..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CRCRef.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H -#pragma once - -template -struct SCRCRef; - -namespace Serialization -{ - class IArchive; -} - -template -bool Serialize(Serialization::IArchive& ar, SCRCRef& crcRef, const char* name, const char* label); - -#include "CRCRefImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H diff --git a/Code/CryEngine/CryCommon/Serialization/CRCRefImpl.h b/Code/CryEngine/CryCommon/Serialization/CRCRefImpl.h deleted file mode 100644 index 28b0f4305b..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CRCRefImpl.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H -#pragma once - -#include "IArchive.h" -#include "Serializer.h" - -template -class CRCRefSerializer - : public Serialization::IString -{ -public: - CRCRefSerializer(TCRCRef& crcRef) - : m_crcRef(crcRef) - { - } - - virtual void set(const char* value) - { - m_crcRef.SetByString(value); - } - - virtual const char* get() const - { - return m_crcRef.c_str(); - } - - const void* handle() const - { - return &m_crcRef; - } - - Serialization::TypeID type() const - { - return Serialization::TypeID::get(); - } - - - TCRCRef& m_crcRef; -}; - - -template -class CCRCRefSerializerNoStrings -{ -public: - CCRCRefSerializerNoStrings(struct SCRCRef& crcRef) - : crc(crcRef.crc) - { - } - - bool Serialize(Serialization::IArchive& ar) - { - return ar(crc, "CRC", "CRC"); - } - - typedef typename THash::TInt TInt; - TInt& crc; -}; - - - -template -bool Serialize(Serialization::IArchive& ar, struct SCRCRef& crcRef, const char* name, const char* label) -{ - if (StoreStrings == 0) - { - if (ar.IsInput()) - { - SCRCRef crcCopy; - ar(CCRCRefSerializerNoStrings(crcCopy), name, label); - if (crcCopy.crc != THash::INVALID) - { - crcRef = crcCopy; - return true; - } - } - else if (ar.IsOutput()) - { - return ar(CCRCRefSerializerNoStrings(crcRef), name, label); - } - } - - CRCRefSerializer > crcRefSerializer(crcRef); - return ar(static_cast(crcRefSerializer), name, label); -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Callback.h b/Code/CryEngine/CryCommon/Serialization/Callback.h deleted file mode 100644 index 0a0ce2b7f8..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Callback.h +++ /dev/null @@ -1,184 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H -#pragma once - -#include - -namespace Serialization -{ - struct ICallback - { - virtual bool SerializeValue(IArchive& ar, const char* name, const char* value) = 0; - virtual ICallback* Clone() = 0; - virtual void Release() = 0; - virtual TypeID Type() const = 0; - - typedef AZStd::function ApplyFunction; - virtual void Call(const ApplyFunction&) = 0; - }; - - template - struct CallbackSimple - : ICallback - { - typedef AZStd::function CallbackFunction; - T* value; - T oldValue; - CallbackFunction callback; - - CallbackSimple(T* value, const T& oldValue, const AZStd::function& callback) - : value(value) - , oldValue(oldValue) - , callback(callback) - { - } - - ICallback* Clone() { return new CallbackSimple(0, oldValue, callback); } - void Release() { delete this; } - bool SerializeValue(IArchive& ar, const char* name, const char* label) { return ar(*value, name, label); } - TypeID Type() const{ return TypeID::get(); } - - void Call(const ApplyFunction& applyFunction) - { - T newValue; - applyFunction((void*)&newValue, TypeID::get()); - if (oldValue != newValue) - { - callback(newValue); - oldValue = newValue; - } - } - }; - - template - struct CallbackWithDecorator - : ICallback - { - typedef AZStd::function CallbackFunction; - typedef AZStd::function DecoratorFunction; - - T oldValue; - T* value; - CallbackFunction callback; - DecoratorFunction decorator; - - CallbackWithDecorator(T* value, - const T& oldValue, - const CallbackFunction& callback, - const DecoratorFunction& decorator) - : value(value) - , oldValue(oldValue) - , callback(callback) - , decorator(decorator) - { - } - - ICallback* Clone() { return new CallbackWithDecorator(0, oldValue, callback, decorator); } - void Release() { delete this; } - bool SerializeValue(IArchive& ar, const char* name, const char* label) { return ar(decorator(*value), name, label); } - TypeID Type() const{ return TypeID::get(); } - - void Call(const ApplyFunction& applyFunction) - { - T newValue; - Decorator dec = decorator(newValue); - applyFunction((void*)&dec, TypeID::get()); - if (oldValue != newValue) - { - callback(newValue); - oldValue = newValue; - } - } - }; - - - - namespace Detail - { - template - struct MethodReturnType - { - typedef void type; - }; - - template - struct MethodReturnType - { - typedef ReturnType type; - }; - - template - struct OperatorBracketsReturnType - { - typedef typename MethodReturnType::type Type; - }; - } - - template - CallbackSimple - Callback(T& value, const CallbackFunc& callback) - { - return CallbackSimple(&value, value, AZStd::function(callback)); - } - - - template - CallbackWithDecorator::Type> - Callback(T& value, const CallbackFunc& callback, const DecoratorFunc& decorator) - { - typedef typename Detail::OperatorBracketsReturnType::Type Decorator; - return CallbackWithDecorator(&value, value, - AZStd::function(callback), - AZStd::function(decorator)); - } - - - template - bool Serialize(IArchive& ar, CallbackSimple& callback, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(static_cast(callback), name, label); - } - else - { - if (!ar(*callback.value, name, label)) - { - return false; - } - return true; - } - } - - template - bool Serialize(IArchive& ar, CallbackWithDecorator& callback, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(static_cast(callback), name, label); - } - else - { - if (!ar(*callback.value, name, label)) - { - return false; - } - return true; - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H diff --git a/Code/CryEngine/CryCommon/Serialization/ClassFactory.h b/Code/CryEngine/CryCommon/Serialization/ClassFactory.h deleted file mode 100644 index 4734a566eb..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ClassFactory.h +++ /dev/null @@ -1,376 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H -#pragma once - -#include -#include - -#include "Serialization/Assert.h" -#include "Serialization/IClassFactory.h" -#include "Serialization/TypeID.h" - -namespace Serialization { - class IArchive; - - class ClassFactoryManager - { - public: - static ClassFactoryManager& the() - { - static ClassFactoryManager factoryManager; - return factoryManager; - } - - const IClassFactory* find(TypeID baseType) const - { - lazyRegisterFactories(); - Factories::const_iterator it = factories_.find(baseType); - if (it == factories_.end()) - { - return 0; - } - else - { - return it->second; - } - } - - void registerFactory([[maybe_unused]] TypeID type, IClassFactory* factory) - { - factory->m_next = m_head; - m_head = factory; - } - protected: - void lazyRegisterFactories() const - { - if (m_head) - { - IClassFactory* factory = m_head; - while (factory) - { - const_cast(this)->factories_[factory->baseType_] = factory; - factory = factory->m_next; - } - const_cast(this)->m_head = nullptr; - } - } - - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> Factories; - Factories factories_; - IClassFactory* m_head = nullptr; - }; - - template - class ClassFactory - : public IClassFactory - { - public: - static ClassFactory& the() - { - static AZStd::aligned_storage_for_t storage; - if (s_instance != (decltype(s_instance))&storage) - { - s_instance = new(&storage) ClassFactory(); - } - return *s_instance; - } - - static void destroy() - { - if (s_instance) - { - s_instance->~ClassFactory(); - s_instance = nullptr; - } - } - - class CreatorBase - { - public: - virtual ~CreatorBase() {} - virtual BaseType* create() const = 0; - virtual const TypeDescription& description() const{ return *description_; } - virtual void* vptr() const { return vptr_; } - virtual TypeID typeID() const = 0; - protected: - const TypeDescription* description_ = nullptr; - void* vptr_ = nullptr; - public: - CreatorBase* next; - }; - - static void* extractVPtr(BaseType* ptr) - { - return *((void**)ptr); - } - - template - struct Annotation - { - Annotation(IClassFactory* factory, const char* name, const char* value) { static_cast*>(factory)->addAnnotation(name, value); } - }; - - template - class Creator - : public CreatorBase - { - public: - Creator(const TypeDescription* description, ClassFactory* factory = nullptr) - { - this->description_ = description; - - if (!factory) - { - factory = &ClassFactory::the(); - } - - factory->registerCreator(this); - } - - void* vptr() const override - { - if (!this->vptr_) - { - Derived vptrProbe; - const_cast(this)->vptr_ = extractVPtr(&vptrProbe); - } - return this->vptr_; - } - - BaseType* create() const override { return new Derived(); } - TypeID typeID() const override { return Serialization::TypeID::get(); } - }; - - ClassFactory() - : IClassFactory(TypeID::get()) - { - ClassFactoryManager::the().registerFactory(baseType_, this); - } - - ~ClassFactory() - { - m_data->~Data(); - m_data = nullptr; - } - - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> TypeToCreatorMap; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> VPtrToCreatorMap; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> RegisteredNameToTypeID; - typedef AZStd::unordered_map >, AZStd::hash, AZStd::equal_to, AZ::StdLegacyAllocator> AnnotationMap; - - virtual BaseType* create(const char* registeredName) const - { - lazyRegisterCreators(); - if (!registeredName) - { - return 0; - } - if (registeredName[0] == '\0') - { - return 0; - } - typename TypeToCreatorMap::const_iterator it = m_data->typeToCreatorMap_.find(registeredName); - if (it != m_data->typeToCreatorMap_.end()) - { - return it->second->create(); - } - else - { - return 0; - } - } - - virtual const char* getRegisteredTypeName(BaseType* ptr) const - { - lazyRegisterCreators(); - if (ptr == 0) - { - return ""; - } - void* vptr = extractVPtr(ptr); - typename VPtrToCreatorMap::const_iterator it = m_data->vptrToCreatorMap_.find(vptr); - if (it == m_data->vptrToCreatorMap_.end()) - { - return ""; - } - return it->second->description().name(); - } - - BaseType* createByIndex(int index) const - { - lazyRegisterCreators(); - YASLI_ASSERT(size_t(index) < m_data->creators_.size()); - return m_data->creators_[index]->create(); - } - - void serializeNewByIndex(IArchive& ar, int index, const char* name, const char* label) - { - lazyRegisterCreators(); - YASLI_ESCAPE(size_t(index) < m_data->creators_.size(), return ); - BaseType* ptr = m_data->creators_[index]->create(); - ar(*ptr, name, label); - delete ptr; - } - // from ClassFactoryInterface: - size_t size() const{ return m_data->creators_.size(); } - const TypeDescription* descriptionByIndex(int index) const override - { - lazyRegisterCreators(); - if (size_t(index) >= int(m_data->creators_.size())) - { - return 0; - } - return &m_data->creators_[index]->description(); - } - - const TypeDescription* descriptionByRegisteredName(const char* name) const override - { - lazyRegisterCreators(); - const size_t numCreators = m_data->creators_.size(); - for (size_t i = 0; i < numCreators; ++i) - { - if (strcmp(m_data->creators_[i]->description().name(), name) == 0) - { - return &m_data->creators_[i]->description(); - } - } - return 0; - } - // ^^^ - - TypeID typeIDByRegisteredName(const char* registeredTypeName) const - { - lazyRegisterCreators(); - RegisteredNameToTypeID::const_iterator it = m_data->registeredNameToTypeID_.find(registeredTypeName); - if (it == m_data->registeredNameToTypeID_.end()) - { - return TypeID(); - } - return it->second; - } - - const char* findAnnotation(const char* registeredTypeName, const char* name) const - { - lazyRegisterCreators(); - TypeID typeID = typeIDByRegisteredName(registeredTypeName); - AnnotationMap::const_iterator it = m_data->annotations_.find(typeID); - if (it == m_data->annotations_.end()) - { - return ""; - } - for (size_t i = 0; i < it->second.size(); ++i) - { - if (strcmp(it->second[i].first, name) == 0) - { - return it->second[i].second; - } - } - return ""; - } - void unregisterCreator(const TypeDescription& typeDescription) - { - auto creator = m_data->typeToCreatorMap_.find(typeDescription.name()); - if (creator != m_data->typeToCreatorMap_.end()) - { - m_data->creators_.erase(std::find(m_data->creators_.begin(), m_data->creators_.end(), m_data->creator->second)); - m_data->vptrToCreatorMap_.erase(m_data->vptrToCreatorMap_.find(creator->second->vptr())); - m_data->typeToCreatorMap_.erase(creator); - } - } - - protected: - virtual void registerCreator(CreatorBase* creator) - { - creator->next = creatorsList; - creatorsList = creator; - } - - void lazyRegisterCreators() const - { - if (!m_data) - { - const_cast(this)->m_data = ::new((void*)&m_dataStorage) Data(); - for (CreatorBase* creator = creatorsList; creator; creator = creator->next) - { - if (!const_cast(this)->m_data->typeToCreatorMap_.insert(AZStd::make_pair(creator->description().name(), creator)).second) - { - YASLI_ASSERT(0 && "Type registered twice in the same factory. Was SERIALIZATION_CLASS_NAME put into header file by mistake?"); - } - const_cast(this)->m_data->creators_.push_back(creator); - const_cast(this)->m_data->registeredNameToTypeID_[creator->description().name()] = creator->typeID(); - const_cast(this)->m_data->vptrToCreatorMap_[creator->vptr()] = creator; - } - } - } - - template - void addAnnotation(const char* name, const char* value) - { - addAnnotation(Serialization::TypeID::get(), name, value); - } - - virtual void addAnnotation(const Serialization::TypeID& id, const char* name, const char* value) - { - lazyRegisterCreators(); - m_data->annotations_[id].push_back(std::make_pair(name, value)); - } - - CreatorBase* creatorsList = nullptr; - static ClassFactory* s_instance; - - struct Data - { - TypeToCreatorMap typeToCreatorMap_; - AZStd::vector creators_; - VPtrToCreatorMap vptrToCreatorMap_; - RegisteredNameToTypeID registeredNameToTypeID_; - AnnotationMap annotations_; - }; - Data* m_data = nullptr; - AZStd::aligned_storage_for_t m_dataStorage; - }; - - template - ClassFactory* ClassFactory::s_instance = nullptr; -} - -#define SERIALIZATION_CLASS_NULL(BaseType, name) \ - namespace { \ - bool BaseType##_NullRegistered = Serialization::ClassFactory::the().setNullLabel(name); \ - } - -#define SERIALIZATION_CLASS_NAME(BaseType, Type, name, label) \ - static const Serialization::TypeDescription Type##BaseType##_DerivedDescription(name, label); \ - static Serialization::ClassFactory::Creator Type##BaseType##_Creator(&Type##BaseType##_DerivedDescription); \ - int dummyForType_##Type##BaseType; - -#define SERIALIZATION_CLASS_NAME_FOR_FACTORY(Factory, BaseType, Type, name, label) \ - static const Serialization::TypeDescription Type##BaseType##_DerivedDescription(name, label); \ - static Serialization::ClassFactory::Creator Type##BaseType##_Creator(&Type##BaseType##_DerivedDescription, &(Factory)); - -#define SERIALIZATION_CLASS_ANNOTATION(BaseType, Type, attributeName, attributeValue) \ - static Serialization::ClassFactory::Annotation Type##BaseType##_Annotation(&Serialization::ClassFactory::the(), attributeName, attributeValue); - -#define SERIALIZATION_CLASS_ANNOTATION_FOR_FACTORY(factory, BaseType, Type, attributeName, attributeValue) \ - static Serialization::ClassFactory::Annotation Type##BaseType##_Annotation(&factory, attributeName, attributeValue); - -#define SERIALIZATION_FORCE_CLASS(BaseType, Type) \ - extern int dummyForType_##Type##BaseType; \ - int* dummyForTypePtr_##Type##BaseType = &dummyForType_##Type##BaseType + 1; - -#include "ClassFactoryImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H diff --git a/Code/CryEngine/CryCommon/Serialization/ClassFactoryImpl.h b/Code/CryEngine/CryCommon/Serialization/ClassFactoryImpl.h deleted file mode 100644 index f3d034fb51..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ClassFactoryImpl.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H -#pragma once - -#include "IArchive.h" -#include "IClassFactory.h" -#include "STL.h" -#include "ClassFactory.h" -#include "Strings.h" - -namespace Serialization { - inline bool Serialize(Serialization::IArchive& ar, Serialization::TypeNameWithFactory& value, const char* name, [[maybe_unused]] const char* label) - { - if (!ar(value.registeredName, name)) - { - return false; - } - - if (ar.IsInput()) - { - const TypeDescription* desc = value.factory->descriptionByRegisteredName(value.registeredName.c_str()); - if (!desc) - { - ar.Error(value, "Unable to read TypeID: unregistered type name: \'%s\'", value.registeredName.c_str()); - value.registeredName.clear(); - return false; - } - } - return true; - } -} - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Color.h b/Code/CryEngine/CryCommon/Serialization/Color.h deleted file mode 100644 index 1b4f612bcd..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Color.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H -#pragma once - -#include -#include - -template -inline bool Serialize(Serialization::IArchive& ar, Color_tpl& c, const char* name, const char* label); - -namespace Serialization -{ - struct Vec3AsColor - { - Vec3& v; - Vec3AsColor(Vec3& v) - : v(v) {} - - void Serialize(Serialization::IArchive& ar) - { - ar(Range(v.x, 0.0f, 1.0f), "r", "^"); - ar(Range(v.y, 0.0f, 1.0f), "g", "^"); - ar(Range(v.z, 0.0f, 1.0f), "b", "^"); - } - }; - - inline bool Serialize(Serialization::IArchive& ar, Vec3AsColor& c, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct(c), name, label); - } - else - { - typedef float (* Array)[3]; - return ar(*((Array) & c.v.x), name, label); - } - } -} - -#include "ColorImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H diff --git a/Code/CryEngine/CryCommon/Serialization/ColorImpl.h b/Code/CryEngine/CryCommon/Serialization/ColorImpl.h deleted file mode 100644 index cf7f5886d7..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ColorImpl.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H -#pragma once - -#include "Color.h" - -////////////////////////////////////////////////////////////////////////// -template -struct SerializableColor_tpl - : Color_tpl -{ - static float ColorRangeMin(float) { return 0.0f; } - static float ColorRangeMax(float) { return 1.0f; } - static unsigned char ColorRangeMin(unsigned char) { return 0; } - static unsigned char ColorRangeMax(unsigned char) { return 255; } - - void Serialize(Serialization::IArchive& ar) - { - ar(Serialization::Range(Color_tpl::r, ColorRangeMin(Color_tpl::r), ColorRangeMax(Color_tpl::r)), "r", "^"); - ar(Serialization::Range(Color_tpl::g, ColorRangeMin(Color_tpl::g), ColorRangeMax(Color_tpl::g)), "g", "^"); - ar(Serialization::Range(Color_tpl::b, ColorRangeMin(Color_tpl::b), ColorRangeMax(Color_tpl::b)), "b", "^"); - ar(Serialization::Range(Color_tpl::a, ColorRangeMin(Color_tpl::a), ColorRangeMax(Color_tpl::a)), "a", "^"); - } -}; - -template -bool Serialize(Serialization::IArchive& ar, Color_tpl& c, const char* name, const char* label) -{ - if (ar.IsEdit()) - { - return Serialize(ar, static_cast&>(c), name, label); - } - else - { - typedef T (& Array)[4]; - return ar((Array)c, name, label); - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryExtension.h b/Code/CryEngine/CryCommon/Serialization/CryExtension.h deleted file mode 100644 index ed4e99fba1..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryExtension.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H -#pragma once - -#ifdef GetClassName -#undef GetClassName -#endif -#include - -namespace Serialization -{ - // Allows to have AZStd::shared_ptr but serialize it by - // interface-casting to TSerializable, i.e. implementing Serialization through - // separate interface. - template - struct CryExtensionPointer - { - AZStd::shared_ptr& ptr; - - CryExtensionPointer(AZStd::shared_ptr& _ptr) - : ptr(_ptr) {} - void Serialize(Serialization::IArchive& ar); - }; -} - -// This function treats T as a type derived from CryUnknown type. -template -bool Serialize(Serialization::IArchive& ar, AZStd::shared_ptr& ptr, const char* name, const char* label); - -#include "CryExtensionImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryExtensionImpl.h b/Code/CryEngine/CryCommon/Serialization/CryExtensionImpl.h deleted file mode 100644 index e976163d55..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryExtensionImpl.h +++ /dev/null @@ -1,281 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H -#pragma once - -#include -#include -#include -#include - -namespace Serialization { - // Generate user-friendly class name, e.g. convert - // "AnimationPoseModifier_FootStore" -> "Foot Store" - inline string MakePrettyClassName(const char* className) - { - const char* firstSep = strchr(className, '_'); - if (!firstSep) - { - // name doesn't follow expected convention, return as is - return className; - } - - const char* start = firstSep + 1; - string result; - result.reserve(strlen(start) + 4); - - const char* p = start; - while (*p != '\0') - { - if (*p >= 'A' && *p <= 'Z' && - *(p - 1) >= 'a' && *(p - 1) <= 'z') - { - result += ' '; - } - if (*p == '_') - { - result += ' '; - } - else - { - result += *p; - } - ++p; - } - - return result; - } - - // Provides Serialization::IClassFactory interface for classes - // registered with CryExtension to IArchive. - // - // TSerializable can be used to expose Serialize method through - // a separate interface, rathern than TBase. Safe to missing - // as QueryInterface is used to check its presence. - template - class CryExtensionClassFactory - : public Serialization::IClassFactory - { - public: - size_t size() const override - { - return m_types.size(); - } - - static CryExtensionClassFactory& the() - { - static CryExtensionClassFactory instance; - return instance; - } - - CryExtensionClassFactory() - : IClassFactory(Serialization::TypeID::get()) - { - setNullLabel("[ None ]"); - ICryFactoryRegistry* factoryRegistry = gEnv->pSystem->GetCryFactoryRegistry(); - - size_t factoryCount = 0; - factoryRegistry->IterateFactories(cryiidof(), 0, factoryCount); - - if (factoryCount) - { - string sharedPrefix; - bool hasSharedPrefix = true; - AZStd::unique_ptr factories(new ICryFactory*[factoryCount]); - factoryRegistry->IterateFactories(cryiidof(), factories.get(), factoryCount); - - for (size_t i = 0; i < factoryCount; ++i) - { - ICryFactory* factory = factories[i]; - if (factory->ClassSupports(cryiidof())) - { - m_factories.push_back(factory); - if (hasSharedPrefix) - { - // make sure that shared prefix is the same for all the names - const char* name = factory->GetName(); - const char* lastPrefixCharacter = strchr(name, '_'); - if (lastPrefixCharacter == 0) - { - hasSharedPrefix = false; - } - else - { - if (!sharedPrefix.empty()) - { - if (strncmp(name, sharedPrefix.c_str(), sharedPrefix.size()) != 0) - { - hasSharedPrefix = false; - } - } - else - { - sharedPrefix.assign(name, lastPrefixCharacter + 1); - } - } - } - } - } - - size_t usableFactoriesCount = m_factories.size(); - m_types.reserve(usableFactoriesCount); - m_labels.reserve(usableFactoriesCount); - - for (size_t i = 0; i < usableFactoriesCount; ++i) - { - ICryFactory* factory = m_factories[i]; - m_classIds.push_back(factory->GetClassID()); - const char* name = factory->GetName(); - m_labels.push_back(MakePrettyClassName(name)); - if (hasSharedPrefix) - { - name += sharedPrefix.size(); - } - m_types.push_back(Serialization::TypeDescription(name, m_labels.back().c_str())); - } - } - } - - const Serialization::TypeDescription* descriptionByIndex(int index) const override - { - if (size_t(index) >= m_types.size()) - { - return 0; - } - return &m_types[index]; - } - - const Serialization::TypeDescription* descriptionByRegisteredName(const char* registeredName) const override - { - size_t count = m_types.size(); - for (size_t i = 0; i < m_types.size(); ++i) - { - if (strcmp(m_types[i].name(), registeredName) == 0) - { - return &m_types[i]; - } - } - return 0; - } - - const char* findAnnotation(const char* typeName, const char* name) const override { return ""; } - - void serializeNewByIndex(IArchive& ar, int index, const char* name, const char* label) override - { - if (size_t(index) >= m_types.size()) - { - return; - } - AZStd::shared_ptr ptr(create(m_types[index].name())); - if (TSerializable* ser = cryinterface_cast(ptr.get())) - { - ar(*ser, name, label); - } - } - - AZStd::shared_ptr create(const char* registeredName) - { - size_t count = m_types.size(); - for (size_t i = 0; i < count; ++i) - { - if (strcmp(m_types[i].name(), registeredName) == 0) - { - return AZStd::static_pointer_cast(m_factories[i]->CreateClassInstance()); - } - } - return AZStd::shared_ptr(); - } - - const char* getRegisteredTypeName(const AZStd::shared_ptr& ptr) const - { - if (!ptr.get()) - { - return ""; - } - CryInterfaceID id = AZStd::static_pointer_cast(ptr)->GetFactory()->GetClassID(); - size_t count = m_classIds.size(); - for (size_t i = 0; i < count; ++i) - { - if (m_classIds[i] == id) - { - return m_types[i].name(); - } - } - return ""; - } - - private: - std::vector m_types; - std::vector m_labels; - std::vector m_factories; - std::vector m_classIds; - }; - - // Exposes CryExtension shared_ptr<> as serializeable type for Serialization::IArchive - template - class CryExtensionSharedPtr - : public Serialization::IPointer - { - public: - CryExtensionSharedPtr(AZStd::shared_ptr& ptr) - : m_ptr(ptr) - {} - - const char* registeredTypeName() const override - { - if (m_ptr) - { - return factory()->getRegisteredTypeName(m_ptr); - } - else - { - return ""; - } - } - - void create(const char* registeredTypeName) const override - { - if (registeredTypeName[0] != '\0') - { - m_ptr = factory()->create(registeredTypeName); - } - else - { - m_ptr.reset((T*)0); - } - } - - Serialization::TypeID baseType() const{ return Serialization::TypeID::get(); } - virtual Serialization::SStruct serializer() const override - { - if (TSerializable* ser = cryinterface_cast(m_ptr.get())) - { - return Serialization::SStruct(*ser); - } - else - { - return Serialization::SStruct(); - } - } - void* get() const override { return reinterpret_cast(m_ptr.get()); } - const void* handle() const override { return &m_ptr; } - Serialization::TypeID pointerType() const override { return Serialization::TypeID::get >(); } - CryExtensionClassFactory* factory() const override { return &CryExtensionClassFactory::the(); } - protected: - AZStd::shared_ptr& m_ptr; - }; -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryName.h b/Code/CryEngine/CryCommon/Serialization/CryName.h deleted file mode 100644 index 978af33379..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryName.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H -#pragma once - -namespace Serialization { - class IArchive; -} - -inline bool Serialize(Serialization::IArchive & ar, class CCryName & cryName, const char* name, const char* label); - -#include "CryNameImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryNameImpl.h b/Code/CryEngine/CryCommon/Serialization/CryNameImpl.h deleted file mode 100644 index e307892fd3..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryNameImpl.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H -#pragma once - -#include "CryName.h" -#include "IArchive.h" - -class CryNameSerializer - : public Serialization::IString -{ -public: - CryNameSerializer(CCryName& s) - : m_s(s) - { - } - - virtual void set(const char* value) - { - m_s = value; - } - - virtual const char* get() const - { - return m_s.c_str(); - } - - virtual const void* handle() const - { - return &m_s; - } - - virtual Serialization::TypeID type() const - { - return Serialization::TypeID::get(); - } - - CCryName& m_s; -}; - - -inline bool Serialize(Serialization::IArchive& ar, CCryName& cryName, const char* name, const char* label) -{ - CryNameSerializer serializer(cryName); - return ar(static_cast(serializer), name, label); -} - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryStrings.h b/Code/CryEngine/CryCommon/Serialization/CryStrings.h deleted file mode 100644 index 560f64c045..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryStrings.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "CryFixedString.h" - -#include "Serialization/Serializer.h" - -namespace Serialization -{ - class IArchive; -} - -// Note : if you are looking for the CryStringT serialization, it is handled in Serialization/STL.h - -template< size_t N > -bool Serialize(Serialization::IArchive& ar, CryFixedStringT< N >& value, const char* name, const char* label); - -template< size_t N > -bool Serialize(Serialization::IArchive& ar, CryStackStringT< char, N >& value, const char* name, const char* label); - -template< size_t N > -bool Serialize(Serialization::IArchive& ar, CryStackStringT< wchar_t, N >& value, const char* name, const char* label); - -#include "Serialization/CryStringsImpl.h" diff --git a/Code/CryEngine/CryCommon/Serialization/CryStringsImpl.h b/Code/CryEngine/CryCommon/Serialization/CryStringsImpl.h deleted file mode 100644 index 41de581b36..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryStringsImpl.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "Serialization/IArchive.h" -#include "Serialization/CryStrings.h" - -namespace Serialization -{ - template< class TFixedStringClass > - class CFixedStringSerializer - : public IString - { - public: - CFixedStringSerializer(TFixedStringClass& str) - : str_(str) { } - - void set(const char* value) { str_ = value; } - const char* get() const { return str_.c_str(); } - const void* handle() const { return &str_; } - TypeID type() const { return TypeID::get(); } - private: - TFixedStringClass& str_; - }; - - template< class TFixedStringClass > - class CFixedWStringSerializer - : public IWString - { - public: - CFixedWStringSerializer(TFixedStringClass& str) - : str_(str) { } - - void set(const wchar_t* value) { str_ = value; } - const wchar_t* get() const { return str_.c_str(); } - const void* handle() const { return &str_; } - TypeID type() const { return TypeID::get(); } - private: - TFixedStringClass& str_; - }; -} - -template< size_t N > -inline bool Serialize(Serialization::IArchive& ar, CryFixedStringT< N >& value, const char* name, const char* label) -{ - Serialization::CFixedStringSerializer< CryFixedStringT< N > > str(value); - return ar(static_cast(str), name, label); -} - -template< size_t N > -inline bool Serialize(Serialization::IArchive& ar, CryStackStringT< char, N >& value, const char* name, const char* label) -{ - Serialization::CFixedStringSerializer< CryStackStringT< char, N > > str(value); - return ar(static_cast(str), name, label); -} - -template< size_t N > -inline bool Serialize(Serialization::IArchive& ar, CryStackStringT< wchar_t, N >& value, const char* name, const char* label) -{ - Serialization::CFixedWStringSerializer< CryStackStringT< wchar_t, N > > str(value); - return ar(static_cast(str), name, label); -} - diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ActionButton.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ActionButton.h deleted file mode 100644 index 2e8e07f597..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ActionButton.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include -#include - -namespace Serialization -{ - struct IActionButton; - - DECLARE_SMART_POINTERS(IActionButton) - - struct IActionButton - { - virtual ~IActionButton() {} - - virtual void Callback() const = 0; - virtual const char* Icon() const = 0; - virtual IActionButtonPtr Clone() const = 0; - }; - - typedef AZStd::function FunctorActionButtonCallback; - - struct FunctorActionButton - : public IActionButton - { - FunctorActionButtonCallback callback; - string icon; - - explicit FunctorActionButton(const FunctorActionButtonCallback& callback, const char* icon = "") - : callback(callback) - , icon(icon) - { - } - - // IActionButton - - virtual void Callback() const override - { - if (callback) - { - callback(); - } - } - - virtual const char* Icon() const override - { - return icon.c_str(); - } - - virtual IActionButtonPtr Clone() const override - { - return IActionButtonPtr(new FunctorActionButton(callback, icon.c_str())); - } - - // ~IActionButton - }; - - inline bool Serialize(Serialization::IArchive& ar, FunctorActionButton& button, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(button)), name, label); - } - else - { - return false; - } - } - - inline FunctorActionButton ActionButton(const FunctorActionButtonCallback& callback, const char* icon = "") - { - return FunctorActionButton(callback, icon); - } -} - diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlags.h b/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlags.h deleted file mode 100644 index 1e23ecee27..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlags.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H -#pragma once - -#include - -namespace Serialization { - class IArchive; - - struct BitFlagsWrapper - { - int* variable; - unsigned int visibleMask; - const CEnumDescription* description; - - void Serialize(IArchive& ar); - }; - - template - BitFlagsWrapper BitFlags(Enum& value) - { - BitFlagsWrapper wrapper; - wrapper.variable = (int*)&value; - wrapper.visibleMask = ~0U; - wrapper.description = &getEnumDescription(); - return wrapper; - } - - template - BitFlagsWrapper BitFlags(int& value, int visibleMask = ~0) - { - BitFlagsWrapper wrapper; - wrapper.variable = &value; - wrapper.visibleMask = visibleMask; - wrapper.description = &getEnumDescription(); - return wrapper; - } - - template - BitFlagsWrapper BitFlags(unsigned int& value, unsigned int visibleMask = ~0) - { - BitFlagsWrapper wrapper; - wrapper.variable = (int*)&value; - wrapper.visibleMask = visibleMask; - wrapper.description = &getEnumDescription(); - return wrapper; - } -} - -#include "BitFlagsImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlagsImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlagsImpl.h deleted file mode 100644 index 77b48fd1f0..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlagsImpl.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H -#pragma once - -#include "Serialization/IArchive.h" - -namespace Serialization { - inline void BitFlagsWrapper::Serialize(IArchive& ar) - { - const Serialization::CEnumDescription& desc = *description; - int count = desc.count(); - if (ar.IsInput()) - { - int previousValue = *variable; - for (int i = 0; i < count; ++i) - { - int flagValue = desc.valueByIndex(i); - if (!(flagValue & visibleMask)) - { - continue; - } - bool flag = (previousValue & flagValue) == flagValue; - bool previousFlag = flag; - ar(flag, desc.nameByIndex(i), desc.labelByIndex(i)); - if (flag != previousFlag) - { - if (flag) - { - *variable |= flagValue; - } - else - { - *variable &= ~flagValue; - } - } - } - } - else - { - for (int i = 0; i < count; ++i) - { - int flagValue = desc.valueByIndex(i); - if (!(flagValue & visibleMask)) - { - continue; - } - bool flag = (*variable & flagValue) == flagValue; - ar(flag, desc.nameByIndex(i), desc.labelByIndex(i)); - } - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPicker.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPicker.h deleted file mode 100644 index 146e7bf42f..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPicker.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H -#pragma once - -#include -#include - -#include - -namespace Serialization -{ - class IArchive; - - struct ColorPicker - { - ColorF* color; - - explicit ColorPicker(ColorF& color_) - : color(&color_) - { - } - - // the function should stay virtual to ensure cross-dll calls are using right heap - virtual void SetColor(const ColorF* color_){* color = *color_; } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::ColorPicker& value, const char* name, const char* label); -} // namespace Serialization - -#include "ColorPickerImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPickerImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPickerImpl.h deleted file mode 100644 index 6585f40a91..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPickerImpl.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H -#pragma once - -#include "../Color.h" - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::ColorPicker& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.color, name, label); - } - } -} // namespace Serialization - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/JointName.h b/Code/CryEngine/CryCommon/Serialization/Decorators/JointName.h deleted file mode 100644 index 69195c20bf..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/JointName.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H -#pragma once - -#include -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/JointNameImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/JointNameImpl.h deleted file mode 100644 index ad168a92a3..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/JointNameImpl.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H -#pragma once - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrame.h b/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrame.h deleted file mode 100644 index 39841623f9..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrame.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H -#pragma once - -#include -#include "Serialization/Math.h" - -namespace Serialization -{ - class IArchive; - - struct LocalPosition - { - Vec3* value; - int space; - const char* parentName; - const void* handle; - - LocalPosition(Vec3& _vec, int _space, const char* _parentName, const void* _handle) - : value(&_vec) - , space(_space) - , parentName(_parentName) - , handle(_handle) - { - } - - void Serialize(IArchive& ar); - }; - - struct LocalOrientation - { - Quat* value; - int space; - const char* parentName; - const void* handle; - - LocalOrientation(Quat& _vec, int _space, const char* _parentName, const void* _handle) - : value(&_vec) - , space(_space) - , parentName(_parentName) - , handle(_handle) - { - } - - void Serialize(IArchive& ar); - }; - - struct LocalFrame - { - Quat* rotation; - Vec3* position; - const char* parentName; - int rotationSpace; - int positionSpace; - const void* handle; - - LocalFrame(Quat* _rotation, int _rotationSpace, Vec3* _position, int _positionSpace, const char* _parentName, const void* _handle) - : rotation(_rotation) - , position(_position) - , parentName(_parentName) - , rotationSpace(_rotationSpace) - , positionSpace(_positionSpace) - , handle(_handle) - { - } - - void Serialize(IArchive& ar); - }; - - enum - { - SPACE_JOINT, - SPACE_ENTITY, - SPACE_JOINT_WITH_PARENT_ROTATION, - SPACE_JOINT_WITH_CHARACTER_ROTATION, - SPACE_SOCKET_RELATIVE_TO_JOINT, - SPACE_SOCKET_RELATIVE_TO_BINDPOSE - }; - - - - //position - inline LocalPosition LocalToEntity(Vec3& position, const void* handle = 0) - { - return LocalPosition(position, SPACE_ENTITY, "", handle ? handle : &position); - } - inline LocalPosition LocalToJoint(Vec3& position, const string& jointName, const void* handle = 0) - { - return LocalPosition(position, SPACE_JOINT, jointName.c_str(), handle ? handle : &position); - } - - inline LocalPosition LocalToJointCharacterRotation(Vec3& position, const string& jointName, const void* handle = 0) - { - return LocalPosition(position, SPACE_JOINT_WITH_CHARACTER_ROTATION, jointName.c_str(), handle ? handle : &position); - } - - bool Serialize(Serialization::IArchive& ar, Serialization::LocalPosition& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::LocalOrientation& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::LocalFrame& value, const char* name, const char* label); -} - -#include "LocalFrameImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrameImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrameImpl.h deleted file mode 100644 index 774cc06852..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrameImpl.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAMEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAMEIMPL_H -#pragma once - -#include "LocalFrame.h" -#include "Serialization/IArchive.h" -#include "Serialization/MathImpl.h" - -namespace Serialization -{ - inline void LocalPosition::Serialize(Serialization::IArchive& ar) - { - ar(value->x, "x", "^"); - ar(value->y, "y", "^"); - ar(value->z, "z", "^"); - } - - inline void LocalOrientation::Serialize(Serialization::IArchive& ar) - { - ar(Serialization::AsAng3(*value), "q", "^"); - } - - inline void LocalFrame::Serialize(Serialization::IArchive& ar) - { - ar(*position, "t", "m_path = path; } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::OutputFilePath& value, const char* name, const char* label); -} - -#include "OutputFilePathImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATH_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/OutputFilePathImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/OutputFilePathImpl.h deleted file mode 100644 index 29d64fcff7..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/OutputFilePathImpl.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H -#pragma once - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::OutputFilePath& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.m_path, name, label); - } - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/Range.h b/Code/CryEngine/CryCommon/Serialization/Decorators/Range.h deleted file mode 100644 index 7966c579dd..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/Range.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGE_H -#pragma once - -namespace Serialization -{ - template - struct RangeDecorator - { - T* value; - T softMin; - T softMax; - T hardMin; - T hardMax; - }; - - template - RangeDecorator Range(T& value, T hardMin, T hardMax) - { - RangeDecorator r; - r.value = &value; - r.softMin = hardMin; - r.softMax = hardMax; - r.hardMin = hardMin; - r.hardMax = hardMax; - return r; - } - - template - RangeDecorator Range(T& value, T softMin, T softMax, T hardMin, T hardMax) - { - RangeDecorator r; - r.value = &value; - r.softMin = softMin; - r.softMax = softMax; - r.hardMin = hardMin; - r.hardMax = hardMax; - return r; - } - - namespace Decorators - { - // Obsolete name, will be removed. Please use Serialization::Range instead. - using Serialization::Range; - } -} - -#include "RangeImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGE_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/RangeImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/RangeImpl.h deleted file mode 100644 index bc0508f3cb..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/RangeImpl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGEIMPL_H -#pragma once - -namespace Serialization -{ - template - bool Serialize(IArchive& ar, RangeDecorator& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - if (!ar(SStruct::ForEdit(value), name, label)) - { - return false; - } - } - else if (!ar(*value.value, name, label)) - { - return false; - } - - if (ar.IsInput()) - { - if (*value.value < value.hardMin) - { - *value.value = value.hardMin; - } - if (*value.value > value.hardMax) - { - *value.value = value.hardMax; - } - } - return true; - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGEIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePath.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePath.h deleted file mode 100644 index 0f0c6dc34e..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePath.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATH_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATH_H -#pragma once - -#include "Serialization/Strings.h" - -namespace Serialization -{ - class IArchive; - - struct ResourceFilePath - { - enum - { - STRIP_EXTENSION = 1 << 0 - }; - - string* m_path; - string filter; - bool group; - int flags; - - // filters are defined in the following format: - // "All Images (bmp, jpg, tga)|*.bmp;*.jpg;*.tga|Targa (tga)|*.tga" - explicit ResourceFilePath(string& path, const char* filter = "", bool group = false, int flags = 0) - : m_path(&path) - , filter(filter) - , group(group) - , flags(flags) - { - } - - // the function should stay virtual to ensure cross-dll calls are using right heap - virtual void SetPath(const char* path) { *this->m_path = path; } - }; - - inline ResourceFilePath MaterialPath(string& path) - { - return ResourceFilePath(path, "Material", false, ResourceFilePath::STRIP_EXTENSION); - } - - bool Serialize(Serialization::IArchive& ar, Serialization::ResourceFilePath& value, const char* name, const char* label); -} - -#include "ResourceFilePathImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATH_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePathImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePathImpl.h deleted file mode 100644 index 66c9140236..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePathImpl.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATHIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATHIMPL_H -#pragma once - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::ResourceFilePath& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.m_path, name, label); - } - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATHIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPath.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPath.h deleted file mode 100644 index 327f668e43..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPath.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATH_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATH_H -#pragma once - -#include "Serialization/Strings.h" - -namespace Serialization -{ - class IArchive; - - struct ResourceFolderPath - { - string* m_path; - string startFolder; - - explicit ResourceFolderPath(string& path, const char* startFolder = "") - : m_path(&path) - , startFolder(startFolder) - { - } - - // the function should stay virtual to ensure cross-dll calls are using right heap - virtual void SetPath(const char* path) { *this->m_path = path; } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::ResourceFolderPath& value, const char* name, const char* label); -} - -#include "ResourceFolderPathImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATH_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPathImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPathImpl.h deleted file mode 100644 index 33ceacbe10..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPathImpl.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATHIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATHIMPL_H -#pragma once - -#include "Serialization/IArchive.h" - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::ResourceFolderPath& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.m_path, name, label); - } - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATHIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceSelector.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceSelector.h deleted file mode 100644 index 3b9920be6c..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceSelector.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -namespace Serialization -{ - struct IResourceSelector - { - const char* resourceType; - - virtual ~IResourceSelector() {} - virtual const char* GetValue() const = 0; - virtual void SetValue(const char* s) = 0; - virtual int GetId() const{ return -1; } - virtual const void* GetHandle() const = 0; - virtual Serialization::TypeID GetType() const = 0; - }; - - // Provides a way to annotate resource reference so different UI can be used - // for them. See IResourceSelector.h to see how selectors for specific types - // are registered. - // - // TString could be SCRCRef or CCryName as well. - // - // Do not use this class directly, instead use function that wraps it for - // specific type, see Resources.h for example. - template - struct ResourceSelector - : IResourceSelector - { - TString& value; - - const char* GetValue() const { return value.c_str(); } - void SetValue(const char* s) { value = s; } - const void* GetHandle() const { return &value; } - Serialization::TypeID GetType() const { return Serialization::TypeID::get(); } - - ResourceSelector(TString& _value, const char* _resourceType) - : value(_value) - { - this->resourceType = _resourceType; - } - }; - - struct ResourceSelectorWithId - : IResourceSelector - { - string& value; - int id; - - const char* GetValue() const { return value.c_str(); } - void SetValue(const char* s) { value = s; } - int GetId() const { return id; } - const void* GetHandle() const { return &value; } - Serialization::TypeID GetType() const { return Serialization::TypeID::get(); } - - ResourceSelectorWithId(string& _value, const char* _resourceType, int _id) - : value(_value) - , id(_id) - { - this->resourceType = _resourceType; - } - }; - - template - bool Serialize(IArchive& ar, ResourceSelector& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(value)), name, label); - } - else - { - return ar(value.value, name, label); - } - } - - inline bool Serialize(IArchive& ar, ResourceSelectorWithId& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(value)), name, label); - } - else - { - return ar(value.value, name, label); - } - } -} diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/Resources.h b/Code/CryEngine/CryCommon/Serialization/Decorators/Resources.h deleted file mode 100644 index 637fc937ed..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/Resources.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCES_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCES_H -#pragma once -#include "ResourceSelector.h" - -namespace Serialization -{ - // animation resources - template - ResourceSelector AnimationAlias(T& s) { return ResourceSelector(s, "AnimationAlias"); } // "name" from animation set - template - ResourceSelector AnimationPath(T& s) { return ResourceSelector(s, "Animation"); } - inline ResourceSelectorWithId AnimationPathWithId(string& s, int id) { return ResourceSelectorWithId(s, "Animation", id); } - template - ResourceSelector CharacterPath(T& s) { return ResourceSelector(s, "Character"); } - template - ResourceSelector CharacterPhysicsPath(T& s) { return ResourceSelector(s, "CharacterPhysics"); } - template - ResourceSelector CharacterRigPath(T& s) { return ResourceSelector(s, "CharacterRig"); } - template - ResourceSelector SkeletonPath(T& s) { return ResourceSelector(s, "Skeleton"); } - template - ResourceSelector SkeletonParamsPath(T& s) { return ResourceSelector(s, "SkeletonParams"); } // CHRParams - template - ResourceSelector JointName(T& s) { return ResourceSelector(s, "Joint"); } - template - ResourceSelector AttachmentName(T& s) { return ResourceSelector(s, "Attachment"); } - - // miscelaneous resources - template - ResourceSelector SoundName(T& s) { return ResourceSelector(s, "Sound"); } - template - ResourceSelector DialogName(T& s) { return ResourceSelector(s, "Dialog"); } - template - ResourceSelector ForceFeedbackIdName(T& s) { return ResourceSelector(s, "ForceFeedbackId"); } - template - ResourceSelector ModelFilename(T& s) { return ResourceSelector(s, "Model"); } - template - ResourceSelector ParticleName(T& s) { return ResourceSelector(s, "Particle"); } - - namespace Decorators - { - // Decorators namespace is obsolete now, SHOULD NOT BE USED. - template - ResourceSelector AnimationName(T& s) { return ResourceSelector(s, "Animation"); } - using Serialization::SoundName; - using Serialization::AttachmentName; - template - ResourceSelector ObjectFilename(T& s) { return ResourceSelector(s, "Model"); } - using Serialization::JointName; - using Serialization::ForceFeedbackIdName; - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCES_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesAudio.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesAudio.h deleted file mode 100644 index 9e10be6c3b..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesAudio.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#include "ResourceSelector.h" - -namespace Serialization -{ - template - ResourceSelector AudioTrigger(T& s) { return ResourceSelector(s, "AudioTrigger"); } - template - ResourceSelector AudioSwitch(T& s) { return ResourceSelector(s, "AudioSwitch"); } - template - ResourceSelector AudioSwitchState(T& s) { return ResourceSelector(s, "AudioSwitchState"); } - template - ResourceSelector AudioRTPC(T& s) { return ResourceSelector(s, "AudioRTPC"); } - template - ResourceSelector AudioEnvironment(T& s) { return ResourceSelector(s, "AudioEnvironment"); } - template - ResourceSelector AudioPreloadRequest(T& s) { return ResourceSelector(s, "AudioPreloadRequest"); } -}; diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesImpl.h deleted file mode 100644 index dde4e1ae0c..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesImpl.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCESIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCESIMPL_H -#pragma once - -namespace Serialization -{ - template - bool Serialize(IArchive& ar, ResourceSelector& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(value)), name, label); - } - else - { - return ar(value.value, name, label); - } - } - - inline bool Serialize(IArchive& ar, ResourceSelectorWithId& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(value)), name, label); - } - else - { - return ar(value.value, name, label); - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCESIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/Slider.h b/Code/CryEngine/CryCommon/Serialization/Decorators/Slider.h deleted file mode 100644 index 8be5086660..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/Slider.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDER_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDER_H -#pragma once - -namespace Serialization -{ - class IArchive; - - struct SSliderF - { - SSliderF(float* value, float _minLimit, float _maxLimit) - : valuePointer(value) - , minLimit(_minLimit) - , maxLimit(_maxLimit) - { - } - - SSliderF() - : valuePointer(0) - , minLimit(0.0f) - , maxLimit(1.0f) - { - } - - - float* valuePointer; - float minLimit; - float maxLimit; - }; - - struct SSliderI - { - SSliderI(int* value, int minLimit, int maxLimit) - : valuePointer(value) - , minLimit(minLimit) - , maxLimit(maxLimit) - { - } - - SSliderI() - : valuePointer(0) - , minLimit(0) - , maxLimit(1) - { - } - - int* valuePointer; - int minLimit; - int maxLimit; - }; - - - inline SSliderF Slider(float& value, float minLimit, float maxLimit) - { - return SSliderF(&value, minLimit, maxLimit); - } - - inline SSliderI Slider(int& value, int minLimit, int maxLimit) - { - return SSliderI(&value, minLimit, maxLimit); - } - - bool Serialize(IArchive& ar, SSliderF& slider, const char* name, const char* label); - bool Serialize(IArchive& ar, SSliderI& slider, const char* name, const char* label); - - namespace Decorators - { - // OBSOLETE NAME, please use Serialization::Slider instead (without Decorators namespace) - using Serialization::Slider; - } -} - -#include "SliderImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDER_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/SliderImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/SliderImpl.h deleted file mode 100644 index c9e0dfc891..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/SliderImpl.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDERIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDERIMPL_H -#pragma once - -#include "Slider.h" -#include "Serialization/IArchive.h" - -namespace Serialization -{ - inline bool Serialize(IArchive& ar, SSliderF& slider, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(SStruct::ForEdit(slider), name, label); - } - else - { - return ar(*slider.valuePointer, name, label); - } - } - - inline bool Serialize(IArchive& ar, SSliderI& slider, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(SStruct::ForEdit(slider), name, label); - } - else - { - return ar(*slider.valuePointer, name, label); - } - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDERIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/Sprite.h b/Code/CryEngine/CryCommon/Serialization/Decorators/Sprite.h deleted file mode 100644 index 0eeefd7536..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/Sprite.h +++ /dev/null @@ -1,44 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITE_H -#pragma once - -namespace Serialization -{ -class IArchive; - -struct Sprite -{ - string* m_path; - string m_filter; - string m_startFolder; - - // filters are defined in the following format: - // "All Images (bmp, jpg, tga)|*.bmp;*.jpg;*.tga|Targa (tga)|*.tga" - explicit Sprite(string& path, const char* filter = "All files|*.*", const char* startFolder = "") - : m_path(&path) - , m_filter(filter) - , m_startFolder(startFolder) - { - } -}; - -bool Serialize(IArchive& ar, Sprite& value, const char* name, const char* label); - -} // namespace Serialization - -#include "SpriteImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITE_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/SpriteImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/SpriteImpl.h deleted file mode 100644 index 6d0075fafc..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/SpriteImpl.h +++ /dev/null @@ -1,35 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITEIMPL_H -#pragma once - -namespace Serialization -{ - -inline bool Serialize(IArchive& ar, Sprite& value, const char* name, const char* label) -{ - if (ar.IsEdit()) - { - return ar(SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.m_path, name, label); - } -} - -} // namespace Serialization - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITEIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/TagList.h b/Code/CryEngine/CryCommon/Serialization/Decorators/TagList.h deleted file mode 100644 index 4c4ad81ebf..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/TagList.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLIST_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLIST_H -#pragma once - -#include -#include "Serialization/Strings.h" - -namespace Serialization { - class IArchive; -} - -struct ITagSource -{ - virtual void AddRef() = 0; - virtual void Release() = 0; - virtual unsigned int TagCount(unsigned int group) const = 0; - virtual const char* TagValue(unsigned int group, unsigned int index) const = 0; - virtual const char* TagDescription(unsigned int group, unsigned int index) const = 0; - virtual const char* GroupName(unsigned int group) const = 0; - virtual unsigned int GroupCount() const = 0; -}; - -struct TagList -{ - std::vector* tags; - - TagList(std::vector& tags) - : tags(&tags) - { - } -}; - -bool Serialize(Serialization::IArchive& ar, TagList& tagList, const char* name, const char* label); - -#include "TagListImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLIST_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/TagListImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/TagListImpl.h deleted file mode 100644 index 2ee6e1769b..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/TagListImpl.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLISTIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLISTIMPL_H -#pragma once - -#include -#include "Serialization/IArchive.h" -#include "Serialization/Strings.h" -#include "Serialization/STL.h" - -struct TagListContainer - : Serialization::ContainerSTL, Serialization::string> -{ - TagListContainer(TagList& tagList) - : ContainerSTL(tagList.tags) - { - } - - Serialization::TypeID containerType() const override { return Serialization::TypeID::get(); }; -}; - -inline bool Serialize(Serialization::IArchive& ar, TagList& tagList, const char* name, const char* label) -{ - TagListContainer container(tagList); - return ar(static_cast(container), name, label); -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLISTIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/DynArray.h b/Code/CryEngine/CryCommon/Serialization/DynArray.h deleted file mode 100644 index 1904cf4ac3..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/DynArray.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAY_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAY_H -#pragma once - -namespace Serialization { - class IArchive; -} - -template -bool Serialize(Serialization::IArchive& ar, DynArray& container, const char* name, const char* label); - -#include "DynArrayImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAY_H diff --git a/Code/CryEngine/CryCommon/Serialization/DynArrayImpl.h b/Code/CryEngine/CryCommon/Serialization/DynArrayImpl.h deleted file mode 100644 index c437604f67..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/DynArrayImpl.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAYIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAYIMPL_H -#pragma once - -#include "IArchive.h" -#include "STLImpl.h" - -template -bool Serialize(Serialization::IArchive& ar, DynArray& container, const char* name, const char* label) -{ - Serialization::ContainerSTL, T> ser(&container); - return ar(static_cast(ser), name, label); -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAYIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Enum.h b/Code/CryEngine/CryCommon/Serialization/Enum.h deleted file mode 100644 index e377269013..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Enum.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUM_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUM_H -#pragma once - - -#include -#include - -#include "StringList.h" -#include "Serialization/TypeID.h" - -namespace Serialization { - class IArchive; - - struct LessStrCmp - { - bool operator()(const char* l, const char* r) const - { - return strcmp(l, r) < 0; - } - }; - - class CEnumDescription - { - public: - struct NameValue - { - NameValue* m_next; - const char* m_name; - const int m_value; - const char* m_label; - - NameValue(CEnumDescription& desc, const char* name, int value, const char* label="") - : m_next(desc.m_regListHead) - , m_name(name) - , m_value(value) - , m_label(label) - { - desc.m_regListHead = this; - } - }; - - NameValue* m_regListHead = nullptr; - - CEnumDescription(const Serialization::TypeID& type) - : type_(type) {} - inline int value(const char* name) const; - inline int valueByIndex(int index) const; - inline int valueByLabel(const char* label) const; - inline const char* name(int value) const; - inline const char* nameByIndex(int index) const; - inline const char* labelByIndex(int index) const; - inline const char* label(int value) const; - inline const char* indexByName(const char* name) const; - inline int indexByValue(int value) const; - - inline bool Serialize(IArchive& ar, int& value, const char* name, const char* label) const; - inline bool serializeBitVector(IArchive& ar, int& value, const char* name, const char* label) const; - - void add(int value, const char* name, const char* label = ""); - int count() const{ return int(values_.size()); } - const StringListStatic& names() const{ return names_; } - const StringListStatic& labels() const{ return labels_; } - inline StringListStatic nameCombination(int bitVector) const; - inline StringListStatic labelCombination(int bitVector) const; - bool registered() const { return !names_.empty(); } - TypeID type() const{ return type_; } - private: - void lazyRegister() const; - - StringListStatic names_; - StringListStatic labels_; - - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> NameToValue; - NameToValue nameToValue_; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> LabelToValue; - LabelToValue labelToValue_; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> ValueToIndex; - ValueToIndex valueToIndex_; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> ValueToName; - ValueToName valueToName_; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> ValueToLabel; - ValueToName valueToLabel_; - AZStd::vector values_; - TypeID type_; - }; - - template - class EnumDescriptionImpl - : public CEnumDescription - { - EnumDescriptionImpl() - : CEnumDescription(Serialization::TypeID::get()) {} - public: - static CEnumDescription& the() - { - static EnumDescriptionImpl description; - return description; - } - }; - - template - CEnumDescription& getEnumDescription() - { - return EnumDescriptionImpl::the(); - } - - inline bool serializeEnum(const CEnumDescription& desc, IArchive& ar, int& value, const char* name, const char* label) - { - return desc.Serialize(ar, value, name, label); - } -} - -#define SERIALIZATION_ENUM_BEGIN(Type, label) \ - namespace { \ - bool registerEnum_##Type(); \ - bool Type##_enum_registered = registerEnum_##Type(); \ - bool registerEnum_##Type(){ \ - Serialization::CEnumDescription& description = Serialization::EnumDescriptionImpl::the(); - -#define SERIALIZATION_ENUM_BEGIN_NESTED(Class, Enum, label) \ - namespace { \ - bool registerEnum_##Class##_##Enum(); \ - bool Class##_##Enum##_enum_registered = registerEnum_##Class##_##Enum(); \ - bool registerEnum_##Class##_##Enum(){ \ - Serialization::CEnumDescription& description = Serialization::EnumDescriptionImpl::the(); - -#define SERIALIZATION_ENUM_BEGIN_NESTED2(Class, Class1, Enum, label) \ - namespace { \ - bool registerEnum_##Class##Class1##_##Enum(); \ - bool Class##Class1##_##Enum##_enum_registered = registerEnum_##Class##Class1##_##Enum(); \ - bool registerEnum_##Class##Class1##_##Enum(){ \ - Serialization::CEnumDescription& description = Serialization::EnumDescriptionImpl::the(); - - -#define SERIALIZATION_ENUM_VALUE(value, label) \ - static Serialization::CEnumDescription::NameValue AZ_JOIN(enumValue, __LINE__)(description, label, (int)value); - -#define SERIALIZATION_ENUM(value, name, label) \ - static Serialization::CEnumDescription::NameValue AZ_JOIN(enumValue, __LINE__)(description, name, (int)value, label); - -#define SERIALIZATION_ENUM_VALUE_NESTED(Class, value, label) \ - static Serialization::CEnumDescription::NameValue AZ_JOIN(enumValue, __LINE__)(description, #value, (int)Class::value, label); - -#define SERIALIZATION_ENUM_VALUE_NESTED2(Class, Class1, value, label) \ - static Serialization::CEnumDescription::NameValue AZ_JOIN(enumValue, __LINE__)(description, #value, (int)Class::Class1::value, label); - - -#define SERIALIZATION_ENUM_END() \ - return true; \ - }; \ - }; - -#include "EnumImpl.h" -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUM_H diff --git a/Code/CryEngine/CryCommon/Serialization/EnumImpl.h b/Code/CryEngine/CryCommon/Serialization/EnumImpl.h deleted file mode 100644 index e5af93e43c..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/EnumImpl.h +++ /dev/null @@ -1,248 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H -#pragma once - -#pragma once -#include "IArchive.h" -#include "STL.h" -#include "Enum.h" -#include "StringList.h" -#ifndef SERIALIZATION_STANDALONE -#include -#endif - -namespace Serialization { - inline void CEnumDescription::add(int value, const char* name, const char* label) - { - YASLI_ESCAPE(name && label, return ); - // Filter for dupes in case enum description included in a shared header - NameToValue::iterator nameIt = nameToValue_.find(name); - if (nameIt != nameToValue_.end() && nameIt->second == value) - { LabelToValue::iterator labelIt = labelToValue_.find(label); - if (labelIt != labelToValue_.end() && labelIt->second == value) - { - return; - } - } - nameToValue_[name] = value; - labelToValue_[label] = value; - valueToName_[value] = name; - valueToLabel_[value] = label; - valueToIndex_[value] = int(names_.size()); - names_.push_back(name); - labels_.push_back(label); - values_.push_back(value); - } - - inline bool CEnumDescription::Serialize(IArchive& ar, int& value, const char* name, const char* label) const - { - lazyRegister(); - if (!ar.IsInPlace()) - { - if (count() == 0) - { -#ifdef SERIALIZATION_STANDALONE - assert(0 && "Attempt to serialize enum type that is not registered with SERIALIZATION_ENUM macro"); -#else - CryFatalError("Attempt to serialize enum type that is not registered with SERIALIZATION_ENUM macro: %s", type().name()); -#endif - return false; - } - - int index = StringListStatic::npos; - if (ar.IsOutput()) - { - index = indexByValue(value); - } - StringListStaticValue stringListValue(ar.IsEdit() ? labels() : names(), index, &value, type()); - ar(stringListValue, name, label); - if (ar.IsInput()) - { - if (stringListValue.index() == StringListStatic::npos) - { - return false; - } - value = ar.IsEdit() ? valueByLabel(stringListValue.c_str()) : this->value(stringListValue.c_str()); - } - else if (index == StringListStatic::npos) - { - ar.Error(&value, type(), "Unregistered or uninitialized enumeration value."); - } - } - else - { - return ar(value, name, label); - } - return true; - } - - inline bool CEnumDescription::serializeBitVector(IArchive& ar, int& value, const char* name, const char* label) const - { - lazyRegister(); - if (ar.IsOutput()) - { - StringListStatic names = nameCombination(value); - string str; - joinStringList(&str, names, '|'); - return ar(str, name, label); - } - else - { - string str; - if (!ar(str, name, label)) - { - return false; - } - StringList values; - splitStringList(&values, str.c_str(), '|'); - StringList::iterator it; - value = 0; - for (it = values.begin(); it != values.end(); ++it) - { - if (!it->empty()) - { - value |= this->value(it->c_str()); - } - } - return true; - } - } - - - inline const char* CEnumDescription::name(int value) const - { - lazyRegister(); - ValueToName::const_iterator it = valueToName_.find(value); - YASLI_ESCAPE(it != valueToName_.end(), return ""); - return it->second; - } - inline const char* CEnumDescription::label(int value) const - { - lazyRegister(); - ValueToLabel::const_iterator it = valueToLabel_.find(value); - YASLI_ESCAPE(it != valueToLabel_.end(), return ""); - return it->second; - } - - inline StringListStatic CEnumDescription::nameCombination(int bitVector) const - { - lazyRegister(); - StringListStatic strings; - for (ValueToName::const_iterator i = valueToName_.begin(); i != valueToName_.end(); ++i) - { - if ((bitVector & i->first) == i->first) - { - bitVector &= ~i->first; - strings.push_back(i->second); - } - } - YASLI_ASSERT(!bitVector && "Unregistered enum value"); - return strings; - } - - inline StringListStatic CEnumDescription::labelCombination(int bitVector) const - { - lazyRegister(); - StringListStatic strings; - for (ValueToLabel::const_iterator i = valueToLabel_.begin(); i != valueToLabel_.end(); ++i) - { - if (i->second && (bitVector & i->first) == i->first) - { - bitVector &= ~i->first; - strings.push_back(i->second); - } - } - YASLI_ASSERT(!bitVector && "Unregistered enum value"); - return strings; - } - - - inline int CEnumDescription::indexByValue(int value) const - { - lazyRegister(); - ValueToIndex::const_iterator it = valueToIndex_.find(value); - if (it == valueToIndex_.end()) - { - return -1; - } - else - { - return it->second; - } - } - - inline int CEnumDescription::valueByIndex(int index) const - { - lazyRegister(); - if (size_t(index) < values_.size()) - { - return values_[index]; - } - return 0; - } - - inline const char* CEnumDescription::nameByIndex(int index) const - { - lazyRegister(); - if (size_t(index) < size_t(names_.size())) - { - return names_[size_t(index)]; - } - return 0; - } - - inline const char* CEnumDescription::labelByIndex(int index) const - { - lazyRegister(); - if (size_t(index) < size_t(labels_.size())) - { - return labels_[size_t(index)]; - } - return 0; - } - - inline int CEnumDescription::value(const char* name) const - { - lazyRegister(); - NameToValue::const_iterator it = nameToValue_.find(name); - YASLI_ESCAPE(it != nameToValue_.end(), return 0); - return it->second; - } - inline int CEnumDescription::valueByLabel(const char* label) const - { - lazyRegister(); - LabelToValue::const_iterator it = labelToValue_.find(label); - YASLI_ESCAPE(it != labelToValue_.end(), return 0); - return it->second; - } - - inline void CEnumDescription::lazyRegister() const - { - if (m_regListHead) - { - NameValue* val = m_regListHead; - while (val) - { - const_cast(this)->add(val->m_value, val->m_name, val->m_label); - val = val->m_next; - } - const_cast(this)->m_regListHead = nullptr; - } - } -} -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/IArchive.h b/Code/CryEngine/CryCommon/Serialization/IArchive.h deleted file mode 100644 index 30de83ccc1..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IArchive.h +++ /dev/null @@ -1,446 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_IARCHIVE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_IARCHIVE_H -#pragma once - - -#include -#include - -#include "Serializer.h" -#include "KeyValue.h" -#include "TypeID.h" - -namespace Serialization { - class IArchive; - - template - bool Serialize(Serialization::IArchive& ar, T& object, const char* name, const char* label); - - class CEnumDescription; - template - CEnumDescription& getEnumDescription(); - bool serializeEnum(const CEnumDescription& desc, IArchive& ar, int& value, const char* name, const char* label); - - // SContextLink should not be used directly. See SContext<> below. - struct SContextLink - { - SContextLink* outer; - TypeID type; - void* contextObject; - - SContextLink() - : outer() - , contextObject() - { - } - }; - - struct SBlackBox; - struct ICallback; - - class IArchive - { - public: - enum ArchiveCaps - { - INPUT = 1 << 0, - OUTPUT = 1 << 1, - TEXT = 1 << 2, - BINARY = 1 << 3, - EDIT = 1 << 4, - INPLACE = 1 << 5, - NO_EMPTY_NAMES = 1 << 6, - VALIDATION = 1 << 7, - DOCUMENTATION = 1 << 8 - }; - - IArchive(int caps) - : caps_(caps) - , filter_(0) - , innerContext_(0) - { - } - virtual ~IArchive() {} - - bool IsInput() const{ return caps_ & INPUT ? true : false; } - bool IsOutput() const{ return caps_ & OUTPUT ? true : false; } - bool IsEdit() const - { -#if !defined(CONSOLE) && !defined(RELEASE) - return (caps_ & EDIT) != 0; -#else - return false; -#endif - } - bool IsInPlace() const{ return caps_ & INPLACE ? true : false; } - bool GetCaps(int caps) const { return (caps_ & caps) == caps; } - - void SetFilter(int filter) - { - filter_ = filter; - } - int GetFilter() const{ return filter_; } - bool Filter(int flags) const - { - YASLI_ASSERT(flags != 0 && "flags is supposed to be a bit mask"); - YASLI_ASSERT(filter_ && "Filter is not set!"); - return (filter_ & flags) != 0; - } - - virtual bool operator()([[maybe_unused]] bool& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] char& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] uint8& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] int8& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] int16& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] uint16& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] int32& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] uint32& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] int64& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] uint64& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] float& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] double& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - - virtual bool operator()([[maybe_unused]] IString& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] IWString& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] const SStruct& ser, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] IContainer& ser, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { return false; } - virtual bool operator()(IPointer& ptr, const char* name = "", const char* label = 0); - virtual bool operator()(IKeyValue& keyValue, const char* name = "", const char* label = 0) { return operator()(SStruct(keyValue), name, label); } - virtual bool operator()([[maybe_unused]] const SBlackBox& blackBox, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { return false; } - virtual bool operator()([[maybe_unused]] ICallback& callback, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { return false; } - - template - bool operator()(const T& value, const char* name = "", const char* label = 0); - - // Error and Warning calls are used for diagnostics and validation of the - // values. Output depends on the specific implementation of IArchive, - // for example PropertyTree uses it to show bubbles with errors in UI - // next to the mentioned property. - template - void Error(T& value, const char* format, ...); - template - void Warning(T& value, const char* format, ...); - - void Error(const void* value, const Serialization::TypeID& type, const char* format, ...); - // Used to add tooltips in PropertyTree - void Doc(const char* docString); - - virtual bool OpenBlock([[maybe_unused]] const char* name, [[maybe_unused]] const char* label) { return true; } - virtual void CloseBlock() {} - - // long, unsigned long and long double are intentionally omitted - - template - T* FindContext() const { return (T*)FindContextByType(TypeID::get()); } - - void* FindContextByType(const TypeID& type) const - { - SContextLink* context = innerContext_; - while (context) - { - if (context->type == type) - { - return context->contextObject; - } - context = context->outer; - } - return 0; - } - - SContextLink* SetInnerContext(SContextLink* context) - { - SContextLink* result = innerContext_; - innerContext_ = context; - return result; - } - SContextLink* GetInnerContext() const{ return innerContext_; } - protected: - virtual void ValidatorMessage([[maybe_unused]] bool error, [[maybe_unused]] const void* handle, [[maybe_unused]] const TypeID& type, [[maybe_unused]] const char* message) {} - virtual void DocumentLastField([[maybe_unused]] const char* text) {} - - void notImplemented() { YASLI_ASSERT(0 && "Not implemented!"); } - - int caps_; - int filter_; - - SContextLink* innerContext_; - }; - - - // IArchive::SContext can be used to establish access to outer objects in serialization stack. - // - // Example: - // void Scene::Serialize(...) { - // IArchive::SContext context(ar, this); - // ar(rootNode, ...); - // } - // - // void Node::Serialize(...) { - // Scene* scene = ar.FindContext(); - // } - template - struct SContext - : SContextLink - { - SContext(IArchive& ar, T* context) - : ar_(&ar) - { - outer = ar_->SetInnerContext(this); - type = TypeID::get(); - contextObject = (void*)context; - } - SContext(T* context) - : ar_(0) - { - outer = 0; - type = TypeID::get(); - contextObject = (void*)context; - } - ~SContext() - { - if (ar_) - { - ar_->SetInnerContext(outer); - } - } - private: - IArchive* ar_; - }; - - namespace detail { - template - struct Selector{}; - - template - struct Selector - { - typedef T2 type; - }; - - template - struct Selector - { - typedef T1 type; - }; - - template - struct Select - { - typedef typename Selector::type selected_type; - typedef typename selected_type::type type; - }; - - template - struct Identity - { - typedef T type; - }; - - - template - struct IsArray - { - enum - { - value = false - }; - }; - - template - struct IsArray< T[Size] > - { - enum - { - value = true - }; - }; - - template - struct ArraySize - { - enum - { - value = true - }; - }; - - template - struct SerializeStruct - { - static bool invoke(IArchive& ar, T& value, const char* name, const char* label) - { - SStruct ser(value); - return ar(ser, name, label); - }; - }; - - template - struct SerializeEnum - { - static bool invoke(IArchive& ar, Enum& value, const char* name, const char* label) - { - const CEnumDescription& enumDescription = getEnumDescription(); - return serializeEnum(enumDescription, ar, reinterpret_cast(value), name, label); - }; - }; - - template - struct SerializeArray{}; - - template - struct SerializeArray - { - static bool invoke(IArchive& ar, T value[Size], const char* name, const char* label) - { - ContainerArray ser(value, Size); - return ar(static_cast(ser), name, label); - } - }; - - - template - struct IsClass - { - private: - struct NoType - { - char dummy; - }; - struct YesType - { - char dummy[100]; - }; - - template - static YesType function_helper(void(U::*)(void)); - - template - static NoType function_helper(...); - public: - enum - { - value = (sizeof(function_helper(0)) == sizeof(YesType)) - }; - }; - } - - template - bool IArchive::operator()(const T& value, const char* name, const char* label) - { - return Serialize(*this, const_cast(value), name, label); - } - - inline bool IArchive::operator()(IPointer& ptr, const char* name, const char* label) - { - return (*this)(SStruct(const_cast(ptr)), name, label); - } - - inline void IArchive::Doc([[maybe_unused]] const char* docString) - { -#if !defined(CONSOLE) && !defined(RELEASE) - if (caps_ & DOCUMENTATION) - { - DocumentLastField(docString); - } -#endif - } - - template - void IArchive::Error([[maybe_unused]] T& value, [[maybe_unused]] const char* format, ...) - { -#if !defined(CONSOLE) && !defined(RELEASE) - if ((caps_ & VALIDATION) == 0) - { - return; - } - va_list args; - va_start(args, format); - char buf[1024]; - azvsnprintf(buf, sizeof(buf), format, args); - va_end(args); - ValidatorMessage(true, &value, TypeID::get(), buf); -#endif - } - - inline void IArchive::Error([[maybe_unused]] const void* handle, [[maybe_unused]] const Serialization::TypeID& type, [[maybe_unused]] const char* format, ...) - { -#if !defined(CONSOLE) && !defined(RELEASE) - if ((caps_ & VALIDATION) == 0) - { - return; - } - va_list args; - va_start(args, format); - char buf[1024]; - azvsnprintf(buf, sizeof(buf), format, args); - va_end(args); - ValidatorMessage(true, handle, type, buf); -#endif - } - - template - void IArchive::Warning([[maybe_unused]] T& value, [[maybe_unused]] const char* format, ...) - { -#if !defined(CONSOLE) && !defined(RELEASE) - if ((caps_ & VALIDATION) == 0) - { - return; - } - va_list args; - va_start(args, format); - char buf[1024]; - azvsnprintf(buf, sizeof(buf), format, args); - va_end(args); - ValidatorMessage(false, &value, TypeID::get(), buf); -#endif - } - - template - bool Serialize(Serialization::IArchive& ar, T object[Size], const char* name, const char* label) - { - YASLI_ASSERT(0); - return false; - } - - template - bool Serialize(Serialization::IArchive& ar, const T& object, const char* name, const char* label) - { - T::unable_to_serialize_CONST_object(); - YASLI_ASSERT(0); - return false; - } - - template - bool Serialize(Serialization::IArchive& ar, T& object, const char* name, const char* label) - { - using namespace Serialization::detail; - - return - Select< IsClass, - Identity< SerializeStruct >, - Select< IsArray, - Identity< SerializeArray >, - Identity< SerializeEnum > - > - >::type::invoke(ar, object, name, label); - } -} - -#include "Serialization/SerializerImpl.h" - -// vim: ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_IARCHIVE_H diff --git a/Code/CryEngine/CryCommon/Serialization/IArchiveHost.h b/Code/CryEngine/CryCommon/Serialization/IArchiveHost.h deleted file mode 100644 index c2afc1778f..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IArchiveHost.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -// IArchiveHost serves a purpose of sharing IArchive implementations among -// diffferent modules. -// -// Example of usage: -// -// struct SType -// { -// void Serialize(Serialization::IArchive& ar); -// }; -// -// SType instanceToSave; -// bool saved = Serialization::SaveJsonFile("Scripts/instance.json", instanceToSave); -// -// SType instanceToLoad; -// bool loaded = Serialization::LoadJsonFile(instanceToLoad, "Scripts/instance.json"); -// -#include -#include - -namespace Serialization -{ - struct IArchiveHost - { - virtual ~IArchiveHost() {} - virtual bool LoadJsonFile(const SStruct& outObj, const char* filename) = 0; - virtual bool SaveJsonFile(const char* filename, const SStruct& obj) = 0; - virtual bool LoadJsonBuffer(const SStruct& outObj, const char* buffer, size_t bufferLength) = 0; - virtual bool SaveJsonBuffer(DynArray& outBuffer, const SStruct& obj) = 0; - - virtual bool LoadBinaryFile(const SStruct& outObj, const char* filename) = 0; - virtual bool SaveBinaryFile(const char* filename, const SStruct& obj) = 0; - virtual bool LoadBinaryBuffer(const SStruct& outObj, const char* buffer, size_t bufferLength) = 0; - virtual bool SaveBinaryBuffer(DynArray& outBuffer, const SStruct& obj) = 0; - virtual bool CloneBinary(const SStruct& dest, const SStruct& source) = 0; - // Compares two instances in serialized form through binary archive - virtual bool CompareBinary(const SStruct& lhs, const SStruct& rhs) = 0; - - virtual bool LoadXmlFile(const SStruct& outObj, const char* filename) = 0; - virtual bool SaveXmlFile(const char* filename, const SStruct& obj, const char* rootNodeName) = 0; - virtual bool LoadXmlNode(const SStruct& outObj, const XmlNodeRef& node) = 0; - virtual XmlNodeRef SaveXmlNode(const SStruct& obj, const char* nodeName) = 0; - virtual bool SaveXmlNode(XmlNodeRef& node, const SStruct& obj) = 0; - }; - - // Syntactic sugar - template - bool LoadJsonFile(T& instance, const char* filename) - { - return gEnv->pSystem->GetArchiveHost()->LoadJsonFile(Serialization::SStruct(instance), filename); - } - - template - bool SaveJsonFile(const char* filename, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveJsonFile(filename, Serialization::SStruct(instance)); - } - - template - bool LoadJsonBuffer(T& instance, const char* buffer, size_t bufferLength) - { - return gEnv->pSystem->GetArchiveHost()->LoadJsonBuffer(Serialization::SStruct(instance), buffer, bufferLength); - } - - template - bool SaveJsonBuffer(DynArray& outBuffer, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveJsonBuffer(outBuffer, Serialization::SStruct(instance)); - } - - // --------------------------------------------------------------------------- - - template - bool LoadBinaryFile(T& outInstance, const char* filename) - { - return gEnv->pSystem->GetArchiveHost()->LoadBinaryFile(Serialization::SStruct(outInstance), filename); - } - - template - bool SaveBinaryFile(const char* filename, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveBinaryFile(filename, Serialization::SStruct(instance)); - } - - template - bool LoadBinaryBuffer(T& outInstance, const char* buffer, size_t bufferLength) - { - return gEnv->pSystem->GetArchiveHost()->LoadBinaryBuffer(Serialization::SStruct(outInstance), buffer, bufferLength); - } - - template - bool SaveBinaryBuffer(DynArray& outBuffer, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveBinaryBuffer(outBuffer, Serialization::SStruct(instance)); - } - - template - bool CloneBinary(T& outInstance, const T& inInstance) - { - return gEnv->pSystem->GetArchiveHost()->CloneBinary(Serialization::SStruct(outInstance), Serialization::SStruct(inInstance)); - } - - template - bool CompareBinary(const T& lhs, const T& rhs) - { - return gEnv->pSystem->GetArchiveHost()->CompareBinary(Serialization::SStruct(lhs), Serialization::SStruct(rhs)); - } - - // --------------------------------------------------------------------------- - - template - bool LoadXmlFile(T& outInstance, const char* filename) - { - return gEnv->pSystem->GetArchiveHost()->LoadXmlFile(Serialization::SStruct(outInstance), filename); - } - - template - bool SaveXmlFile(const char* filename, const T& instance, const char* rootNodeName) - { - return gEnv->pSystem->GetArchiveHost()->SaveXmlFile(filename, Serialization::SStruct(instance), rootNodeName); - } - - template - bool LoadXmlNode(T& outInstance, const XmlNodeRef& node) - { - return gEnv->pSystem->GetArchiveHost()->LoadXmlNode(Serialization::SStruct(outInstance), node); - } - - template - XmlNodeRef SaveXmlNode(const T& instance, const char* nodeName) - { - return gEnv->pSystem->GetArchiveHost()->SaveXmlNode(Serialization::SStruct(instance), nodeName); - } - - template - bool SaveXmlNode(XmlNodeRef& node, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveXmlNode(node, Serialization::SStruct(instance)); - } -} diff --git a/Code/CryEngine/CryCommon/Serialization/IClassFactory.h b/Code/CryEngine/CryCommon/Serialization/IClassFactory.h deleted file mode 100644 index bf50b17acd..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IClassFactory.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ICLASSFACTORY_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ICLASSFACTORY_H -#pragma once - -#include - -#include "Serialization/Assert.h" -#include "Serialization/TypeID.h" - -namespace Serialization { - class IArchive; - class TypeDescription - { - public: - TypeDescription(const char* name, const char* label) - : name_(name) - , label_(label) - { - } - const char* name() const{ return name_; } - const char* label() const{ return label_; } - - protected: - const char* name_; - const char* label_; - }; - - class IClassFactory - { - friend class ClassFactoryManager; - public: - IClassFactory(TypeID baseType) - : baseType_(baseType) - , nullLabel_(0) - { - } - - virtual ~IClassFactory() { } - - virtual size_t size() const = 0; - virtual const TypeDescription* descriptionByIndex(int index) const = 0; - virtual const TypeDescription* descriptionByRegisteredName(const char* typeName) const = 0; - virtual const char* findAnnotation(const char* registeredTypeName, const char* annotationName) const = 0; - virtual void serializeNewByIndex(IArchive& ar, int index, const char* name, const char* label) = 0; - - bool setNullLabel(const char* label){ nullLabel_ = label ? label : ""; return true; } - const char* nullLabel() const{ return nullLabel_; } - protected: - TypeID baseType_; - const char* nullLabel_; - IClassFactory* m_next = nullptr; - }; - - - struct TypeNameWithFactory - { - string registeredName; - IClassFactory* factory; - - TypeNameWithFactory(const char* _registeredName, IClassFactory* _factory = 0) - : registeredName(_registeredName) - , factory(_factory) - { - } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::TypeNameWithFactory& value, const char* name, const char* label); -} - -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ICLASSFACTORY_H diff --git a/Code/CryEngine/CryCommon/Serialization/ITextInputArchive.h b/Code/CryEngine/CryCommon/Serialization/ITextInputArchive.h deleted file mode 100644 index c9f268d9a4..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ITextInputArchive.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTINPUTARCHIVE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTINPUTARCHIVE_H -#pragma once -#include "Serialization/IArchive.h" -#include "CryExtension/ICryUnknown.h" -#include "CryExtension/CryCreateClassInstance.h" - -namespace Serialization { - class ITextInputArchive - : public ICryUnknown - , public IArchive - { - public: - CRYINTERFACE_DECLARE(ITextInputArchive, 0x1845738b1dcc4168, 0xb440dba776b460c9) - - using IArchive::operator(); - - virtual bool LoadFileUsingCRT(const char* filename) = 0; - virtual bool AttachMemory(const char* buffer, size_t size) = 0; - - protected: - ITextInputArchive(int caps) - : IArchive(caps) {} - }; - - inline AZStd::shared_ptr CreateTextInputArchive() - { - AZStd::shared_ptr pArchive; - CryCreateClassInstance(MAKE_CRYGUID(0x7a83a1c890054608, 0x9f8447a4b0ad6c3b), pArchive); - return pArchive; - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTINPUTARCHIVE_H diff --git a/Code/CryEngine/CryCommon/Serialization/ITextOutputArchive.h b/Code/CryEngine/CryCommon/Serialization/ITextOutputArchive.h deleted file mode 100644 index e87b819404..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ITextOutputArchive.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTOUTPUTARCHIVE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTOUTPUTARCHIVE_H -#pragma once -#include "Serialization/IArchive.h" -#include "CryExtension/ICryUnknown.h" -#include "CryExtension/CryCreateClassInstance.h" - -namespace Serialization { - class ITextOutputArchive - : public ICryUnknown - , public IArchive - { - CRYINTERFACE_DECLARE(ITextOutputArchive, 0xa273d6157a8b4f0d, 0x80ad6c8031bbfbf3) - public: - virtual bool SaveFileUsingCRT(const char* filename) = 0; - - // use precise but less readable way to write float/double types - virtual void SetExponentFloatRepresentation(bool) = 0; - - // buffer is a null-terminated string - virtual const char* GetBuffer() const = 0; - virtual size_t GetBufferLength() const = 0; - - // by default nested structres are put in one line, unless the line length is - // longer than 'textWidth' - virtual void SetTextWidth(int textWidth) = 0; - - using IArchive::operator(); - protected: - ITextOutputArchive(int caps) - : IArchive(caps) {} - }; - - inline AZStd::shared_ptr CreateTextOutputArchive() - { - AZStd::shared_ptr pArchive; - CryCreateClassInstance(MAKE_CRYGUID(0xd1f14adbc4e74e49, 0x9cea55d80a55cbdb), pArchive); - return pArchive; - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTOUTPUTARCHIVE_H diff --git a/Code/CryEngine/CryCommon/Serialization/IXmlArchive.h b/Code/CryEngine/CryCommon/Serialization/IXmlArchive.h deleted file mode 100644 index 07d4438d92..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IXmlArchive.h +++ /dev/null @@ -1,175 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_IXMLARCHIVE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_IXMLARCHIVE_H -#pragma once - - -#include "Serialization/IArchive.h" -#include "CryExtension/ICryUnknown.h" -#include "CryExtension/CryCreateClassInstance.h" - -namespace Serialization -{ - struct IXmlArchive - : public ICryUnknown - , public IArchive - { - public: - CRYINTERFACE_DECLARE(IXmlArchive, 0x1386c94ded174f96, 0xab14d20e1b616588); - - using IArchive::operator(); - - virtual void SetXmlNode(XmlNodeRef pRootNode) = 0; - virtual XmlNodeRef GetXmlNode() const = 0; - - protected: - IXmlArchive(int caps) - : IArchive(caps | IArchive::NO_EMPTY_NAMES) {} - }; - - - typedef AZStd::shared_ptr< IXmlArchive > IXmlArchivePtr; - - - inline IXmlArchivePtr CreateXmlInputArchive() - { - IXmlArchivePtr pArchive; - CryCreateClassInstance("CXmlIArchive", pArchive); - return pArchive; - } - - - inline IXmlArchivePtr CreateXmlInputArchive(XmlNodeRef pXmlNode) - { - if (pXmlNode) - { - IXmlArchivePtr pArchive = CreateXmlInputArchive(); - if (pArchive) - { - pArchive->SetXmlNode(pXmlNode); - } - return pArchive; - } - return IXmlArchivePtr(); - } - - - inline IXmlArchivePtr CreateXmlInputArchive(const char* const filename) - { - XmlNodeRef pXmlNode = gEnv->pSystem->LoadXmlFromFile(filename); - return CreateXmlInputArchive(pXmlNode); - } - - - inline IXmlArchivePtr CreateXmlOutputArchive() - { - IXmlArchivePtr pArchive; - CryCreateClassInstance("CXmlOArchive", pArchive); - return pArchive; - } - - - inline IXmlArchivePtr CreateXmlOutputArchive(XmlNodeRef pXmlNode) - { - if (pXmlNode) - { - IXmlArchivePtr pArchive = CreateXmlOutputArchive(); - if (pArchive) - { - pArchive->SetXmlNode(pXmlNode); - } - return pArchive; - } - return IXmlArchivePtr(); - } - - - inline IXmlArchivePtr CreateXmlOutputArchive(const char* const xmlRootElementName) - { - XmlNodeRef pXmlNode = gEnv->pSystem->CreateXmlNode(xmlRootElementName); - return CreateXmlOutputArchive(pXmlNode); - } - - - template< typename T > - bool StructFromXml(const char* const filename, T& dataOut) - { - Serialization::IXmlArchivePtr pXmlArchive = Serialization::CreateXmlInputArchive(filename); - if (pXmlArchive) - { - Serialization::SStruct serializer = Serialization::SStruct(dataOut); - const bool success = serializer(*pXmlArchive); - return success; - } - return false; - } - - - template< typename T > - bool StructFromXml(XmlNodeRef pXmlNode, T& dataOut) - { - Serialization::IXmlArchivePtr pXmlArchive = Serialization::CreateXmlInputArchive(pXmlNode); - if (pXmlArchive) - { - Serialization::SStruct serializer = Serialization::SStruct(dataOut); - const bool success = serializer(*pXmlArchive); - return success; - } - return false; - } - - - template< typename T > - XmlNodeRef StructToXml(const char* const xmlRootElementName, const T& dataIn) - { - Serialization::IXmlArchivePtr pXmlArchive = Serialization::CreateXmlOutputArchive(xmlRootElementName); - if (pXmlArchive) - { - Serialization::SStruct serializer = Serialization::SStruct(const_cast< T& >(dataIn)); - const bool success = serializer(*pXmlArchive); - if (success) - { - return pXmlArchive->GetXmlNode(); - } - } - return XmlNodeRef(); - } - - - template< typename T > - bool StructToXml(XmlNodeRef pXmlNode, const T& dataIn) - { - Serialization::IXmlArchivePtr pXmlArchive = Serialization::CreateXmlOutputArchive(pXmlNode); - if (pXmlArchive) - { - Serialization::SStruct serializer = Serialization::SStruct(const_cast< T& >(dataIn)); - const bool success = serializer(*pXmlArchive); - return success; - } - return false; - } - - - template< typename T > - bool StructToXml(const char* const filename, const char* const xmlRootElementName, const T& dataIn) - { - XmlNodeRef pXmlNode = Serialization::StructToXml(xmlRootElementName, dataIn); - if (pXmlNode) - { - return pXmlNode->saveToFile(filename); - } - return false; - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_IXMLARCHIVE_H diff --git a/Code/CryEngine/CryCommon/Serialization/IntrusiveFactory.h b/Code/CryEngine/CryCommon/Serialization/IntrusiveFactory.h deleted file mode 100644 index dcd92d51a9..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IntrusiveFactory.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_INTRUSIVEFACTORY_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_INTRUSIVEFACTORY_H -#pragma once - -#include - -template -class CIntrusiveFactory -{ -private: - struct ICreator - { - virtual TBase* Create() const = 0; - }; - -public: - template - struct SCreator - : ICreator - { - SCreator() { CIntrusiveFactory::Instance().RegisterType(this); } - - TBase* Create() const override { return new TDerived(); } - }; - - static CIntrusiveFactory& Instance() { static CIntrusiveFactory instance; return instance; } - - TBase* Create(const char* keyType) const - { - TCreatorByType::const_iterator it = m_creators.find(keyType); - if (it == m_creators.end() || it->second == 0) - { - return 0; - } - else - { - return it->second->Create(); - } - } - - struct SSerializer - { - _smart_ptr& pointer; - - SSerializer(_smart_ptr& pointer) - : pointer(pointer) {} - - void Serialize(Serialization::IArchive& ar); - }; - -private: - template - void RegisterType(ICreator* creator) - { - const char* type = TDerived::GetType(); - m_creators[type] = creator; - } - - typedef std::map > TCreatorByType; - TCreatorByType m_creators; -}; - -template -void CIntrusiveFactory::SSerializer::Serialize(Serialization::IArchive & ar) -{ - string type = pointer.get() ? pointer->GetInstanceType() : ""; - string oldType = type; - ar(type, "type", "Type"); - if (ar.IsInput()) - { - if (oldType != type) - { - pointer.reset(CIntrusiveFactory::Instance().Create(type.c_str())); - } - } - if (pointer) - { - pointer->Serialize(ar); - } -} - - - -#define REGISTER_IN_INTRUSIVE_FACTORY(BaseType, DerivedType) namespace { CIntrusiveFactory::SCreator baseType##DerivedType##_Creator; } - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_INTRUSIVEFACTORY_H diff --git a/Code/CryEngine/CryCommon/Serialization/KeyValue.h b/Code/CryEngine/CryCommon/Serialization/KeyValue.h deleted file mode 100644 index afe74927df..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/KeyValue.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_KEYVALUE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_KEYVALUE_H -#pragma once -namespace Serialization { - class IArchive; - - class IKeyValue - : IString - { - public: - virtual const char* get() const = 0; - virtual void set(const char* key) = 0; - virtual bool serializeValue(IArchive& ar, const char* name, const char* label) = 0; - template - void Serialize(TArchive& ar) - { - ar(*(IString*)this, "", "^"); - serializeValue(ar, "", "^"); - } - }; -} - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_KEYVALUE_H diff --git a/Code/CryEngine/CryCommon/Serialization/Math.h b/Code/CryEngine/CryCommon/Serialization/Math.h deleted file mode 100644 index c7d86935e0..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Math.h +++ /dev/null @@ -1,166 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// This header extends serialization to support common geometrical types. -// It allows serialization of mentioned below types simple passing them to archive. -// For example: -// -// #include -// #include -// -// Serialization::IArchive& ar; -// -// Vec3 v; -// ar(v, "v"); -// -// QuatT q; -// ar(q, "q"); -// - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATH_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATH_H -#pragma once -namespace Serialization { - class IArchive; -} - -template -bool Serialize(Serialization::IArchive& ar, struct Vec2_tpl& v, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Vec3_tpl& v, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Vec4_tpl& v, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Quat_tpl& q, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct QuatT_tpl& qt, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Ang3_tpl& a, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Matrix34_tpl& value, const char* name, const char* label); - -bool Serialize(Serialization::IArchive& ar, struct AABB& aabb, const char* name, const char* label); - -// --------------------------------------------------------------------------- -// RadiansAsDeg allows to present radian values as degrees to the user in the -// editor. -// -// Example: -// ... -// float radians; -// ar(RadiansAsDeg(radians), "degrees", "Degrees"); -// -// Ang3 euler; -// ar(RadiansAsDeg(euler), "eulerDegrees", "Euler Degrees"); -// -namespace Serialization -{ - template - struct SRadianAng3AsDeg - { - Ang3_tpl* ang3; - SRadianAng3AsDeg(Ang3_tpl* _ang3) - : ang3(_ang3) {} - }; - - template - SRadianAng3AsDeg RadiansAsDeg(Ang3_tpl& radians) - { - return SRadianAng3AsDeg(&radians); - } - - template - struct SRadiansAsDeg - { - T* radians; - SRadiansAsDeg(T* _radians) - : radians(_radians) {} - }; - - template - SRadiansAsDeg RadiansAsDeg(T& radians) - { - return SRadiansAsDeg(&radians); - } - - template - bool Serialize(Serialization::IArchive& ar, Serialization::SRadiansAsDeg& value, const char* name, const char* label); - template - bool Serialize(Serialization::IArchive& ar, Serialization::SRadianAng3AsDeg& value, const char* name, const char* label); - - // --------------------------------------------------------------------------- - // QuatAsAng3 provides a wrapper that allows editing of quaternions as Ang3 (in degrees). - // - // Example: - // ... - // Quat q; - // ar(QuatAsAng3(q), "orientation", "Orientation"); - // - - template - struct QuatAsAng3 - { - Quat_tpl* quat; - QuatAsAng3(Quat_tpl& _quat) - : quat(&_quat) {} - }; - - template - bool Serialize(Serialization::IArchive& ar, Serialization::QuatAsAng3& value, const char* name, const char* label); - - // --------------------------------------------------------------------------- - // QuatTAsVec3Ang3 provides a wrapper that allows editing of transforms as Vec3 and Ang3 (in degrees). - // - // Example: - // ... - // QuatT trans; - // ar(QuatTAsVec3Ang3(trans), "transform", "Transform"); - // - - template - struct QuatTAsVec3Ang3 - { - QuatT_tpl* trans; - QuatTAsVec3Ang3(QuatT_tpl& _trans) - : trans(&_trans) {} - }; - - template - bool Serialize(Serialization::IArchive& ar, Serialization::QuatTAsVec3Ang3& value, const char* name, const char* label); - - // --------------------------------------------------------------------------- - // Helper functions for Ang3 - // - // Example: - // ... - // Quat q; - // QuatT trans; - // ar(AsAng3(q),"orientation","Orientation"); - // ar(AsAnge(trans),"transform", "Transform"); - // - - template - inline QuatAsAng3 AsAng3(Quat_tpl& q){ return QuatAsAng3(q); } - template - inline QuatTAsVec3Ang3 AsAng3(QuatT_tpl& trans){ return QuatTAsVec3Ang3(trans); } -} - -#include "MathImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATH_H diff --git a/Code/CryEngine/CryCommon/Serialization/MathImpl.h b/Code/CryEngine/CryCommon/Serialization/MathImpl.h deleted file mode 100644 index 95ff63e179..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/MathImpl.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATHIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATHIMPL_H -#pragma once - -#include "Serialization/IArchive.h" - -#include "Cry_Vector2.h" -#include "Cry_Vector3.h" -#include "Cry_Vector4.h" -#include "Cry_Quat.h" -#include "Cry_Matrix34.h" -#include "Cry_Geo.h" - - -template -bool Serialize(Serialization::IArchive& ar, Vec2_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[2]; - return ar((Array)value, name, label); -} - -template -bool Serialize(Serialization::IArchive& ar, Vec3_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[3]; - return ar((Array)value, name, label); -} - -template -inline bool Serialize(Serialization::IArchive& ar, struct Vec4_tpl& v, const char* name, const char* label) -{ - typedef T (& Array)[4]; - return ar((Array)v, name, label); -} - - -template -bool Serialize(Serialization::IArchive& ar, struct Quat_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[4]; - return ar((Array)value, name, label); -} - -template -struct SerializableQuatT - : QuatT_tpl -{ - void Serialize(Serialization::IArchive& ar) - { - ar(this->q, "q", "Quaternion"); - ar(this->t, "t", "Translation"); - } -}; - -template -bool Serialize(Serialization::IArchive& ar, struct QuatT_tpl& value, const char* name, const char* label) -{ - return Serialize(ar, static_cast&>(value), name, label); -} - -struct SerializableAABB - : AABB -{ - void Serialize(Serialization::IArchive& ar) - { - ar(this->min, "min", "Min"); - ar(this->max, "max", "Max"); - } -}; - -inline bool Serialize(Serialization::IArchive& ar, struct AABB& value, const char* name, const char* label) -{ - return Serialize(ar, static_cast(value), name, label); -} - -template -bool Serialize(Serialization::IArchive& ar, Matrix34_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[3][4]; - return ar((Array)value, name, label); -} - -////////////////////////////////////////////////////////////////////////// - - -namespace Serialization -{ - template - bool Serialize(Serialization::IArchive& ar, Serialization::SRadiansAsDeg& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - float degrees = RAD2DEG(*value.radians); - float oldDegrees = degrees; - if (!ar(degrees, name, label)) - { - return false; - } - if (oldDegrees != degrees) - { - *value.radians = DEG2RAD(degrees); - } - return true; - } - else - { - return ar(*value.radians, name, label); - } - } - - template - bool Serialize(Serialization::IArchive& ar, Serialization::SRadianAng3AsDeg& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - Ang3 degrees(RAD2DEG(value.ang3->x), RAD2DEG(value.ang3->y), RAD2DEG(value.ang3->z)); - Ang3 oldDegrees = degrees; - if (!ar(degrees, name, label)) - { - return false; - } - if (oldDegrees != degrees) - { - *value.ang3 = Ang3(DEG2RAD(degrees.x), DEG2RAD(degrees.y), DEG2RAD(degrees.z)); - } - return true; - } - else - { - return ar(*value.ang3, name, label); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -template -bool Serialize(Serialization::IArchive& ar, Ang3_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[3]; - return ar((Array)value, name, label); -} - -////////////////////////////////////////////////////////////////////////// - -namespace Serialization -{ - template - bool Serialize(Serialization::IArchive& ar, Serialization::QuatAsAng3& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - Ang3 ang3(*value.quat); - Ang3 oldAng3 = ang3; - if (!ar(Serialization::RadiansAsDeg(ang3), name, label)) - { - return false; - } - if (ang3 != oldAng3) - { - *value.quat = Quat(ang3); - } - return true; - } - else - { - return ar(*value.quat, name, label); - } - } - - template - bool Serialize(Serialization::IArchive& ar, Serialization::QuatTAsVec3Ang3& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - if (!ar.OpenBlock(name, label)) - { - return false; - } - - ar(QuatAsAng3((value.trans)->q), "rot", "Rotation"); - ar.Doc("Euler Angles in degrees"); - ar((value.trans)->t, "t", "Translation"); - ar.CloseBlock(); - return true; - } - else - { - return ar(*(value.trans), name, label); - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATHIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/NetScriptSerialize.h b/Code/CryEngine/CryCommon/Serialization/NetScriptSerialize.h deleted file mode 100644 index 8c66452419..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/NetScriptSerialize.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_CRYSCRIPTSYSTEM_NETSCRIPTSERIALIZE_H -#define CRYINCLUDE_CRYCOMMON_CRYSCRIPTSYSTEM_NETSCRIPTSERIALIZE_H - -namespace Serialization -{ - class INetScriptMarshaler - { - public: - virtual TSerialize FindSerializer(const char* name) = 0; - virtual bool CommitSerializer(const char* name, TSerialize serializer) = 0; - - virtual int GetMaxServerProperties() const = 0; - }; -} - -#endif diff --git a/Code/CryEngine/CryCommon/Serialization/Object.h b/Code/CryEngine/CryCommon/Serialization/Object.h deleted file mode 100644 index d304883452..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Object.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_OBJECT_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_OBJECT_H -#pragma once - -#include "Serializer.h" - -// --------------------------------------------------------------------------- - -namespace Serialization { - typedef int(* AddRefFunc)(void*); - typedef int(* DecRefFunc)(void*); - - // represents a reference to the persistent object - class Object - { - public: - Object() - : address_(0) - , addRefFunc_(0) - , decRefFunc_(0) - , serializeFunc_(0) - { - } - - Object(const Object& o) - : address_(o.address_) - , type_(o.type_) - , addRefFunc_(o.addRefFunc_) - , decRefFunc_(o.decRefFunc_) - , serializeFunc_(o.serializeFunc_) - { - addRef(); - } - - Object(const SStruct& ser) - : address_(ser.pointer()) - , type_(ser.type()) - , addRefFunc_(0) - , decRefFunc_(0) - , serializeFunc_(ser.serializeFunc()) - { - } - - Object(void* address, const TypeID& type, AddRefFunc addRefFunc, DecRefFunc decRefFunc, SerializeStructFunc serializeFunc) - : address_(address) - , type_(type) - , addRefFunc_(addRefFunc) - , decRefFunc_(decRefFunc) - , serializeFunc_(serializeFunc) - { - addRef(); - } - - ~Object() - { - if (address_) - { - decRef(); - address_ = 0; - } - } - - void* address() const{ return address_; } - const TypeID& type() const{ return type_; } - bool isSet() { return serializeFunc_ != 0; } - - int addRef() - { - if (!addRefFunc_) - { - return 1; - } - if (!address_) - { - return -1; - } - return addRefFunc_(address_); - } - - int decRef() - { - if (!decRefFunc_) - { - return 1; - } - if (!address_) - { - return -1; - } - return decRefFunc_(address_); - } - - bool operator()(IArchive& ar) const - { - if (!serializeFunc_ || !address_) - { - return false; - } - return serializeFunc_(address_, ar); - } - - SStruct serializer() const - { - return SStruct(type_, address_, 0, serializeFunc_); - } - - Object& operator=(const Object& o) - { - if (this == &o) - { - return *this; - } - - if (address_) - { - decRef(); - } - - address_ = o.address_; - type_ = o.type_; - addRefFunc_ = o.addRefFunc_; - decRefFunc_ = o.decRefFunc_; - serializeFunc_ = o.serializeFunc_; - - addRef(); - return *this; - } - - private: - void* address_; - TypeID type_; - AddRefFunc addRefFunc_; - DecRefFunc decRefFunc_; - SerializeStructFunc serializeFunc_; - }; -} - -// --------------------------------------------------------------------------- - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_OBJECT_H diff --git a/Code/CryEngine/CryCommon/Serialization/STL.h b/Code/CryEngine/CryCommon/Serialization/STL.h deleted file mode 100644 index 357a8937a4..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/STL.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STL_H -#pragma once - - -#include -#include -#include - -#include "Serialization/Serializer.h" - -namespace Serialization { - class IArchive; -} - -namespace std -{ - template - bool Serialize(Serialization::IArchive& ar, std::pair& pair, const char* name, const char* label); - - template - bool Serialize(Serialization::IArchive& ar, std::vector& container, const char* name, const char* label); - - template - bool Serialize(Serialization::IArchive& ar, std::list& container, const char* name, const char* label); - - template - bool Serialize(Serialization::IArchive& ar, std::map& container, const char* name, const char* label); -} - -namespace Serialization -{ - bool Serialize(Serialization::IArchive& ar, Serialization::string& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::wstring& value, const char* name, const char* label); -} - -#include "STLImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STL_H diff --git a/Code/CryEngine/CryCommon/Serialization/STLImpl.h b/Code/CryEngine/CryCommon/Serialization/STLImpl.h deleted file mode 100644 index b03d877b55..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/STLImpl.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STLIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STLIMPL_H -#pragma once - - -#include "Serialization/IArchive.h" -#include "Serialization/Serializer.h" - -namespace Serialization { - template - class ContainerSTL - : public IContainer /*{{{*/ - { - public: - explicit ContainerSTL(Container* container = 0) - : container_(container) - , it_(container->begin()) - , size_(container->size()) - { - YASLI_ASSERT(container_ != 0); - } - - template - void resizeHelper(size_t _size, std::vector* _v) const - { - _v->resize(_size); - } - - void resizeHelper(size_t _size, ...) const - { - while (size_t(container_->size()) > _size) - { - typename Container::iterator it = container_->end(); - --it; - container_->erase(it); - } - while (size_t(container_->size()) < _size) - { - container_->insert(container_->end(), Element()); - } - } - - // from ContainerSerializationInterface - size_t size() const - { - YASLI_ESCAPE(container_ != 0, return 0); - return container_->size(); - } - size_t resize(size_t size) - { - YASLI_ESCAPE(container_ != 0, return 0); - resizeHelper(size, container_); - it_ = container_->begin(); - size_ = size; - return size; - } - - void* pointer() const{ return reinterpret_cast(container_); } - TypeID elementType() const{ return TypeID::get(); } - TypeID containerType() const{ return TypeID::get(); } - - - bool next() - { - YASLI_ESCAPE(container_ && it_ != container_->end(), return false); - ++it_; - return it_ != container_->end(); - } - - void* elementPointer() const { return &*it_; } - size_t elementSize() const { return sizeof(typename Container::value_type); } - - bool operator()(IArchive& ar, const char* name, const char* label) - { - YASLI_ESCAPE(container_, return false); - if (it_ == container_->end()) - { - it_ = container_->insert(container_->end(), Element()); - return ar(*it_, name, label); - } - else - { - return ar(*it_, name, label); - } - } - operator bool() const{ - return container_ != 0; - } - void serializeNewElement(IArchive& ar, const char* name = "", const char* label = 0) const - { - Element element; - ar(element, name, label); - } - // ^^^ - protected: - Container* container_; - typename Container::iterator it_; - size_t size_; - };/*}}}*/ -} - -namespace std -{ - template - bool Serialize(Serialization::IArchive& ar, std::vector& container, const char* name, const char* label) - { - Serialization::ContainerSTL, T> ser(&container); - return ar(static_cast(ser), name, label); - } - - template - bool Serialize(Serialization::IArchive& ar, std::list& container, const char* name, const char* label) - { - Serialization::ContainerSTL, T> ser(&container); - return ar(static_cast(ser), name, label); - } - - template - bool Serialize(Serialization::IArchive& ar, std::map& container, const char* name, const char* label) - { - std::vector > temp; - if (ar.IsOutput()) - { - temp.assign(container.begin(), container.end()); - } - if (!ar(temp, name, label)) - { - return false; - } - if (ar.IsInput()) - { - container.clear(); - container.insert(temp.begin(), temp.end()); - } - return true; - } -} - -// --------------------------------------------------------------------------- -namespace Serialization { - class StringSTL - : public IString - { - public: - StringSTL(string& str) - : str_(str) { } - - void set(const char* value) { str_ = value; } - const char* get() const { return str_.c_str(); } - const void* handle() const { return &str_; } - TypeID type() const { return TypeID::get(); } - private: - string& str_; - }; - - inline bool Serialize(Serialization::IArchive& ar, Serialization::string& value, const char* name, const char* label) - { - Serialization::StringSTL str(value); - return ar(static_cast(str), name, label); - } - - // --------------------------------------------------------------------------- - - class WStringSTL - : public IWString - { - public: - WStringSTL(Serialization::wstring& str) - : str_(str) { } - - void set(const wchar_t* value) { str_ = value; } - const wchar_t* get() const { return str_.c_str(); } - const void* handle() const { return &str_; } - TypeID type() const { return TypeID::get(); } - private: - wstring& str_; - }; - - inline bool Serialize(Serialization::IArchive& ar, Serialization::wstring& value, const char* name, const char* label) - { - Serialization::WStringSTL str(value); - return ar(static_cast(str), name, label); - } - - // --------------------------------------------------------------------------- - - template - struct StdPair - { - StdPair(std::pair& pair) - : pair_(pair) {} - void Serialize(Serialization::IArchive& ar) - { - ar(pair_.first, "key", "Key"); - ar(pair_.second, "value", "Value"); - } - std::pair& pair_; - }; - - template - struct StdStringPair - : Serialization::IKeyValue - { - const char* get() const { return pair_.first.c_str(); } - void set(const char* key) { pair_.first.assign(key); } - const void* handle() const { return &pair_; } - Serialization::TypeID type() const { return Serialization::TypeID::get(); } - bool serializeValue(Serialization::IArchive& ar, const char* name, const char* label) - { - return ar(pair_.second, name, label); - } - - StdStringPair(std::pair& pair) - : pair_(pair) - { - } - - std::pair& pair_; - }; -} - -namespace std -{ - template - bool Serialize(Serialization::IArchive& ar, std::pair& pair, const char* name, const char* label) - { - Serialization::StdPair keyValue(pair); - return ar(keyValue, name, label); - } - - template - bool Serialize(Serialization::IArchive& ar, std::pair& pair, const char* name, const char* label) - { - Serialization::StdStringPair keyValue(pair); - return ar(static_cast(keyValue), name, label); - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STLIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Serializer.h b/Code/CryEngine/CryCommon/Serialization/Serializer.h deleted file mode 100644 index 13acc57cec..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Serializer.h +++ /dev/null @@ -1,268 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZER_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZER_H -#pragma once - - -#include -#include "Assert.h" -#include "TypeID.h" - -namespace Serialization { - class IArchive; - class IClassFactory; - - typedef bool(* SerializeStructFunc)(void*, IArchive&); - - typedef bool(* SerializeContainerFunc)(void*, IArchive&, size_t index); - typedef size_t(* ContainerResizeFunc)(void*, size_t size); - typedef size_t(* ContainerSizeFunc)(void*); - - // Struct serializer. - // - // This type is used to pass needed struct/class type information through abstract interface. - // Most importantly it captures: - // - pointer to object - // - reference to serialize method (indirectly through pointer to static func.) - // - TypeID - struct SStruct/*{{{*/ - { - friend class IArchive; - public: - SStruct() - : object_(0) - , size_(0) - , serializeFunc_(0) - { - } - - SStruct(TypeID type, void* object, size_t size, SerializeStructFunc Serialize) - : type_(type) - , object_(object) - , size_(size) - , serializeFunc_(Serialize) - { - YASLI_ASSERT(object != 0); - } - - SStruct(const SStruct& _original) - : type_(_original.type_) - , object_(_original.object_) - , size_(_original.size_) - , serializeFunc_(_original.serializeFunc_) - { - } - - template - explicit SStruct(const T& object) - { - type_ = TypeID::get(); - object_ = (void*)(&object); - size_ = sizeof(T); - serializeFunc_ = &SStruct::serializeRaw; - } - - template - explicit SStruct(const T& object, TypeID type) - { - type_ = type; - object_ = (void*)(&object); - size_ = sizeof(T); - serializeFunc_ = &SStruct::serializeRaw; - } - - // This constructs SStruct from an object that doesn't have Serialize method. - // Such SStruct can not be serialized but conveys object reference and type - // information that is needed for Property-archives. Used for decorators. - template - static SStruct ForEdit(const T& object) - { - SStruct r; - r.type_ = TypeID::get(); - r.object_ = (void*)&object; - r.size_ = sizeof(T); - r.serializeFunc_ = 0; - return r; - } - - bool operator()(IArchive& ar, const char* name, const char* label) const; - bool operator()(IArchive& ar) const; - operator bool() const{ - return object_ != 0; - } - bool operator==(const SStruct& rhs) const{ return object_ == rhs.object_ && serializeFunc_ == rhs.serializeFunc_; } - bool operator!=(const SStruct& rhs) const{ return !operator==(rhs); } - void* pointer() const{ return object_; } - void setPointer(void* p) { object_ = p; } - TypeID type() const{ return type_; } - void setType(const TypeID& type) { type_ = type; } - size_t size() const{ return size_; } - SerializeStructFunc serializeFunc() const{ return serializeFunc_; } - - template - static bool serializeRaw(void* rawPointer, IArchive& ar) - { - YASLI_ESCAPE(rawPointer, return false); - // If you're getting compile error here, most likely, you have one of the following situations: - // - The type you're trying to serialize doesn't have Serialize _method_ implemented. - // - Type is supposed to be serialized with non-member Serialize function and this function is out of scope. - ((T*)(rawPointer))->Serialize(ar); - return true; - } - - template - T* cast() const - { - if (type_ == Serialization::TypeID::get()) - { - return (T*)object_; - } - else - { - return 0; - } - } - private: - - TypeID type_; - void* object_; - size_t size_; - SerializeStructFunc serializeFunc_; - };/*}}}*/ - typedef std::vector SStructs; - - // --------------------------------------------------------------------------- - - // This type is used to generalize access to specific container types. - // It is used by concrete IArchive implementations. - class IContainer - { - public: - virtual ~IContainer() { } - - virtual size_t size() const = 0; - virtual size_t resize(size_t size) = 0; - virtual bool isFixedSize() const{ return false; } - - virtual void* pointer() const = 0; - virtual bool next() = 0; - virtual TypeID containerType() const = 0; - - virtual TypeID elementType() const = 0; - virtual void* elementPointer() const = 0; - virtual size_t elementSize() const = 0; - - virtual bool operator()(IArchive& ar, const char* name, const char* label) = 0; - virtual operator bool() const = 0; - virtual void serializeNewElement(IArchive& ar, const char* name = "", const char* label = 0) const = 0; - }; - - template - class ContainerArray - : public IContainer /*{{{*/ - { - friend class IArchive; - public: - explicit ContainerArray(T* array = 0, int size = 0) - : array_(array) - , index_(0) - , size_(size) - { - } - - // from ContainerSerializationInterface: - size_t size() const{ return size_; } - size_t resize([[maybe_unused]] size_t size) - { - index_ = 0; - return size_; - } - - void* pointer() const{ return reinterpret_cast(array_); } - TypeID containerType() const{ return TypeID::get(); } - TypeID elementType() const{ return TypeID::get(); } - void* elementPointer() const { return &array_[index_]; } - size_t elementSize() const { return sizeof(T); } - virtual bool isFixedSize() const{ return true; } - - bool operator()(IArchive& ar, const char* name, const char* label) - { - YASLI_ESCAPE(size_t(index_) < size_, return false); - return ar(array_[index_], name, label); - } - operator bool() const{ - return array_ != 0; - } - bool next() - { - ++index_; - return size_t(index_) < size_; - } - void serializeNewElement(IArchive& ar, const char* name, const char* label) const - { - T element; - ar(element, name, label); - } - // ^^^ - - private: - T* array_; - int index_; - size_t size_; - };/*}}}*/ - - // Generialized interface over owning polymorphic pointers. - // Used by concrete IArchive implementations. - class IPointer - { - public: - virtual ~IPointer() { } - - virtual const char* registeredTypeName() const = 0; - virtual void create(const char* registedTypeName) const = 0; - virtual TypeID baseType() const = 0; - virtual SStruct serializer() const = 0; - virtual void* get() const = 0; - virtual const void* handle() const = 0; - virtual TypeID pointerType() const = 0; - virtual IClassFactory* factory() const = 0; - - void Serialize(IArchive& ar) const; - }; - - class IString - { - public: - virtual ~IString() { } - - virtual void set(const char* value) = 0; - virtual const char* get() const = 0; - virtual const void* handle() const = 0; - virtual TypeID type() const = 0; - }; - class IWString - { - public: - virtual ~IWString() { } - - virtual void set(const wchar_t* value) = 0; - virtual const wchar_t* get() const = 0; - virtual const void* handle() const = 0; - virtual TypeID type() const = 0; - }; -} -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZER_H diff --git a/Code/CryEngine/CryCommon/Serialization/SerializerImpl.h b/Code/CryEngine/CryCommon/Serialization/SerializerImpl.h deleted file mode 100644 index f4e89c185d..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/SerializerImpl.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZERIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZERIMPL_H -#pragma once - -#include "Serializer.h" -#include "IClassFactory.h" -#include "ClassFactory.h" - -// IArchive.h is supposed to be pre-included - -namespace Serialization { - inline bool SStruct::operator()(IArchive& ar) const - { - YASLI_ESCAPE(serializeFunc_ && object_, return false); - return serializeFunc_(object_, ar); - } - - inline bool SStruct::operator()(IArchive& ar, const char* name, const char* label) const - { - return ar(*this, name, label); - } - - - inline void IPointer::Serialize(IArchive& ar) const - { - const bool noEmptyNames = ar.GetCaps(IArchive::NO_EMPTY_NAMES); - const char* const typePropertyName = noEmptyNames ? "type" : ""; - const char* const dataPropertyName = noEmptyNames ? "data" : ""; - - TypeID baseTypeID = baseType(); - const char* oldRegisteredName = registeredTypeName(); - if (!oldRegisteredName) - { - oldRegisteredName = ""; - } - IClassFactory* factory = this->factory(); - - if (ar.IsOutput()) - { - if (oldRegisteredName[0] != '\0') - { - TypeNameWithFactory pair(oldRegisteredName, factory); - if (ar(pair, typePropertyName)) - { - ar(serializer(), dataPropertyName); - } - else - { - ar.Warning(pair, "Unable to write typeID!"); - } - } - } - else - { - TypeNameWithFactory pair("", factory); - if (!ar(pair, typePropertyName)) - { - if (oldRegisteredName[0] != '\0') - { - create(""); // 0 - } - return; - } - - if (oldRegisteredName[0] != '\0' && (pair.registeredName.empty() || (pair.registeredName != oldRegisteredName))) - { - create(""); // 0 - } - if (!pair.registeredName.empty()) - { - if (!get()) - { - create(pair.registeredName.c_str()); - } - ar(serializer(), dataPropertyName); - } - } - } -} -// vim:sw=4 ts=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZERIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/SmartPtr.h b/Code/CryEngine/CryCommon/Serialization/SmartPtr.h deleted file mode 100644 index 8c109887b7..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/SmartPtr.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTR_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTR_H -#pragma once - -template -class _smart_ptr; - -namespace Serialization -{ - class IArchive; -}; - -template -bool Serialize(Serialization::IArchive& ar, _smart_ptr& ptr, const char* name, const char* label); - -#include "SmartPtrImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTR_H diff --git a/Code/CryEngine/CryCommon/Serialization/SmartPtrImpl.h b/Code/CryEngine/CryCommon/Serialization/SmartPtrImpl.h deleted file mode 100644 index 64cd7f65c1..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/SmartPtrImpl.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTRIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTRIMPL_H -#pragma once - -#include "SmartPtr.h" -#include -#include "ClassFactory.h" - -// Exposes _smart_ptr<> as serializeable type for Serialization::IArchive -template -class SmartPtrSerializer - : public Serialization::IPointer -{ -public: - SmartPtrSerializer(_smart_ptr& ptr) - : m_ptr(ptr) - {} - - const char* registeredTypeName() const override - { - if (m_ptr) - { - return Serialization::ClassFactory::the().getRegisteredTypeName(m_ptr.get()); - } - else - { - return ""; - } - } - - void create(const char* registeredTypeName) const override - { - CRY_ASSERT(!m_ptr || m_ptr->NumRefs() == 1); - if (registeredTypeName && registeredTypeName[0] != '\0') - { - m_ptr.reset(Serialization::ClassFactory::the().create(registeredTypeName)); - } - else - { - m_ptr.reset((T*)0); - } - } - Serialization::TypeID baseType() const{ return Serialization::TypeID::get(); } - virtual Serialization::SStruct serializer() const{ return Serialization::SStruct(*m_ptr); } - void* get() const{ return reinterpret_cast(m_ptr.get()); } - const void* handle() const { return &m_ptr; } - Serialization::TypeID pointerType() const { return Serialization::TypeID::get<_smart_ptr >(); } - Serialization::IClassFactory* factory() const{ return &Serialization::ClassFactory::the(); } -protected: - _smart_ptr& m_ptr; -}; - -template -bool Serialize(Serialization::IArchive& ar, _smart_ptr& ptr, const char* name, const char* label) -{ - SmartPtrSerializer serializer(ptr); - return ar(static_cast(serializer), name, label); -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTRIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/StringList.h b/Code/CryEngine/CryCommon/Serialization/StringList.h deleted file mode 100644 index 4b2ca96278..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/StringList.h +++ /dev/null @@ -1,301 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLIST_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLIST_H -#pragma once - - -#include -#include "Serialization/Strings.h" -#include "Serialization/DynArray.h" -#include -#include "Serialization/Assert.h" -#ifndef SERIALIZATION_STANDALONE -#include -#endif - -#include - -namespace Serialization { - class IArchive; - class StringListStatic -#ifdef SERIALIZATION_STANDALONE - : public std::vector - { -#else - : public AZStd::fixed_vector { -#endif - public: - enum - { - npos = -1 - }; - int find(const char* value) const - { - int numItems = int(size()); - for (int i = 0; i < numItems; ++i) - { - if (strcmp((*this)[i], value) == 0) - { - return i; - } - } - return npos; - } - }; - - class StringListStaticValue - { - public: - StringListStaticValue(const StringListStaticValue& original) - : stringList_(original.stringList_) - , index_(original.index_) - { - handle_ = this; - } - StringListStaticValue() - : stringList_(0) - , index_(StringListStatic::npos) - { - handle_ = this; - } - StringListStaticValue(const StringListStatic& stringList, int value) - : stringList_(&stringList) - , index_(value) - { - handle_ = this; - } - StringListStaticValue(const StringListStatic& stringList, int value, const void* handle, const Serialization::TypeID& type) - : stringList_(&stringList) - , index_(value) - , handle_(handle) - , type_(type) - { - } - StringListStaticValue(const StringListStatic& stringList, const char* value, const void* handle, const Serialization::TypeID& type) - : stringList_(&stringList) - , index_(stringList.find(value)) - , handle_(handle) - , type_(type) - { - YASLI_ASSERT(index_ != StringListStatic::npos); - } - StringListStaticValue& operator=(const char* value) - { - index_ = stringList_->find(value); - return *this; - } - StringListStaticValue& operator=(int value) - { - YASLI_ASSERT(value >= 0 && size_t(value) < size_t(stringList_->size())); - YASLI_ASSERT(this != 0); - index_ = value; - return *this; - } - StringListStaticValue& operator=(const StringListStaticValue& rhs) - { - stringList_ = rhs.stringList_; - index_ = rhs.index_; - return *this; - } - const char* c_str() const - { - if (index_ >= 0 && size_t(index_) < size_t(stringList_->size())) - { - return (*stringList_)[index_]; - } - else - { - return ""; - } - } - int index() const{ return index_; } - const void* handle() const{ return handle_; } - Serialization::TypeID type() const { return type_; } - const StringListStatic& stringList() const{ return *stringList_; } - template - void Serialize(IArchive& ar) - { - ar(index_, "index"); - } - protected: - const StringListStatic* stringList_; - int index_; - const void* handle_; - Serialization::TypeID type_; - }; - - class StringList -#ifdef SERIALIZATION_STANDALONE - : public std::vector - { -#else - : public DynArray{ -#endif - public: - StringList() {} - StringList(const StringList& rhs) - { - *this = rhs; - } - StringList& operator=(const StringList& rhs) - { - // As StringList crosses dll boundaries it is important to copy strings - // rather than reference count them to be sure that stored CryString uses - // proper allocator. - resize(rhs.size()); - for (size_t i = 0; i < size_t(size()); ++i) - { - (*this)[i] = rhs[i].c_str(); - } - return *this; - } - StringList(const StringListStatic& rhs) - { - const int size = int(rhs.size()); - resize(size); - for (int i = 0; i < int(size); ++i) - { - (*this)[i] = rhs[i]; - } - } - enum - { - npos = -1 - }; - int find(const char* value) const - { - const int numItems = int(size()); - for (int i = 0; i < numItems; ++i) - { - if ((*this)[i] == value) - { - return i; - } - } - return npos; - } - }; - - class StringListValue - { - public: - explicit StringListValue(const StringListStaticValue& value) - { - stringList_.resize(value.stringList().size()); - for (size_t i = 0; i < size_t(stringList_.size()); ++i) - { - stringList_[i] = value.stringList()[i]; - } - index_ = value.index(); - } - StringListValue(const StringListValue& value) - { - stringList_ = value.stringList_; - index_ = value.index_; - } - StringListValue() - : index_(StringList::npos) - { - handle_ = this; - } - StringListValue(const StringList& stringList, int value) - : stringList_(stringList) - , index_(value) - { - handle_ = this; - } - StringListValue(const StringList& stringList, int value, const void* handle, const Serialization::TypeID& typeId) - : stringList_(stringList) - , index_(value) - , handle_(handle) - , type_(typeId) - { - } - StringListValue(const StringList& stringList, const char* value) - : stringList_(stringList) - , index_(stringList.find(value)) - { - handle_ = this; - YASLI_ASSERT(index_ != StringList::npos); - } - StringListValue(const StringList& stringList, const char* value, const void* handle, const Serialization::TypeID& typeId) - : stringList_(stringList) - , index_(stringList.find(value)) - , handle_(handle) - , type_(typeId) - { - YASLI_ASSERT(index_ != StringList::npos); - } - StringListValue(const StringListStatic& stringList, const char* value) - : stringList_(stringList) - , index_(stringList.find(value)) - { - handle_ = this; - YASLI_ASSERT(index_ != StringList::npos); - } - StringListValue& operator=(const char* value) - { - index_ = stringList_.find(value); - return *this; - } - StringListValue& operator=(int value) - { - YASLI_ASSERT(value >= 0 && size_t(value) < size_t(stringList_.size())); - YASLI_ASSERT(this != 0); - index_ = value; - return *this; - } - const char* c_str() const - { - if (index_ >= 0 && size_t(index_) < size_t(stringList_.size())) - { - return stringList_[index_].c_str(); - } - else - { - return ""; - } - } - int index() const{ return index_; } - const void* handle() const { return handle_; } - Serialization::TypeID type() const { return type_; } - const StringList& stringList() const{ return stringList_; } - template - void Serialize(IArchive& ar) - { - ar(index_, "index"); - ar(stringList_, "stringList"); - } - protected: - StringList stringList_; - int index_; - const void* handle_; - Serialization::TypeID type_; - }; - - class IArchive; - - void splitStringList(StringList* result, const char* str, char sep); - void joinStringList(string* result, const StringList& stringList, char sep); - void joinStringList(string* result, const StringListStatic& stringList, char sep); - - bool Serialize(Serialization::IArchive& ar, Serialization::StringList& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::StringListValue& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::StringListStaticValue& value, const char* name, const char* label); -} - -#include "StringListImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLIST_H diff --git a/Code/CryEngine/CryCommon/Serialization/StringListImpl.h b/Code/CryEngine/CryCommon/Serialization/StringListImpl.h deleted file mode 100644 index 4f7b573623..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/StringListImpl.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLISTIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLISTIMPL_H -#pragma once - -#include "StringList.h" -#include "IArchive.h" -#include "DynArray.h" -#include "STL.h" - -namespace Serialization { - // --------------------------------------------------------------------------- - inline void splitStringList(StringList* result, const char* str, char delimeter) - { - result->clear(); - - const char* ptr = str; - for (; *ptr; ++ptr) - { - if (*ptr == delimeter) - { - result->push_back(string(str, ptr)); - str = ptr + 1; - } - } - result->push_back(string(str, ptr)); - } - - inline void joinStringList(string* result, const StringList& stringList, char sep) - { - YASLI_ESCAPE(result != 0, return ); - result->clear(); - for (StringList::const_iterator it = stringList.begin(); it != stringList.end(); ++it) - { - if (!result->empty()) - { - result += sep; - } - result->append(*it); - } - } - - inline void joinStringList(string* result, const StringListStatic& stringList, char sep) - { - YASLI_ESCAPE(result != 0, return ); - result->clear(); - for (StringListStatic::const_iterator it = stringList.begin(); it != stringList.end(); ++it) - { - if (!result->empty()) - { - (*result) += sep; - } - YASLI_ESCAPE(*it != 0, continue); - result->append(*it); - } - } - - inline bool Serialize(Serialization::IArchive& ar, Serialization::StringList& value, const char* name, const char* label) - { -#ifdef SERIALIZATION_STANDALONE - return ar(static_cast&>(value), name, label); -#else - return ar(static_cast&>(value), name, label); -#endif - } - - inline bool Serialize(Serialization::IArchive& ar, Serialization::StringListValue& value, const char* name, const char* label) - { - using Serialization::string; - if (ar.IsEdit()) - { - return ar(Serialization::SStruct(value), name, label); - } - else - { - string str; - if (ar.IsOutput()) - { - str = value.c_str(); - } - if (ar(str, name, label) && ar.IsInput()) - { - value = str.c_str(); - return true; - } - return false; - } - } - - inline bool Serialize(Serialization::IArchive& ar, Serialization::StringListStaticValue& value, const char* name, const char* label) - { - using Serialization::string; - if (ar.IsEdit()) - { - return ar(Serialization::SStruct(value), name, label); - } - else - { - string str; - if (ar.IsOutput()) - { - str = value.c_str(); - } - if (ar(str, name, label) && ar.IsInput()) - { - value = str.c_str(); - return true; - } - return true; - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLISTIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Strings.h b/Code/CryEngine/CryCommon/Serialization/Strings.h deleted file mode 100644 index db8be9c3b8..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Strings.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGS_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGS_H -#pragma once - -#ifdef SERIALIZATION_STANDALONE -#include -namespace Serialization { - using std::string; - using std::wstring; -} -#else -#include - -namespace Serialization { - typedef CryStringT string; - typedef CryStringT wstring; -} -#endif // SERIALIZATION_STANDALONE -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGS_H diff --git a/Code/CryEngine/CryCommon/Serialization/TypeID.h b/Code/CryEngine/CryCommon/Serialization/TypeID.h deleted file mode 100644 index 067813d9fc..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/TypeID.h +++ /dev/null @@ -1,290 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEID_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEID_H -#pragma once - - -#include "Serialization/Assert.h" -#include "Serialization/Strings.h" -#include - -namespace Serialization { - class IArchive; - struct TypeInfo; - class TypeID - { - public: - TypeID() - : typeInfo_(0) - , module_(0) {} - - TypeID(const TypeID& original) - : typeInfo_(original.typeInfo_) - , module_(original.module_) - { - } - - operator bool() const{ - return *this != TypeID(); - } - - template - static TypeID get(); - std::size_t sizeOf() const; - const char* name() const; - - bool operator==(const TypeID& rhs) const; - bool operator!=(const TypeID& rhs) const; - bool operator<(const TypeID& rhs) const; - private: - TypeInfo* typeInfo_; - void* module_; - friend struct TypeInfo; - friend class TypeDescription; - }; - - struct TypeInfo - { - TypeID id; - size_t size; - char name[128]; - - // We are trying to minimize type names here. Stripping namespaces, - // whitespaces and S/C/E/I prefixes. Why namespaces? Type names are usually - // used in two contexts: for unique name within factory context, where - // collision is unlikely, or for filtering in PropertyTree where concise - // name is much more useful. - static void cleanTypeName(char*& d, const char* dend, const char*& s, const char* send) - { - if (strncmp(s, "class ", 6) == 0) - { - s += 6; - } - else if (strncmp(s, "struct ", 7) == 0) - { - s += 7; - } - - while (*s == ' ' && s != send) - { - ++s; - } - - // strip C/S/I/E prefixes - if ((*s == 'C' || *s == 'S' || *s == 'I' || *s == 'E') && s[1] >= 'A' && s[1] <= 'Z') - { - ++s; - } - - if (s >= send) - { - return; - } - - char* startd = d; - while (d != dend && s != send) - { - while (*s == ' ' && s != send) - { - ++s; - } - if (s == send) - { - break; - } - if (*s == ':' && s[1] == ':') - { - // strip namespaces - s += 2; - d = startd; - - if ((*s == 'C' || *s == 'S' || *s == 'I' || *s == 'E') && s[1] >= 'A' && s[1] <= 'Z') - { - ++s; - } - } - if (s >= send) - { - break; - } - if (*s == '<') - { - * d = '<'; - ++d; - ++s; - cleanTypeName(d, dend, s, send); - } - else if (*s == '>') - { - * d = '\0'; - return; - } - * d = *s; - ++s; - ++d; - } - } - - template - static void extractTypeName(char (&name)[nameLen], const char* funcName) - { -#ifdef __clang__ - // "static yasli::TypeID yasli::TypeID::get() [T = ActualTypeName]" - const char* s = strstr(funcName, "[T = "); - if (s) - { - s += 5; - } - const char* send = strrchr(funcName, ']'); -#elif __GNUC__ >= 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) - // "static yasli::TypeID yasli::TypeID::get() [with T = ActualTypeName]" - const char* s = strstr(funcName, "[with T = "); - if (s) - { - s += 9; - } - const char* send = strrchr(funcName, ']'); -#else - // "static yasli::TypeID yasli::TypeID::get()" - const char* s = strchr(funcName, '<'); - const char* send = strrchr(funcName, '>'); - YASLI_ASSERT(s != 0 && send != 0); - if (s != send) - { - ++s; - } -#endif - YASLI_ASSERT(s != 0 && send != 0); - - char* d = name; - const char* dend = name + sizeof(name) - 1; - cleanTypeName(d, dend, s, send); - * d = '\0'; - - // This assertion is not critical, but may result in collision as - // stripped name wil be used, e.g. for lookup in factory. - YASLI_ASSERT(s == send && "Type name does not fit into the buffer"); - } - - TypeInfo(size_t _size, const char* templatedFunctionName) - : size(_size) - { - extractTypeName(name, templatedFunctionName); - id.typeInfo_ = this; - static int moduleSpecificSymbol; - id.module_ = &moduleSpecificSymbol; - } - - bool operator==(const TypeInfo& rhs) const - { - return size == rhs.size && strcmp(name, rhs.name) == 0; - } - - bool operator<(const TypeInfo& rhs) const - { - if (size == rhs.size) - { - return strcmp(name, rhs.name) < 0; - } - else - { - return size < rhs.size; - } - } - }; - - template - TypeID TypeID::get() - { -#ifdef _MSC_VER - static TypeInfo typeInfo(sizeof(T), __FUNCSIG__); -#else - static TypeInfo typeInfo(sizeof(T), __PRETTY_FUNCTION__); -#endif - return typeInfo.id; - } - - inline const char* TypeID::name() const - { - if (typeInfo_) - { - return typeInfo_->name; - } - else - { - return ""; - } - } - - inline size_t TypeID::sizeOf() const - { - if (typeInfo_) - { - return typeInfo_->size; - } - else - { - return 0; - } - } - - inline bool TypeID::operator==(const TypeID& rhs) const - { - if (typeInfo_ == rhs.typeInfo_) - { - return true; - } - else if (!typeInfo_ || !rhs.typeInfo_) - { - return false; - } - else if (module_ == rhs.module_) - { - return false; - } - else - { - return *typeInfo_ == *rhs.typeInfo_; - } - } - - inline bool TypeID::operator!=(const TypeID& rhs) const - { - return !operator==(rhs); - } - - inline bool TypeID::operator<(const TypeID& rhs) const - { - if (!typeInfo_) - { - return rhs.typeInfo_ != 0; - } - else if (!rhs.typeInfo_) - { - return false; - } - else - { - return *typeInfo_ < *rhs.typeInfo_; - } - } - - template - T* createDerivedClass(TypeID typeID); -} - -//bool Serialize(Serialization::IArchive& ar, Serialization::TypeID& typeID, const char* name, const char* label); - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEID_H diff --git a/Code/CryEngine/CryCommon/Serialization/TypeInfo.h b/Code/CryEngine/CryCommon/Serialization/TypeInfo.h deleted file mode 100644 index eafd959d51..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/TypeInfo.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFO_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFO_H -#pragma once - - -namespace Serialization { - class IArchive; -} - -struct STypeInfoInstance -{ - template - STypeInfoInstance(T& obj) - : m_pTypeInfo(&TypeInfo(&obj)) - , m_pObject(&obj) - { - } - - STypeInfoInstance(const CTypeInfo* typeInfo, void* object) - : m_pTypeInfo(typeInfo) - , m_pObject(object) - { - } - - inline void Serialize(Serialization::IArchive& ar); - - const CTypeInfo* m_pTypeInfo; - void* m_pObject; - std::set m_persistentStrings; -}; - -#include "TypeInfoImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFO_H diff --git a/Code/CryEngine/CryCommon/Serialization/TypeInfoImpl.h b/Code/CryEngine/CryCommon/Serialization/TypeInfoImpl.h deleted file mode 100644 index 7f94e8bec7..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/TypeInfoImpl.h +++ /dev/null @@ -1,245 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFOIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFOIMPL_H -#pragma once - - - -#include "CryTypeInfo.h" -#include "Serialization/Decorators/Range.h" -#include "Serialization/Enum.h" -#include "ISplines.h" -#include -#include "Serialization/Color.h" -#include "Cry_Color.h" -#include "Decorators/Resources.h" - -struct SPrivateTypeInfoInstanceLevel -{ - SPrivateTypeInfoInstanceLevel(const CTypeInfo* typeInfo, void* object, STypeInfoInstance* instance) - : m_pTypeInfo(typeInfo) - , m_pObject(object) - , m_instance(instance) - { - } - - void Serialize(Serialization::IArchive& ar) - { - for AllSubVars(pVar, *m_pTypeInfo) - { - string group; - if (pVar->GetAttr("Group", group)) - { - if (!m_sCurrentGroup.empty()) - { - ar.CloseBlock(); - } - const char* name = m_instance->m_persistentStrings.insert(group).first->c_str(); - ar.OpenBlock(name, name); - m_sCurrentGroup = name; - } - else - { - const char* name = pVar->GetName(); - if (!*name) - { - name = pVar->Type.Name; - } - - const char* label = pVar->GetName(); - if (!*label) - { - string n = "^"; - n += pVar->GetName(); - label = m_instance->m_persistentStrings.insert(n).first->c_str(); - } - - SerializeVariable(pVar, m_pObject, ar, name, label); - } - } - - if (!m_sCurrentGroup.empty()) - { - ar.CloseBlock(); - m_sCurrentGroup.clear(); - } - } - - template - void SerializeT(const CTypeInfo::CVarInfo* pVar, void* pParentAddress, Serialization::IArchive& ar, const char* name, const char* label) - { - T value; - const CTypeInfo& type = pVar->Type; - type.ToValue(pVar->GetAddress(pParentAddress), value); - ar(value, name, label); - if (ar.IsInput()) - { - type.FromValue(pVar->GetAddress(pParentAddress), value); - } - } - - template - void SerializeNumericalT(const CTypeInfo::CVarInfo* pVar, void* pParentAddress, Serialization::IArchive& ar, const char* name, const char* label) - { - T value; - const CTypeInfo& type = pVar->Type; - type.ToValue(pVar->GetAddress(pParentAddress), value); - - float limMin, limMax; - if (pVar->GetLimit(eLimit_Min, limMin) && pVar->GetLimit(eLimit_Max, limMax)) - { - ar(Serialization::Range(value, limMin, limMax), name, label); - } - else - { - ar(value, name, label); - } - if (ar.IsInput()) - { - type.FromValue(pVar->GetAddress(pParentAddress), value); - } - } - - void SerializeVariable(const CTypeInfo::CVarInfo* pVar, void* pParentAddress, Serialization::IArchive& ar, const char* name, const char* label) - { - const CTypeInfo& type = pVar->Type; - - if (type.HasSubVars()) - { - if (strcmp(name, "Color") == 0) - { - Color3F value; - const CTypeInfo& type = pVar->Type; - type.ToValue(pVar->GetAddress(pParentAddress), value); - ColorF colour = value; - ar(colour, name, label); - if (ar.IsInput()) - { - value = Color3F(colour.r, colour.g, colour.b); - type.FromValue(pVar->GetAddress(pParentAddress), value); - } - } - else - { - // load params of sub-variables (variable is a struct or vector) - SPrivateTypeInfoInstanceLevel instance(&type, pVar->GetAddress(pParentAddress), m_instance); - ar(instance, name, label); - } - } - else - { - if (type.IsType()) - { - SerializeT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.EnumElem(0)) - { - Serialization::StringList stringList; - const char* enumType = type.EnumElem(0); - for (int i = 1; enumType; ++i) - { - stringList.push_back(enumType); - enumType = type.EnumElem(i); - } - - string enumValue = pVar->ToString(pParentAddress); - int index = std::max(stringList.find(enumValue.c_str()), 0); - - Serialization::StringListValue stringListValue(stringList, index); - ar(stringListValue, name, label); - if (ar.IsInput()) - { - pVar->FromString(pParentAddress, stringListValue.c_str()); - } - } - else - { - ISplineInterpolator* pSpline = 0; - if (type.ToValue(pVar->GetAddress(pParentAddress), pSpline)) - { - // TODO: Curve field - } - else - { - string value; - value = pVar->ToString(pParentAddress); - - if (strcmp(name, "Texture") == 0) - { - // TODO: Texture field - } - else if (strcmp(name, "Material") == 0) - { - // TODO: Material field - } - else if (strcmp(name, "Geometry") == 0) - { - ar(Serialization::ModelFilename(value), name, label); - } - else if (strcmp(name, "Sound") == 0) - { - ar(Serialization::SoundName(value), name, label); - } - else if (strcmp(name, "GeomCache") == 0) - { - // TODO: Geom cache field - } - else - { - ar(value, name, label); - } - if (ar.IsInput()) - { - pVar->FromString(pParentAddress, value.c_str()); - } - } - } - } - } - -private: - const CTypeInfo* m_pTypeInfo; - void* m_pObject; - string m_sCurrentGroup; - STypeInfoInstance* m_instance; -}; - -//------------------------------ -inline void STypeInfoInstance::Serialize(Serialization::IArchive& ar) -{ - SPrivateTypeInfoInstanceLevel instance(m_pTypeInfo, m_pObject, this); - instance.Serialize(ar); -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFOIMPL_H diff --git a/Code/CryEngine/CryCommon/crycommon_files.cmake b/Code/CryEngine/CryCommon/crycommon_files.cmake index 3b63dab649..ca95802fd9 100644 --- a/Code/CryEngine/CryCommon/crycommon_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_files.cmake @@ -20,7 +20,6 @@ set(FILES ICmdLine.h IColorGradingController.h IConsole.h - IEngineModule.h IEntityRenderState.h IEntityRenderState_info.cpp IFlares.h @@ -52,7 +51,6 @@ set(FILES IPostEffectGroup.h IProcess.h IReadWriteXMLSink.h - IRemoteCommand.h IRenderAuxGeom.h IRenderer.h IRenderMesh.h @@ -60,7 +58,6 @@ set(FILES IResourceCompilerHelper.h IResourceManager.h ISerialize.h - IServiceNetwork.h IShader.h IShader_info.h ISoftCodeMgr.h @@ -120,7 +117,6 @@ set(FILES MemoryAccess.h Algorithm.h AnimKey.h - AnimTime.h BitFiddling.h CGFContent.h CGFContent_info.cpp @@ -155,7 +151,6 @@ set(FILES CryVersion.h CryZlib.h FrameProfiler.h - GeomCacheFileFormat.h HashGrid.h HeapAllocator.h HeapContainer.h @@ -207,7 +202,6 @@ set(FILES VectorSet.h VertexFormats.h XMLBinaryHeaders.h - Bezier.h RenderBus.h MainThreadRenderRequestBus.h OceanConstants.h @@ -265,101 +259,7 @@ set(FILES platform_impl.cpp Win32specific.h Win64specific.h - CryExtension/CryCreateClassInstance.h - CryExtension/CryGUID.h - CryExtension/CryTypeID.h - CryExtension/ICryFactory.h - CryExtension/ICryFactoryRegistry.h - CryExtension/ICryUnknown.h - CryExtension/Impl/Conversion.h - CryExtension/Impl/ClassWeaver.h - CryExtension/Impl/CryGUIDHelper.h - CryExtension/Impl/ICryFactoryRegistryImpl.h - CryExtension/Impl/RegFactoryNode.h - CryExtension/Impl/TypeList.h - CryPool/Allocator.h - CryPool/Container.h - CryPool/Defrag.h - CryPool/example.h - CryPool/Fallback.h - CryPool/Inspector.h - CryPool/List.h - CryPool/Memory.h - CryPool/PoolAlloc.h - CryPool/STLWrapper.h - CryPool/ThreadSafe.h stl/STLAlignedAlloc.h - Serialization/Assert.h - Serialization/BitVector.h - Serialization/BitVectorImpl.h - Serialization/BlackBox.h - Serialization/BoostSharedPtr.h - Serialization/Callback.h - Serialization/ClassFactory.h - Serialization/ClassFactoryImpl.h - Serialization/Color.h - Serialization/ColorImpl.h - Serialization/CRCRef.h - Serialization/CRCRefImpl.h - Serialization/CryExtension.h - Serialization/CryExtensionImpl.h - Serialization/CryName.h - Serialization/CryNameImpl.h - Serialization/CryStrings.h - Serialization/CryStringsImpl.h - Serialization/DynArray.h - Serialization/DynArrayImpl.h - Serialization/Enum.h - Serialization/EnumImpl.h - Serialization/IArchive.h - Serialization/IArchiveHost.h - Serialization/IClassFactory.h - Serialization/IntrusiveFactory.h - Serialization/ITextInputArchive.h - Serialization/ITextOutputArchive.h - Serialization/KeyValue.h - Serialization/Math.h - Serialization/MathImpl.h - Serialization/NetScriptSerialize.h - Serialization/Object.h - Serialization/Serializer.h - Serialization/SerializerImpl.h - Serialization/SmartPtr.h - Serialization/SmartPtrImpl.h - Serialization/STL.h - Serialization/STLImpl.h - Serialization/StringList.h - Serialization/StringListImpl.h - Serialization/Strings.h - Serialization/TypeID.h - Serialization/TypeInfo.h - Serialization/TypeInfoImpl.h - Serialization/Decorators/ActionButton.h - Serialization/Decorators/BitFlags.h - Serialization/Decorators/BitFlagsImpl.h - Serialization/Decorators/ColorPicker.h - Serialization/Decorators/ColorPickerImpl.h - Serialization/Decorators/JointName.h - Serialization/Decorators/JointNameImpl.h - Serialization/Decorators/LocalFrame.h - Serialization/Decorators/LocalFrameImpl.h - Serialization/Decorators/OutputFilePath.h - Serialization/Decorators/OutputFilePathImpl.h - Serialization/Decorators/Range.h - Serialization/Decorators/RangeImpl.h - Serialization/Decorators/ResourceFilePath.h - Serialization/Decorators/ResourceFilePathImpl.h - Serialization/Decorators/ResourceFolderPath.h - Serialization/Decorators/ResourceFolderPathImpl.h - Serialization/Decorators/Resources.h - Serialization/Decorators/ResourcesAudio.h - Serialization/Decorators/ResourceSelector.h - Serialization/Decorators/Slider.h - Serialization/Decorators/SliderImpl.h - Serialization/Decorators/Sprite.h - Serialization/Decorators/SpriteImpl.h - Serialization/Decorators/TagList.h - Serialization/Decorators/TagListImpl.h LyShine/IDraw2d.h LyShine/ILyShine.h LyShine/ISprite.h diff --git a/Code/CryEngine/CryCommon/platform_impl.cpp b/Code/CryEngine/CryCommon/platform_impl.cpp index 6c261bb1f1..142f07e5e7 100644 --- a/Code/CryEngine/CryCommon/platform_impl.cpp +++ b/Code/CryEngine/CryCommon/platform_impl.cpp @@ -14,8 +14,7 @@ #include #include #include -#include -#include +#include #include #include @@ -42,9 +41,6 @@ SC_API struct SSystemGlobalEnvironment* gEnv = nullptr; #include AZ_RESTRICTED_FILE(platform_impl_h) #endif -//The reg factory is used for registering the different modules along the whole project -struct SRegFactoryNode* g_pHeadToRegFactories = 0; - ////////////////////////////////////////////////////////////////////////// // If not in static library. #include @@ -106,16 +102,6 @@ extern "C" AZ_DLL_EXPORT void ModuleInitISystem(ISystem* pSystem, [[maybe_unused AZ::AllocatorManager::Instance(); // Force the AllocatorManager to instantiate and register any allocators defined in data sections } AZ::Debug::ProfileModuleInit(); - -#if !defined(AZ_MONOLITHIC_BUILD) - ICryFactoryRegistryImpl* pCryFactoryImpl = static_cast(pSystem->GetCryFactoryRegistry()); - if (pCryFactoryImpl) - { - pCryFactoryImpl->RegisterFactories(g_pHeadToRegFactories); - } - - AZ_Error("System", pCryFactoryImpl, "Failed to successfully load factory for %s. You may have a missing or stale DLL that needs to be recompiled.", moduleName); -#endif } // if pSystem } diff --git a/Code/CryEngine/CrySystem/DllMain.cpp b/Code/CryEngine/CrySystem/DllMain.cpp index aba39fb9fb..6173ebc0c6 100644 --- a/Code/CryEngine/CrySystem/DllMain.cpp +++ b/Code/CryEngine/CrySystem/DllMain.cpp @@ -15,10 +15,6 @@ #include "System.h" #include #include "DebugCallStack.h" -#if defined(AZ_MONOLITHIC_BUILD) -#include -#include -#endif #if defined(AZ_RESTRICTED_PLATFORM) #undef AZ_RESTRICTED_SECTION @@ -132,10 +128,7 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar #define AZ_RESTRICTED_SECTION DLLMAIN_CPP_SECTION_2 #include AZ_RESTRICTED_FILE(DllMain_cpp) #endif -#if defined(AZ_MONOLITHIC_BUILD) - ICryFactoryRegistryImpl* pCryFactoryImpl = static_cast(pSystem->GetCryFactoryRegistry()); - pCryFactoryImpl->RegisterFactories(g_pHeadToRegFactories); -#endif // AZ_MONOLITHIC_BUILD + // the earliest point the system exists - w2e tell the callback if (startupParams.pUserCallback) { diff --git a/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.cpp b/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.cpp deleted file mode 100644 index 26c13a070d..0000000000 --- a/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#include "CrySystem_precompiled.h" -#include "CryFactoryRegistryImpl.h" -#include "../System.h" - -#include -#include -#include - -#include - - -CCryFactoryRegistryImpl::CCryFactoryRegistryImpl() - : m_guard() - , m_byCName() - , m_byCID() - , m_byIID() - , m_callbacks() -{ -} - - -CCryFactoryRegistryImpl::~CCryFactoryRegistryImpl() -{ -} - - -CCryFactoryRegistryImpl& CCryFactoryRegistryImpl::Access() -{ - static StaticInstance> s_registry; - return s_registry; -} - - -ICryFactory* CCryFactoryRegistryImpl::GetFactory(const char* cname) const -{ - AUTO_READLOCK(m_guard); - - if (!cname) - { - return 0; - } - - const FactoryByCName search(cname); - FactoriesByCNameConstIt it = std::lower_bound(m_byCName.begin(), m_byCName.end(), search); - return it != m_byCName.end() && !(search < *it) ? (*it).m_ptr : 0; -} - - -ICryFactory* CCryFactoryRegistryImpl::GetFactory(const CryClassID& cid) const -{ - AUTO_READLOCK(m_guard); - - const FactoryByCID search(cid); - FactoriesByCIDConstIt it = std::lower_bound(m_byCID.begin(), m_byCID.end(), search); - return it != m_byCID.end() && !(search < *it) ? (*it).m_ptr : 0; -} - - -void CCryFactoryRegistryImpl::IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const -{ - AUTO_READLOCK(m_guard); - - typedef std::pair SearchResult; - SearchResult res = std::equal_range(m_byIID.begin(), m_byIID.end(), FactoryByIID(iid, 0), LessPredFactoryByIIDOnly()); - - const size_t numFactoriesFound = std::distance(res.first, res.second); - if (pFactories) - { - numFactories = min(numFactories, numFactoriesFound); - FactoriesByIIDConstIt it = res.first; - for (size_t i = 0; i < numFactories; ++i, ++it) - { - pFactories[i] = (*it).m_ptr; - } - } - else - { - numFactories = numFactoriesFound; - } -} - - -void CCryFactoryRegistryImpl::RegisterCallback(ICryFactoryRegistryCallback* pCallback) -{ - if (!pCallback) - { - return; - } - - { - AUTO_MODIFYLOCK(m_guard); - - Callbacks::iterator it = std::lower_bound(m_callbacks.begin(), m_callbacks.end(), pCallback); - if (it == m_callbacks.end() || pCallback < *it) - { - m_callbacks.insert(it, pCallback); - } - else - { - assert(0 && "CCryFactoryRegistryImpl::RegisterCallback() -- pCallback already registered!"); - } - } - { - AUTO_READLOCK(m_guard); - - typedef std::pair SearchResult; - SearchResult res = std::equal_range(m_byIID.begin(), m_byIID.end(), FactoryByIID(cryiidof(), 0), LessPredFactoryByIIDOnly()); - - for (; res.first != res.second; ++res.first) - { - pCallback->OnNotifyFactoryRegistered((*res.first).m_ptr); - } - } -} - - -void CCryFactoryRegistryImpl::UnregisterCallback(ICryFactoryRegistryCallback* pCallback) -{ - if (!pCallback) - { - return; - } - - AUTO_MODIFYLOCK(m_guard); - - Callbacks::iterator it = std::lower_bound(m_callbacks.begin(), m_callbacks.end(), pCallback); - if (it != m_callbacks.end() && !(pCallback < *it)) - { - m_callbacks.erase(it); - } -} - - -bool CCryFactoryRegistryImpl::GetInsertionPos(ICryFactory* pFactory, FactoriesByCNameIt& itPosForCName, FactoriesByCIDIt& itPosForCID) -{ - assert(pFactory); - - struct FatalError - { - static void Report(ICryFactory* pKnownFactory, ICryFactory* pNewFactory) - { - char err[1024]; - sprintf_s(err, sizeof(err), "Conflicting factories...\n" - "Factory (0x%p): ClassID = %s, ClassName = \"%s\"\n" - "Factory (0x%p): ClassID = %s, ClassName = \"%s\"", - pKnownFactory, pKnownFactory ? CryGUIDHelper::Print(pKnownFactory->GetClassID()).c_str() : "$unknown$", pKnownFactory ? pKnownFactory->GetName() : "$unknown$", - pNewFactory, pNewFactory ? CryGUIDHelper::Print(pNewFactory->GetClassID()).c_str() : "$unknown$", pNewFactory ? pNewFactory->GetName() : "$unknown$"); - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_FACTORY_REGISTRY_USE_PRINTF_FOR_FATAL - printf("\n!!! Fatal error !!!\n"); - printf(err); - printf("\n"); -#elif defined(WIN32) || defined(WIN64) - OutputDebugStringA("\n!!! Fatal error !!!\n"); - OutputDebugStringA(err); - OutputDebugStringA("\n"); - MessageBoxA(0, err, "!!! Fatal error !!!", MB_OK | MB_ICONERROR); -#endif - - assert(0); - exit(0); - } - }; - - FactoryByCName searchByCName(pFactory); - FactoriesByCNameIt itForCName = std::lower_bound(m_byCName.begin(), m_byCName.end(), searchByCName); - if (itForCName != m_byCName.end()) - { - // If the addresses match, then this factory is already registered. It's not really worth error-ing about, - // as double registration will not cause any harm. - if (itForCName->m_ptr == pFactory) - { - return false; - } - - if (!(searchByCName < *itForCName)) - { - FatalError::Report((*itForCName).m_ptr, pFactory); - } - } - - FactoryByCID searchByCID(pFactory); - FactoriesByCIDIt itForCID = std::lower_bound(m_byCID.begin(), m_byCID.end(), searchByCID); - if (itForCID != m_byCID.end() && !(searchByCID < *itForCID)) - { - FatalError::Report((*itForCID).m_ptr, pFactory); - } - - itPosForCName = itForCName; - itPosForCID = itForCID; - - return true; -} - - -void CCryFactoryRegistryImpl::RegisterFactories(const SRegFactoryNode* pFactories) -{ - size_t numFactoriesToAdd = 0; - size_t numInterfacesSupported = 0; - { - const SRegFactoryNode* p = pFactories; - while (p) - { - ICryFactory* pFactory = p->m_pFactory; - assert(pFactory); - if (pFactory) - { - const CryInterfaceID* pIIDs = 0; - size_t numIIDs = 0; - pFactory->ClassSupports(pIIDs, numIIDs); - - numInterfacesSupported += numIIDs; - ++numFactoriesToAdd; - } - - p = p->m_pNext; - } - } - - { - AUTO_MODIFYLOCK(m_guard); - - m_byCName.reserve(m_byCName.size() + numFactoriesToAdd); - m_byCID.reserve(m_byCID.size() + numFactoriesToAdd); - m_byIID.reserve(m_byIID.size() + numInterfacesSupported); - - size_t numFactoriesAdded = 0; - const SRegFactoryNode* p = pFactories; - while (p) - { - ICryFactory* pFactory = p->m_pFactory; - if (pFactory) - { - FactoriesByCNameIt itPosForCName; - FactoriesByCIDIt itPosForCID; - if (GetInsertionPos(pFactory, itPosForCName, itPosForCID)) - { - m_byCName.insert(itPosForCName, FactoryByCName(pFactory)); - m_byCID.insert(itPosForCID, FactoryByCID(pFactory)); - - const CryInterfaceID* pIIDs = 0; - size_t numIIDs = 0; - pFactory->ClassSupports(pIIDs, numIIDs); - - for (size_t i = 0; i < numIIDs; ++i) - { - const FactoryByIID newFactory(pIIDs[i], pFactory); - m_byIID.push_back(newFactory); - } - - for (size_t i = 0, s = m_callbacks.size(); i < s; ++i) - { - m_callbacks[i]->OnNotifyFactoryRegistered(pFactory); - } - - ++numFactoriesAdded; - } - } - - p = p->m_pNext; - } - - if (numFactoriesAdded) - { - std::sort(m_byIID.begin(), m_byIID.end()); - } - } -} - - -void CCryFactoryRegistryImpl::UnregisterFactories(const SRegFactoryNode* pFactories) -{ - AUTO_MODIFYLOCK(m_guard); - - const SRegFactoryNode* p = pFactories; - while (p) - { - ICryFactory* pFactory = p->m_pFactory; - UnregisterFactoryInternal(pFactory); - p = p->m_pNext; - } -} - - -void CCryFactoryRegistryImpl::UnregisterFactory(ICryFactory* const pFactory) -{ - AUTO_MODIFYLOCK(m_guard); - - UnregisterFactoryInternal(pFactory); -} - - -void CCryFactoryRegistryImpl::UnregisterFactoryInternal(ICryFactory* const pFactory) -{ - if (pFactory) - { - FactoryByCName searchByCName(pFactory); - FactoriesByCNameIt itForCName = std::lower_bound(m_byCName.begin(), m_byCName.end(), searchByCName); - if (itForCName != m_byCName.end() && !(searchByCName < *itForCName)) - { - assert((*itForCName).m_ptr == pFactory); - if ((*itForCName).m_ptr == pFactory) - { - m_byCName.erase(itForCName); - } - } - - FactoryByCID searchByCID(pFactory); - FactoriesByCIDIt itForCID = std::lower_bound(m_byCID.begin(), m_byCID.end(), searchByCID); - if (itForCID != m_byCID.end() && !(searchByCID < *itForCID)) - { - assert((*itForCID).m_ptr == pFactory); - if ((*itForCID).m_ptr == pFactory) - { - m_byCID.erase(itForCID); - } - } - - const CryInterfaceID* pIIDs = 0; - size_t numIIDs = 0; - pFactory->ClassSupports(pIIDs, numIIDs); - - for (size_t i = 0; i < numIIDs; ++i) - { - FactoryByIID searchByIID(pIIDs[i], pFactory); - FactoriesByIIDIt itForIID = std::lower_bound(m_byIID.begin(), m_byIID.end(), searchByIID); - if (itForIID != m_byIID.end() && !(searchByIID < *itForIID)) - { - m_byIID.erase(itForIID); - } - } - - for (size_t i = 0, s = m_callbacks.size(); i < s; ++i) - { - m_callbacks[i]->OnNotifyFactoryUnregistered(pFactory); - } - } -} - -ICryFactoryRegistry* CSystem::GetCryFactoryRegistry() const -{ - return &CCryFactoryRegistryImpl::Access(); -} diff --git a/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.h b/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.h deleted file mode 100644 index a75ddf782f..0000000000 --- a/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_CRYFACTORYREGISTRYIMPL_H -#define CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_CRYFACTORYREGISTRYIMPL_H -#pragma once - - - -#include -#include - -#include - - -class CCryFactoryRegistryImpl - : public ICryFactoryRegistryImpl -{ -public: - virtual ICryFactory* GetFactory(const char* cname) const; - virtual ICryFactory* GetFactory(const CryClassID& cid) const; - virtual void IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const; - - virtual void RegisterCallback(ICryFactoryRegistryCallback* pCallback); - virtual void UnregisterCallback(ICryFactoryRegistryCallback* pCallback); - - virtual void RegisterFactories(const SRegFactoryNode* pFactories); - virtual void UnregisterFactories(const SRegFactoryNode* pFactories); - - virtual void UnregisterFactory(ICryFactory* const pFactory); - -public: - static CCryFactoryRegistryImpl& Access(); - CCryFactoryRegistryImpl(); - ~CCryFactoryRegistryImpl(); - -private: - struct FactoryByCName - { - const char* m_cname; - ICryFactory* m_ptr; - - FactoryByCName(const char* cname) - : m_cname(cname) - , m_ptr(0) {assert(m_cname); } - FactoryByCName(ICryFactory* ptr) - : m_cname(ptr ? ptr->GetName() : 0) - , m_ptr(ptr) {assert(m_cname && m_ptr); } - bool operator <(const FactoryByCName& rhs) const {return strcmp(m_cname, rhs.m_cname) < 0; } - }; - typedef std::vector FactoriesByCName; - typedef FactoriesByCName::iterator FactoriesByCNameIt; - typedef FactoriesByCName::const_iterator FactoriesByCNameConstIt; - - struct FactoryByCID - { - CryClassID m_cid; - ICryFactory* m_ptr; - - FactoryByCID(const CryClassID& cid) - : m_cid(cid) - , m_ptr(0) {} - FactoryByCID(ICryFactory* ptr) - : m_cid(ptr ? ptr->GetClassID() : MAKE_CRYGUID(0, 0)) - , m_ptr(ptr) {assert(m_ptr); } - bool operator <(const FactoryByCID& rhs) const {return m_cid < rhs.m_cid; } - }; - typedef std::vector FactoriesByCID; - typedef FactoriesByCID::iterator FactoriesByCIDIt; - typedef FactoriesByCID::const_iterator FactoriesByCIDConstIt; - - struct FactoryByIID - { - CryInterfaceID m_iid; - ICryFactory* m_ptr; - - FactoryByIID(CryInterfaceID iid, ICryFactory* pFactory) - : m_iid(iid) - , m_ptr(pFactory) {} - bool operator <(const FactoryByIID& rhs) const - { - if (m_iid != rhs.m_iid) - { - return m_iid < rhs.m_iid; - } - return m_ptr < rhs.m_ptr; - } - }; - typedef std::vector FactoriesByIID; - typedef FactoriesByIID::iterator FactoriesByIIDIt; - typedef FactoriesByIID::const_iterator FactoriesByIIDConstIt; - struct LessPredFactoryByIIDOnly - { - bool operator ()(const FactoryByIID& lhs, const FactoryByIID& rhs) const {return lhs.m_iid < rhs.m_iid; } - }; - - typedef std::vector Callbacks; - typedef Callbacks::iterator CallbacksIt; - typedef Callbacks::const_iterator CallbacksConstIt; - -private: - bool GetInsertionPos(ICryFactory* pFactory, FactoriesByCNameIt& itPosForCName, FactoriesByCIDIt& itPosForCID); - void UnregisterFactoryInternal(ICryFactory* const pFactory); - -private: - mutable CryReadModifyLock m_guard; - - FactoriesByCName m_byCName; - FactoriesByCID m_byCID; - FactoriesByIID m_byIID; - - Callbacks m_callbacks; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_CRYFACTORYREGISTRYIMPL_H diff --git a/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.cpp b/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.cpp deleted file mode 100644 index f87643d4f0..0000000000 --- a/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.cpp +++ /dev/null @@ -1,955 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#include "CrySystem_precompiled.h" -#include "TestExtensions.h" - -#ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES - -#include -#include -#include - - -////////////////////////////////////////////////////////////////////////// - - -namespace TestComposition -{ - struct ITestExt1 - : public ICryUnknown - { - CRYINTERFACE_DECLARE(ITestExt1, 0x9d9e0dcfa5764cb0, 0xa73701595f75bd32) - - virtual void Call1() const = 0; - }; - - DECLARE_SMART_POINTERS(ITestExt1); - - - class CTestExt1 - : public ITestExt1 - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ITestExt1) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CTestExt1, "TestExt1", 0x43b04e7cc1be45ca, 0x9df6ccb1c0dc1ad8) - - public: - virtual void Call1() const; - - private: - int i; - }; - - CRYREGISTER_CLASS(CTestExt1) - - CTestExt1::CTestExt1() - { - i = 1; - } - - CTestExt1::~CTestExt1() - { - printf("Inside CTestExt1 dtor\n"); - } - - void CTestExt1::Call1() const - { - printf("Inside CTestExt1::Call1()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - struct ITestExt2 - : public ICryUnknown - { - CRYINTERFACE_DECLARE(ITestExt2, 0x8eb7a4b399874b9c, 0xb96bd6da7a8c72f9) - - virtual void Call2() = 0; - }; - - DECLARE_SMART_POINTERS(ITestExt2); - - - class CTestExt2 - : public ITestExt2 - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ITestExt2) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CTestExt2, "TestExt2", 0x25b3ebf8f1754b9a, 0xb5494e3da7cdd80f) - - public: - virtual void Call2(); - - private: - int i; - }; - - CRYREGISTER_CLASS(CTestExt2) - - CTestExt2::CTestExt2() - { - i = 2; - } - - CTestExt2::~CTestExt2() - { - printf("Inside CTestExt2 dtor\n"); - } - - void CTestExt2::Call2() - { - printf("Inside CTestExt2::Call2()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CComposed - : public ICryUnknown - { - CRYGENERATE_CLASS(CComposed, "Composed", 0x0439d74b8dcd4b7f, 0x9287dcdf7e26a3a5) - - CRYCOMPOSITE_BEGIN() - CRYCOMPOSITE_ADD(m_pTestExt1, "Ext1") - CRYCOMPOSITE_ADD(m_pTestExt2, "Ext2") - CRYCOMPOSITE_END(CComposed) - - CRYINTERFACE_BEGIN() - CRYINTERFACE_END() - - private: - ITestExt1Ptr m_pTestExt1; - ITestExt2Ptr m_pTestExt2; - }; - - CRYREGISTER_CLASS(CComposed) - - CComposed::CComposed() - : m_pTestExt1() - , m_pTestExt2() - { - CryCreateClassInstance("TestExt1", m_pTestExt1); - CryCreateClassInstance("TestExt2", m_pTestExt2); - } - - CComposed::~CComposed() - { - } - - ////////////////////////////////////////////////////////////////////////// - - struct ITestExt3 - : public ICryUnknown - { - CRYINTERFACE_DECLARE(ITestExt3, 0xdd017935a2134898, 0xbd2fffa145551876) - - virtual void Call3() = 0; - }; - - DECLARE_SMART_POINTERS(ITestExt3); - - class CTestExt3 - : public ITestExt3 - { - CRYGENERATE_CLASS(CTestExt3, "TestExt3", 0xeceab40bc4bb4988, 0xa9f63c1db85a69b1) - - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ITestExt3) - CRYINTERFACE_END() - - public: - virtual void Call3(); - - private: - int i; - }; - - CRYREGISTER_CLASS(CTestExt3) - - CTestExt3::CTestExt3() - { - i = 3; - } - - CTestExt3::~CTestExt3() - { - printf("Inside CTestExt3 dtor\n"); - } - - void CTestExt3::Call3() - { - printf("Inside CTestExt3::Call3()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CComposed2 - : public ICryUnknown - { - CRYGENERATE_CLASS(CComposed2, "Composed2", 0x0439d74b8dcd4b7e, 0x9287dcdf7e26a3a6) - - CRYCOMPOSITE_BEGIN() - CRYCOMPOSITE_ADD(m_pTestExt3, "Ext3") - CRYCOMPOSITE_END(CComposed2) - - CRYINTERFACE_BEGIN() - CRYINTERFACE_END() - - private: - ITestExt3Ptr m_pTestExt3; - }; - - CRYREGISTER_CLASS(CComposed2) - - CComposed2::CComposed2() - : m_pTestExt3() - { - CryCreateClassInstance("TestExt3", m_pTestExt3); - } - - CComposed2::~CComposed2() - { - } - - ////////////////////////////////////////////////////////////////////////// - - class CTestExt4 - : public ITestExt1 - , public ITestExt2 - , public ITestExt3 - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ITestExt1) - CRYINTERFACE_ADD(ITestExt2) - CRYINTERFACE_ADD(ITestExt3) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CTestExt4, "TestExt4", 0x43204e7cc1be45ca, 0x9df4ccb1c0dc1ad8) - - public: - virtual void Call1() const; - virtual void Call2(); - virtual void Call3(); - - private: - int i; - }; - - CRYREGISTER_CLASS(CTestExt4) - - CTestExt4::CTestExt4() - { - i = 4; - } - - CTestExt4::~CTestExt4() - { - printf("Inside CTestExt4 dtor\n"); - } - - void CTestExt4::Call1() const - { - printf("Inside CTestExt4::Call1()\n"); - } - - void CTestExt4::Call2() - { - printf("Inside CTestExt4::Call2()\n"); - } - - void CTestExt4::Call3() - { - printf("Inside CTestExt4::Call3()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CMegaComposed - : public CComposed - , public CComposed2 - { - CRYGENERATE_CLASS(CMegaComposed, "MegaComposed", 0x512787559f84503, 0x421ac1af66f2fb6f) - - CRYCOMPOSITE_BEGIN() - CRYCOMPOSITE_ADD(m_pTestExt4, "Ext4") - CRYCOMPOSITE_ENDWITHBASE2(CMegaComposed, CComposed, CComposed2) - - CRYINTERFACE_BEGIN() - CRYINTERFACE_END() - - private: - AZStd::shared_ptr m_pTestExt4; - }; - - CRYREGISTER_CLASS(CMegaComposed) - - CMegaComposed::CMegaComposed() - : m_pTestExt4() - { - printf("Inside CMegaComposed ctor\n"); - m_pTestExt4 = CTestExt4::CreateClassInstance(); - } - - CMegaComposed::~CMegaComposed() - { - printf("Inside CMegaComposed dtor\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - static void TestComposition() - { - printf("\nTest composition:\n"); - - ICryUnknownPtr p; - if (CryCreateClassInstance("MegaComposed", p)) - { - ITestExt1Ptr p1 = cryinterface_cast(crycomposite_query(p, "Ext1")); - if (p1) - { - p1->Call1(); // calls CTestExt1::Call1() - } - ITestExt2Ptr p2 = cryinterface_cast(crycomposite_query(p, "Ext2")); - if (p2) - { - p2->Call2(); // calls CTestExt2::Call2() - } - ITestExt3Ptr p3 = cryinterface_cast(crycomposite_query(p, "Ext3")); - if (p3) - { - p3->Call3(); // calls CTestExt3::Call3() - } - p3 = cryinterface_cast(crycomposite_query(p, "Ext4")); - if (p3) - { - p3->Call3(); // calls CTestExt4::Call3() - } - p1 = cryinterface_cast(crycomposite_query(p.get(), "Ext4")); - p2 = cryinterface_cast(crycomposite_query(p.get(), "Ext4")); - - bool b = CryIsSameClassInstance(p1, p2); // true - } - - { - ICryUnknownConstPtr pCUnk = p; - ICryUnknownConstPtr pComp1 = crycomposite_query(pCUnk.get(), "Ext1"); - //ICryUnknownPtr pComp1 = crycomposite_query(pCUnk, "Ext1"); // must fail to compile due to const rules - - ITestExt1ConstPtr p1 = cryinterface_cast(pComp1); - if (p1) - { - p1->Call1(); - } - } - } -} // namespace TestComposition - - -////////////////////////////////////////////////////////////////////////// - - -namespace TestExtension -{ - class CFoobar - : public IFoobar - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IFoobar) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CFoobar, "Foobar", 0x76c8dd6d16634531, 0x95d3b1cfabcf7ef4) - - public: - virtual void Foo(); - }; - - CRYREGISTER_CLASS(CFoobar) - - CFoobar::CFoobar() - { - } - - CFoobar::~CFoobar() - { - } - - void CFoobar::Foo() - { - printf("Inside CFoobar::Foo()\n"); - } - - static void TestFoobar() - { - AZStd::shared_ptr p = CFoobar::CreateClassInstance(); - { - CryInterfaceID iid = cryiidof(); - CryClassID clsid = p->GetFactory()->GetClassID(); - int t = 0; - } - - { - IAPtr sp_ = cryinterface_cast(p); // sp_ == NULL - - ICryUnknownPtr sp1 = cryinterface_cast(p); - IFoobarPtr sp = cryinterface_cast(sp1); - sp->Foo(); - } - - { - CFoobar* pF = p.get(); - pF->Foo(); - ICryUnknown* p1 = cryinterface_cast(pF); - } - - IFoobar* pFoo = cryinterface_cast(p.get()); - ICryFactory* pF1 = pFoo->GetFactory(); - pFoo->Foo(); - - int t = 0; - } - - ////////////////////////////////////////////////////////////////////////// - - class CRaboof - : public IRaboof - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IRaboof) - CRYINTERFACE_END() - - CRYGENERATE_SINGLETONCLASS(CRaboof, "Raabof", 0xba482ce12b2e4309, 0x8238ed8b52cb1f1e) - - public: - virtual void Rab(); - }; - - CRYREGISTER_SINGLETON_CLASS(CRaboof) - - CRaboof::CRaboof() - { - } - - CRaboof::~CRaboof() - { - } - - void CRaboof::Rab() - { - printf("Inside CRaboof::Rab()\n"); - } - - static void TestRaboof() - { - AZStd::shared_ptr pFoo0_ = CRaboof::CreateClassInstance(); - IRaboofPtr pFoo0 = cryinterface_cast(pFoo0_); - ICryUnknownPtr p0 = cryinterface_cast(pFoo0); - - CryInterfaceID iid = cryiidof(); - CryClassID clsid = p0->GetFactory()->GetClassID(); - - AZStd::shared_ptr pFoo1 = CRaboof::CreateClassInstance(); - - pFoo0->Rab(); - pFoo1->Rab(); - } - - ////////////////////////////////////////////////////////////////////////// - - class CAB - : public IA - , public IB - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IA) - CRYINTERFACE_ADD(IB) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CAB, "AB", 0xb9e54711a64448c0, 0xa4819b4ed3024d04) - - public: - virtual void A(); - virtual void B(); - - private: - int i; - }; - - CRYREGISTER_CLASS(CAB) - - CAB::CAB() - { - i = 0x12345678; - } - - CAB::~CAB() - { - } - - void CAB::A() - { - printf("Inside CAB::A()\n"); - } - - void CAB::B() - { - printf("Inside CAB::B()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CABC - : public CAB - , public IC - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IC) - CRYINTERFACE_ENDWITHBASE(CAB) - - CRYGENERATE_CLASS(CABC, "ABC", 0x4e61feae11854be7, 0xa16157c5f8baadd9) - - public: - virtual void C(); - - private: - int a; - }; - - CRYREGISTER_CLASS(CABC) - - CABC::CABC() - //: CAB() - { - a = 0x87654321; - } - - CABC::~CABC() - { - } - - void CABC::C() - { - printf("Inside CABC::C()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CCustomC - : public ICustomC - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IC) - CRYINTERFACE_ADD(ICustomC) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CCustomC, "CustomC", 0xee61760b98a44b71, 0xa05e7372b44bd0fd) - - public: - virtual void C(); - virtual void C1(); - - private: - int a; - }; - - CRYREGISTER_CLASS(CCustomC) - - CCustomC::CCustomC() - { - a = 0x87654321; - } - - CCustomC::~CCustomC() - { - } - - void CCustomC::C() - { - printf("Inside CCustomC::C()\n"); - } - - void CCustomC::C1() - { - printf("Inside CCustomC::C1()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CMultiBase - : public CAB - , public CCustomC - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ENDWITHBASE2(CAB, CCustomC) - - CRYGENERATE_CLASS(CMultiBase, "MultiBase", 0x75966b8f98644d42, 0x8fbdd489e94cc29e) - - public: - virtual void A(); - virtual void C1(); - - int i; - }; - - CRYREGISTER_CLASS(CMultiBase) - - CMultiBase::CMultiBase() - { - i = 0x87654321; - } - - CMultiBase::~CMultiBase() - { - } - - void CMultiBase::C1() - { - printf("Inside CMultiBase::C1()\n"); - } - - void CMultiBase::A() - { - printf("Inside CMultiBase::A()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - static void TestComplex() - { - { - ICPtr p; - if (CryCreateClassInstance(MAKE_CRYGUID(0x75966b8f98644d42, 0x8fbdd489e94cc29e), p)) - { - p->C(); - } - } - - { - ICustomCPtr p; - if (CryCreateClassInstance("MultiBase", p)) - { - p->C(); - } - } - - { - IFoobarPtr p; - if (CryCreateClassInstance(MAKE_CRYGUID(0x75966b8f98644d42, 0x8fbdd489e94cc29e), p)) - { - p->Foo(); - } - } - - { - AZStd::shared_ptr p = CMultiBase::CreateClassInstance(); - AZStd::shared_ptr pc = p; - - { - ICryUnknownPtr pUnk = cryinterface_cast(p); - ICryUnknownConstPtr pCUnk0 = cryinterface_cast(p); - ICryUnknownConstPtr pCUnk1 = cryinterface_cast(pc); - //ICryUnknownPtr pUnkF = cryinterface_cast(pc); // must fail to compile due to const rules - - ICryFactory* pF = pUnk->GetFactory(); - - int t = 0; - } - - ICPtr pC = cryinterface_cast(p); - ICustomCPtr pCC = cryinterface_cast(pC); - - p->C(); - p->C1(); - - pC->C(); - pCC->C1(); - - IAPtr pA = cryinterface_cast(p); - pA->A(); - p->A(); - } - - { - AZStd::shared_ptr p = CCustomC::CreateClassInstance(); - - ICPtr pC = cryinterface_cast(p); - ICustomCPtr pCC = cryinterface_cast(pC); - - p->C(); - p->C1(); - - pC->C(); - pCC->C1(); - } - { - CryInterfaceID ia = cryiidof(); - CryInterfaceID ib = cryiidof(); - CryInterfaceID ic = cryiidof(); - CryInterfaceID ico = cryiidof(); - } - - { - AZStd::shared_ptr p = CAB::CreateClassInstance(); - CryClassID clsid = p->GetFactory()->GetClassID(); - - IAPtr pA = cryinterface_cast(p); - IBPtr pB = cryinterface_cast(p); - - IBPtr pB1 = cryinterface_cast(pA); - IAPtr pA1 = cryinterface_cast(pB); - - pA->A(); - pB->B(); - - ICryUnknownPtr p1 = cryinterface_cast(pA); - ICryUnknownPtr p2 = cryinterface_cast(pB); - const ICryUnknown* p3 = cryinterface_cast(pB.get()); - - int t = 0; - } - - { - AZStd::shared_ptr pABC = CABC::CreateClassInstance(); - CryClassID clsid = pABC->GetFactory()->GetClassID(); - - ICryFactory* pFac = pABC->GetFactory(); - pFac->ClassSupports(cryiidof()); - pFac->ClassSupports(cryiidof()); - - IAPtr pABC0 = cryinterface_cast(pABC); - IBPtr pABC1 = cryinterface_cast(pABC0); - ICPtr pABC2 = cryinterface_cast(pABC1); - - pABC2->C(); - pABC1->B(); - - pABC2->GetFactory(); - - const IC* pCconst = pABC2.get(); - const ICryUnknown* pOconst = cryinterface_cast(pCconst); - const IA* pAconst = cryinterface_cast(pOconst); - const IB* pBconst = cryinterface_cast(pAconst); - - //const IA* pA11 = cryinterface_cast(pOconst); - - pCconst = cryinterface_cast(pBconst); - - IC* pC = static_cast(static_cast(pABC1.get())); - pC->C(); // calls IB::B() - - int t = 0; - } - } - - ////////////////////////////////////////////////////////////////////////// - // use of extension system without any of the helper macros/templates - - class CDontLikeMacrosFactory - : public ICryFactory - { - // ICryFactory - public: - virtual const char* GetClassName() const - { - return "DontLikeMacros"; - } - virtual const CryClassID& GetClassID() const - { - static const CryClassID cid = {0x73c3ab0042e6488aull, 0x89ca1a3763365565ull}; - return cid; - } - virtual bool ClassSupports(const CryInterfaceID& iid) const - { - return iid == cryiidof() || iid == cryiidof(); - } - virtual void ClassSupports(const CryInterfaceID*& pIIDs, size_t& numIIDs) const - { - static const CryInterfaceID iids[2] = {cryiidof(), cryiidof()}; - pIIDs = iids; - numIIDs = 2; - } - virtual ICryUnknownPtr CreateClassInstance() const; - - public: - static CDontLikeMacrosFactory& Access() - { - return s_factory; - } - - private: - CDontLikeMacrosFactory() {} - ~CDontLikeMacrosFactory() {} - - private: - static CDontLikeMacrosFactory s_factory; - }; - - CDontLikeMacrosFactory CDontLikeMacrosFactory::s_factory; - - class CDontLikeMacros - : public IDontLikeMacros - { - // ICryUnknown - public: - virtual ICryFactory* GetFactory() const - { - return &CDontLikeMacrosFactory::Access(); - }; - - // only needed to be able to create initial shared_ptr so we don't lose type info for debugging (i.e. inspecting shared_ptr<>) - template - friend void AZStd::Internal::sp_ms_deleter::destroy(); - template - friend AZStd::shared_ptr AZStd::make_shared(); - - protected: - virtual void* QueryInterface(const CryInterfaceID& iid) const - { - if (iid == cryiidof()) - { - return (void*) (ICryUnknown*) this; - } - else if (iid == cryiidof()) - { - return (void*) (IDontLikeMacros*) this; - } - else - { - return 0; - } - } - - virtual void* QueryComposite(const char*) const - { - return 0; - } - - // IDontLikeMacros - public: - virtual void CallMe() - { - printf("Yey, no macros...\n"); - } - - CDontLikeMacros() {} - - protected: - virtual ~CDontLikeMacros() {} - }; - - ICryUnknownPtr CDontLikeMacrosFactory::CreateClassInstance() const - { - AZStd::shared_ptr p = AZStd::make_shared(); - return ICryUnknownPtr(*static_cast*>(static_cast(&p))); - } - - static SRegFactoryNode g_dontLikeMacrosFactory(&CDontLikeMacrosFactory::Access()); - - ////////////////////////////////////////////////////////////////////////// - - static void TestDontLikeMacros() - { - ICryFactory* f = &CDontLikeMacrosFactory::Access(); - - f->ClassSupports(cryiidof()); - f->ClassSupports(cryiidof()); - - const CryInterfaceID* pIIDs = 0; - size_t numIIDs = 0; - f->ClassSupports(pIIDs, numIIDs); - - ICryUnknownPtr p = f->CreateClassInstance(); - IDontLikeMacrosPtr pp = cryinterface_cast(p); - - ICryUnknownPtr pq = crycomposite_query(p, "blah"); - - pp->CallMe(); - } -} // namespace TestExtension - - -////////////////////////////////////////////////////////////////////////// - - -void TestExtensions(ICryFactoryRegistryImpl* pReg) -{ - printf("Test extensions:\n"); - - struct MyCallback - : public ICryFactoryRegistryCallback - { - virtual void OnNotifyFactoryRegistered(ICryFactory* pFactory) - { - int test = 0; - } - virtual void OnNotifyFactoryUnregistered(ICryFactory* pFactory) - { - int test = 0; - } - }; - - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x4); - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x1); - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x3); - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x3); - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x2); - - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x2); - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x2); - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x4); - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x3); - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x1); - - //MyCallback callback0; - //pReg->RegisterCallback(&callback0); - //pReg->RegisterFactories(g_pHeadToRegFactories); - - //pReg->RegisterFactories(g_pHeadToRegFactories); - //pReg->UnregisterFactories(g_pHeadToRegFactories); - - ICryFactory* pF[4]; - size_t numFactories = 4; - pReg->IterateFactories(cryiidof(), pF, numFactories); - pReg->IterateFactories(MAKE_CRYGUID(-1, -1), pF, numFactories); - - numFactories = (size_t) -1; - pReg->IterateFactories(cryiidof(), 0, numFactories); - - MyCallback callback1; - pReg->RegisterCallback(&callback1); - pReg->UnregisterCallback(&callback1); - - ICryFactory* p; - p = pReg->GetFactory(MAKE_CRYGUID(0xee61760b98a44b71, 0xa05e7372b44bd0fd)); - p = pReg->GetFactory("CustomC"); - p = pReg->GetFactory("ABC"); - p = pReg->GetFactory((const char*)0); - - p = pReg->GetFactory("DontLikeMacros"); - p = pReg->GetFactory(MAKE_CRYGUID(0x73c3ab0042e6488a, 0x89ca1a3763365565)); - - TestExtension::TestFoobar(); - TestExtension::TestRaboof(); - TestExtension::TestComplex(); - TestExtension::TestDontLikeMacros(); - - TestComposition::TestComposition(); -} - -#endif // #ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES diff --git a/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.h b/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.h deleted file mode 100644 index ac9ad04dc7..0000000000 --- a/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_TESTCASES_TESTEXTENSIONS_H -#define CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_TESTCASES_TESTEXTENSIONS_H -#pragma once - - -//#define EXTENSION_SYSTEM_INCLUDE_TESTCASES - -#ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES - -#include - -struct ICryFactoryRegistryImpl; - -void TestExtensions(ICryFactoryRegistryImpl* pReg); - -struct IFoobar - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IFoobar, 0x539e9c672cad4a03, 0x9ecd8069c99a846b) - - virtual void Foo() = 0; -}; - -DECLARE_SMART_POINTERS(IFoobar); - -struct IRaboof - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IRaboof, 0x135ca25e634b4d13, 0x9e4467968a708822) - - virtual void Rab() = 0; -}; - -DECLARE_SMART_POINTERS(IRaboof); - -struct IA - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IA, 0xd93aaceb35ec427e, 0xb64bf8dec4997e67) - - virtual void A() = 0; -}; - -DECLARE_SMART_POINTERS(IA); - -struct IB - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IB, 0xe0d830c826424e11, 0x9eacfa19eaf31ffb) - - virtual void B() = 0; -}; - -DECLARE_SMART_POINTERS(IB); - -struct IC - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IC, 0x577509a20fc5477c, 0x893757c9ca88b27b) - - virtual void C() = 0; -}; - -DECLARE_SMART_POINTERS(IC); - -struct ICustomC - : public IC -{ - CRYINTERFACE_DECLARE(ICustomC, 0x2ac769da4c7443bf, 0x80911033e21dfbcf) - - virtual void C1() = 0; -}; - -DECLARE_SMART_POINTERS(ICustomC); - -////////////////////////////////////////////////////////////////////////// -// use of extension system without any of the helper macros/templates - -struct IDontLikeMacros - : public ICryUnknown -{ - template - friend const CryInterfaceID& InterfaceCastSemantics::cryiidof(); - template - friend void AZStd::Internal::sp_ms_deleter::destroy(); - template - friend AZStd::shared_ptr AZStd::make_shared(); -protected: - virtual ~IDontLikeMacros() {} - -private: - // It's very important that this static function is implemented for each interface! - // Otherwise the consistency of cryinterface_cast() is compromised because - // cryiidof() = cryiidof>() {baseof = ICryUnknown in most cases} - static const CryInterfaceID& IID() - { - static const CryInterfaceID iid = {0x0f43b7e3f1364af0ull, 0xb4a16a975bea3ec4ull}; - return iid; - } - -public: - virtual void CallMe() = 0; -}; - -DECLARE_SMART_POINTERS(IDontLikeMacros); - - -#endif // #ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES - -#endif // CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_TESTCASES_TESTEXTENSIONS_H diff --git a/Code/CryEngine/CrySystem/RemoteCommand.cpp b/Code/CryEngine/CrySystem/RemoteCommand.cpp deleted file mode 100644 index 5f1129be22..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommand.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system implementation - -#include "CrySystem_precompiled.h" -#include "IServiceNetwork.h" -#include "RemoteCommand.h" -#include "RemoteCommandHelpers.h" - -//----------------------------------------------------------------------------- - -// remote system internal logging -#ifdef RELEASE - #define LOG_VERBOSE(level, txt, ...) -#else - #define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); } -#endif - -//----------------------------------------------------------------------------- - -CRemoteCommandManager::CRemoteCommandManager() -{ - // Create the CVAR - m_pVerboseLevel = gEnv->pConsole->RegisterInt("rc_debugVerboseLevel", 0, VF_DEV_ONLY); -} - -CRemoteCommandManager::~CRemoteCommandManager() -{ - // Release the CVar - if (NULL != m_pVerboseLevel) - { - m_pVerboseLevel->Release(); - m_pVerboseLevel = NULL; - } -} - -IRemoteCommandServer* CRemoteCommandManager::CreateServer(uint16 localPort) -{ - // Create the listener - IServiceNetworkListener* listener = gEnv->pServiceNetwork->CreateListener(localPort); - if (NULL == listener) - { - return NULL; - } - - // Create the wrapper - return new CRemoteCommandServer(this, listener); -} - -IRemoteCommandClient* CRemoteCommandManager::CreateClient() -{ - // Create the wrapper - return new CRemoteCommandClient(this); -} - -void CRemoteCommandManager::RegisterCommandClass(IRemoteCommandClass& commandClass) -{ - // Make sure command class is not already registered - const string& className(commandClass.GetName()); - TClassMap::const_iterator it = m_pClasses.find(className); - if (it != m_pClasses.end()) - { - LOG_VERBOSE(1, "Class '%s' is already registered", - className.c_str()); - - return; - } - - const uint32 classID = m_pClassesByID.size(); - m_pClassesByID.push_back(&commandClass); - m_pClassesMap[ className ] = classID; - m_pClasses[ className ] = &commandClass; - - // Verbose - LOG_VERBOSE(1, "Registered command class '%s' with id %d", - className.c_str(), - classID); -} - -#ifndef RELEASE -bool CRemoteCommandManager::CheckVerbose(const uint32 level) const -{ - const int verboseLevel = m_pVerboseLevel->GetIVal(); - return (int)level < verboseLevel; -} - -void CRemoteCommandManager::Log(const char* txt, ...) const -{ - // format the print buffer - char buffer[512]; - va_list ap; - va_start(ap, txt); - vsprintf_s(buffer, sizeof(buffer), txt, ap); - va_end(ap); - - // pass to log - gEnv->pLog->LogAlways(buffer); -} -#endif - -void CRemoteCommandManager::BuildClassMapping(const std::vector& classNames, std::vector< IRemoteCommandClass* >& outClasses) -{ - LOG_VERBOSE(3, "Building class mapping for %d classes", - classNames.size()); - - // Output list size has the same size as class names array - const uint32 numClasses = classNames.size(); - outClasses.resize(numClasses); - - // Match the classes - for (size_t i = 0; i < numClasses; ++i) - { - // Find the matching class - const string& className = classNames[i]; - TClassMap::const_iterator it = m_pClasses.find(className); - if (it != m_pClasses.end()) - { - CRY_ASSERT(className == it->second->GetName()); - CRY_ASSERT(it->second != NULL); - outClasses[i] = it->second; - - // Report class mapping in heavy verbose mode - LOG_VERBOSE(3, "Class[%d] = %s", - i, - className.c_str()); - } - else - { - outClasses[i] = NULL; - - // Class not mapped (this can cause errors) - LOG_VERBOSE(0, "Remote command class '%s' not found on this machine", - className.c_str()); - } - } -} - -void CRemoteCommandManager::SetVerbosityLevel(const uint32 level) -{ - // propagate the value to CVar (so it is consistent across the engine) - if (NULL != m_pVerboseLevel) - { - m_pVerboseLevel->Set((int)level); - } -} - -void CRemoteCommandManager::GetClassList(std::vector& outClassNames) const -{ - const uint32 numClasses = m_pClassesByID.size(); - outClassNames.resize(numClasses); - for (size_t id = 0; id < numClasses; ++id) - { - IRemoteCommandClass* theClass = m_pClassesByID[id]; - if (NULL != theClass) - { - outClassNames[id] = theClass->GetName(); - } - } -} - -bool CRemoteCommandManager::FindClassId(IRemoteCommandClass* commandClass, uint32& outClassId) const -{ - // Local search (linear, slower) - TClassIDMap::const_iterator it = m_pClassesMap.find(commandClass->GetName()); - if (it != m_pClassesMap.end()) - { - outClassId = it->second; - return true; - } - - // Not found - return false; -} - -//----------------------------------------------------------------------------- - -// Do not remove (can mess up the uber file builds) -#undef LOG_VERBOSE - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/RemoteCommand.h b/Code/CryEngine/CrySystem/RemoteCommand.h deleted file mode 100644 index 6ce5e3fd11..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommand.h +++ /dev/null @@ -1,459 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system implementation - - -#pragma once - - -//----------------------------------------------------------------------------- - -#include "IServiceNetwork.h" -#include "IRemoteCommand.h" -#include "CryThread.h" - -class CRemoteCommandManager; - -// Remote command client implementation -class CRemoteCommandClient - : public IRemoteCommandClient - , public CryRunnable -{ -protected: - //------------------------------------------------------------- - - class Command - { - public: - ILINE IServiceNetworkMessage* GetMessage() const - { - return m_pMessage; - } - - ILINE uint32 GetCommandId() const - { - return m_id; - } - - public: - // Create command data from serializing a remote command object - static Command* Compile(const IRemoteCommand& cmd, const uint32 commandId, const uint32 classId); - - void AddRef(); - void Release(); - - private: - Command(); - ~Command(); - - volatile int m_refCount; - uint32 m_id; - const char* m_szClassName; // debug only - IServiceNetworkMessage* m_pMessage; - }; - - //------------------------------------------------------------- - - // Local connection reference to command - // NOTE: pCommand is reference counted from the calling code - struct CommandRef - { - Command* m_pCommand; - uint64 m_lastSentTime; - - ILINE CommandRef() - : m_pCommand(NULL) - , m_lastSentTime(0) - {} - - ILINE CommandRef(Command* pCommand) - : m_pCommand(pCommand) - , m_lastSentTime(0) - {} - - // Order function for set container (we want to keep the commands sorted by ID) - static ILINE bool CompareCommandRefs(CommandRef* const& a, CommandRef* const& b) - { - return a->m_pCommand->GetCommandId() < b->m_pCommand->GetCommandId(); - } - }; - - //------------------------------------------------------------- - - // Remote server connection wrapper - class Connection - : public IRemoteCommandConnection - { - // How many commands we can send upfront before waiting for an ACK - static const uint32 kCommandSendLead = 50; - - // How much command data can be merged into a single packet (KB) - static const uint32 kCommandMaxMergePacketSize = 1024; - - // Time after which we start resending commands (ms) - static const uint32 kCommandResendTime = 2000; - - protected: - CRemoteCommandManager* m_pManager; - volatile int m_refCount; - - // Connection (from service network layer) - IServiceNetworkConnection* m_pConnection; - - // Cached address of the remote endpoint - ServiceNetworkAddress m_remoteAddress; - - // Pending commands, they are kept ed here until they are ACKed as executed by server - typedef std::vector TCommands; - TCommands m_pCommands; - CryMutex m_commandAccessMutex; - - // A queue of raw messages - typedef CryMT::CLocklessPointerQueue TRawMessageQueue; - TRawMessageQueue m_pRawMessages; - CryMutex m_rawMessagesMutex; - - // Last command that was ACKed as received by server - // This is used to synchronize the both ends of the pipeline - uint32 m_lastReceivedCommand; - - // Last command that was ACKed as executed by server - // This is used to synchronize the both ends of the pipeline - uint32 m_lastExecutedCommand; - - public: - ILINE CRemoteCommandManager* GetManager() const - { - return m_pManager; - } - - public: - Connection(CRemoteCommandManager* pManager, IServiceNetworkConnection* pConnection, uint32 currentCommandId); - - // Add command to sending queue in this connection - void AddToSendQueue(Command* pCommand); - - // Process the communication, returns false if connection should be deleted - bool Update(); - - // Send the "disconnect" message to the remote side therefore gracefully closing the connection. - void SendDisconnectMessage(); - - public: - // IRemoteCommandConnection interface implementation - virtual bool IsAlive() const; - virtual const ServiceNetworkAddress& GetRemoteAddress() const; - virtual bool SendRawMessage(IServiceNetworkMessage* pMessage); - virtual IServiceNetworkMessage* ReceiveRawMessage(); - virtual void Close(bool bFlushQueueBeforeClosing = false); - virtual void AddRef(); - virtual void Release(); - - private: - ~Connection(); - }; - -protected: - CRemoteCommandManager* m_pManager; - - typedef std::vector TConnections; - TConnections m_pConnections; - TConnections m_pConnectionsToDelete; - CryMutex m_accessMutex; - - // Local command ID counter, incremented atomically using CryInterlockedIncrement - volatile uint32 m_commandId; - - typedef CryThread TRemoteClientThread; - TRemoteClientThread* m_pThread; - CryEvent m_threadEvent; - bool m_bCloseThread; - -public: - ILINE CRemoteCommandManager* GetManager() const - { - return m_pManager; - } - -public: - CRemoteCommandClient(CRemoteCommandManager* pManager); - virtual ~CRemoteCommandClient(); - - // IRemoteCommandClient interface - virtual void Delete(); - virtual bool Schedule(const IRemoteCommand& command); - virtual IRemoteCommandConnection* ConnectToServer(const class ServiceNetworkAddress& serverAddress); - - // CryRunnable interface implementation - virtual void Run(); - virtual void Cancel(); -}; - -//----------------------------------------------------------------------------- - -// Remote command server implementation -class CRemoteCommandServer - : public IRemoteCommandServer - , public CryRunnable -{ -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(RemoteCommand_h) -#endif - -protected: - // Wrapped commands - class WrappedCommand - { - private: - IRemoteCommand* m_pCommand; - volatile int m_refCount; - uint32 m_commandID; - - public: - ILINE const uint32 GetId() const - { - return m_commandID; - } - - ILINE IRemoteCommand* GetCommand() const - { - return m_pCommand; - } - - public: - WrappedCommand(IRemoteCommand* pCommand, const uint32 commandId); - void AddRef(); - void Release(); - - private: - ~WrappedCommand(); - }; - - // Local endpoint - class Endpoint - { - private: - IServiceNetworkConnection* m_pConnection; - class CRemoteCommandServer* m_pServer; - CRemoteCommandManager* m_pManager; - - // ACK counters for synchronization - uint32 m_lastReceivedCommand; - uint32 m_lastExecutedCommand; - uint32 m_lastReceivedCommandACKed; - uint32 m_lastExecutedCommandACKed; - CryMutex m_accessLock; - - // We have received class list (it's a valid RC connection) - bool m_bHasReceivedClassList; - - // Locally mapped class id (because IDs on remote side can be different than here) - typedef std::vector< IRemoteCommandClass* > TLocalClassFactoryList; - TLocalClassFactoryList m_pLocalClassFactories; - - // Commands that were received and should be executed - typedef CryMT::CLocklessPointerQueue< WrappedCommand > TCommandQueue; - TCommandQueue m_pCommandsToExecute; - CryMutex m_commandListLock; - - public: - ILINE CRemoteCommandManager* GetManager() const - { - return m_pManager; - } - - // Get the endpoint connection - ILINE IServiceNetworkConnection* GetConnection() const - { - return m_pConnection; - } - - // Have we received a class list from the client - ILINE bool HasReceivedClassList() const - { - return m_bHasReceivedClassList; - } - - public: - Endpoint(CRemoteCommandManager* pManager, class CRemoteCommandServer* pServer, IServiceNetworkConnection* pConnection); - ~Endpoint(); - - // Execute pending commands (called from main thread) - void Execute(); - - // Update (send/receive, etc) Returns false if endpoint died. - bool Update(); - - // Get the class name as translated by this endpoint (by ID) - const char* GetClassName(const uint32 classId) const; - - // Create command object by class ID - IRemoteCommand* CreateObject(const uint32 classId) const; - }; - - // Received raw message - // Beware to use always via pointer to this type since propper reference counting is not implemented for copy and assigment - struct RawMessage - { - // We keep a reference to connection so we know where to send the response - IServiceNetworkConnection* m_pConnection; - IServiceNetworkMessage* m_pMessage; - - ILINE RawMessage(IServiceNetworkConnection* pConnection, IServiceNetworkMessage* pMessage) - : m_pConnection(pConnection) - , m_pMessage(pMessage) - { - m_pMessage->AddRef(); - m_pConnection->AddRef(); - } - - ILINE ~RawMessage() - { - m_pMessage->Release(); - m_pConnection->Release(); - } - - private: - ILINE RawMessage([[maybe_unused]] const RawMessage& other) {}; - ILINE RawMessage& operator==([[maybe_unused]] const RawMessage& other) { return *this; } - }; - -protected: - CRemoteCommandManager* m_pManager; - - // Network listening socket - IServiceNetworkListener* m_pListener; - - // Live endpoints - typedef std::vector TEndpoints; - TEndpoints m_pEndpoints; - TEndpoints m_pUpdateEndpoints; - CryMutex m_accessLock; - - // Endpoints that were discarded and should be deleted - // We can delete endpoints only from the update thread - TEndpoints m_pEndpointToDelete; - - // Received raw messages - typedef CryMT::CLocklessPointerQueue TRawMessagesQueue; - TRawMessagesQueue m_pRawMessages; - CryMutex m_rawMessagesLock; - - // Listeners for raw messages that require synchronous processing - typedef std::vector TRawMessageListenersSync; - TRawMessageListenersSync m_pRawListenersSync; - - // Listeners for raw messages that can be processed asynchronously (faster path) - typedef std::vector TRawMessageListenersAsync; - TRawMessageListenersAsync m_pRawListenersAsync; - - // Command communication and deserialization is done on thread - typedef CryThread TRemoteServerThread; - TRemoteServerThread* m_pThread; - - // Suppression counter (execution of commands is suppressed when>0) - // This is updated using CryInterlocked* functions - volatile int m_suppressionCounter; - bool m_bIsSuppressed; - - // Request to close the network thread - bool m_bCloseThread; - -public: - ILINE CRemoteCommandManager* GetManager() const - { - return m_pManager; - } - -public: - CRemoteCommandServer(CRemoteCommandManager* pManager, IServiceNetworkListener* pListener); - virtual ~CRemoteCommandServer(); - - // IRemoteCommandServer interface implementation - virtual void Delete(); - virtual void FlushCommandQueue(); - virtual void SuppressCommands(); - virtual void ResumeCommands(); - virtual void RegisterSyncMessageListener(IRemoteCommandListenerSync* pListener); - virtual void UnregisterSyncMessageListener(IRemoteCommandListenerSync* pListener); - virtual void RegisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener); - virtual void UnregisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener); - virtual void Broadcast(IServiceNetworkMessage* pMessage); - virtual bool HasConnectedClients() const; - - // CryRunnable - virtual void Run(); - virtual void Cancel(); - -protected: - void ProcessRawMessageAsync(IServiceNetworkMessage* pMessage, IServiceNetworkConnection* pConnection); - void ProcessRawMessagesSync(); -}; - -//----------------------------------------------------------------------------- - -// Remote command manager implementation -class CRemoteCommandManager - : public IRemoteCommandManager -{ -public: - CRemoteCommandManager(); - virtual ~CRemoteCommandManager(); - - // IRemoteCommandManager interface implementation - virtual void SetVerbosityLevel(const uint32 level); - virtual IRemoteCommandServer* CreateServer(uint16 localPort); - virtual IRemoteCommandClient* CreateClient(); - virtual void RegisterCommandClass(IRemoteCommandClass& commandClass); - - // Debug print -#ifdef RELEASE - void Log([[maybe_unused]] const char* txt, ...) const {}; - bool CheckVerbose([[maybe_unused]] const uint32 level) const { return false; } -#else - void Log(const char* txt, ...) const; - bool CheckVerbose(const uint32 level) const; -#endif - - // Build ID->Class Factory mapping given the class name list, will report errors to the log. - void BuildClassMapping(const std::vector& classNames, std::vector< IRemoteCommandClass* >& outClasses); - - // Get list of class names (in order of their IDs) - void GetClassList(std::vector& outClassNames) const; - - // Find class ID for given class, returns false if not found - bool FindClassId(IRemoteCommandClass* commandClass, uint32& outClassId) const; - -public: - ILINE CRemoteCommandManager* GetManager() - { - return this; - } - -private: - // Class name mapping - typedef std::map< string, IRemoteCommandClass* > TClassMap; - TClassMap m_pClasses; - - // Class ID lookup - typedef std::vector< IRemoteCommandClass* > TClassIDList; - TClassIDList m_pClassesByID; - - // Class ID mapping - typedef std::map< string, int > TClassIDMap; - TClassIDMap m_pClassesMap; - - // Verbose level - ICVar* m_pVerboseLevel; -}; diff --git a/Code/CryEngine/CrySystem/RemoteCommandClient.cpp b/Code/CryEngine/CrySystem/RemoteCommandClient.cpp deleted file mode 100644 index 1855aae4a9..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommandClient.cpp +++ /dev/null @@ -1,756 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system implementation - -#include "CrySystem_precompiled.h" -#include "IServiceNetwork.h" -#include "RemoteCommand.h" -#include "RemoteCommandHelpers.h" - -//----------------------------------------------------------------------------- - -// remote system internal logging -#ifdef RELEASE - #define LOG_VERBOSE(level, txt, ...) -#else - #define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); } -#endif - -//----------------------------------------------------------------------------- - -CRemoteCommandClient::Command::Command() - : m_refCount(1) - , m_szClassName(NULL) - , m_id(0) -{ -} - -CRemoteCommandClient::Command::~Command() -{ - // Release message buffer with compiled command data - if (m_pMessage != NULL) - { - m_pMessage->Release(); - m_pMessage = NULL; - } -} - -CRemoteCommandClient::Command* CRemoteCommandClient::Command::Compile(const IRemoteCommand& cmd, const uint32 commandId, const uint32 classId) -{ - // Build command header - CommandHeader header; - header.classId = classId; - header.commandId = commandId; - header.size = 0; // not known yet - - // Output stream builder - CDataWriteStreamBuffer writer; - - // Start the packet with a command header (it will be later overwritten) - writer << header; - - // Serialize command header and data - const uint32 commandDataStart = writer.GetSize(); - cmd.SaveToStream(writer); - const uint32 commandDataEnd = writer.GetSize(); - - // Extract a message from the stream - IServiceNetworkMessage* pMessage = writer.BuildMessage(); - if (NULL == pMessage) - { - // No message was generated (for some reason) - // Do not allow this command to compile - return NULL; - } - - // Rewrite header with the proper command size - // This is a little bit over-the-top because it uses another serializer created - // on top of the message buffer. The advantage is that we have the endianess problem abstracted away. - // TODO: consider writing the size directly - { - // update header with popper data size - const uint32 dataSize = commandDataEnd - commandDataStart; - header.size = dataSize; - - // rewrite the header in existing message - CDataWriteStreamToMessage inPlaceWriter(pMessage); - inPlaceWriter << header; - } - - // Create command wrapper - Command* pCommand = new Command(); - pCommand->m_id = commandId; - pCommand->m_szClassName = cmd.GetClass()->GetName(); - pCommand->m_pMessage = pMessage; - return pCommand; -} - -void CRemoteCommandClient::Command::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CRemoteCommandClient::Command::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -//----------------------------------------------------------------------------- - -CRemoteCommandClient::Connection::Connection(CRemoteCommandManager* pManager, IServiceNetworkConnection* pConnection, uint32 currentCommandId) - : m_pConnection(pConnection) - , m_pManager(pManager) - , m_lastReceivedCommand(currentCommandId) - , m_lastExecutedCommand(currentCommandId) - , m_remoteAddress(pConnection->GetRemoteAddress()) - , m_refCount(1) -{ - // The first thing to do after the connection is initialized is to - // send the message with list of classes supported by this side. - { - // Write the header - PackedHeader header; - header.magic = PackedHeader::kMagic; - header.msgType = PackedHeader::eCommand_ClassList; - header.count = currentCommandId; // send the intial command ID so we can be in sync - - // Get the class list for our local remote command manager - std::vector< string > classList; - GetManager()->GetClassList(classList); - - // Write the message - CDataWriteStreamBuffer writer; - writer << header; - writer << classList; - - // Send the message to the remote side - IServiceNetworkMessage* pMsg = writer.BuildMessage(); - if (NULL != pMsg) - { - LOG_VERBOSE(1, "Sent class list message (%d classes, size=%d) to '%s'", - classList.size(), - pMsg->GetSize(), - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // TODO: well, there is no reason this can fail since the connection is brand new, but... - // We still relay on the service network to deliver this message unharmed. - m_pConnection->SendMsg(pMsg); - - // cleanup - pMsg->Release(); - } - } -} - -CRemoteCommandClient::Connection::~Connection() -{ - // Close the connection - const bool bFlushBeforeClosing = false; - Close(bFlushBeforeClosing); - - // Release any commands left over on the list - for (TCommands::const_iterator it = m_pCommands.begin(); - it != m_pCommands.end(); ++it) - { - (*it)->m_pCommand->Release(); - delete (*it); - } - m_pCommands.clear(); - - // Release all of the raw messages that were not picked up - while (!m_pRawMessages.empty()) - { - IServiceNetworkMessage* pMessage = m_pRawMessages.pop(); - pMessage->Release(); - } - - // Release the connection object - SAFE_RELEASE(m_pConnection); -} - -void CRemoteCommandClient::Connection::SendDisconnectMessage() -{ - if (NULL != m_pConnection && m_pConnection->IsAlive()) - { - IDataWriteStream* pWriter = gEnv->pServiceNetwork->CreateMessageWriter(); - if (NULL != pWriter) - { - // write header to message - PackedHeader header; - header.magic = PackedHeader::kMagic; - header.count = 0; - header.msgType = PackedHeader::eCommand_Disconnect; - *pWriter << header; - - // Send the disconnect signal - IServiceNetworkMessage* pMessage = pWriter->BuildMessage(); - if (NULL != pMessage) - { - m_pConnection->SendMsg(pMessage); - pMessage->Release(); - } - - pWriter->Delete(); - } - } -} - -void CRemoteCommandClient::Connection::AddToSendQueue(Command* pCommand) -{ - // Do not add commands if the connection is closed - if (m_pConnection == NULL) - { - return; - } - - // Add command to local list - // NOTE: this list always needs to be sorted in increasing command ID for various optimization reason. - // This is achieved by resorting after pushing each element. Usually the cost of this is close to nothing - // because incoming commands tend to be added with increasing command IDs. - // The only case when something else can happen is when commands are added from different threads - // and the one that was lower CommandID took longer to serialize and therefore is added later. - // Anyway, this case is handled here. - { - CryAutoLock lock(m_commandAccessMutex); - - // Always add to the end (don't try to guess position) - // TODO: consider binary search - m_pCommands.push_back(new CommandRef(pCommand)); - - // Resort, NODE: This usually does not sort anything because the vector is already sorted - std::sort(m_pCommands.begin(), m_pCommands.end(), CommandRef::CompareCommandRefs); - } - - // Keep local reference to command (since we added it to our array) - pCommand->AddRef(); -} - -bool CRemoteCommandClient::Connection::Update() -{ - // If the network connection got dead we should close this one to - if ((NULL == m_pConnection) || !m_pConnection->IsAlive()) - { - return false; - } - - // Receive ACKs first so we have better view of what to send - uint32 newLastExecutedCommand = m_lastExecutedCommand; - uint32 newLastReceivedCommand = m_lastReceivedCommand; - IServiceNetworkMessage* pMsg = m_pConnection->ReceiveMsg(); - while (pMsg != NULL) - { - // Deserialize the message - { - CDataReadStreamFormMessage reader(pMsg); - ResponseHeader response; - reader << response; - - // is this proper command system message ? - if (response.magic == PackedHeader::kMagic) - { - if (response.msgType == PackedHeader::eCommand_ACK) - { - // Update internal ACK values - // This code supports getting the ACK messages out of order. - newLastExecutedCommand = max(newLastExecutedCommand, response.lastCommandExecuted); - newLastReceivedCommand = max(newLastReceivedCommand, response.lastCommandReceived); - - LOG_VERBOSE(3, "ACK (rcv=%d, exe=%d) received from '%s'", - response.lastCommandReceived, - response.lastCommandExecuted, - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - else if (response.msgType == PackedHeader::eCommand_Disconnect) - { - // Disconnect request was received - LOG_VERBOSE(3, "DISCONNECT (rcv=%d, exe=%d) received from '%s'", - response.lastCommandReceived, - response.lastCommandExecuted, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // Close connection - m_pConnection->Close(); - m_pConnection->Release(); - m_pConnection = NULL; - - // release the message - pMsg->Release(); - - // Signal manager to delete this object - return false; - } - } - else - { - // Keep an extra reference for the message in the raw message list - pMsg->AddRef(); - - // Assume it's a raw message, add it to the raw list - m_pRawMessages.push(pMsg); - } - } - - // Release message data - pMsg->Release(); - - // Get next message from the network - pMsg = m_pConnection->ReceiveMsg(); - } - - // ACK was updated - if ((newLastExecutedCommand != m_lastExecutedCommand) || - (newLastReceivedCommand != m_lastReceivedCommand)) - { - m_lastExecutedCommand = newLastExecutedCommand; - m_lastReceivedCommand = newLastReceivedCommand; - - // Drop commands that were ACKed as received (server has them and they will be executed soon) - { - CryAutoLock lock(m_commandAccessMutex); - - // we use this to count how many elements we need to remove later from the command vector - uint32 numCommandsToDelete = 0; - - for (TCommands::const_iterator it = m_pCommands.begin(); - it != m_pCommands.end(); ++it) - { - CommandRef* cmdRef = *it; - - // Command is still needed because it was not yet received by the remote part - if (cmdRef->m_pCommand->GetCommandId() > newLastReceivedCommand) - { - break; - } - - // Drop the command data - cmdRef->m_pCommand->Release(); - delete cmdRef; - - ++numCommandsToDelete; - } - - // Erase the command slots in the vector (in one batch) - if (numCommandsToDelete > 0) - { - m_pCommands.erase(m_pCommands.begin(), m_pCommands.begin() + numCommandsToDelete); - } - } - } - - // (Re)Send the commands - { - // Calculate the maximum command ID we can send, this depends on - // the last command that was ACKed as executed on the remote side. - // This effectively throttles the communication and prevents the - // situation when remote side is flooded with unprocessed commands. - // NOTE: the time when command is executed is different to the - // time that command is received. Sometimes if the server is suppressed (level loading) - // it can take a long time before commands begin to execute. - const uint32 maxCommandIdToSend = m_lastExecutedCommand + kCommandSendLead; - - // Calculate the cutoff time for sending (all commands that were not send before this time will be sent again) - // This assumes that the last sent time for new commands is 0 (so they will always got sent the first time) - // This situation can only happen due to the network failure since RemoteCommand layer does not require the commands to be resent. - const uint64 currentTime = gEnv->pTimer->GetAsyncTime().GetMilliSecondsAsInt64(); - const uint64 cutoffTime = currentTime - kCommandResendTime; - - std::vector< CommandRef* > commandsInPacket; // temp array - - // Process until we send all that there is to send - for (;; ) - { - // When sending connections try to merge them in larger packets. - // NOTE: this should not impact delivery time since we are not waiting - // for pending commands to accumulate before sending them, it's just an optimization - // to prevent may small messages from being sent. - uint32 packetDataSizeSoFar = 0; - { - CryAutoLock lock(m_commandAccessMutex); - - // fast local clear - // TODO: do we have a good template alternative to temporary array on stack? - packetDataSizeSoFar = 0; - commandsInPacket.resize(0); - - for (TCommands::iterator it = m_pCommands.begin(); - it != m_pCommands.end(); ++it) - { - CommandRef* commandRef = *it; - - // this command is to new, don't send it - if (commandRef->m_pCommand->GetCommandId() >= maxCommandIdToSend) - { - break; - } - - // should we send this command ? - if (commandRef->m_lastSentTime < cutoffTime) - { - // will it fit into current packet ? - const uint32 commandDataSize = commandRef->m_pCommand->GetMessage()->GetSize(); - if (packetDataSizeSoFar == 0 || // always add at least one command to the packet (no splitting) - (packetDataSizeSoFar + commandDataSize < kCommandMaxMergePacketSize)) - { - if (commandRef->m_lastSentTime == 0) - { - LOG_VERBOSE(3, "Command ID=%d is sent FIRST TIME to '%s'", - commandRef->m_pCommand->GetCommandId(), - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - else - { - LOG_VERBOSE(3, "Command ID=%d is resent to '%s'", - commandRef->m_pCommand->GetCommandId(), - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - - // will be sent - commandsInPacket.push_back(commandRef); - packetDataSizeSoFar += commandDataSize; - } - else - { - LOG_VERBOSE(3, "Command ID=%d is to big (%d) to fit packet size limit (%d)", - commandRef->m_pCommand->GetCommandId(), - commandDataSize, - kCommandMaxMergePacketSize); - - // no more commands will fit current packet - break; - } - } - } - } - - // No new commands to be send - if (commandsInPacket.empty()) - { - break; - } - - // Stats - LOG_VERBOSE(3, "Sending %d commands in packet, total size=%d, maxID=%d, dest: %s", - commandsInPacket.size(), - packetDataSizeSoFar, - maxCommandIdToSend, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // Estimate the size of the network packet - const uint32 messageDataSize = packetDataSizeSoFar + PackedHeader::kSerializationSize; - - // Allocate and fill the message buffer - IServiceNetworkMessage* pSendMsg = gEnv->pServiceNetwork->AllocMessageBuffer(messageDataSize); - if (NULL != pSendMsg) - { - CDataWriteStreamToMessage writer(pSendMsg); - - // Packet header - PackedHeader header; - header.magic = PackedHeader::kMagic; - header.msgType = PackedHeader::eCommand_Command; - header.count = commandsInPacket.size(); // number commands to send in this packet - writer << header; - - // Merge data of single commands - for (size_t i = 0; i < commandsInPacket.size(); ++i) - { - const IServiceNetworkMessage* pCommandMsg = commandsInPacket[i]->m_pCommand->GetMessage(); - writer.Write(pCommandMsg->GetPointer(), pCommandMsg->GetSize()); - } - - // Schedule the packet for sending via our network connection - if (m_pConnection->SendMsg(pSendMsg)) - { - // Only after the network layer has accepted our message we can assume that the commands were sent - for (size_t i = 0; i < commandsInPacket.size(); ++i) - { - CommandRef* cmdRef = commandsInPacket[i]; - cmdRef->m_lastSentTime = currentTime; - } - - // Release temporary message memory - pSendMsg->Release(); - } - else - { - // We failed to send the message (possibly the send queue is full) - pSendMsg->Release(); - break; - } - } - else - { - // No message was created, stop sending - break; - } - } - } - - // Keep the connection alive - return true; -} - -bool CRemoteCommandClient::Connection::IsAlive() const -{ - return (NULL != m_pConnection) && (m_pConnection->IsAlive()); -} - -const ServiceNetworkAddress& CRemoteCommandClient::Connection::GetRemoteAddress() const -{ - return m_remoteAddress; -} - -void CRemoteCommandClient::Connection::Close(bool bFlushQueueBeforeClosing /*= false*/) -{ - // Close the connection - if (NULL != m_pConnection) - { - if (m_pConnection->IsAlive() && bFlushQueueBeforeClosing) - { - // We have a chance to send a graceful disconnect message, so send it - SendDisconnectMessage(); - - // Send all the messages from the send queue before closing this connection. - // This does not block current thread. - m_pConnection->FlushAndClose(IServiceNetworkConnection::kDefaultFlushTime); - } - else - { - // Just close the connection (hasher way) - m_pConnection->Close(); - } - } -} - -bool CRemoteCommandClient::Connection::SendRawMessage(IServiceNetworkMessage* pMessage) -{ - // We can send the raw messages right away - if (NULL != m_pConnection && m_pConnection->IsAlive()) - { - return m_pConnection->SendMsg(pMessage); - } - else - { - return false; - } -} - -IServiceNetworkMessage* CRemoteCommandClient::Connection::ReceiveRawMessage() -{ - return m_pRawMessages.pop(); -} - -void CRemoteCommandClient::Connection::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CRemoteCommandClient::Connection::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -//----------------------------------------------------------------------------- - -CRemoteCommandClient::CRemoteCommandClient(CRemoteCommandManager* pManager) - : m_pManager(pManager) - , m_commandId(0) - , m_bCloseThread(false) -{ - // Start processing thread (sending, etc) - m_pThread = new TRemoteClientThread(); - m_pThread->Start(*this); -} - -CRemoteCommandClient::~CRemoteCommandClient() -{ - // Stop the thread - if (NULL != m_pThread) - { - m_pThread->Cancel(); - m_pThread->Stop(); - m_pThread->WaitForThread(); - delete m_pThread; - } - - // Delete connections - for (size_t i = 0; i < m_pConnections.size(); ++i) - { - m_pConnections[i]->Release(); - } - m_pConnections.clear(); -} - -void CRemoteCommandClient::Delete() -{ - delete this; -} - -IRemoteCommandConnection* CRemoteCommandClient::ConnectToServer(const class ServiceNetworkAddress& serverAddress) -{ - CryAutoLock< CryMutex > lock(m_accessMutex); - - // Do not connect twice to the same server - for (TConnections::const_iterator it = m_pConnections.begin(); - it != m_pConnections.end(); ++it) - { - if (ServiceNetworkAddress::CompareBaseAddress((*it)->GetRemoteAddress(), serverAddress)) - { - LOG_VERBOSE(0, "Failed to connect to server '%s': already connected", - serverAddress.ToString().c_str()); - - return NULL; - } - } - - // Open a network connection - IServiceNetworkConnection* pNetConnection = gEnv->pServiceNetwork->Connect(serverAddress); - if (NULL == pNetConnection) - { - LOG_VERBOSE(0, "Failed to connect to server '%s': server is not responding", - serverAddress.ToString().c_str()); - - return NULL; - } - - // Get current command ID (only commands after this one will be sent) - const uint32 firstCommandId = m_commandId; - - // Create a wrapping class and add it to the connection list - Connection* pConnection = new Connection(GetManager(), pNetConnection, firstCommandId); - m_pConnections.push_back(pConnection); - - // Keep internal reference - pConnection->AddRef(); - - LOG_VERBOSE(0, "Connected to remote command server '%s', first command ID=%d", - serverAddress.ToString().c_str(), - firstCommandId); - - return pConnection; -} - -bool CRemoteCommandClient::Schedule(const IRemoteCommand& command) -{ - // No connections - if (m_pConnections.empty()) - { - return false; - } - - // Find ClassID for command - uint32 classId = 0; - if (!GetManager()->FindClassId(command.GetClass(), classId)) - { - LOG_VERBOSE(0, "Class '%s' not recognized. Did you call RegisterClass() ?", - command.GetClass()->GetName()); - - return false; - } - - // Alloc new command ID and compile command data - // TODO: consider moving the compilation to thread (this may be unsafe). - const uint32 commandId = CryInterlockedIncrement((volatile int*) &m_commandId); - Command* pCommand = Command::Compile(command, commandId, classId); - - // Register new command in all of the existing server connections - if (NULL != pCommand) - { - CryAutoLock lock(m_accessMutex); - - for (TConnections::const_iterator it = m_pConnections.begin(); - it != m_pConnections.end(); ++it) - { - (*it)->AddToSendQueue(pCommand); - } - - // We are done with our reference - pCommand->Release(); - } - - // Signal the thread to process data - m_threadEvent.Set(); - return true; -} - -void CRemoteCommandClient::Run() -{ - TConnections pUpdateList; - - CryThreadSetName(-1, "RemoteCommandThread"); - - while (!m_bCloseThread) - { - // copy to local list for updating - { - CryAutoLock lock(m_accessMutex); - pUpdateList = m_pConnections; - } - - // update current connection list - for (TConnections::const_iterator it = pUpdateList.begin(); - it != pUpdateList.end(); ++it) - { - if (!(*it)->Update()) - { - CryAutoLock lock(m_accessMutex); - m_pConnectionsToDelete.push_back(*it); - } - } - - // delete pending connections - { - CryAutoLock lock(m_accessMutex); - for (TConnections::iterator it = m_pConnectionsToDelete.begin(); - it != m_pConnectionsToDelete.end(); ++it) - { - // delete the object - (*it)->Release(); - (*it)->Close(true); - - // remove from connection list - TConnections::iterator jt = std::find(m_pConnections.begin(), m_pConnections.end(), *it); - if (jt != m_pConnections.end()) - { - m_pConnections.erase(jt); - } - } - - // reset the array - m_pConnectionsToDelete.clear(); - } - - // Limit the CPU usage - const uint32 maxWaitTime = 100; - m_threadEvent.Wait(maxWaitTime); - } -} - -void CRemoteCommandClient::Cancel() -{ - m_bCloseThread = true; -} - -//----------------------------------------------------------------------------- - -// Do not remove (can mess up the uber file builds) -#undef LOG_VERBOSE - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/RemoteCommandHelpers.cpp b/Code/CryEngine/CrySystem/RemoteCommandHelpers.cpp deleted file mode 100644 index 6857a9a31c..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommandHelpers.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Helper classes for remote command system - - -#include "CrySystem_precompiled.h" -#include "IServiceNetwork.h" -#include "RemoteCommandHelpers.h" - -//----------------------------------------------------------------------------- - -CDataReadStreamFormMessage::CDataReadStreamFormMessage(const IServiceNetworkMessage* message) - : m_pMessage(message) - , m_size(message->GetSize()) - , m_pData(static_cast(message->GetPointer())) - , m_offset(0) -{ - // AddRef() is not const unfortunatelly - const_cast(m_pMessage)->AddRef(); -} - -CDataReadStreamFormMessage::~CDataReadStreamFormMessage() -{ - // Release() is not const unfortunatelly - const_cast(m_pMessage)->Release(); -} - -void CDataReadStreamFormMessage::Delete() -{ - delete this; -} - -void CDataReadStreamFormMessage::Skip(const uint32 size) -{ - CRY_ASSERT(m_offset + size < m_size); - m_offset += size; -} - -void CDataReadStreamFormMessage::Read(void* pData, const uint32 size) -{ - CRY_ASSERT(m_offset + size < m_size); - const char* pReadPtr = m_pData + m_offset; - memcpy(pData, pReadPtr, size); - m_offset += size; -} - -void CDataReadStreamFormMessage::Read8(void* pData) -{ - // it does not actually matter if its uint64, int64 or double so use any - ReadType(pData); -} - -void CDataReadStreamFormMessage::Read4(void* pData) -{ - // it does not actually matter if its uint32, int32 or float so use any - ReadType(pData); -} - -void CDataReadStreamFormMessage::Read2(void* pData) -{ - // it does not actually matter if its uint16, int16 so use any - ReadType(pData); -} - -void CDataReadStreamFormMessage::Read1(void* pData) -{ - // it does not actually matter if its uint8, int8 so use any - ReadType(pData); -} - -const void* CDataReadStreamFormMessage::GetPointer() -{ - const char* pReadPtr = m_pData + m_offset; - return pReadPtr; -} - -//----------------------------------------------------------------------------- - -CDataWriteStreamToMessage::CDataWriteStreamToMessage(IServiceNetworkMessage* pMessage) - : m_pMessage(pMessage) - , m_size(pMessage->GetSize()) - , m_pData(static_cast(pMessage->GetPointer())) - , m_offset(0) -{ - m_pMessage->AddRef(); -} - -CDataWriteStreamToMessage::~CDataWriteStreamToMessage() -{ - m_pMessage->Release(); -} - -void CDataWriteStreamToMessage::Delete() -{ - delete this; -} - -const uint32 CDataWriteStreamToMessage::GetSize() const -{ - return m_size; -} - -void CDataWriteStreamToMessage::CopyToBuffer(void* pData) const -{ - memcpy(pData, m_pData, m_size); -} - -IServiceNetworkMessage* CDataWriteStreamToMessage::BuildMessage() const -{ - m_pMessage->AddRef(); - return m_pMessage; -} - -void CDataWriteStreamToMessage::Write(const void* pData, const uint32 size) -{ - CRY_ASSERT(m_offset + size < m_size); - memcpy((char*)m_pData + m_offset, pData, size); - m_offset += size; -} - -void CDataWriteStreamToMessage::Write8(const void* pData) -{ - // it does not actually matter if its uint64, int64 or double so use any - WriteType(pData); -} - -void CDataWriteStreamToMessage::Write4(const void* pData) -{ - // it does not actually matter if its uint32, int32 or float so use any - WriteType(pData); -} - -void CDataWriteStreamToMessage::Write2(const void* pData) -{ - // it does not actually matter if its uint16, int16 so use any - WriteType(pData); -} - -void CDataWriteStreamToMessage::Write1(const void* pData) -{ - // it does not actually matter if its uint8, int8 so use any - WriteType(pData); -} - -//----------------------------------------------------------------------------- - -CDataReadStreamMemoryBuffer::CDataReadStreamMemoryBuffer(const void* pData, const uint32 size) - : m_size(size) - , m_offset(0) -{ - m_pData = new uint8 [size]; - memcpy(m_pData, pData, size); -} - -CDataReadStreamMemoryBuffer::~CDataReadStreamMemoryBuffer() -{ - delete [] m_pData; - m_pData = NULL; -} - -void CDataReadStreamMemoryBuffer::Delete() -{ - delete this; -} - -void CDataReadStreamMemoryBuffer::Skip(const uint32 size) -{ - CRY_ASSERT(m_offset + size <= m_size); - m_offset += size; -} - -void CDataReadStreamMemoryBuffer::Read8(void* pData) -{ - Read(pData, 8); - SwapEndian(*reinterpret_cast(pData)); -} - -void CDataReadStreamMemoryBuffer::Read4(void* pData) -{ - Read(pData, 4); - SwapEndian(*reinterpret_cast(pData)); -} - -void CDataReadStreamMemoryBuffer::Read2(void* pData) -{ - Read(pData, 2); - SwapEndian(*reinterpret_cast(pData)); -} - -void CDataReadStreamMemoryBuffer::Read1(void* pData) -{ - return Read(pData, 1); -} - -const void* CDataReadStreamMemoryBuffer::GetPointer() -{ - return m_pData + m_offset; -}; - -void CDataReadStreamMemoryBuffer::Read(void* pData, const uint32 size) -{ - CRY_ASSERT(m_offset + size <= m_size); - memcpy(pData, m_pData + m_offset, size); - m_offset += size; -} - -//----------------------------------------------------------------------------- - -CDataWriteStreamBuffer::CDataWriteStreamBuffer() - : m_size(0) -{ - // Start with the initial (preallocated) partition - // This optimization assumes that initial size of most of the messages will be small. - // NOTE: default partition is not added to the partition table (that would require push_backs to vector) - char* partitionMemory = &m_defaultPartition[0]; - m_pCurrentPointer = partitionMemory; - m_leftInPartition = sizeof(m_defaultPartition); -} - -CDataWriteStreamBuffer::~CDataWriteStreamBuffer() -{ - // Free all memory partitions that were allocated dynamically - for (size_t i = 0; i < m_pPartitions.size(); ++i) - { - CryModuleFree(m_pPartitions[i]); - } -} - -void CDataWriteStreamBuffer::Delete() -{ - delete this; -} - -const uint32 CDataWriteStreamBuffer::GetSize() const -{ - return m_size; -} - -void CDataWriteStreamBuffer::CopyToBuffer(void* pData) const -{ - uint32 dataLeft = m_size; - char* pWritePtr = (char*)pData; - - // Copy data from default (preallocated) partition - { - const uint32 partitionSize = sizeof(m_defaultPartition); - const uint32 dataToCopy = min(partitionSize, dataLeft); - memcpy(pWritePtr, &m_defaultPartition[0], dataToCopy); - - // advance - pWritePtr += dataToCopy; - dataLeft -= dataToCopy; - } - - // Copy data from dynamic partitions - for (uint32 i = 0; i < m_pPartitions.size(); ++i) - { - // get size of data to copy - const uint32 partitionSize = m_partitionSizes[i]; - const uint32 dataToCopy = min(partitionSize, dataLeft); - memcpy(pWritePtr, m_pPartitions[i], dataToCopy); - - // advance - pWritePtr += dataToCopy; - dataLeft -= dataToCopy; - } - - // Make sure all data was written - CRY_ASSERT(dataLeft == 0); -} - -IServiceNetworkMessage* CDataWriteStreamBuffer::BuildMessage() const -{ - // No data written, no message created - if (0 == m_size) - { - return NULL; - } - - // Create message to hold all the data - IServiceNetworkMessage* pMessage = gEnv->pServiceNetwork->AllocMessageBuffer(m_size); - if (NULL == pMessage) - { - return NULL; - } - - // Copy data to messages - CopyToBuffer(pMessage->GetPointer()); - return pMessage; -} - -void CDataWriteStreamBuffer::Write(const void* pData, const uint32 size) -{ - static const uint32 kAdditionalPartitionSize = 65536; - - uint32 dataLeft = size; - while (dataLeft > 0) - { - // new partition needed - if (m_leftInPartition == 0) - { - // Allocate new partition data - char* partitionMemory = (char*)CryModuleMalloc(kAdditionalPartitionSize); - CRY_ASSERT(partitionMemory != NULL); - - // add new partition to list - m_partitionSizes.push_back(kAdditionalPartitionSize); - m_pPartitions.push_back(partitionMemory); - m_pCurrentPointer = partitionMemory; - m_leftInPartition = kAdditionalPartitionSize; - } - - // how many bytes can we write to current partition ? - const uint32 maxToWrite = min(m_leftInPartition, dataLeft); - memcpy(m_pCurrentPointer, pData, maxToWrite); - - // advance - m_size += maxToWrite; - dataLeft -= maxToWrite; - pData = (const char*)pData + maxToWrite; - m_pCurrentPointer += maxToWrite; - m_leftInPartition -= maxToWrite; - } -} - -void CDataWriteStreamBuffer::Write8(const void* pData) -{ - // it does not actually matter if its uint64, int64 or double so use any - WriteType(pData); -} - -void CDataWriteStreamBuffer::Write4(const void* pData) -{ - // it does not actually matter if its uint32, int32 or float so use any - WriteType(pData); -} - -void CDataWriteStreamBuffer::Write2(const void* pData) -{ - // it does not actually matter if its uint16, int16 so use any - WriteType(pData); -} - -void CDataWriteStreamBuffer::Write1(const void* pData) -{ - // it does not actually matter if its uint8, int8 so use any - WriteType(pData); -} - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/RemoteCommandHelpers.h b/Code/CryEngine/CrySystem/RemoteCommandHelpers.h deleted file mode 100644 index 948097db22..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommandHelpers.h +++ /dev/null @@ -1,307 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system helper classes - - -#ifndef CRYINCLUDE_CRYSYSTEM_REMOTECOMMANDHELPERS_H -#define CRYINCLUDE_CRYSYSTEM_REMOTECOMMANDHELPERS_H -#pragma once - - -//------------------------------------------------------------------------ - -#include "IRemoteCommand.h" - -struct IServiceNetworkMessage; - -//------------------------------------------------------------------------ - -// Stream reader for service network message -// Implements automatic byte swapping -class CDataReadStreamFormMessage - : public IDataReadStream -{ -private: - const IServiceNetworkMessage* m_pMessage; - const char* m_pData; - uint32 m_offset; - uint32 m_size; - -private: - template - ILINE void ReadType(void* pData) - { - CRY_ASSERT(m_offset + sizeof(T) < m_size); - const T& readPos = *reinterpret_cast(m_pData + m_offset); - *reinterpret_cast(pData) = readPos; - SwapEndian(*reinterpret_cast(pData)); - m_offset += sizeof(T); - } - -public: - CDataReadStreamFormMessage(const IServiceNetworkMessage* message); - virtual ~CDataReadStreamFormMessage(); - - const uint32 GetOffset() const - { - return m_offset; - } - - void SetPosition(uint32 offset) - { - m_offset = offset; - } - -public: - // IDataReadStream interface - virtual void Delete(); - virtual void Skip(const uint32 size); - virtual void Read(void* pData, const uint32 size); - virtual void Read8(void* pData); - virtual void Read4(void* pData); - virtual void Read2(void* pData); - virtual void Read1(void* pData); - virtual const void* GetPointer(); -}; - -//------------------------------------------------------------------------ - -// Stream writer that writes into the service network message -class CDataWriteStreamToMessage - : public IDataWriteStream -{ -private: - IServiceNetworkMessage* m_pMessage; - char* m_pData; - uint32 m_offset; - uint32 m_size; - -private: - template - ILINE void WriteType(const void* pData) - { - CRY_ASSERT(m_offset + sizeof(T) < m_size); - T& writePos = *reinterpret_cast(m_pData + m_offset); - writePos = *reinterpret_cast(pData); - SwapEndian(writePos); - m_offset += sizeof(T); - } - -public: - CDataWriteStreamToMessage(IServiceNetworkMessage* pMessage); - virtual ~CDataWriteStreamToMessage(); - - // IDataWriteStream interface implementation - virtual void Delete(); - virtual const uint32 GetSize() const; - virtual struct IServiceNetworkMessage* BuildMessage() const; - virtual void CopyToBuffer(void* pData) const; - virtual void Write(const void* pData, const uint32 size); - virtual void Write8(const void* pData); - virtual void Write4(const void* pData); - virtual void Write2(const void* pData); - virtual void Write1(const void* pData); -}; - -//------------------------------------------------------------------------ - -/// Stream reader reading from owner memory buffer -class CDataReadStreamMemoryBuffer - : public IDataReadStream -{ -private: - const uint32 m_size; - uint8* m_pData; - uint32 m_offset; - -public: - // memory is copied! - CDataReadStreamMemoryBuffer(const void* pData, const uint32 size); - virtual ~CDataReadStreamMemoryBuffer(); - - virtual void Delete(); - virtual void Skip(const uint32 size); - virtual void Read8(void* pData); - virtual void Read4(void* pData); - virtual void Read2(void* pData); - virtual void Read1(void* pData); - virtual const void* GetPointer(); - virtual void Read(void* pData, const uint32 size); -}; - -//------------------------------------------------------------------------ - -// Stream writer that writes into the internal memory buffer -class CDataWriteStreamBuffer - : public IDataWriteStream -{ - static const uint32 kStaticPartitionSize = 4096; - -private: - // Default (preallocated) partition - char m_defaultPartition[ kStaticPartitionSize ]; - - // Allocated dynamic partitions - std::vector m_pPartitions; - - // Size of the dynamic message partitions - std::vector m_partitionSizes; - - // Pointer to current writing position in the current partition - char* m_pCurrentPointer; - - // Space left in current partition - uint32 m_leftInPartition; - - // Total message size so far - uint32 m_size; - -private: - // Directly write typed data into the stream - template - ILINE void WriteType(const void* pData) - { - // try to use the faster path if we are not crossing the partition boundary - if (m_leftInPartition >= sizeof(T)) - { - // faster case - T& writePos = *reinterpret_cast(m_pCurrentPointer); - writePos = *reinterpret_cast(pData); - SwapEndian(writePos); - m_pCurrentPointer += sizeof(T); - m_leftInPartition -= sizeof(T); - m_size += sizeof(T); - } - else - { - // slower case (more generic) - T tempVal(*reinterpret_cast(pData)); - SwapEndian(tempVal); - Write(&tempVal, sizeof(tempVal)); - } - } - -public: - CDataWriteStreamBuffer(); - virtual ~CDataWriteStreamBuffer(); - - // IDataWriteStream interface implementation - virtual void Delete(); - virtual const uint32 GetSize() const; - virtual IServiceNetworkMessage* BuildMessage() const; - virtual void CopyToBuffer(void* pData) const; - virtual void Write(const void* pData, const uint32 size); - virtual void Write8(const void* pData); - virtual void Write4(const void* pData); - virtual void Write2(const void* pData); - virtual void Write1(const void* pData); -}; - -//----------------------------------------------------------------------------- - -// Packet header -struct PackedHeader -{ - // Estimation (or better yet, exact value) of how much data this header will take when written. - // Please make sure that actual size after serialization is not bigger than this value. - static const uint32 kSerializationSize = sizeof(uint8) + sizeof(uint32) + sizeof(uint32); - - // Magic value that identifies command messages vs raw messages - static const uint32 kMagic = 0xABBAF00D; - - // Command type - // Keep the values unchanged as this may break the protocol - enum ECommand - { - // Server class list mapping - eCommand_ClassList = 0, - - // Command data - eCommand_Command = 1, - - // Disconnect signal - eCommand_Disconnect = 2, - - // ACK packet - eCommand_ACK = 3, - }; - - uint32 magic; - uint8 msgType; - uint32 count; - - // serialization operator - template< class T > - friend T& operator<<(T& stream, PackedHeader& header) - { - stream << header.magic; - stream << header.msgType; - stream << header.count; - return stream; - } -}; - -// Header sent with every command -struct CommandHeader -{ - uint32 commandId; - uint32 classId; - uint32 size; - - CommandHeader() - : commandId(0) - , classId(0) - , size(0) - {} - - // serialization operator - template< class T > - friend T& operator<<(T& stream, CommandHeader& header) - { - stream << header.commandId; - stream << header.classId; - stream << header.size; - return stream; - } -}; - -// General Response/ACK header -struct ResponseHeader -{ - uint32 magic; - uint8 msgType; - uint32 lastCommandReceived; - uint32 lastCommandExecuted; - - ResponseHeader() - : lastCommandReceived(0) - , lastCommandExecuted(0) - , msgType(PackedHeader::eCommand_ACK) - {} - - // serialization operator - template< class T > - friend T& operator<<(T& stream, ResponseHeader& header) - { - stream << header.magic; - stream << header.msgType; - stream << header.lastCommandReceived; - stream << header.lastCommandExecuted; - return stream; - } -}; - -//----------------------------------------------------------------------------- - -#endif // CRYINCLUDE_CRYSYSTEM_REMOTECOMMANDHELPERS_H diff --git a/Code/CryEngine/CrySystem/RemoteCommandServer.cpp b/Code/CryEngine/CrySystem/RemoteCommandServer.cpp deleted file mode 100644 index 362a9faf1a..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommandServer.cpp +++ /dev/null @@ -1,832 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system implementation (server) - -#include "CrySystem_precompiled.h" -#include "IServiceNetwork.h" -#include "RemoteCommand.h" -#include "RemoteCommandHelpers.h" - -//----------------------------------------------------------------------------- - -// remote system internal logging -#ifdef RELEASE -#define LOG_VERBOSE(level, txt, ...) -#else -#define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); } -#endif - -//----------------------------------------------------------------------------- - -CRemoteCommandServer::WrappedCommand::WrappedCommand(IRemoteCommand* pCommand, const uint32 commandId) - : m_pCommand(pCommand) - , m_refCount(1) - , m_commandID(commandId) -{ -} - -CRemoteCommandServer::WrappedCommand::~WrappedCommand() -{ - CRY_ASSERT(m_refCount == 0); - m_pCommand->Delete(); -} - -void CRemoteCommandServer::WrappedCommand::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CRemoteCommandServer::WrappedCommand::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -//----------------------------------------------------------------------------- - -CRemoteCommandServer::Endpoint::Endpoint(CRemoteCommandManager* pManager, class CRemoteCommandServer* pServer, IServiceNetworkConnection* pConnection) - : m_pConnection(pConnection) - , m_pManager(pManager) - , m_pServer(pServer) - , m_lastReceivedCommand(0) - , m_lastExecutedCommand(0) - , m_lastReceivedCommandACKed(0) - , m_lastExecutedCommandACKed(0) - , m_bHasReceivedClassList(false) -{ -} - -CRemoteCommandServer::Endpoint::~Endpoint() -{ - // release commands that were not yet executed - // this will release the command memory buffers (if they are not referenced elsewhere) - while (!m_pCommandsToExecute.empty()) - { - WrappedCommand* pCommand = m_pCommandsToExecute.pop(); - pCommand->Release(); - } - - // make sure the network connection is closed - if (NULL != m_pConnection) - { - // send the disconnect message - { - CDataWriteStreamBuffer writer; - - // format messages - PackedHeader header; - header.magic = PackedHeader::kMagic; - header.msgType = PackedHeader::eCommand_Disconnect; - header.count = 0; - writer << header; - - // Send the message - IServiceNetworkMessage* pMessage = writer.BuildMessage(); - if (NULL != pMessage) - { - m_pConnection->SendMsg(pMessage); - pMessage->Release(); - } - } - - // close the connection (but try to send messages out) - m_pConnection->FlushAndClose(IServiceNetworkConnection::kDefaultFlushTime); - m_pConnection->Release(); - m_pConnection = NULL; - } -} - -const char* CRemoteCommandServer::Endpoint::GetClassName(const uint32 classId) const -{ - // class index is out of bounds - if (classId >= m_pLocalClassFactories.size()) - { - return "InvalidClassID"; - } - - // get class factory for the class ID - IRemoteCommandClass* theClass = m_pLocalClassFactories[ classId ]; - if (NULL == theClass) - { - // ID is valid but we do not support this class - // Can happen, usually due to version mismatch between client and server binaries - return "UnsupportedClassID"; - } - - return theClass->GetName(); -} - -IRemoteCommand* CRemoteCommandServer::Endpoint::CreateObject(const uint32 classId) const -{ - // class index is out of bounds - if (classId >= m_pLocalClassFactories.size()) - { - return NULL; - } - - // get class factory for given class index - IRemoteCommandClass* theClass = m_pLocalClassFactories[ classId ]; - if (NULL == theClass) - { - // ID is valid but we do not support this class - // Can happen, usually due to version mismatch between client and server binaries - return NULL; - } - - // use the class definition to create the instance of the remote command object - return theClass->CreateObject(); -} - -void CRemoteCommandServer::Endpoint::Execute() -{ - uint32 idOfLastExecutedCommand = 0; - - // Process the commands on the execution list - while (!m_pCommandsToExecute.empty()) - { - // Pop the command from the stack - WrappedCommand* pCommand = m_pCommandsToExecute.pop(); - - LOG_VERBOSE(3, "Executing command '%s', ID %d", - pCommand->GetCommand()->GetClass()->GetName(), - pCommand->GetId()); - - // Here is where the magic happens - { - pCommand->GetCommand()->Execute(); - } - - // Keep track of the command ID executed so far (so we can update the ACK later) - CRY_ASSERT(pCommand->GetId() > idOfLastExecutedCommand); - idOfLastExecutedCommand = pCommand->GetId(); - - // Command was executed, we can release it - pCommand->Release(); - } - - // Update the ACK data (if it's needed) - if (idOfLastExecutedCommand != 0) - { - CryAutoLock lock(m_accessLock); - - LOG_VERBOSE(3, "Updating LastExecutedCommandID %d->%d", - m_lastExecutedCommand, - idOfLastExecutedCommand); - - // Well, it only makes sens if the current command ID is greater that the last one executed - CRY_ASSERT(idOfLastExecutedCommand > m_lastExecutedCommand); - if (idOfLastExecutedCommand > m_lastExecutedCommand) - { - m_lastExecutedCommand = idOfLastExecutedCommand; - } - } -} - -bool CRemoteCommandServer::Endpoint::Update() -{ - // Check connection status - if (!m_pConnection->IsAlive()) - { - // Signal the owner that this endpoint should be deleted - return false; - } - - // Receive and deserialize the commands - // Note that this is done asynchronously so commands can be decoded even if the main thread is busy - // Note that execution is DEFERRED to the main thread (I wouldn't risk doing it from this thread ;-)) - bool bDisconnectReceived = false; - IServiceNetworkMessage* pMsg = m_pConnection->ReceiveMsg(); - while (NULL != pMsg && !bDisconnectReceived) - { - CDataReadStreamFormMessage reader(pMsg); - - // read back the packet header - PackedHeader packetHeader; - reader << packetHeader; - - // Is this a command system messages ? - if (packetHeader.magic == PackedHeader::kMagic) - { - switch (packetHeader.msgType) - { - // Class list, usually sent as first thing after connection - case PackedHeader::eCommand_ClassList: - { - // deserialize class names - std::vector< string > classNames; - reader << classNames; - - // sync the command ID to the current value on the client - const uint32 firstCommandID = packetHeader.count; - m_lastExecutedCommand = firstCommandID; - m_lastExecutedCommandACKed = firstCommandID; - m_lastReceivedCommand = firstCommandID; - m_lastReceivedCommandACKed = firstCommandID; - m_bHasReceivedClassList = true; - - LOG_VERBOSE(3, "Received class list packet, count=%d, first message=%d from '%s'", - classNames.size(), - packetHeader.count, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // create class mapping between remote client and this server - GetManager()->BuildClassMapping(classNames, m_pLocalClassFactories); - break; - } - - // Actual command packets - case PackedHeader::eCommand_Command: - { - LOG_VERBOSE(3, "Received packet, count=%d from '%s'", - packetHeader.count, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // load the serialized commands - const uint32 numCommands = packetHeader.count; - for (uint32 i = 0; i < numCommands; ++i) - { - // Each command is prefixed with header - CommandHeader header; - reader << header; - - // We must be able to skip to the end of the command data because sometimes - // some data can be omitted - either by dropping the command altogether or - // by faulty deserialization. Don't trust the user. - const uint32 offset = reader.GetOffset(); - const uint32 endOffset = offset + header.size; // here is where we can skip - - LOG_VERBOSE(3, "Received command ID=%d (class id=%d, size=%d) from '%s'", - header.commandId, - header.classId, - header.size, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // Do not process commands out of order. - // This should not happen if network is in good health, but we cannot assume that, never-ever. - // This code will cause our side to stop executing new commands until the remote side to resend the missing ones. - // Typically it is better than executing commands out of order. - const uint32 expectedNextCommand = m_lastReceivedCommand + 1; - if (header.commandId > expectedNextCommand) - { - LOG_VERBOSE(0, "Out of order command ID (%d > %d) received from '%s'", - header.commandId, - expectedNextCommand, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // next commands will be even older, no need to check them - break; - } - - // Do not process the old commands - // This may happen pretty often when command is resent while the ACK is "in-flight" - // Just drop the data and go on. - if (header.commandId <= m_lastReceivedCommand) - { - // getting old command is not an error, it just means that we have large enough lag - // that the client started resending old commands. - LOG_VERBOSE(1, "Old command (%d <= %d) received from '%s'", - header.commandId, - m_lastReceivedCommand, - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - else - { - // next command received, we are very strict about matchig the command IDs here - CRY_ASSERT(header.commandId == expectedNextCommand); - m_lastReceivedCommand = expectedNextCommand; - - // create the command - IRemoteCommand* pCommand = CreateObject(header.classId); - if (NULL != pCommand) - { - // Fine-grain logging - LOG_VERBOSE(3, "Received command '%s', classId=%d, commandId=%d from '%s'", - pCommand->GetClass()->GetName(), - header.classId, - header.commandId, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // Deserialize the command data from network message - pCommand->LoadFromStream(reader); - - // Add to list of commands to execute - { - m_pCommandsToExecute.push(new WrappedCommand(pCommand, header.commandId)); - } - } - else - { - LOG_VERBOSE(0, "ClassId %d not recognized. Skipping command ID%d from '%s'", - header.classId, - header.commandId, - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - - // Update the last command ID - m_lastReceivedCommand = header.commandId; - } - - // Sync the message stream to popper position - CRY_ASSERT(reader.GetOffset() <= endOffset); - reader.SetPosition(endOffset); - } - - break; - } - - // request to disconnect (graceful) - case PackedHeader::eCommand_Disconnect: - { - LOG_VERBOSE(3, "Received disconnect request from '%s'", - m_pConnection->GetRemoteAddress().ToString().c_str()); - - m_pConnection->Close(); - bDisconnectReceived = true; - - break; - } - - // should not happen - default: - { - LOG_VERBOSE(0, "Invalid message type '%s' received from '%s'", - packetHeader.msgType, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - break; - } - } - } - else - { - // This is a raw message, try to process immediately using async listeners. - // If it fails, add to the queue for processing on the main thread by sync listeners. - m_pServer->ProcessRawMessageAsync(pMsg, m_pConnection); - } - - // Release the message data - pMsg->Release(); - - // Get the next message from network - if (!bDisconnectReceived) - { - pMsg = m_pConnection->ReceiveMsg(); - } - } - - // The value of lastExecutedCommand can change outside this thread, - // so capture it one and keep it constant for the duration of the logic in this function. - const uint32 snapshotLastExecutedCommand = m_lastExecutedCommand; - - // Determine if we should send generate the ACK signal - if ((snapshotLastExecutedCommand != m_lastExecutedCommandACKed) || - (m_lastReceivedCommand != m_lastReceivedCommandACKed)) // this can - { - ResponseHeader header; - header.magic = PackedHeader::kMagic; - header.msgType = PackedHeader::eCommand_ACK; - header.lastCommandReceived = m_lastReceivedCommand; - header.lastCommandExecuted = snapshotLastExecutedCommand; // note that we use the captured values - - LOG_VERBOSE(3, "Sending ACK to '%s' with LastReceived=%d, LastExecuted=%d", - m_pConnection->GetRemoteAddress().ToString().c_str(), - header.lastCommandReceived, - header.lastCommandExecuted); - - // Write header into the message - CDataWriteStreamBuffer writer; - writer << header; - - // Extract the message - IServiceNetworkMessage* pMessage = writer.BuildMessage(); - if (NULL != pMessage) - { - // Send it back over the connection (works as ACK) - if (m_pConnection->SendMsg(pMessage)) - { - // Only after the message is accepted by the network we can assume that we have ACKed it properly - // This can still leave a possibility that this message gets eaten in the network but we will resend newer ACK - // soon enough that we don't need to bother with this. - m_lastExecutedCommandACKed = header.lastCommandExecuted; - m_lastReceivedCommandACKed = header.lastCommandReceived; - } - - pMessage->Release(); - } - } - - // Continue - return true; -} - -//----------------------------------------------------------------------------- - -CRemoteCommandServer::CRemoteCommandServer(CRemoteCommandManager* pManager, IServiceNetworkListener* pListener) - : m_pManager(pManager) - , m_pListener(pListener) - , m_bCloseThread(false) - , m_suppressionCounter(0) - , m_bIsSuppressed(false) -{ - // Start processing thread (receiving from network, deserialization, etc) - m_pThread = new TRemoteServerThread(); - m_pThread->Start(*this); -} - -CRemoteCommandServer::~CRemoteCommandServer() -{ - // Stop the thread, assumes that thread is responsive - if (NULL != m_pThread) - { - m_pThread->Cancel(); - m_pThread->Stop(); - m_pThread->WaitForThread(); - delete m_pThread; - } - - // Cleanup the clients endpoints - for (TEndpoints::const_iterator it = m_pEndpoints.begin(); - it != m_pEndpoints.end(); ++it) - { - delete (*it); - } - m_pEndpoints.clear(); - - // Cleanup the clients that were not yet deleted but are dead - for (TEndpoints::const_iterator it = m_pEndpointToDelete.begin(); - it != m_pEndpointToDelete.end(); ++it) - { - delete (*it); - } - m_pEndpointToDelete.clear(); - - // Cleanup the raw messages - while (!m_pRawMessages.empty()) - { - delete m_pRawMessages.pop(); - } - - // Properly close the listening socket - if (m_pListener != NULL) - { - m_pListener->Close(); - m_pListener->Release(); - m_pListener = NULL; - } -} - -void CRemoteCommandServer::ProcessRawMessageAsync(IServiceNetworkMessage* pMessage, IServiceNetworkConnection* pConnection) -{ - // we lock for the whole duration of the function - I think that's the safest. - // this function is being called from remote command server thread and even if it locks for a moment that's not a tragic situation. - CryAutoLock lock(m_rawMessagesLock); - - // Process the message using async listeners - bool bWasProcessed = false; - for (TRawMessageListenersAsync::const_iterator it = m_pRawListenersAsync.begin(); - it != m_pRawListenersAsync.end(); ++it) - { - CDataReadStreamFormMessage reader(pMessage); - CDataWriteStreamBuffer writer; - - // Request the listener to process this message - if ((*it)->OnRawMessageAsync(pConnection->GetRemoteAddress(), reader, writer)) - { - // Send response back using the source connection - if (writer.GetSize() > 0) - { - IServiceNetworkMessage* pNewMessage = writer.BuildMessage(); - if (NULL != pNewMessage) - { - pConnection->SendMsg(pNewMessage); - pNewMessage->Release(); - } - } - - // mark as processed - bWasProcessed = true; - break; - } - } - - // Stats - if (bWasProcessed) - { - LOG_VERBOSE(3, "Raw message from '%s', size %d ASYNC, PROCESSED", - pConnection->GetRemoteAddress().ToString().c_str(), - pMessage->GetSize()); - } - else - { - LOG_VERBOSE(3, "Raw message from '%s', size %d ASYNC, NOT PROCESSED", - pConnection->GetRemoteAddress().ToString().c_str(), - pMessage->GetSize()); - } - - // If we have sync listeners add the raw message for processing on the main thread - if (!bWasProcessed && !m_pRawListenersSync.empty()) - { - m_pRawMessages.push(new RawMessage(pConnection, pMessage)); - } -} - -void CRemoteCommandServer::ProcessRawMessagesSync() -{ - // get messages - TRawMessageListenersSync listeners; - { - CryAutoLock lock(m_rawMessagesLock); - listeners = m_pRawListenersSync; - } - - // process each message - while (!m_pRawMessages.empty()) - { - RawMessage* pMsg = m_pRawMessages.pop(); - - // Process messages only from alive connection (they could die before we got a chance to process the message) - if (pMsg && pMsg->m_pConnection->IsAlive()) - { - // Try to process by on of the listeners - bool bWasProcessed = false; - for (TRawMessageListenersSync::const_iterator jt = listeners.begin(); - jt != listeners.end(); ++jt) - { - CDataReadStreamFormMessage reader(pMsg->m_pMessage); - CDataWriteStreamBuffer writer; - - // Request the listener to process this message - if ((*jt)->OnRawMessageSync(pMsg->m_pConnection->GetRemoteAddress(), reader, writer)) - { - // Send response back using the source connection - if (writer.GetSize() > 0) - { - IServiceNetworkMessage* pMessage = writer.BuildMessage(); - if (NULL != pMessage) - { - pMsg->m_pConnection->SendMsg(pMessage); - pMessage->Release(); - } - } - - // mark as processed - bWasProcessed = true; - break; - } - } - - // Stats - if (bWasProcessed) - { - LOG_VERBOSE(3, "Raw message from '%s', size %d SYNC PROCESSED", - pMsg->m_pConnection->GetRemoteAddress().ToString().c_str(), - pMsg->m_pMessage->GetSize()); - } - else - { - LOG_VERBOSE(3, "Raw message from '%s', size %d SYNC NOT PROCESSED", - pMsg->m_pConnection->GetRemoteAddress().ToString().c_str(), - pMsg->m_pMessage->GetSize()); - } - } - - /// Cleanup - delete pMsg; - } -} - -void CRemoteCommandServer::Delete() -{ - delete this; -} - -void CRemoteCommandServer::FlushCommandQueue() -{ - // Always process raw messages, even if commands are suspended - ProcessRawMessagesSync(); - - // When the command server is suppressed externally, well, then don't execute any commands - // This is usually used when the main thread is doing some heavy stuff. - // TODO: Consider signaling the clients about this condition. - if (m_bIsSuppressed) - { - LOG_VERBOSE(4, "FlushCommandQueue: suppressed (counter=%d)", - m_suppressionCounter); - - return; - } - - // Update the endpoints from a copy of the list - { - CryAutoLock lock(m_accessLock); - m_pUpdateEndpoints = m_pEndpoints; - } - - // Execute the commands for each endpoint - for (TEndpoints::const_iterator it = m_pUpdateEndpoints.begin(); - it != m_pUpdateEndpoints.end(); ++it) - { - (*it)->Execute(); - } - - // Delete endpoints that were discarded within the thread (due to network errors) - // We couldn't do that there because we would need to lock to much inside the mutex (bad idea) - if (!m_pEndpointToDelete.empty()) - { - // TODO: consider using different CS for pDeletedEnpoints array - CryAutoLock lock(m_accessLock); - - // delete the endpoint structured (deferred) - for (size_t i = 0; i < m_pEndpointToDelete.size(); ++i) - { - delete m_pEndpointToDelete[i]; - } - - m_pEndpointToDelete.clear(); - } -} - -void CRemoteCommandServer::SuppressCommands() -{ - if (CryInterlockedIncrement(&m_suppressionCounter) > 0) - { - m_bIsSuppressed = true; - } -} - -void CRemoteCommandServer::ResumeCommands() -{ - if (CryInterlockedDecrement(&m_suppressionCounter) == 0) - { - m_bIsSuppressed = false; - } -} - -void CRemoteCommandServer::Run() -{ - TEndpoints updateList; - - CryThreadSetName(-1, "RemoteCommandThread"); - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(RemoteCommandServer_cpp) -#endif - - while (!m_bCloseThread) - { - // Accept new connections - { - IServiceNetworkConnection* pNewConnection = m_pListener->Accept(); - if (NULL != pNewConnection) - { - LOG_VERBOSE(2, "New endpoint created with connection '%s'", - pNewConnection->GetRemoteAddress().ToString().c_str()); - - // Create endpoint wrapper - Endpoint* pEndPoint = new Endpoint(GetManager(), this, pNewConnection); - - // Add to endpoint list - { - CryAutoLock lock(m_accessLock); - m_pEndpoints.push_back(pEndPoint); - } - } - } - - // Get the current endpoint table (for update) - { - CryAutoLock lock(m_accessLock); - updateList = m_pEndpoints; - } - - // Update endpoints - for (TEndpoints::iterator it = updateList.begin(); - it != updateList.end(); ++it) - { - Endpoint* ep = (*it); - if (!ep->Update()) - { - LOG_VERBOSE(2, "RemoteCommand endpoint '%s' closed", - ep->GetConnection()->GetRemoteAddress().ToString().c_str()); - - // remove the endpoint from the original list - { - CryAutoLock lock(m_accessLock); - - // it's safe to remove from the endpoints list - we are iterating over a copy - m_pEndpoints.erase(std::find(m_pEndpoints.begin(), m_pEndpoints.end(), ep)); - - // don't delete the endpoint structure now (it may still be executed on main thread) - // instead add it to a list that will be processed at the end of execution so this endpoint can get deleted - m_pEndpointToDelete.push_back(ep); - } - } - } - - // Limit the CPU usage - // TODO: consider using some event based mechanism since the only source of - // work for this thread is the network we can esily be triggered by that. - Sleep(5); - } -} - -void CRemoteCommandServer::Cancel() -{ - m_bCloseThread = true; -} - -void CRemoteCommandServer::RegisterSyncMessageListener(IRemoteCommandListenerSync* pListener) -{ - CryAutoLock lock(m_rawMessagesLock); - m_pRawListenersSync.push_back(pListener); -} - -void CRemoteCommandServer::UnregisterSyncMessageListener(IRemoteCommandListenerSync* pListener) -{ - CryAutoLock lock(m_rawMessagesLock); - - TRawMessageListenersSync::iterator it = std::find(m_pRawListenersSync.begin(), m_pRawListenersSync.end(), pListener); - if (it != m_pRawListenersSync.end()) - { - m_pRawListenersSync.erase(it); - } -} - -void CRemoteCommandServer::RegisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) -{ - CryAutoLock lock(m_rawMessagesLock); - m_pRawListenersAsync.push_back(pListener); -} - -void CRemoteCommandServer::UnregisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) -{ - CryAutoLock lock(m_rawMessagesLock); - - TRawMessageListenersAsync::iterator it = std::find(m_pRawListenersAsync.begin(), m_pRawListenersAsync.end(), pListener); - if (it != m_pRawListenersAsync.end()) - { - m_pRawListenersAsync.erase(it); - } -} - -void CRemoteCommandServer::Broadcast(IServiceNetworkMessage* pMessage) -{ - if (NULL != pMessage && pMessage->GetSize() > 0) - { - CryAutoLock lock(m_rawMessagesLock); - for (TEndpoints::const_iterator jt = m_pEndpoints.begin(); - jt != m_pEndpoints.end(); ++jt) - { - Endpoint* pEndpoint = (*jt); - if (pEndpoint->HasReceivedClassList()) - { - IServiceNetworkConnection* pConnection = pEndpoint->GetConnection(); - if (NULL != pConnection) - { - pConnection->SendMsg(pMessage); - } - } - } - } -} - -bool CRemoteCommandServer::HasConnectedClients() const -{ - CryAutoLock lock(m_rawMessagesLock); - - for (TEndpoints::const_iterator jt = m_pEndpoints.begin(); - jt != m_pEndpoints.end(); ++jt) - { - Endpoint* pEndpoint = (*jt); - if (pEndpoint->HasReceivedClassList()) - { - IServiceNetworkConnection* pConnection = pEndpoint->GetConnection(); - if (pConnection->IsAlive()) - { - return true; - } - } - } - - return false; -} - -//----------------------------------------------------------------------------- - -// Do not remove (can mess up the uber file builds) -#undef LOG_VERBOSE - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/Serialization/ArchiveHost.cpp b/Code/CryEngine/CrySystem/Serialization/ArchiveHost.cpp deleted file mode 100644 index f7ed4ae46c..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/ArchiveHost.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include "JSONIArchive.h" -#include "JSONOArchive.h" -#include "BinArchive.h" -#include "XmlIArchive.h" -#include "XmlOArchive.h" -#include - -namespace Serialization -{ - bool LoadFile(std::vector& content, const char* filename) - { - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(filename, "rb"); - if (!fileHandle) - { - return false; - } - - gEnv->pCryPak->FSeek(fileHandle, 0, SEEK_END); - size_t size = gEnv->pCryPak->FTell(fileHandle); - gEnv->pCryPak->FSeek(fileHandle, 0, SEEK_SET); - - content.resize(size); - bool result = true; - if (size != 0) - { - result = gEnv->pCryPak->FRead(&content[0], size, fileHandle) == size; - } - gEnv->pCryPak->FClose(fileHandle); - return result; - } - - class CArchiveHost - : public IArchiveHost - { - public: - bool LoadJsonFile(const SStruct& obj, const char* filename) override - { - std::vector content; - if (!LoadFile(content, filename)) - { - return false; - } - JSONIArchive ia; - if (!ia.open(content.data(), content.size())) - { - return false; - } - return ia(obj); - } - - bool SaveJsonFile(const char* gameFilename, const SStruct& obj) override - { - char buffer[AZ::IO::IArchive::MaxPath]; - const char* filename = gEnv->pCryPak->AdjustFileName(gameFilename, buffer, AZ_ARRAY_SIZE(buffer), AZ::IO::IArchive::FLAGS_FOR_WRITING); - JSONOArchive oa; - if (!oa(obj)) - { - return false; - } - return oa.save(filename); - } - - bool LoadJsonBuffer(const SStruct& obj, const char* buffer, size_t bufferLength) override - { - if (bufferLength == 0) - { - return false; - } - JSONIArchive ia; - if (!ia.open(buffer, bufferLength)) - { - return false; - } - return ia(obj); - } - - bool SaveJsonBuffer(DynArray& buffer, const SStruct& obj) override - { - JSONOArchive oa; - if (!oa(obj)) - { - return false; - } - buffer.assign(oa.buffer(), oa.buffer() + oa.length()); - return true; - } - - - bool LoadBinaryFile(const SStruct& obj, const char* filename) override - { - std::vector content; - if (!LoadFile(content, filename)) - { - return false; - } - BinIArchive ia; - if (!ia.open(content.data(), content.size())) - { - return false; - } - return ia(obj); - } - - bool SaveBinaryFile(const char* gameFilename, const SStruct& obj) override - { - char buffer[AZ::IO::IArchive::MaxPath]; - const char* filename = gEnv->pCryPak->AdjustFileName(gameFilename, buffer, AZ_ARRAY_SIZE(buffer), AZ::IO::IArchive::FLAGS_FOR_WRITING); - BinOArchive oa; - obj(oa); - return oa.save(filename); - } - - bool LoadBinaryBuffer(const SStruct& obj, const char* buffer, size_t bufferLength) override - { - if (bufferLength == 0) - { - return false; - } - BinIArchive ia; - if (!ia.open(buffer, bufferLength)) - { - return false; - } - return ia(obj); - } - - bool SaveBinaryBuffer(DynArray& buffer, const SStruct& obj) override - { - BinOArchive oa; - obj(oa); - buffer.assign(oa.buffer(), oa.buffer() + oa.length()); - return true; - } - - bool CloneBinary(const SStruct& dest, const SStruct& src) override - { - BinOArchive oa; - src(oa); - BinIArchive ia; - if (!ia.open(oa.buffer(), oa.length())) - { - return false; - } - dest(ia); - return true; - } - - bool CompareBinary(const SStruct& lhs, const SStruct& rhs) override - { - BinOArchive oa1; - lhs(oa1); - BinOArchive oa2; - rhs(oa2); - if (oa1.length() != oa2.length()) - { - return false; - } - return memcmp(oa1.buffer(), oa2.buffer(), oa1.length()) == 0; - } - - bool SaveXmlFile(const char* filename, const SStruct& obj, const char* rootNodeName) override - { - XmlNodeRef node = SaveXmlNode(obj, rootNodeName); - if (!node) - { - return false; - } - return node->saveToFile(filename); - } - - bool LoadXmlFile(const SStruct& obj, const char* filename) override - { - XmlNodeRef node = gEnv->pSystem->LoadXmlFromFile(filename); - if (!node) - { - return false; - } - return LoadXmlNode(obj, node); - } - - XmlNodeRef SaveXmlNode(const SStruct& obj, const char* nodeName) override - { - CXmlOArchive oa; - XmlNodeRef node = gEnv->pSystem->CreateXmlNode(nodeName); - if (!node) - { - return XmlNodeRef(); - } - oa.SetXmlNode(node); - if (!obj(oa)) - { - return XmlNodeRef(); - } - return oa.GetXmlNode(); - } - - bool SaveXmlNode(XmlNodeRef& node, const SStruct& obj) override - { - if (!node) - { - return false; - } - CXmlOArchive oa; - oa.SetXmlNode(node); - return obj(oa); - } - - bool LoadXmlNode(const SStruct& obj, const XmlNodeRef& node) override - { - CXmlIArchive ia; - ia.SetXmlNode(node); - if (!obj(ia)) - { - return false; - } - return true; - } - }; - - IArchiveHost* CreateArchiveHost() - { - return new CArchiveHost; - } -} diff --git a/Code/CryEngine/CrySystem/Serialization/ArchiveHost.h b/Code/CryEngine/CrySystem/Serialization/ArchiveHost.h deleted file mode 100644 index 360dded0c7..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/ArchiveHost.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -namespace Serialization -{ - IArchiveHost* CreateArchiveHost(); -} diff --git a/Code/CryEngine/CrySystem/Serialization/BinArchive.cpp b/Code/CryEngine/CrySystem/Serialization/BinArchive.cpp deleted file mode 100644 index f16c15cc96..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/BinArchive.cpp +++ /dev/null @@ -1,839 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "BinArchive.h" -#include -#include "Serialization/ClassFactory.h" - -namespace Serialization { - static const unsigned char SIZE16 = 254; - static const unsigned char SIZE32 = 255; - - static const unsigned int BIN_MAGIC = 0xb1a4c17f; - - //#ifdef _DEBUG - //typedef std::map HashMap; - //static HashMap hashMap; - //#endif - - BinOArchive::BinOArchive() - : IArchive(OUTPUT | BINARY) - { - clear(); - } - - void BinOArchive::clear() - { - stream_.clear(); - stream_.write((const char*)&BIN_MAGIC, sizeof(BIN_MAGIC)); - } - - size_t BinOArchive::length() const - { - return stream_.position(); - } - - bool BinOArchive::save(const char* filename) - { - FILE* f = nullptr; - azfopen(&f, filename, "wb"); - if (!f) - { - return false; - } - - if (fwrite(buffer(), 1, length(), f) != length()) - { - fclose(f); - return false; - } - - fclose(f); - return true; - } - - inline void BinOArchive::openNode(const char* name, bool size8) - { - if (!strlen(name)) - { - return; - } - - unsigned short hash = calcHash(name); - stream_.write(hash); - - blockSizeOffsets_.push_back(int(stream_.position())); - stream_.write((unsigned char)0); - if (!size8) - { - stream_.write((unsigned short)0); - } - -#ifdef _DEBUG - // HashMap::iterator i = hashMap.find(hash); - // if(i != hashMap.end() && i->second != name) - // ASSERT_STR(0, name); - // hashMap[hash] = name; -#endif - } - - inline void BinOArchive::closeNode(const char* name, bool size8) - { - if (!strlen(name)) - { - return; - } - - unsigned int offset = blockSizeOffsets_.back(); - unsigned int size = (unsigned int)(stream_.position() - offset - sizeof(unsigned char) - (size8 ? 0 : sizeof(unsigned short))); - blockSizeOffsets_.pop_back(); - unsigned char* sizePtr = (unsigned char*)(stream_.buffer() + offset); - - if (size < SIZE16) - { - *sizePtr = size; - if (!size8) - { - unsigned char* buffer = sizePtr + 3; - memmove(buffer - 2, buffer, size); - stream_.setPosition(stream_.position() - 2); - } - } - else - { - YASLI_ASSERT(!size8); - if (size < 0x10000) - { - *sizePtr = SIZE16; - *((unsigned short*)(sizePtr + 1)) = size; - } - else - { - unsigned char* buffer = sizePtr + 3; - stream_.write((unsigned short)0); - *sizePtr = SIZE32; - memmove(buffer + 2, buffer, size); - *((unsigned int*)(sizePtr + 1)) = size; - } - } - } - - bool BinOArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - bool size8 = strlen(value.get()) + 1 < SIZE16; - openNode(name, size8); - stream_ << value.get(); - stream_.write(char(0)); - closeNode(name, size8); - return true; - } - - bool BinOArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - bool size8 = (wcslen(value.get()) + 1) * 2 < SIZE16; - openNode(name, size8); - stream_ << value.get(); - stream_.write(short(0)); - closeNode(name, size8); - return true; - } - - bool BinOArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - ser(*this); - closeNode(name, false); - return true; - } - - bool BinOArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - - unsigned int size = (unsigned int)ser.size(); - if (size < SIZE16) - { - stream_.write((unsigned char)size); - } - else if (size < 0x10000) - { - stream_.write(SIZE16); - stream_.write((unsigned short)size); - } - else - { - stream_.write(SIZE32); - stream_.write(size); - } - - if (strlen(name)) - { - if (size > 0) - { - int i = 0; - do - { - char elementName[16]; - azitoa(i++, elementName, AZ_ARRAY_SIZE(elementName), 10); - ser(*this, elementName, ""); - } while (ser.next()); - } - - closeNode(name, false); - } - else - { - if (size > 0) - { - do - { - ser(*this, "", ""); - } - while (ser.next()); - } - } - - return true; - } - - bool BinOArchive::operator()(IPointer& ptr, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - - const char* typeName = ptr.registeredTypeName(); - if (!typeName) - { - typeName = ""; - } - if (typeName[0] == '\0' && ptr.get()) - { - CRY_ASSERT_MESSAGE(0, "Writing unregistered class. Use SERIALIZATION_CLASS_NAME macro for registration."); - } - - TypeID baseType = ptr.baseType(); - - if (ptr.get()) - { - stream_ << typeName; - stream_.write(char(0)); - ptr.serializer()(*this); - } - else - { - stream_.write(char(0)); - } - - closeNode(name, false); - return true; - } - - ////////////////////////////////////////////////////////////////////////// - - BinIArchive::BinIArchive() - : IArchive(INPUT | BINARY) - , loadedData_(0) - { - } - - BinIArchive::~BinIArchive() - { - close(); - } - - bool BinIArchive::load(const char* filename) - { - close(); - - FILE* f = nullptr; - azfopen(&f, filename, "rb"); - - if (!f) - { - return false; - } - fseek(f, 0, SEEK_END); - size_t length = ftell(f); - fseek(f, 0, SEEK_SET); - if (length == 0) - { - fclose(f); - return false; - } - loadedData_ = new char[length]; - if (fread((void*)loadedData_, 1, length, f) != length || !open(loadedData_, length)) - { - close(); - fclose(f); - return false; - } - fclose(f); - return true; - } - - bool BinIArchive::open(const char* buffer, size_t size) - { - if (size < sizeof(int)) - { - return false; - } - if (*(unsigned*)(buffer) != BIN_MAGIC) - { - return false; - } - buffer += sizeof(unsigned int); - size -= sizeof(unsigned int); - - blocks_.push_back(Block(buffer, (unsigned int)size)); - return true; - } - - void BinIArchive::close() - { - if (loadedData_) - { - delete[] loadedData_; - } - loadedData_ = 0; - } - - bool BinIArchive::openNode(const char* name) - { - Block block(0, 0); - if (currentBlock().get(name, block)) - { - blocks_.push_back(block); - return true; - } - return false; - } - - void BinIArchive::closeNode([[maybe_unused]] const char* name, [[maybe_unused]] bool check) - { - YASLI_ASSERT(!check || currentBlock().validToClose()); - blocks_.pop_back(); - } - - bool BinIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - string str; - read(str); - value.set(str.c_str()); - return true; - } - - if (!openNode(name)) - { - return false; - } - - string str; - read(str); - value.set(str.c_str()); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - wstring str; - read(str); - value.set(str.c_str()); - return true; - } - - if (!openNode(name)) - { - return false; - } - - wstring str; - read(str); - value.set(str.c_str()); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - - bool BinIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - ser(*this); - return true; - } - - if (!openNode(name)) - { - return false; - } - - ser(*this); - closeNode(name, false); - return true; - } - - bool BinIArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (strlen(name)) - { - if (!openNode(name)) - { - return false; - } - - size_t size = currentBlock().readPackedSize(); - ser.resize(size); - - if (size > 0) - { - int i = 0; - do - { - char elementName[16]; - azitoa(i++, elementName, AZ_ARRAY_SIZE(elementName), 10); - ser(*this, elementName, ""); - } - while (ser.next()); - } - closeNode(name); - return true; - } - else - { - size_t size = currentBlock().readPackedSize(); - ser.resize(size); - if (size > 0) - { - do - { - ser(*this, "", ""); - } - while (ser.next()); - } - return true; - } - } - - bool BinIArchive::operator()(IPointer& ptr, const char* name, [[maybe_unused]] const char* label) - { - if (strlen(name) && !openNode(name)) - { - return false; - } - - string typeName; - read(typeName); - if (ptr.get() && (typeName.empty() || strcmp(typeName.c_str(), ptr.registeredTypeName()) != 0)) - { - ptr.create(""); // 0 - } - if (!typeName.empty() && !ptr.get()) - { - ptr.create(typeName.c_str()); - } - - if (SStruct ser = ptr.serializer()) - { - ser(*this); - } - - if (strlen(name)) - { - closeNode(name); - } - return true; - } - - unsigned int BinIArchive::Block::readPackedSize() - { - unsigned char size8; - read(size8); - if (size8 < SIZE16) - { - return size8; - } - if (size8 == SIZE16) - { - unsigned short size16; - read(size16); - return size16; - } - unsigned int size32; - read(size32); - return size32; - } - - bool BinIArchive::Block::get(const char* name, Block& block) - { - if (begin_ == end_) - { - return false; - } - complex_ = true; - unsigned short hashName = calcHash(name); - const char* currInitial = curr_; - bool restarted = false; - for (;; ) - { - if (curr_ >= end_) - { - return false; - } - - unsigned short hash; - read(hash); - unsigned int size = readPackedSize(); - - const char* currPrev = curr_; - if ((curr_ += size) == end_) - { - if (restarted) - { - return false; - } - curr_ = begin_; - restarted = true; - } - - //ASSERT(curr_ < end_); - - if (hash == hashName) - { - block = Block(currPrev, size); - return true; - } - - if (curr_ == currInitial) - { - return false; - } - } - } -} diff --git a/Code/CryEngine/CrySystem/Serialization/BinArchive.h b/Code/CryEngine/CrySystem/Serialization/BinArchive.h deleted file mode 100644 index 2d7daba899..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/BinArchive.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -// For tags 16-bit xor-hash is used, with check for uniquness in debug -// Block size is automatic: 8, 16 or 32 bits - -#include "Serialization/IArchive.h" -#include "MemoryWriter.h" - -namespace Serialization { - inline unsigned short calcHash(const char* str) - { - unsigned short hash = 0; - const unsigned short* p = (const unsigned short*)(str); - for (;; ) - { - unsigned short w = *p++; - if (!(w & 0xff)) - { - break; - } - hash ^= w; - if (!(w & 0xff00)) - { - break; - } - } - return hash; - } - - class BinOArchive - : public IArchive - { - public: - - BinOArchive(); - ~BinOArchive() {} - - void clear(); - size_t length() const; - const char* buffer() const { return stream_.buffer(); } - bool save(const char* fileName); - - bool operator()(bool& value, const char* name, const char* label); - bool operator()(IString& value, const char* name, const char* label); - bool operator()(IWString& value, const char* name, const char* label); - bool operator()(float& value, const char* name, const char* label); - bool operator()(double& value, const char* name, const char* label); - bool operator()(int32& value, const char* name, const char* label); - bool operator()(uint32& value, const char* name, const char* label); - bool operator()(int16& value, const char* name, const char* label); - bool operator()(uint16& value, const char* name, const char* label); - bool operator()(int64& value, const char* name, const char* label); - bool operator()(uint64& value, const char* name, const char* label); - - bool operator()(int8& value, const char* name, const char* label); - bool operator()(uint8& value, const char* name, const char* label); - bool operator()(char& value, const char* name, const char* label); - - bool operator()(const SStruct& ser, const char* name, const char* label); - bool operator()(IContainer& ser, const char* name, const char* label); - bool operator()(IPointer& ptr, const char* name, const char* label); - - using IArchive::operator(); - - private: - void openContainer(const char* name, int size, const char* typeName); - void openNode(const char* name, bool size8 = true); - void closeNode(const char* name, bool size8 = true); - - std::vector blockSizeOffsets_; - MemoryWriter stream_; - }; - - ////////////////////////////////////////////////////////////////////////// - - class BinIArchive - : public IArchive - { - public: - - BinIArchive(); - ~BinIArchive(); - - bool load(const char* fileName); - bool open(const char* buffer, size_t length); // doesn't copy the buffer - bool open(const BinOArchive& ar) { return open(ar.buffer(), ar.length()); } - void close(); - - bool operator()(bool& value, const char* name, const char* label); - bool operator()(IString& value, const char* name, const char* label); - bool operator()(IWString& value, const char* name, const char* label); - bool operator()(float& value, const char* name, const char* label); - bool operator()(double& value, const char* name, const char* label); - bool operator()(int16& value, const char* name, const char* label); - bool operator()(uint16& value, const char* name, const char* label); - bool operator()(int32& value, const char* name, const char* label); - bool operator()(uint32& value, const char* name, const char* label); - bool operator()(int64& value, const char* name, const char* label); - bool operator()(uint64& value, const char* name, const char* label); - - bool operator()(int8& value, const char* name, const char* label); - bool operator()(uint8& value, const char* name, const char* label); - bool operator()(char& value, const char* name, const char* label); - - bool operator()(const SStruct& ser, const char* name, const char* label); - bool operator()(IContainer& ser, const char* name, const char* label); - bool operator()(IPointer& ptr, const char* name, const char* label); - - using IArchive::operator(); - - private: - class Block - { - public: - Block(const char* data, int size) - : begin_(data) - , end_(data + size) - , curr_(data) - , complex_(false) {} - - bool get(const char* name, Block& block); - - void read(void* data, int size) - { - YASLI_ASSERT(curr_ + size <= end_); - memcpy(data, curr_, size); - curr_ += size; - } - - template - void read(T& x){ read(&x, sizeof(x)); } - - void read(string& s) - { - YASLI_ASSERT(curr_ + strlen(curr_) < end_); - s = curr_; - curr_ += strlen(curr_) + 1; - } - void read(wstring& s) - { - YASLI_ASSERT(curr_ + sizeof(wchar_t) * wcslen((wchar_t*)curr_) < end_); - s = (wchar_t*)curr_; - curr_ += (wcslen((wchar_t*)curr_) + 1) * sizeof(wchar_t); - } - - unsigned int readPackedSize(); - - bool validToClose() const { return complex_ || curr_ == end_; } - - private: - const char* begin_; - const char* end_; - const char* curr_; - bool complex_; - }; - - typedef std::vector Blocks; - Blocks blocks_; - const char* loadedData_; - - bool openNode(const char* name); - void closeNode(const char* name, bool check = true); - Block& currentBlock() { return blocks_.back(); } - template - void read(T& t) { currentBlock().read(t); } - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/JSONIArchive.cpp b/Code/CryEngine/CrySystem/Serialization/JSONIArchive.cpp deleted file mode 100644 index 8e323cc44c..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/JSONIArchive.cpp +++ /dev/null @@ -1,1525 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include -#include -#include "Serialization/ClassFactory.h" -#include "Serialization/STL.h" -#include "JSONIArchive.h" -#include "Serialization/BlackBox.h" -#include "MemoryReader.h" -#include "MemoryWriter.h" - -#if 0 -# define DEBUG_TRACE(fmt, ...) printf(fmt "\n", __VA_ARGS__) -# define DEBUG_TRACE_TOKENIZER(fmt, ...) printf(fmt "\n", __VA_ARGS__) -#else -# define DEBUG_TRACE(...) -# define DEBUG_TRACE_TOKENIZER(...) -#endif - -namespace Serialization { - static char hexValueTable[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, - - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - static void unescapeString(std::vector& buf, string& out, const char* begin, const char* end) - { - if (begin >= end) - { - out.clear(); - return; - } - // TODO: use stack string - buf.resize(end - begin); - char* ptr = &buf[0]; - while (begin != end) - { - if (*begin != '\\') - { - *ptr = *begin; - ++ptr; - } - else - { - ++begin; - if (begin == end) - { - break; - } - - switch (*begin) - { - case '0': - *ptr = '\0'; - ++ptr; - break; - case 't': - *ptr = '\t'; - ++ptr; - break; - case 'n': - *ptr = '\n'; - ++ptr; - break; - case 'r': - *ptr = '\r'; - ++ptr; - break; - case '\\': - *ptr = '\\'; - ++ptr; - break; - case '\"': - *ptr = '\"'; - ++ptr; - break; - case '\'': - *ptr = '\''; - ++ptr; - break; - case 'x': - if (begin + 2 < end) - { - *ptr = (hexValueTable[int(begin[1])] << 4) + hexValueTable[int(begin[2])]; - ++ptr; - begin += 2; - break; - } - default: - *ptr = *begin; - ++ptr; - break; - } - } - ++begin; - } - buf.resize(ptr - &buf[0]); - if (!buf.empty()) - { - out.assign(&buf[0], &buf[0] + buf.size()); - } - else - { - out.clear(); - } - } - - // --------------------------------------------------------------------------- - - class JSONTokenizer - { - public: - JSONTokenizer(); - - Token operator()(const char* text) const; - private: - inline bool isSpace(char c) const; - inline bool isWordPart(unsigned char c) const; - inline bool isComment(char c) const; - inline bool isQuoteOpen(int& quoteIndex, char c) const; - inline bool isQuoteClose(int quoteIndex, char c) const; - inline bool isQuote(char c) const; - }; - - JSONTokenizer::JSONTokenizer() - { - } - - inline bool JSONTokenizer::isSpace(char c) const - { - return c == ' ' || c == '\t' || c == '\n' || c == '\r'; - } - - inline bool JSONTokenizer::isComment(char c) const - { - return c == '#'; - } - - - inline bool JSONTokenizer::isQuote(char c) const - { - return c == '\"'; - } - - static const char charTypes[256] = { - 0 /* 0x00: */, - 0 /* 0x01: */, - 0 /* 0x02: */, - 0 /* 0x03: */, - 0 /* 0x04: */, - 0 /* 0x05: */, - 0 /* 0x06: */, - 0 /* 0x07: */, - 0 /* 0x08: */, - 0 /* 0x09: \t */, - 0 /* 0x0A: \n */, - 0 /* 0x0B: */, - 0 /* 0x0C: */, - 0 /* 0x0D: */, - 0 /* 0x0E: */, - 0 /* 0x0F: */, - - - 0 /* 0x10: */, - 0 /* 0x11: */, - 0 /* 0x12: */, - 0 /* 0x13: */, - 0 /* 0x14: */, - 0 /* 0x15: */, - 0 /* 0x16: */, - 0 /* 0x17: */, - 0 /* 0x18: */, - 0 /* 0x19: */, - 0 /* 0x1A: */, - 0 /* 0x1B: */, - 0 /* 0x1C: */, - 0 /* 0x1D: */, - 0 /* 0x1E: */, - 0 /* 0x1F: */, - - - 0 /* 0x20: */, - 0 /* 0x21: ! */, - 0 /* 0x22: " */, - 0 /* 0x23: # */, - 0 /* 0x24: $ */, - 0 /* 0x25: % */, - 0 /* 0x26: & */, - 0 /* 0x27: ' */, - 0 /* 0x28: ( */, - 0 /* 0x29: ) */, - 0 /* 0x2A: * */, - 0 /* 0x2B: + */, - 0 /* 0x2C: , */, - 1 /* 0x2D: - */, - 1 /* 0x2E: . */, - 0 /* 0x2F: / */, - - - 1 /* 0x30: 0 */, - 1 /* 0x31: 1 */, - 1 /* 0x32: 2 */, - 1 /* 0x33: 3 */, - 1 /* 0x34: 4 */, - 1 /* 0x35: 5 */, - 1 /* 0x36: 6 */, - 1 /* 0x37: 7 */, - 1 /* 0x38: 8 */, - 1 /* 0x39: 9 */, - 0 /* 0x3A: : */, - 0 /* 0x3B: ; */, - 0 /* 0x3C: < */, - 0 /* 0x3D: = */, - 0 /* 0x3E: > */, - 0 /* 0x3F: ? */, - - - 0 /* 0x40: @ */, - 1 /* 0x41: A */, - 1 /* 0x42: B */, - 1 /* 0x43: C */, - 1 /* 0x44: D */, - 1 /* 0x45: E */, - 1 /* 0x46: F */, - 1 /* 0x47: G */, - 1 /* 0x48: H */, - 1 /* 0x49: I */, - 1 /* 0x4A: J */, - 1 /* 0x4B: K */, - 1 /* 0x4C: L */, - 1 /* 0x4D: M */, - 1 /* 0x4E: N */, - 1 /* 0x4F: O */, - - - 1 /* 0x50: P */, - 1 /* 0x51: Q */, - 1 /* 0x52: R */, - 1 /* 0x53: S */, - 1 /* 0x54: T */, - 1 /* 0x55: U */, - 1 /* 0x56: V */, - 1 /* 0x57: W */, - 1 /* 0x58: X */, - 1 /* 0x59: Y */, - 1 /* 0x5A: Z */, - 0 /* 0x5B: [ */, - 0 /* 0x5C: \ */, - 0 /* 0x5D: ] */, - 0 /* 0x5E: ^ */, - 1 /* 0x5F: _ */, - - - 0 /* 0x60: ` */, - 1 /* 0x61: a */, - 1 /* 0x62: b */, - 1 /* 0x63: c */, - 1 /* 0x64: d */, - 1 /* 0x65: e */, - 1 /* 0x66: f */, - 1 /* 0x67: g */, - 1 /* 0x68: h */, - 1 /* 0x69: i */, - 1 /* 0x6A: j */, - 1 /* 0x6B: k */, - 1 /* 0x6C: l */, - 1 /* 0x6D: m */, - 1 /* 0x6E: n */, - 1 /* 0x6F: o */, - - - 1 /* 0x70: p */, - 1 /* 0x71: q */, - 1 /* 0x72: r */, - 1 /* 0x73: s */, - 1 /* 0x74: t */, - 1 /* 0x75: u */, - 1 /* 0x76: v */, - 1 /* 0x77: w */, - 1 /* 0x78: x */, - 1 /* 0x79: y */, - 1 /* 0x7A: z */, - 0 /* 0x7B: { */, - 0 /* 0x7C: | */, - 0 /* 0x7D: } */, - 0 /* 0x7E: ~ */, - 0 /* 0x7F: */, - - - 0 /* 0x80: */, - 0 /* 0x81: */, - 0 /* 0x82: */, - 0 /* 0x83: */, - 0 /* 0x84: */, - 0 /* 0x85: */, - 0 /* 0x86: */, - 0 /* 0x87: */, - 0 /* 0x88: */, - 0 /* 0x89: */, - 0 /* 0x8A: */, - 0 /* 0x8B: */, - 0 /* 0x8C: */, - 0 /* 0x8D: */, - 0 /* 0x8E: */, - 0 /* 0x8F: */, - - - 0 /* 0x90: */, - 0 /* 0x91: */, - 0 /* 0x92: */, - 0 /* 0x93: */, - 0 /* 0x94: */, - 0 /* 0x95: */, - 0 /* 0x96: */, - 0 /* 0x97: */, - 0 /* 0x98: */, - 0 /* 0x99: */, - 0 /* 0x9A: */, - 0 /* 0x9B: */, - 0 /* 0x9C: */, - 0 /* 0x9D: */, - 0 /* 0x9E: */, - 0 /* 0x9F: */, - - - 0 /* 0xA0: */, - 0 /* 0xA1: */, - 0 /* 0xA2: */, - 0 /* 0xA3: */, - 0 /* 0xA4: */, - 0 /* 0xA5: */, - 0 /* 0xA6: */, - 0 /* 0xA7: */, - 0 /* 0xA8: */, - 0 /* 0xA9: */, - 0 /* 0xAA: */, - 0 /* 0xAB: */, - 0 /* 0xAC: */, - 0 /* 0xAD: */, - 0 /* 0xAE: */, - 0 /* 0xAF: */, - - - 0 /* 0xB0: */, - 0 /* 0xB1: */, - 0 /* 0xB2: */, - 0 /* 0xB3: */, - 0 /* 0xB4: */, - 0 /* 0xB5: */, - 0 /* 0xB6: */, - 0 /* 0xB7: */, - 0 /* 0xB8: */, - 0 /* 0xB9: */, - 0 /* 0xBA: */, - 0 /* 0xBB: */, - 0 /* 0xBC: */, - 0 /* 0xBD: */, - 0 /* 0xBE: */, - 0 /* 0xBF: */, - - - 0 /* 0xC0: */, - 0 /* 0xC1: */, - 0 /* 0xC2: */, - 0 /* 0xC3: */, - 0 /* 0xC4: */, - 0 /* 0xC5: */, - 0 /* 0xC6: */, - 0 /* 0xC7: */, - 0 /* 0xC8: */, - 0 /* 0xC9: */, - 0 /* 0xCA: */, - 0 /* 0xCB: */, - 0 /* 0xCC: */, - 0 /* 0xCD: */, - 0 /* 0xCE: */, - 0 /* 0xCF: */, - - - 0 /* 0xD0: */, - 0 /* 0xD1: */, - 0 /* 0xD2: */, - 0 /* 0xD3: */, - 0 /* 0xD4: */, - 0 /* 0xD5: */, - 0 /* 0xD6: */, - 0 /* 0xD7: */, - 0 /* 0xD8: */, - 0 /* 0xD9: */, - 0 /* 0xDA: */, - 0 /* 0xDB: */, - 0 /* 0xDC: */, - 0 /* 0xDD: */, - 0 /* 0xDE: */, - 0 /* 0xDF: */, - - - 0 /* 0xE0: */, - 0 /* 0xE1: */, - 0 /* 0xE2: */, - 0 /* 0xE3: */, - 0 /* 0xE4: */, - 0 /* 0xE5: */, - 0 /* 0xE6: */, - 0 /* 0xE7: */, - 0 /* 0xE8: */, - 0 /* 0xE9: */, - 0 /* 0xEA: */, - 0 /* 0xEB: */, - 0 /* 0xEC: */, - 0 /* 0xED: */, - 0 /* 0xEE: */, - 0 /* 0xEF: */, - - - 0 /* 0xF0: */, - 0 /* 0xF1: */, - 0 /* 0xF2: */, - 0 /* 0xF3: */, - 0 /* 0xF4: */, - 0 /* 0xF5: */, - 0 /* 0xF6: */, - 0 /* 0xF7: */, - 0 /* 0xF8: */, - 0 /* 0xF9: */, - 0 /* 0xFA: */, - 0 /* 0xFB: */, - 0 /* 0xFC: */, - 0 /* 0xFD: */, - 0 /* 0xFE: */, - 0 /* 0xFF: */ - }; - - inline bool JSONTokenizer::isWordPart(unsigned char c) const - { - return charTypes[c] != 0; - } - - Token JSONTokenizer::operator()(const char* ptr) const - { - while (isSpace(*ptr)) - { - ++ptr; - } - Token cur(ptr, ptr); - while (!cur && *ptr != '\0') - { - while (isComment(*cur.end)) - { -#if 0 - const char* commentStart = ptr; -#endif - while (*cur.end && *cur.end != '\n') - { - ++cur.end; - } - while (isSpace(*cur.end)) - { - ++cur.end; - } - DEBUG_TRACE_TOKENIZER("Got comment: '%s'", string(commentStart, cur.end).c_str()); - cur.start = cur.end; - } - CRY_ASSERT(!isSpace(*cur.end)); - if (isQuote(*cur.end)) - { - ++cur.end; - while (*cur.end) - { - if (*cur.end == '\\') - { - ++cur.end; - if (*cur.end) - { - if (*cur.end != 'x' && *cur.end != 'X') - { - ++cur.end; - } - else - { - ++cur.end; - if (*cur.end) - { - ++cur.end; - } - } - } - } - if (isQuote(*cur.end)) - { - ++cur.end; - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - else - { - ++cur.end; - } - } - } - else - { - if (!*cur.end) - { - return cur; - } - - DEBUG_TRACE_TOKENIZER("%c", *cur.end); - if (isWordPart(*cur.end)) - { - do - { - ++cur.end; - } while (isWordPart(*cur.end) != 0); - } - else - { - ++cur.end; - return cur; - } - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - } - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - - - // --------------------------------------------------------------------------- - - JSONIArchive::JSONIArchive() - : IArchive(INPUT | TEXT) - , buffer_(0) - { - } - - JSONIArchive::~JSONIArchive() - { - if (buffer_) - { - free(buffer_); - buffer_ = 0; - } - stack_.clear(); - reader_.reset(); - } - - bool JSONIArchive::open(const char* buffer, size_t length, bool free) - { - if (!length) - { - return false; - } - - if (buffer) - { - reader_.reset(new MemoryReader(buffer, length, free)); - } - buffer_ = 0; - - token_ = Token(reader_->begin(), reader_->begin()); - stack_.clear(); - - stack_.push_back(Level()); - readToken(); - putToken(); - stack_.back().start = token_.end; - return true; - } - - - bool JSONIArchive::load(const char* filename) - { - FILE* file = nullptr; - azfopen(&file, filename, "rb"); - if (file) - { - fseek(file, 0, SEEK_END); - long fileSize = ftell(file); - fseek(file, 0, SEEK_SET); - - void* buffer = 0; - if (fileSize > 0) - { - buffer = CryModuleMalloc(fileSize + 1); - CRY_ASSERT(buffer != 0); - memset(buffer, 0, fileSize + 1); - size_t elementsRead = fread(buffer, fileSize, 1, file); - CRY_ASSERT(((char*)(buffer))[fileSize] == '\0'); - if (elementsRead != 1) - { - CryModuleFree(buffer); - return false; - } - } - fclose(file); - - filename_ = filename; - buffer_ = buffer; - if (fileSize > 0) - { - return open((char*)buffer, fileSize, false); - } - else - { - return false; - } - } - else - { - return false; - } - } - - void JSONIArchive::readToken() - { - JSONTokenizer tokenizer; - token_ = tokenizer(token_.end); - DEBUG_TRACE(" ~ read token '%s' at %i", token_.str().c_str(), token_.start - reader_->begin()); - } - - void JSONIArchive::putToken() - { - DEBUG_TRACE(" putToken: '%s'", token_.str().c_str()); - token_ = Token(token_.start, token_.start); - } - - int JSONIArchive::line(const char* position) const - { - return int(std::count(reader_->begin(), position, '\n') + 1); - } - - bool JSONIArchive::isName(Token token) const - { - if (!token) - { - return false; - } - char firstChar = token.start[0]; - if (firstChar == '"') - { - return true; - } - return false; - } - - - bool JSONIArchive::expect(char token) - { - if (token_ != token) - { - const char* lineEnd = token_.start; - while (lineEnd && *lineEnd != '\0' && *lineEnd != '\r' && *lineEnd != '\n') - { - ++lineEnd; - } - - MemoryWriter msg; - msg << "Error parsing file, expected ':' at line " << line(token_.start) << ":\n" - << string(token_.start, lineEnd).c_str(); - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - return true; - } - - void JSONIArchive::skipBlock() - { - DEBUG_TRACE("Skipping block from %i ...", token_.end - reader_->begin()); - if (openBracket() || openContainerBracket()) - { - closeBracket(); // Skipping entire block - } - else - { - readToken(); // Skipping value - } - readToken(); - if (token_ != ',') - { - putToken(); - } - DEBUG_TRACE(" ...till %i", token_.end - reader_->begin()); - } - - bool JSONIArchive::findName(const char* name, Token* outName) - { - DEBUG_TRACE(" * finding name '%s'", name); - DEBUG_TRACE(" started at byte %i", int(token_.start - reader_->begin())); - if (stack_.empty()) - { - // TODO: diagnose - return false; - } - if (stack_.back().isKeyValue) - { - return true; - } - const char* start = 0; - const char* blockBegin = stack_.back().start; - if (*blockBegin == '\0') - { - return false; - } - - readToken(); - if (token_ == ',') - { - readToken(); - } - if (!token_) - { - start = blockBegin; - token_.set(blockBegin, blockBegin); - readToken(); - } - - if (stack_.size() == 1 || stack_.back().isContainer || outName != 0) - { - if (token_ == ']' || token_ == '}') - { - DEBUG_TRACE("Got close bracket..."); - putToken(); - return false; - } - else - { - DEBUG_TRACE("Got unnamed value: '%s'", token_.str().c_str()); - putToken(); - return true; - } - } - else - { - if (isName(token_)) - { - DEBUG_TRACE("Seems to be a name '%s'", token_.str().c_str()); - Token nameContent(token_.start + 1, token_.end - 1); - if (nameContent == name) - { - readToken(); - expect(':'); - DEBUG_TRACE("Got one"); - return true; - } - else - { - start = token_.start; - - readToken(); - expect(':'); - skipBlock(); - } - } - else - { - start = token_.start; - if (token_ == ']' || token_ == '}') - { - token_ = Token(blockBegin, blockBegin); - } - else - { - putToken(); - skipBlock(); - } - } - } - - while (true) - { - readToken(); - if (!token_) - { - token_.set(blockBegin, blockBegin); - continue; - } - //return false; // Reached end of file while searching for name - DEBUG_TRACE("'%s'", token_.str().c_str()); - DEBUG_TRACE("Checking for loop: %i and %i", token_.start - reader_->begin(), start - reader_->begin()); - CRY_ASSERT(start != 0); - if (token_.start == start) - { - putToken(); - DEBUG_TRACE("unable to find..."); - return false; // Reached a full circle: unable to find name - } - - if (token_ == '}' || token_ == ']') // CONVERSION - { - DEBUG_TRACE("Going to begin of block, from %i", token_.start - reader_->begin()); - token_ = Token(blockBegin, blockBegin); - DEBUG_TRACE(" to %i", token_.start - reader_->begin()); - continue; // Reached '}' or ']' while searching for name, continue from begin of block - } - - if (name[0] == '\0') - { - if (isName(token_)) - { - readToken(); - if (!token_) - { - return false; // Reached end of file while searching for name - } - expect(':'); - skipBlock(); - } - else - { - putToken(); // Not a name - put it back - return true; - } - } - else - { - if (isName(token_)) - { - Token nameContent(token_.start + 1, token_.end - 1); - readToken(); - expect(':'); - if (nameContent == name) - { - return true; - } - else - { - skipBlock(); - } - } - else - { - putToken(); - skipBlock(); - } - } - } - - return false; - } - - bool JSONIArchive::openBracket() - { - readToken(); - if (token_ == '{') - { - return true; - } - putToken(); - return false; - } - - bool JSONIArchive::closeBracket() - { - int relativeLevel = 0; - while (true) - { - readToken(); - if (token_ == ',') - { - readToken(); - } - if (!token_) - { - MemoryWriter msg; - CRY_ASSERT(!stack_.empty()); - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while no matching bracket found"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - else if (token_ == '}' || token_ == ']') // CONVERSION - { - if (relativeLevel == 0) - { - return true; - } - else - { - --relativeLevel; - } - } - else if (token_ == '{' || token_ == '[') // CONVERSION - { - ++relativeLevel; - } - } - return false; - } - - bool JSONIArchive::openContainerBracket() - { - readToken(); - if (token_ == '[') - { - return true; - } - putToken(); - return false; - } - - bool JSONIArchive::closeContainerBracket() - { - readToken(); - if (token_ == ']') - { - DEBUG_TRACE("closeContainerBracket(): ok"); - return true; - } - else - { - DEBUG_TRACE("closeContainerBracket(): failed ('%s')", token_.str().c_str()); - putToken(); - return false; - } - } - - bool JSONIArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - } - else if (openContainerBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - stack_.back().isContainer = true; - } - else - { - return false; - } - - ser(*this); - CRY_ASSERT(!stack_.empty()); - stack_.pop_back(); -#if !defined(NDEBUG) - bool closed = -#endif - closeBracket(); - CRY_ASSERT(closed); - return true; - } - return false; - } - - bool JSONIArchive::operator()(const SBlackBox& box, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket() || openContainerBracket()) - { - const char* start = token_.start; - putToken(); - skipBlock(); - const char* end = token_.start; - if (end < start) - { - CRY_ASSERT(0); - return false; - } - while (end > start && - (*(end - 1) == ' ' - || *(end - 1) == '\r' - || *(end - 1) == '\n' - || *(end - 1) == '\t')) - { - --end; - } - // box has to be const in the interface so we can serialize - // temporary variables (i.e. function call result or structures - // constructed on the stack) - const_cast(box).set("json", (void*)start, end - start); - return true; - } - } - return false; - } - - bool JSONIArchive::operator()(IKeyValue& keyValue, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) - { - Token nextName; - if (!stack_.empty() && stack_.back().isContainer) - { - readToken(); - if (isName(token_) && checkStringValueToken()) - { - string key; - unescapeString(unescapeBuffer_, key, token_.start + 1, token_.end - 1); - keyValue.set(key.c_str()); - readToken(); - if (!expect(':')) - { - return false; - } - if (!keyValue.serializeValue(*this, "", 0)) - { - return false; - } - return true; - } - else - { - putToken(); - return false; - } - } - else if (findName("", &nextName)) - { - string key; - unescapeString(unescapeBuffer_, key, nextName.start + 1, nextName.end - 1); - keyValue.set(key.c_str()); - stack_.push_back(Level()); - stack_.back().isKeyValue = true; - - bool result = keyValue.serializeValue(*this, "", 0); - if (stack_.empty()) - { - // TODO: diagnose - return false; - } - stack_.pop_back(); - return result; - } - return false; - } - - - bool JSONIArchive::operator()(IPointer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - stack_.back().isKeyValue = true; - - readToken(); - if (isName(token_)) - { - if (checkStringValueToken()) - { - string typeName; - unescapeString(unescapeBuffer_, typeName, token_.start + 1, token_.end - 1); - - if (typeName != ser.registeredTypeName()) - { - ser.create(typeName.c_str()); - } - readToken(); - expect(':'); - operator()(ser.serializer(), "", 0); - } - } - else - { - putToken(); - - ser.create(""); - } - closeBracket(); - stack_.pop_back(); - return true; - } - } - return false; - } - - - bool JSONIArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - bool containerBracket = openContainerBracket(); - bool dictionaryBracket = false; - if (!containerBracket) - { - dictionaryBracket = openBracket(); - } - if (containerBracket || dictionaryBracket) - { - stack_.push_back(Level()); - stack_.back().isContainer = true; - stack_.back().start = token_.end; - - std::size_t size = ser.size(); - std::size_t index = 0; - - while (true) - { - readToken(); - if (token_ == ',') - { - readToken(); - } - if (token_ == '}' || token_ == ']') - { - break; - } - else if (!token_) - { - CRY_ASSERT(0 && "Reached end of file while reading container!"); - return false; - } - putToken(); - if (index == size) - { - size = index + 1; - } - if (index < size) - { - if (!ser(*this, "", "")) - { - // We've got a named item within a container, - // i.e. looks like a dictionary but not a container. - // Bail out, it is nothing we can do here. - closeBracket(); - break; - } - } - else - { - skipBlock(); - } - ser.next(); - ++index; - } - if (size > index) - { - ser.resize(index); - } - - CRY_ASSERT(!stack_.empty()); - stack_.pop_back(); - return true; - } - } - return false; - } - - void JSONIArchive::checkValueToken() - { - if (!token_) - { - CRY_ASSERT(!stack_.empty()); - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while reading element's value"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - } - } - - bool JSONIArchive::checkStringValueToken() - { - if (!token_) - { - return false; - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while reading element's value"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - if (token_.start[0] != '"' || token_.end[-1] != '"') - { - return false; - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": Expected string"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - return true; - } - - bool JSONIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = strtoul(token_.start, 0, 10); - return true; - } - return false; - } - - - bool JSONIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (int16)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (uint16)strtoul(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = _strtoi64(token_.start, 0, 10); -#else - value = strtoll(token_.start, 0, 10); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = _strtoui64(token_.start, 0, 10); -#else - value = strtoull(token_.start, 0, 10); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = float(std::atof(token_.str().c_str())); -#else - value = strtof(token_.start, 0); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = std::atof(token_.str().c_str()); -#else - value = strtod(token_.start, 0); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - if (checkStringValueToken()) - { - string buf; - unescapeString(unescapeBuffer_, buf, token_.start + 1, token_.end - 1); - value.set(buf.c_str()); - } - else - { - return false; - } - return true; - } - return false; - } - - - inline size_t utf8InUtf16Len(const char* p) - { - size_t result = 0; - - for (; *p; ++p) - { - unsigned char ch = (unsigned char)(*p); - - if (ch < 0x80 || (ch >= 0xC0 && ch < 0xFC)) - { - ++result; - } - } - - return result; - } - - inline const char* readUtf16FromUtf8(unsigned int* ch, const char* s) - { - const unsigned char byteMark = 0x80; - const unsigned char byteMaskRead = 0x3F; - - const unsigned char* str = (const unsigned char*)s; - - size_t len; - if (*str < byteMark) - { - *ch = *str; - return s + 1; - } - else if (*str < 0xC0) - { - *ch = ' '; - return s + 1; - } - else if (*str < 0xE0) - { - len = 2; - } - else if (*str < 0xF0) - { - len = 3; - } - else if (*str < 0xF8) - { - len = 4; - } - else if (*str < 0xFC) - { - len = 5; - } - else - { - *ch = ' '; - return s + 1; - } - - const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - *ch = (*str++ & ~firstByteMark[len]); - - switch (len) - { - case 5: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 4: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 3: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 2: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - } - - return (const char*)str; - } - - - inline void utf8ToUtf16(wstring* out, const char* in) - { - out->clear(); - out->reserve(utf8InUtf16Len(in)); - - for (; *in; ) - { - unsigned int character; - in = readUtf16FromUtf8(&character, in); - (*out) += (wchar_t)character; - } - } - - - bool JSONIArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - if (checkStringValueToken()) - { - string buf; - unescapeString(unescapeBuffer_, buf, token_.start + 1, token_.end - 1); - wstring wbuf; - utf8ToUtf16(&wbuf, buf.c_str()); - value.set(wbuf.c_str()); - } - else - { - return false; - } - return true; - } - return false; - } - - bool JSONIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - if (token_ == "true") - { - value = true; - } - else if (token_ == "false") - { - value = false; - } - else - { - CRY_ASSERT(0 && "Invalid boolean value"); - } - return true; - } - return false; - } - - bool JSONIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (int8)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (uint8)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (char)strtol(token_.start, 0, 10); - return true; - } - return false; - } -} -// vim:ts=4 sw=4: diff --git a/Code/CryEngine/CrySystem/Serialization/JSONIArchive.h b/Code/CryEngine/CrySystem/Serialization/JSONIArchive.h deleted file mode 100644 index b38476a597..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/JSONIArchive.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "Serialization/IArchive.h" -#include "MemoryReader.h" -#include "Token.h" -#include - -namespace Serialization { - class MemoryReader; - - class JSONIArchive - : public IArchive - { - public: - JSONIArchive(); - ~JSONIArchive(); - - bool load(const char* filename); - bool open(const char* buffer, size_t length, bool free = false); - - // virtuals: - bool operator()(bool& value, const char* name = "", const char* label = 0); - bool operator()(IString& value, const char* name = "", const char* label = 0); - bool operator()(IWString& value, const char* name = "", const char* label = 0); - bool operator()(float& value, const char* name = "", const char* label = 0); - bool operator()(double& value, const char* name = "", const char* label = 0); - bool operator()(int16& value, const char* name = "", const char* label = 0); - bool operator()(uint16& value, const char* name = "", const char* label = 0); - bool operator()(int32& value, const char* name = "", const char* label = 0); - bool operator()(uint32& value, const char* name = "", const char* label = 0); - bool operator()(int64& value, const char* name = "", const char* label = 0); - bool operator()(uint64& value, const char* name = "", const char* label = 0); - - bool operator()(int8& value, const char* name = "", const char* label = 0); - bool operator()(uint8& value, const char* name = "", const char* label = 0); - bool operator()(char& value, const char* name = "", const char* label = 0); - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0); - bool operator()(const SBlackBox& ser, const char* name = "", const char* label = 0); - bool operator()(IContainer& ser, const char* name = "", const char* label = 0); - bool operator()(IKeyValue& ser, const char* name = "", const char* label = 0); - bool operator()(IPointer& ser, const char* name = "", const char* label = 0); - - using IArchive::operator(); - private: - bool findName(const char* name, Token* outName = 0); - bool openBracket(); - bool closeBracket(); - - bool openContainerBracket(); - bool closeContainerBracket(); - - void checkValueToken(); - bool checkStringValueToken(); - void readToken(); - void putToken(); - int line(const char* position) const; - bool isName(Token token) const; - - bool expect(char token); - void skipBlock(); - - struct Level - { - const char* start; - const char* firstToken; - bool isContainer; - bool isKeyValue; - Level() - : isContainer(false) - , isKeyValue(false) {} - }; - typedef std::vector Stack; - Stack stack_; - - std::unique_ptr reader_; - Token token_; - std::vector unescapeBuffer_; - string filename_; - void* buffer_; - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/JSONOArchive.cpp b/Code/CryEngine/CrySystem/Serialization/JSONOArchive.cpp deleted file mode 100644 index d1aef5601e..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/JSONOArchive.cpp +++ /dev/null @@ -1,828 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "JSONOArchive.h" -#include "MemoryWriter.h" -#include "Serialization/KeyValue.h" -#include "Serialization/ClassFactory.h" -#include "Serialization/BlackBox.h" -#include - -namespace Serialization { - // Some of non-latin1 characters here are not escaped to - // keep compatibility with 8-bit local encoding (e.g. windows-1251) - static const char* escapeTable[256] = { - "\\0" /* 0x00: */, - "\\x01" /* 0x01: */, - "\\x02" /* 0x02: */, - "\\x03" /* 0x03: */, - "\\x04" /* 0x04: */, - "\\x05" /* 0x05: */, - "\\x06" /* 0x06: */, - "\\x07" /* 0x07: */, - "\\x08" /* 0x08: */, - "\\t" /* 0x09: \t */, - "\\n" /* 0x0A: \n */, - "\\x0B" /* 0x0B: */, - "\\x0C" /* 0x0C: */, - "\\r" /* 0x0D: */, - "\\x0E" /* 0x0E: */, - "\\x0F" /* 0x0F: */, - - - "\\x10" /* 0x10: */, - "\\x11" /* 0x11: */, - "\\x12" /* 0x12: */, - "\\x13" /* 0x13: */, - "\\x14" /* 0x14: */, - "\\x15" /* 0x15: */, - "\\x16" /* 0x16: */, - "\\x17" /* 0x17: */, - "\\x18" /* 0x18: */, - "\\x19" /* 0x19: */, - "\\x1A" /* 0x1A: */, - "\\x1B" /* 0x1B: */, - "\\x1C" /* 0x1C: */, - "\\x1D" /* 0x1D: */, - "\\x1E" /* 0x1E: */, - "\\x1F" /* 0x1F: */, - - - " " /* 0x20: */, - "!" /* 0x21: ! */, - "\\\"" /* 0x22: " */, - "#" /* 0x23: # */, - "$" /* 0x24: $ */, - "%" /* 0x25: % */, - "&" /* 0x26: & */, - "'" /* 0x27: ' */, - "(" /* 0x28: ( */, - ")" /* 0x29: ) */, - "*" /* 0x2A: * */, - "+" /* 0x2B: + */, - "," /* 0x2C: , */, - "-" /* 0x2D: - */, - "." /* 0x2E: . */, - "/" /* 0x2F: / */, - - - "0" /* 0x30: 0 */, - "1" /* 0x31: 1 */, - "2" /* 0x32: 2 */, - "3" /* 0x33: 3 */, - "4" /* 0x34: 4 */, - "5" /* 0x35: 5 */, - "6" /* 0x36: 6 */, - "7" /* 0x37: 7 */, - "8" /* 0x38: 8 */, - "9" /* 0x39: 9 */, - ":" /* 0x3A: : */, - ";" /* 0x3B: ; */, - "<" /* 0x3C: < */, - "=" /* 0x3D: = */, - ">" /* 0x3E: > */, - "?" /* 0x3F: ? */, - - - "@" /* 0x40: @ */, - "A" /* 0x41: A */, - "B" /* 0x42: B */, - "C" /* 0x43: C */, - "D" /* 0x44: D */, - "E" /* 0x45: E */, - "F" /* 0x46: F */, - "G" /* 0x47: G */, - "H" /* 0x48: H */, - "I" /* 0x49: I */, - "J" /* 0x4A: J */, - "K" /* 0x4B: K */, - "L" /* 0x4C: L */, - "M" /* 0x4D: M */, - "N" /* 0x4E: N */, - "O" /* 0x4F: O */, - - - "P" /* 0x50: P */, - "Q" /* 0x51: Q */, - "R" /* 0x52: R */, - "S" /* 0x53: S */, - "T" /* 0x54: T */, - "U" /* 0x55: U */, - "V" /* 0x56: V */, - "W" /* 0x57: W */, - "X" /* 0x58: X */, - "Y" /* 0x59: Y */, - "Z" /* 0x5A: Z */, - "[" /* 0x5B: [ */, - "\\\\" /* 0x5C: \ */, - "]" /* 0x5D: ] */, - "^" /* 0x5E: ^ */, - "_" /* 0x5F: _ */, - - - "`" /* 0x60: ` */, - "a" /* 0x61: a */, - "b" /* 0x62: b */, - "c" /* 0x63: c */, - "d" /* 0x64: d */, - "e" /* 0x65: e */, - "f" /* 0x66: f */, - "g" /* 0x67: g */, - "h" /* 0x68: h */, - "i" /* 0x69: i */, - "j" /* 0x6A: j */, - "k" /* 0x6B: k */, - "l" /* 0x6C: l */, - "m" /* 0x6D: m */, - "n" /* 0x6E: n */, - "o" /* 0x6F: o */, - - - "p" /* 0x70: p */, - "q" /* 0x71: q */, - "r" /* 0x72: r */, - "s" /* 0x73: s */, - "t" /* 0x74: t */, - "u" /* 0x75: u */, - "v" /* 0x76: v */, - "w" /* 0x77: w */, - "x" /* 0x78: x */, - "y" /* 0x79: y */, - "z" /* 0x7A: z */, - "{" /* 0x7B: { */, - "|" /* 0x7C: | */, - "}" /* 0x7D: } */, - "~" /* 0x7E: ~ */, - "\x7F" /* 0x7F: */, // for utf-8 - - - "\x80" /* 0x80: */, - "\x81" /* 0x81: */, - "\x82" /* 0x82: */, - "\x83" /* 0x83: */, - "\x84" /* 0x84: */, - "\x85" /* 0x85: */, - "\x86" /* 0x86: */, - "\x87" /* 0x87: */, - "\x88" /* 0x88: */, - "\x89" /* 0x89: */, - "\x8A" /* 0x8A: */, - "\x8B" /* 0x8B: */, - "\x8C" /* 0x8C: */, - "\x8D" /* 0x8D: */, - "\x8E" /* 0x8E: */, - "\x8F" /* 0x8F: */, - - - "\x90" /* 0x90: */, - "\x91" /* 0x91: */, - "\x92" /* 0x92: */, - "\x93" /* 0x93: */, - "\x94" /* 0x94: */, - "\x95" /* 0x95: */, - "\x96" /* 0x96: */, - "\x97" /* 0x97: */, - "\x98" /* 0x98: */, - "\x99" /* 0x99: */, - "\x9A" /* 0x9A: */, - "\x9B" /* 0x9B: */, - "\x9C" /* 0x9C: */, - "\x9D" /* 0x9D: */, - "\x9E" /* 0x9E: */, - "\x9F" /* 0x9F: */, - - - "\xA0" /* 0xA0: */, - "\xA1" /* 0xA1: */, - "\xA2" /* 0xA2: */, - "\xA3" /* 0xA3: */, - "\xA4" /* 0xA4: */, - "\xA5" /* 0xA5: */, - "\xA6" /* 0xA6: */, - "\xA7" /* 0xA7: */, - "\xA8" /* 0xA8: */, - "\xA9" /* 0xA9: */, - "\xAA" /* 0xAA: */, - "\xAB" /* 0xAB: */, - "\xAC" /* 0xAC: */, - "\xAD" /* 0xAD: */, - "\xAE" /* 0xAE: */, - "\xAF" /* 0xAF: */, - - - "\xB0" /* 0xB0: */, - "\xB1" /* 0xB1: */, - "\xB2" /* 0xB2: */, - "\xB3" /* 0xB3: */, - "\xB4" /* 0xB4: */, - "\xB5" /* 0xB5: */, - "\xB6" /* 0xB6: */, - "\xB7" /* 0xB7: */, - "\xB8" /* 0xB8: */, - "\xB9" /* 0xB9: */, - "\xBA" /* 0xBA: */, - "\xBB" /* 0xBB: */, - "\xBC" /* 0xBC: */, - "\xBD" /* 0xBD: */, - "\xBE" /* 0xBE: */, - "\xBF" /* 0xBF: */, - - - "\xC0" /* 0xC0: */, - "\xC1" /* 0xC1: */, - "\xC2" /* 0xC2: */, - "\xC3" /* 0xC3: */, - "\xC4" /* 0xC4: */, - "\xC5" /* 0xC5: */, - "\xC6" /* 0xC6: */, - "\xC7" /* 0xC7: */, - "\xC8" /* 0xC8: */, - "\xC9" /* 0xC9: */, - "\xCA" /* 0xCA: */, - "\xCB" /* 0xCB: */, - "\xCC" /* 0xCC: */, - "\xCD" /* 0xCD: */, - "\xCE" /* 0xCE: */, - "\xCF" /* 0xCF: */, - - - "\xD0" /* 0xD0: */, - "\xD1" /* 0xD1: */, - "\xD2" /* 0xD2: */, - "\xD3" /* 0xD3: */, - "\xD4" /* 0xD4: */, - "\xD5" /* 0xD5: */, - "\xD6" /* 0xD6: */, - "\xD7" /* 0xD7: */, - "\xD8" /* 0xD8: */, - "\xD9" /* 0xD9: */, - "\xDA" /* 0xDA: */, - "\xDB" /* 0xDB: */, - "\xDC" /* 0xDC: */, - "\xDD" /* 0xDD: */, - "\xDE" /* 0xDE: */, - "\xDF" /* 0xDF: */, - - - "\xE0" /* 0xE0: */, - "\xE1" /* 0xE1: */, - "\xE2" /* 0xE2: */, - "\xE3" /* 0xE3: */, - "\xE4" /* 0xE4: */, - "\xE5" /* 0xE5: */, - "\xE6" /* 0xE6: */, - "\xE7" /* 0xE7: */, - "\xE8" /* 0xE8: */, - "\xE9" /* 0xE9: */, - "\xEA" /* 0xEA: */, - "\xEB" /* 0xEB: */, - "\xEC" /* 0xEC: */, - "\xED" /* 0xED: */, - "\xEE" /* 0xEE: */, - "\xEF" /* 0xEF: */, - - - "\xF0" /* 0xF0: */, - "\xF1" /* 0xF1: */, - "\xF2" /* 0xF2: */, - "\xF3" /* 0xF3: */, - "\xF4" /* 0xF4: */, - "\xF5" /* 0xF5: */, - "\xF6" /* 0xF6: */, - "\xF7" /* 0xF7: */, - "\xF8" /* 0xF8: */, - "\xF9" /* 0xF9: */, - "\xFA" /* 0xFA: */, - "\xFB" /* 0xFB: */, - "\xFC" /* 0xFC: */, - "\xFD" /* 0xFD: */, - "\xFE" /* 0xFE: */, - "\xFF" /* 0xFF: */ - }; - - static void escapeString(MemoryWriter& dest, const char* begin, const char* end) - { - while (begin != end) - { - const char* str = escapeTable[(unsigned char)(*begin)]; - dest.write(str); - ++begin; - } - } - - // --------------------------------------------------------------------------- - - static const int TAB_WIDTH = 2; - - JSONOArchive::JSONOArchive(int textWidth, const char* header) - : IArchive(OUTPUT | TEXT) - , header_(header) - , textWidth_(textWidth) - , compactOffset_(0) - { - buffer_.reset(new MemoryWriter(1024, true)); - if (header_) - { - (*buffer_) << header_; - } - - YASLI_ASSERT(stack_.empty()); - stack_.push_back(Level(false, 0, 0)); - } - - JSONOArchive::~JSONOArchive() - { - } - - bool JSONOArchive::save(const char* fileName) - { - YASLI_ESCAPE(fileName && strlen(fileName) > 0, return false); - YASLI_ESCAPE(stack_.size() == 1, return false); - YASLI_ESCAPE(buffer_.get() != 0, return false); - YASLI_ESCAPE(buffer_->position() <= buffer_->size(), return false); - stack_.pop_back(); - FILE* file = nullptr; - azfopen(&file, fileName, "wb"); - if (file) - { - if (fwrite(buffer_->c_str(), 1, buffer_->position(), file) != buffer_->position()) - { - fclose(file); - return false; - } - fclose(file); - return true; - } - else - { - return false; - } - } - - const char* JSONOArchive::c_str() const - { - return buffer_->c_str(); - } - - size_t JSONOArchive::length() const - { - return buffer_->position(); - } - - void JSONOArchive::openBracket() - { - *buffer_ << "{"; - } - - void JSONOArchive::closeBracket() - { - *buffer_ << "}"; - } - - void JSONOArchive::openContainerBracket() - { - *buffer_ << "["; - } - - void JSONOArchive::closeContainerBracket() - { - *buffer_ << "]"; - } - - void JSONOArchive::placeName(const char* name) - { - if (stack_.back().isKeyValue) - { - return; - } - if ((name[0] != '\0' || !stack_.back().isContainer) && stack_.size() > 1) - { - *buffer_ << "\""; - *buffer_ << name; - *buffer_ << "\": "; - stack_.back().nameIndex += 1; - } - } - - void JSONOArchive::placeIndent(bool putComma) - { - if (stack_.back().isKeyValue) - { - return; - } - if (putComma && stack_.back().elementIndex > 0) - { - *buffer_ << ","; - } - if (buffer_->position() > 0) - { - *buffer_ << "\n"; - } - int count = int(stack_.size() - 1); - stack_.back().indentCount += count; - stack_.back().elementIndex += 1; - for (int i = 0; i < count; ++i) - { - *buffer_ << "\t"; - } - compactOffset_ = 0; - } - - void JSONOArchive::placeIndentCompact(bool putComma) - { - if (stack_.back().isKeyValue) - { - return; - } - if (putComma && stack_.back().elementIndex > 0) - { - *buffer_ << ","; - } - if ((compactOffset_ % 32) != 0 && stack_.back().isContainer) - { - *buffer_ << " "; - compactOffset_ += 1; - stack_.back().elementIndex += 1; - } - else if (buffer_->size()) - { - *buffer_ << "\n"; - int count = int(stack_.size() - 1); - stack_.back().indentCount += count /* * TAB_WIDTH*/; - stack_.back().elementIndex += 1; - for (int i = 0; i < count; ++i) - { - *buffer_ << "\t"; - } - compactOffset_ = 1; - } - } - - bool JSONOArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - *buffer_ << (value ? "true" : "false"); - return true; - } - - - bool JSONOArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - (*buffer_) << "\""; - const char* str = value.get(); - escapeString(*buffer_, str, str + strlen(value.get())); - (*buffer_) << "\""; - return true; - } - - inline char* writeUtf16ToUtf8(char* s, unsigned int ch) - { - const unsigned char byteMark = 0x80; - const unsigned char byteMask = 0xBF; - - size_t len; - - if (ch < 0x80) - { - len = 1; - } - else if (ch < 0x800) - { - len = 2; - } - else if (ch < 0x10000) - { - len = 3; - } - else if (ch < 0x200000) - { - len = 4; - } - else - { - return s; - } - - s += len; - - const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - switch (len) - { - case 4: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 3: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 2: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 1: - *--s = (char)(ch | firstByteMark[len]); - } - - return s + len; - } - - bool JSONOArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - (*buffer_) << "\""; - - const wchar_t* in = value.get(); - for (; *in; ++in) - { - char buf[6]; - escapeString(*buffer_, buf, writeUtf16ToUtf8(buf, *in)); - } - - (*buffer_) << "\""; - return true; - } - - bool JSONOArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - std::size_t position = buffer_->position(); - openBracket(); - stack_.push_back(Level(false, position, int(strlen(name) + 2 * (name[0] & 1) + (stack_.size() - 1) * TAB_WIDTH + 2))); - - YASLI_ASSERT(ser); - ser(*this); - - bool joined = joinLinesIfPossible(); - bool noNames = stack_.back().nameIndex == 0; - if (noNames) - { - if (stack_.size() != 2) - { - buffer_->buffer()[stack_.back().startPosition] = '['; - } - } - stack_.pop_back(); - if (!joined) - { - placeIndent(false); - } - else - { - *buffer_ << " "; - } - if (noNames) - { - closeContainerBracket(); - } - else - { - closeBracket(); - } - return true; - } - - bool JSONOArchive::operator()(const SBlackBox& box, const char* name, [[maybe_unused]] const char* label) - { - if (strcmp(box.format, "json") != 0) - { - return false; - } - if (box.size == 0) - { - return false; - } - - placeIndent(); - placeName(name); - return buffer_->write(box.data, box.size); - } - - bool JSONOArchive::operator()(IKeyValue& keyValue, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - - *buffer_ << "\""; - *buffer_ << keyValue.get(); - *buffer_ << "\": "; - stack_.back().nameIndex += 1; - - stack_.back().isKeyValue = true; - keyValue.serializeValue(*this, "", 0); - stack_.back().isKeyValue = false; - if (stack_.back().isContainer) - { - stack_.back().isDictionary = true; - } - return true; - } - - bool JSONOArchive::operator()(IPointer& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - openBracket(); - const char* registeredTypeName = ser.registeredTypeName(); - if (registeredTypeName && registeredTypeName[0] != '\0') - { - *buffer_ << " "; - placeName(registeredTypeName); - stack_.back().isKeyValue = true; - operator()(ser.serializer(), ""); - stack_.back().isKeyValue = false; - *buffer_ << " "; - } - closeBracket(); - return true; - } - - bool JSONOArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - std::size_t position = buffer_->position(); - openContainerBracket(); - stack_.push_back(Level(true, position, int(strlen(name) + 2 * (name[0] & 1) + stack_.size() - 1 * TAB_WIDTH + 2))); - - std::size_t size = ser.size(); - if (size > 0) - { - do - { - ser(*this, "", ""); - } while (ser.next()); - } - - bool joined = joinLinesIfPossible(); - bool isDictionary = stack_.back().isDictionary; - if (isDictionary) - { - buffer_->buffer()[stack_.back().startPosition] = '{'; - } - stack_.pop_back(); - if (!joined) - { - placeIndent(false); - } - else - { - *buffer_ << " "; - } - - if (isDictionary) - { - closeBracket(); - } - else - { - closeContainerBracket(); - } - return true; - } - - static char* joinLines(char* start, char* end) - { - YASLI_ASSERT(start <= end); - char* next = start; - while (next != end) - { - if (*next != '\t' && *next != '\r') - { - if (*next != '\n') - { - *start = *next; - } - else - { - *start = ' '; - } - ++start; - } - ++next; - } - return start; - } - - bool JSONOArchive::joinLinesIfPossible() - { - YASLI_ASSERT(!stack_.empty()); - std::size_t startPosition = stack_.back().startPosition; - YASLI_ASSERT(startPosition < buffer_->size()); - int indentCount = stack_.back().indentCount; - //YASLI_ASSERT(startPosition >= indentCount); - if (buffer_->position() - startPosition - indentCount < std::size_t(textWidth_)) - { - char* buffer = buffer_->buffer(); - char* start = buffer + startPosition; - char* end = buffer + buffer_->position(); - end = joinLines(start, end); - std::size_t newPosition = end - buffer; - YASLI_ASSERT(newPosition <= buffer_->position()); - buffer_->setPosition(newPosition); - return true; - } - return false; - } -} -// vim:ts=4 sw=4: diff --git a/Code/CryEngine/CrySystem/Serialization/JSONOArchive.h b/Code/CryEngine/CrySystem/Serialization/JSONOArchive.h deleted file mode 100644 index 5701c992ac..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/JSONOArchive.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include "Serialization/IArchive.h" -#include "Serialization/MemoryWriter.h" - -namespace Serialization { - class MemoryWriter; - - class JSONOArchive - : public IArchive - { - public: - // header = 0 - default header, use "" to omit - JSONOArchive(int textWidth = 80, const char* header = 0); - ~JSONOArchive(); - - bool save(const char* fileName); - - const char* c_str() const; - const char* buffer() const { return c_str(); } - size_t length() const; - - // from Archive: - bool operator()(bool& value, const char* name = "", const char* label = 0); - bool operator()(IString& value, const char* name = "", const char* label = 0); - bool operator()(IWString& value, const char* name = "", const char* label = 0); - bool operator()(float& value, const char* name = "", const char* label = 0); - bool operator()(double& value, const char* name = "", const char* label = 0); - bool operator()(int16& value, const char* name = "", const char* label = 0); - bool operator()(uint16& value, const char* name = "", const char* label = 0); - bool operator()(int32& value, const char* name = "", const char* label = 0); - bool operator()(uint32& value, const char* name = "", const char* label = 0); - bool operator()(int64& value, const char* name = "", const char* label = 0); - bool operator()(uint64& value, const char* name = "", const char* label = 0); - - bool operator()(char& value, const char* name = "", const char* label = 0); - bool operator()(int8& value, const char* name = "", const char* label = 0); - bool operator()(uint8& value, const char* name = "", const char* label = 0); - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0); - bool operator()(const SBlackBox& box, const char* name = "", const char* label = 0); - bool operator()(IContainer& ser, const char* name = "", const char* label = 0); - bool operator()(IKeyValue& keyValue, const char* name = "", const char* label = 0); - bool operator()(IPointer& ser, const char* name = "", const char* label = 0); - // ^^^ - - using IArchive::operator(); - private: - void openBracket(); - void closeBracket(); - void openContainerBracket(); - void closeContainerBracket(); - void placeName(const char* name); - void placeIndent(bool putComma = true); - void placeIndentCompact(bool putComma = true); - - bool joinLinesIfPossible(); - - struct Level - { - Level(bool _isContainer, std::size_t position, int column) - : isKeyValue(false) - , isContainer(_isContainer) - , isDictionary(false) - , startPosition(position) - , nameIndex(0) - , elementIndex(0) - , indentCount(-column) - {} - bool isKeyValue; - bool isContainer; - bool isDictionary; - std::size_t startPosition; - int nameIndex; - int elementIndex; - int indentCount; - }; - - typedef std::vector Stack; - Stack stack_; - std::unique_ptr buffer_; - const char* header_; - int textWidth_; - string fileName_; - int compactOffset_; - bool isKeyValue_; - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/MemoryReader.cpp b/Code/CryEngine/CrySystem/Serialization/MemoryReader.cpp deleted file mode 100644 index ee424d065f..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/MemoryReader.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include "Serialization/Assert.h" -#include "MemoryReader.h" -#include -#include - -namespace Serialization { - MemoryReader::MemoryReader() - : size_(0) - , position_(0) - , memory_(0) - , ownedMemory_(false) - { - } - - - MemoryReader::MemoryReader(const void* memory, std::size_t size, bool ownAndFree) - : size_(size) - , position_((const char*)(memory)) - , memory_((const char*)(memory)) - , ownedMemory_(ownAndFree) - { - } - - MemoryReader::~MemoryReader() - { - if (ownedMemory_) - { - free(const_cast(memory_)); - memory_ = 0; - size_ = 0; - } - } - - void MemoryReader::setPosition(const char* position) - { - position_ = position; - } - - void MemoryReader::read(void* data, std::size_t size) - { - YASLI_ASSERT(memory_ && position_); - YASLI_ASSERT(position_ - memory_ + size <= size_); - memcpy(data, position_, size); - position_ += size; - } - - bool MemoryReader::checkedRead(void* data, std::size_t size) - { - if (!memory_ || !position_) - { - return false; - } - if (position_ - memory_ + size > size_) - { - return false; - } - - memcpy(data, position_, size); - position_ += size; - return true; - } - - bool MemoryReader::checkedSkip(std::size_t size) - { - if (!memory_ || !position_) - { - return false; - } - if (position_ - memory_ + size > size_) - { - return false; - } - - position_ += size; - return true; - } -} diff --git a/Code/CryEngine/CrySystem/Serialization/MemoryReader.h b/Code/CryEngine/CrySystem/Serialization/MemoryReader.h deleted file mode 100644 index 88ae1d0060..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/MemoryReader.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -namespace Serialization { - class MemoryReader - { - public: - - MemoryReader(); - MemoryReader(const void* memory, size_t size, bool ownAndFree = false); - ~MemoryReader(); - - void setPosition(const char* position); - const char* position(){ return position_; } - - template - void read(T& value) - { - read(reinterpret_cast(&value), sizoef(value)); - } - void read(void* data, size_t size); - bool checkedSkip(size_t size); - bool checkedRead(void* data, size_t size); - template - bool checkedRead(T& t) - { - return checkedRead((void*)&t, sizeof(t)); - } - - const char* buffer() const{ return memory_; } - size_t size() const{ return size_; } - - const char* begin() const{ return memory_; } - const char* end() const{ return memory_ + size_; } - private: - size_t size_; - const char* position_; - const char* memory_; - bool ownedMemory_; - }; -} -// vim:ts=4 sw=4: diff --git a/Code/CryEngine/CrySystem/Serialization/MemoryWriter.cpp b/Code/CryEngine/CrySystem/Serialization/MemoryWriter.cpp deleted file mode 100644 index c426119812..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/MemoryWriter.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include "Serialization/Assert.h" -#include -#include -#include -#include -#ifdef _MSC_VER -# include -# define isnan _isnan -#endif - -#include "MemoryWriter.h" - -#undef YASLI_ASSERT -#define YASLI_ASSERT(x) - -namespace Serialization { - MemoryWriter::MemoryWriter(std::size_t size, bool reallocate) - : size_(size) - , reallocate_(reallocate) - , digits_(5) - { - allocate(size); - } - - MemoryWriter::~MemoryWriter() - { - position_ = 0; - CryModuleFree(memory_); - } - - void MemoryWriter::allocate(std::size_t initialSize) - { - memory_ = (char*)CryModuleMalloc(initialSize + 1); - position_ = memory_; - } - - void MemoryWriter::reallocate(std::size_t newSize) - { - YASLI_ASSERT(newSize > size_); - std::size_t pos = position(); - // Supressing the warning as we generally don't handle malloc errors. - // cppcheck-suppress memleakOnRealloc - memory_ = (char*)CryModuleRealloc(memory_, newSize + 1); - YASLI_ASSERT(memory_ != 0); - position_ = memory_ + pos; - size_ = newSize; - } - - MemoryWriter& MemoryWriter::operator<<(int value) - { - // TODO: optimize - char buffer[12]; - sprintf_s(buffer, "%i", value); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(long value) - { - // TODO: optimize - char buffer[12]; -#ifdef _MSC_VER - sprintf_s(buffer, "%i", value); -#else - sprintf_s(buffer, "%li", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned long value) - { - // TODO: optimize - char buffer[12]; -#ifdef _MSC_VER - sprintf_s(buffer, "%u", value); -#else - sprintf_s(buffer, "%lu", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(long long value) - { - // TODO: optimize - char buffer[24]; -#ifdef _MSC_VER - sprintf_s(buffer, "%I64i", value); -#else - sprintf_s(buffer, "%lli", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned long long value) - { - // TODO: optimize - char buffer[24]; - sprintf_s(buffer, "%llu", value); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned int value) - { - // TODO: optimize - char buffer[12]; - sprintf_s(buffer, "%u", value); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(signed char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - inline void cutRightZeros(const char* str) - { - for (char* p = (char*)str + strlen(str) - 1; p >= str; --p) - { - if (*p == '0') - { - *p = 0; - } - else - { - return; - } - } - } - - MemoryWriter& MemoryWriter::operator<<(double value) - { - YASLI_ASSERT(!isnan(value)); - - char buf[64] = { 0 }; - sprintf_s(buf, "%f", value); - operator<<(buf); - return *this; - } - - MemoryWriter& MemoryWriter::operator<<(const char* value) - { - write((void*)value, strlen(value)); - YASLI_ASSERT(position() < size()); - *position_ = '\0'; - return *this; - } - - MemoryWriter& MemoryWriter::operator<<(const wchar_t* value) - { - write((void*)value, wcslen(value) * sizeof(wchar_t)); - YASLI_ASSERT(position() < size()); - *position_ = '\0'; - return *this; - } - - void MemoryWriter::setPosition(std::size_t pos) - { - YASLI_ASSERT(pos < size_); - YASLI_ASSERT(memory_ + pos <= position_); - position_ = memory_ + pos; - } - - void MemoryWriter::write(const char* value) - { - write((void*)value, strlen(value)); - } - - bool MemoryWriter::write(const void* data, std::size_t size) - { - YASLI_ASSERT(memory_ <= position_); - YASLI_ASSERT(position() < this->size()); - if (size_ - position() > size) - { - memcpy(position_, data, size); - position_ += size; - } - else - { - if (!reallocate_) - { - return false; - } - - reallocate(size_ * 2); - write(data, size); - } - YASLI_ASSERT(position() < this->size()); - return true; - } - - void MemoryWriter::write(char c) - { - if (size_ - position() > 1) - { - *(char*)(position_) = c; - ++position_; - } - else - { - YASLI_ESCAPE(reallocate_, return ); - reallocate(size_ * 2); - write(c); - } - YASLI_ASSERT(position() < this->size()); - } -} diff --git a/Code/CryEngine/CrySystem/Serialization/MemoryWriter.h b/Code/CryEngine/CrySystem/Serialization/MemoryWriter.h deleted file mode 100644 index 314a39c2d8..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/MemoryWriter.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -namespace Serialization { - class MemoryWriter - { - public: - MemoryWriter(std::size_t size = 128, bool reallocate = true); - ~MemoryWriter(); - - const char* c_str() { return memory_; }; - const wchar_t* w_str() { return (wchar_t*)memory_; }; - char* buffer() { return memory_; } - const char* buffer() const { return memory_; } - std::size_t size() const{ return size_; } - void clear() { position_ = memory_; } - - // String interface (after this calls '\0' is always written) - MemoryWriter& operator<<(int value); - MemoryWriter& operator<<(long value); - MemoryWriter& operator<<(unsigned long value); - MemoryWriter& operator<<(unsigned int value); - MemoryWriter& operator<<(long long value); - MemoryWriter& operator<<(unsigned long long value); - MemoryWriter& operator<<(float value) { return (*this) << double(value); } - MemoryWriter& operator<<(double value); - MemoryWriter& operator<<(signed char value); - MemoryWriter& operator<<(unsigned char value); - MemoryWriter& operator<<(char value); - MemoryWriter& operator<<(const char* value); - MemoryWriter& operator<<(const wchar_t* value); - - // Binary interface (does not writes trailing '\0') - template - void write(const T& value) - { - write(reinterpret_cast(&value), sizeof(value)); - } - void write(char c); - void write(const char* str); - bool write(const void* data, std::size_t size); - - std::size_t position() const{ return position_ - memory_; } - void setPosition(std::size_t pos); - - MemoryWriter& setDigits(int digits) { digits_ = (unsigned char)digits; return *this; } - - private: - void allocate(std::size_t initialSize); - void reallocate(std::size_t newSize); - - std::size_t size_; - char* position_; - char* memory_; - bool reallocate_; - unsigned char digits_; - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/Test_ArchiveHost.cpp b/Code/CryEngine/CrySystem/Serialization/Test_ArchiveHost.cpp deleted file mode 100644 index 9608da72c6..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/Test_ArchiveHost.cpp +++ /dev/null @@ -1,492 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include - -#include - -#include "ArchiveHost.h" -#include -#include -#include -#include -#include - -namespace Serialization -{ - struct SMember - { - string name; - float weight; - - SMember() - : weight(0.0f) - {} - - void CheckEquality(const SMember& copy) const - { - EXPECT_TRUE(name == copy.name); - EXPECT_TRUE(weight == copy.weight); - } - - void Change(int index) - { - name = "Changed name "; - name += (index % 10) + '0'; - weight = float(index); - } - - void Serialize(IArchive& ar) - { - ar(name, "name"); - ar(weight, "weight"); - } - }; - - class CPolyBase - : public _i_reference_target_t - { - public: - CPolyBase() - { - baseMember = "Regular base member"; - } - - virtual void Change() - { - baseMember = "Changed base member"; - } - - virtual void Serialize(IArchive& ar) - { - ar(baseMember, "baseMember"); - } - - virtual void CheckEquality(const CPolyBase* copy) const - { - EXPECT_TRUE(baseMember == copy->baseMember); - } - - virtual bool IsDerivedA() const - { - return false; - } - virtual bool IsDerivedB() const - { - return false; - } - protected: - string baseMember; - }; - - class CPolyDerivedA - : public CPolyBase - { - public: - void Serialize(IArchive& ar) - { - CPolyBase::Serialize(ar); - ar(derivedMember, "derivedMember"); - } - - bool IsDerivedA() const override - { - return true; - } - - void CheckEquality(const CPolyBase* copyBase) const - { - EXPECT_TRUE(copyBase->IsDerivedA()); - const CPolyDerivedA* copy = (CPolyDerivedA*)copyBase; - EXPECT_TRUE(derivedMember == copy->derivedMember); - - CPolyBase::CheckEquality(copyBase); - } - protected: - string derivedMember; - }; - - class CPolyDerivedB - : public CPolyBase - { - public: - CPolyDerivedB() - : derivedMember("B Derived") - {} - - bool IsDerivedB() const override - { - return true; - } - - void Serialize(IArchive& ar) - { - CPolyBase::Serialize(ar); - ar(derivedMember, "derivedMember"); - } - - void CheckEquality(const CPolyBase* copyBase) const - { - EXPECT_TRUE(copyBase->IsDerivedB()); - const CPolyDerivedB* copy = (const CPolyDerivedB*)copyBase; - EXPECT_TRUE(derivedMember == copy->derivedMember); - - CPolyBase::CheckEquality(copyBase); - } - protected: - string derivedMember; - }; - - struct SNumericTypes - { - SNumericTypes() - : m_bool(false) - , m_char(0) - , m_int8(0) - , m_uint8(0) - , m_int16(0) - , m_uint16(0) - , m_int32(0) - , m_uint32(0) - , m_int64(0) - , m_uint64(0) - , m_float(0.0f) - , m_double(0.0) - {} - - void Change() - { - m_bool = true; - m_char = -1; - m_int8 = -2; - m_uint8 = 0xff - 3; - m_int16 = -6; - m_uint16 = 0xff - 7; - m_int32 = -4; - m_uint32 = -5; - m_int64 = -8ll; - m_uint64 = 9ull; - m_float = -10.0f; - m_double = -11.0; - } - - void Serialize(IArchive& ar) - { - ar(m_bool, "bool"); - ar(m_char, "char"); - ar(m_int8, "int8"); - ar(m_uint8, "uint8"); - ar(m_int16, "int16"); - ar(m_uint16, "uint16"); - ar(m_int32, "int32"); - ar(m_uint32, "uint32"); - ar(m_int64, "int64"); - ar(m_uint64, "uint64"); - ar(m_float, "float"); - ar(m_double, "double"); - } - - void CheckEquality(const SNumericTypes& rhs) const - { - EXPECT_TRUE(m_bool == rhs.m_bool); - EXPECT_TRUE(m_char == rhs.m_char); - EXPECT_TRUE(m_int8 == rhs.m_int8); - EXPECT_TRUE(m_uint8 == rhs.m_uint8); - EXPECT_TRUE(m_int16 == rhs.m_int16); - EXPECT_TRUE(m_uint16 == rhs.m_uint16); - EXPECT_TRUE(m_int32 == rhs.m_int32); - EXPECT_TRUE(m_uint32 == rhs.m_uint32); - EXPECT_TRUE(m_int64 == rhs.m_int64); - EXPECT_TRUE(m_uint64 == rhs.m_uint64); - EXPECT_TRUE(m_float == rhs.m_float); - EXPECT_TRUE(m_double == rhs.m_double); - } - - bool m_bool; - - char m_char; - int8 m_int8; - uint8 m_uint8; - - int16 m_int16; - uint16 m_uint16; - - int32 m_int32; - uint32 m_uint32; - - int64 m_int64; - uint64 m_uint64; - - float m_float; - double m_double; - }; - - class CComplexClass - { - public: - CComplexClass() - : index(0) - { - name = "Foo"; - stringList.push_back("Choice 1"); - stringList.push_back("Choice 2"); - stringList.push_back("Choice 3"); - - polyPtr.reset(new CPolyDerivedA()); - - polyVector.push_back(new CPolyDerivedB); - polyVector.push_back(new CPolyBase); - - SMember& a = stringToStructMap["a"]; - a.name = "A"; - SMember& b = stringToStructMap["b"]; - b.name = "B"; - - members.resize(13); - - intToString.push_back(std::make_pair(1, "one")); - intToString.push_back(std::make_pair(2, "two")); - intToString.push_back(std::make_pair(3, "three")); - stringToInt.push_back(std::make_pair("one", 1)); - stringToInt.push_back(std::make_pair("two", 2)); - stringToInt.push_back(std::make_pair("three", 3)); - } - - void Change() - { - name = "Slightly changed name"; - index = 2; - polyPtr.reset(new CPolyDerivedB()); - polyPtr->Change(); - - for (size_t i = 0; i < members.size(); ++i) - { - members[i].Change(int(i)); - } - - members.erase(members.begin()); - - for (size_t i = 0; i < polyVector.size(); ++i) - { - polyVector[i]->Change(); - } - - polyVector.resize(4); - polyVector.push_back(new CPolyBase()); - polyVector[4]->Change(); - - const size_t arrayLen = sizeof(array) / sizeof(array[0]); - for (size_t i = 0; i < arrayLen; ++i) - { - array[i].Change(int(arrayLen - i)); - } - - numericTypes.Change(); - - vectorOfStrings.push_back("str1"); - vectorOfStrings.push_back("2str"); - vectorOfStrings.push_back("thirdstr"); - - stringToStructMap.erase("a"); - SMember& c = stringToStructMap["c"]; - c.name = "C"; - - intToString.push_back(std::make_pair(4, "four")); - stringToInt.push_back(std::make_pair("four", 4)); - } - - void Serialize(IArchive& ar) - { - ar(name, "name"); - ar(polyPtr, "polyPtr"); - ar(polyVector, "polyVector"); - ar(members, "members"); - { - StringListValue value(stringList, stringList[index]); - ar(value, "stringList"); - index = value.index(); - if (index == -1) - { - index = 0; - } - } - ar(array, "array"); - ar(numericTypes, "numericTypes"); - ar(vectorOfStrings, "vectorOfStrings"); - ar(stringToInt, "stringToInt"); - } - - void CheckEquality(const CComplexClass& copy) const - { - EXPECT_TRUE(name == copy.name); - EXPECT_TRUE(index == copy.index); - - EXPECT_TRUE(polyPtr != 0); - EXPECT_TRUE(copy.polyPtr != 0); - polyPtr->CheckEquality(copy.polyPtr); - - EXPECT_TRUE(members.size() == copy.members.size()); - for (size_t i = 0; i < members.size(); ++i) - { - members[i].CheckEquality(copy.members[i]); - } - - EXPECT_TRUE(polyVector.size() == copy.polyVector.size()); - for (size_t i = 0; i < polyVector.size(); ++i) - { - if (polyVector[i] == 0) - { - EXPECT_TRUE(copy.polyVector[i] == 0); - continue; - } - EXPECT_TRUE(copy.polyVector[i] != 0); - polyVector[i]->CheckEquality(copy.polyVector[i]); - } - - const size_t arrayLen = sizeof(array) / sizeof(array[0]); - for (size_t i = 0; i < arrayLen; ++i) - { - array[i].CheckEquality(copy.array[i]); - } - - numericTypes.CheckEquality(copy.numericTypes); - - EXPECT_TRUE(stringToInt.size() == copy.stringToInt.size()); - for (size_t i = 0; i < stringToInt.size(); ++i) - { - EXPECT_TRUE(stringToInt[i] == copy.stringToInt[i]); - } - } - protected: - string name; - typedef std::vector Members; - std::vector vectorOfStrings; - std::vector > intToString; - std::vector > stringToInt; - Members members; - int32 index; - SNumericTypes numericTypes; - - StringListStatic stringList; - std::vector< _smart_ptr > polyVector; - _smart_ptr polyPtr; - - std::map stringToStructMap; - - SMember array[5]; - }; - - struct ArchiveHostTests - : ::testing::Test - { - public: - void SetUp() override - { - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - m_classFactoryRTTI = AZStd::make_unique(); - } - - void TearDown() - { - m_classFactoryRTTI.reset(); - - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - } - - struct ClassFactoryRTTI - { - ClassFactoryRTTI() - : CPolyBaseCPolyBase_DerivedDescription("base", "Base") - , CPolyBaseCPolyBase_Creator(&CPolyBaseCPolyBase_DerivedDescription) - , TypeCPolyBase_DerivedDescription("derived_a", "Derived A") - , TypeCPolyBase_Creator(&TypeCPolyBase_DerivedDescription) - , CPolyDerivedBCPolyBase_DerivedDescription("derived_b", "Derived B") - , CPolyDerivedBCPolyBase_Creator(&CPolyDerivedBCPolyBase_DerivedDescription) - {} - - ~ClassFactoryRTTI() - { - Serialization::ClassFactory::destroy(); - } - - const Serialization::TypeDescription CPolyBaseCPolyBase_DerivedDescription; - Serialization::ClassFactory::Creator CPolyBaseCPolyBase_Creator; - - const Serialization::TypeDescription TypeCPolyBase_DerivedDescription; - Serialization::ClassFactory::Creator TypeCPolyBase_Creator; - - const Serialization::TypeDescription CPolyDerivedBCPolyBase_DerivedDescription; - Serialization::ClassFactory::Creator CPolyDerivedBCPolyBase_Creator; - }; - AZStd::unique_ptr m_classFactoryRTTI; - }; - - TEST_F(ArchiveHostTests, JsonBasicTypes) - { - std::unique_ptr host(CreateArchiveHost()); - - DynArray bufChanged; - CComplexClass objChanged; - objChanged.Change(); - host->SaveJsonBuffer(bufChanged, SStruct(objChanged)); - EXPECT_TRUE(!bufChanged.empty()); - - DynArray bufResaved; - { - CComplexClass obj; - - EXPECT_TRUE(host->LoadJsonBuffer(SStruct(obj), bufChanged.data(), bufChanged.size())); - EXPECT_TRUE(host->SaveJsonBuffer(bufResaved, SStruct(obj))); - EXPECT_TRUE(!bufResaved.empty()); - - obj.CheckEquality(objChanged); - } - EXPECT_TRUE(bufChanged.size() == bufResaved.size()); - for (size_t i = 0; i < bufChanged.size(); ++i) - { - EXPECT_TRUE(bufChanged[i] == bufResaved[i]); - } - } - - TEST_F(ArchiveHostTests, BinBasicTypes) - { - std::unique_ptr host(CreateArchiveHost()); - - DynArray bufChanged; - CComplexClass objChanged; - objChanged.Change(); - host->SaveBinaryBuffer(bufChanged, SStruct(objChanged)); - EXPECT_TRUE(!bufChanged.empty()); - - DynArray bufResaved; - { - CComplexClass obj; - - EXPECT_TRUE(host->LoadBinaryBuffer(SStruct(obj), bufChanged.data(), bufChanged.size())); - EXPECT_TRUE(host->SaveBinaryBuffer(bufResaved, SStruct(obj))); - EXPECT_TRUE(!bufResaved.empty()); - - obj.CheckEquality(objChanged); - } - EXPECT_TRUE(bufChanged.size() == bufResaved.size()); - for (size_t i = 0; i < bufChanged.size(); ++i) - { - EXPECT_TRUE(bufChanged[i] == bufResaved[i]); - } - } -} - diff --git a/Code/CryEngine/CrySystem/Serialization/Token.h b/Code/CryEngine/CrySystem/Serialization/Token.h deleted file mode 100644 index 4f730054e4..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/Token.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -#include "Serialization/Strings.h" - -namespace Serialization { - struct Token - { - Token(const char* _str = 0) - : start(_str) - , end(_str ? _str + strlen(_str) : 0) - { - } - - Token(const char* _str, size_t _len) - : start(_str) - , end(_str + _len) {} - Token(const char* _start, const char* _end) - : start(_start) - , end(_end) {} - - void set(const char* _start, const char* _end) { start = _start; end = _end; } - std::size_t length() const{ return end - start; } - - bool operator==(const Token& rhs) const - { - if (length() != rhs.length()) - { - return false; - } - return memcmp(start, rhs.start, length()) == 0; - } - bool operator==(const string& rhs) const - { - if (length() != rhs.size()) - { - return false; - } - return memcmp(start, rhs.c_str(), length()) == 0; - } - - bool operator==(const char* text) const - { - if (strncmp(text, start, length()) == 0) - { - return text[length()] == '\0'; - } - return false; - } - bool operator!=(const char* text) const - { - if (strncmp(text, start, length()) == 0) - { - return text[length()] != '\0'; - } - return true; - } - bool operator==(char c) const - { - return length() == 1 && *start == c; - } - bool operator!=(char c) const - { - return length() != 1 || *start != c; - } - - operator bool() const{ - return start != end; - } - string str() const{ return string(start, end); } - - const char* start; - const char* end; - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/XmlIArchive.cpp b/Code/CryEngine/CrySystem/Serialization/XmlIArchive.cpp deleted file mode 100644 index 914b7857e0..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/XmlIArchive.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "CryExtension/Impl/ClassWeaver.h" - -#include -#include - -#include "XmlIArchive.h" - -#include -#include - -namespace XmlUtil -{ - int g_hintSuccess = 0; - int g_hintFail = 0; - - - XmlNodeRef FindChildNode(XmlNodeRef pParent, const int childIndexOverride, int& childIndexHint, const char* const name) - { - CRY_ASSERT(pParent); - - if (0 <= childIndexOverride) - { - CRY_ASSERT(childIndexOverride < pParent->getChildCount()); - return pParent->getChild(childIndexOverride); - } - else - { - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - CRY_ASSERT(0 <= childIndexHint); - - const int childCount = pParent->getChildCount(); - const bool hasValidChildHint = (childIndexHint < childCount); - if (hasValidChildHint) - { - XmlNodeRef pChildNode = pParent->getChild(childIndexHint); - if (pChildNode->isTag(name)) - { - g_hintSuccess++; - const int nextChildIndexHint = childIndexHint + 1; - childIndexHint = (nextChildIndexHint < childCount) ? nextChildIndexHint : 0; - return pChildNode; - } - else - { - g_hintFail++; - } - } - - for (int i = 0; i < childCount; ++i) - { - XmlNodeRef pChildNode = pParent->getChild(i); - if (pChildNode->isTag(name)) - { - const int nextChildIndexHint = i + 1; - childIndexHint = (nextChildIndexHint < childCount) ? nextChildIndexHint : 0; - return pChildNode; - } - } - } - return XmlNodeRef(); - } - - - template< typename T, typename TOut > - bool ReadChildNodeAs(XmlNodeRef pParent, const int childIndexOverride, int& childIndexHint, const char* const name, TOut& valueOut) - { - XmlNodeRef pChild = FindChildNode(pParent, childIndexOverride, childIndexHint, name); - if (pChild) - { - T tmp; - const bool readValueSuccess = pChild->getAttr("value", tmp); - if (readValueSuccess) - { - valueOut = tmp; - } - return readValueSuccess; - } - return false; - } - - - template< typename T > - bool ReadChildNode(XmlNodeRef pParent, const int childIndexOverride, int& childIndexHint, const char* const name, T& valueOut) - { - return ReadChildNodeAs< T >(pParent, childIndexOverride, childIndexHint, name, valueOut); - } -} - - -Serialization::CXmlIArchive::CXmlIArchive() - : IArchive(INPUT | NO_EMPTY_NAMES) - , m_childIndexOverride(-1) - , m_childIndexHint(0) -{ -} - - -Serialization::CXmlIArchive::CXmlIArchive(XmlNodeRef pRootNode) - : IArchive(INPUT | NO_EMPTY_NAMES) - , m_pRootNode(pRootNode) - , m_childIndexOverride(-1) - , m_childIndexHint(0) -{ - CRY_ASSERT(m_pRootNode); -} - - -Serialization::CXmlIArchive::~CXmlIArchive() -{ -} - - -void Serialization::CXmlIArchive::SetXmlNode(XmlNodeRef pNode) -{ - m_pRootNode = pNode; -} - - -XmlNodeRef Serialization::CXmlIArchive::GetXmlNode() const -{ - return m_pRootNode; -} - - -bool Serialization::CXmlIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) -{ - XmlNodeRef pChild = XmlUtil::FindChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name); - if (pChild) - { - const char* const stringValue = pChild->getAttr("value"); - if (stringValue) - { - value = (strcmp("true", stringValue) == 0); - value = value || (strcmp("1", stringValue) == 0); - return true; - } - return false; - } - return false; -} - - -bool Serialization::CXmlIArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) -{ - XmlNodeRef pChild = XmlUtil::FindChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name); - if (pChild) - { - const char* const stringValue = pChild->getAttr("value"); - if (stringValue) - { - value.set(stringValue); - return true; - } - return false; - } - return false; -} - - -bool Serialization::CXmlIArchive::operator()([[maybe_unused]] IWString& value, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) -{ - CryFatalError("CXmlIArchive::operator() with IWString is not implemented"); - return false; -} - - -bool Serialization::CXmlIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< int >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< uint >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< int >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< uint >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< int >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - XmlNodeRef pChild = XmlUtil::FindChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name); - if (pChild) - { - CXmlIArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - const bool serializeSuccess = ser(childArchive); - return serializeSuccess; - } - return false; -} - - -bool Serialization::CXmlIArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) -{ - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - bool serializeSuccess = true; - - XmlNodeRef pChild = XmlUtil::FindChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name); - if (pChild) - { - const int elementCount = pChild->getChildCount(); - ser.resize(elementCount); - - if (0 < elementCount) - { - CXmlIArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - for (int i = 0; i < elementCount; ++i) - { - childArchive.m_childIndexOverride = i; - - serializeSuccess &= ser(childArchive, "Element", "Element"); - ser.next(); - } - } - } - - return serializeSuccess; -} diff --git a/Code/CryEngine/CrySystem/Serialization/XmlIArchive.h b/Code/CryEngine/CrySystem/Serialization/XmlIArchive.h deleted file mode 100644 index dd23febef6..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/XmlIArchive.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __XML_I_ARCHIVE__H__ -#define __XML_I_ARCHIVE__H__ - -#include - -namespace Serialization -{ - class CXmlIArchive - : public IArchive - { - public: - CXmlIArchive(); - CXmlIArchive(XmlNodeRef pRootNode); - ~CXmlIArchive(); - - void SetXmlNode(XmlNodeRef pNode); - XmlNodeRef GetXmlNode() const; - - // IArchive - bool operator()(bool& value, const char* name = "", const char* label = 0) override; - bool operator()(IString& value, const char* name = "", const char* label = 0) override; - bool operator()(IWString& value, const char* name = "", const char* label = 0) override; - bool operator()(float& value, const char* name = "", const char* label = 0) override; - bool operator()(double& value, const char* name = "", const char* label = 0) override; - bool operator()(int16& value, const char* name = "", const char* label = 0) override; - bool operator()(uint16& value, const char* name = "", const char* label = 0) override; - bool operator()(int32& value, const char* name = "", const char* label = 0) override; - bool operator()(uint32& value, const char* name = "", const char* label = 0) override; - bool operator()(int64& value, const char* name = "", const char* label = 0) override; - bool operator()(uint64& value, const char* name = "", const char* label = 0) override; - - bool operator()(int8& value, const char* name = "", const char* label = 0) override; - bool operator()(uint8& value, const char* name = "", const char* label = 0) override; - bool operator()(char& value, const char* name = "", const char* label = 0) override; - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0) override; - bool operator()(IContainer& ser, const char* name = "", const char* label = 0) override; - // ~IArchive - - using IArchive::operator(); - - private: - XmlNodeRef m_pRootNode; - int m_childIndexOverride; - int m_childIndexHint; - }; -} - -#endif diff --git a/Code/CryEngine/CrySystem/Serialization/XmlOArchive.cpp b/Code/CryEngine/CrySystem/Serialization/XmlOArchive.cpp deleted file mode 100644 index 1133a7e51e..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/XmlOArchive.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "CryExtension/Impl/ClassWeaver.h" - -#include -#include - -#include "XmlOArchive.h" - -#include -#include - -namespace XmlUtil -{ - XmlNodeRef CreateChildNode(XmlNodeRef pParent, const char* const name) - { - CRY_ASSERT(pParent); - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - XmlNodeRef pChild = pParent->createNode(name); - CRY_ASSERT(pChild); - - pParent->addChild(pChild); - return pChild; - } - - template < typename T, typename TIn > - bool WriteChildNodeAs(XmlNodeRef pParent, const char* const name, const TIn& value) - { - XmlNodeRef pChild = XmlUtil::CreateChildNode(pParent, name); - CRY_ASSERT(pChild); - - pChild->setAttr("value", static_cast< T >(value)); - return true; - } - - template < typename T > - bool WriteChildNode(XmlNodeRef pParent, const char* const name, const T& value) - { - return WriteChildNodeAs< T >(pParent, name, value); - } -} - -Serialization::CXmlOArchive::CXmlOArchive() - : IArchive(OUTPUT | NO_EMPTY_NAMES) -{ -} - - -Serialization::CXmlOArchive::CXmlOArchive(XmlNodeRef pRootNode) - : IArchive(OUTPUT | NO_EMPTY_NAMES) - , m_pRootNode(pRootNode) -{ - CRY_ASSERT(m_pRootNode); -} - - -Serialization::CXmlOArchive::~CXmlOArchive() -{ -} - - -void Serialization::CXmlOArchive::SetXmlNode(XmlNodeRef pNode) -{ - m_pRootNode = pNode; -} - - -XmlNodeRef Serialization::CXmlOArchive::GetXmlNode() const -{ - return m_pRootNode; -} - - -bool Serialization::CXmlOArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) -{ - const char* const stringValue = value ? "true" : "false"; - return XmlUtil::WriteChildNode(m_pRootNode, name, stringValue); -} - - -bool Serialization::CXmlOArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) -{ - const char* const stringValue = value.get(); - return XmlUtil::WriteChildNode(m_pRootNode, name, stringValue); -} - - -bool Serialization::CXmlOArchive::operator()([[maybe_unused]] IWString& value, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) -{ - CryFatalError("CXmlOArchive::operator() with IWString is not implemented"); - return false; -} - - -bool Serialization::CXmlOArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< int >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< uint >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< int >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< uint >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< int >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - XmlNodeRef pChild = XmlUtil::CreateChildNode(m_pRootNode, name); - CXmlOArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - const bool serializeSuccess = ser(childArchive); - - return serializeSuccess; -} - - -bool Serialization::CXmlOArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) -{ - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - bool serializeSuccess = true; - - XmlNodeRef pChild = XmlUtil::CreateChildNode(m_pRootNode, name); - CXmlOArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - const size_t containerSize = ser.size(); - if (0 < containerSize) - { - do - { - serializeSuccess &= ser(childArchive, "Element", "Element"); - } while (ser.next()); - } - - return serializeSuccess; -} diff --git a/Code/CryEngine/CrySystem/Serialization/XmlOArchive.h b/Code/CryEngine/CrySystem/Serialization/XmlOArchive.h deleted file mode 100644 index 4451d2ba75..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/XmlOArchive.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __XML_O_ARCHIVE__H__ -#define __XML_O_ARCHIVE__H__ - -#include - -namespace Serialization -{ - class CXmlOArchive - : public IArchive - { - public: - CXmlOArchive(); - CXmlOArchive(XmlNodeRef pRootNode); - ~CXmlOArchive(); - - void SetXmlNode(XmlNodeRef pNode); - XmlNodeRef GetXmlNode() const; - - // IArchive - bool operator()(bool& value, const char* name = "", const char* label = 0) override; - bool operator()(IString& value, const char* name = "", const char* label = 0) override; - bool operator()(IWString& value, const char* name = "", const char* label = 0) override; - bool operator()(float& value, const char* name = "", const char* label = 0) override; - bool operator()(double& value, const char* name = "", const char* label = 0) override; - bool operator()(int16& value, const char* name = "", const char* label = 0) override; - bool operator()(uint16& value, const char* name = "", const char* label = 0) override; - bool operator()(int32& value, const char* name = "", const char* label = 0) override; - bool operator()(uint32& value, const char* name = "", const char* label = 0) override; - bool operator()(int64& value, const char* name = "", const char* label = 0) override; - bool operator()(uint64& value, const char* name = "", const char* label = 0) override; - - bool operator()(int8& value, const char* name = "", const char* label = 0) override; - bool operator()(uint8& value, const char* name = "", const char* label = 0) override; - bool operator()(char& value, const char* name = "", const char* label = 0) override; - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0) override; - bool operator()(IContainer& ser, const char* name = "", const char* label = 0) override; - // ~IArchive - - using IArchive::operator(); - - private: - XmlNodeRef m_pRootNode; - }; -} - -#endif diff --git a/Code/CryEngine/CrySystem/ServiceNetwork.cpp b/Code/CryEngine/CrySystem/ServiceNetwork.cpp deleted file mode 100644 index 4ead14bcba..0000000000 --- a/Code/CryEngine/CrySystem/ServiceNetwork.cpp +++ /dev/null @@ -1,2035 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Service network implementation - - -#include "CrySystem_precompiled.h" -#include "ServiceNetwork.h" -#include "RemoteCommandHelpers.h" - -#include - -//----------------------------------------------------------------------------- - -// network system internal logging -#ifdef RELEASE - #define LOG_VERBOSE(level, txt, ...) -#else - #define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); } -#endif - -//----------------------------------------------------------------------------- - -namespace -{ - union AddValueConv - { - struct - { - uint8 ip0, ip1, ip2, ip3; - } bytes; - - uint32 u32; - }; - - inline void TranslateAddress(const ServiceNetworkAddress& addr, AZ::AzSock::AzSocketAddress& outAddr) - { - AddValueConv addr_value; - addr_value.bytes.ip0 = addr.GetAddress().m_ip0; - addr_value.bytes.ip1 = addr.GetAddress().m_ip1; - addr_value.bytes.ip2 = addr.GetAddress().m_ip2; - addr_value.bytes.ip3 = addr.GetAddress().m_ip3; - - outAddr.SetAddress(addr_value.u32, addr.GetAddress().m_port); - } - - inline void TranslateAddress(const AZ::AzSock::AzSocketAddress& addr, ServiceNetworkAddress& outAddr) - { - AddValueConv addr_value; - - const AZSOCKADDR_IN* addrIn = reinterpret_cast(addr.GetTargetAddress()); - addr_value.u32 = AZ::AzSock::NetToHostLong((*addrIn).sin_addr.s_addr); - - outAddr = ServiceNetworkAddress( - addr_value.bytes.ip0, - addr_value.bytes.ip1, - addr_value.bytes.ip2, - addr_value.bytes.ip3, - addr.GetAddrPort()); - } - - inline bool SocketConnectionsFull(AZ::AzSock::AzSockError error) - { - return (error == AZ::AzSock::AzSockError::eASE_NO_ERROR || error == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK || error == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK_CONN); - } -} - -//----------------------------------------------------------------------------- - -CServiceNetworkMessage::CServiceNetworkMessage(const uint32 id, const uint32 size) - : m_refCount(1) - , m_size(size) - , m_id(id) -{ - // Allocate buffer memory - m_pData = CryModuleMalloc(size); -} - -CServiceNetworkMessage::~CServiceNetworkMessage() -{ - // Release the memory buffer - CryModuleFree(m_pData); - m_pData = NULL; -} - -uint32 CServiceNetworkMessage::GetSize() const -{ - return m_size; -} - -uint32 CServiceNetworkMessage::GetId() const -{ - return m_id; -} - -void* CServiceNetworkMessage::GetPointer() -{ - return m_pData; -} - -const void* CServiceNetworkMessage::GetPointer() const -{ - return m_pData; -} - -void CServiceNetworkMessage::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CServiceNetworkMessage::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -IDataReadStream* CServiceNetworkMessage::CreateReader() const -{ - return new CDataReadStreamFormMessage(this); -} - -//----------------------------------------------------------------------------- - -void CServiceNetworkConnection::Header::Swap() -{ - // if we are on big endian system swap data to LE - // NOTE: this is a little bit confusing so see how the eLittleEndian and eBigEndian is defined - SwapEndian(m_size, eLittleEndian); -} - -void CServiceNetworkConnection::InitHeader::Swap() -{ - // if we are on big endian system swap data to LE - // NOTE: this is a little bit confusing so see how the eLittleEndian and eBigEndian is defined - SwapEndian(m_tryCount, eLittleEndian); - SwapEndian(m_guid0, eLittleEndian); - SwapEndian(m_guid1, eLittleEndian); -} - -//----------------------------------------------------------------------------- - -CServiceNetworkConnection::CServiceNetworkConnection( - class CServiceNetwork* manager, - EEndpoint endpointType, - AZSOCKET socket, - const CryGUID& connectionID, - const ServiceNetworkAddress& localAddress, - const ServiceNetworkAddress& remoteAddress) - - : m_pManager(manager) - , m_connectionID(connectionID) - , m_socket(socket) - , m_localAddress(localAddress) - , m_remoteAddress(remoteAddress) - , m_endpointType(endpointType) - , m_state(eState_Initializing) - , m_sendQueueDataSize(0) - , m_receiveQueueDataSize(0) - , m_messageDataSentSoFar(0) - , m_messageDataReceivedSoFar(0) - , m_bCloseRequested(false) - , m_pCurrentReceiveMessage(NULL) - , m_messageReceiveLength(0) - , m_messageDummyReadLength(0) - , m_reconnectTryCount(0) - , m_bDisableCommunication(false) - , m_pSendedMessages(NULL) - , m_refCount(1) -{ - // put the socket back in non blocking mode - AZ::AzSock::SetSocketBlockingMode(m_socket, false); - - // reset stats - m_statsNumDataSend = 0; - m_statsNumDataReceived = 0; - m_statsNumPacketsSend = 0; - m_statsNumPacketsReceived = 0; - - // reset timers to values at the creation time - const uint64 currentNetworkTime = m_pManager->GetNetworkTime(); - m_lastReconnectTime = currentNetworkTime; - m_lastMessageReceivedTime = currentNetworkTime; - m_lastInitializationSendTime = currentNetworkTime; - - // make sure keep alive messages are sent as soon as possible - m_lastKeepAliveSendTime = currentNetworkTime - kKeepAlivePeriod; - - LOG_VERBOSE(3, "Connection(): local='%s', remote='%s', this=%p", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); -} - -CServiceNetworkConnection::~CServiceNetworkConnection() -{ - // in here we must be already closed! - CRY_ASSERT(m_state == eState_Closed); - - LOG_VERBOSE(3, "~Connection(): local='%s', remote='%s', this=%p", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // can happen - if (m_pCurrentReceiveMessage != NULL) - { - m_pCurrentReceiveMessage->Release(); - m_pCurrentReceiveMessage = NULL; - } -} - -void CServiceNetworkConnection::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CServiceNetworkConnection::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -void CServiceNetworkConnection::Close() -{ - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: close requested", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - m_bCloseRequested = true; - m_bDisableCommunication = true; -} - -void CServiceNetworkConnection::FlushAndClose(const uint32 timeout) -{ - if (!m_bDisableCommunication) - { - // We don't have any messages on the waiting list, we can close immediately - if (m_pSendQueue.empty()) - { - // Normal close - Close(); - } - else - { - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: flush and close requested", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // Disable communication layer so no more new messages can be transmitted - m_bDisableCommunication = true; - - // Register in the manager list of connections to close after sending queue is empty - m_pManager->RegisterForDeferredClose(*this, timeout); - } - } -} - -void CServiceNetworkConnection::FlushAndWait() -{ - // Disable communication layer so no more new messages can be transmitted - m_bDisableCommunication = true; - - // Wait for the connection to be empty - while (IsAlive() && !m_pSendQueue.empty()) - { - Sleep(1); - } - - // Resume communication layer - m_bDisableCommunication = false; -} - -const CryGUID& CServiceNetworkConnection::GetGUID() const -{ - return m_connectionID; -} - -const ServiceNetworkAddress& CServiceNetworkConnection::GetRemoteAddress() const -{ - return m_remoteAddress; -} - -const ServiceNetworkAddress& CServiceNetworkConnection::GetLocalAddress() const -{ - return m_localAddress; -} - -void CServiceNetworkConnection::Reset() -{ - if (m_state == eState_Initializing || m_state == eState_Valid) - { - // Close the socket (we wont be able to use it anyway) - if (AZ::AzSock::IsAzSocketValid(m_socket)) - { - AZ::AzSock::Shutdown(m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - } - - // Reset messages buffers pointers - m_messageDataSentSoFar = 0; - m_messageDataReceivedSoFar = 0; - - // release current in-flight message - if (m_pCurrentReceiveMessage != NULL) - { - m_pCurrentReceiveMessage->Release(); - m_pCurrentReceiveMessage = NULL; - } - - // reset reconnection timer - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - m_lastReconnectTime = m_pManager->GetNetworkTime(); - - // we are in the lost state now, we can try to reconnect - m_state = eState_Lost; - - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: LOST!", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } -} - -void CServiceNetworkConnection::Shutdown() -{ - // Close the socket - if (AZ::AzSock::IsAzSocketValid(m_socket)) - { - AZ::AzSock::Shutdown(m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - } - - // Release all pending messages (they wont be sent anyway) - while (!m_pSendQueue.empty()) - { - CServiceNetworkMessage* message = m_pSendQueue.pop(); - message->Release(); - } - - // release current in-flight message - if (m_pCurrentReceiveMessage != NULL) - { - m_pCurrentReceiveMessage->Release(); - m_pCurrentReceiveMessage = NULL; - } - - // Reset internal send/recv state - m_messageDataSentSoFar = 0; - m_messageDataReceivedSoFar = 0; - - // Force the state - m_state = eState_Closed; - - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: CLOSED!", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); -} - -void CServiceNetworkConnection::Update() -{ - const uint64 currentNetworkTime = m_pManager->GetNetworkTime(); - - // We requested to close the socket - if (m_bCloseRequested) - { - m_bCloseRequested = false; - Shutdown(); - return; - } - - // State machine - switch (m_state) - { - // Connection is closed, nothing to do - case eState_Closed: - { - break; - } - - // We are still not initialized fully - case eState_Initializing: - { - // receive messages when waiting for connection - ProcessReceivingQueue(); - - // if we are a client send the connection initialization messages - if (m_endpointType == eEndpoint_Client) - { - // General timeout handling - if (HandleTimeout(currentNetworkTime)) - { - // do not send to often - if ((currentNetworkTime - m_lastInitializationSendTime) > kInitializationPerior) - { - // send the initialization message - if (TryInitialize()) - { - // message was sent, wait a moment before sending next one - m_lastInitializationSendTime = currentNetworkTime; - } - } - } - } - else if (m_endpointType == eEndpoint_Server) - { - // Server side when waiting for full initialization is sending the "keep alive" messages - // Note that we cannot time out on this end - ProcessKeepAlive(); - } - - break; - } - - // Connection is lost - case eState_Lost: - { - // if we are the client endpoint we can try to reconnect to the server - if (m_endpointType == eEndpoint_Client) - { - // do not try to reconnect to often (floods the network) - if ((currentNetworkTime - m_lastReconnectTime) > kReconnectTryPerior) - { - // reset timer - m_lastReconnectTime = currentNetworkTime; - - // try to reconnect - if (TryReconnect()) - { - // put the socket back in non blocking mode - AZ::AzSock::SetSocketBlockingMode(m_socket, false); - - // give us some slack with timeout after reconnection - m_lastMessageReceivedTime = currentNetworkTime; - - // yeah, we got reconnected, try to reinitialize the connection - m_messageDataReceivedSoFar = 0; - m_state = eState_Initializing; - } - } - } - else if (m_endpointType == eEndpoint_Server) - { - // wait for the reconnection timeout - if ((currentNetworkTime - m_lastMessageReceivedTime) > hReconnectTimeOut) - { - // reconnection time out has occurred - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: reconnection timeout", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // Close - Shutdown(); - } - } - - break; - } - - // Valid connection - case eState_Valid: - { - // Is it time to send a keep alive message? - ProcessKeepAlive(); - - // Process the queue of messages - ProcessSendingQueue(); - ProcessReceivingQueue(); - - // General timeout handling - if (m_endpointType == eEndpoint_Client) - { - HandleTimeout(currentNetworkTime); - } - - break; - } - - default: - { - // should not happen - break; - } - } -} - -bool CServiceNetworkConnection::HandleTimeout(const uint64 currentNetworkTime) -{ - // Connections never time out when there is a debugger attached -#if defined(WIN32) || defined(WIN64) - if (IsDebuggerPresent()) - { - // connection is still alive - return true; - } -#endif - - // Connection time out when there is a long time without any activity from server side (no keep alive or other messages) - const uint64 timeSinceLastMessage = currentNetworkTime - m_lastMessageReceivedTime; - if (timeSinceLastMessage > kTimeout) - { - // Connection has timed out - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: timed out", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // Put in lost state, wait a while before reconnecting - m_lastReconnectTime = currentNetworkTime; - m_state = eState_Lost; - - // Close the socket now - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - - // Connection was lost - return false; - } - - // Connection still alive - return true; -} - -bool CServiceNetworkConnection::TryInitialize() -{ - // This is sent only be clients trying to establish connection with server - // Connection ID is sent over to the server so he can easily identify re connections (even when port changes) - - // Initialization data header - InitHeader header; - header.m_cmd = eCommand_Initialize; - header.m_pad0 = 0; - header.m_pad1 = 0; - header.m_pad2 = 0; - header.m_tryCount = m_reconnectTryCount; - header.m_guid0 = m_connectionID.lopart; - header.m_guid1 = m_connectionID.hipart; - - // Swap the endianess in header (for sending) - header.Swap(); - - // Try send - const bool autoHandleErrors = false; // we do not need errors here - const uint32 dataLeft = sizeof(header) - m_messageDataSentSoFar; - const uint32 ret = TrySend(&header, dataLeft, autoHandleErrors); - m_messageDataSentSoFar += ret; - - // Full packet was sent - if (m_messageDataSentSoFar == sizeof(header)) - { - // We sent the initialization message - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: init message sent, try counter=%d", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_reconnectTryCount); - - // we sent the initialization packet, reset - m_messageDataSentSoFar = 0; - return true; - } - - // Still not valid - return false; -} - -bool CServiceNetworkConnection::TryReconnect() -{ - // We can't reconnect with disabled communication - if (m_bDisableCommunication) - { - return false; - } - - // Create new socket if needed - if (!AZ::AzSock::IsAzSocketValid(m_socket)) - { - m_socket = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(m_socket)) - { - // We sent the initialization message - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: failed to recreate socket", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - return false; - } - } - - // Translate remote address - AZ::AzSock::AzSocketAddress addr; - TranslateAddress(m_remoteAddress, addr); - - // When reconnecting always use the blocking mode - AZ::AzSock::SetSocketBlockingMode(m_socket, true); - - // every time we reconnect increment the internal counter so the receiving end (server) - // will be able to identity the up-to-date connection (and discard the older one) - CRY_ASSERT(m_endpointType == eEndpoint_Client); - m_reconnectTryCount += 1; - - // Connect (blocking) - const int result = AZ::AzSock::Connect(m_socket, addr); - if (result == 0) - { - // Spew to log (important info) - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: SUCCESSFULLY RECONNECTED", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // When connected put socket in the non blocking mode - AZ::AzSock::SetSocketBlockingMode(m_socket, false); - - // connected! - return true; - } - - // not connection, should not happen often - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: failed to reconnect", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // still not connected - return false; -} - -void CServiceNetworkConnection::SendKeepAlive(const uint64 currentNetworkTime) -{ - // Keep alive message is just ONE byte (makes it easier) - uint8 message = eCommand_KeepAlive; - if (1 == TrySend(&message, 1, false)) - { - // Throttle the sending - m_lastKeepAliveSendTime = currentNetworkTime; - - // At high verbose level we need even this :) - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: keep alive SENT", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } -} - -void CServiceNetworkConnection::ProcessSendingQueue() -{ - // Get the top message from the send queue - if (NULL == m_pSendedMessages) - { - m_pSendedMessages = m_pSendQueue.pop(); - if (NULL == m_pSendedMessages) - { - return; - } - } - - // Get the size of the data to transmit - const uint32 messageSize = m_pSendedMessages->GetSize(); - const uint32 headerSize = sizeof(Header); - - // Nothing sent yet, send header - if (m_messageDataSentSoFar < headerSize) - { - // prepare header - endian safe - Header header; - header.m_cmd = eCommand_Data; - header.m_size = messageSize; - - // Swap the header for reading - header.Swap(); - - // send the header - const uint32 dataLeft = headerSize - m_messageDataSentSoFar; - const uint32 sent = TrySend((const char*)&header + m_messageDataSentSoFar, dataLeft, true); - m_messageDataSentSoFar += sent; - } - - // Send message data - const uint32 endOfDataOffset = messageSize + headerSize; - if (m_messageDataSentSoFar >= headerSize && m_messageDataSentSoFar < endOfDataOffset) - { - // send and advance - const uint32 dataLeft = endOfDataOffset - m_messageDataSentSoFar; - const uint32 dataOffset = m_messageDataSentSoFar - headerSize; - const uint32 sent = TrySend((const char*)m_pSendedMessages->GetPointer() + dataOffset, dataLeft, true); - m_messageDataSentSoFar += sent; - } - - // All the data from the message was sent, release the message from this queue - // Note: this message may still be in some other sent queues for connections - if (m_messageDataSentSoFar >= endOfDataOffset) - { - // At high verbose level we need even this :) - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: message ID %d (size=%d) removed from queue", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_pSendedMessages->GetId(), - m_pSendedMessages->GetSize()); - - CryInterlockedAdd(&m_sendQueueDataSize, -(int)m_pSendedMessages->GetSize()); - - // stats (not collected in release builds) -#ifndef RELEASE - CryInterlockedIncrement((volatile int*) &m_statsNumPacketsSend); -#endif - - // release local message reference - m_pSendedMessages->Release(); - m_pSendedMessages = NULL; - - // rewind to zero to indicate fresh message - m_messageDataSentSoFar = 0; - } -} - -void CServiceNetworkConnection::ProcessKeepAlive() -{ - const uint64 currentNetworkTime = m_pManager->GetNetworkTime(); - if ((currentNetworkTime - m_lastKeepAliveSendTime) > kKeepAlivePeriod) - { - // Well, if we are in the middle of something make sure we do not interrupt it with KeepAlive - if (m_messageDataSentSoFar == 0) - { - SendKeepAlive(currentNetworkTime); - } - } -} - -void CServiceNetworkConnection::ProcessReceivingQueue() -{ - // To much data already, do not process - const uint32 kReceivedDataLimit = m_pManager->GetReceivedDataQueueLimit(); - if (m_receiveQueueDataSize > kReceivedDataLimit) - { - return; - } - - // Internal offset - const uint32 kOffsetHeader = 1; - const uint32 kOffsetData = 5; - - // Dummy receive - while (m_messageDummyReadLength > 0) - { - // batch size - const uint32 kTempBufferSize = 256; - - // read dummy data - uint8 tempBuffer[ kTempBufferSize ]; - const uint32 maxRead = min(kTempBufferSize, m_messageDummyReadLength); - const uint32 readCount = TryReceive(tempBuffer, maxRead, false); - m_messageDummyReadLength -= readCount; - - // got less - if (readCount < maxRead) - { - break; - } - } - - // Do not process normal messages until we receive all of the bogus data - if (m_messageDummyReadLength > 0) - { - return; - } - - // First byte - header - if (m_messageDataReceivedSoFar == 0) - { - // message header, read type - uint8 messageType = 0; - const int result = TryReceive(&messageType, 1, true); - if (result == 1) - { - // keep alive received, if we are not yet fully initialized it's the signal that we are :) - if (messageType == eCommand_KeepAlive) - { - // we got confirmed by server - if (m_state == eState_Initializing) - { - // change state - CRY_ASSERT(m_endpointType == eEndpoint_Client); - m_state = eState_Valid; - - // At high verbose level we need even this :) - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: connection confirmed by server", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } - else - { - // At low-level verbose log even this - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: keep alive RECEIVED", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } - - // update the keep alive data timer - m_lastKeepAliveSendTime = m_pManager->GetNetworkTime(); - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - } - else if (messageType == eCommand_Data) - { - // wait for the message length - m_messageReceiveLength = 0; - m_messageDataReceivedSoFar = kOffsetHeader; - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - - // At low-level verbose log even this - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: got data message header", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } - else if (messageType == eCommand_Initialize) - { - // let the system process the message - m_messageDummyReadLength = sizeof(InitHeader) - 1; - - // At low-level verbose log even this - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: outdated initheader received", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } - else - { - // Serious error - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: received invalid command (%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - messageType); - - // reset the connection - Reset(); - } - } - } - - // Message length - if (m_messageDataReceivedSoFar >= kOffsetHeader && m_messageDataReceivedSoFar < kOffsetData) - { - // receive the message length - const uint32 dataOffset = m_messageDataReceivedSoFar - kOffsetHeader; - const uint32 dataLeft = sizeof(uint32) - dataOffset; - const uint32 len = TryReceive((char*)&m_messageReceiveLength + dataOffset, dataLeft, true); - m_messageDataReceivedSoFar += len; - - // Update last message time - if (len > 0) - { - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - } - - // full length received - if (m_messageDataReceivedSoFar == 5) - { - // Swap endianess (for BE platforms) - // NOTE: if this is a little bit confusing, see how the eLittleEndian and eBigEndian are defined - SwapEndian(m_messageReceiveLength, eLittleEndian); - - // Sanity check on the message size - if (m_messageReceiveLength > kMaximumMessageSize) - { - // Serious error - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: unsupported message size (%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_messageReceiveLength); - - Reset(); - } - else if (m_messageReceiveLength > 0) - { - // Create new message that we will add the data into - CRY_ASSERT(m_pCurrentReceiveMessage == NULL); - m_pCurrentReceiveMessage = static_cast< CServiceNetworkMessage* >(m_pManager->AllocMessageBuffer(m_messageReceiveLength)); - CRY_ASSERT(m_pCurrentReceiveMessage != NULL); - - // Serious error - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: created receive buffer ID %d, (size=%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_pCurrentReceiveMessage ? m_pCurrentReceiveMessage->GetId() : 0, - m_messageReceiveLength); - } - } - } - - // Message data - if (m_messageDataReceivedSoFar >= kOffsetData) - { - CRY_ASSERT(m_pCurrentReceiveMessage != NULL); - PREFAST_ASSUME(m_pCurrentReceiveMessage); - - // Message fully received, put in the receive queue (at the end!) - const uint32 dataOffset = m_messageDataReceivedSoFar - kOffsetData; - const uint32 dataLeft = m_pCurrentReceiveMessage->GetSize() - dataOffset; - const uint32 len = TryReceive((char*)m_pCurrentReceiveMessage->GetPointer() + dataOffset, dataLeft, true); - m_messageDataReceivedSoFar += len; - - // connection got lost - if (m_state == eState_Lost) - { - return; - } - - // Update last message time - if (len > 0) - { - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - } - - // Full message received! - if (m_messageDataReceivedSoFar == (kOffsetData + m_pCurrentReceiveMessage->GetSize())) - { - // Serious error - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: full message received(%d), adding to queue", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_pCurrentReceiveMessage->GetSize()); - - // Put in the receive queue, only if no communication is disabled - if (m_bDisableCommunication) - { - m_pCurrentReceiveMessage->Release(); - } - else - { - m_pReceiveQueue.push(m_pCurrentReceiveMessage); - } - - // Stats (not collected in release builds) -#ifndef RELEASE - CryInterlockedIncrement((volatile int*) &m_statsNumPacketsReceived); -#endif - - // Reset - m_pCurrentReceiveMessage = NULL; - m_messageDataReceivedSoFar = 0; - } - } -} - -uint32 CServiceNetworkConnection::TrySend(const void* dataBuffer, uint32 dataSize, bool autoHandleErrors /*=true*/) -{ - // Send the data - const int ret = AZ::AzSock::Send(m_socket, (const char*) dataBuffer, dataSize, 0); - if (AZ::AzSock::SocketErrorOccured(ret)) - { - // We would block, that's not an error - if (ret == static_cast(AZ::AzSock::AzSockError::eASE_EWOULDBLOCK)) - { - return 0; - } - - // Report connection problems - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: send() error: %d", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - ret); - - // Put connection in the lost state - if (autoHandleErrors) - { - Reset(); - } - - // Nothing was sent (according to our logic) - return 0; - } - - // Update stats -#ifndef RELEASE - CryInterlockedAdd((volatile int*) &m_statsNumDataSend, ret); -#endif - - // Return the true amount of data sent - return ret; -} - -uint32 CServiceNetworkConnection::TryReceive(void* dataBuffer, uint32 dataSize, bool autoHandleErrors) -{ - // Send the data - const int ret = AZ::AzSock::Recv(m_socket, (char*) dataBuffer, dataSize, 0); - if (AZ::AzSock::SocketErrorOccured(ret)) - { - // We would block, that's not an error - if (ret == static_cast(AZ::AzSock::AzSockError::eASE_EWOULDBLOCK)) - { - return 0; - } - - // Connection was closed - if (ret == static_cast(AZ::AzSock::AzSockError::eASE_ECONNRESET)) - { - // Report connection problems - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: CLOSED BY PEER", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // Shutdown socket - Shutdown(); - return 0; - } - - // Report connection problems - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: recv() error: %d", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - ret); - - // Put connection in the lost state - if (autoHandleErrors) - { - Reset(); - } - - // Nothing was sent (according to our logic) - return 0; - } - - // Update stats -#ifndef RELEASE - CryInterlockedAdd((volatile int*) &m_statsNumDataReceived, ret); -#endif - - // Return the true amount of data sent - return ret; -} - -bool CServiceNetworkConnection::SendMsg(IServiceNetworkMessage* message) -{ - // Invalid message - if (NULL == message || message->GetSize() == 0) - { - return false; - } - - // Communication layer is disabled, not possible to send any more messages - if (m_bDisableCommunication) - { - return false; - } - - // Process data size limits - { - const uint32 sizeAfterThisMessage = m_sendQueueDataSize + message->GetSize(); - const uint32 sendQueueLimit = m_pManager->GetSendDataQueueLimit(); - if (sizeAfterThisMessage > sendQueueLimit) - { - // Report connection problems - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: to much data on send queue", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // To much data on the queue already, we will not be sending this message - return false; - } - - // Keep the local reference so the source data does not get deleted - message->AddRef(); - - // Update the queue data size - CryInterlockedAdd(&m_sendQueueDataSize, message->GetSize()); - - // Append the message to the sending queue - m_pSendQueue.push(static_cast< CServiceNetworkMessage* >(message)); - } - - // Well, we can't tell any more than that - return true; -} - -IServiceNetworkMessage* CServiceNetworkConnection::ReceiveMsg() -{ - // Anything on the queue ? - IServiceNetworkMessage* message = NULL; - if (!m_pReceiveQueue.empty()) - { - message = m_pReceiveQueue.pop(); - - // Report connection problems - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: message ID %d (size=%d) popped by receive end", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - message->GetId(), - message->GetSize()); - } - - return message; -} - -bool CServiceNetworkConnection::IsAlive() const -{ - return m_state != eState_Closed; -} - -uint32 CServiceNetworkConnection::GetMessageSendCount() const -{ - return m_statsNumPacketsSend; -} - -uint32 CServiceNetworkConnection::GetMessageReceivedCount() const -{ - return m_statsNumPacketsReceived; -} - -uint64 CServiceNetworkConnection::GetMessageSendDataSize() const -{ - return m_statsNumDataSend; -} - -uint64 CServiceNetworkConnection::GetMessageReceivedDataSize() const -{ - return m_statsNumDataReceived; -} - -bool CServiceNetworkConnection::HandleReconnect(AZSOCKET socket, const uint32 tryCount) -{ - CRY_ASSERT(m_endpointType == eEndpoint_Server); - - // connection is older - if (tryCount < m_reconnectTryCount) - { - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: reconnection request OLDER (%d<%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - tryCount, - m_reconnectTryCount); - - return false; - } - - // should not happen - if (tryCount == m_reconnectTryCount) - { - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: reconnection request COLLISION (%d==%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - tryCount, - m_reconnectTryCount); - - return false; - } - - // newer connection, close current socket - AZ::AzSock::Shutdown(m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(m_socket); - - // reset send/receive counters (will resend last message from the queue) - m_messageDataReceivedSoFar = 0; - m_messageDataSentSoFar = 0; - - // Set new socket and update reconnection counter - m_socket = socket; - m_reconnectTryCount = tryCount; - - // revive the connection - m_state = eState_Valid; - - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: successfull reconnection with counter (%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_reconnectTryCount); - - // processed - return true; -} - -//----------------------------------------------------------------------------- - -CServiceNetworkListener::CServiceNetworkListener(CServiceNetwork* pManager, AZSOCKET socket, const ServiceNetworkAddress& address) - : m_pManager(pManager) - , m_socket(socket) - , m_localAddress(address) - , m_closeRequestReceived(false) - , m_refCount(1) -{ - LOG_VERBOSE(3, "Listener() local='%s', this=%p", - m_localAddress.ToString().c_str(), - (UINT_PTR) this); -} - -CServiceNetworkListener::~CServiceNetworkListener() -{ - AZ_Assert(!AZ::AzSock::IsAzSocketValid(m_socket), "AZSocket still valid on ServiceNetworkListener destructor"); - - LOG_VERBOSE(3, "~Listener() local='%s', this=%p", - m_localAddress.ToString().c_str(), - (UINT_PTR) this); -} - -void CServiceNetworkListener::Update() -{ - // We requested to close this listener - if (m_closeRequestReceived) - { - LOG_VERBOSE(3, "Listener local='%s', this=%p: closing due to request", - m_localAddress.ToString().c_str(), - (UINT_PTR) this); - - // Close the socket - if (AZ::AzSock::IsAzSocketValid(m_socket)) - { - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - } - - // Close all connections - for (TConnectionList::iterator it = m_pLocalConnections.begin(); - it != m_pLocalConnections.end(); ++it) - { - (*it)->Close(); - (*it)->Release(); - } - - m_pLocalConnections.clear(); - m_closeRequestReceived = false; - - return; - } - - // Process connection requests - ProcessIncomingConnections(); - - // Service the pending connection - ProcessPendingConnections(); - - // Remove any local connection that got dead - for (TConnectionList::iterator it = m_pLocalConnections.begin(); - it != m_pLocalConnections.end(); /*++it*/) - { - if (!(*it)->IsAlive()) - { - LOG_VERBOSE(2, "Listener local='%s', this=%p: removing dead connection '%s' (%p)", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - (*it)->GetRemoteAddress().ToString().c_str(), - (UINT_PTR) (*it)); - - (*it)->Release(); - it = m_pLocalConnections.erase(it); - } - else - { - ++it; - } - } -} - -const ServiceNetworkAddress& CServiceNetworkListener::GetLocalAddress() const -{ - return m_localAddress; -} - -uint32 CServiceNetworkListener::GetConnectionCount() const -{ - // not safe ? - return m_pLocalConnections.size(); -} - -IServiceNetworkConnection* CServiceNetworkListener::Accept() -{ - // Look for any connection on the list that is in the "initialized" state - { - CryAutoLock lock(m_accessLock); - for (TConnectionList::iterator it = m_pLocalConnections.begin(); - it != m_pLocalConnections.end(); ++it) - { - // we are looking for connections in the "eState_Initializing" which mean that they are valid but not yet recognized by the outside world - CServiceNetworkConnection* con = (*it); - if (con->m_state == CServiceNetworkConnection::eState_Initializing) - { - LOG_VERBOSE(1, "Listener local='%s', this=%p: accepting connection from '%s' (%p)", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con->GetRemoteAddress().ToString().c_str(), - (UINT_PTR) con); - - // switch state to "valid" - con->m_state = CServiceNetworkConnection::eState_Valid; - - // when returning outside increment the ref count (we still want to keep our internal reference) - con->AddRef(); - return con; - } - } - } - - // No pending connections - return NULL; -} - -bool CServiceNetworkListener::IsAlive() const -{ - return AZ::AzSock::IsAzSocketValid(m_socket); -} - -void CServiceNetworkListener::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CServiceNetworkListener::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -void CServiceNetworkListener::Close() -{ - LOG_VERBOSE(2, "Listener local='%s', this=%p: close requested", - m_localAddress.ToString().c_str(), - (UINT_PTR) this); - - m_closeRequestReceived = true; -} - -void CServiceNetworkListener::ProcessIncomingConnections() -{ - // Accept all possible connections as soon as possible (the connect side is blocking) - for (;; ) - { - // Get the pending connection from TCP/IP layers - AZ::AzSock::AzSocketAddress remoteAddrInet; - AZSOCKET sock = AZ::AzSock::Accept(m_socket, remoteAddrInet); - - // No more connections - if (SocketConnectionsFull(AZ::AzSock::AzSockError(sock))) - { - break; - } - - // Different error - if (!AZ::AzSock::IsAzSocketValid(sock)) - { - // Connection has other problems - LOG_VERBOSE(1, "Listener local='%s', this=%p: accept() error: %d", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - (int)sock); - - break; - } - - // Get the remote address - ServiceNetworkAddress remoteAddress; - TranslateAddress(remoteAddrInet, remoteAddress); - - // Any way create a new pending connection information - PendingConnection* pendingConnection = new PendingConnection; - pendingConnection->m_remoteAddress = remoteAddress; - pendingConnection->m_dataReceivedSoFar = 0; - pendingConnection->m_socket = sock; - - // Connection has other problems - LOG_VERBOSE(2, "Listener local='%s', this=%p: new pending connection from '%s'", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - remoteAddress.ToString().c_str()); - - // Add to list (not locked because its used only from net thread) - m_pPendingConnections.push_back(pendingConnection); - } -} - -void CServiceNetworkListener::ProcessPendingConnections() -{ - // Process only pending connections, not locked because its used only from net thread - for (TPendingConnectionList::iterator it = m_pPendingConnections.begin(); - it != m_pPendingConnections.end(); /*++it*/) - { - PendingConnection& con = *(*it); - - // Read the incoming data - CRY_ASSERT(con.m_dataReceivedSoFar < sizeof(con.m_initHeader)); - const uint32 dataLeft = sizeof(con.m_initHeader) - con.m_dataReceivedSoFar; - const int size = AZ::AzSock::Recv(con.m_socket, (char*)&con.m_initHeader + con.m_dataReceivedSoFar, dataLeft, 0); - - // The only no-action case: no data yet - if (size == static_cast(AZ::AzSock::AzSockError::eASE_EWOULDBLOCK)) - { - ++it; - continue; - } - - // Something more important - if (AZ::AzSock::SocketErrorOccured(size)) - { - // well, some problem on the way, remove the pending connection from the list (client will resend) - LOG_VERBOSE(1, "Listener local='%s', this=%p: pending connection from '%s' lost: %d", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con.m_remoteAddress.ToString().c_str(), - (int)size); - } - else - { - // data was received - CRY_ASSERT(size < (int)dataLeft); - con.m_dataReceivedSoFar += size; - - // still not enough data - if (con.m_dataReceivedSoFar < sizeof(con.m_initHeader)) - { - ++it; - continue; - } - - // validate header - if (con.m_initHeader.m_cmd == CServiceNetworkConnection::eCommand_Initialize) - { - // Swap the header after reading - con.m_initHeader.Swap(); - - // Extract the connection ID - const CryGUID connectionId = CryGUID::Construct(con.m_initHeader.m_guid0, con.m_initHeader.m_guid1); - - // try find existing connection with the same connection GUID (reconnection) - CServiceNetworkConnection* existingConnection = NULL; - for (TConnectionList::const_iterator jt = m_pLocalConnections.begin(); - jt != m_pLocalConnections.end(); ++jt) - { - if ((*jt)->GetGUID() == connectionId) - { - existingConnection = *jt; - break; - } - } - - // if existing connection was found that we probably were trying to reconnect - if (existingConnection != NULL) - { - // we already have this connection on our list and we got reconnected with the some GUID - // this usually means that the client has lost communication with server for some time - LOG_VERBOSE(1, "Listener local='%s', this=%p: reconnection from '%s'", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con.m_remoteAddress.ToString().c_str()); - - // substitute the connection with newer one (if it is really newer) - if (!existingConnection->HandleReconnect(con.m_socket, con.m_initHeader.m_tryCount)) - { - // well, we didn't use this connect (it was older than the current one, close it) - AZ::AzSock::Shutdown(con.m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(con.m_socket); - } - else - { - // add to global list of active debug connections (so we can start receiving data) - m_pManager->RegisterConnection(*existingConnection); - } - } - else - { - // no previous connection registered, create one now - CServiceNetworkConnection* newConnection = new CServiceNetworkConnection( - m_pManager, - CServiceNetworkConnection::eEndpoint_Server, // this connection is created from listener side which is considered the "server" - con.m_socket, - connectionId, - m_localAddress, - con.m_remoteAddress); - - // this is the first time we see this connection on set the proper connection counter - newConnection->m_reconnectTryCount = con.m_initHeader.m_tryCount; - - // happy moment, log it - LOG_VERBOSE(0, "Listener local='%s', this=%p: confirmed connection from '%s'", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con.m_remoteAddress.ToString().c_str()); - - // make sure connection is in valid state - CRY_ASSERT(newConnection->m_state == CServiceNetworkConnection::eState_Initializing); - - // add to local list - CRY_ASSERT(newConnection->IsInitialized() == false); - { - CryAutoLock lock(m_accessLock); - m_pLocalConnections.push_back(newConnection); - newConnection->AddRef(); - } - - // add to global list of active debug connections (so we can start receiving data) - m_pManager->RegisterConnection(*newConnection); - } - } - else - { - // well, some problem on the way, remove the pending connection from the list (client will resend) - LOG_VERBOSE(0, "Listener local='%s', this=%p: invalid connection data received from '%s'", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con.m_remoteAddress.ToString().c_str()); - - // close the socket - AZ::AzSock::Shutdown(con.m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(con.m_socket); - } - } - - // any way, delete the connection from the pending list - delete (*it); - it = m_pPendingConnections.erase(it); - } -} - -//----------------------------------------------------------------------------- - -CServiceNetwork::CServiceNetwork() - : m_networkTime(0) - , m_bExitRequested(false) - , m_bufferID(1) -{ - // Create the CVAR - m_pVerboseLevel = gEnv->pConsole->RegisterInt("net_debugVerboseLevel", 0, VF_DEV_ONLY); - - // Send/receive Queue size limits - m_pReceiveDataQueueLimit = gEnv->pConsole->RegisterInt("net_receiveQueueSize", 20 << 20, VF_DEV_ONLY); - m_pSendDataQueueLimit = gEnv->pConsole->RegisterInt("net_sendQueueSize", 5 << 20, VF_DEV_ONLY); - - // Reinitialize the random number generator with independent seed value - m_guidGenerator.Seed((uint32)GetNetworkTime()); - - // Start thread - m_pThread = new TServiceNetworkThread(); - m_pThread->Start(*this); -} - -CServiceNetwork::~CServiceNetwork() -{ - // Signal the network thread to stop - if (NULL != m_pThread) - { - m_pThread->Cancel(); - m_pThread->WaitForThread(); - delete m_pThread; - } - - // Release all closeing connections - for (TConnectionsToCloseArray::const_iterator it = m_connectionsToClose.begin(); - it != m_connectionsToClose.end(); ++it) - { - (*it).pConnection->Release(); - } - - // Release and close all connections - for (TConnectionArray::const_iterator it = m_pConnections.begin(); - it != m_pConnections.end(); ++it) - { - (*it)->Close(); - (*it)->Release(); - } - - // Release all listeners - for (TListenerArray::const_iterator it = m_pListeners.begin(); - it != m_pListeners.end(); ++it) - { - (*it)->Release(); - } - - // Release the CVars - SAFE_RELEASE(m_pVerboseLevel); - SAFE_RELEASE(m_pReceiveDataQueueLimit); - SAFE_RELEASE(m_pSendDataQueueLimit); -} - -#ifndef RELEASE -bool CServiceNetwork::CheckVerbose(const uint32 level) const -{ - const int verboseLevel = m_pVerboseLevel->GetIVal(); - return (int)level < verboseLevel; -} - -void CServiceNetwork::Log(const char* txt, ...) const -{ - // format the print buffer - char buffer[512]; - va_list ap; - va_start(ap, txt); - vsprintf_s(buffer, sizeof(buffer), txt, ap); - va_end(ap); - - // pass to log - gEnv->pLog->LogAlways(buffer); -} -#endif - -void CServiceNetwork::Cancel() -{ - m_bExitRequested = true; - - if (m_pThread) - { - m_pThread->Stop(); - } -} - -void CServiceNetwork::Run() -{ - CryThreadSetName(THREADID_NULL, "ServiceNetworkThread"); - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ServiceNetwork_cpp) -#endif - - TListenerArray updatingListeners; - TConnectionArray updatingConnections; - TConnectionsToCloseArray updatingConnectionsToClose; - - // Process messages - while (!m_bExitRequested) - { - // Well, copy the lists for the duration of update - { - CryAutoLock lock(m_accessMutex); - updatingListeners = m_pListeners; - updatingConnections = m_pConnections; - updatingConnectionsToClose = m_connectionsToClose; - } - - if ((!gEnv) || (!gEnv->pTimer)) - { - Sleep(5); - continue; - } - - // Update network time - m_networkTime = gEnv->pTimer->GetAsyncTime().GetMilliSecondsAsInt64(); - - // Process the listeners (accepts and pending connections) - for (TListenerArray::const_iterator it = updatingListeners.begin(); - it != updatingListeners.end(); ++it) - { - (*it)->Update(); - - // Remove dead listeners from the main list - if (!(*it)->IsAlive()) - { - CryAutoLock lock(m_accessMutex); - - // remove from array - TListenerArray::iterator jt = std::find(m_pListeners.begin(), m_pListeners.end(), *it); - CRY_ASSERT(jt != m_pListeners.end()); - m_pListeners.erase(jt); - - // release internal reference (may delete object if no longer used on main thread) - (*it)->Release(); - } - } - - - // Process the closing connections - for (TConnectionsToCloseArray::const_iterator it = updatingConnectionsToClose.begin(); - it != updatingConnectionsToClose.end(); ++it) - { - const ConnectionToClose& info = *it; - - bool bTimeout = false; - if (info.maxWaitTime && m_networkTime > info.maxWaitTime) - { - bTimeout = true; - } - - // should we close it now ? - if (bTimeout || !it->pConnection->IsAlive() || it->pConnection->IsSendingQueueEmpty()) - { - info.pConnection->Close(); - info.pConnection->Release(); - - // erase from list - { - CryAutoLock lock(m_accessMutex); - for (TConnectionsToCloseArray::iterator jt = m_connectionsToClose.begin(); - jt != m_connectionsToClose.end(); ++jt) - { - if ((*jt).pConnection == info.pConnection) - { - m_connectionsToClose.erase(jt); - break; - } - } - } - } - } - - // Process the connections - for (TConnectionArray::const_iterator it = updatingConnections.begin(); - it != updatingConnections.end(); ++it) - { - (*it)->Update(); - - // Remove dead connections from the main list - if (!(*it)->IsAlive()) - { - CryAutoLock lock(m_accessMutex); - - // remove from array - TConnectionArray::iterator jt = std::find(m_pConnections.begin(), m_pConnections.end(), *it); - CRY_ASSERT(jt != m_pConnections.end()); - m_pConnections.erase(jt); - - // release internal reference (may delete object if no longer used on main thread) - (*it)->Release(); - } - } - - // Internal delay - // TODO: this is guess work right now - Sleep(5); - } -} - -void CServiceNetwork::SetVerbosityLevel(const uint32 level) -{ - // propagate the value to CVar (so it is consistent across the engine) - if (NULL != m_pVerboseLevel) - { - m_pVerboseLevel->Set((int)level); - } -} - -IServiceNetworkMessage* CServiceNetwork::AllocMessageBuffer(const uint32 size) -{ - // Allocate message with new ID - const uint32 bufferID = CryInterlockedIncrement(&m_bufferID); - return new CServiceNetworkMessage(bufferID, size); -} - -IDataWriteStream* CServiceNetwork::CreateMessageWriter() -{ - return new CDataWriteStreamBuffer(); -} - -IDataReadStream* CServiceNetwork::CreateMessageReader(const void* pData, const uint32 dataSize) -{ - if (pData != NULL && dataSize > 0) - { - return new CDataReadStreamMemoryBuffer(pData, dataSize); - } - - return NULL; -} - -ServiceNetworkAddress CServiceNetwork::GetHostAddress(const string& addressString, uint16 optionalPort /*=0*/) const -{ - // cut the address into base and port part - string hostname = addressString.c_str(); - - const int pos = addressString.rfind(':'); - if (pos != -1) - { - // substitute the port number from the part in string - if (optionalPort == 0) - { - const char* portNumberStr = addressString.c_str() + pos + 1; - optionalPort = (uint16)atoi(portNumberStr); - } - - // remove the port part from base address - hostname = addressString.Left(pos); - } - - AZ::AzSock::AzSocketAddress socketAddress; - socketAddress.SetAddress(hostname.c_str(), optionalPort); - - // log on hi verbose mode - LOG_VERBOSE(3, "GetHostAddress(%s) -> %s", addressString.c_str(), socketAddress.GetAddress().c_str()); - - // format the network address - ServiceNetworkAddress out; - TranslateAddress(socketAddress, out); - return out; -} - -IServiceNetworkListener* CServiceNetwork::CreateListener(uint16 localPort) -{ - // Create socket - AZSOCKET createdSocket = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(createdSocket)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): socket() failed: %s", localPort, AZ::AzSock::GetStringForError(createdSocket)); - return NULL; - } - - // Disable merging of small blocks to fight high latency connection - // NOTE: consoles support this mode by default - const int ret3 = AZ::AzSock::EnableTCPNoDelay(createdSocket, true); - if (AZ::AzSock::SocketErrorOccured(ret3)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): setsockopt() failed: %s", localPort, AZ::AzSock::GetStringForError(ret3)); - - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - - // Reuse address - { - const int optRet = AZ::AzSock::SetSocketOption(createdSocket, AZ::AzSock::AzSocketOption::REUSEADDR, true); - if (AZ::AzSock::SocketErrorOccured(optRet)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): setsockopt() (reuse) failed", localPort); - - // cleanup - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - } - - // Put the listener socket in the non blocking mode - if (!AZ::AzSock::SetSocketBlockingMode(createdSocket, false)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): setsockopt() failed", localPort); - - // cleanup - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - - // Setup local bind address - AZ::AzSock::AzSocketAddress service; - service.SetAddrPort(localPort); - - // Bind socket - const int ret = AZ::AzSock::Bind(createdSocket, service); - if (AZ::AzSock::SocketErrorOccured(ret)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): bind() failed: %s", localPort, AZ::AzSock::GetStringForError(createdSocket)); - - // cleanup - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - - // Listen for incoming connection requests on the created socket - const int ret2 = AZ::AzSock::Listen(createdSocket, 64 /*backLogSize*/); - if (AZ::AzSock::SocketErrorOccured(ret2)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): listen() failed: %s", localPort, AZ::AzSock::GetStringForError(createdSocket)); - - // cleanup - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - - // Get our local address - AZ::AzSock::AzSocketAddress localAddressInet; - AZ::AzSock::GetSockName(createdSocket, localAddressInet); - - // Translate to debug network address data - ServiceNetworkAddress localAddress; - TranslateAddress(localAddressInet, localAddress); - - // Spew to log (important info) - LOG_VERBOSE(0, "bind() to '%s'", localAddress.ToString().c_str()); - - // Create the listener wrapper - CServiceNetworkListener* listener = new CServiceNetworkListener(this, createdSocket, localAddress); - - // Listener was created - LOG_VERBOSE(0, "CreateListener(%d): listener created, local address=%s", localPort, listener->GetLocalAddress().ToString().c_str()); - - // Add to list of local listeners - { - CryAutoLock lock(m_accessMutex); - m_pListeners.push_back(listener); - listener->AddRef(); - } - - // Return wrapping interface - return listener; -} - -void CServiceNetwork::RegisterConnection(CServiceNetworkConnection& con) -{ - CryAutoLock lock(m_accessMutex); - - // Make sure to register each connection only once - TConnectionArray::const_iterator it = std::find(m_pConnections.begin(), m_pConnections.end(), &con); - if (it == m_pConnections.end()) - { - // Low-level info - LOG_VERBOSE(3, "RegisterConnection(): registered connection from '%s' to '%s', %p", - con.GetLocalAddress().ToString().c_str(), - con.GetRemoteAddress().ToString().c_str(), - (UINT_PTR) &con); - - // add to connections list, that means we need to also increment the refcount - m_pConnections.push_back(&con); - con.AddRef(); - } -} - -void CServiceNetwork::RegisterForDeferredClose(CServiceNetworkConnection& con, const uint32 timeout) -{ - CryAutoLock lock(m_accessMutex); - - // Low-level info - LOG_VERBOSE(3, "RegisterConnection(): registered connection from '%s' to '%s', %p for defered close, timeout=%d", - con.GetLocalAddress().ToString().c_str(), - con.GetRemoteAddress().ToString().c_str(), - (UINT_PTR) &con, - timeout); - - // Add to connections list, that means we need to also increment the refcount - ConnectionToClose info; - info.pConnection = &con; - info.maxWaitTime = (timeout > 0) ? (GetNetworkTime() + timeout) : 0; - m_connectionsToClose.push_back(info); - - // Keep internal reference - con.AddRef(); -} - -IServiceNetworkConnection* CServiceNetwork::Connect(const ServiceNetworkAddress& remoteAddress) -{ - // Create new socket if needed - AZSOCKET socket = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(socket)) - { - // Connection has problems - LOG_VERBOSE(0, "Connect(%s): socket() failed: %s", remoteAddress.ToString().c_str(), AZ::AzSock::GetStringForError(socket)); - return NULL; - } - - // Translate remote address - AZ::AzSock::AzSocketAddress addr; - TranslateAddress(remoteAddress, addr); - - // Spew to log (important info) - LOG_VERBOSE(1, "Connecting to '%s'...", remoteAddress.ToString().c_str()); - - // Connect (blocking) - const int result = AZ::AzSock::Connect(socket, addr); - if (AZ::AzSock::SocketErrorOccured(result)) - { - // Spew to log (important info) - LOG_VERBOSE(0, "connect() to '%s' failed: %s", remoteAddress.ToString().c_str(), AZ::AzSock::GetStringForError(result)); - return NULL; - } - - // Get the address of local socket endpoint - // Get our local address - AZ::AzSock::AzSocketAddress localAddressInet; - AZ::AzSock::GetSockName(socket, localAddressInet); - - // Translate to debug network address data - ServiceNetworkAddress localAddress; - TranslateAddress(localAddressInet, localAddress); - - // Spew to log (important info) - LOG_VERBOSE(1, "connected() from '%s' to '%s'", localAddress.ToString().c_str(), remoteAddress.ToString().c_str()); - - // Allocate some connection ID - const uint64 loPart = m_guidGenerator.GenerateUint64(); - const uint64 hiPart = m_guidGenerator.GenerateUint64(); - const CryGUID connectionID = CryGUID::Construct(loPart, hiPart); - - // Spew to log (important info) - LOG_VERBOSE(3, "New connection GUID: %08x-%08x-%08x-%08x", (uint64)(hiPart >> 32), (uint64)(hiPart & 0xFFFFFFFF), (uint64)(loPart >> 32), (uint64)(loPart & 0xFFFFFFFF)); - - // Create connection wrapper - CServiceNetworkConnection* newConnection = new CServiceNetworkConnection( - this, - CServiceNetworkConnection::eEndpoint_Client, // we are the client, we are connecting to remove destination - socket, - connectionID, - localAddress, - remoteAddress); - - // Add to list of connections - { - CryAutoLock lock(m_accessMutex); - m_pConnections.push_back(newConnection); - - // since we add the object to our internal list keep an extra reference to it - newConnection->AddRef(); - } - - // Well, good luck and have fun :) - return newConnection; -} - -//----------------------------------------------------------------------------- - -// Do not remove (can mess up the uber file builds) -#undef LOG_VERBOSE - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/ServiceNetwork.h b/Code/CryEngine/CrySystem/ServiceNetwork.h deleted file mode 100644 index 23c3500082..0000000000 --- a/Code/CryEngine/CrySystem/ServiceNetwork.h +++ /dev/null @@ -1,475 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Service network implementation - - -#pragma once - - -//----------------------------------------------------------------------------- - -#include "IServiceNetwork.h" -#include - -class CServiceNetwork; - -//----------------------------------------------------------------------------- - -// General message buffer -class CServiceNetworkMessage - : public IServiceNetworkMessage -{ -private: - void* m_pData; - uint32 m_id; - uint32 m_size; - int volatile m_refCount; - -public: - CServiceNetworkMessage(const uint32 id, const uint32 size); - virtual ~CServiceNetworkMessage(); - - // IServiceNetworMessage interface - virtual uint32 GetId() const; - virtual uint32 GetSize() const; - virtual void* GetPointer(); - virtual const void* GetPointer() const; - virtual struct IDataReadStream* CreateReader() const; - virtual void AddRef(); - virtual void Release(); -}; - -//----------------------------------------------------------------------------- - -// General network TCP/IP connection -class CServiceNetworkConnection - : public IServiceNetworkConnection -{ -public: - friend class CServiceNetworkListener; - - // maximum size of a single message (0.5MB by default) - static const uint32 kMaximumMessageSize = 5 << 19; - - // initialization message send period (ms) - static const uint64 kInitializationPerior = 1000; - - // keep alive period (ms), by default every 2s - static const uint64 kKeepAlivePeriod = 2000; - - // reconnection retries period (ms) - static const uint64 kReconnectTryPerior = 1000; - - // timeout for assuming server side connection dead (reconnection timeout) - static const uint64 hReconnectTimeOut = 30 * 1000; - - // communication time out (ms) - static const uint64 kTimeout = 5000; - - // Type of endpoint - enum EEndpoint - { - // This is the server side of the connection (on the side of the listening socket) - eEndpoint_Server, - - // This is the client side of the connection (we connected to the listening socket) - eEndpoint_Client, - }; - - // Internal state machine - enum EState - { - // Connection is initializing - eState_Initializing, - - // Connection is valid - eState_Valid, - - // Operation on the socket failed (we may need to reconnect) - eState_Lost, - - // Connection is closed - eState_Closed, - }; - - // Command IDs, do not change the numerical values - enum ECommand - { - // Data block command - eCommand_Data = 1, - - // Keep alive command - eCommand_KeepAlive = 2, - - // Initialize communication channel (sent only once) - eCommand_Initialize = 3, - }; - - #pragma pack(push) - #pragma pack(1) - - struct Header - { - uint8 m_cmd; - uint32 m_size; - - void Swap(); - }; - - struct InitHeader - { - uint8 m_cmd; - uint8 m_pad0; - uint8 m_pad1; - uint8 m_pad2; - uint32 m_tryCount; - uint64 m_guid0; - uint64 m_guid1; - - void Swap(); - }; - - #pragma pack(pop) - -private: - CServiceNetwork* m_pManager; - - // Type of endpoint (client/server) - EEndpoint m_endpointType; - - // Connection state (internal) - EState m_state; - - // Reference count (updated using CryInterlocked* functions) - int volatile m_refCount; - - // Internal socket data - AZSOCKET m_socket; - - // Local address - ServiceNetworkAddress m_localAddress; - - // Remote connection address - ServiceNetworkAddress m_remoteAddress; - - // Internal connection ID (unique) - CryGUID m_connectionID; - - // Internal time counters - uint64 m_lastReconnectTime; - uint64 m_lastKeepAliveSendTime; - uint64 m_lastMessageReceivedTime; - uint64 m_lastInitializationSendTime; - uint32 m_reconnectTryCount; - - // Statistics (updated from threads using CryIntelocked* functions) - volatile uint32 m_statsNumPacketsSend; - volatile uint32 m_statsNumPacketsReceived; - volatile uint32 m_statsNumDataSend; - volatile uint32 m_statsNumDataReceived; - - // Queue of messages to send (thread access possible) - typedef CryMT::CLocklessPointerQueue< CServiceNetworkMessage > TSendQueue; - CServiceNetworkMessage* m_pSendedMessages; - TSendQueue m_pSendQueue; - uint32 m_messageDataSentSoFar; - volatile int m_sendQueueDataSize; - - // Queue of received message - typedef CryMT::CLocklessPointerQueue< CServiceNetworkMessage > TReceiveQueue; - TReceiveQueue m_pReceiveQueue; - uint32 m_receiveQueueDataSize; - uint32 m_messageDataReceivedSoFar; - uint32 m_messageReceiveLength; - - // Message being received "right now" - CServiceNetworkMessage* m_pCurrentReceiveMessage; - uint32 m_messageDummyReadLength; - - // External request to close this connection was issued - bool m_bCloseRequested; - - // Do not accept any new data for sending or receiving - bool m_bDisableCommunication; - -public: - ILINE bool IsInitialized() const - { - return m_state != eState_Initializing; - } - - ILINE bool IsSendingQueueEmpty() const - { - return m_pSendQueue.empty(); - } - - ILINE CServiceNetwork* GetManager() const - { - return m_pManager; - } - -public: - CServiceNetworkConnection( - class CServiceNetwork* manager, - EEndpoint endpointType, - AZSOCKET socket, - const CryGUID& connectionID, - const ServiceNetworkAddress& localAddress, - const ServiceNetworkAddress& remoteAddress); - - virtual ~CServiceNetworkConnection(); - - // IServiceNetworkConnection interface implementation - virtual const ServiceNetworkAddress& GetRemoteAddress() const; - virtual const ServiceNetworkAddress& GetLocalAddress() const; - virtual const CryGUID& GetGUID() const; - virtual bool IsAlive() const; - virtual uint32 GetMessageSendCount() const; - virtual uint32 GetMessageReceivedCount() const; - virtual uint64 GetMessageSendDataSize() const; - virtual uint64 GetMessageReceivedDataSize() const; - virtual bool SendMsg(IServiceNetworkMessage* message); - virtual IServiceNetworkMessage* ReceiveMsg(); - virtual void FlushAndClose(const uint32 timeout); - virtual void FlushAndWait(); - virtual void Close(); - virtual void AddRef(); - virtual void Release(); - - // All remote connections are updated on the client side - // This is called from service network update thread, try not to call by hand :) - void Update(); - -private: - void ProcessSendingQueue(); - void ProcessReceivingQueue(); - - // Keep alive message handling - void ProcessKeepAlive(); - void SendKeepAlive(const uint64 currentNetworkTime); - bool HandleTimeout(const uint64 currentNetworkTime); - - // Handle the reconnection request - bool HandleReconnect(AZSOCKET socket, const uint32 tryCount); - - // General send/receive functions with error handling. - // If socket error occurs the connection will be put in the lost state. - uint32 TrySend(const void* dataBuffer, uint32 dataSize, bool autoHandleErrors); - - // Internal receive function with error handling - uint32 TryReceive(void* dataBuffer, uint32 dataSize, bool autoHandleErrors); - - // Try to reconnect to the remote address - bool TryReconnect(); - - // Try to send the initialization header - bool TryInitialize(); - - // Low-level socket shutdown (hash way) - void Shutdown(); - - // Reset the connection (put in the lost state and reconnect) - void Reset(); -}; - -//----------------------------------------------------------------------------- - -// TCP/IP listener -class CServiceNetworkListener - : public IServiceNetworkListener -{ - typedef CServiceNetworkConnection::InitHeader TInitHeader; - - struct PendingConnection - { - // Connection socket - AZSOCKET m_socket; - - // Initialization of initialization header received so far - uint32 m_dataReceivedSoFar; - - // Initialization header - TInitHeader m_initHeader; - - // Remote address (as returned from accept) - ServiceNetworkAddress m_remoteAddress; - }; - -protected: - // Owner (the manager) - CServiceNetwork* m_pManager; - - // Reference count, updated using CryInterlocked* functions - int volatile m_refCount; - - // Listening socket - AZSOCKET m_socket; - - // Local address (usually has the IP in 127.0.0.1:port form) - ServiceNetworkAddress m_localAddress; - - // Request to close this listener was received - bool m_closeRequestReceived; - - // Pending connections (but not yet initialized) - typedef std::vector< PendingConnection* > TPendingConnectionList; - TPendingConnectionList m_pPendingConnections; - - // All active connections spawned from this listener - typedef std::vector< CServiceNetworkConnection* > TConnectionList; - TConnectionList m_pLocalConnections; - - // Access lock for the class members (thread safe) - CryMutex m_accessLock; - -public: - ILINE CServiceNetwork* GetManager() const - { - return m_pManager; - } - -public: - CServiceNetworkListener(CServiceNetwork* pManager, AZSOCKET socket, const ServiceNetworkAddress& address); - virtual ~CServiceNetworkListener(); - - void Update(); - - // IServiceNetworkListener interface implementation - virtual const ServiceNetworkAddress& GetLocalAddress() const; - virtual uint32 GetConnectionCount() const; - virtual IServiceNetworkConnection* Accept(); - virtual bool IsAlive() const; - virtual void AddRef(); - virtual void Release(); - virtual void Close(); - -private: - void ProcessIncomingConnections(); - void ProcessPendingConnections(); -}; - -//----------------------------------------------------------------------------- - -// TCP/IP manager for service connection channels -class CServiceNetwork - : public IServiceNetwork - , public CryRunnable -{ -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ServiceNetwork_h) -#endif - -protected: - struct ConnectionToClose - { - CServiceNetworkConnection* pConnection; - - // timeout for forded close - uint64 maxWaitTime; - }; - -protected: - // Local listeners - typedef std::vector< CServiceNetworkListener* > TListenerArray; - TListenerArray m_pListeners; - - // Local connections - typedef std::vector< CServiceNetworkConnection* > TConnectionArray; - TConnectionArray m_pConnections; - - // Connections that are waiting for all of their data to be sent before closing - typedef std::vector< ConnectionToClose > TConnectionsToCloseArray; - TConnectionsToCloseArray m_connectionsToClose; - - // We are running on threads, needed to sync the access to arrays - CryMutex m_accessMutex; - - // Current network time (ms) - uint64 m_networkTime; - - // Exit was requested - bool m_bExitRequested; - - // Message verbose level - ICVar* m_pVerboseLevel; - - // Thread - typedef CryThread< CServiceNetwork > TServiceNetworkThread; - TServiceNetworkThread* m_pThread; - - // Buffer ID allocator (unique, incremented atomically using CryInterlockedIncrement) - volatile int m_bufferID; - - // Random number generator for GUID creation - CRndGen m_guidGenerator; - - // Send/Receive queue size limit - ICVar* m_pReceiveDataQueueLimit; - ICVar* m_pSendDataQueueLimit; - -public: - ILINE const uint64 GetNetworkTime() const - { - return m_networkTime; - } - - ILINE const CServiceNetwork* GetManager() const - { - return this; - } - - ILINE const uint32 GetReceivedDataQueueLimit() const - { - return m_pReceiveDataQueueLimit->GetIVal(); - } - - ILINE const uint32 GetSendDataQueueLimit() const - { - return m_pSendDataQueueLimit->GetIVal(); - } - -public: - CServiceNetwork(); - virtual ~CServiceNetwork(); - - // IServiceNetwork interface implementation - virtual void SetVerbosityLevel(const uint32 level); - virtual IServiceNetworkMessage* AllocMessageBuffer(const uint32 size); - virtual struct IDataWriteStream* CreateMessageWriter(); - virtual struct IDataReadStream* CreateMessageReader(const void* pData, const uint32 dataSize); - virtual ServiceNetworkAddress GetHostAddress(const string& addressString, uint16 optionalPort = 0) const; - virtual IServiceNetworkListener* CreateListener(uint16 localPort); - virtual IServiceNetworkConnection* Connect(const ServiceNetworkAddress& remoteAddress); - - // CryRunnable - virtual void Run(); - virtual void Cancel(); - - // Register connection in the connection list (thread safe) - void RegisterConnection(CServiceNetworkConnection& con); - - // Register connection for closing one all of the outgoing messages are sent - void RegisterForDeferredClose(CServiceNetworkConnection& con, const uint32 timeout); - - // Debug print -#ifdef RELEASE - void Log([[maybe_unused]] const char* txt, ...) const {}; - bool CheckVerbose([[maybe_unused]] const uint32 level) const { return false; } -#else - void Log(const char* txt, ...) const; - bool CheckVerbose(const uint32 level) const; -#endif -}; - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/System.cpp b/Code/CryEngine/CrySystem/System.cpp index 31eb286a17..8a8cf14d91 100644 --- a/Code/CryEngine/CrySystem/System.cpp +++ b/Code/CryEngine/CrySystem/System.cpp @@ -121,7 +121,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include #include -#include #include #include #include @@ -145,7 +144,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" -#include "Serialization/ArchiveHost.h" #include "SystemEventDispatcher.h" #include "ServerThrottle.h" #include "ResourceManager.h" @@ -445,7 +443,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_pXMLUtils = new CXmlUtils(this); - m_pArchiveHost = Serialization::CreateArchiveHost(); m_pMemoryManager = CryGetIMemoryManager(); m_pThreadTaskManager = new CThreadTaskManager; m_pResourceManager = new CResourceManager; @@ -499,7 +496,6 @@ CSystem::~CSystem() CRY_ASSERT(m_windowMessageHandlers.empty() && "There exists a dangling window message handler somewhere"); SAFE_DELETE(m_pXMLUtils); - SAFE_DELETE(m_pArchiveHost); SAFE_DELETE(m_pThreadTaskManager); SAFE_DELETE(m_pResourceManager); SAFE_DELETE(m_pSystemEventDispatcher); @@ -671,7 +667,6 @@ void CSystem::ShutDown() SAFE_DELETE(m_env.pResourceCompilerHelper); SAFE_RELEASE(m_env.pMovieSystem); - SAFE_DELETE(m_env.pServiceNetwork); SAFE_RELEASE(m_env.pLyShine); SAFE_RELEASE(m_env.pCryFont); if (m_env.pConsole) diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index 5f87fd1ad1..c4f3bfabd6 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -42,7 +42,6 @@ namespace AzFramework struct IConsoleCmdArgs; class CServerThrottle; -struct ICryFactoryRegistryImpl; struct IZLibCompressor; class CWatchdogThread; class CThreadManager; @@ -486,8 +485,6 @@ public: virtual IXmlUtils* GetXmlUtils(); ////////////////////////////////////////////////////////////////////////// - virtual Serialization::IArchiveHost* GetArchiveHost() const { return m_pArchiveHost; } - void SetViewCamera(CCamera& Camera){ m_ViewCamera = Camera; } CCamera& GetViewCamera() { return m_ViewCamera; } @@ -584,15 +581,11 @@ public: // static as memReplay needs it before CSystem has been setup - expose a ISystem interface to this function if you need it outside CrySystem static void debug_GetCallStackRaw(void** callstack, uint32& callstackLength); - virtual ICryFactoryRegistry* GetCryFactoryRegistry() const; - public: #if !defined(RELEASE) void SetVersionInfo(const char* const szVersion); #endif - virtual bool InitializeEngineModule(const char* dllName, const char* moduleClassName, const SSystemInitParams& initParams) override; - virtual bool UnloadEngineModule(const char* dllName, const char* moduleClassName); virtual const IImageHandler* GetImageHandler() const override { return m_imageHandler.get(); } void ShutdownModuleLibraries(); @@ -809,8 +802,6 @@ private: // ------------------------------------------------------ // XML Utils interface. class CXmlUtils* m_pXMLUtils; - Serialization::IArchiveHost* m_pArchiveHost; - int m_iApplicationInstance; //! to hold the values stored in system.cfg diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index 83ef4fcd2b..8bf2fb8930 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -46,8 +46,6 @@ #include #include -#include -#include #include // for AZ_MAX_PATH_LEN #include #include @@ -113,16 +111,12 @@ #include "ResourceManager.h" #include "MTSafeAllocator.h" #include "NotificationNetwork.h" -#include "ExtensionSystem/CryFactoryRegistryImpl.h" -#include "ExtensionSystem/TestCases/TestExtensions.h" #include "ProfileLogSystem.h" #include "SoftCode/SoftCodeMgr.h" #include "ZLibCompressor.h" #include "ZLibDecompressor.h" #include "ZStdDecompressor.h" #include "LZ4Decompressor.h" -#include "ServiceNetwork.h" -#include "RemoteCommand.h" #include "LevelSystem/LevelSystem.h" #include "LevelSystem/SpawnableLevelSystem.h" #include "ViewSystem/ViewSystem.h" @@ -856,148 +850,6 @@ bool CSystem::UnloadDLL(const char* dllName) return isSuccess; } -////////////////////////////////////////////////////////////////////////// -bool CSystem::InitializeEngineModule(const char* dllName, const char* moduleClassName, const SSystemInitParams& initParams) -{ - bool bResult = false; - - stack_string msg; - msg = "Initializing "; - AZStd::string dll = dllName; - - // Strip off Cry if the dllname is Cry - if (dll.find("Cry") == 0) - { - msg += dll.substr(3).c_str(); - } - else - { - msg += dllName; - } - msg += "..."; - - if (m_pUserCallback) - { - m_pUserCallback->OnInitProgress(msg.c_str()); - } - AZ_TracePrintf(moduleClassName, "%s", msg.c_str()); - - IMemoryManager::SProcessMemInfo memStart, memEnd; - if (GetIMemoryManager()) - { - GetIMemoryManager()->GetProcessMemInfo(memStart); - } - else - { - ZeroStruct(memStart); - } - - stack_string dllfile = ""; - - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_16 -#include AZ_RESTRICTED_FILE(SystemInit_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - - dllfile.append(dllName); - -#if defined(LINUX) - dllfile = "lib" + PathUtil::ReplaceExtension(dllfile, "so"); -#ifndef LINUX - dllfile.MakeLower(); -#endif -#elif defined(AZ_PLATFORM_MAC) - dllfile = "lib" + PathUtil::ReplaceExtension(dllfile, "dylib"); -#elif defined(AZ_PLATFORM_IOS) - PathUtil::RemoveExtension(dllfile); -#else - dllfile = PathUtil::ReplaceExtension(dllfile, "dll"); -#endif - -#endif - -#if !defined(AZ_MONOLITHIC_BUILD) - - m_moduleDLLHandles.insert(std::make_pair(dllfile.c_str(), LoadDLL(dllfile.c_str()))); - if (!m_moduleDLLHandles[dllfile.c_str()]) - { - return bResult; - } - -#endif // #if !defined(AZ_MONOLITHIC_BUILD) - - AZStd::shared_ptr pModule; - if (CryCreateClassInstance(moduleClassName, pModule)) - { - bResult = pModule->Initialize(m_env, initParams); - - // After initializing the module, give it a chance to register any AZ console vars - // declared within the module. - pModule->RegisterConsoleVars(); - } - - if (GetIMemoryManager()) - { - GetIMemoryManager()->GetProcessMemInfo(memEnd); - -#if defined(AZ_ENABLE_TRACING) - uint64 memUsed = memEnd.WorkingSetSize - memStart.WorkingSetSize; -#endif - AZ_TracePrintf(AZ_TRACE_SYSTEM_WINDOW, "Initializing %s %s, MemUsage=%uKb", dllName, pModule ? "done" : "failed", uint32(memUsed / 1024)); - } - - return bResult; -} - -////////////////////////////////////////////////////////////////////////// -bool CSystem::UnloadEngineModule(const char* dllName, const char* moduleClassName) -{ - bool isSuccess = false; - - // Remove the factory. - ICryFactoryRegistryImpl* const pReg = static_cast(GetCryFactoryRegistry()); - - if (pReg != nullptr) - { - ICryFactory* pICryFactory = pReg->GetFactory(moduleClassName); - - if (pICryFactory != nullptr) - { - pReg->UnregisterFactory(pICryFactory); - } - } - - stack_string msg; - msg = "Unloading "; - msg += dllName; - msg += "..."; - - AZ_TracePrintf(AZ_TRACE_SYSTEM_WINDOW, "%s", msg.c_str()); - - stack_string dllfile = dllName; - -#if defined(LINUX) - dllfile = "lib" + PathUtil::ReplaceExtension(dllfile, "so"); -#ifndef LINUX - dllfile.MakeLower(); -#endif -#elif defined(APPLE) - dllfile = "lib" + PathUtil::ReplaceExtension(dllfile, "dylib"); -#else - dllfile = PathUtil::ReplaceExtension(dllfile, "dll"); -#endif - -#if !defined(AZ_MONOLITHIC_BUILD) - isSuccess = UnloadDLL(dllfile.c_str()); -#endif // #if !defined(AZ_MONOLITHIC_BUILD) - - return isSuccess; -} - ////////////////////////////////////////////////////////////////////////// void CSystem::ShutdownModuleLibraries() { @@ -1872,12 +1724,6 @@ bool CSystem::Init(const SSystemInitParams& startupParams) AZ_Assert(CryMemory::IsHeapValid(), "Memory heap must be valid before continuing SystemInit."); -#ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES - TestExtensions(&CCryFactoryRegistryImpl::Access()); -#endif - - //_controlfp(0, _EM_INVALID|_EM_ZERODIVIDE | _PC_64 ); - #if defined(WIN32) || defined(WIN64) // check OS version - we only want to run on XP or higher - talk to Martin Mittring if you want to change this { @@ -2412,8 +2258,6 @@ AZ_POP_DISABLE_WARNING } InlineInitializationProcessing("CSystem::Init InitShine"); - - ////////////////////////////////////////////////////////////////////////// // CONSOLE ////////////////////////////////////////////////////////////////////////// if (!InitConsole()) @@ -2421,22 +2265,6 @@ AZ_POP_DISABLE_WARNING return false; } - ////////////////////////////////////////////////////////////////////////// - // SERVICE NETWORK - ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bSkipNetwork && !startupParams.bMinimal) - { - m_env.pServiceNetwork = new CServiceNetwork(); - } - - ////////////////////////////////////////////////////////////////////////// - // REMOTE COMMAND SYTSTEM - ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bSkipNetwork && !startupParams.bMinimal) - { - m_env.pRemoteCommandManager = new CRemoteCommandManager(); - } - if (m_pUserCallback) { m_pUserCallback->OnInitProgress("Initializing additional systems..."); diff --git a/Code/CryEngine/CrySystem/XConsole.cpp b/Code/CryEngine/CrySystem/XConsole.cpp index ee5b500b0b..3b30a7eeed 100644 --- a/Code/CryEngine/CrySystem/XConsole.cpp +++ b/Code/CryEngine/CrySystem/XConsole.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "ConsoleHelpGen.h" // CConsoleHelpGen diff --git a/Code/CryEngine/CrySystem/crysystem_files.cmake b/Code/CryEngine/CrySystem/crysystem_files.cmake index 0b62483e43..5dc8a68f8b 100644 --- a/Code/CryEngine/CrySystem/crysystem_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_files.cmake @@ -55,13 +55,7 @@ set(FILES SystemScheduler.h UnixConsole.h SystemInit.h - Serialization/MemoryReader.h XML/ReadWriteXMLSink.h - Serialization/ArchiveHost.h - Serialization/MemoryWriter.h - Serialization/JSONIArchive.h - Serialization/JSONOArchive.h - Serialization/BinArchive.h AZCrySystemInitLogSink.h AZCoreLogSink.h CmdLine.h @@ -127,10 +121,6 @@ set(FILES ThreadConfigManager.h ThreadConfigManager.cpp SystemThreading.cpp - ExtensionSystem/CryFactoryRegistryImpl.cpp - ExtensionSystem/CryFactoryRegistryImpl.h - ExtensionSystem/TestCases/TestExtensions.cpp - ExtensionSystem/TestCases/TestExtensions.h ZLibCompressor.cpp ZLibCompressor.h SoftCode/SoftCodeMgr.cpp @@ -141,14 +131,6 @@ set(FILES RemoteConsole/RemoteConsole.h RemoteConsole/RemoteConsole_impl.inl RemoteConsole/RemoteConsole_none.inl - ServiceNetwork.cpp - ServiceNetwork.h - RemoteCommand.cpp - RemoteCommand.h - RemoteCommandHelpers.cpp - RemoteCommandHelpers.h - RemoteCommandServer.cpp - RemoteCommandClient.cpp ZLibDecompressor.h ZLibDecompressor.cpp LZ4Decompressor.h @@ -165,17 +147,6 @@ set(FILES ViewSystem/ViewSystem.h ZStdDecompressor.h ZStdDecompressor.cpp - Serialization/ArchiveHost.cpp - Serialization/BinArchive.cpp - Serialization/JSONIArchive.cpp - Serialization/JSONOArchive.cpp - Serialization/MemoryReader.cpp - Serialization/MemoryWriter.cpp - Serialization/Token.h - Serialization/XmlIArchive.cpp - Serialization/XmlIArchive.h - Serialization/XmlOArchive.cpp - Serialization/XmlOArchive.h StreamEngine/StreamAsyncFileRequest.cpp StreamEngine/StreamAsyncFileRequest_Jobs.cpp StreamEngine/StreamEngine.cpp diff --git a/Code/CryEngine/CrySystem/crysystem_test_files.cmake b/Code/CryEngine/CrySystem/crysystem_test_files.cmake index fc236afcf3..a57ba57f77 100644 --- a/Code/CryEngine/CrySystem/crysystem_test_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_test_files.cmake @@ -11,7 +11,6 @@ set(FILES Components/MathConversionTests.cpp - Serialization/Test_ArchiveHost.cpp Tests/Test_CLog.cpp Tests/Test_CommandRegistration.cpp Tests/Test_CryPrimitives.cpp diff --git a/Code/Sandbox/Editor/Controls/CurveEditorCtrl.cpp b/Code/Sandbox/Editor/Controls/CurveEditorCtrl.cpp deleted file mode 100644 index f66943b07d..0000000000 --- a/Code/Sandbox/Editor/Controls/CurveEditorCtrl.cpp +++ /dev/null @@ -1,821 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "CurveEditorCtrl.h" - -// Qt -#include -#include - -namespace CurveEditor -{ - const int kHandleSize = 6; - const int kHandleSizeHalf = kHandleSize / 2; - const int kDefaultPadding = 10; - const int kInfoFontSize = 7; - const int kGrid = 4; - const QColor kColor_SelectCross(132, 132, 132); - const QColor kColor_DisabledCross(90, 90, 90); - const QColor kColor_MiddleLines(80, 80, 80); - const QColor kColor_Background(41, 41, 41); - const QColor kColor_Disabled(60, 60, 60); - const QColor kColor_PaddingBorder(128, 128, 128); - const QColor kColor_Text(128, 128, 128); - const QColor kColor_TextCrtPos(187, 187, 187); - const QColor kColor_Curve(255, 0, 0); - const QColor kColor_SelHandle(200, 200, 200); - const QColor kColor_NormalHandle(30, 30, 30); - const QColor kColor_HandleLight(60, 60, 60); - const QColor kColor_HandleShadow(0, 0, 0); - const QColor kColor_MarkLines(0, 255, 0); -} - - -CCurveEditorCtrl::CCurveEditorCtrl(QWidget* parent) - : QWidget(parent) -{ - m_domainMinX = 0.0f; - m_domainMinY = 0.0f; - m_domainMaxX = 1.0f; - m_domainMaxY = 1.0f; - m_bMouseDown = m_bDragging = false; - m_bAllowMouse = true; - m_padding = CurveEditor::kDefaultPadding; - m_flags = eFlag_ShowVerticalRuler - | eFlag_ShowHorizontalRuler - | eFlag_ShowVerticalRulerText - | eFlag_ShowHorizontalRulerText - | eFlag_ShowPaddingBorder - | eFlag_ShowMovingPointAxis - | eFlag_ShowPointHandles; - m_gridSplits.set(CurveEditor::kGrid, CurveEditor::kGrid); - m_fntInfo.setFamily("Arial"); - m_fntInfo.setPointSize(CurveEditor::kInfoFontSize); - m_bHovered = false; - m_selCrossPen = QPen(CurveEditor::kColor_SelectCross); - - GenerateDefaultCurve(); -} - -CCurveEditorCtrl::~CCurveEditorCtrl() -{ -} - -void CCurveEditorCtrl::SetFlags(UINT aFlags) -{ - m_flags = aFlags; -} - -UINT CCurveEditorCtrl::GetFlags() const -{ - return m_flags; -} - -bool CCurveEditorCtrl::SetDomainBounds(float aMinX, float aMinY, float aMaxX, float aMaxY) -{ - assert(aMinX < aMaxX); - assert(aMinY < aMaxY); - - if (aMinX >= aMaxX) - { - return false; - } - - if (aMinY >= aMaxY) - { - return false; - } - - m_domainMinX = aMinX; - m_domainMinY = aMinY; - m_domainMaxX = aMaxX; - m_domainMaxY = aMaxY; - - return true; -} - -void CCurveEditorCtrl::GetDomainBounds(float& rMinX, float& rMinY, float& rMaxX, float& rMaxY) const -{ - rMinX = m_domainMinX; - rMinY = m_domainMinY; - rMaxX = m_domainMaxX; - rMaxY = m_domainMaxY; -} - -void CCurveEditorCtrl::SetGrid(UINT aHorizontalSplits, UINT aVerticalSplits, const QStringList& labelsX, const QStringList& labelsY) -{ - assert(aHorizontalSplits); - assert(aVerticalSplits); - - if (!aHorizontalSplits) - { - // defaults - aHorizontalSplits = 2; - } - - if (!aVerticalSplits) - { - // defaults - aVerticalSplits = 2; - } - - m_gridSplits.x = aHorizontalSplits; - m_gridSplits.y = aVerticalSplits; - - if (!labelsX.isEmpty()) - { - m_labelsX = labelsX; - } - - if (!labelsY.isEmpty()) - { - m_labelsY = labelsY; - } -} - -QPoint CCurveEditorCtrl::ProjectPoint(float x, float y) -{ - QPoint pt; - - pt.setX(m_padding + (width() - m_padding * 2) * (x - m_domainMinX) / (m_domainMaxX - m_domainMinX)); - pt.setY(m_padding + (height() - m_padding * 2) * (1.0f - (y - m_domainMinY) / (m_domainMaxY - m_domainMinY))); - - return pt; -} - -Vec2 CCurveEditorCtrl::UnprojectPoint(const QPoint& pt) -{ - Vec2 vec; - int y = height() - pt.y(); - float dx = (width() - m_padding * 2); - float dy = (height() - m_padding * 2); - const float kEpsilon = 0.00000001f; - - if (fabs(dx) <= kEpsilon) - { - dx = 1.0f; - } - - if (fabs(dy) <= kEpsilon) - { - dy = 1.0f; - } - - vec.x = m_domainMinX + (float)(pt.x() - m_padding) / dx * (m_domainMaxX - m_domainMinX); - vec.y = m_domainMinY + (float)(y - m_padding) / dy * (m_domainMaxY - m_domainMinY); - - return vec; -} - -void CCurveEditorCtrl::SetControlPointCount(UINT aCount) -{ - m_points.resize(aCount); - m_projectedPoints.clear(); -} - -UINT CCurveEditorCtrl::GetControlPointCount() const -{ - return m_points.size(); -} - -void CCurveEditorCtrl::AddControlPoint(const Vec2& rPosition) -{ - m_points.push_back(CurvePoint(rPosition.x, rPosition.y)); -} - -void CCurveEditorCtrl::ClearControlPoints() -{ - m_points.clear(); -} - -void CCurveEditorCtrl::SetControlPoint(UINT aIndex, const Vec2& rPosition) -{ - assert(aIndex < m_points.size()); - - if (aIndex >= m_points.size()) - { - return; - } - - m_points[aIndex].pos = rPosition; -} - -void CCurveEditorCtrl::SetControlPointTangents(UINT aIndex, const Vec2& rLeft, const Vec2& rRight) -{ - assert(aIndex < m_points.size()); - - if (aIndex >= m_points.size()) - { - return; - } - - m_points[aIndex].tanA = rLeft; - m_points[aIndex].tanB = rRight; -} - -void CCurveEditorCtrl::GetControlPoint(UINT aIndex, Vec2& rOutPosition) const -{ - assert(aIndex < m_points.size()); - - if (aIndex >= m_points.size()) - { - return; - } - - rOutPosition = m_points[aIndex].pos; -} - -void CCurveEditorCtrl::GetControlPointTangents(UINT aIndex, Vec2& rOutLeft, Vec2& rOutRight) const -{ - assert(aIndex < m_points.size()); - - if (aIndex >= m_points.size()) - { - return; - } - - rOutLeft = m_points[aIndex].tanA; - rOutRight = m_points[aIndex].tanB; -} - -void CCurveEditorCtrl::paintEvent(QPaintEvent* event) -{ - QWidget::paintEvent(event); - - QPainter dc(this); - - QRect rc = geometry(); - QString str; - QRect textSize; - - dc.setFont(m_fntInfo); - QFontMetrics fntMetrics(m_fntInfo); - - if (m_flags & eFlag_Disabled) - { - // If disabled, just draw a blank square. - dc.fillRect(rc, CurveEditor::kColor_Disabled); - - dc.setPen(CurveEditor::kColor_DisabledCross); - dc.drawLine(0, 0, rc.width(), rc.height()); - - dc.drawLine(rc.width(), 0, 0, rc.height()); - return; - } - - dc.fillRect(rc, CurveEditor::kColor_Background); - - dc.setPen(CurveEditor::kColor_MiddleLines); - - if (m_flags & eFlag_ShowVerticalRuler) - { - float y = m_domainMinY; - float grid = (m_domainMaxY - m_domainMinY) / m_gridSplits.y; - QPoint p; - - for (int i = 0; i <= m_gridSplits.y; ++i) - { - p = ProjectPoint(0, y); - dc.drawLine(m_padding, p.y(), rc.width() - m_padding, p.y()); - - if (m_flags & eFlag_ShowVerticalRulerText) - { - if (m_labelsY.empty()) - { - str.asprintf("%0.2f", y); - } - else - { - str = m_labelsY[i]; - } - textSize = fntMetrics.tightBoundingRect(str); - dc.drawText(2, p.y(), str); - } - - y += grid; - } - } - - if (m_flags & eFlag_ShowHorizontalRuler) - { - float x = m_domainMinX; - float grid = (m_domainMaxX - m_domainMinX) / m_gridSplits.x; - QPoint p; - - for (int i = 0; i <= m_gridSplits.x; ++i) - { - p = ProjectPoint(x, 0); - dc.drawLine(p.x(), m_padding, p.x(), rc.height() - m_padding); - - if (m_flags & eFlag_ShowHorizontalRulerText) - { - if (m_labelsX.empty()) - { - str.asprintf("%0.2f", x); - } - else - { - str = m_labelsX[i]; - } - textSize = fntMetrics.tightBoundingRect(str); - - p.setX(p.x() + 2); - - if (p.x() + textSize.width() > width()) - { - p.setX(width() - textSize.width()); - } - - dc.drawText(p.x(), height() - m_padding + textSize.height() + 2, str); - } - - x += grid; - } - } - - dc.setPen(CurveEditor::kColor_MarkLines); - - if (m_flags & eFlag_ShowVerticalRuler) - { - QPoint p; - for (size_t i = 0; i < m_marksY.size(); ++i) - { - float v = m_marksY[i]; - if (v < m_domainMinY || v > m_domainMaxY) - { - continue; - } - p = ProjectPoint(0, v); - dc.drawLine(m_padding, p.y(), width() - m_padding, p.y()); - } - } - - if (m_flags & eFlag_ShowHorizontalRuler) - { - QPoint p; - for (size_t i = 0; i < m_marksX.size(); ++i) - { - float v = m_marksX[i]; - if (v < m_domainMinX || v > m_domainMaxX) - { - continue; - } - p = ProjectPoint(v, 0); - dc.drawLine(p.x(), m_padding, p.x(), height() - m_padding); - } - } - - if (m_flags & eFlag_ShowPaddingBorder) - { - dc.setPen(CurveEditor::kColor_PaddingBorder); - dc.drawRect(m_padding, m_padding, width() - m_padding * 2, height() - m_padding * 2); - } - - if (m_bDragging - && !m_selectedIndices.empty() - && (m_flags & eFlag_ShowMovingPointAxis)) - { - const Vec2& crtPos = m_points[m_selectedIndices[0]].pos; - - dc.setBrush(CurveEditor::kColor_TextCrtPos); - str.asprintf("(%0.2f,%0.2f)", crtPos.x, crtPos.y); - textSize = fntMetrics.tightBoundingRect(str); - const int kOffsetFromPointer = 5; - QPoint txtPos(m_lastMousePoint.x() + kOffsetFromPointer, m_lastMousePoint.y() + kOffsetFromPointer); - - if (txtPos.x() + textSize.width() > width()) - { - txtPos.setX(width() - textSize.width()); - } - - if (txtPos.y() + textSize.height() > height()) - { - txtPos.setY(height() - textSize.height()); - } - - dc.drawText(txtPos, str); - } - - ComputeTangents(); - UpdateProjectedPoints(); - - // for curve debug, tangents poly, don't delete - // dc.setPen(Qt::black); - // dc.drawPolyline(m_projectedPoints.data(), m_projectedPoints.size()); - - dc.setPen(CurveEditor::kColor_Curve); - - // curve - QPainterPath bezierPath; - bezierPath.moveTo(m_projectedPoints[0]); - for (int i = 1; i < m_projectedPoints.size(); i += 3) - { - bezierPath.cubicTo(m_projectedPoints[i], m_projectedPoints[i + 1], m_projectedPoints[i + 2]); - } - dc.drawPath(bezierPath); - - // curve control point handles - if (m_flags & eFlag_ShowPointHandles) - { - for (size_t i = 0; i < m_points.size(); ++i) - { - QPoint ptProj = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y); - QRect rcHandle(0, 0, CurveEditor::kHandleSize, CurveEditor::kHandleSize); - rcHandle.moveCenter(ptProj); - - std::vector::iterator iter = - std::find(m_selectedIndices.begin(), m_selectedIndices.end(), i); - - bool bSelected = (iter != m_selectedIndices.end()); - - if (bSelected && m_bDragging) - { - dc.setPen(m_selCrossPen); - dc.drawLine(0, ptProj.y(), width(), ptProj.y()); - dc.drawLine(ptProj.x(), 0, ptProj.x(), height()); - } - - dc.fillRect(rcHandle, bSelected - ? CurveEditor::kColor_SelHandle - : CurveEditor::kColor_NormalHandle); - - dc.setPen(CurveEditor::kColor_HandleLight); - dc.drawLine(ptProj.x() - CurveEditor::kHandleSizeHalf, ptProj.y() - CurveEditor::kHandleSizeHalf, - ptProj.x() - CurveEditor::kHandleSizeHalf, ptProj.y() + CurveEditor::kHandleSizeHalf); - dc.drawLine(ptProj.x() - CurveEditor::kHandleSizeHalf, ptProj.y() + CurveEditor::kHandleSizeHalf, - ptProj.x() + CurveEditor::kHandleSizeHalf, ptProj.y() + CurveEditor::kHandleSizeHalf); - dc.setPen(CurveEditor::kColor_HandleShadow); - dc.drawLine(ptProj.x() + CurveEditor::kHandleSizeHalf, ptProj.y() + CurveEditor::kHandleSizeHalf, - ptProj.x() + CurveEditor::kHandleSizeHalf, ptProj.y() - CurveEditor::kHandleSizeHalf); - dc.drawLine(ptProj.x() + CurveEditor::kHandleSizeHalf, ptProj.y() - CurveEditor::kHandleSizeHalf, - ptProj.x() - CurveEditor::kHandleSizeHalf, ptProj.y() - CurveEditor::kHandleSizeHalf); - } - } -} - -void CCurveEditorCtrl::ComputeTangents() -{ - for (size_t i = 0; i < m_points.size(); ++i) - { - m_points[i].tanA = m_points[i].pos; - m_points[i].tanB = m_points[i].pos; - } - - int maxIndex = m_points.size() - 1; - - for (size_t i = 0; i < m_points.size(); ++i) - { - if (i > maxIndex) - { - break; - } - - Vec2& p2 = m_points[i].pos; - Vec2& back = m_points[i].tanA; - Vec2& forw = m_points[i].tanB; - const float kEpsilon = 0.000001f; - - // first point - if (i == 0) - { - back = p2; - - if (maxIndex == 1) - { - Vec2& p3 = m_points[i + 1].pos; - forw = p2 + (p3 - p2) / 3.0f; - } - else if (maxIndex > 0) - { - Vec2& p3 = m_points[i + 1].pos; - Vec2& pb3 = m_points[i + 1].tanA; - - float lenOsn = (pb3 - p2).GetLength(); - float lenb = (p3 - p2).GetLength(); - - if (lenOsn > kEpsilon && lenb > kEpsilon) - { - forw = p2 + (pb3 - p2) / (lenOsn / lenb * 3.0f); - } - else - { - forw = p2; - } - } - } - - if (i == maxIndex) - { - forw = p2; - - if (i > 0) - { - Vec2& p1 = m_points[i - 1].pos; - Vec2& pf1 = m_points[i - 1].tanB; - - float lenOsn = (pf1 - p2).GetLength(); - float lenf = (p1 - p2).GetLength(); - - if (lenOsn > kEpsilon && lenf > kEpsilon) - { - back = p2 + (pf1 - p2) / (lenOsn / lenf * 3.0f); - } - else - { - back = p2; - } - } - } - else if (i >= 1 && i <= maxIndex - 1) - { - Vec2& p1 = m_points[i - 1].pos; - Vec2& p3 = m_points[i + 1].pos; - - float lenOsn = (p3 - p1).GetLength(); - float lenb = (p1 - p2).GetLength(); - float lenf = (p3 - p2).GetLength(); - - if (lenOsn > kEpsilon - && lenf > kEpsilon - && lenb > kEpsilon) - { - back = p2 + (p1 - p3) * (lenb / lenOsn / 3.0f); - forw = p2 + (p3 - p1) * (lenf / lenOsn / 3.0f); - } - } - - ClampToDomain(back); - ClampToDomain(forw); - } - - // fix tangents in relation of one to another - for (size_t i = 0; i < m_points.size(); ++i) - { - Vec2& p = m_points[i].pos; - Vec2& tanA = m_points[i].tanA; - Vec2& tanB = m_points[i].tanB; - - if (i < m_points.size() - 1) - { - if (tanB.x > m_points[i + 1].tanA.x) - { - tanB.x = (m_points[i + 1].pos.x + p.x) * 0.5f; - } - } - if (i > 0) - { - if (tanA.x < m_points[i - 1].tanB.x) - { - tanA.x = (m_points[i - 1].pos.x + p.x) * 0.5f; - } - } - } -} - -void CCurveEditorCtrl::UpdateProjectedPoints() -{ - m_projectedPoints.resize(m_points.size() * 3 - 2); - - int numPts = 0; - - for (size_t i = 0; i < m_points.size(); ++i) - { - if (i == 0) - { - m_projectedPoints[numPts++] = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y); - m_projectedPoints[numPts++] = ProjectPoint(m_points[i].tanB.x, m_points[i].tanB.y); - } - else if (i == m_points.size() - 1) - { - m_projectedPoints[numPts++] = ProjectPoint(m_points[i].tanA.x, m_points[i].tanA.y); - m_projectedPoints[numPts++] = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y); - } - else - { - m_projectedPoints[numPts++] = ProjectPoint(m_points[i].tanA.x, m_points[i].tanA.y); - m_projectedPoints[numPts++] = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y); - m_projectedPoints[numPts++] = ProjectPoint(m_points[i].tanB.x, m_points[i].tanB.y); - } - } -} - -void CCurveEditorCtrl::ClampToDomain(Vec2& rVec) -{ - if (rVec.x < m_domainMinX) - { - rVec.x = m_domainMinX; - } - else if (rVec.x > m_domainMaxX) - { - rVec.x = m_domainMaxX; - } - - if (rVec.y < m_domainMinY) - { - rVec.y = m_domainMinY; - } - else if (rVec.y > m_domainMaxY) - { - rVec.y = m_domainMaxY; - } -} - -void CCurveEditorCtrl::GenerateDefaultCurve() -{ - m_points.clear(); - m_domainMinX = 0.0f; - m_domainMinY = 0.0f; - m_domainMaxX = 1.0f; - m_domainMaxY = 1.0f; - m_points.push_back(CurvePoint(0.00f, 0.00f)); - m_points.push_back(CurvePoint(0.25f, 0.25f)); - m_points.push_back(CurvePoint(0.50f, 0.50f)); - m_points.push_back(CurvePoint(0.75f, 0.75f)); - m_points.push_back(CurvePoint(1.00f, 1.00f)); -} - -void CCurveEditorCtrl::mousePressEvent(QMouseEvent* event) -{ - QWidget::mousePressEvent(event); - if (event->button() != Qt::LeftButton) - { - return; - } - - const QPoint point = event->pos(); - if (m_bAllowMouse) - { - bool bSimpleSelect = !(event->modifiers() & Qt::ShiftModifier) && !(event->modifiers() & Qt::ControlModifier); - - if (bSimpleSelect) - { - m_selectedIndices.clear(); - } - - for (size_t i = 0; i < m_points.size(); ++i) - { - QPoint ptProj = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y); - - QRect rcHandle(0, 0, CurveEditor::kHandleSize, CurveEditor::kHandleSize); - rcHandle.moveCenter(ptProj); - - if (rcHandle.contains(point)) - { - if (bSimpleSelect) - { - m_selectedIndices.push_back(i); - break; - } - - if (event->modifiers() & Qt::ShiftModifier) - { - m_selectedIndices.push_back(i); - } - else if (event->modifiers() & Qt::ControlModifier) - { - std::vector::iterator iter = - std::find(m_selectedIndices.begin(), m_selectedIndices.end(), i); - - if (iter == m_selectedIndices.end()) - { - m_selectedIndices.push_back(i); - } - else - { - m_selectedIndices.erase(iter); - } - } - } - } - - m_bMouseDown = true; - m_lastMousePoint = point; - } - - grabMouse(); - update(); -} - -void CCurveEditorCtrl::mouseReleaseEvent(QMouseEvent* event) -{ - QWidget::mouseReleaseEvent(event); - if (event->button() != Qt::LeftButton) - { - return; - } - - m_bMouseDown = false; - m_bDragging = false; - m_selectedIndices.clear(); - - releaseMouse(); - update(); -} - -void CCurveEditorCtrl::mouseMoveEvent(QMouseEvent* event) -{ - if (m_bMouseDown && !m_bDragging) - { - m_bDragging = true; - } - - m_bHovered = true; - if (m_flags & eFlag_ShowCursorAlways) - { - m_bHovered = true; - } - else - { - m_bHovered = false; - - for (size_t i = 0; i < m_points.size(); ++i) - { - QPoint ptProj = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y); - QRect rcHandle(0, 0, CurveEditor::kHandleSize, CurveEditor::kHandleSize); - rcHandle.moveCenter(ptProj); - - if (rcHandle.contains(event->pos())) - { - m_bHovered = true; - break; - } - } - } - - if (m_bDragging) - { - Vec2 v1 = UnprojectPoint(m_lastMousePoint); - Vec2 v2 = UnprojectPoint(event->pos()); - Vec2 v = v1 - v2; - - for (size_t i = 0; i < m_selectedIndices.size(); ++i) - { - int index = m_selectedIndices[i]; - CurvePoint& cpt = m_points[index]; - - // do not move first and last points on X - if (index > 0 && index < m_points.size() - 1) - { - cpt.pos.x -= v.x; - } - - cpt.pos.y -= v.y; - - // lets check if the point is overlapping its neighbours - if (index > 0 && (index - 1) > 0) - { - if (cpt.pos.x < m_points[index - 1].pos.x) - { - CurvePoint p = m_points[index]; - - // swap! - m_points[index] = m_points[index - 1]; - m_points[index - 1] = p; - m_selectedIndices[i] = index - 1; - } - } - - if (index < m_points.size() - 1 && (index + 1) < m_points.size() - 1) - { - if (cpt.pos.x > m_points[index + 1].pos.x) - { - CurvePoint p = m_points[index]; - - // swap! - m_points[index] = m_points[index + 1]; - m_points[index + 1] = p; - m_selectedIndices[i] = index + 1; - } - } - - ClampToDomain(cpt.pos); - } - - update(); - m_lastMousePoint = event->pos(); - } - - QWidget::mouseMoveEvent(event); -} - -void CCurveEditorCtrl::MarkX(float value) -{ - m_marksX.push_back(value); -} - -void CCurveEditorCtrl::MarkY(float value) -{ - m_marksY.push_back(value); -} diff --git a/Code/Sandbox/Editor/Controls/CurveEditorCtrl.h b/Code/Sandbox/Editor/Controls/CurveEditorCtrl.h deleted file mode 100644 index 52082febd7..0000000000 --- a/Code/Sandbox/Editor/Controls/CurveEditorCtrl.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITOR_CONTROLS_CURVEEDITORCTRL_H -#define CRYINCLUDE_EDITOR_CONTROLS_CURVEEDITORCTRL_H -#pragma once -#include "Util/GdiUtil.h" -#include -#include - - -class CCurveEditorCtrl - : public QWidget -{ -public: - enum EFlags - { - eFlag_ShowVerticalRuler = (1 << 0), - eFlag_ShowHorizontalRuler = (1 << 1), - eFlag_ShowVerticalRulerText = (1 << 2), - eFlag_ShowHorizontalRulerText = (1 << 3), - eFlag_ShowPaddingBorder = (1 << 4), - eFlag_ShowMovingPointAxis = (1 << 5), - eFlag_ShowPointHandles = (1 << 6), - eFlag_ShowCursorAlways = (1 << 7), - eFlag_Disabled = (1 << 8) // special case, when disabling preview window. - }; - - CCurveEditorCtrl(QWidget* parent); - virtual ~CCurveEditorCtrl(); - - void SetFlags(UINT aFlags); - UINT GetFlags() const; - void SetMouseEnable(bool bEnable = true) { m_bAllowMouse = bEnable; } - bool GetMouseEnable() const {return m_bAllowMouse; } - bool SetDomainBounds(float aMinX, float aMinY, float aMaxX, float aMaxY); - void GetDomainBounds(float& rMinX, float& rMinY, float& rMaxX, float& rMaxY) const; - // labelsX/labelsY must be null (to use default labels) - // or contain aHorizontalSplits+1/aVerticalSplits+1 items. - void SetGrid(UINT aHorizontalSplits, UINT aVerticalSplits, const QStringList& labelsX = QStringList(), const QStringList& labelsY = QStringList()); - void SetPadding(float padding) { m_padding = padding; } - void MarkX(float value); - void MarkY(float value); - void AddControlPoint(const Vec2& rPosition); - void ClearControlPoints(); - void SetControlPointCount(UINT aCount); - UINT GetControlPointCount() const; - void SetControlPoint(UINT aIndex, const Vec2& rPosition); - void SetControlPointTangents(UINT aIndex, const Vec2& rLeft, const Vec2& rRight); - void GetControlPoint(UINT aIndex, Vec2& rOutPosition) const; - void GetControlPointTangents(UINT aIndex, Vec2& rOutLeft, Vec2& rOutRight) const; - QPoint ProjectPoint(float x, float y); - Vec2 UnprojectPoint(const QPoint& pt); - void UpdateProjectedPoints(); - -protected: - struct CurvePoint - { - CurvePoint(float aX = 0.0f, float aY = 0.0f) - { - pos.x = aX; - pos.y = aY; - } - - Vec2 pos; - Vec2 tanA, tanB; - }; - - void ComputeTangents(); - void ClampToDomain(Vec2& rVec); - void GenerateDefaultCurve(); - - void paintEvent(QPaintEvent* event) override; - - std::vector m_points; - std::vector m_projectedPoints; - float m_domainMinX; - float m_domainMinY; - float m_domainMaxX; - float m_domainMaxY; - Vec2 m_gridSplits; - int m_padding; - bool m_bMouseDown, m_bDragging, m_bAllowMouse; - bool m_bHovered; - QPoint m_lastMousePoint; - std::vector m_selectedIndices; - QFont m_fntInfo; - QPen m_pen, m_selCrossPen; - UINT m_flags; - QStringList m_labelsX; - QStringList m_labelsY; - std::vector m_marksX; - std::vector m_marksY; - - void mousePressEvent(QMouseEvent* event) override; - void mouseReleaseEvent(QMouseEvent* event) override; - void mouseMoveEvent(QMouseEvent* event) override; -}; - - - -#endif // CRYINCLUDE_EDITOR_CONTROLS_CURVEEDITORCTRL_H diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index db37653cf1..8afcddd144 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -659,9 +659,6 @@ CBaseObject* EditorViewportWidget::GetCameraObject() const ////////////////////////////////////////////////////////////////////////// void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) { - static ICVar* outputToHMD = gEnv->pConsole->GetCVar("output_to_hmd"); - AZ_Assert(outputToHMD, "cvar output_to_hmd is undeclared"); - switch (event) { case eNotify_OnBeginGameMode: @@ -683,7 +680,6 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) if (deviceInfo) { // Note: This may also need to adjust the viewport size - outputToHMD->Set(1); SetActiveWindow(); SetFocus(); SetSelected(true); @@ -703,10 +699,6 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) if (GetIEditor()->GetViewManager()->GetGameViewport() == this) { SetCurrentCursor(STD_CURSOR_DEFAULT); - if (gSettings.bEnableGameModeVR) - { - outputToHMD->Set(0); - } m_bInRotateMode = false; m_bInMoveMode = false; m_bInOrbitMode = false; diff --git a/Code/Sandbox/Editor/IEditorImpl.cpp b/Code/Sandbox/Editor/IEditorImpl.cpp index 95091a5992..fb9b737733 100644 --- a/Code/Sandbox/Editor/IEditorImpl.cpp +++ b/Code/Sandbox/Editor/IEditorImpl.cpp @@ -71,7 +71,6 @@ AZ_POP_DISABLE_WARNING #include "EditorFileMonitor.h" #include "MainStatusBar.h" -#include "SettingsBlock.h" #include "ResourceSelectorHost.h" #include "Util/FileUtil_impl.h" #include "Util/ImageUtil_impl.h" @@ -1624,8 +1623,6 @@ ESystemConfigPlatform CEditorImpl::GetEditorConfigPlatform() const void CEditorImpl::InitFinished() { - SProjectSettingsBlock::Load(); - if (!m_bInitialized) { m_bInitialized = true; diff --git a/Code/Sandbox/Editor/Include/IResourceSelectorHost.h b/Code/Sandbox/Editor/Include/IResourceSelectorHost.h index f9245f97a4..43586f6cba 100644 --- a/Code/Sandbox/Editor/Include/IResourceSelectorHost.h +++ b/Code/Sandbox/Editor/Include/IResourceSelectorHost.h @@ -28,16 +28,6 @@ // } // REGISTER_RESOURCE_SELECTOR("Sound", SoundFileSelector, "Icons/sound_16x16.png") // -// To expose it to serialization: -// -// #include "Serialization/Decorators/Resources.h" -// template -// ResourceSelector SoundName(TString& s) { return ResourceSelector(s, "Sound"); } -// -// To use in serialization: -// -// ar(Serialization::SoundName(soundString), "soundString", "Sound String"); -// // Here is how it can be invoked directly: // // SResourceSelectorContext x; @@ -56,19 +46,7 @@ // // QString SoundFileSelector(const SResourceSelectorContext& x, const QString& previousValue, // SoundFileList* list) // your context argument -// -// And provide this value through serialization context: -// -// struct SourceFileList -// { -// void Serialize(IArchive& ar) -// { -// Serialization::SContext context(ar, this); -// ... -// } -// } -#include #include class QWidget; @@ -82,7 +60,6 @@ struct SResourceSelectorContext unsigned int entityId; void* contextObject; - Serialization::TypeID contextObjectType; SResourceSelectorContext() : parentWidget(0) @@ -107,7 +84,6 @@ struct IResourceSelectorHost virtual ~IResourceSelectorHost() = default; virtual QString SelectResource(const SResourceSelectorContext& context, const QString& previousValue) = 0; virtual const char* ResourceIconPath(const char* typeName) const = 0; - virtual Serialization::TypeID ResourceContextType(const char* typeName) const = 0; virtual void RegisterResourceSelector(const SStaticResourceSelectorEntry* entry) = 0; @@ -128,7 +104,6 @@ struct SStaticResourceSelectorEntry TResourceSelectionFunction function; TResourceSelectionFunctionWithContext functionWithContext; const char* iconPath; - Serialization::TypeID contextType; static SStaticResourceSelectorEntry*& GetFirst() { static SStaticResourceSelectorEntry* first; return first; } SStaticResourceSelectorEntry* next; @@ -150,7 +125,6 @@ struct SStaticResourceSelectorEntry , functionWithContext(TResourceSelectionFunctionWithContext(function)) , iconPath(icon) { - contextType = Serialization::TypeID::get(); next = GetFirst(); GetFirst() = this; } diff --git a/Code/Sandbox/Editor/ResourceSelectorHost.cpp b/Code/Sandbox/Editor/ResourceSelectorHost.cpp index 6711af0af0..cf08d7f4d4 100644 --- a/Code/Sandbox/Editor/ResourceSelectorHost.cpp +++ b/Code/Sandbox/Editor/ResourceSelectorHost.cpp @@ -72,16 +72,6 @@ public: return ""; } - Serialization::TypeID ResourceContextType(const char* typeName) const override - { - TTypeMap::const_iterator it = m_typeMap.find(typeName); - if (it != m_typeMap.end()) - { - return it->second->contextType; - } - return Serialization::TypeID(); - } - void RegisterResourceSelector(const SStaticResourceSelectorEntry* entry) override { m_typeMap[entry->typeName] = entry; diff --git a/Code/Sandbox/Editor/Serialization.h b/Code/Sandbox/Editor/Serialization.h deleted file mode 100644 index 85dfc35dc6..0000000000 --- a/Code/Sandbox/Editor/Serialization.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITOR_SERIALIZATION_H -#define CRYINCLUDE_EDITOR_SERIALIZATION_H - -#include -#include -#include -#include -#include - -using Serialization::IArchive; - -#endif // CRYINCLUDE_EDITOR_SERIALIZATION_H diff --git a/Code/Sandbox/Editor/Serialization/VariableIArchive.cpp b/Code/Sandbox/Editor/Serialization/VariableIArchive.cpp deleted file mode 100644 index 235ec9a6b0..0000000000 --- a/Code/Sandbox/Editor/Serialization/VariableIArchive.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "VariableIArchive.h" - -// Editor -#include "Serialization/Decorators/Resources.h" -#include "Serialization/Decorators/Range.h" - - -using Serialization::CVariableIArchive; - -namespace VarUtil -{ - _smart_ptr< IVariable > FindChildVariable(const _smart_ptr< IVariable >& pParent, const int childIndexOverride, const char* const name) - { - if (0 <= childIndexOverride) - { - return pParent->GetVariable(childIndexOverride); - } - else - { - const bool shouldSearchRecursively = false; - return pParent->FindVariable(name, shouldSearchRecursively); - } - } - - - template< typename T, typename TOut > - bool ReadChildVariableAs(const _smart_ptr< IVariable >& pParent, const int childIndexOverride, const char* const name, TOut& valueOut) - { - _smart_ptr< IVariable > pVariable = FindChildVariable(pParent, childIndexOverride, name); - if (pVariable) - { - T tmp; - pVariable->Get(tmp); - valueOut = static_cast< TOut >(tmp); - return true; - } - return false; - } - - - template< typename T > - bool ReadChildVariable(const _smart_ptr< IVariable >& pParent, const int childIndexOverride, const char* const name, T& valueOut) - { - return ReadChildVariableAs< T >(pParent, childIndexOverride, name, valueOut); - } -} - - - -CVariableIArchive::CVariableIArchive(const _smart_ptr< IVariable >& pVariable) - : IArchive(IArchive::INPUT | IArchive::EDIT | IArchive::NO_EMPTY_NAMES) - , m_pVariable(pVariable) - , m_childIndexOverride(-1) -{ - CRY_ASSERT(m_pVariable); - - m_structHandlers[ TypeID::get < Serialization::IResourceSelector > ().name() ] = &CVariableIArchive::SerializeResourceSelector; - m_structHandlers[ TypeID::get < Serialization::RangeDecorator < float >> ().name() ] = &CVariableIArchive::SerializeRangeFloat; - m_structHandlers[ TypeID::get < Serialization::RangeDecorator < int >> ().name() ] = &CVariableIArchive::SerializeRangeInt; - m_structHandlers[ TypeID::get < Serialization::RangeDecorator < unsigned int >> ().name() ] = &CVariableIArchive::SerializeRangeUInt; - m_structHandlers[ TypeID::get < StringListStaticValue > ().name() ] = &CVariableIArchive::SerializeStringListStaticValue; -} - - -CVariableIArchive::~CVariableIArchive() -{ -} - - -bool CVariableIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< bool >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(Serialization::IString& value, const char* name, [[maybe_unused]] const char* label) -{ - QString stringValue; - const bool readSuccess = VarUtil::ReadChildVariableAs< QString >(m_pVariable, m_childIndexOverride, name, stringValue); - if (readSuccess) - { - value.set(stringValue.toUtf8().data()); - return true; - } - return false; -} - - -bool CVariableIArchive::operator()([[maybe_unused]] Serialization::IWString& value, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) -{ - CryFatalError("CVariableIArchive::operator() with IWString is not implemented"); - return false; -} - - -bool CVariableIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< float >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< float >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) -{ - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value); -} - - -bool CVariableIArchive::operator()(const Serialization::SStruct& ser, const char* name, const char* label) -{ - const char* const typeName = ser.type().name(); - HandlersMap::const_iterator it = m_structHandlers.find(typeName); - const bool handlerFound = (it != m_structHandlers.end()); - if (handlerFound) - { - StructHandlerFunctionPtr pHandler = it->second; - return (this->*pHandler)(ser, name, label); - } - - return SerializeStruct(ser, name, label); -} - - -bool CVariableIArchive::operator()(Serialization::IContainer& ser, const char* name, [[maybe_unused]] const char* label) -{ - _smart_ptr< IVariable > pChild = VarUtil::FindChildVariable(m_pVariable, m_childIndexOverride, name); - if (pChild) - { - const int elementCount = pChild->GetNumVariables(); - ser.resize(elementCount); - - if (0 < elementCount) - { - CVariableIArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - for (int i = 0; i < elementCount; ++i) - { - childArchive.m_childIndexOverride = i; - - ser(childArchive, "", ""); - ser.next(); - } - } - return true; - } - return false; -} - - -bool CVariableIArchive::SerializeStruct(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - _smart_ptr< IVariable > pChild = VarUtil::FindChildVariable(m_pVariable, m_childIndexOverride, name); - if (pChild) - { - CVariableIArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - ser(childArchive); - return true; - } - return false; -} - -bool CVariableIArchive::SerializeResourceSelector(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - Serialization::IResourceSelector* pSelector = reinterpret_cast< Serialization::IResourceSelector* >(ser.pointer()); - - QString stringValue; - const bool readSuccess = VarUtil::ReadChildVariableAs< QString >(m_pVariable, m_childIndexOverride, name, stringValue); - if (readSuccess) - { - pSelector->SetValue(stringValue.toUtf8().data()); - return true; - } - return false; -} - - -bool CVariableIArchive::SerializeStringListStaticValue(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - StringListStaticValue* const pStringListStaticValue = reinterpret_cast< StringListStaticValue* >(ser.pointer()); - - _smart_ptr< IVariable > pChild = VarUtil::FindChildVariable(m_pVariable, m_childIndexOverride, name); - if (pChild) - { - int index = -1; - pChild->Get(index); - *pStringListStaticValue = index; - return true; - } - return false; -} - - -bool CVariableIArchive::SerializeRangeFloat(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - const Serialization::RangeDecorator< float >* const pRange = reinterpret_cast< Serialization::RangeDecorator< float >* >(ser.pointer()); - return VarUtil::ReadChildVariableAs< float >(m_pVariable, m_childIndexOverride, name, *pRange->value); -} - - -bool CVariableIArchive::SerializeRangeInt(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - const Serialization::RangeDecorator< int >* const pRange = reinterpret_cast< Serialization::RangeDecorator< int >* >(ser.pointer()); - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, *pRange->value); -} - -bool CVariableIArchive::SerializeRangeUInt(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - const Serialization::RangeDecorator< unsigned int >* const pRange = reinterpret_cast< Serialization::RangeDecorator< unsigned int >* >(ser.pointer()); - return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, *pRange->value); -} diff --git a/Code/Sandbox/Editor/Serialization/VariableIArchive.h b/Code/Sandbox/Editor/Serialization/VariableIArchive.h deleted file mode 100644 index ac7c0532e4..0000000000 --- a/Code/Sandbox/Editor/Serialization/VariableIArchive.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "Util/Variable.h" -#include "Serialization.h" - -namespace Serialization -{ - class CVariableIArchive - : public IArchive - { - public: - CVariableIArchive(const _smart_ptr< IVariable >& pVariable); - virtual ~CVariableIArchive(); - - // IArchive - virtual bool operator()(bool& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(IString& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(IWString& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(float& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(double& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(int16& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(uint16& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(int32& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(uint32& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(int64& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(uint64& value, const char* name = "", const char* label = 0) override; - - virtual bool operator()(int8& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(uint8& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(char& value, const char* name = "", const char* label = 0); - - virtual bool operator()(const SStruct& ser, const char* name = "", const char* label = 0) override; - virtual bool operator()(IContainer& ser, const char* name = "", const char* label = 0) override; - //virtual bool operator()( IPointer& ptr, const char* name = "", const char* label = 0 ) override; - // ~IArchive - - using IArchive::operator(); - - private: - bool SerializeResourceSelector(const SStruct& ser, const char* name, const char* label); - - bool SerializeStruct(const SStruct& ser, const char* name, const char* label); - - bool SerializeStringListStaticValue(const SStruct& ser, const char* name, const char* label); - - bool SerializeRangeFloat(const SStruct& ser, const char* name, const char* label); - bool SerializeRangeInt(const SStruct& ser, const char* name, const char* label); - bool SerializeRangeUInt(const SStruct& ser, const char* name, const char* label); - - private: - _smart_ptr< IVariable > m_pVariable; - int m_childIndexOverride; - - typedef bool ( CVariableIArchive::* StructHandlerFunctionPtr )(const SStruct&, const char*, const char*); - typedef std::map< string, StructHandlerFunctionPtr > HandlersMap; - HandlersMap m_structHandlers; // TODO: have only one of these. - }; -} diff --git a/Code/Sandbox/Editor/Serialization/VariableOArchive.cpp b/Code/Sandbox/Editor/Serialization/VariableOArchive.cpp deleted file mode 100644 index d5c53d1966..0000000000 --- a/Code/Sandbox/Editor/Serialization/VariableOArchive.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "VariableOArchive.h" - -// Editor -#include "Serialization/Decorators/Resources.h" -#include "Serialization/Decorators/Range.h" - - -using Serialization::CVariableOArchive; - -namespace VarUtil -{ - template< typename T > - _smart_ptr< IVariable > AddChildVariable(const _smart_ptr< IVariable >& pVariableArray, const T& value, const char* const name, const char* label) - { - CRY_ASSERT(pVariableArray); - - _smart_ptr< IVariable > pVariable = new CVariable< T >(); - pVariable->SetName(name); - pVariable->SetHumanName(label); - pVariable->Set(value); - - pVariableArray->AddVariable(pVariable); - - return pVariable; - } - - template< typename TMin, typename TMax > - void SetLimits(const _smart_ptr< IVariable >& pVariable, const TMin minValue, const TMax maxValue) - { - pVariable->SetLimits(static_cast< float >(minValue), static_cast< float >(maxValue)); - } -} - -CVariableOArchive::CVariableOArchive() - : IArchive(IArchive::OUTPUT | IArchive::EDIT | IArchive::NO_EMPTY_NAMES) - , m_pVariable(new CVariableArray()) -{ - m_resourceHandlers[ "Animation" ] = &CVariableOArchive::SerializeAnimationName; - m_resourceHandlers[ "Sound" ] = &CVariableOArchive::SerializeSoundName; - m_resourceHandlers[ "Model" ] = &CVariableOArchive::SerializeObjectFilename; - - m_structHandlers[ TypeID::get < Serialization::IResourceSelector > ().name() ] = &CVariableOArchive::SerializeIResourceSelector; - m_structHandlers[ TypeID::get < Serialization::RangeDecorator < float >> ().name() ] = &CVariableOArchive::SerializeRangeFloat; - m_structHandlers[ TypeID::get < Serialization::RangeDecorator < int >> ().name() ] = &CVariableOArchive::SerializeRangeInt; - m_structHandlers[ TypeID::get < Serialization::RangeDecorator < unsigned int >> ().name() ] = &CVariableOArchive::SerializeRangeUInt; - m_structHandlers[ TypeID::get < StringListStaticValue > ().name() ] = &CVariableOArchive::SerializeStringListStaticValue; -} - - -CVariableOArchive::~CVariableOArchive() -{ -} - - -_smart_ptr< IVariable > CVariableOArchive::GetIVariable() const -{ - return m_pVariable; -} - - -CVarBlockPtr CVariableOArchive::GetVarBlock() const -{ - CVarBlockPtr pVarBlock = new CVarBlock(); - pVarBlock->AddVariable(m_pVariable); - return pVarBlock; -} - - -bool CVariableOArchive::operator()(bool& value, const char* name, const char* label) -{ - VarUtil::AddChildVariable< bool >(m_pVariable, value, name, label); - return true; -} - - -bool CVariableOArchive::operator()(Serialization::IString& value, const char* name, const char* label) -{ - const QString valueString = value.get(); - VarUtil::AddChildVariable< QString >(m_pVariable, valueString, name, label); - return true; -} - - -bool CVariableOArchive::operator()([[maybe_unused]] Serialization::IWString& value, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) -{ - CryFatalError("CVarBlockOArchive::operator() with IWString is not implemented"); - return false; -} - - -bool CVariableOArchive::operator()(float& value, const char* name, const char* label) -{ - VarUtil::AddChildVariable< float >(m_pVariable, value, name, label); - return true; -} - - -bool CVariableOArchive::operator()(double& value, const char* name, const char* label) -{ - VarUtil::AddChildVariable< float >(m_pVariable, value, name, label); - return true; -} - - -bool CVariableOArchive::operator()(int16& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, SHRT_MIN, SHRT_MAX); - return true; -} - - -bool CVariableOArchive::operator()(uint16& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, 0, USHRT_MAX); - return true; -} - - -bool CVariableOArchive::operator()(int32& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, INT_MIN, INT_MAX); - return true; -} - - -bool CVariableOArchive::operator()(uint32& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, 0, INT_MAX); - return true; -} - - -bool CVariableOArchive::operator()(int64& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, INT_MIN, INT_MAX); - return true; -} - - -bool CVariableOArchive::operator()(uint64& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, 0, INT_MAX); - return true; -} - - -bool CVariableOArchive::operator()(int8& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, SCHAR_MIN, SCHAR_MAX); - return true; -} - - -bool CVariableOArchive::operator()(uint8& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, 0, UCHAR_MAX); - return true; -} - - -bool CVariableOArchive::operator()(char& value, const char* name, const char* label) -{ - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label); - VarUtil::SetLimits(pVariable, CHAR_MIN, CHAR_MAX); - return true; -} - - -bool CVariableOArchive::operator()(const Serialization::SStruct& ser, const char* name, const char* label) -{ - const char* const typeName = ser.type().name(); - HandlersMap::const_iterator it = m_structHandlers.find(typeName); - const bool handlerFound = (it != m_structHandlers.end()); - if (handlerFound) - { - StructHandlerFunctionPtr pHandler = it->second; - return (this->*pHandler)(ser, name, label); - } - - return SerializeStruct(ser, name, label); -} - -static const char* gVec4Names[] = { "X", "Y", "Z", "W" }; -static const char* gEmptyNames[] = { "" }; - -bool CVariableOArchive::operator()(Serialization::IContainer& ser, const char* name, const char* label) -{ - CVariableOArchive childArchive; - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - _smart_ptr< IVariable > pChildVariable = childArchive.GetIVariable(); - pChildVariable->SetName(name); - pChildVariable->SetHumanName(label); - - m_pVariable->AddVariable(pChildVariable); - - const size_t containerSize = ser.size(); - - const char** nameArray = gEmptyNames; - size_t nameArraySize = 1; - if (containerSize >= 2 && containerSize <= 4) - { - nameArray = gVec4Names; - nameArraySize = containerSize; - } - - size_t index = 0; - if (0 < containerSize) - { - do - { - ser(childArchive, nameArray[index % nameArraySize], nameArray[index % nameArraySize]); - ++index; - } while (ser.next()); - } - - return true; -} - - -bool CVariableOArchive::SerializeStruct(const Serialization::SStruct& ser, const char* name, const char* label) -{ - CVariableOArchive childArchive; - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - _smart_ptr< IVariable > pChildVariable = childArchive.GetIVariable(); - pChildVariable->SetName(name); - pChildVariable->SetHumanName(label); - - m_pVariable->AddVariable(pChildVariable); - - const bool serializeSuccess = ser(childArchive); - - return serializeSuccess; -} - - -bool CVariableOArchive::SerializeAnimationName(const Serialization::IResourceSelector* pSelector, const char* name, const char* label) -{ - const QString valueString = pSelector->GetValue(); - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< QString >(m_pVariable, valueString, name, label); - pVariable->SetDataType(IVariable::DT_ANIMATION); - - return true; -} - - -bool CVariableOArchive::SerializeSoundName(const Serialization::IResourceSelector* pSelector, const char* name, const char* label) -{ - const QString valueString = pSelector->GetValue(); - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< QString >(m_pVariable, valueString, name, label); - pVariable->SetDataType(IVariable::DT_AUDIO_TRIGGER); - - return true; -} - -void CVariableOArchive::CreateChildEnumVariable(const QStringList& enumValues, const QString& value, const char* name, const char* label) -{ - if (enumValues.empty()) - { - VarUtil::AddChildVariable< QString >(m_pVariable, value, name, label); - } - else - { - _smart_ptr< CVariableEnum< QString > > pVariable = new CVariableEnum< QString >(); - pVariable->SetName(name); - pVariable->SetHumanName(label); - - pVariable->AddEnumItem("", ""); - - const size_t enumValuesCount = enumValues.size(); - for (size_t i = 0; i < enumValuesCount; ++i) - { - pVariable->AddEnumItem(enumValues[ i ], enumValues[ i ]); - } - - pVariable->Set(value); - - m_pVariable->AddVariable(pVariable); - } -} - -bool CVariableOArchive::SerializeObjectFilename(const Serialization::IResourceSelector* pSelector, const char* name, const char* label) -{ - const QString valueString = pSelector->GetValue(); - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< QString >(m_pVariable, valueString, name, label); - pVariable->SetDataType(IVariable::DT_OBJECT); - - return true; -} - - -bool CVariableOArchive::SerializeStringListStaticValue(const Serialization::SStruct& ser, const char* name, const char* label) -{ - const StringListStaticValue* const pStringListStaticValue = reinterpret_cast< StringListStaticValue* >(ser.pointer()); - const StringListStatic& stringListStatic = pStringListStaticValue->stringList(); - const int index = pStringListStaticValue->index(); - - _smart_ptr< CVariableEnum< int > > pVariable = new CVariableEnum< int >(); - pVariable->SetName(name); - pVariable->SetHumanName(label); - - const size_t stringListStaticSize = stringListStatic.size(); - for (size_t i = 0; i < stringListStaticSize; ++i) - { - pVariable->AddEnumItem(stringListStatic[ i ], static_cast< int >(i)); - } - - if (0 <= index) - { - CRY_ASSERT(index < stringListStaticSize); - pVariable->Set(static_cast< int >(index)); - } - - m_pVariable->AddVariable(pVariable); - - return true; -} - -bool CVariableOArchive::SerializeIResourceSelector(const Serialization::SStruct& ser, const char* name, const char* label) -{ - const Serialization::IResourceSelector* pSelector = reinterpret_cast< Serialization::IResourceSelector* >(ser.pointer()); - - ResourceHandlersMap::iterator it = m_resourceHandlers.find(pSelector->resourceType); - if (it != m_resourceHandlers.end()) - { - return (this->*(it->second))(pSelector, name, label); - } - return false; -} - -template -static void SetLimits(IVariable* pVariable, const Serialization::RangeDecorator* pRange, float stepValue) -{ - if (pRange->softMin != std::numeric_limits::lowest() || pRange->softMax != std::numeric_limits::max()) - { - float minimal = (float)pRange->softMin; - float maximal = (float)pRange->softMax; - bool hardMin = false; - bool hardMax = false; - if (pRange->hardMin != std::numeric_limits::lowest()) - { - minimal = pRange->hardMin; - hardMin = true; - } - if (pRange->hardMax != std::numeric_limits::max()) - { - maximal = pRange->hardMax; - hardMax = true; - } - pVariable->SetLimits(minimal, maximal, stepValue, hardMin, hardMax); - } - else - { - float minimal = 0.0f; - float maximal = 0.0f; - float oldStep = 0.0f; - bool hardMin = false; - bool hardMax = false; - pVariable->GetLimits(minimal, maximal, oldStep, hardMin, hardMax); - pVariable->SetLimits(minimal, maximal, stepValue, hardMin, hardMax); - } -} - -bool CVariableOArchive::SerializeRangeFloat(const Serialization::SStruct& ser, const char* name, const char* label) -{ - const Serialization::RangeDecorator< float >* const pRange = reinterpret_cast< Serialization::RangeDecorator< float >* >(ser.pointer()); - - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< float >(m_pVariable, *pRange->value, name, label); - - SetLimits(pVariable.get(), pRange, 0.01f); - return true; -} - -bool CVariableOArchive::SerializeRangeInt(const Serialization::SStruct& ser, const char* name, const char* label) -{ - const Serialization::RangeDecorator< int >* const pRange = reinterpret_cast< Serialization::RangeDecorator< int >* >(ser.pointer()); - - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, *pRange->value, name, label); - SetLimits(pVariable.get(), pRange, 1.0f); - return true; -} - -bool CVariableOArchive::SerializeRangeUInt(const Serialization::SStruct& ser, const char* name, const char* label) -{ - const Serialization::RangeDecorator< unsigned int >* const pRange = reinterpret_cast< Serialization::RangeDecorator< unsigned int >* >(ser.pointer()); - - _smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, *pRange->value, name, label); - SetLimits(pVariable, pRange, 1.0f); - return true; -} diff --git a/Code/Sandbox/Editor/Serialization/VariableOArchive.h b/Code/Sandbox/Editor/Serialization/VariableOArchive.h deleted file mode 100644 index 60de8f84ac..0000000000 --- a/Code/Sandbox/Editor/Serialization/VariableOArchive.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "Util/Variable.h" -#include "Serialization.h" - - -namespace Serialization -{ - struct IResourceSelector; - - class CVariableOArchive - : public IArchive - { - public: - CVariableOArchive(); - virtual ~CVariableOArchive(); - - _smart_ptr< IVariable > GetIVariable() const; - CVarBlockPtr GetVarBlock() const; - - // IArchive - virtual bool operator()(bool& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(IString& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(IWString& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(float& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(double& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(int16& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(uint16& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(int32& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(uint32& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(int64& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(uint64& value, const char* name = "", const char* label = 0) override; - - virtual bool operator()(int8& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(uint8& value, const char* name = "", const char* label = 0) override; - virtual bool operator()(char& value, const char* name = "", const char* label = 0); - - virtual bool operator()(const SStruct& ser, const char* name = "", const char* label = 0) override; - virtual bool operator()(IContainer& ser, const char* name = "", const char* label = 0) override; - //virtual bool operator()( IPointer& ptr, const char* name = "", const char* label = 0 ) override; - // ~IArchive - - using IArchive::operator(); - - private: - bool SerializeStruct(const SStruct& ser, const char* name, const char* label); - bool SerializeStringListStaticValue(const SStruct& ser, const char* name, const char* label); - bool SerializeRangeFloat(const SStruct& ser, const char* name, const char* label); - bool SerializeRangeInt(const SStruct& ser, const char* name, const char* label); - bool SerializeRangeUInt(const SStruct& ser, const char* name, const char* label); - bool SerializeIResourceSelector(const SStruct& ser, const char* name, const char* label); - - bool SerializeAnimationName(const IResourceSelector* pSelector, const char* name, const char* label); - bool SerializeSoundName(const IResourceSelector* pSelector, const char* name, const char* label); - bool SerializeObjectFilename(const IResourceSelector* pSelector, const char* name, const char* label); - - void CreateChildEnumVariable(const QStringList& enumValues, const QString& value, const char* name, const char* label); - - private: - _smart_ptr< IVariable > m_pVariable; - - typedef bool ( CVariableOArchive::* StructHandlerFunctionPtr )(const SStruct&, const char*, const char*); - typedef std::map< string, StructHandlerFunctionPtr > HandlersMap; - HandlersMap m_structHandlers; // TODO: have only one of these. - - typedef bool ( CVariableOArchive::* ResourceHandlerFunctionPtr )(const IResourceSelector*, const char*, const char*); - typedef std::map< string, ResourceHandlerFunctionPtr > ResourceHandlersMap; - ResourceHandlersMap m_resourceHandlers; - }; -} diff --git a/Code/Sandbox/Editor/SettingsBlock.cpp b/Code/Sandbox/Editor/SettingsBlock.cpp deleted file mode 100644 index d9f596c2d0..0000000000 --- a/Code/Sandbox/Editor/SettingsBlock.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "SettingsBlock.h" - -// CryCommon -#include -#include - -// Editor -#include "Serialization.h" - -using std::vector; - -SProjectSettingsBlock* SProjectSettingsBlock::s_pLastBlock; - -SProjectSettingsBlock::SProjectSettingsBlock(const char* name, const char* label) - : m_name(name) - , m_label(label) -{ - m_pPrevious = s_pLastBlock; - s_pLastBlock = this; -} - - -struct SAllSettingsSerializer -{ - void Serialize(Serialization::IArchive& ar) - { - SProjectSettingsBlock* pCurrent = SProjectSettingsBlock::s_pLastBlock; - while (pCurrent != 0) - { - ar(*pCurrent, pCurrent->GetName(), pCurrent->GetLabel()); - pCurrent = pCurrent->m_pPrevious; - } - } -} static gAllSettingsSerializer; - -void SProjectSettingsBlock::GetAllSettingsSerializer(Serialization::SStruct* pSerializer) -{ - *pSerializer = Serialization::SStruct(gAllSettingsSerializer); -} - -SProjectSettingsBlock* SProjectSettingsBlock::Find(const char* blockName) -{ - SProjectSettingsBlock* pCurrent = SProjectSettingsBlock::s_pLastBlock; - while (pCurrent != 0) - { - if (_stricmp(pCurrent->GetName(), blockName) == 0) - { - return pCurrent; - } - } - return 0; -} - -static bool ReadFileContent(vector* pBuffer, const char* filename) -{ - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(filename, "rb"); - if (fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - size_t size = gEnv->pCryPak->FGetSize(fileHandle); - pBuffer->resize(size); - - bool result = true; - if (gEnv->pCryPak->FRead(&(*pBuffer)[0], size, fileHandle) != size) - { - result = false; - } - gEnv->pCryPak->FClose(fileHandle); - return result; -} - -static bool SaveFileContent(const char* filename, const char* pBuffer, size_t length) -{ - string fullpath = Path::GamePathToFullPath(filename).toUtf8().data(); - - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - if (!gEnv->pFileIO->Open(fullpath.c_str(), AZ::IO::GetOpenModeFromStringMode("wb"), fileHandle)) - { - return false; - } - - bool result = true; - if (!gEnv->pFileIO->Write(fileHandle, pBuffer, length)) - { - result = false; - } - - gEnv->pFileIO->Close(fileHandle); - return result; -} - -static bool SaveFileContentIfDiffers(const char* filename, const char* pBuffer, size_t length) -{ - vector content; - ReadFileContent(&content, filename); - - bool needToWrite = true; - if (!content.empty() && content.size() == length) - { - needToWrite = memcmp(&content[0], pBuffer, length) != 0; - } - - if (needToWrite) - { - return SaveFileContent(filename, pBuffer, length); - } - else - { - return true; - } -} - -bool SProjectSettingsBlock::Load() -{ - const char* filename = GetFilename(); - - vector content; - if (!ReadFileContent(&content, filename)) - { - return false; - } - - auto pArchive(Serialization::CreateTextInputArchive()); - if (!pArchive) - { - return false; - } - - if (!pArchive->AttachMemory(&content[0], content.size())) - { - return false; - } - - Serialization::SStruct serializer; - GetAllSettingsSerializer(&serializer); - serializer(*pArchive); - return true; -} - -bool SProjectSettingsBlock::Save() -{ - const char* filename = GetFilename(); - auto pArchive(Serialization::CreateTextOutputArchive()); - if (!pArchive) - { - return false; - } - - Serialization::SStruct serializer; - GetAllSettingsSerializer(&serializer); - serializer(*pArchive); - - return SaveFileContentIfDiffers(filename, pArchive->GetBuffer(), pArchive->GetBufferLength()); -} - -const char* SProjectSettingsBlock::GetFilename() -{ - return "SandboxSettings.json"; -} - diff --git a/Code/Sandbox/Editor/SettingsBlock.h b/Code/Sandbox/Editor/SettingsBlock.h deleted file mode 100644 index b67e1d3d7e..0000000000 --- a/Code/Sandbox/Editor/SettingsBlock.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -// --------------------------------------------------------------------------- -// Following utility can be used to add blocks of per-project settings. -// Example: -// -// MyComponent.cpp: -// -// struct SProjectSettingsMy : SProjectSettingsBlock -// { -// bool bMyOption; -// -// SProjectSettingsMy() -// : SProjectSettingsBlock("my", "My") -// , bMyOption(false) -// {} -// -// void Serialize(Serialization::IArchive& ar) -// { -// ar(bMyOption, "myOption", "My Option"); -// } -// -// } static gMySettings; -// -// -// Now gMySettings will be loaded and saved automatically and available for -// editing through: -// -// GetIEditor()->OpenProjectSettings("my"); -// -// --------------------------------------------------------------------------- -#ifndef CRYINCLUDE_EDITOR_SETTINGSBLOCK_H -#define CRYINCLUDE_EDITOR_SETTINGSBLOCK_H - -namespace Serialization -{ - class IArchive; - struct SStruct; -}; - -struct SProjectSettingsBlock -{ - SProjectSettingsBlock(const char* name, const char* label); - - virtual void Serialize(Serialization::IArchive& ar) = 0; - - const char* GetName() const{ return m_name; } - const char* GetLabel() const{ return m_label; } - - static void GetAllSettingsSerializer(Serialization::SStruct* serializer); - static SProjectSettingsBlock* Find(const char* name); - static bool Load(); - static bool Save(); - static const char* GetFilename(); -private: - const char* m_name; - const char* m_label; - SProjectSettingsBlock* m_pPrevious; - static SProjectSettingsBlock* s_pLastBlock; - friend struct SAllSettingsSerializer; -}; - -#endif // CRYINCLUDE_EDITOR_SETTINGSBLOCK_H diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index 4832e2b8c2..3d6112d186 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -357,8 +357,6 @@ set(FILES Controls/ConsoleSCB.h Controls/ConsoleSCB.ui Controls/ConsoleSCB.qrc - Controls/CurveEditorCtrl.cpp - Controls/CurveEditorCtrl.h Controls/FolderTreeCtrl.cpp Controls/FolderTreeCtrl.h Controls/HotTrackingTreeCtrl.cpp @@ -575,11 +573,6 @@ set(FILES QtUI/WaitCursor.cpp RenderHelpers/AxisHelper.cpp RenderHelpers/AxisHelper.h - Serialization.h - Serialization/VariableOArchive.cpp - Serialization/VariableOArchive.h - Serialization/VariableIArchive.cpp - Serialization/VariableIArchive.h CustomizeKeyboardDialog.h CustomizeKeyboardDialog.cpp CustomizeKeyboardDialog.ui @@ -738,8 +731,6 @@ set(FILES TrackView/TrackViewEventNode.h ConfigGroup.cpp ConfigGroup.h - SettingsBlock.cpp - SettingsBlock.h Util/AffineParts.h Util/AutoLogTime.cpp Util/AutoLogTime.h diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.cpp index e5ad2a2872..54ac71db16 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin.cpp @@ -15,7 +15,6 @@ #include #include "IResourceSelectorHost.h" -#include "CryExtension/ICryFactoryRegistry.h" #include "UI/QComponentEntityEditorMainWindow.h" #include "UI/QComponentEntityEditorOutlinerWindow.h" diff --git a/Code/Sandbox/Plugins/EditorCommon/BatchFileDialog.cpp b/Code/Sandbox/Plugins/EditorCommon/BatchFileDialog.cpp deleted file mode 100644 index 0dc7a8e7dc..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/BatchFileDialog.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "BatchFileDialog.h" -#include "QPropertyTree/QPropertyDialog.h" -#include "Serialization/StringList.h" -#include "Serialization/STL.h" -#include "Serialization/IArchive.h" -#include "Serialization/STLImpl.h" -#include "IEditor.h" -#include "Pak/CryPakUtils.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct SBatchFileItem -{ - bool selected; - string path; - bool checkable = false; - - bool operator<(const SBatchFileItem& rhs) const { return path < rhs.path; } - - void Serialize(Serialization::IArchive& ar) - { - // ------------------------------------------------------------------- - // Note: The property tree label modifiers used below indicate... - // ! - Readonly, you can't modify the path - // ^ - Raise location to the parent (the index indicator) - // < - Take up the rest of the space - // ------------------------------------------------------------------- - if (!checkable) - { - ar(selected, "selected", "^"); - } - - auto gamePath = PathUtil::MakeGamePath(path); - ar(gamePath, "path", "!^<"); - } -}; -typedef std::vector SBatchFileItems; - -struct CBatchFileDialog::SContent -{ - SBatchFileItems items; - string listLabel; - - SContent(const char* itemsLabelText, bool readonlyList) - { - // Respect the readonly settings - if (readonlyList) - { - listLabel += "!"; - } - - // Label Size (5px per character) - auto labelSize = static_cast(strlen(itemsLabelText)) * 5; - { - // Format is: >#>+ where the >#> indicates the label size, and the + indicates end of all row formatting - char buffer[16]; - sprintf_s(buffer, sizeof(buffer), ">%i>+", labelSize); - listLabel += buffer; - } - - // Add the actual label text (the text that is seen) - listLabel += itemsLabelText; - } - - void Serialize(Serialization::IArchive& ar) - { - ar(items, "items", listLabel.c_str()); - } -}; - -static bool ReadFile(std::vector* buffer, const char* path) -{ - FILE* f = nullptr; - azfopen(&f, path, "rb"); - if (!f) - { - return false; - } - fseek(f, 0, SEEK_END); - size_t len = (size_t)ftell(f); - fseek(f, 0, SEEK_SET); - - buffer->resize(len); - bool result = true; - if (len) - { - result = fread(&(*buffer)[0], 1, len, f) == len; - } - fclose(f); - return result; -} - -static void SplitLines(std::vector* lines, const char* start, const char* end) -{ - const char* p = start; - const char* lineStart = start; - while (true) - { - if (p == end || *p == '\r' || *p == '\n') - { - if (p != lineStart) - { - string line(lineStart, p); - bool hasPrintableChars = false; - for (size_t i = 0; i < line.size(); ++i) - { - if (!isspace(line[i])) - { - hasPrintableChars = true; - } - } - if (hasPrintableChars) - { - lines->push_back(line); - } - } - lineStart = p + 1; - if (p == end) - { - break; - } - } - ++p; - } -} - -static string NormalizePath(const char* path) -{ - string result = path; - result.replace('\\', '/'); - result.MakeLower(); - - // strip .phys extensions in case list of .cdf is provided - string::size_type dotPos = result.rfind('.'); - if (dotPos != string::npos) - { - if (_stricmp(result.c_str() + dotPos, ".phys")) - { - result.erase(dotPos, 5); - } - } - return result; -} - -static bool IsEquivalentPath(const char* pathA, const char* pathB) -{ - string normalizedA = NormalizePath(pathA); - string normalizedB = NormalizePath(pathB); - return normalizedA == normalizedB; -} - -void CBatchFileDialog::OnLoadList() -{ - QString existingFile = QFileDialog::getOpenFileName(m_dialog, "Load file list...", QString(), QString("Text Files (*.txt)")); - if (existingFile.isEmpty()) - { - return; - } - - string path = existingFile.toLocal8Bit().data(); - std::vector content; - ReadFile(&content, path.c_str()); - - std::vector lines; - SplitLines(&lines, &content[0], &content[0] + content.size()); - - for (size_t i = 0; i < m_content->items.size(); ++i) - { - m_content->items[i].selected = false; - } - - for (size_t i = 0; i < lines.size(); ++i) - { - const char* line = lines[i].c_str(); - for (size_t j = 0; j < m_content->items.size(); ++j) - { - const char* itemPath = m_content->items[j].path.c_str(); - if (IsEquivalentPath(line, itemPath)) - { - m_content->items[j].selected = true; - break; - } - } - } - - m_dialog->revert(); -} - -void CBatchFileDialog::OnSelectAll() -{ - for (size_t i = 0; i < m_content->items.size(); ++i) - { - m_content->items[i].selected = true; - } - - m_dialog->revert(); -} - -void CBatchFileDialog::OnSelectNone() -{ - for (size_t i = 0; i < m_content->items.size(); ++i) - { - m_content->items[i].selected = false; - } - - m_dialog->revert(); -} - -bool EDITOR_COMMON_API ShowBatchFileDialog(Serialization::StringList* result, const SBatchFileSettings& settings, QWidget* parent) -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - CBatchFileDialog::SContent content(settings.listLabel, settings.readonlyList); - if (settings.scanExtension[0] != '\0') - { - if (settings.useCryPak) - { - AZStd::vector files; - - string mask = "*."; - mask += settings.scanExtension; - SDirectoryEnumeratorHelper helper; - helper.ScanDirectoryRecursive(gEnv->pCryPak, Path::GetEditingGameDataFolder().c_str(), "", mask.c_str(), files); - - for (int k = 0; k < files.size(); ++k) - { - SBatchFileItem item; - item.checkable = settings.filesAreCheckable; - item.selected = true; - item.path = { files[k].data(), files[k].size() }; - content.items.push_back(item); - } - } - else - { - string gameFolder = Path::GetEditingGameDataFolder().c_str(); - string gamePrefix = GetIEditor()->GetPrimaryCDFolder().toUtf8().data(); - if (!gamePrefix.empty() && gamePrefix[gamePrefix.size() - 1] != '\\') - { - gamePrefix += "\\"; - } - gamePrefix += gameFolder; - if (!gamePrefix.empty() && gamePrefix[gamePrefix.size() - 1] != '\\') - { - gamePrefix += "\\"; - } - gamePrefix.replace('/', '\\'); - - QString mask = "*." + QString(settings.scanExtension); - QDirIterator dirIterator(QString(gamePrefix), QStringList() << mask, QDir::Files, QDirIterator::Subdirectories); - while (dirIterator.hasNext()) - { - SBatchFileItem item; - item.selected = true; - QByteArray array = dirIterator.next().toUtf8(); - item.path = string(array); - item.path.replace('/', '\\'); - content.items.push_back(item); - } - - } - } - - content.items.reserve(content.items.size() + settings.explicitFileList.size()); - for (size_t i = 0; i < settings.explicitFileList.size(); ++i) - { - SBatchFileItem item; - item.path = settings.explicitFileList[i].c_str(); - item.selected = true; - content.items.push_back(item); - } - - - std::sort(content.items.begin(), content.items.end()); - QApplication::restoreOverrideCursor(); - - QPropertyDialog dialog(parent); - dialog.setSerializer(Serialization::SStruct(content)); - dialog.setWindowTitle(settings.title); - dialog.setWindowStateFilename(settings.stateFilename); - dialog.setSizeHint(QSize(settings.defaultWidth, settings.defaultHeight)); - dialog.setMinimumSize(QSize(540, 250)); - - CBatchFileDialog handler; - handler.m_dialog = &dialog; - handler.m_content = &content; - - QBoxLayout* topRow = new QBoxLayout(QBoxLayout::LeftToRight); - QLabel* label = new QLabel(settings.descriptionText); - QFont font; - font.setBold(true); - label->setFont(font); - topRow->addWidget(label, 1); - { - if (settings.allowListLoading && !settings.readonlyList) - { - QPushButton* loadListButton = new QPushButton("Load List..."); - QObject::connect(loadListButton, SIGNAL(pressed()), &handler, SLOT(OnLoadList())); - topRow->addWidget(loadListButton); - } - QPushButton* selectAllButton = new QPushButton("Select All"); - QObject::connect(selectAllButton, SIGNAL(pressed()), &handler, SLOT(OnSelectAll())); - topRow->addWidget(selectAllButton); - QPushButton* selectNoneButton = new QPushButton("Select None"); - QObject::connect(selectNoneButton, SIGNAL(pressed()), &handler, SLOT(OnSelectNone())); - topRow->addWidget(selectNoneButton); - } - dialog.layout()->insertLayout(0, topRow); - - if (parent) - { - QPoint center = parent->rect().center(); - dialog.window()->move(max(0, center.x() - dialog.width() / 2), - max(0, center.y() - dialog.height() / 2)); - } - - std::vector failedFiles; - if (dialog.exec() == QDialog::Accepted) - { - result->clear(); - for (size_t i = 0; i < content.items.size(); ++i) - { - if (content.items[i].selected) - { - const char* path = content.items[i].path.c_str(); - result->push_back(path); - } - } - return true; - } - return false; -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/BatchFileDialog.h b/Code/Sandbox/Plugins/EditorCommon/BatchFileDialog.h deleted file mode 100644 index 3c1b071bca..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/BatchFileDialog.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_BATCHFILEDIALOG_H -#define CRYINCLUDE_EDITORCOMMON_BATCHFILEDIALOG_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "EditorCommonAPI.h" -#include -#include -#endif - -// Private class, should not be used directly -class QWidget; -class QPropertyDialog; -class CBatchFileDialog - : public QObject -{ - Q_OBJECT - -public slots: - void OnSelectAll(); - void OnSelectNone(); - void OnLoadList(); - -public: - QPropertyDialog* m_dialog; - struct SContent; - SContent* m_content; -}; -// ^^^ - -struct SBatchFileSettings -{ - const char* scanExtension; - const char* scanFolder; - const char* title; - const char* descriptionText; - const char* listLabel; - const char* stateFilename; - bool useCryPak; - bool allowListLoading; - bool readonlyList; - bool filesAreCheckable; - Serialization::StringList explicitFileList; - int defaultWidth; - int defaultHeight; - - SBatchFileSettings() - : useCryPak(true) - , readonlyList(true) - , filesAreCheckable(false) - , allowListLoading(true) - , descriptionText("Batch Selected Files") - , listLabel("Files") - , stateFilename("batchFileDialog.state") - , title("Batch Files") - , scanFolder("") - , scanExtension("*") - { - } -}; - -bool EDITOR_COMMON_API ShowBatchFileDialog(Serialization::StringList* filenames, const SBatchFileSettings& settings, QWidget* parent); - -#endif // CRYINCLUDE_EDITORCOMMON_BATCHFILEDIALOG_H diff --git a/Code/Sandbox/Plugins/EditorCommon/CMakeLists.txt b/Code/Sandbox/Plugins/EditorCommon/CMakeLists.txt index b0450d6b3d..001f0c65d5 100644 --- a/Code/Sandbox/Plugins/EditorCommon/CMakeLists.txt +++ b/Code/Sandbox/Plugins/EditorCommon/CMakeLists.txt @@ -13,8 +13,6 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - # Header only target to prevent linkage against editor libraries when it is not needed. Eventually the targets that depend # on editor headers should cleanup dependencies and interact with the editor through buses or other mechanisms ly_add_target( @@ -34,7 +32,6 @@ ly_add_target( AUTORCC FILES_CMAKE editorcommon_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PUBLIC . diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditor.cpp b/Code/Sandbox/Plugins/EditorCommon/CurveEditor.cpp deleted file mode 100644 index e5426b78e4..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditor.cpp +++ /dev/null @@ -1,2459 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "CurveEditor.h" -#include "CurveEditorControl.h" -#include "DrawingPrimitives/TimeSlider.h" -#include "DrawingPrimitives/Ruler.h" - -AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // class '...' needs to have dll-interface to be used by clients of class '...' -#include -#include -#include -#include -#include -#include -#include -#include -#include -AZ_POP_DISABLE_WARNING - -// C6201: buffer overrun for , which is possibly stack allocated: index is out of valid index range to -#if defined(__clang__) -#define INDEX_NOT_OUT_OF_RANGE _Pragma("clang diagnostic ignored \"-Warray-bounds\"") -#else -#define INDEX_NOT_OUT_OF_RANGE PREFAST_SUPPRESS_WARNING(6201) -#endif - -#define NO_BUFFER_OVERRUN PREFAST_SUPPRESS_WARNING(6385 6386) -#include -#include "Cry_LegacyPhysUtils.h" - -namespace CurveEditorHelpers -{ - const uint numColors = 4; - ColorB colors[numColors] = - { - ColorB(243, 126, 121), - ColorB(121, 152, 243), - ColorB(187, 243, 121), - ColorB(243, 121, 223), - }; - - ColorB GetCurveColor(const uint n) - { - return colors[n % numColors]; - } - - QColor LerpColor(const QColor& a, const QColor& b, float k) - { - float mk = 1.0f - k; - return QColor(aznumeric_cast(a.red() * mk + b.red() * k), - aznumeric_cast(a.green() * mk + b.green() * k), - aznumeric_cast(a.blue() * mk + b.blue() * k), - aznumeric_cast(a.alpha() * mk + b.alpha() * k)); - } -} - -namespace -{ - const int kRulerHeight = 16; - const int kRulerShadowHeight = 6; - const int kRulerMarkHeight = 8; - const int kTextXOffset = -1; - const int kTextYOffset = 16; - const int kTangentLength = 24; - - const float kHitDistance = 15.0f; - const float kMinZoom = 0.001f; - const float kMaxZoom = 1000.0f; - const float kFitMargin = 16.0f; - - const QPointF kPointRectExtent = QPointF(2.5f, 2.5f); - - Vec2 TransformPointToScreen(const Vec2 zoom, const Vec2 translation, QRect curveArea, Vec2 point) - { - Vec2 transformedPoint = Vec2(point.x * zoom.x, point.y * -zoom.y) + translation; - transformedPoint.x *= curveArea.width(); - transformedPoint.y *= curveArea.height(); - return Vec2(transformedPoint.x + curveArea.left(), transformedPoint.y + curveArea.top()); - } - - Vec2 TransformPointFromScreen(const Vec2 zoom, const Vec2 translation, QRect curveArea, Vec2 point) - { - Vec2 transformedPoint = Vec2((point.x - curveArea.left()) / curveArea.width(), (point.y - curveArea.top()) / curveArea.height()) - translation; - transformedPoint.x /= zoom.x; - transformedPoint.y /= -zoom.y; - return Vec2(transformedPoint.x, transformedPoint.y); - } - - float EvaluateBezier(float t, float p0, float p1, float p2, float p3) - { - const float a = 1 - t; - const float aSq = a * a; - const float tSq = t * t; - return (aSq * a * p0) + (3.0f * aSq * t * p1) + (3.0f * a * tSq * p2) + (tSq * t * p3); - } - - void SplitBezier(SCurveEditorKey& newKey, SCurveEditorKey& leftKey, SCurveEditorKey& rightKey) - { - // use De Casteljau's algorithm to find the - float normalizedTime = (newKey.m_time - leftKey.m_time) / (rightKey.m_time - leftKey.m_time); - - Vec2 p0 = Vec2(leftKey.m_time, leftKey.m_value); - Vec2 p3 = Vec2(rightKey.m_time, rightKey.m_value); - Vec2 p1 = p0 + leftKey.m_outTangent; - Vec2 p2 = p3 + rightKey.m_inTangent; - - Vec2 q0 = p0 + (p1 - p0) * normalizedTime; - Vec2 q1 = p1 + (p2 - p1) * normalizedTime; - Vec2 q2 = p2 + (p3 - p2) * normalizedTime; - - Vec2 r0 = q0 + (q1 - q0) * normalizedTime; - Vec2 r1 = q1 + (q2 - q1) * normalizedTime; - - Vec2 s0 = r0 + (r1 - r0) * normalizedTime; - - newKey.m_inTangent = r0 - s0; - newKey.m_outTangent = r1 - s0; - - leftKey.m_outTangent = q0 - p0; - rightKey.m_inTangent = q2 - p3; - } - - QPointF Vec2ToPoint(Vec2 point) - { - return QPointF(point.x, point.y); - } - - Vec2 PointToVec2(QPointF point) - { - return Vec2(aznumeric_cast(point.x()), aznumeric_cast(point.y())); - } - - // This function returns a new key with position and weights affected by eTangentType_Smooth, eTangentType_Linear and eTangentType_Step for the outgoing tangent - SCurveEditorKey ApplyOutTangentFlags(const SCurveEditorKey& key, [[maybe_unused]] const SCurveEditorKey* pLeftKey, const SCurveEditorKey& rightKey) - { - SCurveEditorKey newKey = key; - - if (rightKey.m_inTangentType == SCurveEditorKey::eTangentType_Step - && key.m_outTangentType != SCurveEditorKey::eTangentType_Step) - { - newKey.m_outTangent.y = 0.0f; - return newKey; - } - - switch (key.m_outTangentType) - { - case SCurveEditorKey::eTangentType_Linear: - newKey.m_outTangent.y = (rightKey.m_value - key.m_value) / 3.0f; - break; - case SCurveEditorKey::eTangentType_Step: - newKey.m_outTangent.x = 0.0f; - newKey.m_outTangent.y = 0.0f; - newKey.m_value = rightKey.m_value; - break; - default: - const float oneThirdDeltaTime = (rightKey.m_time - newKey.m_time) / 3.0f; - float ratio = oneThirdDeltaTime / newKey.m_outTangent.x; - newKey.m_outTangent *= ratio; - break; - } - - return newKey; - } - - // This function returns a new key with position and weights affected by eTangentType_Smooth, eTangentType_Linear and eTangentType_Step for the incoming tangent - SCurveEditorKey ApplyInTangentFlags(const SCurveEditorKey& key, const SCurveEditorKey& leftKey, [[maybe_unused]] const SCurveEditorKey* pRightKey) - { - SCurveEditorKey newKey = key; - - if (leftKey.m_outTangentType == SCurveEditorKey::eTangentType_Step) - { - newKey.m_inTangent.y = 0.0f; - return newKey; - } - - switch (key.m_inTangentType) - { - case SCurveEditorKey::eTangentType_Linear: - newKey.m_inTangent.y = (leftKey.m_value - key.m_value) / 3.0f; - break; - case SCurveEditorKey::eTangentType_Step: - newKey.m_inTangent.x = 0.0f; - newKey.m_inTangent.y = 0.0f; - newKey.m_value = leftKey.m_value; - break; - default: - const float oneThirdDeltaTime = (newKey.m_time - leftKey.m_time) / 3.0f; - float ratio = oneThirdDeltaTime / -newKey.m_inTangent.x; - newKey.m_inTangent *= ratio; - break; - } - - return newKey; - } - - QPainterPath CreatePathFromCurve(const SCurveEditorCurve& curve, - ECurveEditorCurveType curveType, AZStd::function transformFunc) - { - QPainterPath path; - - const Vec2 startPoint(curve.m_keys[0].m_time, curve.m_keys[0].m_value); - const Vec2 startTransformed = transformFunc(startPoint); - path.moveTo(startTransformed.x, startTransformed.y); - - const auto endIter = curve.m_keys.end() - 1; - - if (curve.m_customInterpolator && curve.m_keys.size() > 1) - { - const float range_start = curve.m_customInterpolator->GetKeyTime(0); - const float range_end = curve.m_customInterpolator->GetKeyTime(curve.m_customInterpolator->GetKeyCount() - 1); - const float range_delta = range_end - range_start; - - if (range_delta > 0) - { - const int drawResolution = (int)ceil_tpl(transformFunc(Vec2(range_end, 0.0f)).x - - transformFunc(Vec2(range_start, 0.0f)).x); - - const float increment = range_delta / drawResolution; - std::vector drawList; - drawList.reserve(512); - float value; - for (float time = range_start; time < range_end; time += increment) - { - curve.m_customInterpolator->InterpolateFloat(time, value); - drawList.push_back(Vec2(time, value)); - } - - path.moveTo(Vec2ToPoint(transformFunc(drawList.front()))); - for (int i = 1; i < drawList.size(); i++) - { - path.lineTo(Vec2ToPoint(transformFunc(drawList[i]))); - } - } - } - else if (curveType == eCECT_Bezier) - { - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - const SCurveEditorKey* pKeyLeftOfSegment = (iter != curve.m_keys.begin()) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pKeyRightOfSegment = (iter != (curve.m_keys.end() - 2)) ? &*(iter + 2) : nullptr; - - const SCurveEditorKey segmentStartKey = ApplyOutTangentFlags(*iter, pKeyLeftOfSegment, *(iter + 1)); - const SCurveEditorKey segmentEndKey = ApplyInTangentFlags(*(iter + 1), *iter, pKeyRightOfSegment); - - const Vec2 p0 = Vec2(segmentStartKey.m_time, segmentStartKey.m_value); - const Vec2 p3 = Vec2(segmentEndKey.m_time, segmentEndKey.m_value); - - // Need to compute tangents for x so that the cubic 2D Bezier does a linear interpolation in - // that dimension, because we actually want to draw a cubic 1D Bezier curve - //const float outTangentX = (2.0f * p0.x + p3.x) / 3.0f; // p1 = (2 * p0 + p3) / 3 - //const float inTangentX = (p0.x + 2.0f * p3.x) / 3.0f; // p2 = (p0 + 2 * p3) / 3 - - const Vec2 p1 = p0 + segmentStartKey.m_outTangent; // Vec2(inTangentX, p0.y + segmentStartKey.m_outTangent.y); - const Vec2 p2 = p3 + segmentEndKey.m_inTangent; // Vec2(inTangentX, p3.y + segmentEndKey.m_inTangent.y); - - const QPointF p0Transformed = Vec2ToPoint(transformFunc(p0)); - const QPointF p1Transformed = Vec2ToPoint(transformFunc(p1)); - const QPointF p2Transformed = Vec2ToPoint(transformFunc(p2)); - const QPointF p3Transformed = Vec2ToPoint(transformFunc(p3)); - path.moveTo(p0Transformed); - path.cubicTo(p1Transformed, p2Transformed, p3Transformed); - } - } - else if (curveType == eCECT_2DBezier) - { - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - const SCurveEditorKey& segmentStartKey = *iter; - const SCurveEditorKey& segmentEndKey = *(iter + 1); - - const Vec2 p0 = Vec2(segmentStartKey.m_time, segmentStartKey.m_value); - const Vec2 p3 = Vec2(segmentEndKey.m_time, segmentEndKey.m_value); - const Vec2 p1 = p0 + segmentStartKey.m_outTangent; - const Vec2 p2 = p3 + segmentEndKey.m_inTangent; - - const QPointF p1Transformed = Vec2ToPoint(transformFunc(p1)); - const QPointF p2Transformed = Vec2ToPoint(transformFunc(p2)); - const QPointF p3Transformed = Vec2ToPoint(transformFunc(p3)); - path.cubicTo(p1Transformed, p2Transformed, p3Transformed); - } - } - - return path; - } - - // Renders path outside of the current range of the curve - QPainterPath CreateExtrapolatedPathFromCurve(const SCurveEditorCurve& curve, AZStd::function transformFunc, float windowWidth) - { - QPainterPath path; - - if (curve.m_keys.size() > 0) - { - const Vec2 startPoint = Vec2(curve.m_keys[0].m_time, curve.m_keys[0].m_value); - const Vec2 startTransformed = transformFunc(startPoint); - if (startTransformed.x > 0.0f) - { - path.moveTo(std::min(startTransformed.x, windowWidth), startTransformed.y); - path.lineTo(0.0f, startTransformed.y); - } - - const Vec2 endPoint(curve.m_keys.back().m_time, curve.m_keys.back().m_value); - const Vec2 endTransformed = transformFunc(endPoint); - if (endTransformed.x < windowWidth) - { - path.moveTo(std::max(endTransformed.x, 0.0f), endTransformed.y); - path.lineTo(windowWidth, endTransformed.y); - } - } - else - { - const Vec2 pointOnCurve = Vec2(0.0f, curve.m_defaultValue); - const Vec2 pointOnTransformed = transformFunc(pointOnCurve); - path.moveTo(0.0, pointOnTransformed.y); - path.lineTo(windowWidth, pointOnTransformed.y); - } - - QVector dashPattern; - dashPattern << 16 << 8; - - QPainterPathStroker stroker; - stroker.setCapStyle(Qt::RoundCap); - stroker.setDashPattern(dashPattern); - stroker.setWidth(0.5); - - return stroker.createStroke(path); - } - - // Renders line between discontinuous path when step mode is used for a control point - QPainterPath CreateDiscontinuinityPathFromCurve(const SCurveEditorCurve& curve, ECurveEditorCurveType curveType, AZStd::function transformFunc) - { - QPainterPath path; - - if (curve.m_keys.size() > 0) - { - const auto endIter = curve.m_keys.end() - 1; - - if (curveType == eCECT_Bezier && !curve.m_customInterpolator) - { - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - const SCurveEditorKey* pKeyLeftOfSegment = (iter != curve.m_keys.begin()) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pKeyRightOfSegment = (iter != (curve.m_keys.end() - 2)) ? &*(iter + 2) : nullptr; - - const SCurveEditorKey segmentStartKey = ApplyOutTangentFlags(*iter, pKeyLeftOfSegment, *(iter + 1)); - const SCurveEditorKey segmentEndKey = ApplyInTangentFlags(*(iter + 1), *iter, pKeyRightOfSegment); - - if (segmentStartKey.m_value != iter->m_value) - { - const Vec2 start = Vec2(segmentStartKey.m_time, segmentStartKey.m_value); - const Vec2 end = Vec2(iter->m_time, iter->m_value); - - const QPointF startTransformed = Vec2ToPoint(transformFunc(start)); - const QPointF endTransformed = Vec2ToPoint(transformFunc(end)); - - path.moveTo(startTransformed); - path.lineTo(endTransformed); - } - - if (segmentEndKey.m_value != (iter + 1)->m_value) - { - const Vec2 start = Vec2(segmentEndKey.m_time, segmentEndKey.m_value); - const Vec2 end = Vec2((iter + 1)->m_time, (iter + 1)->m_value); - - const QPointF startTransformed = Vec2ToPoint(transformFunc(start)); - const QPointF endTransformed = Vec2ToPoint(transformFunc(end)); - - path.moveTo(startTransformed); - path.lineTo(endTransformed); - } - } - } - } - - QVector dashPattern; - dashPattern << 2 << 10; - - QPainterPathStroker stroker; - stroker.setCapStyle(Qt::RoundCap); - stroker.setDashPattern(dashPattern); - stroker.setWidth(0.5); - - return stroker.createStroke(path); - } - - void DrawPointRect(QPainter& painter, QPointF point, const QColor& color) - { - painter.setBrush(QBrush(color)); - painter.setPen(QColor(0, 0, 0)); - painter.drawRect(QRectF(point - kPointRectExtent, point + kPointRectExtent)); - } - - void ForEachKey(SCurveEditorContent& content, AZStd::function fun) - { - for (auto iter = content.m_curves.begin(); iter != content.m_curves.end(); ++iter) - { - SCurveEditorCurve& curve = *iter; - for (size_t i = 0; i < curve.m_keys.size(); ++i) - { - fun(curve, curve.m_keys[i]); - } - } - } - - Vec2 ClosestPointOnBezierSegment(const Vec2 point, const float t0, const float t1, const float p0, const float p1, const float p2, const float p3) - { - using namespace LegacyCryPhysicsUtils; - - // If values are too close the distance function is too flat to be useful. We just assume the curve is flat then - if ((p0 * p0 + p1 * p1 + p2 * p2 + p3 * p3) < 1e-10f) - { - return Vec2(point.x, p0); - } - - const float deltaTime = (t1 - t0); - const float deltaTimeSq = deltaTime * deltaTime; - - // Those are just the normal cubic Bezier formulas B(t) and B'(t) in collected polynomial form - const P3f cubicBezierPoly = P3f(-p0 + 3.0f * p1 - 3.0f * p2 + p3) + P2f(3.0f * p0 - 6.0f * p1 + 3.0f * p2) + P1f(3.0f * p1 - 3.0f * p0) + p0; - const P2f cubicBezierDerivativePoly = P2f(-3.0f * p0 + 9.0f * p1 - 6.0f * p2 + 3.0f * (p3 - p2)) + P1f(6.0f * p0 - 12.0f * p1 + 6.0f * p2) - 3.0f * p0 + 3.0f * p1; - - // lerp(t, t0, t1) in polynomial form - const P1f timePoly = P1f(deltaTime) + t0; - - // Derivative of the distance function (cubicBezierPoly - point.y) ^ 2 + (timePoly - point.x) ^ 2 - const auto distanceDerivativePoly = (cubicBezierDerivativePoly * (cubicBezierPoly - point.y) + (timePoly - point.x) * deltaTime) * 2.0f; - - // The point of minimum distance must be at one of the roots of the distance derivative or at the start/end of the segment - float checkPoints[7]; - const uint numRoots = distanceDerivativePoly.findroots(0.0f, 1.0f, checkPoints + 2); - // Start and end of segment - checkPoints[0] = 0.0f; - checkPoints[1] = 1.0f; - - // Find the closest point under all the candidates - Vec2 closestPoint; - float minDistanceSq = std::numeric_limits::max(); - for (uint i = 0; i < numRoots + 2; ++i) - { - const Vec2 rootPoint(Lerp(t0, t1, checkPoints[i]), EvaluateBezier(checkPoints[i], p0, p1, p2, p3)); - const float deltaX = rootPoint.x - point.x; - const float deltaY = rootPoint.y - point.y; - const float distSq = deltaX * deltaX + deltaY * deltaY; - if (distSq < minDistanceSq) - { - closestPoint = rootPoint; - minDistanceSq = distSq; - } - } - - return closestPoint; - } - - Range GetBezierSegmentValueRange(const SCurveEditorKey& startKey, const SCurveEditorKey& endKey) - { - using namespace LegacyCryPhysicsUtils; - - const float p0 = startKey.m_value; - const float p1 = p0 + startKey.m_outTangent.y; - const float p3 = endKey.m_value; - const float p2 = p3 + endKey.m_inTangent.y; - - Range valueRange(std::min(p0, p3), std::max(p0, p3)); - const P2f cubicBezierDerivativePoly = P2f(-3.0f * p0 + 9.0f * p1 - 6.0f * p2 + 3.0f * (p3 - p2)) + P1f(6.0f * p0 - 12.0f * p1 + 6.0f * p2) - 3.0f * p0 + 3.0f * p1; - - float roots[2]; - const uint numRoots = cubicBezierDerivativePoly.findroots(0.0f, 1.0f, roots); - for (uint i = 0; i < numRoots; ++i) - { - const float rootValue = EvaluateBezier(roots[i], p0, p1, p2, p3); - valueRange.start = std::min(valueRange.start, rootValue); - valueRange.end = std::max(valueRange.end, rootValue); - } - return valueRange; - } - - float DistanceTo2DBezierSegment([[maybe_unused]] const Vec2 point, [[maybe_unused]] const SCurveEditorKey& startKey, [[maybe_unused]] const SCurveEditorKey& endKey) - { - return std::numeric_limits::max(); - } - - - void SmoothTangents(const SCurveEditorKey& key, Vec2& inTangent, Vec2& outTangent, SCurveEditorKey* pLeftKey, SCurveEditorKey* pRightKey, bool applyInverseSegmentLengthFactor) - { - inTangent.Normalize(); - outTangent.Normalize(); - - if (!pLeftKey && !pRightKey) - { - return; - } - else if (!pLeftKey) - { - inTangent = -outTangent; - } - else if (!pRightKey) - { - outTangent = -inTangent; - } - else - { - const float deltaTime = pRightKey->m_time - pLeftKey->m_time; - const float ratio = (key.m_time - pLeftKey->m_time) / deltaTime; - - Vec2 smoothedTangent = Vec2::CreateLerp(-inTangent, outTangent, applyInverseSegmentLengthFactor ? ratio : 0.5f); - inTangent = -smoothedTangent; - outTangent = smoothedTangent; - } - - if (pLeftKey) - { - float leftSegmentTime = key.m_time - pLeftKey->m_time; - float inFactor = (leftSegmentTime / -inTangent.x) / 3.0f; - inTangent *= inFactor; - } - if (pRightKey) - { - float rightSegmentTime = pRightKey->m_time - key.m_time; - float outFactor = (rightSegmentTime / outTangent.x) / 3.0f; - outTangent *= outFactor; - } - } - - Vec2 GetSmoothInTangent(SCurveEditorKey& key, Vec2 inTangent, Vec2 outTangent, SCurveEditorKey* pLeftKey, SCurveEditorKey* pRightKey, bool applyInverseSegmentLengthFactor) - { - SmoothTangents(key, inTangent, outTangent, pLeftKey, pRightKey, applyInverseSegmentLengthFactor); - return inTangent; - } - - Vec2 GetSmoothOutTangent(SCurveEditorKey& key, Vec2 inTangent, Vec2 outTangent, SCurveEditorKey* pLeftKey, SCurveEditorKey* pRightKey, bool applyInverseSegmentLengthFactor) - { - SmoothTangents(key, inTangent, outTangent, pLeftKey, pRightKey, applyInverseSegmentLengthFactor); - return outTangent; - } -} - -void showTooltip(const SCurveEditorKey& key, const QPoint& pos, QWidget* parent, QString tipOverride = QString()) -{ - if (!tipOverride.isEmpty()) - { - return QToolTip::showText(pos, tipOverride, parent); - } - - QString tip = QString().asprintf("%s <- [%5.2f, %5.2f] -> %s", - CCurveEditor::TangentTypeToString(key.m_inTangentType).toUtf8().data(), - key.m_time, key.m_time, - CCurveEditor::TangentTypeToString(key.m_outTangentType).toUtf8().data()); - - QToolTip::showText(pos, tip, parent); -} - -struct CCurveEditor::SSelectionHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - QPoint m_startPoint; - QRect m_rect; - bool m_bAdd; - - SSelectionHandler(CCurveEditor* pCurveEditor, bool bAdd) - : m_pCurveEditor(pCurveEditor) - , m_bAdd(bAdd) {} - - void mousePressEvent(QMouseEvent* pEvent) override - { - m_startPoint = pEvent->pos(); - m_rect = QRect(m_startPoint, m_startPoint + QPoint(1, 1)); - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - m_rect = QRect(m_startPoint, pEvent->pos() + QPoint(1, 1)); - } - - void mouseReleaseEvent([[maybe_unused]] QMouseEvent* pEvent) override - { - m_pCurveEditor->SelectInRect(m_rect); - } - - void paintOver(QPainter& painter) override - { - painter.save(); - QColor highlightColor = m_pCurveEditor->palette().color(QPalette::Highlight); - QColor highlightColorA = QColor(highlightColor.red(), highlightColor.green(), highlightColor.blue(), 128); - painter.setPen(QPen(highlightColor)); - painter.setBrush(QBrush(highlightColorA)); - painter.drawRect(QRectF(m_rect)); - painter.restore(); - } -}; - -struct CCurveEditor::SPanHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - QPoint m_startPoint; - Vec2 m_startTranslation; - - SPanHandler(CCurveEditor* pCurveEditor) - : m_pCurveEditor(pCurveEditor) - { - } - - void mousePressEvent(QMouseEvent* pEvent) override - { - if (m_pCurveEditor->m_optOutFlags & EOptOutZoomingAndPanning) - { - return; - } - m_startPoint = QPoint(int(pEvent->x()), int(pEvent->y())); - m_startTranslation = m_pCurveEditor->m_translation; - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - if (m_pCurveEditor->m_optOutFlags & EOptOutZoomingAndPanning) - { - return; - } - const Vec2 windowSize((float)m_pCurveEditor->size().width(), (float)m_pCurveEditor->size().height()); - - const int pixelDeltaX = pEvent->x() - m_startPoint.x(); - const int pixelDeltaY = pEvent->y() - m_startPoint.y(); - - float deltaX = float(pixelDeltaX) / (windowSize.x); - float deltaY = float(pixelDeltaY) / (windowSize.y); - - if (m_pCurveEditor->IsTimeRangeEnforced()) - { - deltaX = 0; - } - - const Vec2 delta(deltaX, deltaY); - m_pCurveEditor->m_translation = m_startTranslation + delta; - m_pCurveEditor->update(); - } -}; - -struct CCurveEditor::SZoomHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - QPoint m_lastPoint; - - SZoomHandler(CCurveEditor* pCurveEditor) - : m_pCurveEditor(pCurveEditor) - { - } - - void mousePressEvent(QMouseEvent* pEvent) override - { - if (m_pCurveEditor->m_optOutFlags & EOptOutZoomingAndPanning) - { - return; - } - m_lastPoint = QPoint(int(pEvent->x()), int(pEvent->y())); - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - if (m_pCurveEditor->m_optOutFlags & EOptOutZoomingAndPanning) - { - return; - } - const Vec2 windowSize((float)m_pCurveEditor->size().width(), (float)m_pCurveEditor->size().height()); - - const int pixelDeltaX = pEvent->x() - m_lastPoint.x(); - const int pixelDeltaY = pEvent->y() - m_lastPoint.y(); - - m_lastPoint = QPoint(int(pEvent->x()), int(pEvent->y())); - - m_pCurveEditor->m_zoom.x *= pow(1.2f, (float)pixelDeltaX * 0.03f); - m_pCurveEditor->m_zoom.y *= pow(1.2f, (float)pixelDeltaY * 0.03f); - - m_pCurveEditor->m_zoom.x = clamp_tpl(m_pCurveEditor->m_zoom.x, kMinZoom, kMaxZoom); - m_pCurveEditor->m_zoom.y = clamp_tpl(m_pCurveEditor->m_zoom.y, kMinZoom, kMaxZoom); - - m_pCurveEditor->update(); - } -}; - -struct CCurveEditor::SScrubHandler - : SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - float m_startThumbPosition; - QPoint m_startPoint; - - SScrubHandler(CCurveEditor* pCurveEditor) - : m_pCurveEditor(pCurveEditor) - { - } - - void mousePressEvent(QMouseEvent* ev) override - { - QPoint point = QPoint(ev->pos().x(), ev->pos().y()); - - const Vec2 pointInCurveSpace = TransformPointFromScreen(m_pCurveEditor->m_zoom, m_pCurveEditor->m_translation, m_pCurveEditor->GetCurveArea(), PointToVec2(point)); - - m_pCurveEditor->m_time = pointInCurveSpace.x; - m_startThumbPosition = m_pCurveEditor->m_time; - m_startPoint = point; - - m_pCurveEditor->SignalScrub(); - } - - void Apply(QMouseEvent* ev, [[maybe_unused]] bool continuous) - { - QPoint point = QPoint(ev->pos().x(), ev->pos().y()); - - bool shift = ev->modifiers().testFlag(Qt::ShiftModifier); - bool control = ev->modifiers().testFlag(Qt::ControlModifier); - - const float deltaX = (float)(point.x() - m_startPoint.x()); - const float width = (float)m_pCurveEditor->size().width(); - float delta = float(deltaX) / (width * m_pCurveEditor->m_zoom.x); - - if (shift) - { - delta *= 0.01f; - } - - if (control) - { - delta *= 0.1f; - } - - m_pCurveEditor->m_time = m_startThumbPosition + delta; - m_pCurveEditor->SignalScrub(); - } - - void mouseMoveEvent(QMouseEvent* ev) override - { - Apply(ev, true); - } - - void mouseReleaseEvent(QMouseEvent* ev) override - { - Apply(ev, false); - } -}; - -struct CCurveEditor::SMoveKeyHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - bool m_bCycleSelection; - Vec2 m_startPoint; - std::vector m_keyPositions; - bool m_clamp; - QRectF m_range; - - SMoveKeyHandler(CCurveEditor* pCurveEditor, bool bCycleSelection, QRectF* clampRange = nullptr) - : m_pCurveEditor(pCurveEditor) - , m_bCycleSelection(bCycleSelection) - , m_startPoint(0.0f, 0.0f) - , m_clamp(clampRange ? true : false) - , m_range(clampRange ? *clampRange : QRectF()) - {} - - void mousePressEvent(QMouseEvent* pEvent) override - { - const QPoint currentPos = pEvent->pos(); - m_startPoint = TransformPointFromScreen(m_pCurveEditor->m_zoom, - m_pCurveEditor->m_translation, m_pCurveEditor->GetCurveArea(), PointToVec2(currentPos)); - StoreKeyPositions(); - m_pCurveEditor->SignalKeyMoveStarted(); - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - RestoreKeyPositions(); - const QPoint currentPos = pEvent->pos(); - Vec2 transformedPos = TransformPointFromScreen(m_pCurveEditor->m_zoom, - m_pCurveEditor->m_translation, m_pCurveEditor->GetCurveArea(), PointToVec2(currentPos)); - - const Vec2 offset = transformedPos - m_startPoint; - - SCurveEditorContent* pContent = m_pCurveEditor->m_pContent; - for (auto curveIter = pContent->m_curves.begin(); curveIter != pContent->m_curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - - for (auto iter = curve.m_keys.begin(); iter != curve.m_keys.end(); ++iter) - { - if (iter->m_bSelected) - { - iter->m_time += offset.x; - iter->m_value += offset.y; - if (m_clamp) - { - iter->m_time = clamp_tpl(iter->m_time, (float)m_range.left(), (float)m_range.right()); - iter->m_value = clamp_tpl(iter->m_value, (float)m_range.bottom(), (float)m_range.top()); - } - iter->m_bModified = true; - } - } - - m_pCurveEditor->SortKeys(curve); - } - - m_pCurveEditor->SignalKeyMoved(); - } - - void focusOutEvent([[maybe_unused]] QFocusEvent* pEvent) override - { - RestoreKeyPositions(); - } - - void mouseReleaseEvent([[maybe_unused]] QMouseEvent* pEvent) override - { - m_pCurveEditor->ContentChanged(); - } - - void StoreKeyPositions() - { - SCurveEditorContent* pContent = m_pCurveEditor->m_pContent; - for (auto curveIter = pContent->m_curves.begin(); curveIter != pContent->m_curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - for (auto iter = curve.m_keys.begin(); iter != curve.m_keys.end(); ++iter) - { - if (iter->m_bSelected) - { - m_keyPositions.push_back(Vec2(iter->m_time, iter->m_value)); - } - } - } - } - - void RestoreKeyPositions() - { - SCurveEditorContent* pContent = m_pCurveEditor->m_pContent; - auto posIter = m_keyPositions.begin(); - for (auto curveIter = pContent->m_curves.begin(); curveIter != pContent->m_curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - for (auto iter = curve.m_keys.begin(); iter != curve.m_keys.end(); ++iter) - { - if (iter->m_bSelected) - { - iter->m_time = posIter->x; - iter->m_value = (posIter++)->y; - } - } - } - } -}; - -struct CCurveEditor::SRotateTangentHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - CCurveEditorTangentControl* m_pSelectedTangent; - Vec2 m_StartPoint; - Vec2 m_InitialInTangent; - SCurveEditorKey::ETangentType m_InitialInTangentType; - Vec2 m_InitialOutTangent; - SCurveEditorKey::ETangentType m_InitialOutTangentType; - - SRotateTangentHandler(CCurveEditor* pCurveEditor, CCurveEditorTangentControl* pTangentControl) - : m_pCurveEditor(pCurveEditor) - , m_pSelectedTangent(pTangentControl) - , m_StartPoint(0.0f, 0.0f) - {} - - void mousePressEvent(QMouseEvent* pEvent) override - { - const QPoint currentPos = pEvent->pos(); - m_StartPoint = m_pCurveEditor->TransformFromScreenCoordinates(PointToVec2(currentPos)); - - StoreTangents(); - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - const QPoint currentPos = pEvent->pos(); - const Vec2 transformedPos = m_pCurveEditor->TransformFromScreenCoordinates(PointToVec2(currentPos)); - const Vec2 offset = transformedPos - m_StartPoint; - - SCurveEditorKey& key = m_pSelectedTangent->GetControl().GetKey(); - Vec2 keyPos(key.m_time, key.m_value); - - bool isInTangent = m_pSelectedTangent->GetTangentDirection() == ETangent_In; - bool shouldTangentsBePaired = key.m_inTangentType == key.m_outTangentType - && (key.m_inTangentType == SCurveEditorKey::eTangentType_Standard - || key.m_inTangentType == SCurveEditorKey::eTangentType_Smooth - || key.m_inTangentType == SCurveEditorKey::eTangentType_Flat); - - float tangentEpsilon = 1e-6f; - - // strictly left or right of key - have a fairly large epsilon to avoid weird floating point innaccuracies in editor - bool leftOfKey = (transformedPos.x - keyPos.x) < -tangentEpsilon; - bool rightOfKey = (transformedPos.x - keyPos.x) > tangentEpsilon; - bool tangentVertical = !(leftOfKey || rightOfKey); - - if ((isInTangent && leftOfKey) || (shouldTangentsBePaired && !tangentVertical)) - { - Vec2 newInTangent = transformedPos - keyPos; - if (rightOfKey) - { - // mirror tangent - newInTangent *= -1; - } - float scale = key.m_inTangent.x / newInTangent.x; - newInTangent *= scale; - key.m_inTangent = newInTangent; - - key.m_inTangentType = shouldTangentsBePaired ? SCurveEditorKey::eTangentType_Standard : key.m_inTangentType; - } - - if ((!isInTangent && rightOfKey) || (shouldTangentsBePaired && !tangentVertical)) - { - Vec2 newOutTangent = transformedPos - keyPos; - if (leftOfKey) - { - // mirror tangent - newOutTangent *= -1; - } - float scale = key.m_outTangent.x / newOutTangent.x; - newOutTangent *= scale; - key.m_outTangent = newOutTangent; - - key.m_outTangentType = shouldTangentsBePaired ? SCurveEditorKey::eTangentType_Standard : key.m_outTangentType; - } - } - - void focusOutEvent([[maybe_unused]] QFocusEvent* pEvent) override - { - RestoreTangents(); - } - - void mouseReleaseEvent([[maybe_unused]] QMouseEvent* pEvent) override - { - m_pCurveEditor->ContentChanged(); - } - - void StoreTangents() - { - SCurveEditorKey& key = m_pSelectedTangent->GetControl().GetKey(); - - m_InitialInTangent = key.m_inTangent; - m_InitialInTangentType = key.m_inTangentType; - - m_InitialOutTangent = key.m_outTangent; - m_InitialOutTangentType = key.m_outTangentType; - } - - void RestoreTangents() - { - SCurveEditorKey& key = m_pSelectedTangent->GetControl().GetKey(); - - key.m_inTangent = m_InitialInTangent; - key.m_inTangentType = m_InitialInTangentType; - - key.m_outTangent = m_InitialOutTangent; - key.m_outTangentType = m_InitialOutTangentType; - } -}; - -CCurveEditor::CCurveEditor(QWidget* parent) - : QWidget(parent) - , m_pContent(nullptr) - , m_pMouseHandler(nullptr) - , m_curveType(eCECT_Bezier) - , m_bWeighted(false) - , m_bHandlesVisible(true) - , m_bRulerVisible(true) - , m_bTimeSliderVisible(true) - , m_time(0.0f) - , m_zoom(0.5f, 0.5f) - , m_translation(0.5f, 0.5f) - , m_timeRange(0, 1) - , m_timeRangeEnforced(false) - , m_valueRange(0, 1) - , m_optOutFlags(0) -{ - setMouseTracking(true); - //EnforceTimeRange(0.0f, 1.0f); - SetTimeRange(0, 1); - SetValueRange(0, 1); - ZoomToTimeRange(-0.1f, 1.1f); - ZoomToValueRange(-0.1f, 1.1f); - SetRulerVisible(true); - QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - setSizePolicy(sizePolicy); -} - -CCurveEditor::~CCurveEditor() -{ -} - -void CCurveEditor::SetContent(SCurveEditorContent* pContent) -{ - m_pContent = pContent; - - ContentChanged(); - - update(); -} - -void CCurveEditor::SetTime(const float time) -{ - m_time = time; - update(); -} - -void CCurveEditor::SetTimeRange(const float start, const float end) -{ - SetTimeRange(start, end, false); -} - -void CCurveEditor::EnforceTimeRange(const float start, const float end) -{ - SetTimeRange(start, end, true); - ZoomToTimeRange(start, end); -} - -bool CCurveEditor::IsTimeRangeEnforced() const -{ - return m_timeRangeEnforced; -} - -void CCurveEditor::SetTimeRange(const float start, const float end, bool enforce) -{ - if (start <= end) - { - m_timeRangeEnforced = enforce; - m_timeRange = Range(start, end); - update(); - } -} - -void CCurveEditor::SetValueRange(const float min, const float max) -{ - if (min <= max) - { - m_valueRange = Range(min, max); - update(); - } -} - -void CCurveEditor::ZoomToTimeRange(const float start, const float end) -{ - if (start < end) - { - m_zoom.x = 1.0f / (end - start); - m_translation.x = start / (start - end); - } -} - -void CCurveEditor::ZoomToValueRange(const float min, const float max) -{ - if (min < max) - { - m_zoom.y = 1.0f / (max - min); - m_translation.y = max / (max - min); - } -} - -void CCurveEditor::paintEvent([[maybe_unused]] QPaintEvent* pEvent) -{ - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.translate(0.5f, 0.5f); - - const QPalette& palette = this->palette(); - - auto transformFunc = [&](Vec2 point) - { - return TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), point); - }; - - auto invTransformFunc = [&](Vec2 screenPoint) - { - return TransformPointFromScreen(m_zoom, m_translation, GetCurveArea(), screenPoint); - }; - - const QColor rangeHighlightColor = CurveEditorHelpers::LerpColor(palette.color(QPalette::WindowText), palette.color(QPalette::Window), 0.95f); - const QRectF rangesRect(Vec2ToPoint(transformFunc(Vec2(m_timeRange.start, m_valueRange.start))), Vec2ToPoint(transformFunc(Vec2(m_timeRange.end, m_valueRange.end)))); - painter.setPen(QPen(Qt::NoPen)); - if ((m_optOutFlags & EOptOutBackground)) - { - painter.setBrush(Qt::transparent); - } - else - { - painter.setBrush(rangeHighlightColor); - } - - if ((m_optOutFlags & EOptOutRuler)) - { - painter.drawRect(rangesRect); - } - else - { - painter.drawRect(rect()); - } - - if (m_pContent) - { - const QPen extrapolatedCurvePen = QPen(palette.color(QPalette::Highlight)); - - TCurveEditorCurves& curves = m_pContent->m_curves; - for (auto curveIter = curves.begin(); curveIter != curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - QColor penColor = QColor(curve.m_color.r, curve.m_color.g, curve.m_color.b, curve.m_color.a); - - if (!(m_optOutFlags & EOptOutCustomPenColor) && m_penColor.isValid()) - { - penColor = m_penColor; - } - - painter.setBrush(QBrush(Qt::NoBrush)); - const QPen curvePen = QPen(penColor, 2); - const QPen narrowCurvePen = QPen(penColor); - if (!(m_optOutFlags & eOptOutDashedPath)) - { - const QPainterPath extrapolatedPath = CreateExtrapolatedPathFromCurve(curve, transformFunc, aznumeric_cast(width())); - painter.setPen(narrowCurvePen); - painter.drawPath(extrapolatedPath); - } - - const QPainterPath discontinuinityPath = CreateDiscontinuinityPathFromCurve(curve, m_curveType, transformFunc); - painter.setPen(narrowCurvePen); - painter.drawPath(discontinuinityPath); - - if (curve.m_keys.size() > 0) - { - UpdateTangents(); - const QPainterPath path = CreatePathFromCurve(curve, m_curveType, transformFunc); - painter.setPen(curvePen); - painter.drawPath(path); - } - } - } - - if (!(m_optOutFlags & EOptOutSelectionKey)) - { - if ((m_optOutFlags & EOptOutKeyIcon)) - { - for (CCurveEditorControl* pControlKey : m_pControlKeys) - { - pControlKey->Paint(painter, palette, !(m_optOutFlags & EOptOutSelectionInOutTangent)); - } - } - else - { - for (CCurveEditorControl* pControlKey : m_pControlKeys) - { - pControlKey->PaintIcon(painter, palette, !(m_optOutFlags & EOptOutSelectionInOutTangent)); - } - } - } - - if (m_pMouseHandler) - { - m_pMouseHandler->paintOver(painter); - } - if (!(m_optOutFlags & EOptOutRuler)) - { - DrawingPrimitives::SRulerOptions rulerOptions; - rulerOptions.m_rect = QRect(0, -1, size().width(), kRulerHeight + 2); - rulerOptions.m_visibleRange = Range(-m_translation.x / m_zoom.x, (1.0f - m_translation.x) / m_zoom.x); - rulerOptions.m_rulerRange = rulerOptions.m_visibleRange; - rulerOptions.m_markHeight = kRulerMarkHeight; - rulerOptions.m_shadowSize = kRulerShadowHeight; - rulerOptions.m_textXOffset = kTextXOffset; - rulerOptions.m_textYOffset = kTextYOffset; - - int rulerPrecision; - DrawingPrimitives::DrawRuler(painter, palette, rulerOptions, &rulerPrecision); - - if (m_pContent && isEnabled() && !(m_optOutFlags & EOptOutTimeSlider)) - { - DrawingPrimitives::STimeSliderOptions timeSliderOptions; - timeSliderOptions.m_rect = rect(); - timeSliderOptions.m_precision = rulerPrecision; - timeSliderOptions.m_position = aznumeric_cast(transformFunc(Vec2(m_time, 0.0f)).x); - timeSliderOptions.m_time = m_time; - timeSliderOptions.m_bHasFocus = hasFocus(); - DrawingPrimitives::DrawTimeSlider(painter, palette, timeSliderOptions); - } - } -} - -void CCurveEditor::mousePressEvent(QMouseEvent* pEvent) -{ - if (m_optOutFlags & EOptOutControls) - { - return QWidget::mousePressEvent(pEvent); - } - setFocus(); - - if (pEvent->button() == Qt::LeftButton) - { - LeftButtonMousePressEvent(pEvent); - } - else if (pEvent->button() == Qt::MiddleButton) - { - MiddleButtonMousePressEvent(pEvent); - } - else if (pEvent->button() == Qt::RightButton) - { - RightButtonMousePressEvent(pEvent); - } -} - -void CCurveEditor::mouseDoubleClickEvent(QMouseEvent* pEvent) -{ - if (m_optOutFlags & EOptOutControls) - { - return QWidget::mouseDoubleClickEvent(pEvent); - } - if (pEvent->button() == Qt::LeftButton) - { - auto curveHitPair = HitDetectCurve(pEvent->pos()); - if (curveHitPair.first) - { - if (AddPointToCurve(curveHitPair.second, curveHitPair.first)) - { - setCursor(QCursor(Qt::SizeAllCursor)); - } - } - } -} - -void CCurveEditor::LeftButtonMousePressEvent(QMouseEvent* pEvent) -{ - const bool bCtrlPressed = (pEvent->modifiers() & Qt::CTRL) != 0; - const bool bAltPressed = (pEvent->modifiers() & Qt::ALT) != 0; - - if (pEvent->y() < kRulerHeight && !(m_optOutFlags & EOptOutRuler)) - { - m_pMouseHandler.reset(new SScrubHandler(this)); - m_pMouseHandler->mousePressEvent(pEvent); - } - else - { - if (bCtrlPressed) - { - auto curveHitPair = HitDetectCurve(pEvent->pos()); - if (curveHitPair.first) - { - if (AddPointToCurve(curveHitPair.second, curveHitPair.first)) - { - setCursor(QCursor(Qt::SizeAllCursor)); - } - } - } - else if (bAltPressed) - { - auto pCurveKey = HitDetectKey(pEvent->pos()); - if (pCurveKey) - { - pCurveKey->MarkKeyForRemoval(); - ContentChanged(); - } - } - else - { - auto pTangentKey = HitDetectTangent(pEvent->pos()); - if (pTangentKey) - { - SelectTangent(pTangentKey); - - m_pMouseHandler.reset(new SRotateTangentHandler(this, pTangentKey)); - } - else - { - auto pCurveKey = HitDetectKey(pEvent->pos()); - if (pCurveKey) - { - SelectKey(pCurveKey, false); - - QRectF range; - range.setLeft(m_timeRange.start); - range.setRight(m_timeRange.end); - range.setBottom(m_valueRange.start); - range.setTop(m_valueRange.end); - - m_pMouseHandler.reset(new SMoveKeyHandler(this, false, - m_timeRangeEnforced ? &range : nullptr)); - } - else - { - m_pMouseHandler.reset(new SSelectionHandler(this, false)); - } - } - - m_pMouseHandler->mousePressEvent(pEvent); - } - } - - update(); -} - -void CCurveEditor::MiddleButtonMousePressEvent(QMouseEvent* pEvent) -{ - const bool bShiftPressed = (pEvent->modifiers() & Qt::SHIFT) != 0; - - if (!bShiftPressed) - { - m_pMouseHandler.reset(new SPanHandler(this)); - } - else - { - m_pMouseHandler.reset(new SZoomHandler(this)); - } - - m_pMouseHandler->mousePressEvent(pEvent); - update(); -} - -void CCurveEditor::RightButtonMousePressEvent(QMouseEvent* pEvent) -{ - CCurveEditorControl* pCurveKey = HitDetectKey(pEvent->pos()); - if (pCurveKey) - { - SelectKey(pCurveKey, false); - update(); //Repaint so that we see that the key is selected - - QMenu* pMenu = new QMenu(this); - PopulateControlContextMenu(pMenu); - pMenu->popup(pEvent->globalPos()); - } - else - { - return QWidget::mousePressEvent(pEvent); - } -} - -void CCurveEditor::mouseMoveEvent(QMouseEvent* pEvent) -{ - if (m_optOutFlags & EOptOutControls) - { - return QWidget::mouseMoveEvent(pEvent); - } - const CCurveEditorControl* control = HitDetectKey(pEvent->pos()); - if (control) - { - if (!(m_optOutFlags & EOptOutDefaultTooltip)) - { - showTooltip(control->GetKey(), pEvent->globalPos(), this, control->GetToolTip()); - } - setCursor(QCursor(Qt::SizeAllCursor)); - } - else - { - if (!(m_optOutFlags & EOptOutDefaultTooltip)) - { - QToolTip::hideText(); - } - setCursor(QCursor()); - } - - if (m_pMouseHandler) - { - m_pMouseHandler->mouseMoveEvent(pEvent); - } - - update(); -} - -void CCurveEditor::mouseReleaseEvent(QMouseEvent* pEvent) -{ - if (m_optOutFlags & EOptOutControls) - { - return QWidget::mouseReleaseEvent(pEvent); - } - if (m_pMouseHandler) - { - m_pMouseHandler->mouseReleaseEvent(pEvent); - m_pMouseHandler.reset(); - update(); - } -} - -void CCurveEditor::focusOutEvent(QFocusEvent* pEvent) -{ - if (m_optOutFlags & EOptOutControls) - { - return focusOutEvent(pEvent); - } - if (m_pMouseHandler) - { - m_pMouseHandler->focusOutEvent(pEvent); - m_pMouseHandler.reset(); - update(); - } -} - -void CCurveEditor::wheelEvent(QWheelEvent* pEvent) -{ - if (m_optOutFlags & EOptOutControls || m_optOutFlags & EOptOutZoomingAndPanning) - { - return QWidget::wheelEvent(pEvent); - } - Vec2 windowSize((float)size().width(), (float)size().height()); - windowSize.y = (windowSize.y > 0.0f) ? windowSize.y : 1.0f; - - const QRect curveArea = GetCurveArea(); - const float mouseXNormalized = (float)(pEvent->position().x() - curveArea.left()) / (float)curveArea.width(); - const float mouseYNormalized = (float)(pEvent->position().y() - curveArea.top()) / (float)curveArea.height(); - - const float pivotX = (mouseXNormalized - m_translation.x) / m_zoom.x; - const float pivotY = (mouseYNormalized - m_translation.y) / m_zoom.y; - - float zoomFactor = pow(1.2f, (float)pEvent->angleDelta().y() * 0.01f); - - if (!m_timeRangeEnforced) - { - m_zoom.x *= zoomFactor; - } - m_zoom.y *= zoomFactor; - - m_zoom.x = clamp_tpl(m_zoom.x, kMinZoom, kMaxZoom); - m_zoom.y = clamp_tpl(m_zoom.y, kMinZoom, kMaxZoom); - - // Adjust translation so pivot point stays at same x and y position on screen - m_translation.x += ((mouseXNormalized - m_translation.x) / m_zoom.x - pivotX) * m_zoom.x; - m_translation.y += ((mouseYNormalized - m_translation.y) / m_zoom.y - pivotY) * m_zoom.y; - - update(); -} - -void CCurveEditor::keyPressEvent(QKeyEvent* pEvent) -{ - if (m_optOutFlags & EOptOutControls) - { - return QWidget::keyPressEvent(pEvent); - } - if (!m_pContent) - { - return; - } - - QKeySequence key(pEvent->key()); - - if (key == QKeySequence(Qt::Key_Delete)) - { - OnDeleteSelectedKeys(); - } - - update(); -} - -void CCurveEditor::SetCurveType(ECurveEditorCurveType curveType) -{ - m_curveType = curveType; -} - -void CCurveEditor::SetHandlesVisible(bool bVisible) -{ - m_bHandlesVisible = bVisible; - update(); -} - -void CCurveEditor::SetRulerVisible(bool bVisible) -{ - m_bRulerVisible = bVisible; - update(); -} - -void CCurveEditor::SetTimeSliderVisible(bool bVisible) -{ - m_bTimeSliderVisible = bVisible; - update(); -} - -std::pair CCurveEditor::HitDetectCurve(const QPoint point) -{ - if (!m_pContent) - { - return std::make_pair(nullptr, Vec2(ZERO)); - } - - SCurveEditorCurve* pNearestCurve = nullptr; - Vec2 closestPoint = Vec2(ZERO); - - float nearestDistance = std::numeric_limits::max(); - for (auto iter = m_pContent->m_curves.rbegin(); iter != m_pContent->m_curves.rend(); ++iter) - { - SCurveEditorCurve& curve = *iter; - const Vec2 closestPointOnCurve = ClosestPointOnCurve(PointToVec2(point), curve, m_curveType); - - const float distance = (PointToVec2(point) - closestPointOnCurve).GetLength(); - if (distance < nearestDistance) - { - nearestDistance = distance; - pNearestCurve = &curve; - closestPoint = closestPointOnCurve; - } - } - - if (nearestDistance <= kHitDistance) - { - return std::make_pair(pNearestCurve, TransformPointFromScreen(m_zoom, m_translation, GetCurveArea(), closestPoint)); - } - - return std::make_pair(nullptr, Vec2(ZERO)); -} - -CCurveEditorControl* CCurveEditor::GetSelectedCurveKey() -{ - for (CCurveEditorControl* pControlKey : m_pControlKeys) - { - if (pControlKey->IsSelected()) - { - return pControlKey; - } - } - return nullptr; -} - - -CCurveEditorControl* CCurveEditor::HitDetectKey(const QPoint point) -{ - for (CCurveEditorControl* pControlKey : m_pControlKeys) - { - if (pControlKey->IsMouseWithinControl(point)) - { - return pControlKey; - } - } - - return NULL; -} - -CCurveEditorTangentControl* CCurveEditor::HitDetectTangent(const QPoint point) -{ - if (m_optOutFlags & EOptOutSelectionInOutTangent) - { - return NULL; - } - - for (CCurveEditorControl* pControlKey : m_pControlKeys) - { - if (pControlKey->GetInTangent().IsMouseWithinControl(point)) - { - return &pControlKey->GetInTangent(); - } - else if (pControlKey->GetOutTangent().IsMouseWithinControl(point)) - { - return &pControlKey->GetOutTangent(); - } - } - - return NULL; -} - -void CCurveEditor::SelectKey(CCurveEditorControl* pControlToSelect, bool addToExistingSelection) -{ - bool wasSelected = pControlToSelect->IsSelected(); - - if (!wasSelected) - { - if (!addToExistingSelection) - { - for (CCurveEditorControl* pControlKey : m_pControlKeys) - { - pControlKey->SetSelected(false); - } - } - pControlToSelect->SetSelected(true); - //update key selection style - updateCurveKeyShapeColor(); - emit SignalKeySelected(pControlToSelect); - } -} - -void CCurveEditor::SelectTangent(CCurveEditorTangentControl* pTangentToSelect) -{ - bool wasSelected = pTangentToSelect->IsSelected(); - if (!wasSelected) - { - for (CCurveEditorControl* pControlKey : m_pControlKeys) - { - pControlKey->SetSelected(false); - pControlKey->GetInTangent().SetSelected(false); - pControlKey->GetOutTangent().SetSelected(false); - } - pTangentToSelect->GetControl().SetSelected(true); - pTangentToSelect->SetSelected(true); - } -} - -void CCurveEditor::SelectInRect(const QRect& rect) -{ - if (!m_pContent || (m_optOutFlags & EOptOutSelectionKey)) - { - return; - } - - ForEachKey(*m_pContent, [&]([[maybe_unused]] SCurveEditorCurve& curve, SCurveEditorKey& key) - { - const Vec2 screenPoint = TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), Vec2(key.m_time, key.m_value)); - key.m_bSelected = rect.contains((int)screenPoint.x, (int)screenPoint.y); - }); - - update(); -} - -// Input and output are in screen space -Vec2 CCurveEditor::ClosestPointOnCurve(const Vec2 point, const SCurveEditorCurve& curve, const ECurveEditorCurveType curveType) -{ - auto transformFunc = [&](Vec2 point) - { - return TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), point); - }; - - if (curve.m_keys.size() == 0) - { - const Vec2 pointOnCurve = transformFunc(Vec2(0.0f, curve.m_defaultValue)); - return Vec2(point.x, pointOnCurve.y); - } - - Vec2 closestPoint; - float minDistance = std::numeric_limits::max(); - - const Vec2 startKeyTransformed = transformFunc(Vec2(curve.m_keys.front().m_time, curve.m_keys.front().m_value)); - if (point.x < startKeyTransformed.x) - { - const float distanceToCurve = std::abs(point.y - startKeyTransformed.y); - if (distanceToCurve < minDistance) - { - closestPoint = Vec2(point.x, startKeyTransformed.y); - minDistance = distanceToCurve; - } - } - - const Vec2 endKeyTransformed = transformFunc(Vec2(curve.m_keys.back().m_time, curve.m_keys.back().m_value)); - if (point.x > endKeyTransformed.x) - { - const float distanceToCurve = std::abs(point.y - endKeyTransformed.y); - if (distanceToCurve < minDistance) - { - closestPoint = Vec2(point.x, endKeyTransformed.y); - minDistance = distanceToCurve; - } - } - - int numCustomKeys = curve.m_customInterpolator ? curve.m_customInterpolator->GetKeyCount() : 0; - if (numCustomKeys > 1 - && transformFunc(Vec2(curve.m_customInterpolator->GetKeyTime(0), 0)).x <= point.x - && transformFunc(Vec2(curve.m_customInterpolator->GetKeyTime(numCustomKeys - 1), 0)).x >= point.x) - { - const int sampleCount = 5; - for (int sample = 0; sample < sampleCount; sample++) - { - float value; - float offset = (float)sample - floorf((float)sampleCount / 2.0f); - float t = TransformPointFromScreen(m_zoom, m_translation, GetCurveArea(), Vec2(point.x + offset, point.y)).x; - curve.m_customInterpolator->InterpolateFloat(t, value); - value = transformFunc(Vec2(0, value)).y; - const Vec2 closestOnSegment = Vec2(point.x, value); - const float distanceToSegment = (closestOnSegment - point).GetLength(); - if (distanceToSegment < minDistance) - { - closestPoint = closestOnSegment; - minDistance = distanceToSegment; - } - } - } - else - { - const auto endIter = curve.m_keys.end() - 1; - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - if (curveType == eCECT_Bezier) - { - const SCurveEditorKey* pKeyLeftOfSegment = (iter != curve.m_keys.begin()) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pKeyRightOfSegment = (iter != (curve.m_keys.end() - 2)) ? &*(iter + 2) : nullptr; - - const SCurveEditorKey segmentStartKey = ApplyOutTangentFlags(*iter, pKeyLeftOfSegment, *(iter + 1)); - const SCurveEditorKey segmentEndKey = ApplyInTangentFlags(*(iter + 1), *iter, pKeyRightOfSegment); - - const Vec2 p0 = transformFunc(Vec2(segmentStartKey.m_time, segmentStartKey.m_value)); - const Vec2 p3 = transformFunc(Vec2(segmentEndKey.m_time, segmentEndKey.m_value)); - const Vec2 p1 = transformFunc(Vec2(0.0f, segmentStartKey.m_value + segmentStartKey.m_outTangent.y)); - const Vec2 p2 = transformFunc(Vec2(0.0f, segmentEndKey.m_value + segmentEndKey.m_inTangent.y)); - - const Vec2 closestOnSegment = ClosestPointOnBezierSegment(point, p0.x, p3.x, p0.y, p1.y, p2.y, p3.y); - const float distanceToSegment = (closestOnSegment - point).GetLength(); - if (distanceToSegment < minDistance) - { - closestPoint = closestOnSegment; - minDistance = distanceToSegment; - } - } - } - } - - return closestPoint; -} - -void CCurveEditor::ContentChanged() -{ - DeleteMarkedKeys(); - - while (!m_pControlKeys.isEmpty()) - { - delete m_pControlKeys.takeFirst(); - } - - for (auto iter = m_pContent->m_curves.begin(); iter != m_pContent->m_curves.end(); ++iter) - { - SCurveEditorCurve& curve = *iter; - for (size_t i = 0; i < curve.m_keys.size(); ++i) - { - SCurveEditorKey& key = curve.m_keys[i]; - key.m_bModified = false; - - CCurveEditorControl* pControlKey = new CCurveEditorControl(*this, curve, key); - pControlKey->SetSelected(key.m_bSelected); - - m_pControlKeys.append(pControlKey); - } - } - - UpdateTangents(); - - update(); - - SignalContentChanged(); -} - -void CCurveEditor::DeleteMarkedKeys() -{ - if (m_pContent) - { - bool changed = false; - // just delete the underlying key from the data model - the UI controls will be automatically updated to match the new model - for (auto iter = m_pContent->m_curves.begin(); iter != m_pContent->m_curves.end(); ++iter) - { - SCurveEditorCurve& curve = *iter; - for (auto keyIter = curve.m_keys.begin(); keyIter != curve.m_keys.end(); ) - { - if (keyIter->m_bDeleted) - { - keyIter = curve.m_keys.erase(keyIter); - changed = true; - } - else - { - ++keyIter; - } - } - } - } -} - -bool CCurveEditor::AddPointToCurve(const Vec2 point, SCurveEditorCurve* pCurve) -{ - assert(pCurve); - - // Makes sure that a new point can be only added at a safe distance - if (pCurve->m_customInterpolator) - { - const float w = aznumeric_cast(kPointRectExtent.x() * 2); - const float h = aznumeric_cast(kPointRectExtent.y() * 2); - const float minDist = w * w + h * h; - auto keys = pCurve->m_keys; - for (int i = 0; i < keys.size(); i++) - { - const SCurveEditorKey& k = keys[i]; - const Vec2 scrP0 = TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), Vec2(k.m_time, k.m_value)); - const Vec2 scrP1 = TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), point); - const float sqrDist = (scrP1 - scrP0).GetLength2(); - if (sqrDist <= minDist) - { - return false; - } - } - } - - SCurveEditorKey key; - key.m_bAdded = true; - key.m_time = point.x; - float yValue; - pCurve->m_customInterpolator->InterpolateFloat(point.x, yValue); - key.m_value = pCurve->m_customInterpolator ? yValue : point.y; - - // Set in/out tangents based on neighboring keys - const SCurveEditorKey* closestFromLeft = nullptr; - float closestTimeFromLeft = -std::numeric_limits::max(); - const SCurveEditorKey* closestFromRight = nullptr; - float closestTimeFromRight = std::numeric_limits::max(); - for (const SCurveEditorKey& k : pCurve->m_keys) - { - // Check left - if (k.m_time > closestTimeFromLeft && k.m_time < key.m_time) - { - closestTimeFromLeft = k.m_time; - closestFromLeft = &k; - } - - // Check right - if (k.m_time < closestTimeFromRight && k.m_time > key.m_time) - { - closestTimeFromRight = k.m_time; - closestFromRight = &k; - } - } - - if (closestFromLeft) - { - key.m_inTangentType = SCurveEditorKey::eTangentType_Bezier; - float value; - pCurve->m_customInterpolator->EvalInTangentFloat(key.m_time, value); - key.m_inTangent = Vec2(1.0f, value); - - } - - if (closestFromRight) - { - key.m_outTangentType = SCurveEditorKey::eTangentType_Bezier; - float value; - pCurve->m_customInterpolator->EvalOutTangentFloat(key.m_time, value); - key.m_outTangent = Vec2(1.0f, value); - } - - pCurve->m_keys.push_back(key); - - SortKeys(*pCurve); - - ContentChanged(); - return true; -} - -void CCurveEditor::SortKeys(SCurveEditorCurve& curve) -{ - std::stable_sort(curve.m_keys.begin(), curve.m_keys.end(), [](const SCurveEditorKey& a, const SCurveEditorKey& b) - { - return a.m_time < b.m_time; - }); -} - -QString CCurveEditor::TangentTypeToString(SCurveEditorKey::ETangentType type) -{ - switch (type) - { - case SCurveEditorKey::eTangentType_Standard: // Tangent freely rotates but will stay in sync with its pair if its pair is also standard - return tr("Standard"); - case SCurveEditorKey::eTangentType_Free: // Tangent is completely free moving (does not sync with its pair) - return tr("Free"); - case SCurveEditorKey::eTangentType_Step: // Step immediately to value of next control point in tangent direction - return tr("Step"); - case SCurveEditorKey::eTangentType_Linear: // Tangent always points to next control point - return tr("Linear"); - case SCurveEditorKey::eTangentType_Smooth: // Tangent is smoothed automatically based on direction/distance to neighboring controls - return tr("Smooth"); - case SCurveEditorKey::eTangentType_Flat: // Tangent is flattened (y = 0) - will still sync with its pair if both are flat - return tr("Flat"); - case SCurveEditorKey::eTangentType_Bezier: // Tangent is free moving and can be justified by user. Curve defined by Bz - return tr("Bezier"); - default: - break; - } - - return tr("Undefined tangent!"); -} - -void CCurveEditor::OnDeleteSelectedKeys() -{ - ForEachKey(*m_pContent, []([[maybe_unused]] SCurveEditorCurve& curve, SCurveEditorKey& key) - { - key.m_bDeleted = key.m_bDeleted || key.m_bSelected; - }); - - ContentChanged(); -} - -void CCurveEditor::OnSetSelectedKeysTangentStandard() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Standard); - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Standard); - - SmoothSelectedKeys(); -} - -void CCurveEditor::OnSetSelectedKeysTangentSmooth() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Smooth); - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Smooth); -} - -void CCurveEditor::OnSetSelectedKeysTangentFree() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Free); - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Free); -} - -void CCurveEditor::OnSetSelectedKeysTangentBezier() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Bezier); - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Bezier); -} - -void CCurveEditor::OnSetSelectedKeysTangentFlat() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Flat); - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Flat); -} - -void CCurveEditor::OnSetSelectedKeysTangentLinear() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Linear); - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Linear); -} - -void CCurveEditor::OnSetSelectedKeysInTangentFree() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Free); -} - -void CCurveEditor::OnSetSelectedKeysInTangentFlat() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Flat); -} - -void CCurveEditor::OnSetSelectedKeysInTangentLinear() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Linear); -} - -void CCurveEditor::OnSetSelectedKeysInTangentStep() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Step); -} - -void CCurveEditor::OnSetSelectedKeysInTangentBezier() -{ - SetSelectedKeysTangentType(ETangent_In, SCurveEditorKey::eTangentType_Bezier); -} - -void CCurveEditor::OnSetSelectedKeysOutTangentFree() -{ - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Free); -} - -void CCurveEditor::OnSetSelectedKeysOutTangentFlat() -{ - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Flat); -} - -void CCurveEditor::OnSetSelectedKeysOutTangentStep() -{ - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Step); -} - -void CCurveEditor::OnSetSelectedKeysOutTangentLinear() -{ - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Linear); -} - -void CCurveEditor::OnSetSelectedKeysOutTangentBezier() -{ - SetSelectedKeysTangentType(ETangent_Out, SCurveEditorKey::eTangentType_Bezier); -} - -void CCurveEditor::OnFitCurvesHorizontally() -{ - if (m_timeRangeEnforced) - { - return; - } - if (m_pContent) - { - bool bAnyKeyFound = false; - float timeMin = std::numeric_limits::max(); - float timeMax = -std::numeric_limits::max(); - - TCurveEditorCurves& curves = m_pContent->m_curves; - for (auto curveIter = curves.begin(); curveIter != curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - if (curve.m_keys.size() > 0) - { - bAnyKeyFound = true; - timeMin = std::min(curve.m_keys.front().m_time, timeMin); - timeMax = std::max(curve.m_keys.back().m_time, timeMax); - } - } - - if (bAnyKeyFound) - { - ZoomToTimeRange(timeMin, timeMax); - - // Adjust zoom and translation depending on kFitMargin - const float pivot = (0.5f - m_translation.x) / m_zoom.x; - m_zoom.x /= 1.0f + 2.0f * (kFitMargin / GetCurveArea().width()); - m_translation.x += ((0.5f - m_translation.x) / m_zoom.x - pivot) * m_zoom.x; - - update(); - } - } -} - -void CCurveEditor::OnFitCurvesVertically() -{ - if (m_pContent) - { - bool bAnyKeyFound = false; - float valueMin = std::numeric_limits::max(); - float valueMax = -std::numeric_limits::max(); - - TCurveEditorCurves& curves = m_pContent->m_curves; - for (auto curveIter = curves.begin(); curveIter != curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - - if (m_curveType == eCECT_Bezier && curve.m_keys.size() > 0 && !curve.m_customInterpolator) - { - const auto endIter = curve.m_keys.end() - 1; - - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - bAnyKeyFound = true; - - const SCurveEditorKey* pKeyLeftOfSegment = (iter != curve.m_keys.begin()) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pKeyRightOfSegment = (iter != (curve.m_keys.end() - 2)) ? &*(iter + 2) : nullptr; - - const SCurveEditorKey segmentStartKey = ApplyOutTangentFlags(*iter, pKeyLeftOfSegment, *(iter + 1)); - const SCurveEditorKey segmentEndKey = ApplyInTangentFlags(*(iter + 1), *iter, pKeyRightOfSegment); - - const Range valueRange = GetBezierSegmentValueRange(segmentStartKey, segmentEndKey); - valueMin = std::min(valueMin, valueRange.start); - valueMax = std::max(valueMax, valueRange.end); - } - } - } - - if (bAnyKeyFound) - { - ZoomToValueRange(valueMin, valueMax); - - // Adjust zoom and translation depending on kFitMargin - const float pivot = (0.5f - m_translation.y) / m_zoom.y; - m_zoom.y /= 1.0f + 2.0f * (kFitMargin / GetCurveArea().height()); - m_translation.y += ((0.5f - m_translation.y) / m_zoom.y - pivot) * m_zoom.y; - - update(); - } - } -} - -void CCurveEditor::SetSelectedKeysTangentType(const ETangent tangent, const SCurveEditorKey::ETangentType type) -{ - if (m_pContent) - { - ForEachKey(*m_pContent, [&]([[maybe_unused]] SCurveEditorCurve& curve, SCurveEditorKey& key) - { - if (key.m_bSelected) - { - if (tangent == ETangent_In) - { - key.m_inTangentType = type; - } - else - { - key.m_outTangentType = type; - } - } - }); - - UpdateTangents(); - - update(); - - SignalContentChanged(); - } -} - -void CCurveEditor::SmoothSelectedKeys() -{ - if (m_pContent) - { - for (SCurveEditorCurve& curve : m_pContent->m_curves) - { - for (int keyIx = 0; keyIx < curve.m_keys.size(); ++keyIx) - { - SCurveEditorKey& key = curve.m_keys[keyIx]; - if (key.m_bSelected) - { - SCurveEditorKey* pLeftKey = (keyIx > 0) ? &curve.m_keys[keyIx - 1] : nullptr; - SCurveEditorKey* pRightKey = (keyIx + 1 < curve.m_keys.size()) ? &curve.m_keys[keyIx + 1] : nullptr; - SmoothTangents(key, key.m_inTangent, key.m_outTangent, pLeftKey, pRightKey, false); - } - } - } - - UpdateTangents(); - - update(); - } -} - -void CCurveEditor::UpdateTangents() -{ - for (SCurveEditorCurve& curve : m_pContent->m_curves) - { - for (int keyIx = 0; keyIx < curve.m_keys.size(); ++keyIx) - { - SCurveEditorKey& key = curve.m_keys[keyIx]; - - if (key.m_bAdded) - { - if (curve.m_keys.size() == 1) - { - return; - } - if (keyIx == 0) - { - SCurveEditorKey& nextKey = curve.m_keys[keyIx + 1]; - key.m_outTangent = Vec2(nextKey.m_time - key.m_time, nextKey.m_value - key.m_value) / 3.0f; - key.m_inTangent = -key.m_outTangent; - } - else if (keyIx + 1 == curve.m_keys.size()) - { - SCurveEditorKey& prevKey = curve.m_keys[keyIx - 1]; - key.m_inTangent = Vec2(prevKey.m_time - key.m_time, prevKey.m_value - key.m_value) / 3.0f; - key.m_outTangent = -key.m_outTangent; - } - key.m_bAdded = false; - } - if (keyIx > 0) - { - SCurveEditorKey& prevKey = curve.m_keys[keyIx - 1]; - - switch (key.m_inTangentType) - { - case SCurveEditorKey::eTangentType_Smooth: - { - if (keyIx + 1 >= curve.m_keys.size()) - { - key.m_inTangent = Vec2(prevKey.m_time - key.m_time, prevKey.m_value - key.m_value) / 3.0f; - break; - } - SCurveEditorKey& nextKey = curve.m_keys[keyIx + 1]; - const float deltaTime = nextKey.m_time - prevKey.m_time; - if (deltaTime > 0.0f) - { - Vec2 normalizedIn = Vec2(prevKey.m_time - key.m_time, prevKey.m_value - key.m_value); - Vec2 normalizedOut = Vec2(nextKey.m_time - key.m_time, nextKey.m_value - key.m_value); - - key.m_inTangent = GetSmoothInTangent(key, normalizedIn, normalizedOut, &prevKey, &nextKey, true); - } - break; - } - case SCurveEditorKey::eTangentType_Flat: - { - key.m_inTangent = Vec2(prevKey.m_time - key.m_time, 0.0f) / 3.0f; - break; - } - case SCurveEditorKey::eTangentType_Step: - { - //key.m_inTangent = Vec2(0.0f, 0.0f); - break; - } - case SCurveEditorKey::eTangentType_Linear: - { - key.m_inTangent = Vec2(prevKey.m_time - key.m_time, prevKey.m_value - key.m_value) / 3.0f; - break; - } - default: - { - const float oneThirdDeltaTime = (key.m_time - prevKey.m_time) / 3.0f; - float ratio = oneThirdDeltaTime / -key.m_inTangent.x; - key.m_inTangent *= ratio; - break; - } - } - } - if (keyIx + 1 < curve.m_keys.size()) - { - SCurveEditorKey& nextKey = curve.m_keys[keyIx + 1]; - - switch (key.m_outTangentType) - { - case SCurveEditorKey::eTangentType_Smooth: - { - if (keyIx <= 0) - { - key.m_outTangent = Vec2(nextKey.m_time - key.m_time, nextKey.m_value - key.m_value) / 3.0f; - } - if (keyIx > 0) - { - SCurveEditorKey& prevKey = curve.m_keys[keyIx - 1]; - const float deltaTime = nextKey.m_time - prevKey.m_time; - if (deltaTime > 0.0f) - { - Vec2 normalizedIn = Vec2(prevKey.m_time - key.m_time, prevKey.m_value - key.m_value); - Vec2 normalizedOut = Vec2(nextKey.m_time - key.m_time, nextKey.m_value - key.m_value); - - key.m_outTangent = GetSmoothOutTangent(key, normalizedIn, normalizedOut, &prevKey, &nextKey, true); - } - } - break; - } - case SCurveEditorKey::eTangentType_Flat: - { - key.m_outTangent = Vec2(nextKey.m_time - key.m_time, 0.0f) / 3.0f; - break; - } - case SCurveEditorKey::eTangentType_Step: - { - //key.m_outTangent = Vec2(0.0f, 0.0f); - break; - } - case SCurveEditorKey::eTangentType_Linear: - { - key.m_outTangent = Vec2(nextKey.m_time - key.m_time, nextKey.m_value - key.m_value) / 3.0f; - break; - } - default: - { - const float oneThirdDeltaTime = (nextKey.m_time - key.m_time) / 3.0f; - float ratio = oneThirdDeltaTime / key.m_outTangent.x; - key.m_outTangent *= ratio; - break; - } - } - } - } - } -} - -QRect CCurveEditor::GetCurveArea() -{ - const uint rulerAreaHeight = m_bRulerVisible ? kRulerHeight : 0; - return QRect(0, rulerAreaHeight, width(), height() - rulerAreaHeight); -} - -Vec2 CCurveEditor::TransformToScreenCoordinates(Vec2 graphPoint) -{ - return TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), graphPoint); -} - -Vec2 CCurveEditor::TransformFromScreenCoordinates(Vec2 screenPoint) -{ - return TransformPointFromScreen(m_zoom, m_translation, GetCurveArea(), screenPoint); -} - -void CCurveEditor::SetOptOutFlags(int flags) -{ - m_optOutFlags = flags; - if (m_optOutFlags & EOptOutRuler) - { - m_bRulerVisible = false; - } -} - -void CCurveEditor::PopulateControlContextMenu(QMenu* pMenu) -{ - #define OPTOUT(BITS) ((m_optOutFlags & (BITS))) - - bool needsSeperator = false; - - pMenu->addAction("Delete selected keys", this, SLOT(OnDeleteSelectedKeys())); - pMenu->addSeparator(); - - // standard and smooth should only be available for both - flat, free, step, and linear should be available for all - const int flagsFreeStep = EOptOutFree | EOptOutStep; - if (OPTOUT(flagsFreeStep) != flagsFreeStep) - { - pMenu->addAction("Standard", this, SLOT(OnSetSelectedKeysTangentStandard())); - pMenu->addAction("Auto Smooth", this, SLOT(OnSetSelectedKeysTangentSmooth())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutFree)) - { - pMenu->addAction("Free", this, SLOT(OnSetSelectedKeysTangentFree())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutBezier)) - { - pMenu->addAction("Bezier", this, SLOT(OnSetSelectedKeysTangentBezier())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutFlat)) - { - pMenu->addAction("Flat", this, SLOT(OnSetSelectedKeysTangentFlat())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutLinear)) - { - pMenu->addAction("Linear", this, SLOT(OnSetSelectedKeysTangentLinear())); - needsSeperator = true; - } - - if (needsSeperator) - { - pMenu->addSeparator(); - } - needsSeperator = false; - - if (!OPTOUT(EOptOutBezier)) - { - pMenu->addAction("IN Tangent - Bezier", this, SLOT(OnSetSelectedKeysInTangentBezier())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutFree)) - { - pMenu->addAction("IN Tangent - Free", this, SLOT(OnSetSelectedKeysInTangentFree())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutFlat)) - { - pMenu->addAction("IN Tangent - Flat", this, SLOT(OnSetSelectedKeysInTangentFlat())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutLinear)) - { - pMenu->addAction("IN Tangent - Linear", this, SLOT(OnSetSelectedKeysInTangentLinear())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutStep)) - { - pMenu->addAction("IN Tangent - Step", this, SLOT(OnSetSelectedKeysInTangentStep())); - needsSeperator = true; - } - - if (needsSeperator) - { - pMenu->addSeparator(); - } - needsSeperator = false; - - if (!OPTOUT(EOptOutBezier)) - { - pMenu->addAction("OUT Tangent - Bezier", this, SLOT(OnSetSelectedKeysOutTangentBezier())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutFree)) - { - pMenu->addAction("OUT Tangent - Free", this, SLOT(OnSetSelectedKeysOutTangentFree())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutFlat)) - { - pMenu->addAction("OUT Tangent - Flat", this, SLOT(OnSetSelectedKeysOutTangentFlat())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutLinear)) - { - pMenu->addAction("OUT Tangent - Linear", this, SLOT(OnSetSelectedKeysOutTangentLinear())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutStep)) - { - pMenu->addAction("OUT Tangent - Step", this, SLOT(OnSetSelectedKeysOutTangentStep())); - needsSeperator = true; - } - - if (!OPTOUT(EOptOutFitCurvesContextMenuOptions)) - { - if (needsSeperator) - { - pMenu->addSeparator(); - } - needsSeperator = false; - pMenu->addAction("Fit curves horizontally", this, SLOT(OnFitCurvesHorizontally())); - pMenu->addAction("Fit curves vertically", this, SLOT(OnFitCurvesVertically())); - } -} - -void CCurveEditor::setPenColor(QColor color) -{ - if (color.isValid()) - { - m_penColor = color; - } - else if (!m_penColor.isValid()) - { - m_penColor = palette().highlight().color(); - } -} - -void CCurveEditor::updateCurveKeyShapeColor() -{ - for (CCurveEditorControl* key : m_pControlKeys) - { - QColor color = key->IsSelected() ? QColor(Qt::yellow) : QColor(Qt::white); - key->SetIconShapeColor(color); - } -} - -void CCurveEditor::SetIconShapeColor(unsigned int key, QColor color) -{ - m_pControlKeys[key]->SetIconShapeColor(color); -} - -void CCurveEditor::SetIconFillColor(unsigned int key, QColor color) -{ - m_pControlKeys[key]->SetIconFillColor(color); -} - -void CCurveEditor::SetIconImage(QString str) -{ - for (auto* key : m_pControlKeys) - { - key->SetIconImage(str); - } -} - -void CCurveEditor::SetIconShapeMask(QColor color) -{ - for (auto* key : m_pControlKeys) - { - key->SetIconShapeMask(color); - } -} - -void CCurveEditor::SetIconFillMask(QColor color) -{ - for (auto* key : m_pControlKeys) - { - key->SetIconFillMask(color); - } -} - -void CCurveEditor::SetIconToolTip(unsigned int key, QString str) -{ - m_pControlKeys[key]->SetIconToolTip(str); -} - -void CCurveEditor::SetIconSize(unsigned int key, unsigned int size) -{ - m_pControlKeys[key]->SetIconSize(size); - m_pControlKeys[key]->SetVisualSize(size); - m_pControlKeys[key]->SetClickableSize(size); -} - - diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditor.h b/Code/Sandbox/Plugins/EditorCommon/CurveEditor.h deleted file mode 100644 index 60d5608005..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditor.h +++ /dev/null @@ -1,233 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "CurveEditorContent.h" -#include -#include - -class QMenu; -class CCurveEditorControl; -class CCurveEditorTangentControl; -struct ISplineInterpolator; - -enum ETangent -{ - ETangent_In, - ETangent_Out -}; - -enum ECurveEditorCurveType -{ - eCECT_Bezier, - // 2D Bezier curves are used for better curve control, the editor - // will enforce that the resulting curve is always 1D. - eCECT_2DBezier, -}; - -namespace CurveEditorHelpers -{ - // Picks a nice color value for a curve. Wraps around after 4. - EDITOR_COMMON_API ColorB GetCurveColor(const uint n); - EDITOR_COMMON_API QColor LerpColor(const QColor& a, const QColor& b, float k); -} - -class EDITOR_COMMON_API CCurveEditor - : public QWidget -{ - Q_OBJECT -public: - enum EOptOutFlags - { - EOptOutFree = 1 << 0, - EOptOutFlat = 1 << 1, - EOptOutLinear = 1 << 2, - EOptOutStep = 1 << 3, - EOptOutBezier = 1 << 4, - EOptOutSelectionKey = 1 << 5, - EOptOutSelectionInOutTangent = 1 << 6, - //steven@conffx added some optout options to allow easier graphical customization - EOptOutKeyIcon = 1 << 7, - EOptOutRuler = 1 << 8, - EOptOutTimeSlider = 1 << 9, - EOptOutBackground = 1 << 10, - EOptOutCustomPenColor = 1 << 11, - EOptOutControls = 1 << 12, - eOptOutDashedPath = 1 << 13, - EOptOutDefaultTooltip = 1 << 14, - EOptOutFitCurvesContextMenuOptions = 1 << 15, - EOptOutZoomingAndPanning = 1 << 16 - }; - - CCurveEditor(QWidget* parent); - ~CCurveEditor(); - - void SetContent(SCurveEditorContent* pContent); - SCurveEditorContent* Content() const { return m_pContent; } - - void SetTime(const float time); - - // The background in the time and value range will be drawn a bit brighter to indicate where keys - // should be placed. The curve editor does not enforce that the curves actually stay in those ranges. - void SetTimeRange(const float start, const float end); - void SetValueRange(const float min, const float max); - - // Points cannot be added outside of the time range and the view will not move horizontally...zooming will only be done on the vertical axis - void EnforceTimeRange(const float start, const float end); - bool IsTimeRangeEnforced() const; - - void ZoomToTimeRange(const float start, const float end); - void ZoomToValueRange(const float min, const float max); - - void SetCurveType(ECurveEditorCurveType curveType); - void SetWeighted(bool bWeighted); - void SetHandlesVisible(bool bVisible); - void SetRulerVisible(bool bVisible); - void SetTimeSliderVisible(bool bVisible); - - Vec2 TransformToScreenCoordinates(Vec2 graphPoint); - Vec2 TransformFromScreenCoordinates(Vec2 screenPoint); - - // Removes parts of the popup-menu, use CCurveEditor::EMenuOptOutFlags - void SetOptOutFlags(int flags); - - // Tools added to tool bar depend on options above - void PopulateControlContextMenu(QMenu* pToolBar); - - virtual void paintEvent(QPaintEvent* pEvent) override; - void mousePressEvent(QMouseEvent* pEvent) override; - void mouseDoubleClickEvent(QMouseEvent* pEvent) override; - void mouseMoveEvent(QMouseEvent* pEvent) override; - void mouseReleaseEvent(QMouseEvent* pEvent) override; - void focusOutEvent(QFocusEvent* pEvent) override; - void wheelEvent(QWheelEvent* pEvent) override; - void keyPressEvent(QKeyEvent* pEvent) override; - - QString static TangentTypeToString(SCurveEditorKey::ETangentType type); - - void updateCurveKeyShapeColor(); // loop through curve keys and set shape color for them - void SetIconShapeColor(unsigned int key, QColor color); - void SetIconFillColor(unsigned int key, QColor color); - void SetIconImage(QString str); - void SetIconShapeMask(QColor color); - void SetIconFillMask(QColor color); - void SetIconToolTip(unsigned int key, QString str); - void SetIconSize(unsigned int key, unsigned int size); - - void setPenColor(QColor color); - void ContentChanged(); - void SortKeys(SCurveEditorCurve& curve); - - std::pair HitDetectCurve(const QPoint point); - CCurveEditorControl* HitDetectKey(const QPoint point); - CCurveEditorTangentControl* HitDetectTangent(const QPoint point); - - CCurveEditorControl* GetSelectedCurveKey(); - QRectF GetBackgroundRect(); - - void SelectKey(CCurveEditorControl* pKeyToSelect, bool addToExistingSelection); - void SelectTangent(CCurveEditorTangentControl* pTangentToSelect); - void SelectInRect(const QRect& rect); - -signals: - void SignalContentChanged(); - void SignalScrub(); - void SignalKeyMoved(); - void SignalKeyMoveStarted(); - void SignalKeySelected(CCurveEditorControl* selectedKey); - -public slots: - void OnDeleteSelectedKeys(); - void OnSetSelectedKeysTangentStandard(); - void OnSetSelectedKeysTangentSmooth(); - void OnSetSelectedKeysTangentFree(); - void OnSetSelectedKeysTangentBezier(); - void OnSetSelectedKeysTangentFlat(); - void OnSetSelectedKeysTangentLinear(); - - void OnSetSelectedKeysInTangentFree(); - void OnSetSelectedKeysInTangentFlat(); - void OnSetSelectedKeysInTangentLinear(); - void OnSetSelectedKeysInTangentStep(); - void OnSetSelectedKeysInTangentBezier(); - - void OnSetSelectedKeysOutTangentFree(); - void OnSetSelectedKeysOutTangentFlat(); - void OnSetSelectedKeysOutTangentLinear(); - void OnSetSelectedKeysOutTangentStep(); - void OnSetSelectedKeysOutTangentBezier(); - - void OnFitCurvesHorizontally(); - void OnFitCurvesVertically(); - -protected: - struct SMouseHandler - { - virtual ~SMouseHandler() = default; - virtual void mousePressEvent([[maybe_unused]] QMouseEvent* pEvent) {} - virtual void mouseDoubleClickEvent([[maybe_unused]] QMouseEvent* pEvent) {} - virtual void mouseMoveEvent([[maybe_unused]] QMouseEvent* pEvent) {} - virtual void mouseReleaseEvent([[maybe_unused]] QMouseEvent* pEvent) {} - virtual void focusOutEvent([[maybe_unused]] QFocusEvent* pEvent) {} - virtual void paintOver([[maybe_unused]] QPainter& painter) {} - }; - struct SSelectionHandler; - struct SPanHandler; - struct SZoomHandler; - struct SMoveKeyHandler; - struct SRotateTangentHandler; - struct SScrubHandler; - QColor m_penColor; - - void LeftButtonMousePressEvent(QMouseEvent* pEvent); - void MiddleButtonMousePressEvent(QMouseEvent* pEvent); - void RightButtonMousePressEvent(QMouseEvent* pEvent); - - void DeleteMarkedKeys(); - - void SetTimeRange(const float start, const float end, bool enforce); - - Vec2 ClosestPointOnCurve(const Vec2 point, const SCurveEditorCurve& curve, const ECurveEditorCurveType curveType); - - bool AddPointToCurve(Vec2 point, SCurveEditorCurve* pCurve); - - QRect GetCurveArea(); - - void SetSelectedKeysTangentType(const ETangent tangent, const SCurveEditorKey::ETangentType type); - void SmoothSelectedKeys(); - - void UpdateTangents(); - SCurveEditorContent* m_pContent; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - std::unique_ptr m_pMouseHandler; - - ECurveEditorCurveType m_curveType; - bool m_bWeighted; - bool m_bHandlesVisible; - bool m_bRulerVisible; - bool m_bTimeSliderVisible; - - float m_time; - Vec2 m_zoom; - Vec2 m_translation; - Range m_timeRange; - bool m_timeRangeEnforced; - Range m_valueRange; - - int m_optOutFlags; -public: - QList m_pControlKeys; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent.h b/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent.h deleted file mode 100644 index 49acc62f67..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include - -#include "Serialization/Strings.h" -#include "Serialization/SmartPtr.h" -#include "Serialization/Color.h" -#include "Serialization.h" - -struct ISplineInterpolator; - -struct SCurveEditorKey -{ - SCurveEditorKey() - : m_bSelected(false) - , m_bModified(false) - , m_bAdded(false) - , m_bDeleted(false) - , m_time(0.0f) - , m_value(0.0f) - , m_inTangentType(eTangentType_Standard) - , m_outTangentType(eTangentType_Standard) - , m_inTangent(ZERO) - , m_outTangent(ZERO) - { - } - - enum ETangentType - { - eTangentType_Standard, // Tangent freely rotates but will stay in sync with its pair if its pair is also standard - eTangentType_Free, // Tangent is completely free moving (does not sync with its pair) - eTangentType_Step, // Step immediately to value of next control point in tangent direction - eTangentType_Linear, // Tangent always points to next control point - eTangentType_Bezier, // Tangent is free moving and can be justified by user - eTangentType_Smooth, // Tangent is smoothed automatically based on direction/distance to neighboring controls - eTangentType_Flat, // Tangent is flattened (y = 0) - will still sync with its pair if both are flat - }; - - void Serialize(IArchive& ar) - { - ar(m_inTangentType, "inTangentType"); - ar(m_outTangentType, "outTangentType"); - ar(m_time, "time"); - ar(m_value, "value"); - ar(m_inTangent, "inTangent"); - ar(m_outTangent, "outTangent"); - } - - bool m_bSelected : 1; - bool m_bModified : 1; - bool m_bAdded : 1; - bool m_bDeleted : 1; - - ETangentType m_inTangentType : 4; - ETangentType m_outTangentType : 4; - - float m_time; - float m_value; - - // For 1D Bezier only the Y component is used - Vec2 m_inTangent; - Vec2 m_outTangent; - - - bool operator==(const SCurveEditorKey& rhs) const - { - return (m_inTangentType == rhs.m_inTangentType - && m_outTangentType == rhs.m_outTangentType - && m_time == rhs.m_time - && m_value == rhs.m_value - && m_inTangent == rhs.m_inTangent - && m_outTangent == rhs.m_outTangent); - } - - bool operator!=(const SCurveEditorKey& rhs) const - { - return !(*this == rhs); - } -}; - -struct SCurveEditorCurve -{ - SCurveEditorCurve() - : m_bModified(false) - , m_defaultValue(0.0f) - , m_color(255, 255, 255) - , m_customInterpolator(nullptr) - {} - - void Serialize(IArchive& ar) - { - ar(m_keys, "keys"); - ar(m_defaultValue, "defaultValue"); - ar(m_color, "color"); - } - - bool m_bModified : 1; - float m_defaultValue; - ColorB m_color; - - // Setting m_customInterpolator will override spline-draw code. - // When used, its up to developer to fill and update all necessary keys. - ISplineInterpolator* m_customInterpolator; - - std::vector m_keys; - - bool operator==(const SCurveEditorCurve& rhs) const - { - if (m_defaultValue != rhs.m_defaultValue - || m_color != rhs.m_color - || m_keys.size() != rhs.m_keys.size()) - { - return false; - } - - for (int i = 0; i < m_keys.size(); i++) - { - if (m_keys[i] != rhs.m_keys[i]) - return false; - } - - return true; - } - - bool operator!=(const SCurveEditorCurve& rhs) const - { - return !(*this == rhs); - } -}; - -typedef std::vector TCurveEditorCurves; - -struct SCurveEditorContent -{ - void Serialize(IArchive& ar) - { - ar(m_curves, "curves"); - } - - TCurveEditorCurves m_curves; -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent_38.h b/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent_38.h deleted file mode 100644 index f11a135c80..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent_38.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include -#include -#include -#include - -#include "Serialization/Strings.h" -#include "Serialization/SmartPtr.h" -#include "Serialization/Color.h" -#include "Serialization.h" - -struct SCurveEditorKey -{ - SCurveEditorKey() - : m_time(0) - , m_bSelected(false) - , m_bModified(false) - , m_bAdded(false) - , m_bDeleted(false) - { - } - - void Serialize(IArchive& ar) - { - ar(m_time); - ar(m_controlPoint); - } - - SAnimTime m_time; - SBezierControlPoint m_controlPoint; - - bool m_bSelected : 1; - bool m_bModified : 1; - bool m_bAdded : 1; - bool m_bDeleted : 1; -}; - -struct SCurveEditorCurve -{ - SCurveEditorCurve() - : m_bModified(false) - , m_defaultValue(0.0f) - , m_color(255, 255, 255) - {} - - void Serialize(IArchive& ar) - { - ar(m_keys, "keys"); - ar(m_defaultValue, "defaultValue"); - ar(m_color, "color"); - } - - bool m_bModified : 1; - float m_defaultValue; - ColorB m_color; - - DynArray userSideLoad; - - std::vector m_keys; -}; - -typedef std::vector TCurveEditorCurves; - -struct SCurveEditorContent -{ - void Serialize(IArchive& ar) - { - ar(m_curves, "curves"); - } - - TCurveEditorCurves m_curves; -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent_impl.h b/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent_impl.h deleted file mode 100644 index 9d2bdd796a..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditorContent_impl.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CurveEditorContent.h" - -SERIALIZATION_ENUM_BEGIN_NESTED(SCurveEditorKey, ETangentType, "TangentType") -SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Custom, "Custom") -SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Auto, "Smooth") -SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Zero, "Zero") -SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Step, "Step") -SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Linear, "Linear") -SERIALIZATION_ENUM_END() diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditorControl.cpp b/Code/Sandbox/Plugins/EditorCommon/CurveEditorControl.cpp deleted file mode 100644 index 0b0359a0ad..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditorControl.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "EditorCommon_precompiled.h" -#include "CurveEditorControl.h" - -#include -#include -#include - -#include - -#include "CurveEditor.h" - -namespace -{ - const int kDefaultControlVisualSize = 8; - const int kDefaultControlClickableSize = 10; - const int kDefaultTangentControlVisualSize = 6; - const int kDefaultTangentControlClickableSize = 8; - const int kDefaultTangentControlDistanceFromControl = 30; - - void DrawPointRect(QPainter& painter, QPointF point, const QColor& color, int size) - { - painter.setBrush(QBrush(color)); - painter.setPen(QColor(0, 0, 0)); - float halfSize = size / 2.0f; - QPointF extents = QPointF(halfSize, halfSize); - painter.drawRect(QRectF(point - extents, point + extents)); - } -} - -CCurveEditorControl::CCurveEditorControl(CCurveEditor& curveEditor, SCurveEditorCurve& curve, SCurveEditorKey& key) - : m_CurveEditor(curveEditor) - , m_Curve(curve) - , m_Key(key) - , m_VisualSize(kDefaultControlVisualSize) - , m_ClickableSize(kDefaultControlClickableSize) - , m_pInTangent(new CCurveEditorTangentControl(*this, ETangent_In)) - , m_pOutTangent(new CCurveEditorTangentControl(*this, ETangent_Out)) - , m_filledPxr(kDefaultControlVisualSize, kDefaultControlVisualSize) - , m_shapePxr(kDefaultControlVisualSize, kDefaultControlVisualSize) - , m_icon(kDefaultControlVisualSize, kDefaultControlVisualSize) - , m_originalPxr(kDefaultControlVisualSize, kDefaultControlVisualSize) - , m_tip("") - , m_iconsize(16) -{ -} - -CCurveEditorControl::~CCurveEditorControl() -{ - delete m_pInTangent; - delete m_pOutTangent; -} - -CCurveEditor& CCurveEditorControl::GetCurveEditor() const -{ - return m_CurveEditor; -} - -SCurveEditorCurve& CCurveEditorControl::GetCurve() const -{ - return m_Curve; -} - -SCurveEditorKey& CCurveEditorControl::GetKey() const -{ - return m_Key; -} - -CCurveEditorTangentControl& CCurveEditorControl::GetInTangent() -{ - return *m_pInTangent; -} - -CCurveEditorTangentControl& CCurveEditorControl::GetOutTangent() -{ - return *m_pOutTangent; -} - -bool CCurveEditorControl::IsSelected() const -{ - return m_Key.m_bSelected; -} - -void CCurveEditorControl::SetSelected(bool selected) -{ - m_Key.m_bSelected = selected; - m_pInTangent->SetVisible(selected); - m_pOutTangent->SetVisible(selected); -} - -bool CCurveEditorControl::IsKeyMarkedForRemoval() const -{ - return m_Key.m_bDeleted; -} - -void CCurveEditorControl::MarkKeyForRemoval() -{ - m_Key.m_bDeleted = true; -} - -void CCurveEditorControl::Paint(QPainter& painter, const QPalette& palette, const bool& paintInOutTangents) -{ - const QColor pointColor = m_Key.m_bSelected ? palette.color(QPalette::Highlight) : QColor(255, 255, 255, 255); - - if (paintInOutTangents) - { - m_pInTangent->Paint(painter, palette); - m_pOutTangent->Paint(painter, palette); - } - - DrawPointRect(painter, GetScreenPosition(), pointColor, m_VisualSize); -} -void CCurveEditorControl::PaintIcon(QPainter& painter, const QPalette& palette, const bool& paintInOutTangents) -{ - if (paintInOutTangents) - { - m_pInTangent->Paint(painter, palette); - m_pOutTangent->Paint(painter, palette); - } - - QPointF pos = GetScreenPosition(); - float halfSize = m_iconsize / 2.0f; - QPointF extents = QPointF(halfSize, halfSize); - painter.drawPixmap(QRectF(GetScreenPosition() - extents, GetScreenPosition() + extents), m_icon, QRectF(0, 0, m_iconsize, m_iconsize)); -} - -bool CCurveEditorControl::IsMouseWithinControl(QPointF screenPos) const -{ - QPointF keyPosition = GetScreenPosition(); - QPointF deltaPos = screenPos - keyPosition; - - float halfClickSize = m_ClickableSize / 2.0f; - - return abs(deltaPos.x()) <= halfClickSize && abs(deltaPos.y()) <= halfClickSize; -} - -QPointF CCurveEditorControl::GetScreenPosition() const -{ - Vec2 screenPosition = m_CurveEditor.TransformToScreenCoordinates(Vec2(m_Key.m_time, m_Key.m_value)); - return QPointF(screenPosition.x, screenPosition.y); -} - -void CCurveEditorControl::BuildIcon() -{ - m_filledPxr = QPixmap(m_originalPxr.size()); - m_shapePxr = QPixmap(m_originalPxr.size()); - m_shapePxr.fill(m_shapeColor); - m_filledPxr.fill(m_fillColor); - m_shapePxr.setMask(m_originalPxr.createMaskFromColor(m_shapeMask).createMaskFromColor(m_fillMask)); - m_filledPxr.setMask(m_originalPxr.createMaskFromColor(m_fillMask, Qt::MaskOutColor)); - QPainter painter(&m_shapePxr); - painter.drawPixmap(0, 0, m_filledPxr); - m_icon = m_shapePxr.scaled(m_iconsize, m_iconsize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); -} - -void CCurveEditorControl::SetIconFillMask(QColor color) -{ - m_fillMask = color; - BuildIcon(); -} - -void CCurveEditorControl::SetIconShapeMask(QColor color) -{ - m_shapeMask = color; - BuildIcon(); -} - -void CCurveEditorControl::SetIconImage(QString str) -{ - m_originalPxr.load(str); - BuildIcon(); -} - -void CCurveEditorControl::SetIconFillColor(QColor color) -{ - m_fillColor = color; - BuildIcon(); -} - -void CCurveEditorControl::SetIconShapeColor(QColor color) -{ - m_shapeColor = color; - BuildIcon(); -} - - -CCurveEditorTangentControl::CCurveEditorTangentControl(CCurveEditorControl& control, ETangent tangentDirection) - : m_Control(control) - , m_TangentDirection(tangentDirection) - , m_Visible(false) - , m_Selected(false) - , m_VisualSize(kDefaultTangentControlVisualSize) - , m_ClickableSize(kDefaultTangentControlClickableSize) - , m_DistanceFromControl(kDefaultTangentControlDistanceFromControl) -{ -} - -CCurveEditorTangentControl::~CCurveEditorTangentControl() -{ -} - -CCurveEditorControl& CCurveEditorTangentControl::GetControl() -{ - return m_Control; -} - -ETangent CCurveEditorTangentControl::GetTangentDirection() const -{ - return m_TangentDirection; -} - -bool CCurveEditorTangentControl::IsVisible() const -{ - if (!m_Visible) - { - return false; - } - SCurveEditorKey::ETangentType tangentType; - - if (m_TangentDirection == ETangent_In) - { - tangentType = m_Control.GetKey().m_inTangentType; - } - else - { - tangentType = m_Control.GetKey().m_outTangentType; - } - - if (tangentType == SCurveEditorKey::eTangentType_Step) - { - return false; - } - - // first in - if ((*m_Control.GetCurve().m_keys.begin()).m_time == m_Control.GetKey().m_time && m_TangentDirection == ETangent_In) - { - return false; - } - - // last out - if ((*(m_Control.GetCurve().m_keys.end() - 1)).m_time == m_Control.GetKey().m_time && m_TangentDirection == ETangent_Out) - { - return false; - } - - return true; -} - -void CCurveEditorTangentControl::SetVisible(bool visible) -{ - m_Visible = visible; -} - -bool CCurveEditorTangentControl::IsSelected() const -{ - return m_Selected; -} - -void CCurveEditorTangentControl::SetSelected(bool selected) -{ - m_Selected = selected; -} - -void CCurveEditorTangentControl::SetVisualSize(int visualSize) -{ - m_VisualSize = visualSize; -} - -void CCurveEditorTangentControl::SetClickableSize(int clickableSize) -{ - m_ClickableSize = clickableSize; -} - -void CCurveEditorTangentControl::SetDistanceFromControl(int distanceFromControl) -{ - m_DistanceFromControl = distanceFromControl; -} - -void CCurveEditorTangentControl::Paint(QPainter& painter, const QPalette& palette) -{ - if (!IsVisible()) - { - return; - } - - QPointF controlPosition = m_Control.GetScreenPosition(); - QPointF tangentPosition = GetScreenPosition(); - - float highlightPercent; - if (m_Selected) - { - highlightPercent = 0.0f; - } - else - { - highlightPercent = 0.5f; - } - const QColor tangentColor = CurveEditorHelpers::LerpColor(palette.color(QPalette::Highlight), palette.color(QPalette::Window), highlightPercent); - const QPen tangentPen = QPen(tangentColor); - - painter.setPen(tangentPen); - painter.drawLine(controlPosition, tangentPosition); - - const QColor tangentControlColor = m_Selected ? palette.color(QPalette::Highlight) : palette.color(QPalette::Dark); - DrawPointRect(painter, tangentPosition, tangentControlColor, m_VisualSize); -} - -bool CCurveEditorTangentControl::IsMouseWithinControl(QPointF screenPos) const -{ - if (!IsVisible()) - { - return false; - } - - QPointF keyPosition = GetScreenPosition(); - QPointF deltaPos = screenPos - keyPosition; - - float halfClickSize = m_ClickableSize / 2.0f; - - return abs(deltaPos.x()) <= halfClickSize && abs(deltaPos.y()) <= halfClickSize; -} - -QPointF CCurveEditorTangentControl::GetScreenPosition() const -{ - QPointF controlPosition = m_Control.GetScreenPosition(); - - Vec2 tangent; - if (m_TangentDirection == ETangent_In) - { - tangent = m_Control.GetKey().m_inTangent; - } - else - { - tangent = m_Control.GetKey().m_outTangent; - } - - Vec2 tangentScreenPosition = m_Control.GetCurveEditor().TransformToScreenCoordinates(Vec2(m_Control.GetKey().m_time + tangent.x, m_Control.GetKey().m_value + tangent.y)); - Vec2 transformedTangentDelta = (tangentScreenPosition - Vec2(aznumeric_cast(controlPosition.x()), aznumeric_cast(controlPosition.y()))).Normalize() * aznumeric_cast(m_DistanceFromControl); - - return controlPosition + QPointF(transformedTangentDelta.x, transformedTangentDelta.y); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditorControl.h b/Code/Sandbox/Plugins/EditorCommon/CurveEditorControl.h deleted file mode 100644 index 5cc12cbfcf..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditorControl.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include "CurveEditor.h" - -#include - -class CCurveEditor; -class CCurveEditorTangentControl; -class QMouseEvent; - -class QPainter; - -class EDITOR_COMMON_API CCurveEditorControl -{ -public: - CCurveEditorControl(CCurveEditor& curveEditor, SCurveEditorCurve& curve, SCurveEditorKey& key); - ~CCurveEditorControl(); - - CCurveEditor& GetCurveEditor() const; - SCurveEditorCurve& GetCurve() const; - SCurveEditorKey& GetKey() const; - - CCurveEditorTangentControl& GetInTangent(); - CCurveEditorTangentControl& GetOutTangent(); - - void SetVisualSize(int visualSize) - { - m_VisualSize = visualSize; - } - void SetClickableSize(int clickableSize) - { - m_ClickableSize = clickableSize; - } - - bool IsSelected() const; - void SetSelected(bool selected); - - bool IsKeyMarkedForRemoval() const; - void MarkKeyForRemoval(); - - void Paint(QPainter& painter, const QPalette& palette, const bool& paintInOutTangents); - void PaintIcon(QPainter& painter, const QPalette& palette, const bool& paintInOutTangents); - - bool IsMouseWithinControl(QPointF screenPos) const; - - QPointF GetScreenPosition() const; - - QRect GetRect() const - { - return QRect(aznumeric_cast(GetScreenPosition().x() - (m_VisualSize / 2)), aznumeric_cast(GetScreenPosition().y() - (m_VisualSize / 2)), m_VisualSize, m_VisualSize); - } - - void SetIconShapeColor(QColor color); - - void SetIconFillColor(QColor color); - - void SetIconImage(QString str); - - void SetIconShapeMask(QColor color); - - void SetIconFillMask(QColor color); - - void SetIconToolTip(QString str) - { - m_tip = str; - } - - void SetIconSize(int size) - { - m_iconsize = size; - BuildIcon(); - } - - QString GetToolTip() const { return m_tip; } - -protected: - void BuildIcon(); - -private: - QPixmap m_icon; - QPixmap m_filledPxr; - QPixmap m_shapePxr; - QPixmap m_originalPxr; - QColor m_fillColor; - QColor m_shapeColor; - QColor m_fillMask; - QColor m_shapeMask; - QString m_tip; - int m_iconsize; - - CCurveEditor& m_CurveEditor; - SCurveEditorCurve& m_Curve; - SCurveEditorKey& m_Key; - - int m_VisualSize; - int m_ClickableSize; - - CCurveEditorTangentControl* m_pInTangent; - CCurveEditorTangentControl* m_pOutTangent; -}; - -class EDITOR_COMMON_API CCurveEditorTangentControl -{ -public: - CCurveEditorTangentControl(CCurveEditorControl& curveControl, ETangent tangentDirection); - ~CCurveEditorTangentControl(); - - CCurveEditorControl& GetControl(); - ETangent GetTangentDirection() const; - - bool IsVisible() const; - void SetVisible(bool visible); - - bool IsSelected() const; - void SetSelected(bool selected); - - void SetVisualSize(int visualSize); - void SetClickableSize(int clickableSize); - void SetDistanceFromControl(int distanceFromControl); - - void Paint(QPainter& painter, const QPalette& palette); - - bool IsMouseWithinControl(QPointF screenPos) const; - -private: - - QPointF GetScreenPosition() const; - - CCurveEditorControl& m_Control; - ETangent m_TangentDirection; - - bool m_Selected; - - int m_VisualSize; - int m_ClickableSize; - int m_DistanceFromControl; - - bool m_Visible; -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditor_38.cpp b/Code/Sandbox/Plugins/EditorCommon/CurveEditor_38.cpp deleted file mode 100644 index 60a61b930f..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditor_38.cpp +++ /dev/null @@ -1,1825 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "EditorCommon_precompiled.h" -#include "CurveEditor.h" -#include "DrawingPrimitives/TimeSlider.h" -#include "DrawingPrimitives/Ruler.h" - -#include -#include -#include -#include -#include - -#pragma warning (push) -#pragma warning (disable : 4554) - -#define INDEX_NOT_OUT_OF_RANGE PREFAST_SUPPRESS_WARNING(6201) -#define NO_BUFFER_OVERRUN PREFAST_SUPPRESS_WARNING(6385 6386) -#include "Cry_LegacyPhysUtils.h" - -#pragma warning (pop) - -namespace CurveEditorHelpers -{ - const uint numColors = 4; - ColorB colors[numColors] = - { - ColorB(243, 126, 121), - ColorB(121, 152, 243), - ColorB(187, 243, 121), - ColorB(243, 121, 223), - }; - - ColorB GetCurveColor(const uint n) - { - return colors[n % numColors]; - } - - QColor Interpolate(const QColor& a, const QColor& b, float k) - { - float mk = 1.0f - k; - return QColor(a.red() * mk + b.red() * k, - a.green() * mk + b.green() * k, - a.blue() * mk + b.blue() * k, - a.alpha() * mk + b.alpha() * k); - } -} - -namespace -{ - using namespace LegacyCryPhysicsUtils; - - const int kRulerHeight = 16; - const int kRulerShadowHeight = 6; - const int kRulerMarkHeight = 8; - const float kHitDistance = 5.0f; - const float kMinZoom = 0.00001f; - const float kMaxZoom = 1000.0f; - const float kFitMargin = 30.0f; - - const QPointF kPointRectExtent = QPointF(2.5f, 2.5f); - - Vec2 TransformPointToScreen(const Vec2 zoom, const Vec2 translation, QRect curveArea, Vec2 point) - { - Vec2 transformedPoint = Vec2(point.x * zoom.x, point.y * -zoom.y) + translation; - transformedPoint.x *= curveArea.width(); - transformedPoint.y *= curveArea.height(); - return Vec2(transformedPoint.x + curveArea.left(), transformedPoint.y + curveArea.top()); - } - - Vec2 TransformPointFromScreen(const Vec2 zoom, const Vec2 translation, QRect curveArea, Vec2 point) - { - Vec2 transformedPoint = Vec2((point.x - curveArea.left()) / curveArea.width(), (point.y - curveArea.top()) / curveArea.height()) - translation; - transformedPoint.x /= zoom.x; - transformedPoint.y /= -zoom.y; - return Vec2(transformedPoint.x, transformedPoint.y); - } - - QPointF Vec2ToPoint(Vec2 point) - { - return QPointF(point.x, point.y); - } - - Vec2 PointToVec2(QPointF point) - { - return Vec2(point.x(), point.y()); - } - - // This function returns a new key with position and weights affected by eTangentType_Smooth, eTangentType_Linear and eTangentType_Step for the incoming tangent - SCurveEditorKey ApplyInTangentFlags(const SCurveEditorKey& key, const SCurveEditorKey& leftKey, const SCurveEditorKey* pRightKey) - { - SCurveEditorKey newKey = key; - - if (leftKey.m_controlPoint.m_outTangentType == SBezierControlPoint::eTangentType_Step) - { - newKey.m_controlPoint.m_inTangent = Vec2(0.0f, 0.0f); - return newKey; - } - else if (key.m_controlPoint.m_inTangentType != SBezierControlPoint::eTangentType_Step) - { - const SAnimTime leftTime = leftKey.m_time; - const SAnimTime rightTime = pRightKey ? pRightKey->m_time : key.m_time; - - // Rebase to [0, rightTime - leftTime] to increase float precision - const float floatTime = (key.m_time - leftTime).ToFloat(); - const float floatLeftTime = 0.0f; - const float floatRightTime = (rightTime - leftTime).ToFloat(); - - newKey.m_controlPoint = Bezier::CalculateInTangent(floatTime, key.m_controlPoint, - floatLeftTime, &leftKey.m_controlPoint, - floatRightTime, pRightKey ? &pRightKey->m_controlPoint : nullptr); - } - else - { - newKey.m_controlPoint.m_inTangent = Vec2(0.0f, 0.0f); - newKey.m_controlPoint.m_value = leftKey.m_controlPoint.m_value; - } - - return newKey; - } - - // This function returns a new key with position and weights affected by eTangentType_Smooth, eTangentType_Linear and eTangentType_Step for the outgoing tangent - SCurveEditorKey ApplyOutTangentFlags(const SCurveEditorKey& key, const SCurveEditorKey* pLeftKey, const SCurveEditorKey& rightKey) - { - SCurveEditorKey newKey = key; - - if (rightKey.m_controlPoint.m_inTangentType == SBezierControlPoint::eTangentType_Step - && key.m_controlPoint.m_outTangentType != SBezierControlPoint::eTangentType_Step) - { - newKey.m_controlPoint.m_outTangent = Vec2(0.0f, 0.0f); - } - else if (key.m_controlPoint.m_outTangentType != SBezierControlPoint::eTangentType_Step) - { - const SAnimTime leftTime = pLeftKey ? pLeftKey->m_time : key.m_time; - const SAnimTime rightTime = rightKey.m_time; - - // Rebase to [0, rightTime - leftTime] to increase float precision - const float floatTime = (key.m_time - leftTime).ToFloat(); - const float floatLeftTime = 0.0f; - const float floatRightTime = (rightTime - leftTime).ToFloat(); - - newKey.m_controlPoint = Bezier::CalculateOutTangent(floatTime, key.m_controlPoint, - floatLeftTime, pLeftKey ? &pLeftKey->m_controlPoint : nullptr, - floatRightTime, &rightKey.m_controlPoint); - } - else - { - newKey.m_controlPoint.m_outTangent = Vec2(0.0f, 0.0f); - newKey.m_controlPoint.m_value = rightKey.m_controlPoint.m_value; - } - - return newKey; - } - - QPainterPath CreatePathFromCurve(const SCurveEditorCurve& curve, ECurveEditorCurveType curveType, AZStd::function transformFunc) - { - QPainterPath path; - - const Vec2 startPoint(curve.m_keys[0].m_time.ToFloat(), curve.m_keys[0].m_controlPoint.m_value); - const Vec2 startTransformed = transformFunc(startPoint); - path.moveTo(startTransformed.x, startTransformed.y); - - const auto endIter = curve.m_keys.end() - 1; - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - const SCurveEditorKey* pKeyLeftOfSegment = (iter != curve.m_keys.begin()) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pKeyRightOfSegment = (iter != (curve.m_keys.end() - 2)) ? &*(iter + 2) : nullptr; - - const SCurveEditorKey segmentStartKey = ApplyOutTangentFlags(*iter, pKeyLeftOfSegment, *(iter + 1)); - const SCurveEditorKey segmentEndKey = ApplyInTangentFlags(*(iter + 1), *iter, pKeyRightOfSegment); - - const Vec2 p0 = Vec2(segmentStartKey.m_time.ToFloat(), segmentStartKey.m_controlPoint.m_value); - const Vec2 p3 = Vec2(segmentEndKey.m_time.ToFloat(), segmentEndKey.m_controlPoint.m_value); - - Vec2 p1, p2; - if (curveType == eCECT_Bezier) - { - // Need to compute tangents for x so that the cubic 2D Bezier does a linear interpolation in - // that dimension, because we actually want to draw a cubic 1D Bezier curve - const float outTangentX = (2.0f * p0.x + p3.x) / 3.0f; // p1 = (2 * p0 + p3) / 3 - const float inTangentX = (p0.x + 2.0f * p3.x) / 3.0f; // p2 = (p0 + 2 * p3) / 3 - - p1 = Vec2(outTangentX, p0.y + segmentStartKey.m_controlPoint.m_outTangent.y); - p2 = Vec2(inTangentX, p3.y + segmentEndKey.m_controlPoint.m_inTangent.y); - } - else if (curveType == eCECT_2DBezier) - { - p1 = p0 + segmentStartKey.m_controlPoint.m_outTangent; - p2 = p3 + segmentEndKey.m_controlPoint.m_inTangent; - } - - const QPointF p0Transformed = Vec2ToPoint(transformFunc(p0)); - const QPointF p1Transformed = Vec2ToPoint(transformFunc(p1)); - const QPointF p2Transformed = Vec2ToPoint(transformFunc(p2)); - const QPointF p3Transformed = Vec2ToPoint(transformFunc(p3)); - path.moveTo(p0Transformed); - path.cubicTo(p1Transformed, p2Transformed, p3Transformed); - } - - return path; - } - - QPainterPath CreateExtrapolatedPathFromCurve(const SCurveEditorCurve& curve, AZStd::function transformFunc, float windowWidth) - { - QPainterPath path; - - if (curve.m_keys.size() > 0) - { - const Vec2 startPoint = Vec2(curve.m_keys[0].m_time.ToFloat(), curve.m_keys[0].m_controlPoint.m_value); - const Vec2 startTransformed = transformFunc(startPoint); - if (startTransformed.x > 0.0f) - { - path.moveTo(std::min(startTransformed.x, windowWidth), startTransformed.y); - path.lineTo(0.0f, startTransformed.y); - } - - const Vec2 endPoint(curve.m_keys.back().m_time.ToFloat(), curve.m_keys.back().m_controlPoint.m_value); - const Vec2 endTransformed = transformFunc(endPoint); - if (endTransformed.x < windowWidth) - { - path.moveTo(std::max(endTransformed.x, 0.0f), endTransformed.y); - path.lineTo(windowWidth, endTransformed.y); - } - } - else - { - const Vec2 pointOnCurve = Vec2(0.0f, curve.m_defaultValue); - const Vec2 pointOnTransformed = transformFunc(pointOnCurve); - path.moveTo(0.0, pointOnTransformed.y); - path.lineTo(windowWidth, pointOnTransformed.y); - } - - QVector dashPattern; - dashPattern << 16 << 8; - - QPainterPathStroker stroker; - stroker.setCapStyle(Qt::RoundCap); - stroker.setDashPattern(dashPattern); - stroker.setWidth(0.5); - - return stroker.createStroke(path); - } - - QPainterPath CreateDiscontinuityPathFromCurve(const SCurveEditorCurve& curve, ECurveEditorCurveType curveType, AZStd::function transformFunc) - { - QPainterPath path; - - if (curve.m_keys.size() > 0) - { - const auto endIter = curve.m_keys.end() - 1; - - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - const SCurveEditorKey* pKeyLeftOfSegment = (iter != curve.m_keys.begin()) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pKeyRightOfSegment = (iter != (curve.m_keys.end() - 2)) ? &*(iter + 2) : nullptr; - - const SCurveEditorKey segmentStartKey = ApplyOutTangentFlags(*iter, pKeyLeftOfSegment, *(iter + 1)); - const SCurveEditorKey segmentEndKey = ApplyInTangentFlags(*(iter + 1), *iter, pKeyRightOfSegment); - - if (segmentStartKey.m_controlPoint.m_value != iter->m_controlPoint.m_value) - { - const Vec2 start = Vec2(segmentStartKey.m_time.ToFloat(), segmentStartKey.m_controlPoint.m_value); - const Vec2 end = Vec2(iter->m_time.ToFloat(), iter->m_controlPoint.m_value); - - const QPointF startTransformed = Vec2ToPoint(transformFunc(start)); - const QPointF endTransformed = Vec2ToPoint(transformFunc(end)); - - path.moveTo(startTransformed); - path.lineTo(endTransformed); - } - - if (segmentEndKey.m_controlPoint.m_value != (iter + 1)->m_controlPoint.m_value) - { - const Vec2 start = Vec2(segmentEndKey.m_time.ToFloat(), segmentEndKey.m_controlPoint.m_value); - const Vec2 end = Vec2((iter + 1)->m_time.ToFloat(), (iter + 1)->m_controlPoint.m_value); - - const QPointF startTransformed = Vec2ToPoint(transformFunc(start)); - const QPointF endTransformed = Vec2ToPoint(transformFunc(end)); - - path.moveTo(startTransformed); - path.lineTo(endTransformed); - } - } - } - - QVector dashPattern; - dashPattern << 2 << 10; - - QPainterPathStroker stroker; - stroker.setCapStyle(Qt::RoundCap); - stroker.setDashPattern(dashPattern); - stroker.setWidth(0.5); - - return stroker.createStroke(path); - } - - void DrawPointRect(QPainter& painter, QPointF point, const QColor& color) - { - painter.setBrush(QBrush(color)); - painter.setPen(QColor(0, 0, 0)); - painter.drawRect(QRectF(point - kPointRectExtent, point + kPointRectExtent)); - } - - void DrawKeys(QPainter& painter, const QPalette& palette, const SCurveEditorCurve& curve, ECurveEditorCurveType curveType, AZStd::function transformFunc, const bool bDrawHandles) - { - const QColor tangentColor = CurveEditorHelpers::Interpolate(QColor(), QColor(curve.m_color.r, curve.m_color.g, curve.m_color.b, curve.m_color.a), 0.3f); - const QPen tangentPen = QPen(tangentColor, 2.5); - - for (auto iter = curve.m_keys.begin(); iter != curve.m_keys.end(); ++iter) - { - SCurveEditorKey key = *iter; - - const Vec2 keyPoint = Vec2(key.m_time.ToFloat(), key.m_controlPoint.m_value); - const QPointF transformedKeyPoint = Vec2ToPoint(transformFunc(keyPoint)); - - const bool bIsFirstKey = (iter == curve.m_keys.begin()); - const bool bIsLastKey = (iter == (curve.m_keys.end() - 1)); - const SCurveEditorKey* pLeftKey = (!bIsFirstKey) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pRightKey = (!bIsLastKey) ? &*(iter + 1) : nullptr; - key = pRightKey ? ApplyOutTangentFlags(key, pLeftKey, *pRightKey) : key; - key = pLeftKey ? ApplyInTangentFlags(key, *pLeftKey, pRightKey) : key; - - // For 1D Bezier, we need to ignore the X component - const Vec2 inTangent = (curveType == eCECT_Bezier) ? Vec2(0.0f, key.m_controlPoint.m_inTangent.y) : key.m_controlPoint.m_inTangent; - const Vec2 outTangent = (curveType == eCECT_Bezier) ? Vec2(0.0f, key.m_controlPoint.m_outTangent.y) : key.m_controlPoint.m_outTangent; - - if (key.m_bSelected && (key.m_controlPoint.m_inTangentType != SBezierControlPoint::eTangentType_Step) && !bIsFirstKey && bDrawHandles) - { - // Draw incoming tangent - const Vec2 tangentHandlePoint = keyPoint + inTangent; - const QPointF transformedTangentHandlePoint = Vec2ToPoint(transformFunc(tangentHandlePoint)); - painter.setPen(tangentPen); - painter.drawLine(transformedKeyPoint, transformedTangentHandlePoint); - DrawPointRect(painter, transformedTangentHandlePoint, palette.color(QPalette::Dark)); - } - - if (key.m_bSelected && (key.m_controlPoint.m_outTangentType != SBezierControlPoint::eTangentType_Step) && !bIsLastKey && bDrawHandles) - { - // Draw outgoing tangent - const Vec2 tangentHandlePoint = keyPoint + outTangent; - const QPointF transformedTangentHandlePoint = Vec2ToPoint(transformFunc(tangentHandlePoint)); - painter.setPen(tangentPen); - painter.drawLine(transformedKeyPoint, transformedTangentHandlePoint); - DrawPointRect(painter, transformedTangentHandlePoint, palette.color(QPalette::Dark)); - } - - const QColor pointColor = key.m_bSelected ? palette.color(QPalette::Highlight) : palette.color(QPalette::Dark); - DrawPointRect(painter, transformedKeyPoint, pointColor); - } - } - - void ForEachKey(SCurveEditorContent& content, AZStd::function fun) - { - for (auto iter = content.m_curves.begin(); iter != content.m_curves.end(); ++iter) - { - SCurveEditorCurve& curve = *iter; - for (size_t i = 0; i < curve.m_keys.size(); ++i) - { - fun(curve, curve.m_keys[i]); - } - } - } - -#pragma warning (push) -#pragma warning (disable : 4554) - - Vec2 ClosestPointOnBezierSegment(const Vec2 point, const float t0, const float t1, const float p0, const float p1, const float p2, const float p3) - { - // If values are too close the distance function is too flat to be useful. We just assume the curve is flat then - if ((p0 * p0 + p1 * p1 + p2 * p2 + p3 * p3) < 1e-10f) - { - return Vec2(point.x, p0); - } - - const float deltaTime = (t1 - t0); - const float deltaTimeSq = deltaTime * deltaTime; - - // Those are just the normal cubic Bezier formulas B(t) and B'(t) in collected polynomial form - const P3f cubicBezierPoly = P3f(-p0 + 3.0f * p1 - 3.0f * p2 + p3) + P2f(3.0f * p0 - 6.0f * p1 + 3.0f * p2) + P1f(3.0f * p1 - 3.0f * p0) + p0; - const P2f cubicBezierDerivativePoly = P2f(-3.0f * p0 + 9.0f * p1 - 6.0f * p2 + 3.0f * (p3 - p2)) + P1f(6.0f * p0 - 12.0f * p1 + 6.0f * p2) - 3.0f * p0 + 3.0f * p1; - - // lerp(t, t0, t1) in polynomial form - const P1f timePoly = P1f(deltaTime) + t0; - - // Derivative of the distance function (cubicBezierPoly - point.y) ^ 2 + (timePoly - point.x) ^ 2 - const auto distanceDerivativePoly = (cubicBezierDerivativePoly * (cubicBezierPoly - point.y) + (timePoly - point.x) * deltaTime) * 2.0f; - - // The point of minimum distance must be at one of the roots of the distance derivative or at the start/end of the segment - float checkPoints[7]; - const uint numRoots = distanceDerivativePoly.findroots(0.0f, 1.0f, checkPoints + 2); - - // Start and end of segment - checkPoints[0] = 0.0f; - checkPoints[1] = 1.0f; - - // Find the closest point among all the candidates - Vec2 closestPoint; - float minDistanceSq = std::numeric_limits::max(); - for (uint i = 0; i < numRoots + 2; ++i) - { - const Vec2 rootPoint(Lerp(t0, t1, checkPoints[i]), Bezier::Evaluate(checkPoints[i], p0, p1, p2, p3)); - const float deltaX = rootPoint.x - point.x; - const float deltaY = rootPoint.y - point.y; - const float distSq = deltaX * deltaX + deltaY * deltaY; - if (distSq < minDistanceSq) - { - closestPoint = rootPoint; - minDistanceSq = distSq; - } - } - - return closestPoint; - } - - Vec2 ClosestPointOn2DBezierSegment(const Vec2 point, const Vec2 p0, const Vec2 p1, const Vec2 p2, const Vec2 p3) - { - // If values are too close the distance function is too flat to be useful. We just assume the curve is flat then - if ((p0.y * p0.y + p1.y * p1.y + p2.y * p2.y + p3.y * p3.y) < 1e-10f) - { - return Vec2(point.x, p0.y); - } - - // Those are just the normal cubic Bezier formulas B(t) and B'(t) in collected polynomial form - const P3f xCubicBezierPoly = P3f(-p0.x + 3.0f * p1.x - 3.0f * p2.x + p3.x) + P2f(3.0f * p0.x - 6.0f * p1.x + 3.0f * p2.x) + P1f(3.0f * p1.x - 3.0f * p0.x) + p0.x; - const P2f xCubicBezierDerivativePoly = P2f(-3.0f * p0.x + 9.0f * p1.x - 6.0f * p2.x + 3.0f * (p3.x - p2.x)) + P1f(6.0f * p0.x - 12.0f * p1.x + 6.0f * p2.x) - 3.0f * p0.x + 3.0f * p1.x; - const P3f yCubicBezierPoly = P3f(-p0.y + 3.0f * p1.y - 3.0f * p2.y + p3.y) + P2f(3.0f * p0.y - 6.0f * p1.y + 3.0f * p2.y) + P1f(3.0f * p1.y - 3.0f * p0.y) + p0.y; - const P2f yCubicBezierDerivativePoly = P2f(-3.0f * p0.y + 9.0f * p1.y - 6.0f * p2.y + 3.0f * (p3.y - p2.y)) + P1f(6.0f * p0.y - 12.0f * p1.y + 6.0f * p2.y) - 3.0f * p0.y + 3.0f * p1.y; - - // Derivative of the distance function (yCubicBezierPoly - point.y) ^ 2 + (xCubicBezierPoly - point.x) ^ 2 - const auto distanceDerivativePoly = yCubicBezierDerivativePoly * (yCubicBezierPoly - point.y) + xCubicBezierDerivativePoly * (xCubicBezierPoly - point.x); - - // The point of minimum distance must be at one of the roots of the distance derivative or at the start/end of the segment - float checkPoints[7]; - const uint numRoots = distanceDerivativePoly.findroots(0.0f, 1.0f, checkPoints + 2); - - // Start and end of segment - checkPoints[0] = 0.0f; - checkPoints[1] = 1.0f; - - // Find the closest point among all the candidates - Vec2 closestPoint; - float minDistanceSq = std::numeric_limits::max(); - for (uint i = 0; i < numRoots + 2; ++i) - { - const Vec2 rootPoint(Bezier::Evaluate(checkPoints[i], p0.x, p1.x, p2.x, p3.x), Bezier::Evaluate(checkPoints[i], p0.y, p1.y, p2.y, p3.y)); - const float deltaX = rootPoint.x - point.x; - const float deltaY = rootPoint.y - point.y; - const float distSq = deltaX * deltaX + deltaY * deltaY; - if (distSq < minDistanceSq) - { - closestPoint = rootPoint; - minDistanceSq = distSq; - } - } - - return closestPoint; - } - - // This works for 1D and 2D bezier because the y range of values is not affected by the x bezier in the 2D case. - Range GetBezierSegmentValueRange(const SCurveEditorKey& startKey, const SCurveEditorKey& endKey) - { - const float p0 = startKey.m_controlPoint.m_value; - const float p1 = p0 + startKey.m_controlPoint.m_outTangent.y; - const float p3 = endKey.m_controlPoint.m_value; - const float p2 = p3 + endKey.m_controlPoint.m_inTangent.y; - - Range valueRange(std::min(p0, p3), std::max(p0, p3)); - - const P2f cubicBezierDerivativePoly = P2f(-3.0f * p0 + 9.0f * p1 - 6.0f * p2 + 3.0f * (p3 - p2)) + P1f(6.0f * p0 - 12.0f * p1 + 6.0f * p2) - 3.0f * p0 + 3.0f * p1; - - float roots[2]; - const uint numRoots = cubicBezierDerivativePoly.findroots(0.0f, 1.0f, roots); - for (uint i = 0; i < numRoots; ++i) - { - const float rootValue = Bezier::Evaluate(roots[i], p0, p1, p2, p3); - valueRange.start = std::min(valueRange.start, rootValue); - valueRange.end = std::max(valueRange.end, rootValue); - } - - return valueRange; - } -} - -#pragma warning (pop) - -struct CCurveEditor::SMouseHandler -{ - virtual ~SMouseHandler() = default; - virtual void mousePressEvent(QMouseEvent* pEvent) {} - virtual void mouseDoubleClickEvent(QMouseEvent* pEvent) {} - virtual void mouseMoveEvent(QMouseEvent* pEvent) {} - virtual void mouseReleaseEvent(QMouseEvent* pEvent) {} - virtual void focusOutEvent(QFocusEvent* pEvent) {} - virtual void paintOver(QPainter& painter) {} -}; - -struct CCurveEditor::SSelectionHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - QPoint m_startPoint; - QRect m_rect; - bool m_bAdd; - - SSelectionHandler(CCurveEditor* pCurveEditor, bool bAdd) - : m_pCurveEditor(pCurveEditor) - , m_bAdd(bAdd) {} - - void mousePressEvent(QMouseEvent* pEvent) override - { - m_startPoint = pEvent->pos(); - m_rect = QRect(m_startPoint, m_startPoint + QPoint(1, 1)); - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - m_rect = QRect(m_startPoint, pEvent->pos() + QPoint(1, 1)); - } - - void mouseReleaseEvent(QMouseEvent* pEvent) override - { - m_pCurveEditor->SelectInRect(m_rect); - } - - void paintOver(QPainter& painter) override - { - painter.save(); - QColor highlightColor = m_pCurveEditor->palette().color(QPalette::Highlight); - QColor highlightColorA = QColor(highlightColor.red(), highlightColor.green(), highlightColor.blue(), 128); - painter.setPen(QPen(highlightColor)); - painter.setBrush(QBrush(highlightColorA)); - painter.drawRect(QRectF(m_rect)); - painter.restore(); - } -}; - -struct CCurveEditor::SPanHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - QPoint m_startPoint; - Vec2 m_startTranslation; - - SPanHandler(CCurveEditor* pCurveEditor) - : m_pCurveEditor(pCurveEditor) - { - } - - void mousePressEvent(QMouseEvent* pEvent) override - { - m_startPoint = QPoint(int(pEvent->x()), int(pEvent->y())); - m_startTranslation = m_pCurveEditor->m_translation; - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - const Vec2 windowSize((float)m_pCurveEditor->size().width(), (float)m_pCurveEditor->size().height()); - - const int pixelDeltaX = pEvent->x() - m_startPoint.x(); - const int pixelDeltaY = pEvent->y() - m_startPoint.y(); - - const float deltaX = float(pixelDeltaX) / (windowSize.x); - const float deltaY = float(pixelDeltaY) / (windowSize.y); - - const Vec2 delta(deltaX, deltaY); - m_pCurveEditor->m_translation = m_startTranslation + delta; - m_pCurveEditor->update(); - } -}; - -struct CCurveEditor::SZoomHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - Vec2 m_pivot; - QPoint m_lastPoint; - - SZoomHandler(CCurveEditor* pCurveEditor) - : m_pCurveEditor(pCurveEditor) - { - } - - void mousePressEvent(QMouseEvent* pEvent) override - { - m_lastPoint = QPoint(int(pEvent->x()), int(pEvent->y())); - - const QRect curveArea = m_pCurveEditor->GetCurveArea(); - const float pivotXNormalized = (float)(m_lastPoint.x() - curveArea.left()) / (float)curveArea.width(); - const float pivotYNormalized = (float)(m_lastPoint.y() - curveArea.top()) / (float)curveArea.height(); - m_pivot = Vec2(pivotXNormalized, pivotYNormalized); - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - const Vec2 windowSize((float)m_pCurveEditor->size().width(), (float)m_pCurveEditor->size().height()); - - const int pixelDeltaX = pEvent->x() - m_lastPoint.x(); - const int pixelDeltaY = -(pEvent->y() - m_lastPoint.y()); - m_lastPoint = QPoint(int(pEvent->x()), int(pEvent->y())); - - Vec2& translation = m_pCurveEditor->m_translation; - Vec2& zoom = m_pCurveEditor->m_zoom; - - const float pivotX = (m_pivot.x - translation.x) / zoom.x; - const float pivotY = (m_pivot.y - translation.y) / zoom.y; - - zoom.x *= pow(1.2f, (float)pixelDeltaX * 0.03f); - zoom.y *= pow(1.2f, (float)pixelDeltaY * 0.03f); - - zoom.x = clamp_tpl(zoom.x, kMinZoom, kMaxZoom); - zoom.y = clamp_tpl(zoom.y, kMinZoom, kMaxZoom); - - // Adjust translation so pivot point stays at same x and y position on screen - translation.x += ((m_pivot.x - translation.x) / zoom.x - pivotX) * zoom.x; - translation.y += ((m_pivot.y - translation.y) / zoom.y - pivotY) * zoom.y; - - m_pCurveEditor->update(); - } -}; - -struct CCurveEditor::SScrubHandler - : SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - SAnimTime m_startThumbPosition; - QPoint m_startPoint; - - SScrubHandler(CCurveEditor* pCurveEditor) - : m_pCurveEditor(pCurveEditor) - { - } - - void mousePressEvent(QMouseEvent* ev) override - { - QPoint point = QPoint(ev->pos().x(), ev->pos().y()); - - const Vec2 pointInCurveSpace = TransformPointFromScreen(m_pCurveEditor->m_zoom, m_pCurveEditor->m_translation, m_pCurveEditor->GetCurveArea(), PointToVec2(point)); - - m_pCurveEditor->m_time = clamp_tpl(SAnimTime(pointInCurveSpace.x), m_pCurveEditor->m_timeRange.start, m_pCurveEditor->m_timeRange.end); - m_startThumbPosition = m_pCurveEditor->m_time; - m_startPoint = point; - - m_pCurveEditor->SignalScrub(); - } - - void Apply(QMouseEvent* ev, bool continuous) - { - QPoint point = QPoint(ev->pos().x(), ev->pos().y()); - - bool shift = ev->modifiers().testFlag(Qt::ShiftModifier); - bool control = ev->modifiers().testFlag(Qt::ControlModifier); - - const float deltaX = (float)(point.x() - m_startPoint.x()); - const float width = (float)m_pCurveEditor->size().width(); - float delta = float(deltaX) / (width * m_pCurveEditor->m_zoom.x); - - if (shift) - { - delta *= 0.01f; - } - - if (control) - { - delta *= 0.1f; - } - - m_pCurveEditor->m_time = clamp_tpl(m_startThumbPosition + SAnimTime(delta), m_pCurveEditor->m_timeRange.start, m_pCurveEditor->m_timeRange.end); - m_pCurveEditor->SignalScrub(); - } - - void mouseMoveEvent(QMouseEvent* ev) override - { - Apply(ev, true); - } - - void mouseReleaseEvent(QMouseEvent* ev) override - { - Apply(ev, false); - } -}; - -struct CCurveEditor::SMoveHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - bool m_bCycleSelection; - Vec2 m_startPoint; - SAnimTime m_minSelectedTime; - std::vector m_keyTimes; - std::vector m_keyValues; - - SMoveHandler(CCurveEditor* pCurveEditor, bool bCycleSelection) - : m_pCurveEditor(pCurveEditor) - , m_bCycleSelection(bCycleSelection) - , m_startPoint(0.0f, 0.0f) - {} - - void mousePressEvent(QMouseEvent* pEvent) override - { - const QPoint currentPos = pEvent->pos(); - m_startPoint = TransformPointFromScreen(m_pCurveEditor->m_zoom, m_pCurveEditor->m_translation, m_pCurveEditor->GetCurveArea(), PointToVec2(currentPos)); - StoreKeyPositions(); - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - RestoreKeyPositions(); - - const QPoint currentPos = pEvent->pos(); - const Vec2 transformedPos = TransformPointFromScreen(m_pCurveEditor->m_zoom, m_pCurveEditor->m_translation, m_pCurveEditor->GetCurveArea(), PointToVec2(currentPos)); - const Vec2 offset = transformedPos - m_startPoint; - - SAnimTime deltaTime = SAnimTime(offset.x); - if (m_pCurveEditor->m_bSnapKeys) - { - SAnimTime newMinKeyTime = m_minSelectedTime + deltaTime; - newMinKeyTime = newMinKeyTime.SnapToNearest(m_pCurveEditor->m_frameRate); - deltaTime = newMinKeyTime - m_minSelectedTime; - } - - SCurveEditorContent* pContent = m_pCurveEditor->m_pContent; - for (auto curveIter = pContent->m_curves.begin(); curveIter != pContent->m_curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - - for (auto iter = curve.m_keys.begin(); iter != curve.m_keys.end(); ++iter) - { - if (iter->m_bSelected) - { - iter->m_time += deltaTime; - iter->m_controlPoint.m_value += offset.y; - iter->m_bModified = true; - } - } - - m_pCurveEditor->SortKeys(curve); - } - } - - void focusOutEvent(QFocusEvent* pEvent) override - { - RestoreKeyPositions(); - } - - void mouseReleaseEvent(QMouseEvent* pEvent) override - { - m_pCurveEditor->ContentChanged(); - } - - void StoreKeyPositions() - { - m_minSelectedTime = SAnimTime::Max(); - - SCurveEditorContent* pContent = m_pCurveEditor->m_pContent; - for (auto curveIter = pContent->m_curves.begin(); curveIter != pContent->m_curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - for (auto iter = curve.m_keys.begin(); iter != curve.m_keys.end(); ++iter) - { - if (iter->m_bSelected) - { - m_keyTimes.push_back(iter->m_time); - m_keyValues.push_back(iter->m_controlPoint.m_value); - m_minSelectedTime = min(m_minSelectedTime, iter->m_time); - } - } - } - } - - void RestoreKeyPositions() - { - SCurveEditorContent* pContent = m_pCurveEditor->m_pContent; - - auto timeIter = m_keyTimes.begin(); - auto valueIter = m_keyValues.begin(); - - for (auto curveIter = pContent->m_curves.begin(); curveIter != pContent->m_curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - for (auto iter = curve.m_keys.begin(); iter != curve.m_keys.end(); ++iter) - { - if (iter->m_bSelected) - { - iter->m_time = *(timeIter++); - iter->m_controlPoint.m_value = *(valueIter++); - iter->m_bModified = false; - } - } - } - } -}; - -struct CCurveEditor::SHandleMoveHandler - : public CCurveEditor::SMouseHandler -{ - CCurveEditor* m_pCurveEditor; - SCurveEditorKey m_appliedHandlesKey; - SCurveEditorKey* m_pKey; - CCurveEditor::ETangent m_tangent; - Vec2 m_startPoint; - Vec2 m_inTangentStartPosition; - Vec2 m_outTangentStartPosition; - SBezierControlPoint::ETangentType m_inTangentStartType; - SBezierControlPoint::ETangentType m_outTangentStartType; - float m_inTangentStartLength; - float m_outTangentStartLength; - - SHandleMoveHandler(CCurveEditor* pCurveEditor, SCurveEditorKey appliedHandlesKey, SCurveEditorKey* pKey, CCurveEditor::ETangent tangent) - : m_pCurveEditor(pCurveEditor) - , m_appliedHandlesKey(appliedHandlesKey) - , m_pKey(pKey) - , m_tangent(tangent) - , m_inTangentStartPosition(ZERO) - , m_inTangentStartType(SBezierControlPoint::eTangentType_Auto) - , m_inTangentStartLength(0.0f) - , m_outTangentStartPosition(ZERO) - , m_outTangentStartType(SBezierControlPoint::eTangentType_Auto) - , m_outTangentStartLength(0.0f) - { - } - - void mousePressEvent(QMouseEvent* pEvent) override - { - const QPoint currentPos = pEvent->pos(); - m_startPoint = TransformPointFromScreen(m_pCurveEditor->m_zoom, m_pCurveEditor->m_translation, m_pCurveEditor->GetCurveArea(), PointToVec2(currentPos)); - - m_inTangentStartPosition = m_appliedHandlesKey.m_controlPoint.m_inTangent; - m_inTangentStartType = m_appliedHandlesKey.m_controlPoint.m_inTangentType; - m_inTangentStartLength = m_inTangentStartPosition.GetLength(); - m_outTangentStartPosition = m_appliedHandlesKey.m_controlPoint.m_outTangent; - m_outTangentStartType = m_appliedHandlesKey.m_controlPoint.m_outTangentType; - m_outTangentStartLength = m_outTangentStartPosition.GetLength(); - } - - void mouseMoveEvent(QMouseEvent* pEvent) override - { - const QPoint currentPos = pEvent->pos(); - const Vec2 transformedPos = TransformPointFromScreen(m_pCurveEditor->m_zoom, m_pCurveEditor->m_translation, m_pCurveEditor->GetCurveArea(), PointToVec2(currentPos)); - - if (m_tangent == CCurveEditor::ETangent_In) - { - const Vec2 newPos = m_inTangentStartPosition + (transformedPos - m_startPoint); - - m_pKey->m_controlPoint.m_inTangent = newPos; - m_pKey->m_controlPoint.m_inTangentType = SBezierControlPoint::eTangentType_Custom; - - if (!m_pKey->m_controlPoint.m_bBreakTangents) - { - m_pKey->m_controlPoint.m_outTangent = -newPos.GetNormalizedSafe() * m_outTangentStartLength; - m_pKey->m_controlPoint.m_outTangentType = SBezierControlPoint::eTangentType_Custom; - } - } - else - { - const Vec2 newPos = m_outTangentStartPosition + (transformedPos - m_startPoint); - - m_pKey->m_controlPoint.m_outTangent = newPos; - m_pKey->m_controlPoint.m_outTangentType = SBezierControlPoint::eTangentType_Custom; - - if (!m_pKey->m_controlPoint.m_bBreakTangents) - { - m_pKey->m_controlPoint.m_inTangent = -newPos.GetNormalizedSafe() * m_inTangentStartLength; - m_pKey->m_controlPoint.m_inTangentType = SBezierControlPoint::eTangentType_Custom; - } - } - - m_pKey->m_bModified = true; - } - - void focusOutEvent(QFocusEvent* pEvent) override - { - m_pKey->m_controlPoint.m_inTangent = m_inTangentStartPosition; - m_pKey->m_controlPoint.m_inTangentType = m_inTangentStartType; - m_pKey->m_controlPoint.m_outTangent = m_outTangentStartPosition; - m_pKey->m_controlPoint.m_outTangentType = m_outTangentStartType; - m_pKey->m_bModified = false; - } - - void mouseReleaseEvent(QMouseEvent* pEvent) override - { - m_pCurveEditor->ContentChanged(); - } -}; - -CCurveEditor::CCurveEditor(QWidget* parent) - : QWidget(parent) - , m_pContent(nullptr) - , m_pMouseHandler(nullptr) - , m_curveType(eCECT_Bezier) - , m_frameRate(SAnimTime::eFrameRate_30fps) - , m_bWeighted(false) - , m_bHandlesVisible(true) - , m_bRulerVisible(true) - , m_bTimeSliderVisible(true) - , m_bGridVisible(false) - , m_bSnapTime(false) - , m_bSnapKeys(false) - , m_time(SAnimTime(0)) - , m_zoom(0.5f, 0.5f) - , m_translation(0.5f, 0.5f) - , m_timeRange(SAnimTime::Min(), SAnimTime::Max()) - , m_valueRange(-1e10f, 1e10f) -{ - setMouseTracking(true); -} - -CCurveEditor::~CCurveEditor() -{ -} - -void CCurveEditor::SetContent(SCurveEditorContent* pContent) -{ - m_pContent = pContent; - update(); -} - -void CCurveEditor::SetTime(const SAnimTime time) -{ - m_time = clamp_tpl<>(time, m_timeRange.start, m_timeRange.end); - update(); -} - -void CCurveEditor::SetTimeRange(const SAnimTime start, const SAnimTime end) -{ - if (start <= end) - { - m_timeRange = TRange(start, end); - update(); - } -} - -void CCurveEditor::SetValueRange(const float min, const float max) -{ - if (min <= max) - { - m_valueRange = Range(min, max); - update(); - } -} - -void CCurveEditor::ZoomToTimeRange(const float start, const float end) -{ - const float delta = (end - start); - - if (delta > 1e-10f) - { - m_zoom.x = 1.0f / (end - start); - m_translation.x = start / (start - end); - } - else - { - // Just center around value with zoom = 1.0f - m_zoom.x = 1.0f; - m_translation.x = 0.5f - start; - } -} - -void CCurveEditor::ZoomToValueRange(const float min, const float max) -{ - const float delta = (max - min); - - if (delta > 1e-10f) - { - m_zoom.y = 1.0f / (max - min); - m_translation.y = max / (max - min); - } - else - { - // Just center around value with zoom = 1.0f - m_zoom.y = 1.0f; - m_translation.y = 0.5f + min; - } -} - -void CCurveEditor::paintEvent(QPaintEvent* pEvent) -{ - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.translate(0.5f, 0.5f); - - const QPalette& palette = this->palette(); - - auto transformFunc = [&](Vec2 point) - { - return TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), point); - }; - - const QColor rangeHighlightColor = CurveEditorHelpers::Interpolate(palette.color(QPalette::Foreground), palette.color(QPalette::Background), 0.95f); - const QRectF rangesRect(Vec2ToPoint(transformFunc(Vec2(m_timeRange.start.ToFloat(), m_valueRange.start))), Vec2ToPoint(transformFunc(Vec2(m_timeRange.end.ToFloat(), m_valueRange.end)))); - painter.setPen(QPen(Qt::NoPen)); - painter.setBrush(rangeHighlightColor); - painter.drawRect(rangesRect); - - if (m_bGridVisible) - { - DrawGrid(painter, palette); - } - - if (m_pContent) - { - const QPen extrapolatedCurvePen = QPen(palette.color(QPalette::Highlight)); - - TCurveEditorCurves& curves = m_pContent->m_curves; - for (auto curveIter = curves.begin(); curveIter != curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - - painter.setBrush(QBrush(Qt::NoBrush)); - const QPen curvePen = QPen(QColor(curve.m_color.r, curve.m_color.g, curve.m_color.b, curve.m_color.a), 2); - const QPen narrowCurvePen = QPen(QColor(curve.m_color.r, curve.m_color.g, curve.m_color.b, curve.m_color.a)); - - const QPainterPath extrapolatedPath = CreateExtrapolatedPathFromCurve(curve, transformFunc, width()); - painter.setPen(narrowCurvePen); - painter.drawPath(extrapolatedPath); - - const QPainterPath discontinuityPath = CreateDiscontinuityPathFromCurve(curve, m_curveType, transformFunc); - painter.setPen(narrowCurvePen); - painter.drawPath(discontinuityPath); - - if (curve.m_keys.size() > 0) - { - const QPainterPath path = CreatePathFromCurve(curve, m_curveType, transformFunc); - painter.setPen(curvePen); - painter.drawPath(path); - - DrawKeys(painter, palette, curve, m_curveType, transformFunc, m_bHandlesVisible); - } - } - } - - if (m_pMouseHandler) - { - m_pMouseHandler->paintOver(painter); - } - - DrawingPrimitives::SRulerOptions rulerOptions; - rulerOptions.m_rect = QRect(0, -1, size().width(), kRulerHeight + 2); - rulerOptions.m_visibleRange = Range(-m_translation.x / m_zoom.x, (1.0f - m_translation.x) / m_zoom.x); - rulerOptions.m_rulerRange = rulerOptions.m_visibleRange; - rulerOptions.m_markHeight = kRulerMarkHeight; - rulerOptions.m_shadowSize = kRulerShadowHeight; - - int rulerPrecision; - DrawingPrimitives::DrawRuler(painter, palette, rulerOptions, &rulerPrecision); - - if (m_pContent && isEnabled()) - { - DrawingPrimitives::STimeSliderOptions timeSliderOptions; - timeSliderOptions.m_rect = rect(); - timeSliderOptions.m_precision = rulerPrecision; - timeSliderOptions.m_position = transformFunc(Vec2(m_time.ToFloat(), 0.0f)).x; - timeSliderOptions.m_time = m_time.ToFloat(); - timeSliderOptions.m_bHasFocus = hasFocus(); - DrawingPrimitives::DrawTimeSlider(painter, palette, timeSliderOptions); - } -} - -void CCurveEditor::mousePressEvent(QMouseEvent* pEvent) -{ - setFocus(); - - if (pEvent->button() == Qt::LeftButton) - { - LeftButtonMousePressEvent(pEvent); - } - else if (pEvent->button() == Qt::MiddleButton) - { - MiddleButtonMousePressEvent(pEvent); - } - else if (pEvent->button() == Qt::RightButton) - { - RightButtonMousePressEvent(pEvent); - } -} - -void CCurveEditor::mouseDoubleClickEvent(QMouseEvent* pEvent) -{ - if (pEvent->button() == Qt::LeftButton) - { - auto curveHitPair = HitDetectCurve(pEvent->pos()); - if (curveHitPair.first) - { - AddPointToCurve(curveHitPair.second, curveHitPair.first); - setCursor(QCursor(Qt::SizeAllCursor)); - } - } -} - -void CCurveEditor::DrawGrid(QPainter& painter, const QPalette& palette) -{ - using namespace DrawingPrimitives; - - QColor gridColor = CurveEditorHelpers::Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f); - gridColor.setAlpha(128); - const QColor textColor = palette.color(QPalette::BrightText); - - const Range horizontalVisibleRange = Range(-m_translation.x / m_zoom.x, (1.0f - m_translation.x) / m_zoom.x); - const Range verticalVisibleRange = Range((m_translation.y - 1.0f) / m_zoom.y, m_translation.y / m_zoom.y); - - const int height = size().height(); - const int width = size().width(); - - int verticalRulerPrecision; - - std::vector horizontalTicks = CalculateTicks(width, horizontalVisibleRange, horizontalVisibleRange, nullptr, nullptr); - std::vector verticalTicks = CalculateTicks(height, verticalVisibleRange, verticalVisibleRange, &verticalRulerPrecision, nullptr); - - char format[16] = ""; - sprintf_s(format, "%%.%df", verticalRulerPrecision); - - const QPen gridPen(gridColor, 1.0); - painter.setPen(gridPen); - - for (const STick& tick : horizontalTicks) - { - if (!tick.m_bTenth) - { - const int x = tick.m_position; - painter.drawLine(x, kRulerHeight, x, height); - } - } - - for (const STick& tick : verticalTicks) - { - if (!tick.m_bTenth) - { - const int y = height - tick.m_position; - painter.drawLine(0, y, width, y); - } - } - - const QPen textPen(textColor); - painter.setPen(textPen); - - QString str; - for (const STick& tick : verticalTicks) - { - if (!tick.m_bTenth) - { - const int y = height - tick.m_position; - str.sprintf(format, tick.m_value); - painter.drawText(5, y - 4, str); - } - } -} - -void CCurveEditor::LeftButtonMousePressEvent(QMouseEvent* pEvent) -{ - const bool bCtrlPressed = (pEvent->modifiers() & Qt::CTRL) != 0; - const bool bAltPressed = (pEvent->modifiers() & Qt::ALT) != 0; - - if (pEvent->y() < kRulerHeight) - { - m_pMouseHandler.reset(new SScrubHandler(this)); - m_pMouseHandler->mousePressEvent(pEvent); - } - else - { - if (bCtrlPressed) - { - auto curveHitPair = HitDetectCurve(pEvent->pos()); - if (curveHitPair.first) - { - AddPointToCurve(curveHitPair.second, curveHitPair.first); - setCursor(QCursor(Qt::SizeAllCursor)); - } - } - else if (bAltPressed) - { - auto curveKeyPair = HitDetectKey(pEvent->pos()); - if (curveKeyPair.first) - { - curveKeyPair.second->m_bDeleted = true; - ContentChanged(); - } - } - else - { - auto curveKeyPair = HitDetectKey(pEvent->pos()); - auto handleKeyTuple = HitDetectHandle(pEvent->pos()); - - if (std::get<0>(handleKeyTuple)) - { - m_pMouseHandler.reset(new SHandleMoveHandler(this, std::get<1>(handleKeyTuple), std::get<2>(handleKeyTuple), std::get<3>(handleKeyTuple))); - } - else if (curveKeyPair.first) - { - bool useExistingSelection = curveKeyPair.second->m_bSelected; - if (!useExistingSelection) - { - ForEachKey(*m_pContent, [](SCurveEditorCurve& curve, SCurveEditorKey& key) - { - key.m_bSelected = false; - }); - curveKeyPair.second->m_bSelected = true; - } - - m_pMouseHandler.reset(new SMoveHandler(this, false)); - } - else - { - m_pMouseHandler.reset(new SSelectionHandler(this, false)); - } - - m_pMouseHandler->mousePressEvent(pEvent); - } - } - - update(); -} - -void CCurveEditor::MiddleButtonMousePressEvent(QMouseEvent* pEvent) -{ - const bool bShiftPressed = (pEvent->modifiers() & Qt::SHIFT) != 0; - - if (!bShiftPressed) - { - m_pMouseHandler.reset(new SPanHandler(this)); - } - else - { - m_pMouseHandler.reset(new SZoomHandler(this)); - } - - m_pMouseHandler->mousePressEvent(pEvent); - update(); -} - -void CCurveEditor::RightButtonMousePressEvent(QMouseEvent* pEvent) -{ -} - -void CCurveEditor::mouseMoveEvent(QMouseEvent* pEvent) -{ - if (m_pMouseHandler) - { - m_pMouseHandler->mouseMoveEvent(pEvent); - } - else - { - if (HitDetectKey(pEvent->pos()).first || std::get<0>(HitDetectHandle(pEvent->pos()))) - { - setCursor(QCursor(Qt::SizeAllCursor)); - } - else - { - setCursor(QCursor()); - } - } - - update(); -} - -void CCurveEditor::mouseReleaseEvent(QMouseEvent* pEvent) -{ - if (m_pMouseHandler) - { - m_pMouseHandler->mouseReleaseEvent(pEvent); - m_pMouseHandler.reset(); - update(); - } -} - -void CCurveEditor::focusOutEvent(QFocusEvent* pEvent) -{ - if (m_pMouseHandler) - { - m_pMouseHandler->focusOutEvent(pEvent); - m_pMouseHandler.reset(); - update(); - } -} - -void CCurveEditor::wheelEvent(QWheelEvent* pEvent) -{ - Vec2 windowSize((float)size().width(), (float)size().height()); - windowSize.y = (windowSize.y > 0.0f) ? windowSize.y : 1.0f; - - const QRect curveArea = GetCurveArea(); - const float mouseXNormalized = (float)(pEvent->x() - curveArea.left()) / (float)curveArea.width(); - const float mouseYNormalized = (float)(pEvent->y() - curveArea.top()) / (float)curveArea.height(); - - const float pivotX = (mouseXNormalized - m_translation.x) / m_zoom.x; - const float pivotY = (mouseYNormalized - m_translation.y) / m_zoom.y; - - m_zoom *= pow(1.2f, (float)pEvent->delta() * 0.01f); - m_zoom.x = clamp_tpl(m_zoom.x, kMinZoom, kMaxZoom); - m_zoom.y = clamp_tpl(m_zoom.y, kMinZoom, kMaxZoom); - - // Adjust translation so pivot point stays at same x and y position on screen - m_translation.x += ((mouseXNormalized - m_translation.x) / m_zoom.x - pivotX) * m_zoom.x; - m_translation.y += ((mouseYNormalized - m_translation.y) / m_zoom.y - pivotY) * m_zoom.y; - - update(); -} - -void CCurveEditor::keyPressEvent(QKeyEvent* pEvent) -{ - if (!m_pContent) - { - return; - } - - QKeySequence key(pEvent->key()); - - if (key == QKeySequence(Qt::Key_Delete)) - { - OnDeleteSelectedKeys(); - } - - update(); -} - -void CCurveEditor::SetCurveType(ECurveEditorCurveType curveType) -{ - m_curveType = curveType; - update(); -} - -void CCurveEditor::SetHandlesVisible(bool bVisible) -{ - m_bHandlesVisible = bVisible; - update(); -} - -void CCurveEditor::SetRulerVisible(bool bVisible) -{ - m_bRulerVisible = bVisible; - update(); -} - -void CCurveEditor::SetTimeSliderVisible(bool bVisible) -{ - m_bTimeSliderVisible = bVisible; - update(); -} - -void CCurveEditor::SetGridVisible(bool bVisible) -{ - m_bGridVisible = bVisible; - update(); -} - -void CCurveEditor::SelectInRect(const QRect& rect) -{ - if (!m_pContent) - { - return; - } - - ForEachKey(*m_pContent, [&](SCurveEditorCurve& curve, SCurveEditorKey& key) - { - const Vec2 screenPoint = TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), Vec2(key.m_time.ToFloat(), key.m_controlPoint.m_value)); - key.m_bSelected = rect.contains((int)screenPoint.x, (int)screenPoint.y); - }); - - update(); - SignalContentChanged(); -} - -std::pair CCurveEditor::HitDetectCurve(const QPoint point) -{ - if (!m_pContent) - { - return std::make_pair(nullptr, Vec2(ZERO)); - } - - SCurveEditorCurve* pNearestCurve = nullptr; - Vec2 closestPoint = Vec2(ZERO); - - float nearestDistance = std::numeric_limits::max(); - for (auto iter = m_pContent->m_curves.rbegin(); iter != m_pContent->m_curves.rend(); ++iter) - { - SCurveEditorCurve& curve = *iter; - const Vec2 closestPointOnCurve = ClosestPointOnCurve(PointToVec2(point), curve, m_curveType); - - const float distance = (PointToVec2(point) - closestPointOnCurve).GetLength(); - if (distance < nearestDistance) - { - nearestDistance = distance; - pNearestCurve = &curve; - closestPoint = closestPointOnCurve; - } - } - - if (nearestDistance <= kHitDistance) - { - return std::make_pair(pNearestCurve, TransformPointFromScreen(m_zoom, m_translation, GetCurveArea(), closestPoint)); - } - - return std::make_pair(nullptr, Vec2(ZERO)); -} - -std::pair CCurveEditor::HitDetectKey(const QPoint point) -{ - if (!m_pContent) - { - return std::make_pair(nullptr, nullptr); - } - - for (auto curvesIter = m_pContent->m_curves.rbegin(); curvesIter != m_pContent->m_curves.rend(); ++curvesIter) - { - SCurveEditorCurve& curve = *curvesIter; - for (auto iter = curve.m_keys.rbegin(); iter != curve.m_keys.rend(); ++iter) - { - SCurveEditorKey& key = *iter; - const Vec2 keyPoint = Vec2(key.m_time.ToFloat(), key.m_controlPoint.m_value); - const Vec2 transformedPoint = TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), keyPoint); - if ((transformedPoint - PointToVec2(point)).GetLength() <= kHitDistance) - { - return std::make_pair(&curve, &key); - } - } - } - - return std::make_pair(nullptr, nullptr); -} - -std::tuple CCurveEditor::HitDetectHandle(const QPoint point) -{ - if (!m_pContent || !m_bHandlesVisible) - { - return std::make_tuple(nullptr, SCurveEditorKey(), nullptr, ETangent_In); - } - - for (auto curvesIter = m_pContent->m_curves.rbegin(); curvesIter != m_pContent->m_curves.rend(); ++curvesIter) - { - SCurveEditorCurve& curve = *curvesIter; - for (auto iter = curve.m_keys.begin(); iter != curve.m_keys.end(); ++iter) - { - SCurveEditorKey key = *iter; - - const bool bIsFirstKey = (iter == curve.m_keys.begin()); - const bool bIsLastKey = (iter == (curve.m_keys.end() - 1)); - const SCurveEditorKey* pLeftKey = (!bIsFirstKey) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pRightKey = (!bIsLastKey) ? &*(iter + 1) : nullptr; - key = pRightKey ? ApplyOutTangentFlags(key, pLeftKey, *pRightKey) : key; - key = pLeftKey ? ApplyInTangentFlags(key, *pLeftKey, pRightKey) : key; - - const Vec2 inTangent = (m_curveType == eCECT_Bezier) ? Vec2(0.0f, key.m_controlPoint.m_inTangent.y) : key.m_controlPoint.m_inTangent; - const Vec2 outTangent = (m_curveType == eCECT_Bezier) ? Vec2(0.0f, key.m_controlPoint.m_outTangent.y) : key.m_controlPoint.m_outTangent; - - const Vec2 keyPoint = Vec2(key.m_time.ToFloat(), key.m_controlPoint.m_value); - - if (!bIsFirstKey && (key.m_controlPoint.m_inTangentType != SBezierControlPoint::eTangentType_Step)) - { - const Vec2 tangentHandlePoint = keyPoint + inTangent; - const Vec2 transformedTangentHandlePoint = TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), tangentHandlePoint); - if ((transformedTangentHandlePoint - PointToVec2(point)).GetLength() <= kHitDistance) - { - return std::make_tuple(&curve, key, &(*iter), ETangent_In); - } - } - - if (!bIsLastKey && (key.m_controlPoint.m_outTangentType != SBezierControlPoint::eTangentType_Step)) - { - const Vec2 tangentHandlePoint = keyPoint + outTangent; - const Vec2 transformedTangentHandlePoint = TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), tangentHandlePoint); - if ((transformedTangentHandlePoint - PointToVec2(point)).GetLength() <= kHitDistance) - { - return std::make_tuple(&curve, key, &(*iter), ETangent_Out); - } - } - } - } - - return std::make_tuple(nullptr, SCurveEditorKey(), nullptr, ETangent_In); -} - -// Input and output are in screen space -Vec2 CCurveEditor::ClosestPointOnCurve(const Vec2 point, const SCurveEditorCurve& curve, const ECurveEditorCurveType curveType) -{ - auto transformFunc = [&](Vec2 point) - { - return TransformPointToScreen(m_zoom, m_translation, GetCurveArea(), point); - }; - - if (curve.m_keys.size() == 0) - { - const Vec2 pointOnCurve = transformFunc(Vec2(0.0f, curve.m_defaultValue)); - return Vec2(point.x, pointOnCurve.y); - } - - Vec2 closestPoint; - float minDistance = std::numeric_limits::max(); - - const Vec2 startKeyTransformed = transformFunc(Vec2(curve.m_keys.front().m_time.ToFloat(), curve.m_keys.front().m_controlPoint.m_value)); - if (point.x < startKeyTransformed.x) - { - const float distanceToCurve = std::abs(point.y - startKeyTransformed.y); - if (distanceToCurve < minDistance) - { - closestPoint = Vec2(point.x, startKeyTransformed.y); - minDistance = distanceToCurve; - } - } - - const Vec2 endKeyTransformed = transformFunc(Vec2(curve.m_keys.back().m_time.ToFloat(), curve.m_keys.back().m_controlPoint.m_value)); - if (point.x > endKeyTransformed.x) - { - const float distanceToCurve = std::abs(point.y - endKeyTransformed.y); - if (distanceToCurve < minDistance) - { - closestPoint = Vec2(point.x, endKeyTransformed.y); - minDistance = distanceToCurve; - } - } - - const auto endIter = curve.m_keys.end() - 1; - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - const SCurveEditorKey* pKeyLeftOfSegment = (iter != curve.m_keys.begin()) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pKeyRightOfSegment = (iter != (curve.m_keys.end() - 2)) ? &*(iter + 2) : nullptr; - - const SCurveEditorKey segmentStartKey = ApplyOutTangentFlags(*iter, pKeyLeftOfSegment, *(iter + 1)); - const SCurveEditorKey segmentEndKey = ApplyInTangentFlags(*(iter + 1), *iter, pKeyRightOfSegment); - - const Vec2 p0 = transformFunc(Vec2(segmentStartKey.m_time.ToFloat(), segmentStartKey.m_controlPoint.m_value)); - const Vec2 p3 = transformFunc(Vec2(segmentEndKey.m_time.ToFloat(), segmentEndKey.m_controlPoint.m_value)); - const Vec2 p1 = transformFunc(Vec2(segmentStartKey.m_time.ToFloat() + segmentStartKey.m_controlPoint.m_outTangent.x, - segmentStartKey.m_controlPoint.m_value + segmentStartKey.m_controlPoint.m_outTangent.y)); - const Vec2 p2 = transformFunc(Vec2(segmentEndKey.m_time.ToFloat() + segmentEndKey.m_controlPoint.m_inTangent.x, - segmentEndKey.m_controlPoint.m_value + segmentEndKey.m_controlPoint.m_inTangent.y)); - - const Vec2 closestOnSegment = (curveType == eCECT_Bezier) ? ClosestPointOnBezierSegment(point, p0.x, p3.x, p0.y, p1.y, p2.y, p3.y) : ClosestPointOn2DBezierSegment(point, p0, p1, p2, p3); - const float distanceToSegment = (closestOnSegment - point).GetLength(); - if (distanceToSegment < minDistance) - { - closestPoint = closestOnSegment; - minDistance = distanceToSegment; - } - } - - return closestPoint; -} - -void CCurveEditor::ContentChanged() -{ - SignalContentChanged(); - - DeleteMarkedKeys(); - - ForEachKey(*m_pContent, [](SCurveEditorCurve& curve, SCurveEditorKey& key) - { - key.m_bModified = false; - }); - - update(); -} - -void CCurveEditor::DeleteMarkedKeys() -{ - if (m_pContent) - { - for (auto iter = m_pContent->m_curves.begin(); iter != m_pContent->m_curves.end(); ++iter) - { - SCurveEditorCurve& curve = *iter; - for (auto keyIter = curve.m_keys.begin(); keyIter != curve.m_keys.end(); ) - { - if (keyIter->m_bDeleted) - { - keyIter = curve.m_keys.erase(keyIter); - } - else - { - ++keyIter; - } - } - } - } -} - -void CCurveEditor::AddPointToCurve(const Vec2 point, SCurveEditorCurve* pCurve) -{ - SCurveEditorKey key; - key.m_time = SAnimTime(point.x); - if (m_bSnapKeys) - { - key.m_time.SnapToNearest(m_frameRate); - } - key.m_controlPoint.m_value = point.y; - key.m_bAdded = true; - pCurve->m_keys.push_back(key); - - SortKeys(*pCurve); - ContentChanged(); -} - -void CCurveEditor::SortKeys(SCurveEditorCurve& curve) -{ - std::stable_sort(curve.m_keys.begin(), curve.m_keys.end(), [](const SCurveEditorKey& a, const SCurveEditorKey& b) - { - return a.m_time < b.m_time; - }); -} - -void CCurveEditor::OnDeleteSelectedKeys() -{ - ForEachKey(*m_pContent, [](SCurveEditorCurve& curve, SCurveEditorKey& key) - { - key.m_bDeleted = key.m_bDeleted || key.m_bSelected; - }); - - ContentChanged(); -} - -void CCurveEditor::OnSetSelectedKeysTangentAuto() -{ - SetSelectedKeysTangentType(ETangent_In, SBezierControlPoint::eTangentType_Auto); - SetSelectedKeysTangentType(ETangent_Out, SBezierControlPoint::eTangentType_Auto); -} - -void CCurveEditor::OnSetSelectedKeysInTangentZero() -{ - SetSelectedKeysTangentType(ETangent_In, SBezierControlPoint::eTangentType_Zero); -} - -void CCurveEditor::OnSetSelectedKeysInTangentStep() -{ - SetSelectedKeysTangentType(ETangent_In, SBezierControlPoint::eTangentType_Step); -} - -void CCurveEditor::OnSetSelectedKeysInTangentLinear() -{ - SetSelectedKeysTangentType(ETangent_In, SBezierControlPoint::eTangentType_Linear); -} - -void CCurveEditor::OnSetSelectedKeysOutTangentZero() -{ - SetSelectedKeysTangentType(ETangent_Out, SBezierControlPoint::eTangentType_Zero); -} - -void CCurveEditor::OnSetSelectedKeysOutTangentStep() -{ - SetSelectedKeysTangentType(ETangent_Out, SBezierControlPoint::eTangentType_Step); -} - -void CCurveEditor::OnSetSelectedKeysOutTangentLinear() -{ - SetSelectedKeysTangentType(ETangent_Out, SBezierControlPoint::eTangentType_Linear); -} - -void CCurveEditor::OnFitCurvesHorizontally() -{ - if (m_pContent) - { - bool bAnyKeyFound = false; - SAnimTime timeMin = SAnimTime::Max(); - SAnimTime timeMax = SAnimTime::Min(); - - TCurveEditorCurves& curves = m_pContent->m_curves; - for (auto curveIter = curves.begin(); curveIter != curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - if (curve.m_keys.size() > 0) - { - bAnyKeyFound = true; - timeMin = std::min(curve.m_keys.front().m_time, timeMin); - timeMax = std::max(curve.m_keys.back().m_time, timeMax); - } - } - - if (!bAnyKeyFound) - { - timeMin = m_timeRange.start; - timeMax = m_timeRange.end; - } - - ZoomToTimeRange(timeMin.ToFloat(), timeMax.ToFloat()); - - // Adjust zoom and translation depending on kFitMargin - const float pivot = (0.5f - m_translation.x) / m_zoom.x; - m_zoom.x /= 1.0f + 2.0f * (kFitMargin / GetCurveArea().width()); - m_translation.x += ((0.5f - m_translation.x) / m_zoom.x - pivot) * m_zoom.x; - } - - update(); -} - -void CCurveEditor::OnFitCurvesVertically() -{ - if (m_pContent) - { - bool bAnyKeyFound = false; - float valueMin = std::numeric_limits::max(); - float valueMax = -std::numeric_limits::max(); - - TCurveEditorCurves& curves = m_pContent->m_curves; - for (auto curveIter = curves.begin(); curveIter != curves.end(); ++curveIter) - { - SCurveEditorCurve& curve = *curveIter; - - if (curve.m_keys.size() > 1) - { - const auto endIter = curve.m_keys.end() - 1; - - for (auto iter = curve.m_keys.begin(); iter != endIter; ++iter) - { - bAnyKeyFound = true; - - const SCurveEditorKey* pKeyLeftOfSegment = (iter != curve.m_keys.begin()) ? &*(iter - 1) : nullptr; - const SCurveEditorKey* pKeyRightOfSegment = (iter != (curve.m_keys.end() - 2)) ? &*(iter + 2) : nullptr; - - const SCurveEditorKey segmentStartKey = ApplyOutTangentFlags(*iter, pKeyLeftOfSegment, *(iter + 1)); - const SCurveEditorKey segmentEndKey = ApplyInTangentFlags(*(iter + 1), *iter, pKeyRightOfSegment); - - const Range valueRange = GetBezierSegmentValueRange(segmentStartKey, segmentEndKey); - valueMin = std::min(valueMin, valueRange.start); - valueMax = std::max(valueMax, valueRange.end); - } - } - else if (curve.m_keys.size() == 1) - { - bAnyKeyFound = true; - valueMin = valueMax = curve.m_keys[0].m_controlPoint.m_value; - } - } - - if (!bAnyKeyFound) - { - valueMin = -0.5f; - valueMax = 0.5f; - } - - ZoomToValueRange(valueMin, valueMax); - - // Adjust zoom and translation depending on kFitMargin - const float pivot = (0.5f - m_translation.y) / m_zoom.y; - m_zoom.y /= 1.0f + 2.0f * (kFitMargin / GetCurveArea().height()); - m_translation.y += ((0.5f - m_translation.y) / m_zoom.y - pivot) * m_zoom.y; - } - - update(); -} - -void CCurveEditor::OnBreakTangents() -{ - if (m_pContent) - { - ForEachKey(*m_pContent, [&](SCurveEditorCurve& curve, SCurveEditorKey& key) - { - if (key.m_bSelected) - { - key.m_controlPoint.m_bBreakTangents = true; - } - }); - } - - SignalContentChanged(); -} - -void CCurveEditor::OnUnifyTangents() -{ - if (m_pContent) - { - ForEachKey(*m_pContent, [&](SCurveEditorCurve& curve, SCurveEditorKey& key) - { - if (key.m_bSelected) - { - key.m_controlPoint.m_bBreakTangents = false; - } - }); - } - - SignalContentChanged(); -} - -void CCurveEditor::SetSelectedKeysTangentType(const ETangent tangent, const SBezierControlPoint::ETangentType type) -{ - if (m_pContent) - { - ForEachKey(*m_pContent, [&](SCurveEditorCurve& curve, SCurveEditorKey& key) - { - if (key.m_bSelected) - { - if (tangent == ETangent_In) - { - key.m_controlPoint.m_inTangentType = type; - } - else - { - key.m_controlPoint.m_outTangentType = type; - } - } - }); - - update(); - } - - SignalContentChanged(); -} - -QRect CCurveEditor::GetCurveArea() -{ - const uint rulerAreaHeight = m_bRulerVisible ? kRulerHeight : 0; - return QRect(0, rulerAreaHeight, width(), height() - rulerAreaHeight); -} - -void CCurveEditor::FillWithCurveToolsAndConnect(QToolBar* pToolBar) -{ - pToolBar->addAction(QIcon(":/Icons/CurveEditor/auto.png"), "Set in and out tangents to auto", this, SLOT(OnSetSelectedKeysTangentAuto())); - pToolBar->addSeparator(); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/zero_in.png"), "Set in tangent to zero", this, SLOT(OnSetSelectedKeysInTangentZero())); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/step_in.png"), "Set in tangent to step", this, SLOT(OnSetSelectedKeysInTangentStep())); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/linear_in.png"), "Set in tangent to linear", this, SLOT(OnSetSelectedKeysInTangentLinear())); - pToolBar->addSeparator(); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/zero_out.png"), "Set out tangent to zero", this, SLOT(OnSetSelectedKeysOutTangentZero())); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/step_out.png"), "Set out tangent to step", this, SLOT(OnSetSelectedKeysOutTangentStep())); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/linear_out.png"), "Set out tangent to linear", this, SLOT(OnSetSelectedKeysOutTangentLinear())); - pToolBar->addSeparator(); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/fit_horizontal.png"), "Fit curves horizontally", this, SLOT(OnFitCurvesHorizontally())); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/fit_vertical.png"), "Fit curves vertically", this, SLOT(OnFitCurvesVertically())); - pToolBar->addSeparator(); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/break.png"), "Break tangents", this, SLOT(OnBreakTangents())); - pToolBar->addAction(QIcon(":/Icons/CurveEditor/unify.png"), "Unify tangents", this, SLOT(OnUnifyTangents())); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/CurveEditor_38.h b/Code/Sandbox/Plugins/EditorCommon/CurveEditor_38.h deleted file mode 100644 index f0c5da608b..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/CurveEditor_38.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include "CurveEditorContent.h" -#include -#include -#include - -class QToolBar; - -enum ECurveEditorCurveType -{ - eCECT_Bezier, - // 2D Bezier curves are used for better curve control, the editor - // will enforce that the resulting curve is always 1D. - eCECT_2DBezier, -}; - -namespace CurveEditorHelpers -{ - // Picks a nice color value for a curve. Wraps around after 4. - EDITOR_COMMON_API ColorB GetCurveColor(const uint n); -} - -class EDITOR_COMMON_API CCurveEditor - : public QWidget -{ - Q_OBJECT -public: - CCurveEditor(QWidget* parent); - ~CCurveEditor(); - - void SetContent(SCurveEditorContent* pContent); - SCurveEditorContent* Content() const { return m_pContent; } - - SAnimTime Time() const { return m_time; } - void SetTime(const SAnimTime time); - - // The background in the time and value range will be drawn a bit brighter to indicate where keys - // should be placed. The curve editor does not enforce that the curves actually stay in those ranges. - void SetTimeRange(const SAnimTime start, const SAnimTime end); - void SetValueRange(const float min, const float max); - - void ZoomToTimeRange(const float start, const float end); - void ZoomToValueRange(const float min, const float max); - - void SetCurveType(ECurveEditorCurveType curveType); - void SetWeighted(bool bWeighted); - void SetHandlesVisible(bool bVisible); - void SetRulerVisible(bool bVisible); - void SetTimeSliderVisible(bool bVisible); - void SetGridVisible(bool bVisible); - void SetFrameRate(SAnimTime::EFrameRate frameRate) { m_frameRate = frameRate; } - void SetTimeSnapping(bool snapTime) { m_bSnapTime = snapTime; } - void SetKeySnapping(bool snapKeys) { m_bSnapKeys = snapKeys; } - - // Tools added to tool bar depend on options above - void FillWithCurveToolsAndConnect(QToolBar* pToolBar); - - void paintEvent(QPaintEvent* pEvent) override; - void mousePressEvent(QMouseEvent* pEvent) override; - void mouseDoubleClickEvent(QMouseEvent* pEvent) override; - void mouseMoveEvent(QMouseEvent* pEvent) override; - void mouseReleaseEvent(QMouseEvent* pEvent) override; - void focusOutEvent(QFocusEvent* pEvent) override; - void wheelEvent(QWheelEvent* pEvent) override; - void keyPressEvent(QKeyEvent* pEvent) override; - -signals: - void SignalContentChanged(); - void SignalScrub(); - -public slots: - void OnDeleteSelectedKeys(); - void OnSetSelectedKeysTangentAuto(); - void OnSetSelectedKeysInTangentZero(); - void OnSetSelectedKeysInTangentStep(); - void OnSetSelectedKeysInTangentLinear(); - void OnSetSelectedKeysOutTangentZero(); - void OnSetSelectedKeysOutTangentStep(); - void OnSetSelectedKeysOutTangentLinear(); - void OnFitCurvesHorizontally(); - void OnFitCurvesVertically(); - void OnBreakTangents(); - void OnUnifyTangents(); - -private: - struct SMouseHandler; - struct SSelectionHandler; - struct SPanHandler; - struct SZoomHandler; - struct SMoveHandler; - struct SHandleMoveHandler; - struct SScrubHandler; - enum ETangent; - - void DrawGrid(QPainter& painter, const QPalette& palette); - - void LeftButtonMousePressEvent(QMouseEvent* pEvent); - void MiddleButtonMousePressEvent(QMouseEvent* pEvent); - void RightButtonMousePressEvent(QMouseEvent* pEvent); - - void SelectInRect(const QRect& rect); - - void ContentChanged(); - void DeleteMarkedKeys(); - - std::pair HitDetectCurve(const QPoint point); - std::pair HitDetectKey(const QPoint point); - std::tuple HitDetectHandle(const QPoint point); - Vec2 ClosestPointOnCurve(const Vec2 point, const SCurveEditorCurve& curve, const ECurveEditorCurveType curveType); - - void AddPointToCurve(Vec2 point, SCurveEditorCurve* pCurve); - void SortKeys(SCurveEditorCurve& curve); - - QRect GetCurveArea(); - - enum ETangent - { - ETangent_In, - ETangent_Out - }; - - void SetSelectedKeysTangentType(const ETangent tangent, const SBezierControlPoint::ETangentType type); - - SCurveEditorContent* m_pContent; - std::unique_ptr m_pMouseHandler; - - ECurveEditorCurveType m_curveType; - SAnimTime::EFrameRate m_frameRate; - bool m_bWeighted : 1; - bool m_bHandlesVisible : 1; - bool m_bRulerVisible : 1; - bool m_bTimeSliderVisible : 1; - bool m_bGridVisible : 1; - bool m_bSnapTime : 1; - bool m_bSnapKeys : 1; - - SAnimTime m_time; - Vec2 m_zoom; - Vec2 m_translation; - TRange m_timeRange; - Range m_valueRange; -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/DisplayViewportAdapter.cpp b/Code/Sandbox/Plugins/EditorCommon/DisplayViewportAdapter.cpp deleted file mode 100644 index 3d6a33fd6a..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/DisplayViewportAdapter.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "EditorCommon_precompiled.h" -//Cry -#include - -//Editor -#include -#include - -//Local -#include "QViewport.h" -#include "DisplayViewportAdapter.h" - -CDisplayViewportAdapter::CDisplayViewportAdapter(QViewport* viewport) - : m_viewport(viewport) -{ - m_screenMatrix.SetIdentity(); -} - -void CDisplayViewportAdapter::Update() -{ -} - -const Matrix34& CDisplayViewportAdapter::GetScreenTM() const -{ - return m_screenMatrix; -} - -float CDisplayViewportAdapter::GetScreenScaleFactor(const Vec3& position) const -{ - float dist = m_viewport->Camera()->GetPosition().GetDistance(position); - if (dist < m_viewport->Camera()->GetNearPlane()) - { - dist = m_viewport->Camera()->GetNearPlane(); - } - return dist; -} - -float CDisplayViewportAdapter::GetScreenScaleFactor([[maybe_unused]] const CCamera& camera, [[maybe_unused]] const Vec3& object_position) -{ - return 1; -} - -bool CDisplayViewportAdapter::HitTestLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& hitpoint, int pixelRadius, float* pToCameraDistance) const -{ - float dist = GetDistanceToLine(lineP1, lineP2, hitpoint); - if (dist <= pixelRadius) - { - if (pToCameraDistance) - { - Vec3 raySrc, rayDir; - ViewToWorldRay(hitpoint, raySrc, rayDir); - Vec3 rayTrg = raySrc + rayDir * 10000.0f; - - Vec3 pa, pb; - float mua, mub; - LineLineIntersect(lineP1, lineP2, raySrc, rayTrg, pa, pb, mua, mub); - *pToCameraDistance = mub; - } - - return true; - } - - return false; -} - -float CDisplayViewportAdapter::GetDistanceToLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& point) const -{ - QPoint p1 = WorldToView(lineP1); - QPoint p2 = WorldToView(lineP2); - - return PointToLineDistance2D( - Vec3(float(p1.x()), float(p1.y()), 0), - Vec3(float(p2.x()), float(p2.y()), 0), - Vec3(float(point.x()), float(point.y()), 0)); -} - -CBaseObjectsCache* CDisplayViewportAdapter::GetVisibleObjectsCache() -{ - return 0; -} - -bool CDisplayViewportAdapter::IsBoundsVisible([[maybe_unused]] const AABB& box) const -{ - return false; -} - -void CDisplayViewportAdapter::GetPerpendicularAxis(EAxis* axis, bool* is2D) const -{ - *axis = AXIS_NONE; - *is2D = false; -} - -const Matrix34& CDisplayViewportAdapter::GetViewTM() const -{ - m_viewMatrix = m_viewport->Camera()->GetViewMatrix(); - return m_viewMatrix; -} - -QPoint CDisplayViewportAdapter::WorldToView(const Vec3& worldPoint) const -{ - return m_viewport->ProjectToScreen(worldPoint); -} - -QPoint CDisplayViewportAdapter::WorldToViewParticleEditor(const Vec3& worldPoint, [[maybe_unused]] int width, [[maybe_unused]] int height) const -{ - return m_viewport->ProjectToScreen(worldPoint); -} - -Vec3 CDisplayViewportAdapter::WorldToView3D([[maybe_unused]] const Vec3& worldPoint, [[maybe_unused]] int flags) const -{ - return Vec3(0.0f, 0.0f, 0.0f); -} - -Vec3 CDisplayViewportAdapter::ViewToWorld([[maybe_unused]] const QPoint& vp, [[maybe_unused]] bool* collideWithTerrain, [[maybe_unused]] bool onlyTerrain, [[maybe_unused]] bool bSkipVegetation, [[maybe_unused]] bool bTestRenderMesh, [[maybe_unused]] bool* collideWithObject) const -{ - return Vec3(0.0f, 0.0f, 0.0f); -} - -void CDisplayViewportAdapter::ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const -{ - Ray ray; - // this can fail for number of reasons - if (!m_viewport->ScreenToWorldRay(&ray, vp.x(), vp.y())) - { - // return some "safe" default that will not cause FPE - raySrc = m_viewport->Camera()->GetPosition(); - rayDir = m_viewport->Camera()->GetViewdir(); - - // the interface should be changed to accommodate for error - return; - } - raySrc = ray.origin; - rayDir = ray.direction; -} - -float CDisplayViewportAdapter::GetGridStep() const -{ - return 1.0f; -} - -float CDisplayViewportAdapter::GetAspectRatio() const -{ - int w, h; - GetDimensions(&w, &h); - if (h != 0) - { - return float(w) / h; - } - else - { - return 1.0f; - } -} - -const Plane* CDisplayViewportAdapter::GetConstructionPlane() const -{ - return 0; -} - -void CDisplayViewportAdapter::ScreenToClient([[maybe_unused]] QPoint& pt) const -{ -} - -void CDisplayViewportAdapter::GetDimensions(int* width, int* height) const -{ - if (width) - { - *width = m_viewport->Width(); - } - if (height) - { - *height = m_viewport->Height(); - } -} - -void CDisplayViewportAdapter::setRay([[maybe_unused]] QPoint& vp, [[maybe_unused]] Vec3& raySrc, [[maybe_unused]] Vec3& rayDir) -{ -} - -void CDisplayViewportAdapter::setHitcontext([[maybe_unused]] QPoint& vp, [[maybe_unused]] Vec3& raySrc, [[maybe_unused]] Vec3& rayDir) -{ -} diff --git a/Code/Sandbox/Plugins/EditorCommon/DisplayViewportAdapter.h b/Code/Sandbox/Plugins/EditorCommon/DisplayViewportAdapter.h deleted file mode 100644 index 9b1d8bc27b..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/DisplayViewportAdapter.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -//Cry -#include -#include "Cry_Matrix34.h" -#include "Cry_Vector3.h" - -//Editor -#include "Include/IDisplayViewport.h" - -//Local -#include "EditorCommonAPI.h" - -class EDITOR_COMMON_API QViewport; - -AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING -class EDITOR_COMMON_API CDisplayViewportAdapter - : public ::IDisplayViewport -{ -public: -AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING - CDisplayViewportAdapter(QViewport* viewport); - - void Update() override; - const Matrix34& GetScreenTM() const override; - float GetScreenScaleFactor(const Vec3& position) const override; - float GetScreenScaleFactor(const CCamera& camera, const Vec3& object_position) override; - bool HitTestLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& hitpoint, int pixelRadius, float* pToCameraDistance = 0) const override; - float GetDistanceToLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& point) const override; - CBaseObjectsCache* GetVisibleObjectsCache() override; - bool IsBoundsVisible(const AABB& box) const override; - void GetPerpendicularAxis(EAxis* axis, bool* is2D) const override; - const Matrix34& GetViewTM() const override; - QPoint WorldToView(const Vec3& worldPoint) const override; - QPoint WorldToViewParticleEditor(const Vec3& worldPoint, int width, int height) const override; - Vec3 WorldToView3D(const Vec3& worldPoint, int flags = 0) const override; - Vec3 ViewToWorld(const QPoint& vp, bool* collideWithTerrain = nullptr, bool onlyTerrain = false, bool bSkipVegetation = false, bool bTestRenderMesh = false, bool* collideWithObject = nullptr) const override; - void ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const override; - float GetGridStep() const override; - float GetAspectRatio() const override; - const Plane* GetConstructionPlane() const override; - void ScreenToClient(QPoint& pt) const override; - void GetDimensions(int* width, int* height) const override; - void setRay(QPoint& vp, Vec3& raySrc, Vec3& rayDir) override; - void setHitcontext(QPoint& vp, Vec3& raySrc, Vec3& rayDir) override; - -private: - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - mutable Matrix34 m_viewMatrix; - Matrix34 m_screenMatrix; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - QViewport* m_viewport; -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/DockTitleBarWidget.cpp b/Code/Sandbox/Plugins/EditorCommon/DockTitleBarWidget.cpp index e7de4904d1..06b3c29104 100644 --- a/Code/Sandbox/Plugins/EditorCommon/DockTitleBarWidget.cpp +++ b/Code/Sandbox/Plugins/EditorCommon/DockTitleBarWidget.cpp @@ -16,13 +16,16 @@ #include #include -static QColor Interpolate(const QColor& a, const QColor& b, float k) +namespace DockTitleBarInterpolate { - float mk = 1.0f - k; - return QColor(aznumeric_cast(a.red() * mk + b.red() * k), - aznumeric_cast(a.green() * mk + b.green() * k), - aznumeric_cast(a.blue() * mk + b.blue() * k), - aznumeric_cast(a.alpha() * mk + b.alpha() * k)); + static QColor Interpolate(const QColor& a, const QColor& b, float k) + { + float mk = 1.0f - k; + return QColor(aznumeric_cast(a.red() * mk + b.red() * k), + aznumeric_cast(a.green() * mk + b.green() * k), + aznumeric_cast(a.blue() * mk + b.blue() * k), + aznumeric_cast(a.alpha() * mk + b.alpha() * k)); + } } class CDockWidgetTitleButton @@ -60,7 +63,7 @@ public: p.setRenderHint(QPainter::Antialiasing, true); QRect r = rect().adjusted(2, 2, -3, -3); p.translate(0.5f, 0.5f); - QColor color = Interpolate(palette().color(QPalette::Window), palette().color(QPalette::Shadow), 0.2f); + QColor color = DockTitleBarInterpolate::Interpolate(palette().color(QPalette::Window), palette().color(QPalette::Shadow), 0.2f); p.setBrush(QBrush(color)); p.setPen(Qt::NoPen); p.drawRoundedRect(r, 4, 4, Qt::AbsoluteSize); diff --git a/Code/Sandbox/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp b/Code/Sandbox/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp index 18439e3aa4..6a070b364b 100644 --- a/Code/Sandbox/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp +++ b/Code/Sandbox/Plugins/EditorCommon/DrawingPrimitives/Ruler.cpp @@ -101,7 +101,7 @@ namespace DrawingPrimitives void DrawTicks(const std::vector& ticks, QPainter& painter, const QPalette& palette, const STickOptions& options) { - QColor midDark = Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f); + QColor midDark = DrawingPrimitives::Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f); painter.setPen(QPen(midDark)); const int height = options.m_rect.height(); @@ -149,13 +149,13 @@ namespace DrawingPrimitives painter.fillRect(shadowRect, upperBrush); } - painter.fillRect(options.m_rect, Interpolate(palette.color(QPalette::Button), palette.color(QPalette::Midlight), 0.25f)); + painter.fillRect(options.m_rect, DrawingPrimitives::Interpolate(palette.color(QPalette::Button), palette.color(QPalette::Midlight), 0.25f)); if (options.m_drawBackgroundCallback) { options.m_drawBackgroundCallback(); } - QColor midDark = Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f); + QColor midDark = DrawingPrimitives::Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f); painter.setPen(QPen(midDark)); QFont font; diff --git a/Code/Sandbox/Plugins/EditorCommon/EditorCommon.qrc b/Code/Sandbox/Plugins/EditorCommon/EditorCommon.qrc deleted file mode 100644 index c9dc7c4283..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/EditorCommon.qrc +++ /dev/null @@ -1,15 +0,0 @@ - - - Icons/CurveEditor/auto.png - Icons/CurveEditor/fit_horizontal.png - Icons/CurveEditor/fit_vertical.png - Icons/CurveEditor/linear_in.png - Icons/CurveEditor/linear_out.png - Icons/CurveEditor/step_in.png - Icons/CurveEditor/step_out.png - Icons/CurveEditor/zero_in.png - Icons/CurveEditor/zero_out.png - Icons/CurveEditor/break.png - Icons/CurveEditor/unify.png - - diff --git a/Code/Sandbox/Plugins/EditorCommon/Events/EventManager.cpp b/Code/Sandbox/Plugins/EditorCommon/Events/EventManager.cpp deleted file mode 100644 index 793cd119f0..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Events/EventManager.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "EventManager.h" -#include "Serialization/JSONIArchive.h" -#include "Serialization/JSONOArchive.h" - -CEventManager* CEventManager::ms_pEventManager; - -CEventManager::CEventManager() - : m_nextAddress(0) - , m_nextHandlerId(0) -{ - if (ms_pEventManager) - { - CryFatalError("There should be only one event manager instance"); - } - - ms_pEventManager = this; -} - -void CEventManager::Init([[maybe_unused]] SSystemGlobalEnvironment* env) -{ -} - -CEventManager* CEventManager::GetInstance() -{ - return ms_pEventManager; -} - -uint CEventManager::GetAddressId(const char* name) -{ - auto findIter = m_nameToAddressMap.find(name); - if (findIter != m_nameToAddressMap.end()) - { - return findIter->second; - } - - uint newId = m_nextAddress++; - m_nameToAddressMap[name] = newId; - return newId; -} - -uint CEventManager::GetUniqueAddressId() -{ - return m_nextAddress++; -} - -void CEventManager::SendEventRaw(const uint address, const char* eventName, const char* message) const -{ - SendEventImplementation(address, eventName, message, DynArray()); -} - -void CEventManager::SendEventRaw(const uint address, const char* eventName, const char* message, const DynArray& excludedHandlers) const -{ - SendEventImplementation(address, eventName, message, excludedHandlers); -} - -void CEventManager::SendEventImplementation(const uint address, const string& eventName, const string& message, const DynArray& excludedHandlers) const -{ - auto handlerFindIter = m_messageRoutingMap.find(std::make_pair(address, eventName)); - if (handlerFindIter != m_messageRoutingMap.end()) - { - const std::vector >& handlers = handlerFindIter->second; - - for (uint i = 0; i < handlers.size(); ++i) - { - if (!stl::find(excludedHandlers, handlers[i].first)) - { - handlers[i].second(message); - } - } - } -} - -bool CEventManager::CanDeliverRaw(const uint address, const char* eventName) const -{ - auto handlerFindIter = m_messageRoutingMap.find(std::make_pair(address, eventName)); - if (handlerFindIter != m_messageRoutingMap.end()) - { - const std::vector >& handlers = handlerFindIter->second; - return !handlers.empty(); - } - - return false; -} - -CEventConnection CEventManager::AddEventCallbackRaw(const uint address, const char* eventName, TEventHandlerFunc callback) -{ - const uint handlerId = m_nextHandlerId++; - m_messageRoutingMap[std::make_pair(address, eventName)].push_back(std::make_pair(handlerId, callback)); - return CEventConnection(address, eventName, handlerId); -} - -string CEventManager::SerializeMessageToJSON(const Serialization::SStruct& ref) const -{ - Serialization::JSONOArchive oArchive; - oArchive(ref); - return oArchive.buffer(); -} - -void CEventManager::DeserializeFromJSON(const Serialization::SStruct& ref, const string& json) -{ - Serialization::JSONIArchive iArchive; - if (iArchive.open(json.data(), json.size())) - { - iArchive(ref); - } -} - -void CEventConnection::Disconnect() -{ - if (m_bConnected) - { - auto& messageMap = CEventManager::GetInstance()->m_messageRoutingMap; - auto findIter = messageMap.find(std::make_pair(m_address, m_eventName)); - - if (findIter != messageMap.end()) - { - stl::find_and_erase_if(findIter->second, [=](const std::pair& h) - { - return h.first == m_handlerId; - }); - } - - if (findIter->second.empty()) - { - messageMap.erase(findIter); - } - - Reset(); - } -} diff --git a/Code/Sandbox/Plugins/EditorCommon/Events/EventManager.h b/Code/Sandbox/Plugins/EditorCommon/Events/EventManager.h deleted file mode 100644 index ad35d4e0e8..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Events/EventManager.h +++ /dev/null @@ -1,204 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_EVENTS_EVENTMANAGER_H -#define CRYINCLUDE_EDITORCOMMON_EVENTS_EVENTMANAGER_H -#pragma once - - -#include "platform.h" - -#include "EditorCommonAPI.h" -#include "IEditor.h" - -#include "Serialization/IArchive.h" - -struct SSystemGlobalEnvironment; - -class CEventConnection -{ - friend class CEventManager; - friend class CScopedEventConnection; - -public: - CEventConnection() - : m_bConnected(false) {} - - EDITOR_COMMON_API void Disconnect(); - - uint GetHandlerId() const { return m_handlerId; } - -private: - CEventConnection(const uint address, const string& eventName, const uint handlerId) - : m_address(address) - , m_eventName(eventName) - , m_handlerId(handlerId) - , m_bConnected(true) {} - - void Reset() - { - m_bConnected = false; - m_address = 0; - m_handlerId = 0; - m_eventName.clear(); - } - - void Move(CEventConnection& other) - { - m_bConnected = other.m_bConnected; - m_address = other.m_address; - m_handlerId = other.m_handlerId; - m_eventName.swap(other.m_eventName); - other.Reset(); - } - - bool m_bConnected; - uint m_address; - uint m_handlerId; - string m_eventName; -}; - -class CScopedEventConnection - : public CEventConnection -{ -public: - CScopedEventConnection() - : CEventConnection() {} - - CScopedEventConnection(CScopedEventConnection&& connection) - { - Move(connection); - } - - CScopedEventConnection(CEventConnection&& connection) - { - Move(connection); - } - - CScopedEventConnection& operator =(CEventConnection&& connection) - { - if (&connection != this) - { - Disconnect(); - Move(connection); - } - return *this; - } - - ~CScopedEventConnection() { Disconnect(); } - -private: - CScopedEventConnection(const CScopedEventConnection&); // no implementation - CScopedEventConnection& operator =(const CScopedEventConnection&); // no implementation -}; - -class EDITOR_COMMON_API CEventManager -{ - friend class CEventConnection; - -public: - CEventManager(); - - static CEventManager* GetInstance(); - - void Init(SSystemGlobalEnvironment* pEnv); - - // Registers an address and returns its ID. Multiple event handlers can listen to the same address, allowing broadcasts. - uint GetAddressId(const char* name); - - // Registers a new unique address - uint GetUniqueAddressId(); - -public: - - // Sends an event to an address - // - // TMessageType must be a serializable struct - // - template - void SendEvent(const uint address, const TMessageType& message) - { - const string json = SerializeMessageToJSON(Serialization::SStruct(message)); - SendEventRaw(address, TMessageType::GetName(), json); - } - - template - void SendEvent(const uint address, const TMessageType& message, const DynArray& excludedHandlers) const - { - const string json = SerializeMessageToJSON(Serialization::SStruct(message)); - SendEventRaw(address, TMessageType::GetName(), json, excludedHandlers); - } - - // For sending a raw JSON message. - void SendEventRaw(const uint address, const char* eventName, const char* message) const; - void SendEventRaw(const uint address, const char* eventName, const char* message, const DynArray& excludedHandlers) const; - - // Tests if a call to SendEvent would actually send a message (there is someone listening to this message) - bool CanDeliverRaw(const uint address, const char* eventName) const; - template - bool CanDeliver(const uint address) const - { - const char* pEventName = TMessageType::GetName(); - return CanDeliverRaw(address, pEventName); - } - - // This should be the most common way to add an event callback - // - // This example will install an event handler for OnEvent(const SMessageType &message) that is sent to a specific address: - // CEventManager::GetInstance()->AddEventCallback(componentId, this, &CEventHandler::OnEvent); - // - // TMessageType must be a serializable struct - // - // Returns a CEventConnection. The callback is removed when this object is destroyed. - // - template - CEventConnection AddEventCallback(const uint address, TClassType* pThis, void (TClassType::* pMethod)(const TMessageType&)) - { - return AddEventCallback(address, std::bind(pMethod, pThis, std::placeholders::_1)); - } - - // Same as above, but you can pass in any function object that takes TMessageType& as an argument directly. - // - template - CEventConnection AddEventCallback(const uint address, std::function callback) - { - return AddEventCallbackRaw(address, TMessageType::GetName(), [=](const string& json) - { - TMessageType message; - DeserializeFromJSON(Serialization::SStruct(message), json); - callback(message); - }); - } - - // This can be used if raw parsing of JSON is preferred. - typedef std::function TEventHandlerFunc; - CEventConnection AddEventCallbackRaw(const uint componentId, const char* eventName, TEventHandlerFunc callback); - -private: - void SendEventImplementation(const uint address, const string& eventName, const string& message, const DynArray& excludedHandlers) const; - - string SerializeMessageToJSON(const Serialization::SStruct& ref) const; - void DeserializeFromJSON(const Serialization::SStruct& ref, const string& json); - - uint m_nextAddress; - uint m_nextHandlerId; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - std::map > m_nameToAddressMap; - std::map, std::vector > > m_messageRoutingMap; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - static CEventManager* ms_pEventManager; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_EVENTS_EVENTMANAGER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/ListSelectionDialog.cpp b/Code/Sandbox/Plugins/EditorCommon/ListSelectionDialog.cpp deleted file mode 100644 index 13c0bf5d50..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/ListSelectionDialog.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "Serialization/ClassFactory.h" -#include "Serialization/Pointers.h" -#include "Serialization/IArchive.h" -#include "ListSelectionDialog.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "IResourceSelectorHost.h" - -#include "DeepFilterProxyModel.h" - -// --------------------------------------------------------------------------- - -ListSelectionDialog::ListSelectionDialog(QWidget* parent) - : QDialog(parent) - , m_currentColumn(0) -{ - setWindowTitle("Choose..."); - setWindowModality(Qt::ApplicationModal); - - QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom); - setLayout(layout); - - QBoxLayout* filterBox = new QBoxLayout(QBoxLayout::LeftToRight); - layout->addLayout(filterBox); - { - filterBox->addWidget(new QLabel("Filter:", this), 0); - filterBox->addWidget(m_filterEdit = new QLineEdit(this), 1); - connect(m_filterEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onFilterChanged(const QString&))); - m_filterEdit->installEventFilter(this); - } - - QBoxLayout* infoBox = new QBoxLayout(QBoxLayout::LeftToRight); - layout->addLayout(infoBox); - - m_model = new QStandardItemModel(); - m_model->setColumnCount(1); - m_model->setHeaderData(0, Qt::Horizontal, "Name", Qt::DisplayRole); - - m_filterModel = new DeepFilterProxyModel(this); - m_filterModel->setSourceModel(m_model); - m_filterModel->setDynamicSortFilter(true); - - m_tree = new QTreeView(this); - //m_tree->setColumnCount(3); - m_tree->setModel(m_filterModel); - - m_tree->header()->setStretchLastSection(false); -#if QT_VERSION >= 0x50000 - m_tree->header()->setSectionResizeMode(0, QHeaderView::Stretch); -#else - m_tree->header()->setResizeMode(0, QHeaderView::Stretch); -#endif - //m_tree->header()->resizeSection(0, 80); - connect(m_tree, SIGNAL(activated(const QModelIndex&)), this, SLOT(onActivated(const QModelIndex&))); - - layout->addWidget(m_tree, 1); - - QDialogButtonBox* buttons = new QDialogButtonBox(this); - buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttons, SIGNAL(rejected()), this, SLOT(reject())); - layout->addWidget(buttons, 0); -} - -bool ListSelectionDialog::eventFilter(QObject* obj, QEvent* event) -{ - if (obj == m_filterEdit && event->type() == QEvent::KeyPress) - { - QKeyEvent* keyEvent = (QKeyEvent*)event; - if (keyEvent->key() == Qt::Key_Down || - keyEvent->key() == Qt::Key_Up || - keyEvent->key() == Qt::Key_PageDown || - keyEvent->key() == Qt::Key_PageUp) - { - QCoreApplication::sendEvent(m_tree, event); - return true; - } - } - return QDialog::eventFilter(obj, event); -} - -void ListSelectionDialog::onFilterChanged(const QString& str) -{ - m_filterModel->setFilterString(str); - m_filterModel->invalidate(); - m_tree->expandAll(); - - QModelIndex currentSource = m_filterModel->mapToSource(m_tree->selectionModel()->currentIndex()); - if (!currentSource.isValid() || !m_filterModel->matchFilter(currentSource.row(), currentSource.parent())) - { - QModelIndex firstMatchingIndex = m_filterModel->findFirstMatchingIndex(QModelIndex()); - if (firstMatchingIndex.isValid()) - { - m_tree->selectionModel()->setCurrentIndex(firstMatchingIndex, QItemSelectionModel::SelectCurrent); - } - } -} - -void ListSelectionDialog::onActivated(const QModelIndex& index) -{ - m_tree->setCurrentIndex(index); - accept(); -} - -QSize ListSelectionDialog::sizeHint() const -{ - return QSize(600, 900); -} - -void ListSelectionDialog::SetColumnText(int column, const char* text) -{ - if (column >= m_model->columnCount()) - { - int oldColumnCount = m_model->columnCount(); - m_model->setColumnCount(column + 1); - for (int i = oldColumnCount; i <= column; ++i) - { -#if QT_VERSION >= 0x50000 - m_tree->header()->setSectionResizeMode(i, QHeaderView::Interactive); - #else - m_tree->header()->setResizeMode(i, QHeaderView::Interactive); - #endif - m_tree->header()->resizeSection(i, 40); - } - } - m_model->setHeaderData(column, Qt::Horizontal, text, Qt::DisplayRole); -} - -void ListSelectionDialog::SetColumnWidth(int column, int width) -{ - if (column >= m_model->columnCount()) - { - return; - } - m_tree->header()->resizeSection(column, width); -} - - -void ListSelectionDialog::AddRow(const char* name) -{ - AddRow(name, QIcon()); -} - -void ListSelectionDialog::AddRow(const char* name, const QIcon& icon) -{ - QStandardItem* item = new QStandardItem(name); - item->setEditable(false); - item->setData(name); - item->setIcon(icon); - - QList items; - items.append(item); - - m_model->appendRow(items); - m_currentColumn = 1; - m_firstColumnToItem[name] = item; -} - -void ListSelectionDialog::AddRowColumn(const char* text) -{ - int itemCount = m_model->rowCount(QModelIndex()); - if (itemCount == 0) - { - return; - } - - QStandardItem* item = new QStandardItem(); - item->setText(QString::fromLocal8Bit(text)); - if (QStandardItem* lastItem = m_model->item(itemCount - 1, 0)) - { - item->setData(lastItem->data()); - } - item->setEditable(false); - m_model->setItem(itemCount - 1, m_currentColumn, item); - ++m_currentColumn; -} - -QString ListSelectionDialog::ChooseItem(const QString& currentValue) -{ - m_tree->expandAll(); - - if (exec() == QDialog::Accepted && m_tree->selectionModel()->currentIndex().isValid()) - { - QModelIndex currentIndex = m_tree->selectionModel()->currentIndex(); - QModelIndex sourceCurrentIndex = m_filterModel->mapToSource(currentIndex); - QStandardItem* item = m_model->itemFromIndex(sourceCurrentIndex); - if (item) - { - m_chosenItem = item->data().toString().toUtf8(); - return m_chosenItem.constData(); - } - } - return currentValue; -} - -// --------------------------------------------------------------------------- - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/ListSelectionDialog.h b/Code/Sandbox/Plugins/EditorCommon/ListSelectionDialog.h deleted file mode 100644 index 5a21d92b5d..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/ListSelectionDialog.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_LISTSELECTIONDIALOG_H -#define CRYINCLUDE_EDITORCOMMON_LISTSELECTIONDIALOG_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "EditorCommonAPI.h" -#include -#include -#endif - -class DeepFilterProxyModel; -class QLineEdit; -class QModelIndex; -class QStandardItemModel; -class QStandardItem; -class QString; -class QTreeView; -class QWidget; -class QByteArray; - -class EDITOR_COMMON_API ListSelectionDialog - : public QDialog -{ - Q_OBJECT - -public: - ListSelectionDialog(QWidget* parent); - void SetColumnText(int column, const char* text); - void SetColumnWidth(int column, int width); - - void AddRow(const char* firstColumnValue); - void AddRow(const char* firstColumnValue, const QIcon& icon); - void AddRowColumn(const char* value); - - QString ChooseItem(const QString& currentValue); - - QSize sizeHint() const override; - -protected slots: - void onActivated(const QModelIndex& index); - void onFilterChanged(const QString&); - -protected: - bool eventFilter(QObject* obj, QEvent* event); - -private: - QTreeView* m_tree; - QStandardItemModel* m_model; - DeepFilterProxyModel* m_filterModel; - typedef QMap StringToItem; - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - StringToItem m_firstColumnToItem; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - QLineEdit* m_filterEdit; - QByteArray m_chosenItem; - int m_currentColumn; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_LISTSELECTIONDIALOG_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Platform/Common/UnixLike/QPropertyTree/Unicode_UnixLike.cpp b/Code/Sandbox/Plugins/EditorCommon/Platform/Common/UnixLike/QPropertyTree/Unicode_UnixLike.cpp deleted file mode 100644 index 89ab3276f9..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Platform/Common/UnixLike/QPropertyTree/Unicode_UnixLike.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates - -#include - -#include -#include - -string fromWideChar(const wchar_t* wstr) -{ - return QString::fromWCharArray(wstr).toUtf8().data(); -} - -wstring toWideChar(const char* str) -{ - QString s = QString::fromUtf8(str); - - std::vector result(s.size()+1); - s.toWCharArray(&result[0]); - return &result[0]; -} - diff --git a/Code/Sandbox/Plugins/EditorCommon/Platform/Linux/platform_linux_files.cmake b/Code/Sandbox/Plugins/EditorCommon/Platform/Linux/platform_linux_files.cmake deleted file mode 100644 index 5bfcbe55a6..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Platform/Linux/platform_linux_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../Common/UnixLike/QPropertyTree/Unicode_UnixLike.cpp -) diff --git a/Code/Sandbox/Plugins/EditorCommon/Platform/Mac/platform_mac_files.cmake b/Code/Sandbox/Plugins/EditorCommon/Platform/Mac/platform_mac_files.cmake deleted file mode 100644 index 5bfcbe55a6..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Platform/Mac/platform_mac_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../Common/UnixLike/QPropertyTree/Unicode_UnixLike.cpp -) diff --git a/Code/Sandbox/Plugins/EditorCommon/Platform/Windows/QPropertyTree/Unicode_Windows.cpp b/Code/Sandbox/Plugins/EditorCommon/Platform/Windows/QPropertyTree/Unicode_Windows.cpp deleted file mode 100644 index a8bd6b92ed..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Platform/Windows/QPropertyTree/Unicode_Windows.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates - -#include - -#include - -string fromWideChar(const wchar_t* wstr) -{ - // We have different implementation for windows as Qt for windows - // is built with wchar_t of diferent size (4 bytes, as on linux). - // Therefore we avoid calling any wchar_t functions in Qt. - const unsigned int codepage = CP_UTF8; - int len = WideCharToMultiByte(codepage, 0, wstr, -1, NULL, 0, 0, 0); - char* buf = (char*)alloca(len); - if (len > 1) { - WideCharToMultiByte(codepage, 0, wstr, -1, buf, len, 0, 0); - return string(buf, len - 1); - } - return string(); -} - -wstring toWideChar(const char* str) -{ - const unsigned int codepage = CP_UTF8; - int len = MultiByteToWideChar(codepage, 0, str, -1, NULL, 0); - wchar_t* buf = (wchar_t*)alloca(len * sizeof(wchar_t)); - if (len > 1) { - MultiByteToWideChar(codepage, 0, str, -1, buf, len); - return wstring(buf, len - 1); - } - return wstring(); -} - diff --git a/Code/Sandbox/Plugins/EditorCommon/Platform/Windows/platform_windows_files.cmake b/Code/Sandbox/Plugins/EditorCommon/Platform/Windows/platform_windows_files.cmake deleted file mode 100644 index 4c6a5b0644..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Platform/Windows/platform_windows_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - QPropertyTree/Unicode_Windows.cpp -) diff --git a/Code/Sandbox/Plugins/EditorCommon/QAbstractQVariantTreeDataModel.cpp b/Code/Sandbox/Plugins/EditorCommon/QAbstractQVariantTreeDataModel.cpp deleted file mode 100644 index d7ccd1d8e5..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QAbstractQVariantTreeDataModel.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include - - -QAbstractQVariantTreeDataModel::Item* QAbstractQVariantTreeDataModel::itemFromIndex(const QModelIndex& index) const -{ - if (index.isValid()) - { - return (Item*)index.internalPointer(); - } - return m_root.get(); -} - -QModelIndex QAbstractQVariantTreeDataModel::indexFromItem(QAbstractQVariantTreeDataModel::Item* item, int col /*= 0*/) const -{ - if (0 == item) - { - return QModelIndex(); - } - if (!item->m_parent || !item->m_parent->asFolder()) - { - return QModelIndex(); - } - int row = item->m_parent->asFolder()->row(item); - return createIndex(row, col, item); -} - -QModelIndex QAbstractQVariantTreeDataModel::index(int row, int column, const QModelIndex& parent /*= QModelIndex()*/) const -{ - Item* parentItem = itemFromIndex(parent); - if (parentItem && parentItem->asFolder() && row < parentItem->asFolder()->m_children.size()) - { - Item* item = parentItem->asFolder()->m_children[row].get(); - return createIndex(row, column, item); - } - return QModelIndex(); -} - -QModelIndex QAbstractQVariantTreeDataModel::parent(const QModelIndex& child) const -{ - Item* item = itemFromIndex(child); - return item && item->m_parent && item->m_parent->asFolder() ? indexFromItem(item->m_parent) : QModelIndex(); -} - -bool QAbstractQVariantTreeDataModel::hasChildren(const QModelIndex& parent /* = QModelIndex() */) const -{ - Item* item = itemFromIndex(parent); - return item && item->asFolder() && item->asFolder()->m_children.size(); -} - -int QAbstractQVariantTreeDataModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const -{ - Item* item = itemFromIndex(parent); - int res = 0; - if (item && item->asFolder()) - { - res = (int) item->asFolder()->m_children.size(); - } - return res; -} - -int QAbstractQVariantTreeDataModel::columnCount([[maybe_unused]] const QModelIndex& parent /*= QModelIndex()*/) const -{ - return 1; -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QAbstractQVariantTreeDataModel.h b/Code/Sandbox/Plugins/EditorCommon/QAbstractQVariantTreeDataModel.h deleted file mode 100644 index bdc8979c27..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QAbstractQVariantTreeDataModel.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef QABSTRACTQVARIANTTREEDATAMODEL_H -#define QABSTRACTQVARIANTTREEDATAMODEL_H - -#include -#include -#include - -#include "EditorCommonAPI.h" - - -class EDITOR_COMMON_API QAbstractQVariantTreeDataModel - : public QAbstractItemModel -{ -public: - QAbstractQVariantTreeDataModel(QObject* parent) - : QAbstractItemModel(parent) { } - - QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex& child) const override; - bool hasChildren(const QModelIndex& parent = QModelIndex()) const override; - - int rowCount(const QModelIndex& parent = QModelIndex()) const override; - int columnCount(const QModelIndex& parent = QModelIndex()) const override; - -protected: - struct Folder; - - struct Item - { - Item() - : m_parent(0) { } - - QMap m_data; - Folder* m_parent; - - virtual ~Item() = default; - virtual const Folder* asFolder() const { return 0; } // need this as we don't have RTTI - }; - - struct Folder - : public Item - { - Folder(const QString& name) - { - m_data.insert(Qt::DisplayRole, name); - } - std::vector < std::shared_ptr > m_children; - const Folder* asFolder() const override { return this; } // need this as we don't have RTTI - - int row(Item* item) const - { - for (int i = 0; i < m_children.size(); ++i) - { - if (m_children[i].get() == item) - { - return i; - } - } - return -1; - } - void addChild(std::shared_ptr item) - { - item->m_parent = this; - m_children.push_back(item); - } - }; - - Item* itemFromIndex(const QModelIndex& index) const; - QModelIndex indexFromItem(Item* item, int col = 0) const; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - std::shared_ptr m_root; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -}; - -#endif // QABSTRACTQVARIANTTREEDATAMODEL_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QParentWndWidget.cpp b/Code/Sandbox/Plugins/EditorCommon/QParentWndWidget.cpp deleted file mode 100644 index f0bbf572df..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QParentWndWidget.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "QParentWndWidget.h" -#include -#include -#include -#include - -#include "QParentWndWidget.h" - -#include - -#if QT_VERSION >= 0x050000 -#include -#endif -static HWND FindTopmostWindow(HWND child, bool considerWsChild) -{ - if (child == GetDesktopWindow()) - { - return 0; - } - HWND current = child; - while (GetParent(current) != 0) - { - if (considerWsChild && (GetWindowLongW(current, GWL_STYLE) & WS_CHILD) == 0) - { - break; - } - current = GetParent(current); - } - - return current; -} - -QParentWndWidget::QParentWndWidget(HWND parent) - : m_parent(parent) - , m_previousFocus(0) - , m_modalityRoot(0) - , m_parentToCenterOn(0) -{ - if (m_parent) - { - SetWindowLongA((HWND)winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP); - -#if QT_VERSION >= 0x50000 - QWindow* window = windowHandle(); - window->setProperty("_q_embedded_native_parent_handle", (WId)m_parent); - SetParent((HWND)winId(), m_parent); - window->setFlags(Qt::FramelessWindowHint); -#else - SetParent((HWND)winId(), m_parent); -#endif - QEvent e(QEvent::EmbeddingControl); - QApplication::sendEvent(this, &e); - } - - m_parentToCenterOn = FindTopmostWindow(m_parent, true); - m_modalityRoot = FindTopmostWindow(m_parent, false); -} - -void QParentWndWidget::childEvent(QChildEvent* ev) -{ - QObject* child = ev->child(); - if (child->isWidgetType()) - { - if (ev->added()) - { - if (child->isWidgetType()) - { - child->installEventFilter(this); - } - } - else if (ev->removed() && m_parentWasDisabled) - { - m_parentWasDisabled = false; - EnableWindow(m_modalityRoot, true); - child->removeEventFilter(this); - } - } - QWidget::childEvent(ev); -} - -void QParentWndWidget::show() -{ - if (!m_previousFocus) - { - m_previousFocus = ::GetFocus(); - } - if (!m_previousFocus) - { - m_previousFocus = parentWindow(); - } - - QWidget::show(); -} -void QParentWndWidget::hide() -{ - QWidget::hide(); -} - -void QParentWndWidget::center() -{ - const QWidget* child = findChild(); - - RECT rect; - GetWindowRect(m_parentToCenterOn, &rect); - setGeometry((rect.right - rect.left) / 2 + rect.left, - (rect.bottom - rect.top) / 2 + rect.top, 0, 0); -} - -#if QT_VERSION >= 0x50000 -bool QParentWndWidget::nativeEvent(const QByteArray&, void* message, long* result) -#else -bool QParentWndWidget::winEvent(MSG* msg, long* result) -#endif -{ -#if QT_VERSION >= 0x50000 - MSG* msg = (MSG*)message; -#endif - if (msg->message == WM_SETFOCUS) - { - Qt::FocusReason reason; - if (::GetKeyState(VK_LBUTTON) < 0 || - ::GetKeyState(VK_RBUTTON) < 0) - { - reason = Qt::MouseFocusReason; - } - else if (::GetKeyState(VK_SHIFT) < 0) - { - reason = Qt::BacktabFocusReason; - } - else - { - reason = Qt::TabFocusReason; - } - QFocusEvent ev(QEvent::FocusIn, reason); - QApplication::sendEvent(this, &ev); - } - if (msg->message == WM_GETDLGCODE) - { - *result = DLGC_WANTARROWS | DLGC_WANTTAB; - return(true); - } - - return false; -} - -bool QParentWndWidget::eventFilter(QObject* obj, QEvent* ev) -{ - QWidget* widget = (QWidget*)obj; - switch (ev->type()) - { - case QEvent::WindowDeactivate: - { - if (widget->isModal() && isHidden()) - { - BringWindowToTop(m_parent); - } - break; - } - case QEvent::Show: - { - if (widget->isWindow()) - { - if (!m_previousFocus) - { - m_previousFocus = ::GetFocus(); - } - if (!m_previousFocus) - { - m_previousFocus = parentWindow(); - } - hide(); - if (widget->isModal() && !m_parentWasDisabled) - { - EnableWindow(m_modalityRoot, false); - m_parentWasDisabled = true; - } - } - break; - } - case QEvent::Hide: - { - if (m_parentWasDisabled) - { - EnableWindow(m_modalityRoot, true); - m_parentWasDisabled = false; - } - if (m_previousFocus) - { - ::SetFocus(m_previousFocus); - } - else - { - ::SetFocus(parentWindow()); - } - if (widget->testAttribute(Qt::WA_DeleteOnClose) && widget->isWindow()) - { - deleteLater(); - } - break; - } - case QEvent::Close: - { - ::SetActiveWindow(m_parent); - if (widget->testAttribute(Qt::WA_DeleteOnClose)) - { - deleteLater(); - } - break; - } - default: - break; - } - ; - - return QWidget::eventFilter(obj, ev); -} - -void QParentWndWidget::focusInEvent(QFocusEvent* ev) -{ - QWidget* candidate = this; - - if (ev->reason() == Qt::TabFocusReason || ev->reason() == Qt::BacktabFocusReason) - { - while (candidate && (candidate->focusPolicy() & Qt::TabFocus) == 0) - { - candidate = candidate->nextInFocusChain(); - if (candidate == this) - { - candidate = 0; - } - } - if (candidate) - { - candidate->setFocus(ev->reason()); - candidate->setAttribute(Qt::WA_KeyboardFocusChange); - candidate->window()->setAttribute(Qt::WA_KeyboardFocusChange); - if (ev->reason() == Qt::BacktabFocusReason) - { - QWidget::focusNextPrevChild(false); - } - } - } -} - -bool QParentWndWidget::focusNextPrevChild(bool next) -{ - QWidget* current = focusWidget(); - if (next) - { - QWidget* nextFocus = current; - while (true) - { - nextFocus = nextFocus->nextInFocusChain(); - if (nextFocus->isWindow()) - { - break; - } - if (nextFocus->focusPolicy() & Qt::TabFocus) - { - return QWidget::focusNextPrevChild(true); - } - } - } - else - { - if (!current->isWindow()) - { - QWidget* nextFocus = current->nextInFocusChain(); - QWidget* prevFocus = 0; - QWidget* topLevel = 0; - while (nextFocus != current) - { - if ((nextFocus->focusPolicy() & Qt::TabFocus) != 0) - { - prevFocus = nextFocus; - topLevel = 0; - } - else if (nextFocus->isWindow()) - { - topLevel = nextFocus; - } - nextFocus = nextFocus->nextInFocusChain(); - } - - if (!topLevel) - { - return QWidget::focusNextPrevChild(false); - } - } - } - - ::SetFocus(m_parent); - return true; -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QParentWndWidget.h b/Code/Sandbox/Plugins/EditorCommon/QParentWndWidget.h deleted file mode 100644 index a608261b9b..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QParentWndWidget.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_QPARENTWNDWIDGET_H -#define CRYINCLUDE_EDITORCOMMON_QPARENTWNDWIDGET_H - -#if !defined(Q_MOC_RUN) -#include - -#include "EditorCommonAPI.h" -#endif - -// QParentWndWidget can be used to show Qt popup windows/dialogs on top on -// Win32/MFC windows. -// -// Example of usage: -// QParentWndWidget parent(parentHwnd); -// -// QDialog dialog(parent); -// dialog.exec(...); -class EDITOR_COMMON_API QParentWndWidget - : public QWidget -{ - Q_OBJECT -public: - QParentWndWidget(HWND parent); - - void show(); - void hide(); - void center(); - - HWND parentWindow() const { return m_parent; } - -protected: - void childEvent(QChildEvent* e) override; - void focusInEvent(QFocusEvent* ev) override; - bool focusNextPrevChild(bool next) override; - - bool eventFilter(QObject* o, QEvent* e) override; -#if QT_VERSION >= 0x50000 - bool nativeEvent(const QByteArray&, void* message, long*); -#else - bool winEvent(MSG* msg, long*); -#endif - -private: - HWND m_parent; - HWND m_parentToCenterOn; - HWND m_modalityRoot; - - HWND m_previousFocus; - - bool m_parentWasDisabled; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPARENTWNDWIDGET_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyCtrl.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyCtrl.h deleted file mode 100644 index 5cea9535a1..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyCtrl.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - - -#include "EditorCommonAPI.h" -#include "Controls/PropertyCtrl.h" -#include - -template -class TemplatePropertyCtrl - : public QWinHost -{ -public: - TemplatePropertyCtrl(QWidget* parent) - : QWinHost(parent) { } - - T m_props; -protected: - virtual HWND createWindow(HWND parent, HINSTANCE instance) - { - CWnd* parentWindow = CWnd::FromHandle(parent); - m_props.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 100, 100), parentWindow /*, IDC_GRAPH_PROPERTIES*/); - m_props.ModifyStyleEx(0, WS_EX_CLIENTEDGE); - m_props.SetParent(parentWindow); - return m_props.m_hWnd; - } -}; - -class QPropertyCtrl - : public TemplatePropertyCtrl -{ -public: - QPropertyCtrl(QWidget* parent) - : TemplatePropertyCtrl(parent) - { - } -}; - - diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Color.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Color.cpp deleted file mode 100644 index f8ce31ae66..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Color.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "Color.h" -#include "Serialization/IArchive.h" -#include -#include "MathUtils.h" - - -// HSV -// h=0..360, s=0..1, v=0..1 -inline void HSVtoRGB(float h,float s,float v, - float& r,float& g,float& b) -{ - const float min=1e-5f; - int i; - float f,m,n,k; - - if(s=360.0f) - h=0; - else - h=h/60.0f; - - i=xround(floor(h)); - f=h-i; - m=v*(1-s); - n=v*(1-s*f); - k=v*(1-s*(1-f)); - - switch(i){ - case 0: - r=v; g=k; b=m; - break; - case 1: - r=n; g=v; b=m; - break; - case 2: - r=m; g=v; b=k; - break; - case 3: - r=m; g=n; b=v; - break; - case 4: - r=k; g=m; b=v; - break; - case 5: - r=v; g=m; b=n; - break; - default: - YASLI_ASSERT(0); - } - } - - YASLI_ASSERT(r>=0 && r<=1); - YASLI_ASSERT(g>=0 && g<=1); - YASLI_ASSERT(b>=0 && b<=1); -} - -void Color::setHSV(float h,float s,float v, unsigned char alpha) -{ - float rf,gf,bf; - HSVtoRGB(h,s,v, rf,gf,bf); - r = xround(rf*255); - g = xround(gf*255); - b = xround(bf*255); - a = alpha; -} - - -void Color::toHSV(float& h,float& s,float& v) -{ - float rf = r/255.f; - float gf = g/255.f; - float bf = b/255.f; - v = max(max(rf,gf),bf); - float temp=min(min(rf,gf),bf); - if(v==0) - s=0; - else - s=(v-temp)/v; - - if(s==0) - h=0; - else { - float Cr=(v-rf)/(v-temp); - float Cg=(v-gf)/(v-temp); - float Cb=(v-bf)/(v-temp); - - if(rf==v) { - h=Cb-Cg; - } - else if(gf==v) { - h=2+Cr-Cb; - } - else if(bf==v) { - h=4+Cg-Cr; - } - - h=60*h; - if(h<0)h+=360; - } -} - -void Color::Serialize(Serialization::IArchive& ar) -{ - ar(r, "", "^R"); - ar(g, "", "^G"); - ar(b, "", "^B"); - ar(a, "", "^A"); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Color.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Color.h deleted file mode 100644 index 57c12d53dc..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Color.h +++ /dev/null @@ -1,66 +0,0 @@ -// Modifications copyright Amazon.com, Inc. or its affiliates. -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_COLOR_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_COLOR_H -#pragma once - - -namespace Serialization { - class IArchive; -} - -struct Color -{ - unsigned char b, g, r, a; - - Color() : r(255), g(255), b(255), a(255) { } - Color(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a = 255) { r=_r; g=_g; b=_b; a=_a; } - explicit Color(unsigned long _argb) { argb() = _argb; } - void set(int rc,int gc,int bc,int ac = 255) { r=rc; g=gc; b=bc; a=ac; } - - Color& setGDI(unsigned long color) { - b = (unsigned char)(color >> 16); - g = (unsigned char)(color >> 8); - r = (unsigned char)(color); - a = 255; - return *this; - } - - void setHSV(float h,float s,float v, unsigned char alpha = 255); - void toHSV(float& h,float& s, float& v); - - Color& operator*= (float f) { r=int(r*f); g=int(g*f); b=int(b*f); a=int(a*f); return *this; } - Color& operator+= (Color &p) { r+=p.r; g+=p.g; b+=p.b; a+=p.a; return *this; } - Color& operator-= (Color &p) { r-=p.r; g-=p.g; b-=p.b; a-=p.a; return *this; } - Color operator+ (Color &p) { return Color(r+p.r,g+p.g,b+p.b,a+p.a); } - Color operator- (Color &p) { return Color(r-p.r,g-p.g,b-p.b,a-p.a); } - Color operator* (float f) const { return Color(int(r*f), int(g*f), int(b*f), int(a*f)); } - Color operator* (int f) const { return Color(r*f,g*f,b*f,a*f); } - Color operator/ (int f) const { if(f!=0) f=(1<<16)/f; else f=1<<16; return Color((r*f)>>16,(g*f)>>16,(b*f)>>16,(a*f)>>16); } - - bool operator==(const Color& rhs) const { return argb() == rhs.argb(); } - bool operator!=(const Color& rhs) const { return argb() != rhs.argb(); } - - unsigned long argb() const { return *reinterpret_cast(this); } - unsigned long& argb() { return *reinterpret_cast(this); } - unsigned long rgb() const { return r | g << 8 | b << 16; } - unsigned long rgba() const { return r | g << 8 | b << 16 | a << 24; } - unsigned char& operator[](int i) { return ((unsigned char*)this)[i];} - Color interpolate(const Color &v, float f) const - { - return Color(int(r+int(v.r-r)*f), - int(g+int(v.g-g)*f), - int(b+int(v.b-b)*f), - int(a+(v.a-a)*f)); - } - void Serialize(Serialization::IArchive& ar); -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_COLOR_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ConstStringList.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ConstStringList.cpp deleted file mode 100644 index 15900bcbe4..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ConstStringList.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "ConstStringList.h" -#include -#include "Serialization/STL.h" -#include "Serialization/IArchive.h" -#include "Serialization/STLImpl.h" - -ConstStringList globalConstStringList; - -const char* ConstStringList::findOrAdd(const char* string) -{ - // TODO: try sorted vector of const char* - Strings::iterator it = std::find(strings_.begin(), strings_.end(), string); - if (it == strings_.end()) { - strings_.push_back(string); - return strings_.back().c_str(); - } - else { - return it->c_str(); - } -} - - -ConstStringWrapper::ConstStringWrapper(ConstStringList* list, const char*& string) - : list_(list ? list : &globalConstStringList) - , string_(string) -{ - YASLI_ASSERT(string_); -} - -using Serialization::string; - -bool Serialize(Serialization::IArchive& ar, ConstStringWrapper& val, const char* name, const char* label) -{ - if (ar.IsOutput()) { - YASLI_ASSERT(val.string_); - string out = val.string_; - return ar(out, name, label); - } - else { - string in; - bool result = ar(in, name, label); - - val.string_ = val.list_->findOrAdd(in.c_str()); - return result; - } -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ConstStringList.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ConstStringList.h deleted file mode 100644 index 709c85d6b4..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ConstStringList.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - // Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONSTSTRINGLIST_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONSTSTRINGLIST_H -#pragma once - - -#include -#include -#include "EditorCommonAPI.h" - -class ConstStringWrapper; - -namespace Serialization { class IArchive; } - -bool Serialize(Serialization::IArchive& ar, ConstStringWrapper &wrapper, const char* name, const char* label); - -class ConstStringList{ -public: - const char* findOrAdd(const char* string); -protected: - typedef std::list Strings; - Strings strings_; -}; - -class ConstStringWrapper { -public: - ConstStringWrapper(ConstStringList* list, const char*& string); -protected: - ConstStringList* list_; - const char*& string_; - friend bool ::Serialize(Serialization::IArchive& ar, ConstStringWrapper &wrapper, const char* name, const char* label); -}; - -extern ConstStringList globalConstStringList; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONSTSTRINGLIST_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ContextList.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ContextList.h deleted file mode 100644 index 47d8558a0b..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ContextList.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONTEXTLIST_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONTEXTLIST_H -#pragma once - -#include - -namespace Serialization -{ - class CContextList - { - public: - template - void Update(T* contextObject) - { - for (size_t i = 0; i < links_.size(); ++i) - { - if (links_[i]->type == TypeID::get()) - { - links_[i]->contextObject = (void*)contextObject; - return; - } - } - - SContextLink* newLink = new SContextLink; - newLink->type = TypeID::get(); - newLink->outer = links_.empty() ? connectedList_ : links_.back(); - newLink->contextObject = (void*)contextObject; - tail_.outer = newLink; - links_.push_back(newLink); - } - - CContextList() - { - tail_.outer = 0; - tail_.contextObject = 0; - connectedList_ = 0; - } - - explicit CContextList(SContextLink* connectedList) - { - tail_.outer = 0; - tail_.contextObject = 0; - connectedList_ = connectedList; - } - - ~CContextList() - { - for (size_t i = 0; i < links_.size(); ++i) - { - delete links_[i]; - } - links_.clear(); - } - - SContextLink* Tail() { return &tail_; } - private: - SContextLink tail_; - std::vector links_; - SContextLink* connectedList_; - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONTEXTLIST_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Factory.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Factory.h deleted file mode 100644 index 83f8ef3ad3..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Factory.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * yasli - Serialization Library. - * Copyright (C) 2007-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_FACTORY_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_FACTORY_H -#pragma once - -#include -#include -#include "Serialization/Assert.h" - -template> -class Factory { -public: - typedef AZStd::map<_Key, AZStd::function<_Product *()>, _KeyPred, AZ::StdLegacyAllocator> Creators; - typedef _Product* (*ProductConstructionFunction)(void); - - Factory() {} - - struct Creator - { - Creator() - { - if (s_creatorsHead) - { - m_next = s_creatorsHead; - } - s_creatorsHead = this; - } - - Creator(Factory& factory, _Key key, ProductConstructionFunction construction_function_) - : Creator() - { - // capture key and construction_function_ by value so the lazy load won't try to access possibly deleted data - Register = [&, key, construction_function_]() - { - factory.add(key, construction_function_); - }; - } - - Creator(_Key key, ProductConstructionFunction construction_function_) - : Creator() - { - // capture key and construction_function_ by value so the lazy load won't try to access possibly deleted data - Register = [&, key, construction_function_]() - { - Factory::the().add(key, construction_function_); - }; - } - - AZStd::function Register; - Creator* m_next = nullptr; - }; - - void add(const _Key& key, AZStd::function<_Product *()> creator) { - YASLI_ASSERT(creators_.find(key) == creators_.end()); - YASLI_ASSERT(creator); - creators_[key] = creator; - } - - void remove(const _Key& key) { - auto& entry = creators_.find(key); - if (entry != creators_.end()) { - creators_.erase(entry); - } - } - - _Product* create(const _Key& key) const - { - lazyRegisterCreators(); - typename Creators::const_iterator it = creators_.find(key); - if (it != creators_.end()) { - return it->second(); - } - else - return 0; - } - - std::size_t size() const - { - lazyRegisterCreators(); - return creators_.size(); - } - - _Product* createByIndex(int index) const - { - lazyRegisterCreators(); - YASLI_ASSERT(index >= 0 && index < creators_.size()); - typename Creators::const_iterator it = creators_.begin(); - std::advance(it, index); - return it->second(); - } - - - const Creators& creators() const - { - lazyRegisterCreators(); - return creators_; - } - - static Factory& the() - { - static Factory* genericFactory = nullptr; - static AZStd::aligned_storage_for_t s_storage; - if (!genericFactory) - { - genericFactory = new(&s_storage) Factory(); - } - return *genericFactory; - } - -private: - void lazyRegisterCreators() const - { - if (s_creatorsHead) - { - Creator* creator = s_creatorsHead; - while (creator) - { - creator->Register(); - creator = creator->m_next; - } - s_creatorsHead = nullptr; - } - } - -protected: - Creators creators_; - - static Creator* s_creatorsHead; -}; - -template -typename Factory<_Key, _Product, _KeyPred>::Creator* Factory<_Key, _Product, _KeyPred>::s_creatorsHead = nullptr; - -#define REGISTER_IN_FACTORY(factory, key, product, construction_function) \ - static factory::Creator factory##product##Creator(key, construction_function); - -#define REGISTER_IN_FACTORY_INSTANCE(factory, factoryType, key, product) \ - static factoryType::Creator factoryType##product##Creator(factory, key); - -#define DECLARE_SEGMENT(fileName) int dataSegment##fileName; - -#define FORCE_SEGMENT(fileName) \ - extern int dataSegment##fileName; \ - int* dataSegmentPtr##fileName = &dataSegment##fileName; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_FACTORY_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/MathUtils.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/MathUtils.h deleted file mode 100644 index 82c49a8806..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/MathUtils.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_MATHUTILS_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_MATHUTILS_H -#pragma once - -inline int xround(float v) -{ - return int(v + 0.5f); -} - -inline int min(int a, int b) -{ - return a < b ? a : b; -} - -inline int max(int a, int b) -{ - return a > b ? a : b; -} - -inline float min(float a, float b) -{ - return a < b ? a : b; -} - -inline float max(float a, float b) -{ - return a > b ? a : b; -} - -inline float clamp(float value, float min, float max) -{ - return ::min(::max(min, value), max); -} - -inline int clamp(int value, int min, int max) -{ - return ::min(::max(min, value), max); -} - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_MATHUTILS_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyDrawContext.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyDrawContext.cpp deleted file mode 100644 index b13c89464d..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyDrawContext.cpp +++ /dev/null @@ -1,466 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "PropertyDrawContext.h" -#include -#include "QPropertyTree.h" -#include "Serialization/Decorators/IconXPM.h" -#include "Unicode.h" -#include -#include -#include -#include - -// required to create context for the draw calls -#include -#include -#include - -#include - -#ifndef _MSC_VER -# define _stricmp strcasecmp -#endif - -// --------------------------------------------------------------------------- - -QColor interpolateColor(const QColor& a, const QColor& b, float k); - -IconXPMCache::~IconXPMCache() -{ - flush(); -} - - -void IconXPMCache::flush() -{ - IconToBitmap::iterator it; - for (it = iconToImageMap_.begin(); it != iconToImageMap_.end(); ++it) - delete it->second.bitmap; - iconToImageMap_.clear(); -} - -struct RGBAImage -{ - int width_; - int height_; - std::vector pixels_; - - RGBAImage() : width_(0), height_(0) {} -}; - -bool IconXPMCache::parseXPM(RGBAImage* out, const Serialization::IconXPM& icon) -{ - if (icon.lineCount < 3) { - return false; - } - - // parse values - std::vector pixels; - int width = 0; - int height = 0; - int charsPerPixel = 0; - int colorCount = 0; - int hotSpotX = -1; - int hotSpotY = -1; - - int scanResult = azsscanf(icon.source[0], "%d %d %d %d %d %d", &width, &height, &colorCount, &charsPerPixel, &hotSpotX, &hotSpotY); - if (scanResult != 4 && scanResult != 6) - return false; - - if (charsPerPixel > 4) - return false; - - if (icon.lineCount != 1 + colorCount + height) { - YASLI_ASSERT(0 && "Wrong line count"); - return false; - } - - // parse colors - std::vector > colors; - colors.resize(colorCount); - - for (int colorIndex = 0; colorIndex < colorCount; ++colorIndex) { - const char* p = icon.source[colorIndex + 1]; - int code = 0; - for (int charIndex = 0; charIndex < charsPerPixel; ++charIndex) { - if (*p == '\0') - return false; - code = (code << 8) | *p; - ++p; - } - colors[colorIndex].first = code; - - while (*p == '\t' || *p == ' ') - ++p; - - if (*p == '\0') - return false; - - if (*p != 'c' && *p != 'g') - return false; - ++p; - - while (*p == '\t' || *p == ' ') - ++p; - - if (*p == '\0') - return false; - - if (*p == '#') { - ++p; - if (strlen(p) == 6) { - int colorCode; - if (azsscanf(p, "%x", &colorCode) != 1) - return false; - Color color((colorCode & 0xff0000) >> 16, - (colorCode & 0xff00) >> 8, - (colorCode & 0xff), - 255); - colors[colorIndex].second = color; - } - } - else { - if (_stricmp(p, "None") == 0) - colors[colorIndex].second = Color(0, 0, 0, 0); - else if (_stricmp(p, "Black") == 0) - colors[colorIndex].second = Color(0, 0, 0, 255); - else { - // unknown color - colors[colorIndex].second = Color(255, 0, 0, 255); - } - } - } - - // parse pixels - pixels.resize(width * height); - int pi = 0; - for (int y = 0; y < height; ++y) { - const char* p = icon.source[1 + colorCount + y]; - if (strlen(p) != width * charsPerPixel) - return false; - - for (int x = 0; x < width; ++x) { - int code = 0; - for (int i = 0; i < charsPerPixel; ++i) { - code = (code << 8) | *p; - ++p; - } - - for (size_t i = 0; i < size_t(colorCount); ++i) - if (colors[i].first == code) - pixels[pi] = colors[i].second; - ++pi; - } - } - - out->pixels_.swap(pixels); - out->width_ = width; - out->height_ = height; - return true; -} - - -QImage* IconXPMCache::getImageForIcon(const Serialization::IconXPM& icon) -{ - IconToBitmap::iterator it = iconToImageMap_.find(icon.source); - if (it != iconToImageMap_.end()) - return it->second.bitmap; - - RGBAImage image; - if (!parseXPM(&image, icon)) - return 0; - - BitmapCache& cache = iconToImageMap_[icon.source]; - cache.pixels.swap(image.pixels_); - cache.bitmap = new QImage((unsigned char*)&cache.pixels[0], image.width_, image.height_, QImage::Format_ARGB32); - return cache.bitmap; -} - -// --------------------------------------------------------------------------- - -void drawRoundRectangle(QPainter& p, const QRect &_r, unsigned int color, int radius, [[maybe_unused]] int width) -{ - QRect r = _r; - int dia = 2 * radius; - - p.setPen(QColor(color)); - p.drawRoundedRect(r, dia, dia); -} - -void fillRoundRectangle(QPainter& p, const QBrush& brush, const QRect& _r, const QColor& border, int radius) -{ - bool wasAntialisingSet = p.renderHints().testFlag(QPainter::Antialiasing); - p.setRenderHints(QPainter::Antialiasing, true); - - p.setBrush(brush); - QPen pen(QBrush(border), 1.0, Qt::SolidLine); - p.setPen(pen); - QRectF adjustedRect = _r; - adjustedRect.adjust(0.5f, 0.5f, -0.5f, -0.5f); - p.drawRoundedRect(adjustedRect, radius, radius); - - p.setRenderHints(QPainter::Antialiasing, wasAntialisingSet); -} - -// --------------------------------------------------------------------------- - -void PropertyDrawContext::drawIcon(const QRect& rect, const Serialization::IconXPM& icon) const -{ - QImage* image = tree->_iconCache()->getImageForIcon(icon); - if (!image) - return; - int x = rect.left() + (rect.width() - image->width()) / 2; - int y = rect.top() + (rect.height() - image->height()) / 2; - painter->drawImage(x, y, *image); -} - -void PropertyDrawContext::drawCheck(const QRect& rect, bool disabled, CheckState checked) const -{ - QStyleOptionButton option; - if (!disabled) - option.state |= QStyle::State_Enabled; - else { - option.state |= QStyle::State_ReadOnly; - option.palette.setCurrentColorGroup(QPalette::Disabled); - } - if (checked == CHECK_SET) - option.state |= QStyle::State_On; - else if (checked == CHECK_IN_BETWEEN) - option.state |= QStyle::State_NoChange; - else - option.state |= QStyle::State_Off; - - // create a widget so that the style sheet has context for its draw calls - QCheckBox forContext; - QSize checkboxSize = tree->style()->subElementRect(QStyle::SE_CheckBoxIndicator, &option, &forContext).size(); - option.rect = QRect(rect.left(), rect.center().y() - checkboxSize.height() / 2, checkboxSize.width(), checkboxSize.height()); - tree->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter, &forContext); - if (disabled) { - // With Fusion theme difference between disabled and enabled checkbox is very subtle, let's amplify it - QColor readOnlyOverlay = tree->backgroundColor(); - readOnlyOverlay.setAlpha(128); - painter->fillRect(option.rect, QBrush(readOnlyOverlay)); - } -} - -void PropertyDrawContext::drawButton(const QRect& rect, const wchar_t* text, int buttonFlags, const QFont* font, const Color* colorOverride) const -{ - QPushButton button; - button.ensurePolished(); - QStyleOptionButton option; - option.initFrom(&button); - if (buttonFlags & BUTTON_DISABLED) { - option.state |= QStyle::State_ReadOnly; - option.palette.setCurrentColorGroup(QPalette::Disabled); - } - else - option.state |= QStyle::State_Enabled; - if (buttonFlags & BUTTON_PRESSED) { - option.state |= QStyle::State_On; - option.state |= QStyle::State_Sunken; - } - else - option.state |= QStyle::State_Raised; - - if (buttonFlags & BUTTON_FOCUSED) - option.state |= QStyle::State_HasFocus; - option.rect = rect.adjusted(0, 0, -1, -1); - - QWidget* pseudoDrawWidget = &button; - - if (colorOverride) { - QPalette& palette = option.palette; - palette.setCurrentColorGroup(QPalette::Normal); - QColor tintTarget(colorOverride->r, colorOverride->g, colorOverride->b, colorOverride->a); - - QPalette::ColorRole groups[] = { QPalette::Button, QPalette::Light, QPalette::Dark, QPalette::Midlight, QPalette::Mid, QPalette::Shadow }; - for (int i = 0; i < sizeof(groups) / sizeof(groups[0]); ++i) - palette.setColor(groups[i], interpolateColor(palette.color(groups[i]), tintTarget, 0.11f)); - - tree->style()->drawControl(QStyle::CE_PushButtonBevel, &option, painter, pseudoDrawWidget); - } - else - { - // Previously, a temporary QPushButton widget was used as the drawing aid - // for this control. However, our stylesheets didn't seem to affect the - // QPushButton as intended, which left some of them with incorrect background - // colors. It seemed to work to let the tree be the drawing aid, but we should - // probably revisit this in the future. - tree->style()->drawControl(QStyle::CE_PushButtonBevel, &option, painter, pseudoDrawWidget); - } - - QRect textRect; - if ((buttonFlags & BUTTON_DISABLED) == 0 && buttonFlags & BUTTON_POPUP_ARROW) - { - QStyleOption arrowOption; - arrowOption.rect = QRect(rect.right() - 11, rect.top(), 8, rect.height()); - arrowOption.state |= QStyle::State_Enabled; - - // part of the above context change - tree->style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOption, painter, tree); - - textRect = rect.adjusted(0, 0, -8, 0); - } - else - { - textRect = rect; - } - - if (buttonFlags & BUTTON_PRESSED) - { - textRect = textRect.adjusted(1, 0, 1, 0); - } - if ((buttonFlags & BUTTON_CENTER) == 0) - { - textRect.adjust(4, 0, -5, 0); - } - - QColor textColor; - if (colorOverride && !(buttonFlags & BUTTON_DISABLED)) - { - textColor = interpolateColor(tree->palette().color(QPalette::Normal, QPalette::ButtonText), - QColor(colorOverride->r, colorOverride->g, colorOverride->b, colorOverride->a), 0.4f); - } - else - { - textColor = tree->palette().color((buttonFlags & BUTTON_DISABLED) ? QPalette::Disabled : QPalette::Normal, QPalette::ButtonText); - } - tree->_drawRowValue(*painter, text, font, textRect, textColor, false, (buttonFlags & BUTTON_CENTER) != 0); -} - -void PropertyDrawContext::drawButtonWithIcon(const QIcon& icon, const QRect& rect, const wchar_t* text, bool selected, bool pressed, bool focused, bool enabled, bool showButtonFrame, const QFont* font) const -{ - QStyleOptionButton option; - if (enabled) - option.state |= QStyle::State_Enabled; - else - option.state |= QStyle::State_ReadOnly; - if (pressed) { - option.state |= QStyle::State_On; - option.state |= QStyle::State_Sunken; - } - else - option.state |= QStyle::State_Raised; - - if (focused) - option.state |= QStyle::State_HasFocus; - option.rect = rect.adjusted(0, 0, -1, -1); - - // See the comment in the drawButton method above for why we don't use the - // QPushButton as the drawing aid for this control - if (showButtonFrame) - tree->style()->drawControl(QStyle::CE_PushButton, &option, painter, tree); - - int iconSize = 16; - QRect iconRect(rect.topLeft(), QPoint(rect.left() + iconSize, rect.bottom())); - QRect textRect; - if (enabled) - textRect = rect.adjusted(iconSize, 0, -8, 0); - else - textRect = rect.adjusted(iconSize, 0, 0, 0); - - if (pressed) - { - textRect.adjust(5, 0, 1, 0); - iconRect.adjust(4, 0, 4, 0); - } - else - { - textRect.adjust(4, 0, 0, 0); - iconRect.adjust(3, 0, 3, 0); - } - icon.paint(painter, iconRect); - - QColor textColor = tree->palette().color(enabled ? QPalette::Active : QPalette::Disabled, selected && !showButtonFrame ? QPalette::HighlightedText : QPalette::ButtonText); - tree->_drawRowValue(*painter, text, font, textRect, textColor, false, false); -} - -void PropertyDrawContext::drawValueText(bool highlighted, const wchar_t* text) const -{ - QColor textColor = highlighted ? tree->palette().highlight().color() : tree->palette().buttonText().color(); - QRect textRect(widgetRect.left() + 3, widgetRect.top() + 2, widgetRect.width() - 6, widgetRect.height() - 4); - tree->_drawRowValue(*painter, text, &tree->font(), textRect, textColor, false, false); -} - -void PropertyDrawContext::drawEntry(const wchar_t* text, bool pathEllipsis, bool grayBackground, int trailingOffset) const -{ - QRect rt = widgetRect; - rt.adjust(0, 0, -trailingOffset, 0); - - // the drawing context requires context so that the style sheet can be used: - QFrame frameForContext; - QLineEdit forContext; -#if (QT_VERSION < QT_VERSION_CHECK(5, 11, 0)) - QStyleOptionFrameV2 option; - option.features = QStyleOptionFrameV2::None; -#else - QStyleOptionFrame option; - option.features = QStyleOptionFrame::None; -#endif - option.state = QStyle::State_Sunken; - option.lineWidth = tree->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, &frameForContext); - option.midLineWidth = 0; - if (!grayBackground) - option.state |= QStyle::State_Enabled; - else { - option.palette.setCurrentColorGroup(QPalette::Disabled); - } - if (captured) - option.state |= QStyle::State_HasFocus; - option.rect = rt; // option.rect is the rectangle to be drawn on. - QRect textRect = tree->style()->subElementRect(QStyle::SE_LineEditContents, &option, &forContext); - if (!textRect.isValid()) - { - textRect = rt; - textRect.adjust(3, 1, -3, -2); - } - else { - textRect.adjust(2, 1, -2, -1); - } - - // make sure the context control is polished (ie, ready for rendering) since we need to use its color palette: - forContext.ensurePolished(); - - // some styles rely on default pens - painter->setPen(QPen(forContext.palette().color(QPalette::Text))); - painter->setBrush(QBrush(forContext.palette().color(QPalette::Base))); - - tree->style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, painter, &forContext); - tree->_drawRowValue(*painter, text, &tree->font(), textRect, forContext.palette().color(QPalette::Text), pathEllipsis, false); - // end amazno changes -} - - -QFont* propertyTreeDefaultFont() -{ - static QFont font; - return &font; -} - -QFont* propertyTreeDefaultBoldFont() -{ - static QFont font; - font.setBold(true); - return &font; -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyDrawContext.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyDrawContext.h deleted file mode 100644 index 611216eb73..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyDrawContext.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - // Modifications copyright Amazon.com, Inc. or its affiliates. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYDRAWCONTEXT_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYDRAWCONTEXT_H -#pragma once - - -#include -#include -#include -#include "Color.h" -#include "EditorCommonAPI.h" - -class QPainter; -class QImage; -class QBrush; -class QRect; -class QIcon; -class QColor; -class QFont; -struct RGBAImage; -namespace Serialization { struct IconXPM; } -struct Color; - -struct IconXPMCache -{ - void initialize(); - void finalize(); - void flush(); - - ~IconXPMCache(); - - QImage* getImageForIcon(const Serialization::IconXPM& icon); -private: - struct BitmapCache { - std::vector pixels; - QImage* bitmap; - }; - - static bool parseXPM(RGBAImage* out, const Serialization::IconXPM& xpm); - typedef std::map IconToBitmap; - IconToBitmap iconToImageMap_; -}; - - -void fillRoundRectangle(QPainter& p, const QBrush& brush, const QRect& r, const QColor& borderColor, int radius); -void drawRoundRectangle(QPainter& p, const QRect &_r, unsigned int color, int radius, int width); - - -enum CheckState { - CHECK_SET, - CHECK_NOT_SET, - CHECK_IN_BETWEEN -}; - -enum { - BUTTON_POPUP_ARROW = 1 << 0, - BUTTON_DISABLED = 1 << 1, - BUTTON_FOCUSED = 1 << 2, - BUTTON_PRESSED = 1 << 3, - BUTTON_CENTER = 1 << 4 -}; - -class QPropertyTree; -struct EDITOR_COMMON_API PropertyDrawContext { - const QPropertyTree* tree; - QPainter* painter; - QRect widgetRect; - QRect lineRect; - bool captured; - bool m_pressed; - - void drawIcon(const QRect& rect, const Serialization::IconXPM& icon) const; - void drawCheck(const QRect& rect, bool disabled, CheckState checked) const; - void drawButton(const QRect& rect, const wchar_t* text, int buttonFlags, const QFont* font, const Color* optionalColorOverride = 0) const; - void drawButtonWithIcon(const QIcon& icon, const QRect& rect, const wchar_t* text, bool selected, bool pressed, bool focused, bool enabled, bool showButtonFrame, const QFont* font) const; - void drawValueText(bool highlighted, const wchar_t* text) const; - void drawEntry(const wchar_t* text, bool pathEllipsis, bool grayBackground, int trailingOffset) const; - - PropertyDrawContext() - : tree(0) - , painter(0) - , captured(false) - , m_pressed(false) - { - } -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYDRAWCONTEXT_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyIArchive.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyIArchive.cpp deleted file mode 100644 index 4b03246db5..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyIArchive.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "Serialization.h" -#include "Serialization/Enum.h" -#include "Serialization/Callback.h" -#include "PropertyTreeModel.h" -#include "PropertyIArchive.h" -#include "PropertyRowBool.h" -#include "PropertyRowString.h" -#include "PropertyRowNumber.h" -#include "PropertyRowPointer.h" -#include "PropertyRowObject.h" -#include "Unicode.h" - -using Serialization::TypeID; - -PropertyIArchive::PropertyIArchive(PropertyTreeModel* model, PropertyRow* root) -: IArchive(INPUT | EDIT) -, model_(model) -, currentNode_(0) -, lastNode_(0) -, root_(root) -{ - stack_.push_back(Level()); - - if (!root_) - root_ = model_->root(); - else - currentNode_ = root; -} - -bool PropertyIArchive::operator()(Serialization::IString& value, const char* name, const char* label) -{ - if(openRow(name, label, "string")){ - if(PropertyRowString* row = static_cast(currentNode_)) - value.set(fromWideChar(row->value().c_str()).c_str()); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(Serialization::IWString& value, const char* name, const char* label) -{ - if(openRow(name, label, "string")){ - if(PropertyRowString* row = static_cast(currentNode_)) { - value.set(row->value().c_str()); - } - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(bool& value, const char* name, const char* label) -{ - if(openRow(name, label, "bool")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(char& value, const char* name, const char* label) -{ - if(openRow(name, label, "char")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -// Signed types -bool PropertyIArchive::operator()(int8& value, const char* name, const char* label) -{ - if(openRow(name, label, "int8")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(int16& value, const char* name, const char* label) -{ - if(openRow(name, label, "int16")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(int32& value, const char* name, const char* label) -{ - if(openRow(name, label, "int32")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(int64& value, const char* name, const char* label) -{ - if(openRow(name, label, "int64")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -// Unsigned types -bool PropertyIArchive::operator()(uint8& value, const char* name, const char* label) -{ - if(openRow(name, label, "uint8")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(uint16& value, const char* name, const char* label) -{ - if(openRow(name, label, "uint16")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(uint32& value, const char* name, const char* label) -{ - if(openRow(name, label, "uint32")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(uint64& value, const char* name, const char* label) -{ - if(openRow(name, label, "uint64")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(float& value, const char* name, const char* label) -{ - if(openRow(name, label, "float")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(double& value, const char* name, const char* label) -{ - if(openRow(name, label, "double")){ - currentNode_->assignToPrimitive(&value, sizeof(value)); - closeRow(name); - return true; - } - else - return false; -} - -bool PropertyIArchive::operator()(Serialization::IContainer& ser, const char* name, const char* label) -{ - const char* typeName = ser.containerType().name(); - if(!openRow(name, label, typeName)) - return false; - - size_t size = 0; - if(currentNode_->multiValue()) - size = ser.size(); - else{ - size = currentNode_->count(); - size = ser.resize(size); - } - - stack_.push_back(Level()); - - size_t index = 0; - if(ser.size() > 0) - while(index < size) - { - ser(*this, "", "<"); - ser.next(); - ++index; - } - - stack_.pop_back(); - - closeRow(name); - return true; -} - -bool PropertyIArchive::operator()(const Serialization::SStruct& ser, const char* name, const char* label) -{ - PropertyRow* nonLeafNode = 0; - if(openRow(name, label, ser.type().name())){ - if (currentNode_->isLeaf()) { - if(!currentNode_->isRoot()){ - currentNode_->assignTo(ser); - closeRow(name); - return true; - } - } - else - nonLeafNode = currentNode_; - } - else - return false; - - stack_.push_back(Level()); - - ser(*this); - - stack_.pop_back(); - - if (nonLeafNode) - nonLeafNode->closeNonLeaf(ser, *this); - closeRow(name); - return true; -} - - -bool PropertyIArchive::operator()(Serialization::IPointer& ser, const char* name, const char* label) -{ - const char* baseName = ser.baseType().name(); - - if(openRow(name, label, baseName)){ - if (!currentNode_->isPointer()) { - closeRow(name); - return false; - } - - YASLI_ASSERT(currentNode_); - PropertyRowPointer* row = static_cast(currentNode_); - if(!row){ - closeRow(name); - return false; - } - row->assignTo(ser); - } - else - return false; - - stack_.push_back(Level()); - - if(ser.get() != 0) - ser.serializer()( *this ); - - stack_.pop_back(); - - closeRow(name); - return true; -} - -bool PropertyIArchive::operator()(Serialization::ICallback& callback, const char* name, const char* label) -{ - return callback.SerializeValue(*this, name, label); -} - -bool PropertyIArchive::operator()(Serialization::Object& obj, const char* name, const char* label) -{ - if(openRow(name, label, obj.type().name())){ - bool result = false; - if (currentNode_->isObject()) { - PropertyRowObject* rowObj = static_cast(currentNode_); - result = rowObj->assignTo(&obj); - } - closeRow(name); - return result; - } - else - return false; -} - -bool PropertyIArchive::OpenBlock(const char* name, const char* label) -{ - if(openRow(name, label, "block")){ - stack_.push_back(Level()); - return true; - } - else - return false; -} - -void PropertyIArchive::CloseBlock() -{ - closeRow("block"); - stack_.pop_back(); -} - -bool PropertyIArchive::openRow(const char* name, [[maybe_unused]] const char* label, const char* typeName) -{ - if(!name) - return false; - - if(!currentNode_){ - lastNode_ = currentNode_ = model_->root(); - YASLI_ASSERT(currentNode_); - if (currentNode_ && strcmp(currentNode_->typeName(), typeName) != 0) - return false; - return true; - } - - YASLI_ESCAPE(currentNode_, return false); - - if(currentNode_->empty()) - return false; - - Level& level = stack_.back(); - - PropertyRow* node = 0; - if(currentNode_->isContainer()){ - if (level.rowIndex < int(currentNode_->children_.size())) - node = currentNode_->children_[level.rowIndex]; - ++level.rowIndex; - } - else { - node = currentNode_->findFromIndex(&level.rowIndex, name, typeName, level.rowIndex); - ++level.rowIndex; - } - - if(node){ - lastNode_ = node; - if(node->isContainer() || !node->multiValue()){ - currentNode_ = node; - if (currentNode_ && strcmp(currentNode_->typeName(), typeName) != 0) - return false; - return true; - } - } - return false; -} - -void PropertyIArchive::closeRow([[maybe_unused]] const char* name) -{ - YASLI_ESCAPE(currentNode_, return); - currentNode_ = currentNode_->parent(); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyIArchive.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyIArchive.h deleted file mode 100644 index 265a819cf7..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyIArchive.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYIARCHIVE_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYIARCHIVE_H -#pragma once - - -#include "Serialization/IArchive.h" - -namespace Serialization{ - class CEnumDescription; - class Object; -} - -class PropertyRow; -class PropertyTreeModel; - -class PropertyIArchive : public Serialization::IArchive{ -public: - PropertyIArchive(PropertyTreeModel* model, PropertyRow* root); - -protected: - bool operator()(Serialization::IString& value, const char* name, const char* label); - bool operator()(Serialization::IWString& value, const char* name, const char* label); - bool operator()(bool& value, const char* name, const char* label); - bool operator()(char& value, const char* name, const char* label); - - // Signed types - bool operator()(int8& value, const char* name, const char* label); - bool operator()(int16& value, const char* name, const char* label); - bool operator()(int32& value, const char* name, const char* label); - bool operator()(int64& value, const char* name, const char* label); - // Unsigned types - bool operator()(uint8& value, const char* name, const char* label); - bool operator()(uint16& value, const char* name, const char* label); - bool operator()(uint32& value, const char* name, const char* label); - bool operator()(uint64& value, const char* name, const char* label); - - bool operator()(float& value, const char* name, const char* label); - bool operator()(double& value, const char* name, const char* label); - - bool operator()(const Serialization::SStruct& ser, const char* name, const char* label); - bool operator()(Serialization::IPointer& ser, const char* name, const char* label); - bool operator()(Serialization::IContainer& ser, const char* name, const char* label); - bool operator()(Serialization::Object& obj, const char* name, const char* label); - bool operator()(Serialization::ICallback& callback, const char* name, const char* label); - using Serialization::IArchive::operator(); - - bool OpenBlock(const char* name, const char* label); - void CloseBlock(); - -protected: - bool needDefaultArchive([[maybe_unused]] const char* baseName) const { return false; } -private: - bool openRow(const char* name, const char* label, const char* typeName); - void closeRow(const char* name); - - struct Level { - int rowIndex; - Level() : rowIndex(0) {} - }; - - vector stack_; - - PropertyTreeModel* model_; - PropertyRow* currentNode_; - PropertyRow* lastNode_; - PropertyRow* root_; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYIARCHIVE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyOArchive.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyOArchive.cpp deleted file mode 100644 index fd6773f4da..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyOArchive.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include -#include - -#include "PropertyTreeModel.h" -#include "QPropertyTree.h" - -#include "PropertyRowContainer.h" -#include "PropertyRowBool.h" -#include "PropertyRowString.h" -#include "PropertyRowNumber.h" -#include "PropertyRowPointer.h" -#include "PropertyRowObject.h" -#include "ConstStringList.h" -#include "Unicode.h" - -#include "Serialization.h" -#include "PropertyOArchive.h" -#include "Serialization/Callback.h" -using Serialization::TypeID; - - -PropertyOArchive::PropertyOArchive(PropertyTreeModel* model, PropertyRow* root, ValidatorBlock* validator) -: IArchive(OUTPUT | EDIT | VALIDATION | DOCUMENTATION) -, model_(model) -, currentNode_(root) -, lastNode_(0) -, updateMode_(false) -, defaultValueCreationMode_(false) -, rootNode_(root) -, outlineMode_(false) -, validator_(validator) -{ - stack_.push_back(Level()); - YASLI_ASSERT(model != 0); - if(!rootNode_->empty()){ - updateMode_ = true; - stack_.back().oldRows.swap(rootNode_->children_); - } -} - - - -PropertyOArchive::PropertyOArchive(PropertyTreeModel* model, bool forDefaultType) -: IArchive(OUTPUT | EDIT | VALIDATION | DOCUMENTATION) -, model_(model) -, currentNode_(0) -, lastNode_(0) -, updateMode_(false) -, defaultValueCreationMode_(forDefaultType) -, rootNode_(0) -, outlineMode_(false) -, validator_(0) -{ - rootNode_ = new PropertyRow(); - rootNode_->setName("root"); - currentNode_ = rootNode_.get(); - stack_.push_back(Level()); -} - -PropertyOArchive::~PropertyOArchive() -{ -} - -PropertyRow* PropertyOArchive::defaultValueRootNode() -{ - if (!rootNode_) - return 0; - return rootNode_->childByIndex(0); -} - -void PropertyOArchive::enterNode(PropertyRow* row) -{ - currentNode_ = row; - - stack_.push_back(Level()); - Level& level = stack_.back(); - level.oldRows.swap(row->children_); - row->children_.reserve(level.oldRows.size()); -} - -void PropertyOArchive::closeStruct([[maybe_unused]] const char* name) -{ - stack_.pop_back(); - - if(currentNode_){ - lastNode_ = currentNode_; - currentNode_ = currentNode_->parent(); - } -} - -static PropertyRow* findRow(int* index, PropertyRows& rows, const char* name, const char* typeName, int startIndex) -{ - int count = int(rows.size()); - for(int i = startIndex; i < count; ++i){ - PropertyRow* row = rows[i]; - if (!row) - continue; - if(((row->name() == name) || strcmp(row->name(), name) == 0) && - (row->typeName() == typeName || strcmp(row->typeName(), typeName) == 0)) { - *index = (int)i; - return row; - } - } - for(int i = 0; i < startIndex; ++i){ - PropertyRow* row = rows[i]; - if (!row) - continue; - if(((row->name() == name) || strcmp(row->name(), name) == 0) && - (row->typeName() == typeName || strcmp(row->typeName(), typeName) == 0)) { - *index = (int)i; - return row; - } - } - return 0; -} - -template -RowType* PropertyOArchive::updateRow(const char* name, const char* label, const char* typeName, const ValueType& value) -{ - SharedPtr newRow; - if(currentNode_ == 0){ - if (rootNode_) - newRow = static_cast(rootNode_.get()); - else - newRow.reset(new RowType()); - newRow->setNames(name, label, typeName); - if(updateMode_){ - model_->setRoot(newRow); - return newRow; - } - else{ - if(defaultValueCreationMode_) - rootNode_ = newRow; - else - model_->setRoot(newRow); - newRow->setValueAndContext(value, *this); - return newRow; - } - } - else{ - - Level& level = stack_.back(); - int rowIndex; - PropertyRow* oldRow = findRow(&rowIndex, level.oldRows, name, typeName, level.rowIndex); - - const char* oldLabel = 0; - if(oldRow){ - oldRow->setMultiValue(false); - newRow = static_cast(oldRow); - level.oldRows[rowIndex] = 0; - level.rowIndex = rowIndex + 1; - oldLabel = oldRow->label(); - newRow->setNames(name, label, typeName); - } - else{ - PropertyRowFactory& factory = PropertyRowFactory::the(); - newRow = static_cast(factory.create(typeName)); - if(!newRow) - newRow.reset(new RowType()); - newRow->setNames(name, label, typeName); - if(model_->expandLevels() != 0 && (model_->expandLevels() == -1 || model_->expandLevels() >= currentNode_->level())) - newRow->_setExpanded(true); - } - currentNode_->add(newRow); - if (!oldRow || oldLabel != label) { - // for new rows we should mark all parents with labelChanged_ - newRow->setLabelChanged(); - newRow->setLabelChangedToChildren(); - } - newRow->setValueAndContext(value, *this); - return newRow; - } -} - -template -PropertyRow* PropertyOArchive::updateRowPrimitive(const char* name, const char* label, const char* typeName, const ValueType& value, const void* handle, const Serialization::TypeID& typeId) -{ - SharedPtr newRow; - - if(currentNode_ == 0) - return 0; - - int rowIndex; - Level& level = stack_.back(); - PropertyRow* oldRow = findRow(&rowIndex, level.oldRows, name, typeName, level.rowIndex); - - const char* oldLabel = 0; - if(oldRow){ - oldRow->setMultiValue(false); - newRow.reset(static_cast(oldRow)); - level.oldRows[rowIndex] = 0; - level.rowIndex = rowIndex + 1; - oldLabel = oldRow->label(); - oldRow->setNames(name, label, typeName); - } - else{ - newRow = new RowType(); - newRow->setNames(name, label, typeName); - if(model_->expandLevels() != 0){ - if(model_->expandLevels() == -1 || model_->expandLevels() >= currentNode_->level()) - newRow->_setExpanded(true); - } - } - currentNode_->add(newRow); - if (!oldRow || oldLabel != label) - { - // for new rows we should mark all parents with labelChanged_ - newRow->setLabelChanged(); - } - - newRow->setValue(value, handle, typeId); - return newRow; -} - -bool PropertyOArchive::operator()(const Serialization::SStruct& ser, const char* name, const char* label) -{ - const char* typeName = ser.type().name(); - - lastNode_ = currentNode_; - bool hideChildren = outlineMode_ && currentNode_ && currentNode_->isContainer(); - PropertyRow* row = updateRow(name, label, typeName, ser); - row->setHideChildren(hideChildren); - - PropertyRow* nonLeaf = 0; - if(!row->isLeaf() || currentNode_ == 0){ - enterNode(row); - - if(currentNode_->isLeaf()) - return false; - else - nonLeaf = currentNode_; - } - else{ - lastNode_ = row; - return true; - } - - if (ser) - ser(*this); - - if (nonLeaf) - nonLeaf->closeNonLeaf(ser, *this); - - closeStruct(name); - return true; -} - -bool PropertyOArchive::operator()(Serialization::IString& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive(name, label, "string", value.get(), value.handle(), value.type()); - return true; -} - -bool PropertyOArchive::operator()(Serialization::IWString& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive(name, label, "string", value.get(), value.handle(), value.type()); - return true; -} - -bool PropertyOArchive::operator()(bool& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive(name, label, "bool", value, &value, Serialization::TypeID::get()); - return true; -} - -bool PropertyOArchive::operator()(char& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "char", value, &value, Serialization::TypeID::get()); - return true; -} - -// --- - -bool PropertyOArchive::operator()(int8& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "int8", value, &value, Serialization::TypeID::get()); - return true; -} - -bool PropertyOArchive::operator()(int16& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "int16", value, &value, Serialization::TypeID::get()); - return true; -} - -bool PropertyOArchive::operator()(int32& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "int32", value, &value, Serialization::TypeID::get()); - return true; -} - -bool PropertyOArchive::operator()(int64& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "int64", value, &value, Serialization::TypeID::get()); - return true; -} - -// --- - -bool PropertyOArchive::operator()(uint8& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "uint8", value, &value, Serialization::TypeID::get()); - return true; -} - -bool PropertyOArchive::operator()(uint16& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "uint16", value, &value, Serialization::TypeID::get()); - return true; -} - -bool PropertyOArchive::operator()(uint32& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "uint32", value, &value, Serialization::TypeID::get()); - return true; -} - -bool PropertyOArchive::operator()(uint64& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "uint64", value, &value, Serialization::TypeID::get()); - return true; -} - -// --- - -bool PropertyOArchive::operator()(float& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "float", value, &value, Serialization::TypeID::get()); - return true; -} - -bool PropertyOArchive::operator()(double& value, const char* name, const char* label) -{ - lastNode_ = updateRowPrimitive >(name, label, "double", value, &value, Serialization::TypeID::get()); - return true; -} - - -bool PropertyOArchive::operator()(Serialization::IContainer& ser, const char *name, const char *label) -{ - const char* elementTypeName = ser.elementType().name(); - enterNode(updateRow(name, label, ser.containerType().name(), ser)); - - if (!model_->defaultTypeRegistered(elementTypeName)) { - PropertyOArchive ar(model_, true); - ar.SetOutlineMode(outlineMode_); - ar.SetFilter(GetFilter()); - ar.SetInnerContext(GetInnerContext()); - model_->addDefaultType(0, elementTypeName); // add empty default to prevent recursion - ser.serializeNewElement(ar, "", (label&&*label=='!')?"!<":"<"); - if (ar.defaultValueRootNode() != 0) - model_->addDefaultType(ar.defaultValueRootNode(), elementTypeName); - } - if ( ser.size() > 0 ) - while( true ) { - ser(*this, "", (label&&*label=='!')?"!<":"<"); - if ( !ser.next() ) - break; - } - currentNode_->labelChanged(); - closeStruct(name); - return true; -} - -bool PropertyOArchive::operator()(Serialization::IPointer& ptr, const char *name, const char *label) -{ - lastNode_ = currentNode_; - - bool hideChildren = outlineMode_ && currentNode_ && currentNode_->isContainer(); - PropertyRow* row = updateRow(name, label, ptr.baseType().name(), ptr); - row->setHideChildren(hideChildren); - enterNode(row); - { - TypeID baseType = ptr.baseType(); - Serialization::IClassFactory* factory = ptr.factory(); - size_t count = factory->size(); - - const char* nullLabel = factory->nullLabel(); - if (!(nullLabel && nullLabel[0] == '\0')) - { - PropertyDefaultDerivedTypeValue nullValue; - nullValue.factory = factory; - nullValue.factoryIndex = -1; - nullValue.label = nullLabel ? nullLabel : "[ null ]"; - model_->addDefaultType(baseType, nullValue); - } - - for(size_t i = 0; i < count; ++i) { - const Serialization::TypeDescription *desc = factory->descriptionByIndex((int)i); - if (!model_->defaultTypeRegistered(baseType, desc->name())){ - PropertyOArchive ar(model_, true); - ar.SetOutlineMode(outlineMode_); - ar.SetInnerContext(GetInnerContext()); - ar.SetFilter(GetFilter()); - - PropertyDefaultDerivedTypeValue defaultValue; - defaultValue.registeredName = desc->name(); - defaultValue.factory = factory; - defaultValue.factoryIndex = int(i); - defaultValue.label = desc->label(); - - model_->addDefaultType(baseType, defaultValue); - factory->serializeNewByIndex(ar, (int)i, "name", "label"); - if (ar.defaultValueRootNode() != 0) { - ar.defaultValueRootNode()->setTypeName(desc->name()); - defaultValue.root = ar.defaultValueRootNode(); - model_->addDefaultType(baseType, defaultValue); - } - } - } - } - - if(Serialization::SStruct ser = ptr.serializer()) - ser(*this); - closeStruct(name); - return true; -} - -bool PropertyOArchive::operator()(Serialization::ICallback& callback, const char* name, const char* label) -{ - if (!callback.SerializeValue(*this, name, label)) - return false; - - lastNode_->setCallback(callback.Clone()); - return true; -} - -bool PropertyOArchive::operator()(Serialization::Object& obj, const char *name, const char *label) -{ - PropertyRowObject* row = 0; - row = updateRow(name, label, obj.type().name(), obj); - - lastNode_ = row; - return true; -} - -bool PropertyOArchive::OpenBlock(const char* name, const char* label) -{ - PropertyRow* row = updateRow(name, label, "block", Serialization::SStruct()); - lastNode_ = currentNode_; - enterNode(row); - return true; -} - -void PropertyOArchive::ValidatorMessage(bool error, const void* handle, const Serialization::TypeID& type, const char* message) -{ - if (validator_) - { - ValidatorEntry entry(error ? VALIDATOR_ENTRY_ERROR : VALIDATOR_ENTRY_WARNING, - handle, - type, - message); - validator_->AddEntry(entry); - } -} - -void PropertyOArchive::DocumentLastField(const char* message) -{ - if (lastNode_ && (!currentNode_ || lastNode_->parent() == currentNode_)) - lastNode_->setTooltip(message ? message : ""); - else if (currentNode_) - currentNode_->setTooltip(message ? message : ""); -} - -void PropertyOArchive::CloseBlock() -{ - closeStruct("block"); -} - -void PropertyOArchive::SetOutlineMode(bool outlineMode) -{ - outlineMode_ = outlineMode; -} - -// vim:ts=4 sw=4: diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyOArchive.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyOArchive.h deleted file mode 100644 index 33be92466c..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyOArchive.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYOARCHIVE_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYOARCHIVE_H -#pragma once - - -#include "Serialization/IArchive.h" -#include "Serialization/Pointers.h" - -namespace Serialization -{ - class CEnumDescription; - class Object; - struct ICallback; -} - -class PropertyRow; -class PropertyTreeModel; -class ValidatorBlock; - -using Serialization::SharedPtr; - -class PropertyOArchive : public Serialization::IArchive{ -public: - PropertyOArchive(PropertyTreeModel* model, PropertyRow* root, ValidatorBlock* validator); - ~PropertyOArchive(); - - void SetOutlineMode(bool outlineMode); - - inline const SharedPtr& currentNode() const { - return currentNode_; - } - -protected: - bool operator()(Serialization::IString& value, const char* name, const char* label); - bool operator()(Serialization::IWString& value, const char* name, const char* label); - bool operator()(bool& value, const char* name, const char* label); - bool operator()(char& value, const char* name, const char* label); - - bool operator()(int8& value, const char* name, const char* label); - bool operator()(int16& value, const char* name, const char* label); - bool operator()(int32& value, const char* name, const char* label); - bool operator()(int64& value, const char* name, const char* label); - - bool operator()(uint8& value, const char* name, const char* label); - bool operator()(uint16& value, const char* name, const char* label); - bool operator()(uint32& value, const char* name, const char* label); - bool operator()(uint64& value, const char* name, const char* label); - - bool operator()(float& value, const char* name, const char* label); - bool operator()(double& value, const char* name, const char* label); - - bool operator()(const Serialization::SStruct& ser, const char* name, const char* label); - bool operator()(Serialization::IPointer& ptr, const char *name, const char *label); - bool operator()(Serialization::IContainer& ser, const char *name, const char *label); - bool operator()(Serialization::Object& obj, const char *name, const char *label); - bool operator()(Serialization::ICallback& ser, const char *name, const char *label); - using Serialization::IArchive::operator(); - - bool OpenBlock(const char* name, const char* label); - void CloseBlock(); - void ValidatorMessage(bool error, const void* handle, const Serialization::TypeID& type, const char* message); - void DocumentLastField(const char* docString); - -protected: - PropertyOArchive(PropertyTreeModel* model, bool forDefaultType); - -private: - struct Level { - std::vector > oldRows; - int rowIndex; - Level() : rowIndex(0) {} - }; - std::vector stack_; - - template - PropertyRow* updateRowPrimitive(const char* name, const char* label, const char* typeName, const ValueType& value, const void* handle, const Serialization::TypeID& typeId); - - template - RowType* updateRow(const char* name, const char* label, const char* typeName, const ValueType& value); - - void enterNode(PropertyRow* row); // sets currentNode - void closeStruct(const char* name); - PropertyRow* defaultValueRootNode(); - - bool updateMode_; - bool defaultValueCreationMode_; - PropertyTreeModel* model_; - ValidatorBlock* validator_; - SharedPtr currentNode_; - SharedPtr lastNode_; - - // for defaultArchive - SharedPtr rootNode_; - std::string typeName_; - const char* derivedTypeName_; - std::string derivedTypeNameAlt_; - bool outlineMode_; -}; - -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYOARCHIVE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRow.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRow.cpp deleted file mode 100644 index 05b073cda6..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRow.cpp +++ /dev/null @@ -1,1906 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "QPropertyTree.h" -#include "QPropertyTreeStyle.h" -#include "PropertyTreeModel.h" -#include "PropertyRowContainer.h" -#include "PropertyDrawContext.h" -#include "Unicode.h" -#include "Serialization.h" -#include "Serialization/BinArchive.h" -#include "Serialization/Callback.h" -#include "Serialization/Decorators/IconXPM.h" - -#include -#include -#include -#include -#include -#include -#include "MathUtils.h" -#include "warning.xpm" -#include "error.xpm" - -#if 0 -# define DEBUG_TRACE(fmt, ...) printf(fmt "\n", __VA_ARGS__) -# define DEBUG_TRACE_ROW(fmt, ...) for(PropertyRow* zzzz = this; zzzz; zzzz = zzzz->parent()) printf(" "); printf(fmt "\n", __VA_ARGS__) -#else -# define DEBUG_TRACE(...) -# define DEBUG_TRACE_ROW(...) -#endif - -enum { TEXT_VALUE_SPACING = 3 }; - -QColor interpolateColor(const QColor& a, const QColor& b, float k) -{ - float mk = 1.0f - k; - return QColor(aznumeric_cast(a.red() * mk + b.red() * k), - aznumeric_cast(a.green() * mk + b.green() * k), - aznumeric_cast(a.blue() * mk + b.blue() * k), - aznumeric_cast(a.alpha() * mk + b.alpha() * k)); -} - -// --------------------------------------------------------------------------- - -template -static void visitPulledRows(PropertyRow* row, T& drawFunc) -{ - int count = (int)row->count(); - for (int i = 0; i < count; ++i) { - PropertyRow* child = row->childByIndex(i); - if (child->pulledUp() || child->pulledBefore()) { - drawFunc(child); - visitPulledRows(child, drawFunc); - } - } -}; - -// --------------------------------------------------------------------------- - -ConstStringList* PropertyRow::constStrings_ = 0; - -PropertyRow::PropertyRow() -{ - parent_ = 0; - callback_ = 0; - - expanded_ = false; - selected_ = false; - visible_ = true; - labelUndecorated_ = 0; - belongsToFilteredRow_ = false; - matchFilter_ = true; - - pos_ = QPoint(0, 0); - size_ = QPoint(-1, -1); - plusSize_ = 0; - textPos_ = 0; - textSizeInitial_ = 0; - textHash_ = 0; - textSize_ = 0; - widgetPos_ = 0; - widgetSize_ = 0; - userWidgetSize_ = -1; - heightIncludingChildren_ = 0; - - name_ = ""; - typeName_ = ""; - - pulledUp_ = false; - pulledBefore_ = false; - packedAfterPreviousRow_ = false; - hasPulled_ = false; - userReadOnly_ = false; - userReadOnlyRecurse_ = false; - userFullRow_ = false; - userPackCheckboxes_ = false; - userWidgetToContent_ = false; - multiValue_ = false; - fontWeight_ = FontWeight::Undefined; - userNonCopyable_ = false; - - label_ = ""; - labelChanged_ = true; - layoutChanged_ = true; - hideChildren_ = false; - validatorHasErrors_ = false; - validatorHasWarnings_ = false; - - tooltip_ = ""; -} - -PropertyRow::~PropertyRow() -{ - size_t count = children_.size(); - for (size_t i = 0; i < count; ++i) - if (children_[i]->parent() == this) - children_[i]->setParent(0); - if (callback_) - callback_->Release(); - callback_ = 0; -} - -void PropertyRow::setNames(const char* name, const char* label, const char* typeName) -{ - name_ = name; - label_ = label ? label : ""; - typeName_ = typeName; -} - -PropertyRow* PropertyRow::childByIndex(int index) -{ - if(index >= 0 && index < int(children_.size())) - return children_[index]; - else - return 0; -} - -const PropertyRow* PropertyRow::childByIndex(int index) const -{ - if(index >= 0 && index < int(children_.size())) - return children_[index]; - else - return 0; -} - -void PropertyRow::_setExpanded(bool expanded) -{ - expanded_ = expanded; - int numChildren = (int)children_.size(); - - for (int i = 0; i < numChildren; ++i) { - PropertyRow* child = children_[i]; - if(child->pulledUp()) - child->_setExpanded(expanded); - } - - layoutChanged_ = true; - setLayoutChangedToChildren(); - -} - -struct SetExpandedOp { - bool expanded_; - SetExpandedOp(bool expanded) : expanded_(expanded) {} - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, [[maybe_unused]] int index) - { - if(row->canBeToggled(tree)) - row->_setExpanded(expanded_); - return SCAN_CHILDREN_SIBLINGS; - } -}; - -void PropertyRow::setExpandedRecursive(QPropertyTree* tree, bool expanded) -{ - if(canBeToggled(tree)) - _setExpanded(expanded); - - SetExpandedOp op(expanded); - scanChildren(op, tree); -} - -int PropertyRow::childIndex(const PropertyRow* row) const -{ - YASLI_ASSERT(row); - Rows::const_iterator it = std::find(children_.begin(), children_.end(), row); - YASLI_ESCAPE(it != children_.end(), return -1); - return aznumeric_cast(std::distance(children_.begin(), it)); -} - -bool PropertyRow::isChildOf(const PropertyRow* row) const -{ - const PropertyRow* p = parent(); - while(p){ - if(p == row) - return true; - p = p->parent(); - } - return false; -} - -void PropertyRow::add(PropertyRow* row) -{ - children_.push_back(row); - row->setParent(this); -} - -void PropertyRow::addAfter(PropertyRow* row, PropertyRow* after) -{ - iterator it = std::find(children_.begin(), children_.end(), after); - if(it != children_.end()){ - ++it; - children_.insert(it, row); - } - else{ - children_.push_back(row); - } - - row->setParent(this); -} - -void PropertyRow::assignRowState(const PropertyRow& row, bool recurse) -{ - expanded_ = row.expanded_; - selected_ = row.selected_; - if(recurse){ - int numChildren = (int)children_.size(); - for (int i = 0; i < numChildren; ++i) { - PropertyRow* child = children_[i].get(); - YASLI_ESCAPE(child, continue); - int unusedIndex; - const PropertyRow* rhsChild = row.findFromIndex(&unusedIndex, child->name(), child->typeName(), i); - if(rhsChild) - child->assignRowState(*rhsChild, true); - } - } -} - -void PropertyRow::assignRowProperties(PropertyRow* row) -{ - YASLI_ESCAPE(row, return); - parent_ = row->parent_; - - userReadOnly_ = row->userReadOnly_; - userReadOnlyRecurse_ = row->userReadOnlyRecurse_; - userFixedWidget_ = row->userFixedWidget_; - pulledUp_ = row->pulledUp_; - pulledBefore_ = row->pulledBefore_; - size_ = row->size_; - pos_ = row->pos_; - plusSize_ = row->plusSize_; - textPos_ = row->textPos_; - textSizeInitial_ = row->textSizeInitial_; - textHash_ = row->textHash_; - textSize_ = row->textSize_; - widgetPos_ = row->widgetPos_; - widgetSize_ = row->widgetSize_; - userWidgetSize_ = row->userWidgetSize_; - userWidgetToContent_ = row->userWidgetToContent_; - callback_ = row->callback_; - row->callback_ = 0; - - assignRowState(*row, false); -} - -void PropertyRow::replaceAndPreserveState(PropertyRow* oldRow, PropertyRow* newRow, PropertyTreeModel* model) -{ - Rows::iterator it = std::find(children_.begin(), children_.end(), oldRow); - YASLI_ASSERT(it != children_.end()); - if(it != children_.end()){ - newRow->assignRowProperties(*it); - newRow->labelChanged_ = true; - *it = newRow; - if (model) - model->callRowCallback(newRow); - } -} - -void PropertyRow::erase(PropertyRow* row) -{ - PropertyRow* childToRemove = PropertyRow::findChildFromDescendant(row); - if(childToRemove) - { - childToRemove->setParent(nullptr); - children_.erase(std::find(children_.begin(), children_.end(), childToRemove)); - } -} - -void PropertyRow::swapChildren(PropertyRow* row, PropertyTreeModel* model) -{ - children_.swap(row->children_); - iterator it; - for( it = children_.begin(); it != children_.end(); ++it) - (**it).setParent(this); - for( it = row->children_.begin(); it != row->children_.end(); ++it) - (**it).setParent(row); - if (model){ - for(it = children_.begin(); it != children_.end(); ++it){ - PropertyRow* child = *it; - if (PropertyRow* srcChild = row->find(child->name(), child->label(), child->typeName())) { - child->setCallback(srcChild->callback_); - srcChild->setCallback(0); - model->callRowCallback(child); - } - } - } -} - -void PropertyRow::addBefore(PropertyRow* row, PropertyRow* before) -{ - if(before == 0) - children_.insert(children_.begin(), row); - else{ - iterator it = std::find(children_.begin(), children_.end(), before); - if(it != children_.end()) - children_.insert(it, row); - else - children_.push_back(row); - } - row->setParent(this); -} - -wstring PropertyRow::valueAsWString() const -{ - return toWideChar(valueAsString().c_str()); -} - -string PropertyRow::valueAsString() const -{ - return string(); -} - -SharedPtr PropertyRow::clone(ConstStringList* constStrings) const -{ - PropertyRow::setConstStrings(constStrings); - Serialization::BinOArchive oa; - SharedPtr self(const_cast(this)); - oa(self, "row", "Row"); - - Serialization::BinIArchive ia; - ia.open(oa); - SharedPtr clonedRow; - ia(clonedRow, "row", "Row"); - PropertyRow::setConstStrings(0); - if (clonedRow) - clonedRow->setHideChildren(hideChildren_); - return clonedRow; -} - -void PropertyRow::drawStaticText([[maybe_unused]] QPainter& p, [[maybe_unused]] const QRect& widgetRect) -{ -} - -void PropertyRow::Serialize(IArchive& ar) -{ - serializeValue(ar); - - ar(ConstStringWrapper(constStrings_, name_), "name", "name"); - ar(ConstStringWrapper(constStrings_, label_), "label", "label"); - ar(ConstStringWrapper(constStrings_, typeName_), "type", "type"); - ar(reinterpret_cast >&>(children_), "children", "!^children"); - if(ar.IsInput()){ - labelChanged_ = true; - layoutChanged_ = true; - PropertyRow::iterator it; - for(it = begin(); it != end(); ){ - PropertyRow* row = *it; - if(row){ - row->setParent(this); - ++it; - } - else{ - YASLI_ASSERT_STR(false, "Missing property row"); - it = erase(it); - } - } - } -} - -bool PropertyRow::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason != e.REASON_RELEASE) - return e.tree->spawnWidget(this, e.force); - else - return false; -} - -void PropertyRow::setLabelChanged() -{ - for(PropertyRow* row = this; row != 0; row = row->parent()) - row->labelChanged_ = true; -} - -void PropertyRow::setLayoutChanged() -{ - layoutChanged_ = true; -} - -void PropertyRow::setLabelChangedToChildren() -{ - size_t numChildren = children_.size(); - for (size_t i = 0; i < numChildren; ++i) { - children_[i]->labelChanged_ = true; - children_[i]->setLabelChangedToChildren(); - } -} - -void PropertyRow::setLayoutChangedToChildren() -{ - size_t numChildren = children_.size(); - for (size_t i = 0; i < numChildren; ++i) { - children_[i]->layoutChanged_ = true; - children_[i]->setLayoutChangedToChildren(); - } -} - -void PropertyRow::setLabel(const char* label) -{ - if (!label) - label = ""; - if (label_ != label) { - label_ = label; - setLabelChanged(); - } -} - -void PropertyRow::propagateFlagsTopToBottom() -{ - // these flags are reset in parseControlCodes - if (!userReadOnly_ && !userWidgetToContent_) - return; - size_t numChildren = children_.size(); - for (size_t i = 0; i < numChildren; ++i) { - PropertyRow* r = children_[i]; - if (userReadOnly_) - r->userReadOnly_ = true; - if (userWidgetToContent_) { - r->userWidgetToContent_ = true; - r->userFixedWidget_ = true; - } - r->propagateFlagsTopToBottom(); - } -} - -void PropertyRow::setTooltip(const char* tooltip) -{ - tooltip_ = tooltip; -} - -bool PropertyRow::setValidatorEntry(int index, int count) -{ - if (index != validatorIndex_ || count != validatorCount_) { - validatorIndex_ = min(index, 0xffff); - validatorCount_ = min(count, 0xff); - validatorsHeight_ = 0; - return true; - } - return false; -} - -void PropertyRow::resetValidatorIcons() -{ - validatorHasWarnings_ = false; - validatorHasErrors_ = false; -} - -void PropertyRow::addValidatorIcons(bool hasWarnings, bool hasErrors) -{ - if (hasWarnings ) - validatorHasWarnings_ = true; - if (hasErrors) - validatorHasErrors_ = true; -} - -void PropertyRow::updateLabel(const QPropertyTree* tree, [[maybe_unused]] int index, bool parentHidesNonInlineChildren) -{ - if (!labelChanged_) { - if (pulledUp_) - parent()->hasPulled_ = true; - return; - } - - hasPulled_ = false; - - int numChildren = (int)children_.size(); - for (int i = 0; i < numChildren; ++i) { - PropertyRow* row = children_[i]; - row->updateLabel(tree, i, hideChildren_); - } - - parseControlCodes(tree, label_, true); - bool hiddenByParentFlag = parentHidesNonInlineChildren && !pulledUp_; - visible_ = (*labelUndecorated_ != '\0' || userFullRow_ || pulledUp_ || isRoot()) && !hiddenByParentFlag; - - propagateFlagsTopToBottom(); - - if(pulledContainer()) - pulledContainer()->_setExpanded(expanded()); - - layoutChanged_ = true; - labelChanged_ = false; -} - -struct ResetSerializerOp{ - ScanResult operator()(PropertyRow* row) - { - row->setSerializer(SStruct()); - return SCAN_CHILDREN_SIBLINGS; - } -}; - -void PropertyRow::parseControlCodes(const QPropertyTree* tree, const char* ptr, bool changeLabel) -{ - if (changeLabel) { - userFullRow_ = false; - pulledUp_ = false; - pulledBefore_ = false; - userFixedWidget_ = false; - userPackCheckboxes_ = false; - userWidgetSize_ = -1; - userWidgetToContent_ = false; - fontWeight_ = FontWeight::Undefined; - userNonCopyable_ = false; - } - - while(true){ - if(*ptr == '^'){ - if(parent() && !parent()->isRoot()){ - if(pulledUp_) - pulledBefore_ = true; - pulledUp_ = true; - parent()->hasPulled_ = true; - - if(pulledUp() && isContainer()) - parent()->setPulledContainer(this); - } - } - else if(*ptr == '='){ - userWidgetToContent_ = true; - } - else if(*ptr == '+'){ - bool isFirstUpdate = labelUndecorated_ == 0; - if (isFirstUpdate) - _setExpanded(true); - } - else if(*ptr == '-'){ - bool isFirstUpdate = labelUndecorated_ == 0; - if (isFirstUpdate) - _setExpanded(false); - } - else if(*ptr == '<') - userFullRow_ = true; - else if(*ptr == '>'){ - userFixedWidget_ = true; - const char* p = ++ptr; - while(*p >= '0' && *p <= '9') - ++p; - if(*p == '>'){ - userWidgetSize_ = atoi(ptr); - ptr = ++p; - } - continue; - } - else if(*ptr == '~'){ - ResetSerializerOp op; - scanChildren(op); - } - else if(*ptr == '!'){ - if(userReadOnly_) - userReadOnlyRecurse_ = true; - userReadOnly_ = true; - } - else if(*ptr == '|'){ - userPackCheckboxes_ = true; - } - else if(*ptr == '['){ - ++ptr; - PropertyRow::iterator it; - for(it = children_.begin(); it != children_.end(); ++it) - (*it)->parseControlCodes(tree, ptr, false); - - int counter = 1; - while(*ptr){ - if(*ptr == ']' && !--counter) - break; - else if(*ptr == '[') - ++counter; - ++ptr; - } - } - else if(*ptr == '@'){ - switch (ptr[1]) - { - case 'b': case 'B': - fontWeight_ = FontWeight::Bold; - ++ptr; - break; - - case 'r': case 'R': - fontWeight_ = FontWeight::Regular; - ++ptr; - break; - - default: - break; - } - } - else if(*ptr == ':'){ - userNonCopyable_ = true; - } - else - break; - ++ptr; - } - - if (isContainer()) { - // automatically inline children for short arrays - PropertyRowContainer* container = static_cast(this); - int numChildren = (int)container->count(); - if (container->isFixedSize() && numChildren > 0 && numChildren <= 4) { - if (container->childByIndex(0)->inlineInShortArrays()) { - for(int i = 0; i < numChildren; ++i) { - PropertyRow* child = container->childByIndex(i); - child->pulledUp_ = true; - if (child->label_) - child->labelUndecorated_ = child->label_ + strlen(child->label_); - } - hasPulled_ = true; - container->setInlined(true); - } - } - } - - if (changeLabel) - labelUndecorated_ = ptr; - - labelChanged(); -} - -const char* PropertyRow::typeNameForFilter([[maybe_unused]] QPropertyTree* tree) const -{ - return typeName(); -} - -void PropertyRow::updateTextSizeInitial(const QPropertyTree* tree, int index, bool fontChanged) -{ - char containerLabel[1024] = ""; - const char* text = rowText(containerLabel, sizeof(containerLabel), tree, index); - if(text[0] == '\0' || widgetPlacement() == WIDGET_INSTEAD_OF_TEXT) { - textSizeInitial_ = 0; - textHash_ = 0; - } - else{ - unsigned hash = calculateHash(text); - const QFont* font = rowFont(tree); - hash = calculateHash(font, hash); - if(hash != textHash_ || fontChanged){ - QFontMetrics fm(*font); - textSizeInitial_ = fm.horizontalAdvance(text); - textHash_ = hash; - } - } -} - -void PropertyRow::calculateMinimalSize(const QPropertyTree* tree, int posX, int availableWidth, bool force, int* _extraSizeRemainder, int* _extraSize, int index) -{ - PropertyRow* nonPulled = nonPulledParent(); - if (!layoutChanged_ && !force && !nonPulled->layoutChanged_) { - DEBUG_TRACE_ROW("... skipping size for %s", label()); - return; - } - plusSize_ = 0; - if(isRoot()) - expanded_ = true; - else{ - if(nonPulled->isRoot() || (tree->treeStyle().compact && nonPulled->parent()->isRoot())) - _setExpanded(true); - else if(!pulledUp()) - plusSize_ = int(tree->treeStyle().firstLevelIndent * tree->_defaultRowHeight()); - - if(parent()->pulledUp()) - pulledBefore_ = false; - - if(!visible(tree) && !(isContainer() && pulledUp())){ - size_ = QPoint(0, 0); - DEBUG_TRACE_ROW("row '%s' got zero size", label()); - layoutChanged_ = false; - return; - } - } - - int minWidgetSize = widgetSizeMin(tree); - widgetSize_ = minWidgetSize; - if (_extraSizeRemainder && *_extraSizeRemainder) { - widgetSize_ += *_extraSizeRemainder; - *_extraSizeRemainder = 0; - } - - updateTextSizeInitial(tree, index, force); - - int height = isRoot() ? 0 : tree->_defaultRowHeight() + floorHeight(); - size_.setY(height); - - pos_.setX(posX); - posX += plusSize_; - - int extraSizeStorage = 0; - int& extraSize = !pulledUp() || !_extraSize ? extraSizeStorage : *_extraSize; - - int validatorIconsWidth = 0; - if (validatorHasErrors_) - validatorIconsWidth += tree->_defaultRowHeight(); - if (validatorHasWarnings_) - validatorIconsWidth += tree->_defaultRowHeight(); - - int freePulledChildren = 0; - if(!pulledUp()){ - int minTextSize = 0; - int totalMinimalWidth = 0; - calcPulledRows(&minTextSize, &freePulledChildren, &totalMinimalWidth, tree, index); - DEBUG_TRACE_ROW("%s minTextSize: %i, totalMinimalWidth: %i", label(), minTextSize, totalMinimalWidth); - size_.setX(totalMinimalWidth); - extraSize = (tree->rightBorder() - tree->leftBorder()) - totalMinimalWidth - posX - validatorIconsWidth; - DEBUG_TRACE_ROW("%s extraSize 0: %i", label(), extraSize); - - float textScale = 1.0f; - bool hideOwnText = false; - if(extraSize < 0){ - // hide container item text first - if (parent() && parent()->isContainer()){ - extraSize += textSizeInitial_; - minTextSize -= textSizeInitial_; - hideOwnText = true; - } - - textScale = minTextSize ? clamp(1.0f - float(-extraSize) / minTextSize, 0.0f, 1.0f) : 0; - } - setTextSize(tree, index, textScale); - - if (hideOwnText) { - textSize_ = 0; - DEBUG_TRACE_ROW("%s hideOwnText", label()); - } - } - - DEBUG_TRACE_ROW("%s extraSize 1: %i", label(), extraSize); - - WidgetPlacement widgetPlace = widgetPlacement(); - - int numChildren = (int)children_.size(); - - if(widgetPlace == WIDGET_ICON){ - if (tree->treeStyle().alignLabelsToRight && !pulledUp_ && !pulledBefore_ && !hasPulled_ && numChildren == 0) - widgetPos_ = widgetSize_ ? tree->leftBorder() + xround((tree->rightBorder() - tree->leftBorder())* (1.f - tree->treeStyle().valueColumnWidth)) : -1000; - else - widgetPos_ = widgetSize_ ? posX : -1000; - posX += widgetSize_; - if (tree->treeStyle().alignLabelsToRight) - textPos_ = widgetPos_ + widgetSize_ + TEXT_VALUE_SPACING; - else - textPos_ = posX; - posX += textSize_; - } - - bool hasPulledBefore = false; - if (hasPulled_) { - for (int i = 0; i < numChildren; ++i) { - PropertyRow* row = children_[i]; - if(row->visible(tree) && row->pulledBefore()){ - row->calculateMinimalSize(tree, posX, availableWidth, force, 0, &extraSize, i); - posX += row->size_.x(); - hasPulledBefore = true; - } - } - if (hasPulledBefore) - posX += TEXT_VALUE_SPACING; - } - - if(widgetPlace != WIDGET_ICON){ - textPos_ = posX; - posX += textSize_; - } - - if(widgetPlace == WIDGET_AFTER_NAME){ - if (textSize_) - posX += TEXT_VALUE_SPACING; - widgetPos_ = posX; - posX += widgetSize_; - } - - if (widgetPlace == WIDGET_INSTEAD_OF_TEXT) - widgetPos_ = posX; - - if(widgetPlace == WIDGET_VALUE || widgetPlace == WIDGET_AFTER_PULLED || (freePulledChildren > 0)){ - if (textSize_) - posX += TEXT_VALUE_SPACING; - - if(!pulledUp() && extraSize > 0){ - // align widget value to value column - if(!isFullRow(tree)) - { - int oldX = posX; - - bool rightAlignment = tree->treeStyle().alignLabelsToRight && !hasPulledBefore; - int maxX = rightAlignment ? textSize_ + TEXT_VALUE_SPACING: posX; - int newX = max(tree->leftBorder() + xround((tree->rightBorder() - tree->leftBorder())* (1.f - tree->treeStyle().valueColumnWidth)), maxX); - - if (rightAlignment) { - textPos_ = newX - textSize_ - TEXT_VALUE_SPACING; - widgetPos_ = textPos_ - widgetSize_ - TEXT_VALUE_SPACING; - } - - int xDelta = newX - oldX; - if (xDelta <= extraSize) - { - extraSize -= xDelta; - posX = newX; - } - else - { - posX += extraSize; - extraSize = 0; - } - } - } - } - - int extraSizeRemainder = 0; - if (freePulledChildren > 0) { - extraSizeRemainder = extraSize % freePulledChildren; - extraSize = extraSize / freePulledChildren; - } - - if (widgetPlace == WIDGET_VALUE || widgetPlace == WIDGET_INSTEAD_OF_TEXT) { - if(minWidgetSize && !isWidgetFixed() && extraSize > 0) { - DEBUG_TRACE_ROW("%s widget extraSize: %i+%d", label(), extraSize, extraSizeRemainder); - widgetSize_ += extraSize + extraSizeRemainder; - extraSizeRemainder = 0; - } - - if (widgetPlace != WIDGET_INSTEAD_OF_TEXT) - widgetPos_ = posX; - DEBUG_TRACE_ROW("textSize: %i widgetPos: %i", int(textSize_), int(widgetPos_)); - posX += widgetSize_; - } - - size_.setX(textSize_ + (textSize_ ? TEXT_VALUE_SPACING : 0) + widgetSize_ + validatorIconsWidth); - - int childrenLeft = nonPulled->pos_.x(); - if (parent() != 0){ - if (parent()->parent() == 0) { - if (!tree->treeStyle().doNotIndentSecondLevel) - childrenLeft = aznumeric_cast(childrenLeft + tree->treeStyle().firstLevelIndent * tree->_defaultRowHeight()); - } - else - childrenLeft = aznumeric_cast(childrenLeft + tree->treeStyle().levelIndent * tree->_defaultRowHeight()); - } - - int checkBoxChildren = 0; - for (int i = 0; i < numChildren; ++i) { - PropertyRow* row = children_[i]; - if(!row->visible(tree)) { - DEBUG_TRACE_ROW("skipping invisible child: %s", row->label()); - continue; - } - if(row->pulledUp()){ - if(!row->pulledBefore()){ - row->calculateMinimalSize(tree, posX, availableWidth, force, &extraSizeRemainder, &extraSize, i); - posX += row->size_.x(); - posX += TEXT_VALUE_SPACING; - } - size_.setX(size_.x() + TEXT_VALUE_SPACING + row->size_.x()); - size_.setY(max(size_.y(), row->size_.y())); - } - else if(expanded()){ - - row->calculateMinimalSize(tree, childrenLeft, availableWidth, force, 0, &extraSize, i); - if (row->widgetPlacement() == WIDGET_ICON && row->count() == 0) - ++checkBoxChildren; - } - } - - // align checkboxes into two columns - if (tree->packCheckboxes() || userPackCheckboxes_) { - if (expanded() && checkBoxChildren > 0 && hasVisibleChildren(tree)) { - int widthTotal = tree->rightBorder() - 16 - childrenLeft - plusSize_; - int widthNextToLastCheckbox = 0; - int left = childrenLeft + plusSize_; - PropertyRow* previousCheckbox = nullptr; - - std::vector checkboxesToRealign; - bool hasChanges = false; - - for (int i = 0; i < numChildren; ++i) { - PropertyRow* row = children_[i]; - if(!row->visible(tree)) - continue; - if(row->widgetPlacement() != WIDGET_ICON || row->count() > 0) { - previousCheckbox = 0; - continue; - } - if(!row->pulledUp()){ - int checkboxWidth = row->textSize_ + tree->_defaultRowHeight()/* + TEXT_VALUE_SPACING*/; - - if (previousCheckbox && widthNextToLastCheckbox >= widthTotal / 2 && checkboxWidth < widthTotal / 2) { - row->packedAfterPreviousRow_ = true; - widthNextToLastCheckbox = 0; - - row->pos_.setX(left + widthTotal / 2); - row->widgetPos_ = row->pos_.x(); - row->textPos_ = row->pos_.x() + row->widgetSize_; - row->size_.setX(widthTotal / 2); - - previousCheckbox->size_.setX(widthTotal / 2); - previousCheckbox->pos_.setX(left); - previousCheckbox->widgetPos_ = left; - previousCheckbox->textPos_ = left + previousCheckbox->widgetSize_; - row->size_.setX(widthTotal / 2); - previousCheckbox = 0; - hasChanges = true; - } - else { - row->packedAfterPreviousRow_ = false; - widthNextToLastCheckbox = widthTotal - checkboxWidth; - previousCheckbox = row; - } - - if (previousCheckbox && tree->treeStyle().alignLabelsToRight) - checkboxesToRealign.push_back(previousCheckbox); - } - } - - if (hasChanges) { - for (int i = 0; i < checkboxesToRealign.size(); ++i) { - PropertyRow* row = checkboxesToRealign[i]; - row->size_.setX(widthTotal / 2); - row->pos_.setX(left); - row->widgetPos_ = left; - row->textPos_ = left + row->widgetSize_; - } - } - } - } - - if (widgetPlace == WIDGET_AFTER_PULLED) - { - posX += TEXT_VALUE_SPACING; - widgetPos_ = posX; - } - - if(!pulledUp()) - size_.setX(tree->rightBorder() - pos_.x()); - DEBUG_TRACE_ROW("calculateMinimalSize: '%s' %i %i (%s)", label(), size_.x(), size_.y(), isRoot() ? "root" : "non-root"); - layoutChanged_ = false; - - validatorsHeight_ = 0; - if (!pulledUp() && !pulledBefore() && (validatorCount_ != 0 || hasPulled_)) { - QFontMetrics fm(tree->font()); - int padding = aznumeric_cast(0.1f * tree->_defaultRowHeight()); - auto calculateValidatorHeight = [&](PropertyRow* row) { - const ValidatorEntry* entries = tree->_validatorBlock()->GetEntry(row->validatorIndex_, row->validatorCount_); - if (entries) { - for (int i = 0; i < row->validatorCount_; ++i) { - int startPos = pos_.x() + plusSize_; - QRect r = fm.boundingRect(0, 0, availableWidth - startPos - tree->_defaultRowHeight() - padding * 2, 0, - Qt::TextWordWrap|Qt::AlignTop, QString::fromUtf8(entries[i].message.c_str())); - validatorsHeight_ += max(tree->_defaultRowHeight(), r.height() + padding * 2) + padding * 3; - } - } - }; - calculateValidatorHeight(this); - visitPulledRows(this, calculateValidatorHeight); - } - - size_.setY(size_.y() + validatorsHeight_); -} - -void PropertyRow::adjustVerticalPosition(const QPropertyTree* tree, int& totalHeight) -{ - int defaultRowHeight = tree->_defaultRowHeight(); - pos_.setY(totalHeight); - int rowHeight = size_.y() + int(defaultRowHeight * (tree->treeStyle().rowSpacing - 1.0f) + 0.5f); - - if (packedAfterPreviousRow_) - pos_.setY(totalHeight - rowHeight); - else - pos_.setY(totalHeight); - - if(!pulledUp()) { - if (!packedAfterPreviousRow_) - totalHeight += rowHeight; - } - else{ - pos_.setY(parent()->pos_.y()); - expanded_ = parent()->expanded(); - } - PropertyRow* nonPulled = nonPulledParent(); - - DEBUG_TRACE_ROW("adjustRect: %s %i %i %i %i %s", label(), pos_.x(), pos_.y(), size_.x(), size_.y(), pulledUp() ? "pulled" : ""); - - if (expanded_ || hasPulled_) { - for(PropertyRows::iterator it = children_.begin(); it != children_.end(); ++it){ - PropertyRow* row = *it; - if(row->visible(tree) && (nonPulled->expanded() || row->pulledUp())) - row->adjustVerticalPosition(tree, totalHeight); - } - } - int delta = totalHeight - pos_.y(); - if (delta > USHRT_MAX) - delta = USHRT_MAX; - heightIncludingChildren_ = delta; -} - -void PropertyRow::setTextSize(const QPropertyTree* tree, int index, float mult) -{ - updateTextSizeInitial(tree, index, false); - - textSize_ = int(textSizeInitial_ * mult); - - size_t numChildren = children_.size(); - for (size_t i = 0; i < numChildren; ++i) { - PropertyRow* row = children_[i]; - if(row->pulledUp()) - row->setTextSize(tree, 0, mult); - } -} - -void PropertyRow::calcPulledRows(int* minTextSize, int* freePulledChildren, int* minimalWidth, const QPropertyTree *tree, int index) -{ - updateTextSizeInitial(tree, index, false); - - *minTextSize += textSizeInitial_; - WidgetPlacement widgetPlace = widgetPlacement(); - if((widgetPlace == WIDGET_VALUE || widgetPlace == WIDGET_INSTEAD_OF_TEXT || widgetPlace == WIDGET_AFTER_PULLED) && !isWidgetFixed()) - *freePulledChildren += 1; - *minimalWidth += textSizeInitial_ + widgetSizeMin(tree); // spacing - bool hasWidget = widgetPlace == WIDGET_VALUE || - widgetPlace == WIDGET_INSTEAD_OF_TEXT || - widgetPlace == WIDGET_AFTER_PULLED; - if (textSizeInitial_ && (hasWidget || hasPulled_)) - *minimalWidth += TEXT_VALUE_SPACING; - if (hasWidget && hasPulled_) - *minimalWidth += TEXT_VALUE_SPACING; - - size_t numChildren = children_.size(); - int pulledCount = 0; - for (size_t i = 0; i < numChildren; ++i) { - PropertyRow* row = children_[i]; - if(row->pulledUp()) - { - ++pulledCount; - row->calcPulledRows(minTextSize, freePulledChildren, minimalWidth, tree, index); - } - } - if (hasPulled_) - *minimalWidth += (pulledCount - 1) * TEXT_VALUE_SPACING; -} - -PropertyRow* PropertyRow::findSelected() -{ - if(selected()) - return this; - iterator it; - for(it = children_.begin(); it != children_.end(); ++it){ - PropertyRow* result = (*it)->findSelected(); - if(result) - return result; - } - return 0; -} - -PropertyRow* PropertyRow::find(const char* name, const char* nameAlt, const char* typeName) -{ - iterator it; - for(it = children_.begin(); it != children_.end(); ++it){ - PropertyRow* row = *it; - if(((row->name() == name) || strcmp(row->name(), name) == 0) && - ((nameAlt == 0) || (row->label() != 0 && strcmp(row->label(), nameAlt) == 0)) && - ((typeName == 0) || (row->typeName() != 0 && strcmp(row->typeName(), typeName) == 0))) - return row; - } - return 0; -} - -PropertyRow* PropertyRow::findFromIndex(int* outIndex, const char* name, const char* typeName, int startIndex) const -{ - int numChildren = (int)children_.size(); - startIndex = min(startIndex, numChildren); - - for (int i = startIndex; i < numChildren; ++i) { - PropertyRow* row = children_[i]; - if(((row->name() == name) || strcmp(row->name(), name) == 0) && - ((row->typeName() == typeName || strcmp(row->typeName(), typeName) == 0))) { - *outIndex = i; - return row; - } - } - - for (int i = 0; i < startIndex; ++i) { - PropertyRow* row = children_[i]; - if(((row->name() == name) || strcmp(row->name(), name) == 0) && - ((row->typeName() == typeName || strcmp(row->typeName(), typeName) == 0))) { - *outIndex = i; - return row; - } - } - - *outIndex = -1; - return 0; -} - -const PropertyRow* PropertyRow::find(const char* name, const char* nameAlt, const char* typeName) const -{ - return const_cast(this)->find(name, nameAlt, typeName); -} - -bool PropertyRow::processesKey([[maybe_unused]] QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete && ev->modifiers() == Qt::NoModifier) - { - return true; - } - else if (ev->key() == Qt::Key_Insert && ev->modifiers() == Qt::SHIFT) - { - return true; - } - - return false; -} - -bool PropertyRow::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if(parent() && parent()->isContainer() && !parent()->userReadOnly()){ - PropertyRowContainer* container = static_cast(parent()); - std::unique_ptr menuHandler = - std::unique_ptr(createMenuHandler(tree, container)); - menuHandler->element = this; - if(ev->key() == Qt::Key_Delete && ev->modifiers() == Qt::NoModifier) { - menuHandler->onMenuChildRemove(); - return true; - } - else if(ev->key() == Qt::Key_Insert && ev->modifiers() == Qt::SHIFT){ - menuHandler->onMenuChildInsertBefore(); - return true; - } - } - return false; -} - -ContainerMenuHandler* PropertyRow::createMenuHandler(QPropertyTree* tree, PropertyRowContainer* container) -{ - return new ContainerMenuHandler(tree, container); -} - -bool PropertyRow::onContextMenu(QMenu &menu, QPropertyTree* tree) -{ - PropertyRowContainer* container = 0; - if (parent() && parent()->isContainer()) - container = static_cast(parent()); - if (!container) { - PropertyRow* nonPulled = nonPulledParent(); - if (nonPulled->parent() && nonPulled->parent()->isContainer()) - container = static_cast(nonPulled->parent()); - } - if(container){ - PropertyRow* containerElement = this; - ContainerMenuHandler* handler = createMenuHandler(tree, container); - handler->element = containerElement; - tree->addMenuHandler(handler); - if(!container->isFixedSize()){ - if(!menu.isEmpty()) - { - menu.addSeparator(); - } - - menu.addAction("Insert Before", handler, SLOT(onMenuChildInsertBefore()), QKeySequence("Shift+Insert"))->setEnabled(!container->userReadOnly()); - menu.addAction("Remove", handler, SLOT(onMenuChildRemove()), QKeySequence("Delete"))->setEnabled(!container->userReadOnly()); - } - } - - if(hasVisibleChildren(tree)){ - if(!menu.isEmpty()) - { - menu.addSeparator(); - } - - menu.addAction("Expand", tree, SLOT(expandAll())); - menu.addAction("Collapse", tree, SLOT(collapseAll())); - } - - return !menu.isEmpty(); -} - -int PropertyRow::level() const -{ - int result = 0; - const PropertyRow* row = this; - while(row){ - row = row->parent(); - ++result; - } - return result; -} - -PropertyRow* PropertyRow::nonPulledParent() -{ - PropertyRow* row = this; - while(row->pulledUp()) - row = row->parent(); - return row; -} - -bool PropertyRow::pulledSelected() const -{ - if(selected()) - return true; - const PropertyRow* row = this; - while(row->parent() && row->pulledUp()){ - row = row->parent(); - if(row->selected()) - return true; - } - return false; -} - - -const QFont* PropertyRow::rowFont(const QPropertyTree* tree) const -{ - switch (fontWeight_) - { - case FontWeight::Regular: - return &tree->font(); - - case FontWeight::Bold: - return &tree->_boldFont(); - - default: - // Bold for structures/containers - return hasVisibleChildren(tree) || (isContainer() && !static_cast(this)->isInlined()) ? &tree->_boldFont() : &tree->font(); - } -} - -QRect PropertyRow::rectIncludingChildren(const QPropertyTree* tree) const -{ - QRect r = rect(); - if (expanded()) - for (size_t i = 0; i < children_.size(); ++i) - if (children_[i]->visible(tree)) - r = r.united(children_[i]->rectIncludingChildren(tree)); - return r; -} - -static void drawVerticalGradient(QPainter& painter, const QRect& rect, const QColor& topColor, const QColor& bottomColor) -{ - QLinearGradient gradient(rect.left(), rect.top(), rect.left(), rect.bottom()); - gradient.setColorAt(0.0f, topColor); - gradient.setColorAt(1.0f, bottomColor); - painter.fillRect(rect, QBrush(gradient)); -} - - -void PropertyRow::drawRow(QPainter& painter, const QPropertyTree* tree, int index, bool selectionPass) -{ - QRect rowRect = rect(); - QRect selectionRect = rowRect; - if (!isRoot()) { - bool selectionDrawn = !tree->hideSelection() || tree->hasFocusOrInplaceHasFocus(); - if(!pulledUp()) - selectionRect = rowRect.adjusted(plusSize_ - (tree->treeStyle().compact ? 2 : 3), -2, 1, 1); - else - selectionRect = rowRect.adjusted(-2, -2, 2, 1); - if (selectionPass) { - if (tree->treeStyle().groupShadows && this->level() == 2 && !children_.empty()) { - QRect childrenRect = this->rectIncludingChildren(tree); - int top = rowRect.bottom() + 2; - if (top < childrenRect.bottom()) - { - childrenRect = QRect(-tree->leftBorder(), top, tree->width() - 16 + tree->leftBorder(), childrenRect.bottom() + 3 - top); - QColor windowColor = tree->palette().color(QPalette::Button); - QColor shadowColor = tree->palette().color(QPalette::Mid); - QColor backgroundColor(interpolateColor(windowColor, shadowColor, tree->treeStyle().groupShade)); - painter.fillRect(childrenRect, QBrush(backgroundColor)); - - int levelShadowOpacity = tree->treeStyle().levelShadowOpacity; - int h = int(tree->_defaultRowHeight() * 0.75f); - drawVerticalGradient(painter, QRect(childrenRect.left()+1, childrenRect.top(), childrenRect.width()-2, h), QColor(0, 0, 0, levelShadowOpacity), QColor(0, 0, 0, 0)); - drawVerticalGradient(painter, QRect(childrenRect.left(), childrenRect.top(), 1, h*2), QColor(0, 0, 0, levelShadowOpacity), QColor(0, 0, 0, 0)); - drawVerticalGradient(painter, QRect(childrenRect.width()-2, childrenRect.top(), 1, h*2), QColor(0, 0, 0, levelShadowOpacity), QColor(0, 0, 0, 0)); - - h = (int(tree->_defaultRowHeight() * 0.25f)); - drawVerticalGradient(painter, QRect(childrenRect.left() + 1, childrenRect.bottom() - h, childrenRect.width() - 2, h), QColor(0, 0, 0, 0), QColor(0, 0, 0, levelShadowOpacity)); - drawVerticalGradient(painter, QRect(childrenRect.left(), childrenRect.bottom() - h*2, 1, h*2), QColor(0, 0, 0, 0), QColor(0, 0, 0, levelShadowOpacity)); - drawVerticalGradient(painter, QRect(childrenRect.width()-2, childrenRect.bottom() - h*2, 1, h*2), QColor(0, 0, 0, 0), QColor(0, 0, 0, levelShadowOpacity)); - } - } - if (tree->treeStyle().groupRectangle && this->level() < 3 && (canBeToggled(tree) || isContainer() || widgetPlacement() == WIDGET_NONE)) - { - QColor windowColor = tree->palette().color(QPalette::Button); - QColor shadowColor = tree->palette().color(QPalette::Mid); - QColor backgroundColor(interpolateColor(windowColor, shadowColor, tree->treeStyle().groupShade)); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setBrush(QBrush(backgroundColor)); - painter.setPen(Qt::NoPen); - painter.drawRoundedRect(rowRect.adjusted(0, tree->_defaultRowHeight() / 8, 0, -tree->_defaultRowHeight() / 8), 4, 4); - painter.setRenderHint(QPainter::Antialiasing, false); - - } - } - else{ - PropertyDrawContext context; - context.tree = tree; - context.widgetRect = widgetRect(tree); - context.lineRect = floorRect(tree); - context.painter = &painter; - context.captured = tree->_isCapturedRow(this); - context.m_pressed = tree->_pressedRow() == this; - - QColor textColor = tree->palette().buttonText().color(); - - char containerLabel[1024] = ""; - wstring text = toWideChar(rowText(containerLabel, sizeof(containerLabel), tree, index)); - - if (tree->treeStyle().showHorizontalLines) { - if(textSize_ && !isStatic() && widgetPlacement() == WIDGET_VALUE && - !pulledUp() && !isFullRow(tree) && !hasPulled() && floorHeight() == 0) - { - QRect rect(textPos_ - 1, rowRect.bottom() - 2, context.lineRect.width() - (textPos_ - 1), 1); - - QLinearGradient gradient(rect.left(), rect.top(), rect.right(), rect.top()); - gradient.setColorAt(0.0f, tree->palette().color(QPalette::Button)); - gradient.setColorAt(0.6f, tree->palette().color(QPalette::Light)); - gradient.setColorAt(0.95f, tree->palette().color(QPalette::Light)); - gradient.setColorAt(1.0f, tree->palette().color(QPalette::Button)); - QBrush brush(gradient); - painter.fillRect(rect, brush); - } - } - - - if(selectionDrawn && pulledSelected()){ - textColor = tree->palette().highlight().color(); - } - else{ - overrideTextColor(textColor); - } - - if(!tree->treeStyle().compact || !parent()->isRoot()){ - if(hasVisibleChildren(tree)){ - drawPlus(painter, tree, plusRect(tree), expanded(), selected(), expanded()); - } - } - - if(!isStatic() && context.widgetRect.isValid()) - redraw(context); - - if(textSize_ > 0){ - const QFont* font = rowFont(tree); - tree->_drawRowLabel(painter, text.c_str(), font, textRect(tree), textColor); - } - - if (validatorHasWarnings_) { - QImage* icon = tree->_iconCache()->getImageForIcon(Serialization::IconXPM(warning_xpm)); - - QRect r = validatorWarningIconRect(tree); - r.setWidth(tree->_defaultRowHeight()); - painter.drawImage(r.center() - QPoint(icon->width() / 2, icon->height() / 2), *icon); - } - if (validatorHasErrors_) { - QImage* icon = tree->_iconCache()->getImageForIcon(Serialization::IconXPM(error_xpm)); - QRect r = validatorErrorIconRect(tree); - r.setWidth(tree->_defaultRowHeight()); - painter.drawImage(r.center() - QPoint(icon->width() / 2, icon->height() / 2), *icon); - } - } - } - - if (!selectionPass && validatorsHeight_ > 0) - { - QRect totalRect = validatorRect(tree); - QFontMetrics fm(tree->font()); - const int padding = aznumeric_cast(tree->_defaultRowHeight() * 0.1f); - int offset = padding; - auto drawFunc = [&](PropertyRow* row) { - if (const ValidatorEntry* validatorEntries = tree->_validatorBlock()->GetEntry(row->validatorIndex_, row->validatorCount_)) { - for (int i = 0; i < row->validatorCount_; ++i) { - const ValidatorEntry* validatorEntry = validatorEntries + i; - bool isError = validatorEntry->type == VALIDATOR_ENTRY_ERROR; - - QImage* icon = tree->_iconCache()->getImageForIcon(isError ? Serialization::IconXPM(error_xpm) : Serialization::IconXPM(warning_xpm)); - QColor brushColor = isError ? QColor(255, 64, 64, 192) : QPalette().color(QPalette::ToolTipBase); - QColor penColor = isError ? QColor(64, 0, 0, 255) : QPalette().color(QPalette::ToolTipText); - - QRect rect(totalRect.left(), totalRect.top() + offset, - totalRect.width(), totalRect.height() - offset); - QRect textRect = rect.adjusted(tree->_defaultRowHeight() + padding, padding, -padding, -padding); - const char* text = validatorEntry->message.c_str(); - int textHeight = max(tree->_defaultRowHeight(), - fm.boundingRect(textRect, Qt::TextWordWrap, text, 0, 0).height() + padding * 2); - rect.setHeight(textHeight + padding * 2); - textRect.setHeight(textHeight); - - QPen pen(penColor); - pen.setWidth(1); - painter.setPen(QPen(penColor)); - painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(brushColor); - painter.translate(-0.5f, -0.5f); - painter.drawRoundedRect(rect, 5, 5, Qt::AbsoluteSize); - painter.translate(0.5f, 0.5f); - painter.setPen(penColor); - painter.setBrush(QBrush()); - QTextOption opt; - opt.setWrapMode(QTextOption::WordWrap); - opt.setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - painter.drawText(textRect, text, opt); - textRect.setHeight(0xffff); - QRect iconRect(rect.left(), rect.top(), tree->_defaultRowHeight(), rect.height()); - painter.drawImage(iconRect.center() - QPoint(icon->width() / 2, icon->height() / 2), *icon); - offset += rect.height() + padding; - } - } - }; - drawFunc(this); - visitPulledRows(this, drawFunc); - } -} - -void PropertyRow::drawPlus(QPainter& p, const QPropertyTree* tree, const QRect& rect, bool expanded, [[maybe_unused]] bool selected, [[maybe_unused]] bool grayed) const -{ - QStyleOption option; - option.rect = rect; - option.state = QStyle::State_Enabled | QStyle::State_Children; - if (expanded) - option.state |= QStyle::State_Open; - p.setPen(QPen()); - p.setBrush(QBrush()); - - // create a widget for context so that the stylesheet is applied: - QWidget tempWidgetForContext; - QStyle::PrimitiveElement elementToUse = QStyle::PE_IndicatorArrowRight; - if (expanded) - elementToUse = QStyle::PE_IndicatorArrowDown; - - tree->style()->drawPrimitive(elementToUse, &option, &p, &tempWidgetForContext); -} - -bool PropertyRow::visible(const QPropertyTree* tree) const -{ - if (tree->_isDragged(this)) - return false; - return ((visible_ || !tree->hideUntranslated()) && (matchFilter_ || belongsToFilteredRow_)); -} - -bool PropertyRow::canBeToggled(const QPropertyTree* tree) const -{ - if(!visible(tree)) - return false; - if((tree->treeStyle().compact && (parent() && parent()->isRoot())) || (isContainer() && pulledUp()) || !hasVisibleChildren(tree)) - return false; - return !empty(); -} - -bool PropertyRow::canBeDragged() const -{ - if(parent()){ - if(parent()->isContainer()) - return true; - } - return false; -} - -bool PropertyRow::canBeDroppedOn(const PropertyRow* parentRow, const PropertyRow* beforeChild, const QPropertyTree* tree) const -{ - YASLI_ASSERT(parentRow); - - if(parentRow->pulledContainer()) - parentRow = parentRow->pulledContainer(); - - if(parentRow->isContainer()){ - const PropertyRowContainer* container = static_cast(parentRow); - - if((container->isFixedSize() || container->userReadOnly()) && parent() != parentRow) - return false; - - if(beforeChild && beforeChild->parent() != parentRow) - return false; - - const PropertyRow* defaultRow = container->defaultRow(tree->model()); - if(defaultRow && strcmp(defaultRow->typeName(), typeName()) == 0) - return true; - } - return false; -} - -void PropertyRow::dropInto(PropertyRow* parentRow, PropertyRow* cursorRow, QPropertyTree* tree, bool before) -{ - SharedPtr ref(this); - - PropertyTreeModel* model = tree->model(); - PropertyTreeModel::UpdateLock lock = model->lockUpdate(); - if(parentRow->pulledContainer()) - parentRow = parentRow->pulledContainer(); - if(parentRow->isContainer()){ - tree->model()->rowAboutToBeChanged(tree->model()->root()); // FIXME: select optimal row - setSelected(false); - PropertyRow* oldParent = parent(); - TreePath oldParentPath = tree->model()->pathFromRow(oldParent); - oldParent->erase(this); - if(before) - parentRow->addBefore(this, cursorRow); - else - parentRow->addAfter(this, cursorRow); - model->selectRow(this, true); - TreePath thisPath = tree->model()->pathFromRow(this); - TreePath parentRowPath = tree->model()->pathFromRow(parentRow); - oldParent = tree->model()->rowFromPath(oldParentPath); - if (oldParent) - model->rowChanged(oldParent); // after this call we can get invalid this - if(PropertyRow* newThis = tree->model()->rowFromPath(thisPath)) { - TreeSelection selection; - selection.push_back(thisPath); - model->setSelection(selection); - - // we use path to obtain new row - tree->ensureVisible(newThis); - model->rowChanged(newThis); // after this call row pointers are invalidated - } - parentRow = tree->model()->rowFromPath(parentRowPath); - if (parentRow) - model->rowChanged(parentRow); // after this call row pointers are invalidated - } -} - -void PropertyRow::intersect(const PropertyRow* row) -{ - setMultiValue(multiValue() || row->multiValue() || valueAsString() != row->valueAsString()); - - - int indexSource = 0; - for(int i = 0; i < int(children_.size()); ++i) - { - PropertyRow* testRow = children_[i]; - PropertyRow* matchingRow = row->findFromIndex(&indexSource, testRow->name_, testRow->typeName_, indexSource); - ++indexSource; - if (matchingRow == 0) { - children_.erase(children_.begin() + i); - --i; - } - else { - children_[i]->intersect(matchingRow); - } - } -} - -const char* PropertyRow::rowText(char *containerLabelBuffer, size_t bufsiz, const QPropertyTree* tree, int index) const -{ - if(parent() && parent()->isContainer() && !pulledUp()){ - if (tree->showContainerIndices()) { - if (tree->showContainerIndexLabels()) { - azsnprintf(containerLabelBuffer, bufsiz, " %i. %s", - index + 1 - tree->containerIndicesZeroBased(), - labelUndecorated() ? labelUndecorated() : ""); - } - else { - azsnprintf(containerLabelBuffer, bufsiz, "%i.", - index + 1 - tree->containerIndicesZeroBased()); - } - return containerLabelBuffer; - } - else - return ""; - } - else - return labelUndecorated() ? labelUndecorated() : ""; -} - -bool PropertyRow::hasVisibleChildren(const QPropertyTree* tree, bool internalCall) const -{ - if(empty() || (!internalCall && pulledUp())) - return false; - - PropertyRow::const_iterator it; - for(it = children_.begin(); it != children_.end(); ++it){ - const PropertyRow* child = *it; - if(child->pulledUp()){ - if(child->hasVisibleChildren(tree, true)) - return true; - } - else if(child->visible(tree)) - return true; - } - return false; -} - -const PropertyRow* PropertyRow::hit(const QPropertyTree* tree, QPoint point) const -{ - return const_cast(this)->hit(tree, point); -} - -PropertyRow* PropertyRow::hit(const QPropertyTree* tree, QPoint point) -{ - bool expanded = this->expanded(); - if(isContainer() && pulledUp()) - expanded = parent() ? parent()->expanded() : true; - bool onlyPulled = !expanded; - PropertyRow::const_iterator it; - for(it = children_.begin(); it != children_.end(); ++it){ - PropertyRow* child = *it; - if (!child->visible(tree)) - continue; - if(!onlyPulled || child->pulledUp()) - if(PropertyRow* result = child->hit(tree, point)) - return result; - } - if (QRect(pos_.x(), pos_.y(), size_.x(), size_.y()).contains(point)) - return this; - return 0; -} - -PropertyRow* PropertyRow::findByAddress(const void* addr) -{ - if(searchHandle() == addr) - return this; - else{ - Rows::iterator it; - for(it = children_.begin(); it != children_.end(); ++it){ - PropertyRow* result = it->get()->findByAddress(addr); - if(result) - return result; - } - } - return 0; -} - -const void* PropertyRow::searchHandle() const -{ - return serializer_.pointer(); -} - - -PropertyRow* PropertyRow::findChildFromDescendant(PropertyRow* row) const -{ - PropertyRow* child = row; - Rows::const_iterator it = std::find(children_.begin(), children_.end(), child); - while( it == children_.end() && child ) - { - child = child->parent(); - it = std::find(children_.begin(), children_.end(), child); - } - - return child; -} - -struct GetVerticalIndexOp{ - int index_; - const PropertyRow* row_; - - GetVerticalIndexOp(const PropertyRow* row) : row_(row), index_(0) {} - - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, [[maybe_unused]] int index) - { - if(row == row_) - return SCAN_FINISHED; - if(row->visible(tree) && row->isSelectable() && !row->pulledUp() && !row->packedAfterPreviousRow()) - ++index_; - return row->expanded() ? SCAN_CHILDREN_SIBLINGS : SCAN_SIBLINGS; - } -}; - -int PropertyRow::verticalIndex(QPropertyTree* tree, PropertyRow* row) -{ - GetVerticalIndexOp op(row); - scanChildren(op, tree); - return op.index_; -} - - -struct RowByVerticalIndexOp{ - int index_; - PropertyRow* row_; - - RowByVerticalIndexOp(int index) : row_(0), index_(index) {} - - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, [[maybe_unused]] int index) - { - if(row->visible(tree) && !row->pulledUp() && row->isSelectable() && !row->packedAfterPreviousRow()){ - row_ = row; - if(index_-- <= 0) - return SCAN_FINISHED; - } - return row->expanded() ? SCAN_CHILDREN_SIBLINGS : SCAN_SIBLINGS; - } -}; - -PropertyRow* PropertyRow::rowByVerticalIndex(QPropertyTree* tree, int index) -{ - RowByVerticalIndexOp op(index); - scanChildren(op, tree); - return op.row_; -} - -struct HorizontalIndexOp{ - int index_; - PropertyRow* row_; - bool pulledBefore_; - - HorizontalIndexOp(PropertyRow* row) : row_(row), index_(0), pulledBefore_(row->pulledBefore()) {} - - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, [[maybe_unused]] int index) - { - if(!row->pulledUp()) - return SCAN_SIBLINGS; - if(row->visible(tree) && row->isSelectable() && row->pulledUp() && row->pulledBefore() == pulledBefore_){ - index_ += pulledBefore_ ? -1 : 1; - if(row == row_) - return SCAN_FINISHED; - } - return SCAN_CHILDREN_SIBLINGS; - } -}; - -int PropertyRow::horizontalIndex(QPropertyTree* tree, PropertyRow* row) -{ - if(row == this) - return 0; - HorizontalIndexOp op(row); - if(row->pulledBefore()) - scanChildrenReverse(op, tree); - else - scanChildren(op, tree); - return op.index_; -} - -struct RowByHorizontalIndexOp{ - int index_; - PropertyRow* row_; - bool pulledBefore_; - - RowByHorizontalIndexOp(int index) : row_(0), index_(index), pulledBefore_(index < 0) {} - - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, [[maybe_unused]] int index) - { - if(!row->pulledUp()) - return SCAN_SIBLINGS; - if(row->visible(tree) && row->isSelectable() && row->pulledUp() && row->pulledBefore() == pulledBefore_){ - row_ = row; - if(pulledBefore_ ? ++index_ >= 0 : --index_ <= 0) - return SCAN_FINISHED; - } - return SCAN_CHILDREN_SIBLINGS; - } -}; - -PropertyRow* PropertyRow::rowByHorizontalIndex(QPropertyTree* tree, int index) -{ - if(!index) - return this; - RowByHorizontalIndexOp op(index); - if(index < 0) - scanChildrenReverse(op, tree); - else - scanChildren(op, tree); - return op.row_ ? op.row_ : this; -} - -void PropertyRow::redraw([[maybe_unused]] const PropertyDrawContext& context) -{ - -} - -bool PropertyRow::isFullRow(const QPropertyTree* tree) const -{ - if (tree->treeStyle().fullRowMode) - return true; - if (parent() && parent()->isContainer()) - return true; - return userFullRow(); -} - -QRect PropertyRow::textRect(const QPropertyTree* tree) const -{ - return QRect(textPos_, pos_.y(), textSize_ < textSizeInitial_ ? textSize_ - 1 : textSize_, tree->_defaultRowHeight()); -} - -QRect PropertyRow::widgetRect(const QPropertyTree* tree) const -{ - return QRect(widgetPos_, pos_.y(), widgetSize_, tree->_defaultRowHeight()); -} - -QRect PropertyRow::validatorRect([[maybe_unused]] const QPropertyTree* tree) const -{ - return QRect(pos_.x() + plusSize_, pos_.y() + size_.y() - validatorsHeight_, size_.x() - plusSize_, validatorsHeight_); -} - -QRect PropertyRow::validatorErrorIconRect(const QPropertyTree* tree) const -{ - int rowHeight = tree->_defaultRowHeight(); - int width = validatorHasErrors_ && !expanded_ ? rowHeight : 0; - int normalX = pos_.x() + size_.x() - width; - int minimalX = max(widgetPos_ + widgetSize_, textPos_ + textSize_); - return QRect(max(minimalX, normalX), pos_.y(), width, rowHeight); -} - -QRect PropertyRow::validatorWarningIconRect(const QPropertyTree* tree) const -{ - QRect r = validatorErrorIconRect(tree); - int width = validatorHasWarnings_ && !expanded_ ? r.height() : 0; - return QRect(r.left() - width, pos_.y(), width, r.height()); -} - -QRect PropertyRow::plusRect(const QPropertyTree* tree) const -{ - return QRect(pos_.x(), pos_.y(), plusSize_, tree->_defaultRowHeight()); -} - -QRect PropertyRow::floorRect(const QPropertyTree* tree) const -{ - return QRect(textPos_, pos_.y() + tree->_defaultRowHeight(), size_.x() - (textPos_ - pos_.x()) , size_.y() - tree->_defaultRowHeight()); -} - -void PropertyRow::setCallback(Serialization::ICallback* callback) -{ - callback_ = callback; -} - -SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRow, "PropertyRow", "Structure"); - -// --------------------------------------------------------------------------- - -EDITOR_COMMON_API PropertyRowFactory& GlobalPropertyRowFactory() -{ - return PropertyRowFactory::the(); -} - -EDITOR_COMMON_API Serialization::ClassFactory& GlobalPropertyRowClassFactory() -{ - return Serialization::ClassFactory::the(); -} - -// --------------------------------------------------------------------------- - -PropertyRowWidget::PropertyRowWidget(PropertyRow* row, QPropertyTree* tree) -: row_(row) -, model_(tree->model()) -, tree_(tree) -{ -} - -PropertyRowWidget::~PropertyRowWidget() -{ - if(actualWidget()) - actualWidget()->setParent(0); - tree_->setFocus(); -} - -// --------------------------------------------------------------------------- -Serialization::ClassFactory& GetPropertyRowClassFactory() -{ - return Serialization::ClassFactory::the(); -} -PropertyRowFactory& GetPropertyRowFactory() -{ - return PropertyRowFactory::the(); -} - -int RowWidthCache::getOrUpdate(const QPropertyTree* tree, const PropertyRow* rowForValue, int extraSpace) -{ - string value = rowForValue->valueAsString(); - const QFont* font = rowForValue->rowFont(tree); - unsigned int newHash = calculateHash(value.c_str()); - newHash = calculateHash(font, valueHash); - if (newHash != valueHash) - { - QFontMetrics fm(*font); - width = fm.horizontalAdvance(value.c_str()) + 6 + extraSpace; - if (width < 24) - width = 24; - valueHash = newHash; - } - return width; -} - -// --------------------------------------------------------------------------- - -FORCE_SEGMENT(PropertyRowNumber) -FORCE_SEGMENT(PropertyRowStringList) -/* -FORCE_SEGMENT(PropertyRowDecorators) -FORCE_SEGMENT(PropertyRowBitVector) -FORCE_SEGMENT(PropertyRowFileSelector) -FORCE_SEGMENT(PropertyRowColor) -FORCE_SEGMENT(PropertyRowHotkey) -FORCE_SEGMENT(PropertyRowSlider) -FORCE_SEGMENT(PropertyRowIcon) -*/ -#include - diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRow.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRow.h deleted file mode 100644 index d5556857b7..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRow.h +++ /dev/null @@ -1,575 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include "Serialization/Serializer.h" -#include "Serialization/StringList.h" -#include -#include "Factory.h" -#include "ConstStringList.h" -#include "Strings.h" -#include "../EditorCommonAPI.h" -#include "Serialization/ClassFactory.h" - -#include -#include -#include -#include -#endif - -namespace Serialization { struct ICallback; } - -class QWidget; -class QFont; -class QPainter; -class QMenu; -class QKeyEvent; - -using std::vector; -class QPropertyTree; -class PropertyRow; -class PropertyTreeModel; -class PopupMenuItem; -struct PropertyDrawContext; -struct EDITOR_COMMON_API ContainerMenuHandler; -class PropertyRowContainer; - -enum ScanResult { - SCAN_FINISHED, - SCAN_CHILDREN, - SCAN_SIBLINGS, - SCAN_CHILDREN_SIBLINGS, -}; - -struct EDITOR_COMMON_API PropertyRowMenuHandler : QObject -{ -public: - virtual ~PropertyRowMenuHandler() {} - -}; - -struct PropertyActivationEvent -{ - enum Reason - { - REASON_PRESS, - REASON_RELEASE, - REASON_DOUBLECLICK, - REASON_KEYBOARD, - REASON_NEW_ELEMENT - }; - - QPropertyTree* tree; - Reason reason; - bool force; - QPoint clickPoint; - - PropertyActivationEvent() - : force(false) - , clickPoint(0, 0) - , tree(0) - , reason(REASON_PRESS) - { - } -}; - -struct PropertyDragEvent -{ - QPropertyTree* tree; - QPoint pos; - QPoint start; - QPoint lastDelta; - QPoint totalDelta; -}; - -struct PropertyHoverInfo -{ - QCursor cursor; - QString toolTip; - - PropertyHoverInfo() - : cursor() - { - } -}; - -enum DragCheckBegin { - DRAG_CHECK_IGNORE, - DRAG_CHECK_SET, - DRAG_CHECK_UNSET -}; - -class PropertyRowWidget : public QObject -{ - Q_OBJECT -public: - PropertyRowWidget(PropertyRow* row, QPropertyTree* tree); - virtual ~PropertyRowWidget(); - virtual QWidget* actualWidget() { return 0; } - virtual void showPopup() {} - virtual void commit() = 0; - PropertyRow* row() { return row_; } - PropertyTreeModel* model() { return model_; } -protected: - PropertyRow* row_; - QPropertyTree* tree_; - PropertyTreeModel* model_; -}; - -class PropertyTreeTransaction; - -AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING -class EDITOR_COMMON_API PropertyRow : public Serialization::RefCounter -{ -AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING -public: - enum WidgetPlacement { - WIDGET_NONE, - WIDGET_ICON, - WIDGET_AFTER_NAME, - WIDGET_VALUE, - WIDGET_AFTER_PULLED, - WIDGET_INSTEAD_OF_TEXT - }; - - typedef std::vector< Serialization::SharedPtr > Rows; - typedef Rows::iterator iterator; - typedef Rows::const_iterator const_iterator; - - PropertyRow(); - virtual ~PropertyRow(); - - void setNames(const char* name, const char* label, const char* typeName); - - bool selected() const{ return selected_; } - void setSelected(bool selected) { selected_ = selected; } - bool expanded() const{ return expanded_; } - void _setExpanded(bool expanded); // use QPropertyTree::expandRow - void setExpandedRecursive(QPropertyTree* tree, bool expanded); - - void setMatchFilter(bool matchFilter) { matchFilter_ = matchFilter; } - bool matchFilter() const { return matchFilter_; } - - void setBelongsToFilteredRow(bool belongs) { belongsToFilteredRow_ = belongs; } - bool belongsToFilteredRow() const { return belongsToFilteredRow_; } - - bool visible(const QPropertyTree* tree) const; - bool hasVisibleChildren(const QPropertyTree* tree, bool internalCall = false) const; - - const PropertyRow* hit(const QPropertyTree* tree, QPoint point) const; - PropertyRow* hit(const QPropertyTree* tree, QPoint point); - PropertyRow* parent() { return parent_; } - const PropertyRow* parent() const{ return parent_; } - void setParent(PropertyRow* row) { parent_ = row; } - bool isRoot() const { return !parent_; } - int level() const; - - void add(PropertyRow* row); - void addAfter(PropertyRow* row, PropertyRow* after); - void addBefore(PropertyRow* row, PropertyRow* before); - - template bool scanChildren(Op& op); - template bool scanChildren(Op& op, QPropertyTree* tree); - template bool scanChildrenReverse(Op& op, QPropertyTree* tree); - template bool scanChildrenBottomUp(Op& op, QPropertyTree* tree); - - PropertyRow* childByIndex(int index); - const PropertyRow* childByIndex(int index) const; - int childIndex(const PropertyRow* row) const; - bool isChildOf(const PropertyRow* row) const; - - bool empty() const{ return children_.empty(); } - iterator find(PropertyRow* row) { return std::find(children_.begin(), children_.end(), row); } - PropertyRow* findFromIndex(int* outIndex, const char* name, const char* typeName, int startIndex) const; - PropertyRow* findByAddress(const void* handle); - virtual const void* searchHandle() const; - iterator begin() { return children_.begin(); } - iterator end() { return children_.end(); } - const_iterator begin() const{ return children_.begin(); } - const_iterator end() const{ return children_.end(); } - std::size_t count() const{ return children_.size(); } - iterator erase(iterator it){ return children_.erase(it); } - void clear(){ children_.clear(); } - void erase(PropertyRow* row); - void swapChildren(PropertyRow* row, PropertyTreeModel* model); - - void assignRowState(const PropertyRow& row, bool recurse); - void assignRowProperties(PropertyRow* row); - void replaceAndPreserveState(PropertyRow* oldRow, PropertyRow* newRow, PropertyTreeModel* model); - - const char* name() const{ return name_; } - void setName(const char* name) { name_ = name; } - const char* label() const { return label_; } - const char* labelUndecorated() const { return labelUndecorated_; } - void setLabel(const char* label); - void setLabelChanged(); - void setTooltip(const char* tooltip); - bool setValidatorEntry(int index, int count); - int validatorCount() const{ return validatorCount_; } - int validatorIndex() const{ return validatorIndex_; } - void resetValidatorIcons(); - void addValidatorIcons(bool hasWarnings, bool hasErrors); - const char* tooltip() const { return tooltip_; } - void setLayoutChanged(); - void setLabelChangedToChildren(); - void setLayoutChangedToChildren(); - void setHideChildren(bool hideChildren) { hideChildren_ = hideChildren; } - bool hideChildren() const { return hideChildren_; } - void updateLabel(const QPropertyTree* tree, int index, bool parentHidesNonInlineChildren); - void updateTextSizeInitial(const QPropertyTree* tree, int index, bool force); - virtual void labelChanged() {} - void parseControlCodes(const QPropertyTree* tree, const char* label, bool changeLabel); - const char* typeName() const{ return typeName_; } - virtual const char* typeNameForFilter(QPropertyTree* tree) const; - void setTypeName(const char* typeName) { typeName_ = typeName; } - const char* rowText(char* containerLabelBuffer, size_t bufsiz, const QPropertyTree* tree, int rowIndex) const; - - PropertyRow* findSelected(); - PropertyRow* find(const char* name, const char* nameAlt, const char* typeName); - const PropertyRow* find(const char* name, const char* nameAlt, const char* typeName) const; - void intersect(const PropertyRow* row); - - int verticalIndex(QPropertyTree* tree, PropertyRow* row); - PropertyRow* rowByVerticalIndex(QPropertyTree* tree, int index); - int horizontalIndex(QPropertyTree* tree, PropertyRow* row); - PropertyRow* rowByHorizontalIndex(QPropertyTree* tree, int index); - - virtual bool assignToPrimitive([[maybe_unused]] void* object, [[maybe_unused]] size_t size) const{ return false; } - virtual bool assignTo([[maybe_unused]] const Serialization::SStruct& ser) const{ return false; } - virtual bool assignToByPointer(void* instance, const Serialization::TypeID& type) const{ return assignTo(Serialization::SStruct(type, instance, type.sizeOf(), 0)); } - virtual void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) { serializer_ = ser; } - virtual void handleChildrenChange() {} - virtual string valueAsString() const; - virtual wstring valueAsWString() const; - - int height() const{ return size_.y(); } - - virtual int widgetSizeMin(const QPropertyTree*) const { return userWidgetSize() >= 0 ? userWidgetSize() : 0; } - virtual int floorHeight() const{ return 0; } - - void calcPulledRows(int* minTextSize, int* freePulledChildren, int* minimalWidth, const QPropertyTree* tree, int index); - void calculateMinimalSize(const QPropertyTree* tree, int posX, int availableWidth, bool force, int* extraSizeRemainder, int* _extraSize, int index); - void setTextSize(const QPropertyTree* tree, int rowIndex, float multiplier); - void calculateTotalSizes(int* minTextSize); - void adjustVerticalPosition(const QPropertyTree* tree, int& totalHeight); - - virtual bool isWidgetFixed() const{ return userFixedWidget_ || (widgetPlacement() != WIDGET_VALUE && widgetPlacement() != WIDGET_INSTEAD_OF_TEXT); } - - virtual WidgetPlacement widgetPlacement() const{ return WIDGET_NONE; } - - QRect rect() const{ return QRect(pos_.x(), pos_.y(), size_.x(), size_.y()); } - QRect rectIncludingChildren(const QPropertyTree* tree) const; - QRect textRect(const QPropertyTree* tree) const; - QRect widgetRect(const QPropertyTree* tree) const; - QRect plusRect(const QPropertyTree* tree) const; - QRect floorRect(const QPropertyTree* tree) const; - QRect validatorRect(const QPropertyTree* tree) const; - QRect validatorWarningIconRect(const QPropertyTree* tree) const; - QRect validatorErrorIconRect(const QPropertyTree* tree) const; - void adjustHoveredRect(QRect& hoveredRect); - int heightIncludingChildren() const{ return heightIncludingChildren_; } - const QFont* rowFont(const QPropertyTree* tree) const; - - void drawRow(QPainter& painter, const QPropertyTree* tree, int rowIndex, bool selectionPass); - void drawPlus(QPainter& p, const QPropertyTree* tree, const QRect& rect, bool expanded, bool selected, bool grayed) const; - void drawStaticText(QPainter& p, const QRect& widgetRect); - - virtual void redraw(const PropertyDrawContext& context); - virtual PropertyRowWidget* createWidget([[maybe_unused]] QPropertyTree* tree) { return 0; } - - virtual bool isContainer() const{ return false; } - virtual bool isPointer() const{ return false; } - virtual bool isObject() const{ return false; } - - virtual bool isLeaf() const{ return false; } - virtual void closeNonLeaf([[maybe_unused]] const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) {} - virtual bool isStatic() const{ return pulledContainer_ == 0; } - virtual bool isSelectable() const{ return (!userReadOnly() && !userReadOnlyRecurse()) || (!pulledUp() && !pulledBefore()); } - virtual bool activateOnAdd() const{ return false; } - virtual bool inlineInShortArrays() const{ return false; } - - bool canBeToggled(const QPropertyTree* tree) const; - bool canBeDragged() const; - bool canBeDroppedOn(const PropertyRow* parentRow, const PropertyRow* beforeChild, const QPropertyTree* tree) const; - void dropInto(PropertyRow* parentRow, PropertyRow* cursorRow, QPropertyTree* tree, bool before); - virtual bool getHoverInfo(PropertyHoverInfo* hit, [[maybe_unused]] const QPoint& cursorPos, [[maybe_unused]] const QPropertyTree* tree) const { - hit->toolTip = QString::fromUtf8(tooltip_); - return true; - } - - virtual bool onActivate(const PropertyActivationEvent& e); - virtual bool processesKey(QPropertyTree* tree, const QKeyEvent* ev); // returns true if it wants to process key events; otherwise, they will get processed by shortcuts in some cases, like delete - virtual bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev); - virtual bool onMouseDown([[maybe_unused]] QPropertyTree* tree, [[maybe_unused]] QPoint point, [[maybe_unused]] bool& changed) { return false; } - virtual void onMouseDrag([[maybe_unused]] const PropertyDragEvent& e) {} - virtual void onMouseStill([[maybe_unused]] const PropertyDragEvent& e) {} - virtual void onMouseUp([[maybe_unused]] QPropertyTree* tree, [[maybe_unused]] QPoint point) {} - // "drag check" allows you to "paint" with the mouse through checkboxes to set all values at once - virtual DragCheckBegin onMouseDragCheckBegin() { return DRAG_CHECK_IGNORE; } - virtual bool onMouseDragCheck([[maybe_unused]] QPropertyTree* tree, [[maybe_unused]] bool value) { return false; } - virtual bool onContextMenu(QMenu &menu, QPropertyTree* tree); - virtual ContainerMenuHandler* createMenuHandler(QPropertyTree* tree, PropertyRowContainer* container); - - virtual bool isFullRow(const QPropertyTree* tree) const; - - // User states. - // Assigned using control codes (characters in the beginning of label) - // fixed widget doesn't expand automatically to occupy all available place - bool userFixedWidget() const{ return userFixedWidget_; } - bool userFullRow() const { return userFullRow_; } - void setUserReadOnly(bool userReadOnly) { userReadOnly_ = userReadOnly; } - virtual bool userReadOnly() const { return userReadOnly_; } - void propagateFlagsTopToBottom(); - virtual bool userReadOnlyRecurse() const { return userReadOnlyRecurse_; } - bool userWidgetToContent() const { return userWidgetToContent_; } - int userWidgetSize() const{ return userWidgetSize_; } - bool userNonCopyable() const { return userNonCopyable_; } - - // multiValue is used to edit properties of multiple objects simulateneously - bool multiValue() const { return multiValue_; } - void setMultiValue(bool multiValue) { multiValue_ = multiValue; } - - // pulledRow - is the one that is pulled up to the parents row - // (created with ^ in the beginning of label) - bool pulledUp() const { return pulledUp_; } - bool pulledBefore() const { return pulledBefore_; } - bool hasPulled() const { return hasPulled_; } - bool packedAfterPreviousRow() const { return packedAfterPreviousRow_; } - bool pulledSelected() const; - PropertyRow* nonPulledParent(); - void setPulledContainer(PropertyRow* container){ pulledContainer_ = container; } - PropertyRow* pulledContainer() { return pulledContainer_; } - const PropertyRow* pulledContainer() const{ return pulledContainer_; } - - Serialization::SharedPtr clone(ConstStringList* constStrings) const; - - Serialization::SStruct serializer() const{ return serializer_; } - virtual Serialization::TypeID typeId() const{ return serializer_.type(); } - void setSerializer(const Serialization::SStruct& ser) { serializer_ = ser; } - virtual void serializeValue([[maybe_unused]] Serialization::IArchive& ar) {} - void setCallback(Serialization::ICallback* callback); - Serialization::ICallback* callback() { return callback_; } - virtual void Serialize(Serialization::IArchive& ar); - - static void setConstStrings(ConstStringList* constStrings){ constStrings_ = constStrings; } - -protected: - void init(const char* name, const char* nameAlt, const char* typeName); - PropertyRow* findChildFromDescendant(PropertyRow* row) const; - - virtual void overrideTextColor([[maybe_unused]] QColor& textColor) {} - - const char* name_; - const char* label_; - const char* labelUndecorated_; - const char* typeName_; - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - Serialization::SStruct serializer_; - PropertyRow* parent_; - Serialization::ICallback* callback_; - const char* tooltip_; - Rows children_; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - unsigned int textHash_; - - // do we really need QPoint here? - QPoint pos_; - QPoint size_; - short int textPos_; - short int textSizeInitial_; - short int textSize_; - short int widgetPos_; // widget == icon! - short int widgetSize_; - short int userWidgetSize_; - unsigned short heightIncludingChildren_; - unsigned short validatorIndex_; - unsigned short validatorsHeight_; - unsigned char validatorCount_; - unsigned char plusSize_; - bool visible_ : 1; - bool matchFilter_ : 1; - bool belongsToFilteredRow_ : 1; - bool expanded_ : 1; - bool selected_ : 1; - bool labelChanged_ : 1; - bool layoutChanged_ : 1; - bool userReadOnly_ : 1; - bool userReadOnlyRecurse_ : 1; - bool userFixedWidget_ : 1; - bool userFullRow_ : 1; - bool userPackCheckboxes_ : 1; - bool userWidgetToContent_ : 1; - bool pulledUp_ : 1; - bool pulledBefore_ : 1; - bool packedAfterPreviousRow_ : 1; - bool hasPulled_ : 1; - bool multiValue_ : 1; - bool hideChildren_ : 1; - bool validatorHasErrors_ : 1; - bool validatorHasWarnings_ : 1; - bool userNonCopyable_ : 1; - enum class FontWeight - { - Undefined, - Bold, - Regular - }; - FontWeight fontWeight_; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - Serialization::SharedPtr pulledContainer_; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - static ConstStringList* constStrings_; - friend class PropertyOArchive; - friend class PropertyIArchive; -}; - -inline unsigned int calculateHash(const char* str, unsigned hash = 5381) -{ - while(*str) - hash = hash * 33 + (unsigned char)*str++; - return hash; -} - -template -inline unsigned int calculateHash(const T& t, unsigned hash = 5381) -{ - for (int i = 0; i < sizeof(T); i++) - hash = hash * 33 + ((unsigned char*)&t)[i]; - return hash; -} - -struct RowWidthCache -{ - unsigned int valueHash; - int width; - - RowWidthCache() : valueHash(0), width(-1) {} - int getOrUpdate(const QPropertyTree* tree, const PropertyRow* rowForValue, int extraSpace); -}; - -typedef vector > PropertyRows; - -template -struct StaticBool{ - enum { Value = value }; -}; - -struct LessStrCmp -{ - bool operator()(const char* a, const char* b) const { - return strcmp(a, b) < 0; - } -}; - -typedef Factory PropertyRowFactory; - -template -bool PropertyRow::scanChildren(Op& op) -{ - Rows::iterator it; - - for(it = children_.begin(); it != children_.end(); ++it){ - ScanResult result = op(*it); - if(result == SCAN_FINISHED) - return false; - if(result == SCAN_CHILDREN || result == SCAN_CHILDREN_SIBLINGS){ - if(!(*it)->scanChildren(op)) - return false; - if(result == SCAN_CHILDREN) - return false; - } - } - return true; -} - -template -bool PropertyRow::scanChildren(Op& op, QPropertyTree* tree) -{ - int numChildren = int(children_.size()); - for(int index = 0; index < numChildren; ++index){ - PropertyRow* child = children_[index]; - ScanResult result = op(child, tree, index); - if(result == SCAN_FINISHED) - return false; - if(result == SCAN_CHILDREN || result == SCAN_CHILDREN_SIBLINGS){ - if(!child->scanChildren(op, tree)) - return false; - if(result == SCAN_CHILDREN) - return false; - } - } - return true; -} - -template -bool PropertyRow::scanChildrenReverse(Op& op, QPropertyTree* tree) -{ - int numChildren = (int)children_.size(); - for(int index = numChildren - 1; index >= 0; --index){ - PropertyRow* child = children_[index]; - ScanResult result = op(child, tree, index); - if(result == SCAN_FINISHED) - return false; - if(result == SCAN_CHILDREN || result == SCAN_CHILDREN_SIBLINGS){ - if(!child->scanChildrenReverse(op, tree)) - return false; - if(result == SCAN_CHILDREN) - return false; - } - } - return true; -} - -template -bool PropertyRow::scanChildrenBottomUp(Op& op, QPropertyTree* tree) -{ - size_t numChildren = children_.size(); - for(size_t i = 0; i < numChildren; ++i) - { - PropertyRow* child = children_[i]; - if(!child->scanChildrenBottomUp(op, tree)) - return false; - ScanResult result = op(child, tree); - if(result == SCAN_FINISHED) - return false; - } - return true; -} - -EDITOR_COMMON_API PropertyRowFactory& GlobalPropertyRowFactory(); -EDITOR_COMMON_API Serialization::ClassFactory& GlobalPropertyRowClassFactory(); - -struct PropertyRowPtrSerializer : Serialization::SharedPtrSerializer -{ - PropertyRowPtrSerializer(Serialization::SharedPtr& ptr) : SharedPtrSerializer(ptr) {} - Serialization::ClassFactory* factory() const override { return &GlobalPropertyRowClassFactory(); } -}; - -inline bool Serialize(Serialization::IArchive& ar, Serialization::SharedPtr& ptr, const char* name, const char* label) -{ - PropertyRowPtrSerializer serializer(ptr); - return ar(static_cast(serializer), name, label); -} - -#define REGISTER_PROPERTY_ROW(DataType, RowType) \ - PropertyRow* _Factory_For_##RowType() {return new RowType; }; \ - REGISTER_IN_FACTORY(PropertyRowFactory, Serialization::TypeID::get().name(), RowType, _Factory_For_##RowType); \ - SERIALIZATION_CLASS_NAME_FOR_FACTORY(GlobalPropertyRowClassFactory(), PropertyRow, RowType, #DataType, #DataType); - -// Exposes the necessary class factories to extend the property tree -// Exposes the necessary class factories to extend the property tree -EDITOR_COMMON_API Serialization::ClassFactory& GetPropertyRowClassFactory(); -EDITOR_COMMON_API PropertyRowFactory& GetPropertyRowFactory(); diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowActionButton.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowActionButton.cpp deleted file mode 100644 index d268c87311..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowActionButton.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "platform.h" - -#include - -#include "Serialization/ClassFactory.h" -#include "PropertyDrawContext.h" -#include "PropertyRowImpl.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Serialization.h" -#include "Color.h" -#include "Unicode.h" -#include "Serialization/Decorators/ActionButton.h" - -using Serialization::IActionButton; -using Serialization::IActionButtonPtr; - -class PropertyRowActionButton - : public PropertyRow -{ -public: - PropertyRowActionButton() - : underMouse_() - , pressed_() - , minimalWidth_() {} - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - bool isSelectable() const override { return true; } - - bool onActivate(const PropertyActivationEvent& e) override - { - if (e.reason == PropertyActivationEvent::REASON_KEYBOARD) - { - if (value_) - { - value_->Callback(); - } - } - return true; - } - - bool onMouseDown(QPropertyTree* tree, QPoint point, [[maybe_unused]] bool& changed) override - { - if (userReadOnly()) - { - return false; - } - if (widgetRect(tree).contains(point)) - { - underMouse_ = true; - pressed_ = true; - tree->update(); - return true; - } - return false; - } - - void onMouseDrag(const PropertyDragEvent& e) override - { - if (userReadOnly()) - { - return; - } - bool underMouse = widgetRect(e.tree).contains(e.pos); - if (underMouse != underMouse_) - { - underMouse_ = underMouse; - e.tree->update(); - } - } - - void onMouseUp(QPropertyTree* tree, QPoint point) override - { - if (userReadOnly()) - { - return; - } - if (widgetRect(tree).contains(point)) - { - pressed_ = false; - if (value_) - { - value_->Callback(); - } - tree->update(); - } - } - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override - { - value_ = static_cast(ser.pointer())->Clone(); - const char* icon = value_->Icon(); - icon_ = icon && icon[0] ? QIcon() : QIcon(QString::fromLocal8Bit(icon)); - } - bool assignTo([[maybe_unused]] const Serialization::SStruct& ser) const override { return true; } - wstring valueAsWString() const override { return L""; } - WidgetPlacement widgetPlacement() const override { return WIDGET_INSTEAD_OF_TEXT; } - void serializeValue([[maybe_unused]] Serialization::IArchive& ar) override { } - - int widgetSizeMin(const QPropertyTree* tree) const override - { - if (minimalWidth_ == 0) - { - QFontMetrics fm(tree->font()); - minimalWidth_ = (int)fm.horizontalAdvance(QString::fromLocal8Bit(labelUndecorated())) + 6 + (icon_.isNull() ? 0 : 18); - } - return minimalWidth_; - } - - void redraw(const PropertyDrawContext& context) - { - QRect rect = context.widgetRect.adjusted(-1, -1, 1, 1); - bool pressed = pressed_ && underMouse_; - - wstring text = toWideChar(labelUndecorated()); - if (icon_.isNull()) - { - int buttonFlags = BUTTON_CENTER; - if (pressed) - { - buttonFlags |= BUTTON_PRESSED; - } - if (selected()) - { - buttonFlags |= BUTTON_FOCUSED; - } - if (userReadOnly()) - { - buttonFlags |= BUTTON_DISABLED; - } - context.drawButton(rect, text.c_str(), buttonFlags, &context.tree->font()); - } - else - { - context.drawButtonWithIcon(icon_, rect, text.c_str(), selected(), pressed, selected(), !userReadOnly(), true, &context.tree->font()); - } - } - bool isFullRow(const QPropertyTree* tree) const override - { - if (PropertyRow::isFullRow(tree)) - { - return true; - } - return !userFixedWidget(); - } -protected: - mutable int minimalWidth_; - bool underMouse_; - bool pressed_; - QIcon icon_; - IActionButtonPtr value_; -}; - -REGISTER_PROPERTY_ROW(IActionButton, PropertyRowActionButton); diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowBool.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowBool.cpp deleted file mode 100644 index a2704601b0..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowBool.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowBool.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "PropertyDrawContext.h" -#include "Serialization/ClassFactory.h" -#include "Serialization.h" -#include - -SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRowBool, "PropertyRowBool", "bool"); - -PropertyRowBool::PropertyRowBool() - : value_(false) -{ -} - -bool PropertyRowBool::assignToPrimitive(void* object, [[maybe_unused]] size_t size) const -{ - YASLI_ASSERT(size == sizeof(bool)); - *reinterpret_cast(object) = value_; - return true; -} - -bool PropertyRowBool::assignToByPointer(void* instance, const Serialization::TypeID& type) const -{ - return assignToPrimitive(instance, type.sizeOf()); -} - -void PropertyRowBool::redraw(const PropertyDrawContext& context) -{ - context.drawCheck(widgetRect(context.tree), userReadOnly(), multiValue() ? CHECK_IN_BETWEEN : (value_ ? CHECK_SET : CHECK_NOT_SET)); -} - -bool PropertyRowBool::processesKey(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (QKeySequence(ev->key()) == QKeySequence(Qt::Key_Space)) - { - return true; - } - - return PropertyRow::processesKey(tree, ev); -} - -bool PropertyRowBool::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (QKeySequence(ev->key()) == QKeySequence(Qt::Key_Space)) - { - PropertyActivationEvent e; - e.tree = tree; - e.reason = e.REASON_KEYBOARD; - onActivate(e); - return true; - } - - return PropertyRow::onKeyDown(tree, ev); -} - -bool PropertyRowBool::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason != e.REASON_RELEASE) - { - if (!this->userReadOnly()) - { - e.tree->model()->rowAboutToBeChanged(this); - value_ = !value_; - e.tree->model()->rowChanged(this); - return true; - } - } - return false; -} - -DragCheckBegin PropertyRowBool::onMouseDragCheckBegin() -{ - if (userReadOnly()) - { - return DRAG_CHECK_IGNORE; - } - return value_ ? DRAG_CHECK_UNSET : DRAG_CHECK_SET; -} - -bool PropertyRowBool::onMouseDragCheck(QPropertyTree* tree, bool value) -{ - if (value_ != value) - { - tree->model()->rowAboutToBeChanged(this); - value_ = value; - tree->model()->rowChanged(this); - return true; - } - return false; -} - -void PropertyRowBool::serializeValue(Serialization::IArchive& ar) -{ - ar(value_, "value", "Value"); -} - -int PropertyRowBool::widgetSizeMin(const QPropertyTree* tree) const -{ - return aznumeric_cast(tree->_defaultRowHeight() * 0.9f); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowBool.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowBool.h deleted file mode 100644 index 0900cd09e6..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowBool.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWBOOL_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWBOOL_H -#pragma once - -#include "PropertyRow.h" -#include "Unicode.h" - -class PropertyRowBool - : public PropertyRow -{ -public: - PropertyRowBool(); - bool assignToPrimitive(void* val, size_t size) const override; - bool assignToByPointer(void* instance, const Serialization::TypeID& type) const; - void setValue(bool value, const void* handle, [[maybe_unused]] const Serialization::TypeID& typeId) { value_ = value; serializer_.setPointer((void*)handle); serializer_.setType(Serialization::TypeID::get()); } - - void redraw(const PropertyDrawContext& context); - bool isLeaf() const{ return true; } - bool isStatic() const{ return false; } - - bool onActivate(const PropertyActivationEvent& e); - DragCheckBegin onMouseDragCheckBegin() override; - bool onMouseDragCheck(QPropertyTree* tree, bool value) override; - wstring valueAsWString() const{ return value_ ? L"true" : L"false"; } - string valueAsString() const{ return value_ ? "true" : "false"; } - WidgetPlacement widgetPlacement() const{ return WIDGET_ICON; } - void serializeValue(Serialization::IArchive& ar); - int widgetSizeMin(const QPropertyTree* tree) const override; - bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; -protected: - bool value_; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWBOOL_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColor.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColor.cpp deleted file mode 100644 index f83dd6713e..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColor.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowColor.h" -#include "Serialization/ClassFactory.h" -#include -#include -#include -#include - -#include -#include - -using Serialization::Vec3AsColor; -typedef SerializableColor_tpl SerializableColorB; -typedef SerializableColor_tpl SerializableColorF; - -QColor ToQColor(const ColorB& v) -{ - return QColor(v.r, v.g, v.b, v.a); -} - -void FromQColor(SerializableColorB& vColor, QColor color) -{ - vColor.r = color.red(); - vColor.g = color.green(); - vColor.b = color.blue(); - vColor.a = color.alpha(); -} - - -QColor ToQColor(const Vec3AsColor& v) -{ - return QColor(int(v.v.x * 255.0f), int(v.v.y * 255.0f), int(v.v.z * 255.0f)); -} - -void FromQColor(Vec3AsColor& vColor, QColor color) -{ - vColor.v.x = color.red() / 255.0f; - vColor.v.y = color.green() / 255.0f; - vColor.v.z = color.blue() / 255.0f; -} - -QColor ToQColor(const SerializableColorF& v) -{ - return QColor::fromRgbF(v.r, v.g, v.b, v.a); -} - -void FromQColor(SerializableColorF& vColor, QColor color) -{ - vColor.r = aznumeric_cast(color.redF()); - vColor.g = aznumeric_cast(color.greenF()); - vColor.b = aznumeric_cast(color.blueF()); - vColor.a = aznumeric_cast(color.alphaF()); -} - - -template -bool PropertyRowColor::pickColor(QPropertyTree* tree) -{ - const AZ::Color initialColor = AzQtComponents::fromQColor(color_); - const AZ::Color color = AzQtComponents::ColorPicker::getColor(AzQtComponents::ColorPicker::Configuration::RGB, initialColor, QObject::tr("Select Color")); - - if (color != initialColor) - { - tree->model()->rowAboutToBeChanged(this); - color_.setRed(color.GetR8()); - color_.setGreen(color.GetG8()); - color_.setBlue(color.GetB8()); - colorChanged_ = true; - tree->model()->rowChanged(this); - return true; - } - - return false; -} - -template -bool PropertyRowColor::onActivate(const PropertyActivationEvent& e) -{ - return pickColor(e.tree); -} - -template -void PropertyRowColor::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] IArchive& ar) -{ - color_ = ToQColor(*(ColorClass*)ser.pointer()); - colorChanged_ = false; -} - -template -bool PropertyRowColor::assignTo(const Serialization::SStruct& ser) const -{ - FromQColor(*((ColorClass*)ser.pointer()), color_); - return true; -} - -template -string PropertyRowColor::valueAsString() const -{ - char buf[64]; - sprintf_s(buf, "%d %d %d", (int)color_.red(), (int)color_.green(), (int)color_.blue()); - return string(buf); -} - -template -bool PropertyRowColor::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - Serialization::SharedPtr selfPointer(this); - ColorMenuHandler* handler = new ColorMenuHandler(tree, this); - menu.addAction("Pick Color", handler, SLOT(onMenuPickColor())); - tree->addMenuHandler(handler); - return true; -} - -template -void PropertyRowColor::redraw(const PropertyDrawContext& context) -{ - static QImage checkboardPattern; - if (checkboardPattern.isNull()) - { - int size = 12; - static vector pixels(size * size); - for (int i = 0; i < pixels.size(); ++i) - { - pixels[i] = ((i / size) / (size / 2) + (i % size) / (size / 2)) % 2 ? 0xffffffff : 0x000000ff; - } - checkboardPattern = QImage((unsigned char*)pixels.data(), size, size, size * 4, QImage::Format_RGBA8888); - } - - QRect r = context.widgetRect.adjusted(0, 0, 0, -1); - - context.painter->save(); - context.painter->setPen(QPen(Qt::NoPen)); - context.painter->setRenderHint(QPainter::Antialiasing, true); - context.painter->setBrush(context.tree->palette().color(QPalette::Dark)); - context.painter->setPen(Qt::NoPen); - context.painter->drawRoundedRect(r, 2, 2); - r = r.adjusted(1, 1, -1, -1); - QRect cr = r.adjusted(0, 0, -r.width() / 2, 0); - context.painter->setBrushOrigin(cr.topRight() + QPoint(1, 0)); - context.painter->setBrush(QBrush(checkboardPattern)); - - context.painter->setRenderHint(QPainter::Antialiasing, false); - context.painter->drawRoundedRect(r, 2, 2); - - context.painter->setPen(QPen(Qt::NoPen)); - context.painter->setClipRect(cr); - context.painter->setBrush(QBrush(color_)); - context.painter->drawRoundedRect(r, 2, 2); - - cr = r.adjusted(r.width() / 2, 0, 0, 0); - context.painter->setClipRect(cr); - context.painter->setBrush(QBrush(QColor(color_.red(), color_.green(), color_.blue(), 255))); - context.painter->drawRoundedRect(r, 2, 2); - context.painter->restore(); -} - -template -void PropertyRowColor::closeNonLeaf(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) -{ - color_ = ToQColor(*(ColorClass*)ser.pointer()); -} - -static int componentFromRowValue(const char* str, ColorB*) -{ - return clamp_tpl(atoi(str), 0, 255); -} - -static int componentFromRowValue(const char* str, ColorF*) -{ - return clamp_tpl(int(atof(str) * 255.0f + 0.5f), 0, 255); -} - -static int componentFromRowValue(const char* str, Vec3AsColor*) -{ - return clamp_tpl(int(atof(str) * 255.0f + 0.5f), 0, 255); -} - -template -void PropertyRowColor::handleChildrenChange() -{ - // generally is not needed unless we are using callbacks - PropertyRow* rows[4] = { - childByIndex(0), - childByIndex(1), - childByIndex(2), - childByIndex(3) - }; - - if (rows[0]) - { - color_.setRed(componentFromRowValue(rows[0]->valueAsString().c_str(), (ColorClass*)0)); - } - if (rows[1]) - { - color_.setGreen(componentFromRowValue(rows[1]->valueAsString().c_str(), (ColorClass*)0)); - } - if (rows[2]) - { - color_.setBlue(componentFromRowValue(rows[2]->valueAsString().c_str(), (ColorClass*)0)); - } - if (rows[3]) - { - color_.setAlpha(componentFromRowValue(rows[3]->valueAsString().c_str(), (ColorClass*)0)); - } -} - - -ColorMenuHandler::ColorMenuHandler(QPropertyTree* tree, IPropertyRowColor* propertyRowColor) - : propertyRowColor(propertyRowColor) - , tree(tree) -{ -} - -void ColorMenuHandler::onMenuPickColor() -{ - propertyRowColor->pickColor(tree); -} - -typedef PropertyRowColor PropertyRowColorB; -typedef PropertyRowColor PropertyRowVec3AsColor; -typedef PropertyRowColor PropertyRowColorF; - -REGISTER_PROPERTY_ROW(SerializableColorB, PropertyRowColorB); -REGISTER_PROPERTY_ROW(Vec3AsColor, PropertyRowVec3AsColor); -REGISTER_PROPERTY_ROW(SerializableColorF, PropertyRowColorF); - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColor.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColor.h deleted file mode 100644 index 9859539b46..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColor.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyDrawContext.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include -#endif - -struct IPropertyRowColor -{ - virtual bool pickColor(QPropertyTree* tree) = 0; -}; - -template -class PropertyRowColor - : public PropertyRow - , public IPropertyRowColor -{ -public: - PropertyRowColor() - : colorChanged_(false) {} - - bool isLeaf() const override { return colorChanged_; } - bool isStatic() const override { return false; } - WidgetPlacement widgetPlacement() const{ return WIDGET_AFTER_PULLED; } - int widgetSizeMin(const QPropertyTree* tree) const { return userWidgetSize() >= 0 ? userWidgetSize() : tree->_defaultRowHeight()* 2 - 4; } - void handleChildrenChange() override; - - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - bool assignTo(const Serialization::SStruct& ser) const override; - void closeNonLeaf(const Serialization::SStruct& ser, Serialization::IArchive& ar); - - bool onActivate(const PropertyActivationEvent& ev) override; - - string valueAsString() const; - void redraw(const PropertyDrawContext& context); - - bool onContextMenu(QMenu& menu, QPropertyTree* tree); - - bool pickColor(QPropertyTree* tree) override; - -private: - QColor color_; - bool colorChanged_; -}; - -struct ColorMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - QPropertyTree * tree; - IPropertyRowColor* propertyRowColor; - - ColorMenuHandler(QPropertyTree* tree, IPropertyRowColor* propertyRowColor); - ~ColorMenuHandler(){}; - -public slots: - void onMenuPickColor(); -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColorPicker.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColorPicker.cpp deleted file mode 100644 index 24650d9b89..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColorPicker.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "EditorCommon_precompiled.h" -#include "PropertyRowColorPicker.h" -#include "Serialization/ClassFactory.h" -#include -#include -#include -#include -#include - -#include -#include - -bool PropertyRowColorPicker::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason == e.REASON_RELEASE) - { - return false; - } - - // ColorF -> QColor. - AZ::Color initialColor; - initialColor.SetR(color_.r); - initialColor.SetG(color_.g); - initialColor.SetB(color_.b); - initialColor.SetA(color_.a); - - const AZ::Color colorFromDialog = AzQtComponents::ColorPicker::getColor(AzQtComponents::ColorPicker::Configuration::RGBA, - initialColor, - QObject::tr("Select Color")); - - if (initialColor == colorFromDialog) - { - // The user cancelled the dialog box. - // Nothing more to do. - return false; - } - - // QColor -> ColorF. - ColorF color(colorFromDialog.GetR(), - colorFromDialog.GetG(), - colorFromDialog.GetB(), - colorFromDialog.GetA()); - - e.tree->model()->rowAboutToBeChanged(this); - color_ = color; - e.tree->model()->rowChanged(this); - - return true; -} -void PropertyRowColorPicker::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) -{ - ColorPicker* value = (ColorPicker*)ser.pointer(); - color_ = *value->color; -} - -bool PropertyRowColorPicker::assignTo(const Serialization::SStruct& ser) const -{ - ((ColorPicker*)ser.pointer())->SetColor(&color_); - - return true; -} - -void PropertyRowColorPicker::serializeValue(Serialization::IArchive& ar) -{ - ar(color_, "color"); -} - -const QIcon& PropertyRowColorPicker::buttonIcon([[maybe_unused]] const QPropertyTree* tree, [[maybe_unused]] int index) const -{ - // Color-chip. - - QColor color((int)(color_.r * 255.0f), - (int)(color_.g * 255.0f), - (int)(color_.b * 255.0f)); - QPen pen(color); - QBrush brush(color); - - QPixmap pixmap(16, 16); - pixmap.fill(Qt::transparent); - - QPainter painter(&pixmap); - painter.setBrush(brush); - painter.setPen(pen); - painter.drawEllipse(0, 0, 15, 15); - - static QIcon icon; - icon.addPixmap(pixmap); - return icon; -} - -string PropertyRowColorPicker::valueAsString() const -{ - int r = (int)(255.0f * color_.r); - int g = (int)(255.0f * color_.g); - int b = (int)(255.0f * color_.b); - int a = (int)(255.0f * color_.a); - string value; - value.Format("#%02x%02x%02x%02x", r, g, b, a); - return value; -} - -void PropertyRowColorPicker::clear() -{ - color_ = Col_White; -} - -bool PropertyRowColorPicker::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - QAction* action = menu.addAction("Clear"); - QObject::connect(action, - &QAction::triggered, - tree, - [ this, tree ] - { - tree->model()->rowAboutToBeChanged(this); - clear(); - tree->model()->rowChanged(this); - }); - return true; -} - -bool PropertyRowColorPicker::processesKey(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (QKeySequence(ev->key()) == QKeySequence(Qt::Key_Delete)) - { - return true; - } - - return PropertyRowField::processesKey(tree, ev); -} - -bool PropertyRowColorPicker::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - tree->model()->rowAboutToBeChanged(this); - clear(); - tree->model()->rowChanged(this); - return true; - } - return PropertyRowField::onKeyDown(tree, ev); -} - -REGISTER_PROPERTY_ROW(ColorPicker, PropertyRowColorPicker); -DECLARE_SEGMENT(PropertyRowColorPicker) - diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColorPicker.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColorPicker.h deleted file mode 100644 index 90fb049a04..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowColorPicker.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCOLORPICKER_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCOLORPICKER_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyDrawContext.h" -#include "PropertyRowField.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Serialization.h" -#include -#include -#include -#endif - -using Serialization::ColorPicker; - -class PropertyRowColorPicker - : public PropertyRowField -{ -public: - void clear(); - - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - bool assignTo(const Serialization::SStruct& ser) const override; - bool onActivate(const PropertyActivationEvent& e) override; - - int buttonCount() const override { return 1; } - virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override; - string valueAsString() const override; - void serializeValue(Serialization::IArchive& ar); - - bool onContextMenu(QMenu& menu, QPropertyTree* tree); - - bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; - -private: - ColorF color_; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCOLORPICKER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowContainer.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowContainer.cpp deleted file mode 100644 index c67c7fbd05..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowContainer.cpp +++ /dev/null @@ -1,439 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowContainer.h" -#include "PropertyRowPointer.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "PropertyDrawContext.h" -#include "Serialization.h" -#include "PropertyRowPointer.h" - -#include -#include - -// --------------------------------------------------------------------------- - -ContainerMenuHandler::ContainerMenuHandler(QPropertyTree* tree, PropertyRowContainer* container) - : element() - , container(container) - , tree(tree) - , pointerIndex(-1) -{ -} - - - -// --------------------------------------------------------------------------- -SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRowContainer, "PropertyRowContainer", "Container"); - -PropertyRowContainer::PropertyRowContainer() - : fixedSize_(false) - , elementTypeName_("") - , inlined_(false) -{ - buttonLabel_[0] = '\0'; -} - -struct ClassMenuItemAdderRowContainer - : ClassMenuItemAdder -{ - ClassMenuItemAdderRowContainer(PropertyRowContainer* row, QPropertyTree* tree, bool insert = false) - : row_(row) - , tree_(tree) - , insert_(insert) {} - - void addAction(QMenu& menu, const char* text, int index) override - { - ContainerMenuHandler* handler = row_->createMenuHandler(tree_, row_); - tree_->addMenuHandler(handler); - handler->pointerIndex = index; - - QAction* action = menu.addAction(text); - QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuAppendPointerByIndex())); - } -protected: - PropertyRowContainer* row_; - QPropertyTree* tree_; - bool insert_; -}; - -void PropertyRowContainer::redraw(const PropertyDrawContext& context) -{ - QRect widgetRect = context.widgetRect; - if (widgetRect.width() == 0 || inlined_) - { - return; - } - QRect rt = widgetRect; - rt.adjust(0, 1, -1, -1); - QColor brushColor = context.tree->palette().button().color(); - QLinearGradient gradient(rt.left(), rt.top(), rt.left(), rt.bottom()); - gradient.setColorAt(0.0f, brushColor); - gradient.setColorAt(0.6f, brushColor); - gradient.setColorAt(1.0f, context.tree->palette().color(QPalette::Shadow)); - QBrush brush(gradient); - - const wchar_t* text = multiValue() ? L"..." : buttonLabel_; - int buttonFlags = BUTTON_CENTER | BUTTON_POPUP_ARROW; - if (userReadOnly()) - { - buttonFlags |= BUTTON_DISABLED; - } - if (context.m_pressed) - { - buttonFlags |= BUTTON_PRESSED; - } - context.drawButton(rt, text, buttonFlags, &context.tree->font()); -} - - -bool PropertyRowContainer::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason == e.REASON_RELEASE) - { - return false; - } - if (userReadOnly()) - { - return false; - } - if (inlined_) - { - return false; - } - QMenu menu; - generateMenu(menu, e.tree, true); - e.tree->_setPressedRow(this); - menu.exec(e.tree->_toScreen(QPoint(widgetPos_, pos_.y() + e.tree->_defaultRowHeight()))); - e.tree->_setPressedRow(0); - return true; -} - -ContainerMenuHandler* PropertyRowContainer::createMenuHandler(QPropertyTree* tree, PropertyRowContainer* container) -{ - return new ContainerMenuHandler(tree, container); -} - -void PropertyRowContainer::generateMenu(QMenu& menu, QPropertyTree* tree, bool addActions) -{ - ContainerMenuHandler* handler = createMenuHandler(tree, this); - tree->addMenuHandler(handler); - - if (fixedSize_) - { - if (!inlined_) - { - menu.addAction("[ Fixed Size Container ]")->setEnabled(false); - } - } - else if (userReadOnly()) - { - menu.addAction("[ Read Only Container ]")->setEnabled(false); - } - else - { - if (addActions) - { - PropertyRow* row = defaultRow(tree->model()); - if (row && row->isPointer()) - { - QMenu* createItem = menu.addMenu("Add"); - menu.addSeparator(); - - PropertyRowPointer* pointerRow = static_cast(row); - ClassMenuItemAdderRowContainer(this, tree).generateMenu(*createItem, tree->model()->typeStringList(pointerRow->baseType())); - } - else - { - menu.addAction("Insert", handler, SLOT(onMenuAddElement())); - menu.addAction("Add", handler, SLOT(onMenuAppendElement()), Qt::Key_Insert); - } - } - - if (!menu.isEmpty()) - { - menu.addSeparator(); - } - - QAction* removeAll = menu.addAction(pulledUp() ? "Remove Children" : "Remove All"); - removeAll->setShortcut(QKeySequence("Shift+Delete")); - removeAll->setEnabled(!userReadOnly()); - QObject::connect(removeAll, SIGNAL(triggered()), handler, SLOT(onMenuRemoveAll())); - } -} - -bool PropertyRowContainer::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - if (!menu.isEmpty()) - { - menu.addSeparator(); - } - - generateMenu(menu, tree, true); - - if (pulledUp()) - { - return !menu.isEmpty(); - } - - return PropertyRow::onContextMenu(menu, tree); -} - - -void ContainerMenuHandler::onMenuRemoveAll() -{ - tree->model()->rowAboutToBeChanged(container); - container->clear(); - tree->model()->rowChanged(container); -} - -PropertyRow* PropertyRowContainer::defaultRow(PropertyTreeModel* model) -{ - PropertyRow* defaultType = model->defaultType(elementTypeName_); - //YASLI_ASSERT(defaultType); - //YASLI_ASSERT(defaultType->numRef() == 1); - return defaultType; -} - -const PropertyRow* PropertyRowContainer::defaultRow(const PropertyTreeModel* model) const -{ - const PropertyRow* defaultType = model->defaultType(elementTypeName_); - return defaultType; -} - -void ContainerMenuHandler::onMenuAddElement() -{ - container->addElement(tree, false); -} - -void ContainerMenuHandler::onMenuAppendElement() -{ - container->addElement(tree, true); -} - -PropertyRow* PropertyRowContainer::addElement(QPropertyTree* tree, bool append) -{ - tree->model()->rowAboutToBeChanged(this); - PropertyRow* defaultType = defaultRow(tree->model()); - YASLI_ESCAPE(defaultType != 0, return 0); - SharedPtr clonedRow = defaultType->clone(tree->model()->constStrings()); - if (count() == 0) - { - tree->expandRow(this); - } - if (append) - { - add(clonedRow); - } - else - { - addBefore(clonedRow, 0); - } - clonedRow->setHideChildren(tree->outlineMode()); - clonedRow->setLabelChanged(); - clonedRow->setLabelChangedToChildren(); - setMultiValue(false); - if (expanded()) - { - tree->model()->selectRow(clonedRow, true); - } - tree->expandRow(clonedRow); - TreePath path = tree->model()->pathFromRow(clonedRow); - tree->model()->rowChanged(clonedRow); - clonedRow = tree->model()->rowFromPath(path); - tree->update(); - clonedRow = tree->model()->rowFromPath(path); - if (clonedRow) - { - PropertyTreeModel::Selection sel; - sel.push_back(path); - tree->model()->setSelection(sel); - if (clonedRow->activateOnAdd()) - { - PropertyActivationEvent e; - e.tree = tree; - e.reason = e.REASON_NEW_ELEMENT; - clonedRow->onActivate(e); - } - } - return clonedRow; -} - - -void ContainerMenuHandler::onMenuAppendPointerByIndex() -{ - PropertyRow* defaultType = container->defaultRow(tree->model()); - PropertyRowPointer* defaultTypePointer = static_cast(defaultType); - SharedPtr clonedRow = defaultType->clone(tree->model()->constStrings()); - if (container->count() == 0) - { - tree->expandRow(container); - } - container->add(clonedRow); - clonedRow->setLabelChanged(); - clonedRow->setLabelChangedToChildren(); - clonedRow->setHideChildren(tree->outlineMode()); - container->setMultiValue(false); - PropertyRowPointer* clonedRowPointer = static_cast(clonedRow.get()); - clonedRowPointer->setDerivedType(defaultTypePointer->derivedTypeName(), defaultTypePointer->factory()); - clonedRowPointer->setBaseType(defaultTypePointer->baseType()); - clonedRowPointer->setFactory(defaultTypePointer->factory()); - if (container->expanded()) - { - tree->model()->selectRow(clonedRow, true); - } - tree->expandRow(clonedRowPointer); - PropertyTreeModel::Selection sel = tree->model()->selection(); - - CreatePointerMenuHandler handler; - handler.tree = tree; - handler.row = clonedRowPointer; - handler.index = pointerIndex; - handler.onMenuCreateByIndex(); - tree->model()->setSelection(sel); - tree->update(); -} - -void ContainerMenuHandler::onMenuChildInsertBefore() -{ - tree->model()->rowAboutToBeChanged(container); - PropertyRow* defaultType = tree->model()->defaultType(container->elementTypeName()); - if (!defaultType) - { - return; - } - SharedPtr clonedRow = defaultType->clone(tree->model()->constStrings()); - clonedRow->setHideChildren(tree->outlineMode()); - element->setSelected(false); - container->addBefore(clonedRow, element); - container->setMultiValue(false); - tree->model()->selectRow(clonedRow, true); - PropertyTreeModel::Selection sel = tree->model()->selection(); - tree->model()->rowChanged(clonedRow); - tree->model()->setSelection(sel); - tree->update(); - clonedRow = tree->selectedRow(); - if (clonedRow->activateOnAdd()) - { - PropertyActivationEvent e; - e.tree = tree; - e.reason = PropertyActivationEvent::REASON_NEW_ELEMENT; - clonedRow->onActivate(e); - } -} - -void ContainerMenuHandler::onMenuChildRemove() -{ - tree->model()->rowAboutToBeChanged(container); - container->erase(element); - container->setMultiValue(false); - tree->model()->rowChanged(container); -} - - -void PropertyRowContainer::labelChanged() -{ - swprintf(buttonLabel_, sizeof(buttonLabel_) / sizeof(buttonLabel_[0]), L"%zi", count()); -} - -void PropertyRowContainer::serializeValue(IArchive& ar) -{ - ar(ConstStringWrapper(constStrings_, elementTypeName_), "elementTypeName", "ElementTypeName"); - ar(fixedSize_, "fixedSize", "fixedSize"); -} - -string PropertyRowContainer::valueAsString() const -{ - char buf[32] = { 0 }; - sprintf_s(buf, "%d", (int)children_.size()); - return string(buf); -} - -const char* PropertyRowContainer::typeNameForFilter(QPropertyTree* tree) const -{ - const PropertyRow* defaultType = defaultRow(tree->model()); - if (defaultType) - { - return defaultType->typeNameForFilter(tree); - } - else - { - return elementTypeName_; - } -} - -bool PropertyRowContainer::processesKeyContainer([[maybe_unused]] QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete && ev->modifiers() == Qt::SHIFT) - { - return true; - } - - if (ev->key() == Qt::Key_Insert && ev->modifiers() == Qt::NoModifier) - { - return true; - } - - return false; -} - -bool PropertyRowContainer::processesKey(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (processesKeyContainer(tree, ev)) - { - return true; - } - - return PropertyRow::processesKey(tree, ev); -} - -bool PropertyRowContainer::onKeyDownContainer(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (userReadOnly()) - { - return false; - } - - std::unique_ptr handler(createMenuHandler(tree, this)); - if (ev->key() == Qt::Key_Delete && ev->modifiers() == Qt::SHIFT) - { - handler->onMenuRemoveAll(); - return true; - } - - if (ev->key() == Qt::Key_Insert && ev->modifiers() == Qt::NoModifier) - { - handler->onMenuAppendElement(); - return true; - } - - return false; -} - -bool PropertyRowContainer::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (onKeyDownContainer(tree, ev)) - { - return true; - } - return PropertyRow::onKeyDown(tree, ev); -} - -int PropertyRowContainer::widgetSizeMin(const QPropertyTree* tree) const -{ - return inlined_ ? 0 : (userWidgetSize() >= 0 ? userWidgetSize() : aznumeric_cast(tree->_defaultRowHeight() * 1.7f)); -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowContainer.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowContainer.h deleted file mode 100644 index d4e8d2f6d3..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowContainer.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCONTAINER_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCONTAINER_H -#pragma once -#if !defined(Q_MOC_RUN) -#include "PropertyRow.h" -#endif - - -class EDITOR_COMMON_API PropertyRowContainer; -struct EDITOR_COMMON_API ContainerMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - - QPropertyTree * tree; - PropertyRowContainer* container; - PropertyRow* element; - int pointerIndex; - - ContainerMenuHandler(QPropertyTree* tree, PropertyRowContainer* container); - -public slots: - virtual void onMenuAddElement(); - virtual void onMenuAppendElement(); - virtual void onMenuAppendPointerByIndex(); - virtual void onMenuRemoveAll(); - virtual void onMenuChildInsertBefore(); - virtual void onMenuChildRemove(); -}; - -class EDITOR_COMMON_API PropertyRowContainer - : public PropertyRow -{ -public: - PropertyRowContainer(); - bool isContainer() const{ return true; } - bool onActivate(const PropertyActivationEvent& e); - bool onContextMenu(QMenu& item, QPropertyTree* tree); - virtual ContainerMenuHandler* createMenuHandler(QPropertyTree* tree, PropertyRowContainer* container) override; - void redraw(const PropertyDrawContext& context); - bool processesKeyContainer(QPropertyTree* tree, const QKeyEvent* ev); - bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onKeyDownContainer(QPropertyTree* tree, const QKeyEvent* key); - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* key) override; - - void labelChanged() override; - bool isStatic() const{ return false; } - bool isSelectable() const{ return userWidgetSize() == 0 ? false : true; } - PropertyRow* addElement(QPropertyTree* tree, bool append); - void setInlined(bool inlined) { inlined_ = inlined; } - bool isInlined() const{ return inlined_; } - - PropertyRow* defaultRow(PropertyTreeModel* model); - const PropertyRow* defaultRow(const PropertyTreeModel* model) const; - void serializeValue(Serialization::IArchive& ar); - - const char* elementTypeName() const{ return elementTypeName_; } - using PropertyRow::setValueAndContext; - virtual void setValueAndContext(const Serialization::IContainer& value, [[maybe_unused]] Serialization::IArchive& ar) - { - fixedSize_ = value.isFixedSize(); - elementTypeName_ = value.elementType().name(); - serializer_.setPointer(value.pointer()); - serializer_.setType(value.containerType()); - } - const char* typeNameForFilter(QPropertyTree* tree) const override; - string valueAsString() const; - // C-array is an example of fixed size container - bool isFixedSize() const{ return fixedSize_; } - WidgetPlacement widgetPlacement() const override { return inlined_ ? WIDGET_NONE : WIDGET_AFTER_NAME; } - int widgetSizeMin(const QPropertyTree* tree) const override; - -protected: - virtual void generateMenu(QMenu& menu, QPropertyTree* tree, bool addActions); - - const char* elementTypeName_; - wchar_t buttonLabel_[8]; - bool fixedSize_; - bool inlined_; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCONTAINER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowField.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowField.cpp deleted file mode 100644 index b91c4fb9b3..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowField.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowField.h" -#include "PropertyDrawContext.h" -#include "QPropertyTree.h" -#include "QPropertyTreeStyle.h" -#include - -enum { BUTTON_SIZE = 16 }; - -QRect PropertyRowField::fieldRect(const QPropertyTree* tree) const -{ - QRect fieldRect = widgetRect(tree); - fieldRect.setRight(fieldRect.right() - buttonCount() * BUTTON_SIZE); - return fieldRect; -} - -bool PropertyRowField::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason == e.REASON_PRESS) { - int buttonCount = this->buttonCount(); - QRect buttonsRect = widgetRect(e.tree); - buttonsRect.setLeft(buttonsRect.right() - buttonCount * BUTTON_SIZE); - - if (buttonsRect.contains(e.clickPoint)) { - int buttonIndex = buttonCount - (e.clickPoint.x() - buttonsRect.x()) / BUTTON_SIZE - 1; - if (buttonIndex >= 0 && buttonIndex < buttonCount) - { - if (onActivateButton(buttonIndex, e)) - return true; - } - } - } - - return PropertyRow::onActivate(e); -} - -void PropertyRowField::redraw(const PropertyDrawContext& context) -{ - int buttonCount = this->buttonCount(); - int offset = 0; - for (int i = 0; i < buttonCount; ++i) { - const QIcon& icon = buttonIcon(context.tree, i); - QRect iconRect(context.widgetRect.right() - offset - BUTTON_SIZE, context.widgetRect.top(), BUTTON_SIZE, context.widgetRect.height()); - icon.paint(context.painter, iconRect, Qt::AlignCenter, userReadOnly() ? QIcon::Disabled : QIcon::Normal); - offset += BUTTON_SIZE; - } - - int iconSpace = offset ? offset + 2 : 0; - if(multiValue()) - context.drawEntry(L" ... ", false, true, iconSpace); - else if(userReadOnly()) - context.drawValueText(pulledSelected(), valueAsWString().c_str()); - else - context.drawEntry(valueAsWString().c_str(), usePathEllipsis(), false, iconSpace); - -} - -const QIcon& PropertyRowField::buttonIcon([[maybe_unused]] const QPropertyTree* tree, [[maybe_unused]] int index) const -{ - static QIcon defaultIcon; - return defaultIcon; -} - -int PropertyRowField::widgetSizeMin(const QPropertyTree* tree) const -{ - if (userWidgetSize() >= 0) - return userWidgetSize(); - - if (userWidgetToContent_) - return widthCache_.getOrUpdate(tree, this, 0); - else - return 40; -} - diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowField.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowField.h deleted file mode 100644 index a512fd330a..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowField.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWFIELD_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWFIELD_H -#pragma once - -#include "PropertyRow.h" -class QIcon; - -class PropertyRowField : public PropertyRow -{ -public: - WidgetPlacement widgetPlacement() const override{ return WIDGET_VALUE; } - int widgetSizeMin(const QPropertyTree* tree) const override; - - virtual int buttonCount() const{ return 0; } - virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const; - virtual bool usePathEllipsis() const { return false; } - virtual bool onActivateButton([[maybe_unused]] int buttonIndex, [[maybe_unused]] const PropertyActivationEvent& e) { return false; } - - void redraw(const PropertyDrawContext& context) override; - bool onActivate(const PropertyActivationEvent& e) override; -protected: - QRect fieldRect(const QPropertyTree* tree) const; - void drawButtons(int* offset); - - mutable RowWidthCache widthCache_; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWFIELD_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowIconXPM.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowIconXPM.cpp deleted file mode 100644 index 1227ec20d7..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowIconXPM.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/** - * yasli - Serialization Library. - * Copyright (C) 2007-2013 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "Serialization/ClassFactory.h" - -#include "PropertyDrawContext.h" -#include "PropertyRowImpl.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Serialization.h" -#include "Color.h" -#include "Serialization/Decorators/IconXPM.h" -using Serialization::IconXPM; -using Serialization::IconXPMToggle; - -class PropertyRowIconXPM : public PropertyRow{ -public: - void redraw(const PropertyDrawContext& context) - { - QRect rect = context.widgetRect; - context.drawIcon(rect, icon_); - } - - bool isLeaf() const{ return true; } - bool isStatic() const{ return false; } - bool isSelectable() const{ return false; } - - bool onActivate([[maybe_unused]] const PropertyActivationEvent& e) - { - return false; - } - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override { - YASLI_ESCAPE(ser.size() == sizeof(IconXPM), return); - icon_ = *(IconXPM*)(ser.pointer()); - } - wstring valueAsWString() const{ return L""; } - WidgetPlacement widgetPlacement() const{ return WIDGET_ICON; } - void serializeValue([[maybe_unused]] Serialization::IArchive& ar) {} - int widgetSizeMin(const QPropertyTree* tree) const override{ return tree->_defaultRowHeight(); } - int height() const{ return 16; } -protected: - IconXPM icon_; -}; - -class PropertyRowIconToggle : public PropertyRow{ -public: - void redraw(const PropertyDrawContext& context) override - { - IconXPM& icon = value_ ? iconTrue_ : iconFalse_; - context.drawIcon(context.widgetRect, icon); - } - - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override { - YASLI_ESCAPE(ser.size() == sizeof(IconXPMToggle), return); - const IconXPMToggle* icon = (IconXPMToggle*)(ser.pointer()); - iconTrue_ = icon->iconTrue_; - iconFalse_ = icon->iconFalse_; - value_ = icon->value_; - } - - bool assignTo(const Serialization::SStruct& ser) const override - { - IconXPMToggle* toggle = (IconXPMToggle*)ser.pointer(); - toggle->value_ = value_; - return true; - } - - bool isLeaf() const override{ return true; } - bool isStatic() const override{ return false; } - bool isSelectable() const override{ return true; } - bool onActivate(const PropertyActivationEvent& e) - { - if (e.reason != e.REASON_RELEASE) - { - e.tree->model()->rowAboutToBeChanged(this); - value_ = !value_; - e.tree->model()->rowChanged(this); - return true; - } - return false; - } - DragCheckBegin onMouseDragCheckBegin() override - { - if (userReadOnly()) - return DRAG_CHECK_IGNORE; - return value_ ? DRAG_CHECK_UNSET : DRAG_CHECK_SET; - } - bool onMouseDragCheck(QPropertyTree* tree, bool value) override - { - if (value_ != value) { - tree->model()->rowAboutToBeChanged(this); - value_ = value; - tree->model()->rowChanged(this); - return true; - } - return false; - } - wstring valueAsWString() const{ return value_ ? L"true" : L"false"; } - WidgetPlacement widgetPlacement() const{ return WIDGET_ICON; } - - int widgetSizeMin(const QPropertyTree* tree) const{ return tree->_defaultRowHeight(); } - int height() const{ return 16; } - - IconXPM iconTrue_; - IconXPM iconFalse_; - bool value_; -}; - -REGISTER_PROPERTY_ROW(IconXPM, PropertyRowIconXPM); -REGISTER_PROPERTY_ROW(IconXPMToggle, PropertyRowIconToggle); -DECLARE_SEGMENT(PropertyRowIconXPM) diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowImpl.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowImpl.h deleted file mode 100644 index 61cf50c9ad..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowImpl.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWIMPL_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWIMPL_H -#pragma once - -#include "Serialization/STL.h" -#include "PropertyRowField.h" -#include "Serialization.h" - -template -class PropertyRowImpl; - -template -class PropertyRowImpl : public PropertyRowField{ -public: - bool assignTo(const Serialization::SStruct& ser) const override { - *reinterpret_cast(ser.pointer()) = value(); - return true; - } - bool isLeaf() const override{ return true; } - bool isStatic() const override{ return false; } - void setValue(const Type& value) { value_ = value; } - Type& value() { return value_; } - const Type& value() const{ return value_; } - - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override { - YASLI_ESCAPE(ser.size() == sizeof(Type), return); - value_ = *(Type*)(ser.pointer()); - } - - void serializeValue(Serialization::IArchive& ar) override{ - ar(value_, "value", "Value"); - } -protected: - Type value_; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWIMPL_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowLocalFrame.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowLocalFrame.cpp deleted file mode 100644 index 6d318aecde..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowLocalFrame.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowLocalFrame.h" -#include -#include -#include -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include -#include -#include "Serialization/ClassFactory.h" -#include "PropertyDrawContext.h" -#include "Serialization.h" -#include - -using Serialization::LocalPosition; - -void LocalFrameMenuHandler::onMenuReset() -{ - self->reset(tree); -} - -PropertyRowLocalFrameBase::PropertyRowLocalFrameBase() - : m_sink(0) - , m_gizmoIndex(-1) - , m_handle(0) - , m_reset(false) -{ -} - -PropertyRowLocalFrameBase::~PropertyRowLocalFrameBase() -{ - m_sink = 0; -} - -bool PropertyRowLocalFrameBase::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason == e.REASON_RELEASE) - { - return false; - } - return false; -} - -string PropertyRowLocalFrameBase::valueAsString() const -{ - return string(); -} - -bool PropertyRowLocalFrameBase::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - Serialization::SharedPtr selfPointer(this); - - LocalFrameMenuHandler* handler = new LocalFrameMenuHandler(tree, this); - - menu.addAction("Reset", handler, SLOT(onMenuReset())); - - tree->addMenuHandler(handler); - return true; -} - -void PropertyRowLocalFrameBase::reset(QPropertyTree* tree) -{ - tree->model()->rowAboutToBeChanged(this); - m_reset = true; - tree->model()->rowChanged(this); -} - -void PropertyRowLocalFrameBase::redraw(const PropertyDrawContext& context) -{ - static QIcon gizmo("Icons/animation/gizmo_location.png"); - gizmo.paint(context.painter, context.widgetRect.adjusted(1, 1, 1, 1), Qt::AlignRight); -} - -static void ResetTransform(Serialization::LocalPosition* l) { *l->value = ZERO; } -static void ResetTransform(Serialization::LocalOrientation* l) { *l->value = IDENTITY; } -static void ResetTransform(Serialization::LocalFrame* l) { *l->position = ZERO; *l->rotation = IDENTITY; } - -template -class PropertyRowLocalFrameImpl - : public PropertyRowLocalFrameBase -{ -public: - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override - { - serializer_ = ser; - - TLocal* value = (TLocal*)ser.pointer(); - m_handle = value->handle; - m_reset = false; - - if (label() && label()[0]) - { - m_sink = ar.FindContext(); - if (m_sink) - { - m_gizmoIndex = m_sink->Write(*value, m_gizmoFlags, m_handle); - } - } - } - - void closeNonLeaf(const Serialization::SStruct& ser, Serialization::IArchive& ar) override - { - if (label() && label()[0] && ar.IsInput()) - { - TLocal& value = *((TLocal*)ser.pointer()); - if (m_sink) - { - if (m_sink->CurrentGizmoIndex() == m_gizmoIndex) - { - m_sink->Read(&value, &m_gizmoFlags, m_handle); - } - else - { - m_sink->SkipRead(); - } - } - } - } - - bool assignTo(const Serialization::SStruct& ser) const - { - if (m_reset) - { - TLocal& value = *((TLocal*)ser.pointer()); - ResetTransform(&value); - } - return false; - } -}; - -typedef PropertyRowLocalFrameImpl PropertyRowLocalPosition; -typedef PropertyRowLocalFrameImpl PropertyRowLocalOrientation; -typedef PropertyRowLocalFrameImpl PropertyRowLocalFrame; - -REGISTER_PROPERTY_ROW(Serialization::LocalPosition, PropertyRowLocalPosition); -REGISTER_PROPERTY_ROW(Serialization::LocalOrientation, PropertyRowLocalOrientation); -REGISTER_PROPERTY_ROW(Serialization::LocalFrame, PropertyRowLocalFrame); - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowLocalFrame.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowLocalFrame.h deleted file mode 100644 index 44b0597542..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowLocalFrame.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWLOCALFRAME_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWLOCALFRAME_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "Serialization/Decorators/IGizmoSink.h" -#include "PropertyRowField.h" -#include "QPropertyTree.h" -#endif - -struct IGizmoSink; - -class PropertyRowLocalFrameBase - : public PropertyRow -{ -public: - PropertyRowLocalFrameBase(); - ~PropertyRowLocalFrameBase(); - - bool isLeaf() const override { return m_reset; } - bool isStatic() const override { return false; } - - bool onActivate(const PropertyActivationEvent& e) override; - - WidgetPlacement widgetPlacement() const override { return WIDGET_AFTER_PULLED; } - int widgetSizeMin(const QPropertyTree* tree) const override { return tree->_defaultRowHeight(); } - - string valueAsString() const override; - bool onContextMenu(QMenu& menu, QPropertyTree* tree) override; - const void* searchHandle() const override { return m_handle; } - void redraw(const PropertyDrawContext& context) override; - - void reset(QPropertyTree* tree); -protected: - Serialization::IGizmoSink* m_sink; - const void* m_handle; - int m_gizmoIndex; - mutable Serialization::GizmoFlags m_gizmoFlags; - bool m_reset; -}; - -struct LocalFrameMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - QPropertyTree * tree; - PropertyRowLocalFrameBase* self; - - LocalFrameMenuHandler(QPropertyTree* tree, PropertyRowLocalFrameBase* self) - : tree(tree) - , self(self) {} -public slots: - void onMenuReset(); -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWLOCALFRAME_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumber.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumber.cpp deleted file mode 100644 index 3ba58a83aa..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumber.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Serialization.h" -#include "PropertyRowNumber.h" - -#define REGISTER_NUMBER_ROW(TypeName, postfix) \ - typedef PropertyRowNumber PropertyRow##postfix; \ - typedef Serialization::RangeDecorator RangeDecorator##postfix; \ - PropertyRow* TypeName##postfixFactory() { return new PropertyRow##postfix; }; \ - REGISTER_IN_FACTORY(PropertyRowFactory, Serialization::TypeID::get().name(), PropertyRow##postfix, TypeName##postfixFactory); \ - SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRow##postfix, "PropertyRow" #postfix, #TypeName); - -REGISTER_NUMBER_ROW(float, Float) -REGISTER_NUMBER_ROW(double , Double) - -REGISTER_NUMBER_ROW(char, Char) -REGISTER_NUMBER_ROW(int8, Int8) -REGISTER_NUMBER_ROW(uint8, Uint8) - -REGISTER_NUMBER_ROW(int16, Int16) -REGISTER_NUMBER_ROW(int32, Int32) -REGISTER_NUMBER_ROW(int64, Int64) -REGISTER_NUMBER_ROW(uint16, Uint16) -REGISTER_NUMBER_ROW(uint32, Uint32) -REGISTER_NUMBER_ROW(uint64, Uint64) - -#undef REGISTER_NUMBER_ROW - -DECLARE_SEGMENT(PropertyRowNumber) - -// --------------------------------------------------------------------------- diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumber.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumber.h deleted file mode 100644 index 8658f5d878..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumber.h +++ /dev/null @@ -1,237 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBER_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBER_H -#pragma once - - -#include "QPropertyTree.h" -#include "Serialization/MemoryWriter.h" -#include "Serialization/Decorators/Range.h" -#include "PropertyRowNumberField.h" - -#include -#include -#include - -template -string numberAsString(T value) -{ - Serialization::MemoryWriter buf; - buf << value; - return buf.c_str(); -} - -inline long long stringToSignedInteger(const char* str) -{ - long long value; -#ifdef _MSC_VER - value = _atoi64(str); -#else - char* endptr = (char*)str; - value = strtoll(str, &endptr, 10); -#endif - return value; -} - -inline unsigned long long stringToUnsignedInteger(const char* str) -{ - unsigned long long value; - if (*str == '-') { - value = 0; - } - else { -#ifdef _MSC_VER - char* endptr = (char*)str; - value = _strtoui64(str, &endptr, 10); -#else - char* endptr = (char*)str; - value = strtoull(str, &endptr, 10); -#endif - } - return value; -} - -template -Output clamp(Input value, Output min, Output max) -{ - if (value < Input(min)) - return min; - if (value > Input(max)) - return max; - return Output(value); -} - -template void clampToType(Out* out, In value) { *out = clamp(value, std::numeric_limits::lowest(), std::numeric_limits::max()); } - -inline void clampedNumberFromString(char* value, const char* str) { clampToType(value, stringToSignedInteger(str)); } -inline void clampedNumberFromString(signed char* value, const char* str) { clampToType(value, stringToSignedInteger(str)); } -inline void clampedNumberFromString(short* value, const char* str) { clampToType(value, stringToSignedInteger(str)); } -inline void clampedNumberFromString(int* value, const char* str) { clampToType(value, stringToSignedInteger(str)); } -inline void clampedNumberFromString(long* value, const char* str) { clampToType(value, stringToSignedInteger(str)); } -inline void clampedNumberFromString(long long* value, const char* str) { clampToType(value, stringToSignedInteger(str)); } -inline void clampedNumberFromString(unsigned char* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); } -inline void clampedNumberFromString(unsigned short* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); } -inline void clampedNumberFromString(unsigned int* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); } -inline void clampedNumberFromString(unsigned long* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); } -inline void clampedNumberFromString(unsigned long long* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); } -inline void clampedNumberFromString(float* value, const char* str) -{ - double v = atof(str); - if (v > FLT_MAX) - v = FLT_MAX; - if (v < -FLT_MAX) - v = -FLT_MAX; - *value = float(v); -} - -inline void clampedNumberFromString(double* value, const char* str) -{ - *value = atof(str); -} - - -template -class PropertyRowNumber : public PropertyRowNumberField{ -public: - PropertyRowNumber() - { - softMin_ = std::numeric_limits::lowest(); - softMax_ = std::numeric_limits::max(); - hardMin_ = std::numeric_limits::lowest(); - hardMax_ = std::numeric_limits::max(); - } - - void setValue(Type value, const void* handle, const Serialization::TypeID& type) - { - value_ = value; - serializer_.setPointer((void*)handle); - serializer_.setType(type); - } - bool setValueFromString(const char* str) override{ - Type value = value_; - clampedNumberFromString(&value_, str); - return value_ != value; - } - string valueAsString() const override - { - return numberAsString(Type(value_)); - } - - bool assignToPrimitive(void* object, [[maybe_unused]] size_t size) const override - { - *reinterpret_cast(object) = value_; - return true; - } - - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override - { - Serialization::RangeDecorator* range = (Serialization::RangeDecorator*)ser.pointer(); - serializer_.setPointer((void*)range->value); - serializer_.setType(Serialization::TypeID::get()); - value_ = *range->value; - softMin_ = range->softMin; - softMax_ = range->softMax; - hardMin_ = range->hardMin; - hardMax_ = range->hardMax; - } - - bool assignTo(const Serialization::SStruct& ser) const override - { - if (ser.type() == Serialization::TypeID::get>()) { - Serialization::RangeDecorator* range = (Serialization::RangeDecorator*)ser.pointer(); - *range->value = value_; - } - else if (ser.type() == Serialization::TypeID::get()) { - *(Type*)ser.pointer() = value_; - } - return true; - } - - void serializeValue(Serialization::IArchive& ar) - { - ar(value_, "value", "Value"); - ar(softMin_, "softMin", "SoftMin"); - ar(softMax_, "softMax", "SoftMax"); - ar(hardMin_, "hardMin", "HardMin"); - ar(hardMax_, "hardMax", "HardMax"); - } - - void startIncrement() override - { - incrementStartValue_ = value_; - } - - void endIncrement(QPropertyTree* tree) override - { - if (value_ != incrementStartValue_) { - Type value = value_; - value_ = incrementStartValue_; - value_ = value; - tree->model()->rowChanged(this, true); - } - } - - void incrementLog(float screenFraction, float valueFieldFraction) - { - bool bothSoftLimitsSet = (std::numeric_limits::lowest() == 0 || softMin_ != std::numeric_limits::lowest()) && softMax_ != std::numeric_limits::max(); - - if (bothSoftLimitsSet) - { - Type softRange = softMax_ - softMin_; - double newValue = incrementStartValue_ + softRange * valueFieldFraction; - value_ = clamp(newValue, hardMin_, hardMax_); - } - else - { - double screenFractionMultiplier = 1000.0; - if (Serialization::TypeID::get() == Serialization::TypeID::get() || - Serialization::TypeID::get() == Serialization::TypeID::get()) - screenFractionMultiplier = 10.0; - - double startPower = log10(fabs(double(incrementStartValue_)) + 1.0) - 3.0; - double power = startPower + fabs(screenFraction) * 10.0f; - double delta = pow(10.0, power) - pow(10.0, startPower) + screenFractionMultiplier * fabs(screenFraction); - double newValue; - if (screenFraction > 0.0f) - newValue = double(incrementStartValue_) + delta; - else - newValue = double(incrementStartValue_) - delta; -#ifdef _MSC_VER - if (_isnan(newValue)) { -#else - if (isnan(newValue)) { -#endif - if (screenFraction > 0.0f) - newValue = DBL_MAX; - else - newValue = -DBL_MAX; - } - value_ = clamp(newValue, hardMin_, hardMax_); - } - } - - double sliderPosition() const override - { - if ((softMin_ == std::numeric_limits::lowest() && softMax_ == std::numeric_limits::max() && softMax_ != Type(255)) || (softMin_ >= softMax_)) - return 0.0; - return clamp(double(value_ - softMin_) / (softMax_ - softMin_), 0.0, 1.0); - } -protected: - Type incrementStartValue_; - Type value_; - Type softMin_; - Type softMax_; - Type hardMin_; - Type hardMax_; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumberField.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumberField.cpp deleted file mode 100644 index 94b30fb2ab..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumberField.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "QPropertyTree.h" -#include "QPropertyTreeStyle.h" -#include "PropertyTreeModel.h" -#include "PropertyRowNumberField.h" -#include "PropertyDrawContext.h" -#include "MathUtils.h" -#include -#include -#include -#include -#include - -PropertyRowNumberField::PropertyRowNumberField() - : pressed_(false) - , dragStarted_(false) -{ -} - -PropertyRowWidget* PropertyRowNumberField::createWidget(QPropertyTree* tree) -{ - return new PropertyRowWidgetNumber(tree->model(), this, tree); -} - -QColor interpolateColor(const QColor& a, const QColor& b, float k); - -void PropertyRowNumberField::redraw(const PropertyDrawContext& context) -{ - if (multiValue()) - context.drawEntry(L" ... ", false, true, 0); - else if (userReadOnly()) - context.drawValueText(pulledSelected(), valueAsWString().c_str()); - else - { - QPainter* painter = context.painter; - const QPropertyTree* tree = context.tree; - - QRect rt = context.widgetRect; - rt.adjust(0, 0, 0, -1); - -#if (QT_VERSION < QT_VERSION_CHECK(5, 11, 0)) - QStyleOptionFrameV2 option; - option.features = QStyleOptionFrameV2::None; -#else - QStyleOptionFrame option; - option.features = QStyleOptionFrame::None; -#endif - - option.state = QStyle::State_Sunken; - - // We require a widget to use as context, so that the style sheet can work. - QLineEdit widgetForContext; - option.lineWidth = tree->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, &widgetForContext); - - option.midLineWidth = 0; - - if (context.captured) { - option.state |= QStyle::State_HasFocus; - option.state |= QStyle::State_Active; - option.state |= QStyle::State_MouseOver; - } - else if (!userReadOnly()) { - option.state |= QStyle::State_Enabled; - } - option.rect = rt; // option.rect is the rectangle to be drawn on. - option.palette = tree->palette(); - option.fontMetrics = tree->fontMetrics(); - QRect textRect = tree->style()->subElementRect(QStyle::SE_LineEditContents, &option, &widgetForContext); - if (!textRect.isValid()) { - textRect = rt; - textRect.adjust(3, 1, -3, -2); - } - else { - textRect.adjust(2, 1, -2, -1); - } - - - widgetForContext.ensurePolished(); - option.palette = widgetForContext.palette(); - - painter->setPen(QPen(widgetForContext.palette().color(QPalette::WindowText))); - painter->setBrush(QBrush(widgetForContext.palette().color(QPalette::Base))); - tree->style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, painter, &widgetForContext); - - double sliderPos = sliderPosition(); - if (sliderPos != 0.0) - { - QRect r = textRect.adjusted(-2, -1, 2, 1); - QRect sliderOverlayRect(r.left(), r.top(), int(r.width() * sliderPos), r.height()); - QColor sliderOverlayColor = interpolateColor(tree->palette().color(QPalette::Window), tree->palette().color(QPalette::Highlight), tree->treeStyle().sliderSaturation); - sliderOverlayColor.setAlpha(192); - painter->setBrush(QBrush(sliderOverlayColor)); - painter->setPen(Qt::NoPen); - painter->drawRoundedRect(sliderOverlayRect, 1, 1); - - if (pressed_) { - painter->setPen(QColor(255, 255, 255)); - painter->setBrush(QBrush(QColor(255, 255, 255))); - painter->drawLine(sliderOverlayRect.right(), sliderOverlayRect.top(), sliderOverlayRect.right(), sliderOverlayRect.bottom()); - painter->setRenderHint(QPainter::Antialiasing, true); - painter->translate(0.5f, 0.5f); - int r2 = sliderOverlayRect.right(); - int t = sliderOverlayRect.top(); - int h = sliderOverlayRect.height(); - QPoint points[3] = { - QPoint(r2 - 1 - h / 8 - h / 3, t + h / 2), - QPoint(r2 - 1 - h / 8, t + h * 1 / 4), - QPoint(r2 - 1 - h / 8, t + h * 3 / 4) - }; - QPoint pointsR[3] = { - QPoint(r2 + 1 + h / 8 + h / 3, t + h / 2), - QPoint(r2 + 1 + h / 8, t + h * 1 / 4), - QPoint(r2 + 1 + h / 8, t + h * 3 / 4) - }; - painter->drawPolygon(points, 3); - painter->drawPolygon(pointsR, 3); - painter->setRenderHint(QPainter::Antialiasing, false); - painter->translate(-0.5f, -0.5f); - } - } - - painter->setPen(QPen(widgetForContext.palette().color(QPalette::WindowText))); - painter->setBrush(QBrush(widgetForContext.palette().color(QPalette::Base))); - painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, QString(valueAsString().c_str())); - - - } -} - -QCursor createSliderHoverCursor() -{ - QCursor arrow(Qt::ArrowCursor); - QPoint hotSpot = arrow.hotSpot(); - static QImage image = arrow.pixmap().toImage(); - if (image.isNull()) - return QCursor(Qt::SizeHorCursor); - - int w = image.width(); - int h = image.height(); - QImage empty(w * 2, h, QImage::Format_ARGB32); - empty.fill(Qt::transparent); - QPixmap pixmap = QPixmap::fromImage(empty); - if (pixmap.isNull()) - return QCursor(Qt::SizeHorCursor); - QPainter p(&pixmap); - p.drawImage(image.width() / 2, 0, image); - p.setRenderHint(QPainter::Antialiasing, true); - - QPoint points[3] = { - QPoint(w / 2 - w * 2 / 8, h / 2), - QPoint(w / 2 - w / 8, h * 3 / 8), - QPoint(w / 2 - w / 8, h * 5 / 8) - }; - QPoint pointsR[3] = { - QPoint(w, h * 3 / 8), - QPoint(w, h * 5 / 8), - QPoint(w + w / 8, h / 2), - }; - p.setBrush(QBrush(QColor(255, 255, 255))); - p.setPen(QPen(QColor(0, 0, 0))); - p.drawPolygon(points, 3); - p.drawPolygon(pointsR, 3); - return QCursor(pixmap, image.width() / 2 + hotSpot.x(), hotSpot.y()); -} - - -void PropertyRowNumberField::onMouseDrag(const PropertyDragEvent& e) -{ - if (!dragStarted_) { - e.tree->model()->rowAboutToBeChanged(this); - dragStarted_ = true; - } - QSize screenSize = QApplication::desktop()->screenGeometry(e.tree).size(); - float relativeDelta = float(e.totalDelta.x()) / screenSize.width(); - int fieldRectWidth = widgetRect(e.tree).width(); - if (fieldRectWidth < 16) - fieldRectWidth = aznumeric_cast(e.tree->treeSize().x() * e.tree->valueColumnWidth()); - float valueFieldFraction = fieldRectWidth < FLT_EPSILON ? 0 : float(e.totalDelta.x()) / fieldRectWidth; - incrementLog(relativeDelta, valueFieldFraction); - setMultiValue(false); -} - -bool PropertyRowNumberField::getHoverInfo(PropertyHoverInfo* hit, const QPoint& cursorPos, const QPropertyTree* tree) const -{ - if (pressed_ && !userReadOnly()) - hit->cursor = QCursor(Qt::BlankCursor); - else if (widgetRect(tree).contains(cursorPos) && !userReadOnly()) - hit->cursor = QCursor(createSliderHoverCursor()); - hit->toolTip = tooltip_; - return true; -} - -void PropertyRowNumberField::onMouseStill(const PropertyDragEvent& e) -{ - e.tree->model()->callRowCallback(this); - e.tree->apply(true); -} - -bool PropertyRowNumberField::onMouseDown(QPropertyTree* tree, QPoint point, bool& changed) -{ - changed = false; - if (widgetRect(tree).contains(point) && !userReadOnly()) { - startIncrement(); - pressed_ = true; - return true; - } - return false; -} - -void PropertyRowNumberField::onMouseUp(QPropertyTree* tree, [[maybe_unused]] QPoint point) -{ - tree->unsetCursor(); - pressed_ = false; - dragStarted_ = false; - - // endIncrement() can cause PropertyRow to be destroy, - // so no "this" members should be accessed after the call. - endIncrement(tree); -} - -bool PropertyRowNumberField::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason == e.REASON_RELEASE || e.reason == e.REASON_DOUBLECLICK) - return e.tree->spawnWidget(this, false); - return false; -} - -int PropertyRowNumberField::widgetSizeMin(const QPropertyTree* tree) const -{ - if (userWidgetSize() >= 0) - return userWidgetSize(); - - if (userWidgetToContent()) - return widthCache_.getOrUpdate(tree, this, 0); - else - return 40; -} - -// --------------------------------------------------------------------------- - -PropertyRowWidgetNumber::PropertyRowWidgetNumber([[maybe_unused]] PropertyTreeModel* model, PropertyRowNumberField* row, QPropertyTree* tree) - : PropertyRowWidget(row, tree) - , row_(row) - , entry_(new QLineEdit()) - , tree_(tree) -{ - entry_->setText(row_->valueAsString().c_str()); - connect(entry_, SIGNAL(editingFinished()), this, SLOT(onEditingFinished())); - connect(entry_, &QLineEdit::textChanged, this, [this, tree] { - QFontMetrics fm(entry_->font()); - int contentWidth = min((int)fm.horizontalAdvance(entry_->text()) + 8, tree->width() - entry_->x()); - if (contentWidth > entry_->width()) - entry_->resize(contentWidth, entry_->height()); - }); - - entry_->selectAll(); -} - - -void PropertyRowWidgetNumber::onEditingFinished() -{ - tree_->model()->rowAboutToBeChanged(row()); - string str = entry_->text().toLocal8Bit().data(); - if (row_->setValueFromString(str.c_str()) || row_->multiValue()) - tree_->model()->rowChanged(row()); - else - tree_->_cancelWidget(); -} - -void PropertyRowWidgetNumber::commit() -{ - if (entry_) - onEditingFinished(); -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumberField.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumberField.h deleted file mode 100644 index 888fb204fe..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowNumberField.h +++ /dev/null @@ -1,75 +0,0 @@ -// Modifications copyright Amazon.com, Inc. or its affiliates. -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBERFIELD_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBERFIELD_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyRow.h" -#include -#endif - -class PropertyRowNumberField; -class PropertyRowWidgetNumber : public PropertyRowWidget -{ - Q_OBJECT -public: - PropertyRowWidgetNumber(PropertyTreeModel* mode, PropertyRowNumberField* numberField, QPropertyTree* tree); - ~PropertyRowWidgetNumber(){ - if (entry_) - entry_->setParent(0); - entry_->deleteLater(); - entry_ = 0; - } - - void commit(); - QWidget* actualWidget() { return entry_; } -public slots: - void onEditingFinished(); -protected: - QLineEdit* entry_; - PropertyRowNumberField* row_; - QPropertyTree* tree_; -}; - -// --------------------------------------------------------------------------- - -class PropertyRowNumberField : public PropertyRow -{ -public: - PropertyRowNumberField(); - WidgetPlacement widgetPlacement() const override{ return WIDGET_VALUE; } - int widgetSizeMin(const QPropertyTree* tree) const override; - - PropertyRowWidget* createWidget(QPropertyTree* tree) override; - bool isLeaf() const override{ return true; } - bool isStatic() const override{ return false; } - bool inlineInShortArrays() const override{ return true; } - void redraw(const PropertyDrawContext& context) override; - bool onActivate(const PropertyActivationEvent& e) override; - bool onMouseDown(QPropertyTree* tree, QPoint point, bool& changed) override; - void onMouseUp(QPropertyTree* tree, QPoint point) override; - void onMouseDrag(const PropertyDragEvent& e) override; - void onMouseStill(const PropertyDragEvent& e) override; - bool getHoverInfo(PropertyHoverInfo* hit, const QPoint& cursorPos, const QPropertyTree* tree) const; - - virtual void startIncrement() = 0; - virtual void endIncrement(QPropertyTree* tree) = 0; - virtual void incrementLog(float screenFraction, float valueFieldFraction) = 0; - virtual bool setValueFromString(const char* str) = 0; - virtual double sliderPosition() const = 0; - - mutable RowWidthCache widthCache_; - bool pressed_ : 1; - bool dragStarted_ : 1; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBERFIELD_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowObject.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowObject.cpp deleted file mode 100644 index 35ffd659f2..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowObject.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowObject.h" -#include "PropertyTreeModel.h" - -PropertyRowObject::PropertyRowObject() - : model_(0) -{ -} - -bool PropertyRowObject::assignTo(Serialization::Object* obj) -{ - if (object_.type() == obj->type()) - { - *obj = object_; - return true; - } - return false; -} - -PropertyRowObject::~PropertyRowObject() -{ - object_ = Serialization::Object(); -} - -void PropertyRowObject::Serialize(Serialization::IArchive& ar) -{ - PropertyRow::Serialize(ar); -} - diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowObject.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowObject.h deleted file mode 100644 index 8f6f44cc00..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowObject.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOBJECT_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOBJECT_H -#pragma once -#include "PropertyRow.h" -#include "Serialization/MemoryWriter.h" -#include "Serialization/Pointers.h" -#include "Serialization/Object.h" - -namespace Serialization { - class IArchive; - struct SStruct; - class MemoryWriter; -}; - -class PropertyRowObject - : public PropertyRow -{ -public: - PropertyRowObject(); - ~PropertyRowObject(); - - using PropertyRow::setValueAndContext; - using PropertyRow::assignTo; - - void setValueAndContext(const Serialization::Object& obj, [[maybe_unused]] Serialization::IArchive& ar) { object_ = obj; } - void setModel(PropertyTreeModel* model) { model_ = model; } - bool isObject() const override { return true; } - bool assignTo(Serialization::Object* obj); - void Serialize(Serialization::IArchive& ar); - const Serialization::Object& object() const{ return object_; } -protected: - - Serialization::Object object_; - PropertyTreeModel* model_; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOBJECT_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowOutputFilePath.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowOutputFilePath.cpp deleted file mode 100644 index 545ba4a02d..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowOutputFilePath.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowOutputFilePath.h" -#include "Serialization/ClassFactory.h" -#include -#ifndef SERIALIZATION_STANDALONE -#include -#include // for Getting game folder -#endif -#include -#include -#include -#include - -OutputFilePathMenuHandler::OutputFilePathMenuHandler(QPropertyTree* tree, PropertyRowOutputFilePath* self) - : self(self) - , tree(tree) -{ -} - - -void OutputFilePathMenuHandler::onMenuClear() -{ - tree->model()->rowAboutToBeChanged(self); - self->clear(); - tree->model()->rowChanged(self); -} - -QString convertMFCToQtFileFilter(QString* defaultSuffix, const char* mfcFilter) -{ - // convert filter from "All Files|*.*|Text files|*.txt||" - // format into "All files (*.*);;Text Files (*.txt)" - QString filterMFC = QString::fromLocal8Bit(mfcFilter); - QStringList filterItems = filterMFC.split("|"); - - if (defaultSuffix && filterItems.size() > 1) - { - QString extensions = filterItems[1]; - QRegExp re("\\*\\.(\\w*)"); - if (extensions.indexOf(re) >= 0) - { - *defaultSuffix = re.cap(1); - } - } - - QString filter; - for (int i = 0; i < int(filterItems.size()) / 2; ++i) - { - int bracketPos = filterItems[i].indexOf('('); - QString desc = bracketPos >= 0 ? filterItems[i].left(bracketPos) : filterItems[i]; - int extIndex = i * 2 + 1; - if (extIndex >= filterItems.size()) - { - break; - } - if (!filter.isEmpty()) - { - filter += ";;"; - } - filter += desc; - filter += " ("; - filter += filterItems[extIndex]; - filter += ")"; - } - - return filter; -} - -bool PropertyRowOutputFilePath::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason == e.REASON_RELEASE) - { - return false; - } -#ifndef SERIALIZATION_STANDALONE - if (!GetIEditor()) - { - return true; - } -#endif - - QString title; - if (labelUndecorated()) - { - title = QString("Choose file for '") + labelUndecorated() + "'"; - } - else - { - title = "Choose file"; - } - -#ifdef SERIALIZATION_STANDALONE - QString gameFolder; -#else - QString gameFolder = QString::fromLocal8Bit(Path::GetEditingGameDataFolder().c_str()); -#endif - QDir gameFolderDir(QDir::fromNativeSeparators(gameFolder)); - QString defaultSuffix; - QString filter = convertMFCToQtFileFilter(&defaultSuffix, filter_.c_str()); - QString existingFile = QString::fromLocal8Bit(path_.c_str()); - - QString existingFilePath = (existingFile.isEmpty() || QDir::isAbsolutePath(existingFile)) ? existingFile : gameFolderDir.absoluteFilePath(existingFile); - QString startFolder = QString::fromLocal8Bit(startFolder_.c_str()); - - // Not using QFileDialog().exec() as it implements custom file dialog that - // freezes for couple of seconds when being open. Scannign network drives? - QString result = QFileDialog::getSaveFileName(e.tree, title, existingFilePath.isEmpty() ? (gameFolder + "/" + startFolder) : existingFilePath, filter); - if (!result.isEmpty()) - { - e.tree->model()->rowAboutToBeChanged(this); - QString relativeFilename = gameFolderDir.relativeFilePath(result); - path_ = relativeFilename.toLocal8Bit().data(); - e.tree->model()->rowChanged(this); - } - return true; -} -void PropertyRowOutputFilePath::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) -{ - OutputFilePath* value = (OutputFilePath*)ser.pointer(); - path_ = value->m_path->c_str(); - filter_ = value->filter.c_str(); - startFolder_ = value->startFolder.c_str(); - handle_ = value->m_path; -} - -bool PropertyRowOutputFilePath::assignTo(const Serialization::SStruct& ser) const -{ - ((OutputFilePath*)ser.pointer())->SetPath(path_.c_str()); - return true; -} - -const QIcon& PropertyRowOutputFilePath::buttonIcon(const QPropertyTree* tree, [[maybe_unused]] int index) const -{ - #include "file_save.xpm" - static QIcon fileOpenIcon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_save_xpm)))); - return fileOpenIcon; -} - -string PropertyRowOutputFilePath::valueAsString() const -{ - return path_; -} - - -void PropertyRowOutputFilePath::clear() -{ - path_.clear(); -} - -bool PropertyRowOutputFilePath::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - QAction* action = menu.addAction("Clear"); - Serialization::SharedPtr selfPointer(this); - - OutputFilePathMenuHandler* handler = new OutputFilePathMenuHandler(tree, this); - QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuClear())); - tree->addMenuHandler(handler); - return true; -} - -void PropertyRowOutputFilePath::serializeValue(Serialization::IArchive& ar) -{ - ar(path_, "path"); - ar(filter_, "filter"); - ar(startFolder_, "startFolder"); -} - -bool PropertyRowOutputFilePath::processesKey(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - return true; - } - - return PropertyRowField::processesKey(tree, ev); -} - -bool PropertyRowOutputFilePath::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - tree->model()->rowAboutToBeChanged(this); - clear(); - tree->model()->rowChanged(this); - return true; - } - return PropertyRowField::onKeyDown(tree, ev); -} - -REGISTER_PROPERTY_ROW(OutputFilePath, PropertyRowOutputFilePath); -DECLARE_SEGMENT(PropertyRowOutputFilePath) - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowOutputFilePath.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowOutputFilePath.h deleted file mode 100644 index d9f4cb1489..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowOutputFilePath.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOUTPUTFILEPATH_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOUTPUTFILEPATH_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyDrawContext.h" -#include "PropertyRowField.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Serialization.h" -#include -#include -#endif - -using Serialization::OutputFilePath; - -class PropertyRowOutputFilePath - : public PropertyRowField -{ -public: - void clear(); - - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - - bool onActivate(const PropertyActivationEvent& e) override; - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - bool assignTo(const Serialization::SStruct& ser) const override; - string valueAsString() const; - void serializeValue(Serialization::IArchive& ar); - bool onContextMenu(QMenu& menu, QPropertyTree* tree); - const void* searchHandle() const { return handle_; } - - int buttonCount() const override { return 1; } - virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override; - virtual bool usePathEllipsis() const override { return true; } - - bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; - -private: - string path_; - string filter_; - string startFolder_; - const void* handle_; -}; - -struct OutputFilePathMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - QPropertyTree * tree; - PropertyRowOutputFilePath* self; - - OutputFilePathMenuHandler(QPropertyTree* tree, PropertyRowOutputFilePath* container); -public slots: - void onMenuClear(); -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOUTPUTFILEPATH_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowPointer.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowPointer.cpp deleted file mode 100644 index d11897b043..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowPointer.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowPointer.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "PropertyDrawContext.h" -#include "Serialization.h" -#include "Unicode.h" -#include - - -// --------------------------------------------------------------------------- - -void ClassMenuItemAdder::generateMenu(QMenu& createItem, const StringList& comboStrings) -{ - StringList::const_iterator it; - int index = 0; - for (it = comboStrings.begin(); it != comboStrings.end(); ++it) - { - StringList path; - splitStringList(&path, it->c_str(), '\\'); - QMenu* item = &createItem; - //createItem.addMenu( - for (int level2 = 0; level2 < int(path.size()); ++level2) - { - const char* leaf = path[level2].c_str(); - if (level2 == path.size() - 1) - { - addAction(*item, leaf, index++); - } - else - { - if (QMenu* menu = item->findChild(leaf)) - { - item = menu; - } - else - { - item = addMenu(*item, leaf); //&item->add(leaf); - } - } - } - } -} - -void ClassMenuItemAdder::addAction(QMenu& menu, const char* text, [[maybe_unused]] int index) -{ - menu.addAction(text)->setEnabled(false); -} - -QMenu* ClassMenuItemAdder::addMenu(QMenu& menu, const char* text) -{ - QMenu* result = menu.addMenu(text); - result->setObjectName(text); - return result; -} - - -// --------------------------------------------------------------------------- - -SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRowPointer, "PropertyRowPointer", "SharedPtr"); - -PropertyRowPointer::PropertyRowPointer() - : factory_(0) - , searchHandle_(0) - , colorOverride_(0, 0, 0, 0) -{ -} - -void PropertyRowPointer::setDerivedType(const char* typeName, Serialization::IClassFactory* factory) -{ - if (!factory) - { - derivedTypeName_.clear(); - return; - } - derivedTypeName_ = typeName; -} - -bool PropertyRowPointer::assignTo(Serialization::IPointer& ptr) -{ - if (derivedTypeName_ != ptr.registeredTypeName()) - { - ptr.create(derivedTypeName_.c_str()); - } - - return true; -} - - -void CreatePointerMenuHandler::onMenuCreateByIndex() -{ - tree->model()->rowAboutToBeChanged(row); - if (index < 0) // NULL value - { - row->setDerivedType("", 0); - row->clear(); - } - else - { - const PropertyDefaultDerivedTypeValue* defaultValue = tree->model()->defaultType(row->baseType(), index); - SharedPtr clonedDefault = defaultValue->root->clone(tree->model()->constStrings()); - if (defaultValue && defaultValue->root) - { - YASLI_ASSERT(defaultValue->root->refCount() == 1); - if (useDefaultValue) - { - row->clear(); - row->swapChildren(clonedDefault, 0); - } - row->setDerivedType(defaultValue->registeredName.c_str(), row->factory()); - row->setLabelChanged(); - row->setLabelChangedToChildren(); - tree->expandRow(row); - } - else - { - row->setDerivedType("", 0); - row->clear(); - } - } - tree->model()->rowChanged(row); -} - - -string PropertyRowPointer::valueAsString() const -{ - string result; - const Serialization::TypeDescription* desc = 0; - if (factory_) - { - desc = factory_->descriptionByRegisteredName(derivedTypeName_.c_str()); - } - if (desc) - { - result = desc->label(); - } - else - { - result = derivedTypeName_; - } - - return result; -} - -wstring PropertyRowPointer::generateLabel() const -{ - if (multiValue()) - { - return L"..."; - } - - wstring str; - if (!derivedTypeName_.empty()) - { - const char* textStart = derivedTypeName_.c_str(); - if (factory_) - { - const Serialization::TypeDescription* desc = factory_->descriptionByRegisteredName(derivedTypeName_.c_str()); - - if (desc) - { - textStart = desc->label(); - } - } - const char* p = textStart + strlen(textStart); - while (p > textStart) - { - if (*(p - 1) == '\\') - { - break; - } - --p; - } - str = toWideChar(p); - if (p != textStart) - { - str += L" ("; - str += toWideChar(string(textStart, p - 1).c_str()); - str += L")"; - } - } - else - { - if (factory_) - { - str = toWideChar(factory_->nullLabel() ? factory_->nullLabel() : "[ null ]"); - } - else - { - str = L"[ null ]"; - } - } - return str; -} - -void PropertyRowPointer::redraw(const PropertyDrawContext& context) -{ - QRect widgetRect = context.widgetRect; - QRect rt = widgetRect; - rt.adjust(-1, 0, 0, 1); - wstring str = generateLabel(); - const QFont* font = derivedTypeName_.empty() ? &context.tree->font() : &context.tree->_boldFont(); - int buttonFlags = BUTTON_POPUP_ARROW; - if (userReadOnly()) - { - buttonFlags |= BUTTON_DISABLED; - } - if (context.m_pressed) - { - buttonFlags |= BUTTON_PRESSED; - } - context.drawButton(rt, str.c_str(), buttonFlags, font, colorOverride_.a != 0 ? &colorOverride_ : 0); -} - -struct ClassMenuItemAdderRowPointer - : ClassMenuItemAdder -{ - ClassMenuItemAdderRowPointer(PropertyRowPointer* row, QPropertyTree* tree) - : row_(row) - , tree_(tree) {} - void addAction(QMenu& menu, const char* text, int index) - { - CreatePointerMenuHandler* handler = new CreatePointerMenuHandler; - tree_->addMenuHandler(handler); - handler->row = row_; - handler->tree = tree_; - handler->index = index; - handler->useDefaultValue = !tree_->immediateUpdate(); - - QAction* action = menu.addAction(text); - - QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuCreateByIndex())); - } -protected: - PropertyRowPointer* row_; - QPropertyTree* tree_; -}; - - -bool PropertyRowPointer::onActivate(QPropertyTree* tree, [[maybe_unused]] bool force) -{ - if (userReadOnly()) - { - return false; - } - QMenu menu; - ClassMenuItemAdderRowPointer(this, tree).generateMenu(menu, tree->model()->typeStringList(baseType())); - tree->_setPressedRow(this); - menu.exec(tree->_toScreen(QPoint(widgetPos_, pos_.y() + tree->_defaultRowHeight()))); - tree->_setPressedRow(0); - return true; -} - -bool PropertyRowPointer::onMouseDown(QPropertyTree* tree, QPoint point, bool& changed) -{ - if (widgetRect(tree).contains(point)) - { - if (onActivate(tree, false)) - { - changed = true; - } - } - return false; -} - -bool PropertyRowPointer::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - if (!menu.isEmpty()) - { - menu.addSeparator(); - } - if (!userReadOnly()) - { - QMenu* createItem = menu.addMenu("Set"); - ClassMenuItemAdderRowPointer(this, tree).generateMenu(*createItem, tree->model()->typeStringList(baseType())); - } - return PropertyRow::onContextMenu(menu, tree); -} - -void PropertyRowPointer::serializeValue(IArchive& ar) -{ - ar(derivedTypeName_, "derivedTypeName", "Derived Type Name"); -} - -int PropertyRowPointer::widgetSizeMin(const QPropertyTree* tree) const -{ - QFontMetrics fm(tree->_boldFont()); - QString str(fromWideChar(generateLabel().c_str()).c_str()); - return fm.horizontalAdvance(str) + 24; -} - -static Color parseColorString(const char* str) -{ - unsigned int color = 0; - if (azsscanf(str, "%x", &color) != 1) - { - return Color(0, 0, 0, 0); - } - Color result((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, 255); - return result; -} - -void PropertyRowPointer::setValueAndContext(const Serialization::IPointer& ptr, [[maybe_unused]] Serialization::IArchive& ar) -{ - baseType_ = ptr.baseType(); - factory_ = ptr.factory(); - serializer_ = ptr.serializer(); - pointerType_ = ptr.pointerType(); - searchHandle_ = ptr.handle(); - - const char* colorString = factory_->findAnnotation(ptr.registeredTypeName(), "color"); - if (colorString[0] != '\0') - { - colorOverride_ = parseColorString(colorString); - } - else - { - colorOverride_ = Color(0, 0, 0, 0); - } - - const Serialization::TypeDescription* desc = factory_->descriptionByRegisteredName(ptr.registeredTypeName()); - if (desc) - { - derivedTypeName_ = desc->name(); - } - else - { - derivedTypeName_.clear(); - } -} - -#include -// vim:ts=4 sw=4: diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowPointer.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowPointer.h deleted file mode 100644 index aae8cb875a..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowPointer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWPOINTER_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWPOINTER_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "Color.h" -#include "Serialization/StringList.h" -using Serialization::StringList; - -#include "PropertyRow.h" -#endif - -class QPropertyTree; -class PropertyRowPointer; -struct CreatePointerMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - QPropertyTree * tree; - PropertyRowPointer* row; - int index; - bool useDefaultValue; -public slots: - void onMenuCreateByIndex(); -}; - -class QMenu; -struct ClassMenuItemAdder -{ - virtual void addAction(QMenu& menu, const char* text, int index); - virtual QMenu* addMenu(QMenu& menu, const char* text); - void generateMenu(QMenu& createItem, const StringList& comboStrings); -}; - -class PropertyRowPointer - : public PropertyRow -{ -public: - PropertyRowPointer(); - - bool assignTo(Serialization::IPointer& ptr); - void setValueAndContext(const Serialization::IPointer& ptr, Serialization::IArchive& ar); - using PropertyRow::assignTo; - using PropertyRow::setValueAndContext; - using PropertyRow::onActivate; - - Serialization::TypeID baseType() const{ return baseType_; } - void setBaseType(const Serialization::TypeID& baseType) { baseType_ = baseType; } - const char* derivedTypeName() const{ return derivedTypeName_.c_str(); } - void setDerivedType(const char* typeName, Serialization::IClassFactory* factory); - void setFactory(Serialization::IClassFactory* factory) { factory_ = factory; } - Serialization::IClassFactory* factory() const{ return factory_; } - bool onActivate(QPropertyTree* tree, bool force); - bool onMouseDown(QPropertyTree* tree, QPoint point, bool& changed); - bool onContextMenu(QMenu& root, QPropertyTree* tree); - bool isStatic() const{ return false; } - bool isPointer() const{ return true; } - int widgetSizeMin(const QPropertyTree* tree) const override; - wstring generateLabel() const; - string valueAsString() const; - const char* typeNameForFilter([[maybe_unused]] QPropertyTree* tree) const override { return baseType_.name(); } - void redraw(const PropertyDrawContext& context); - WidgetPlacement widgetPlacement() const{ return WIDGET_VALUE; } - void serializeValue(Serialization::IArchive& ar); - const void* searchHandle() const override { return searchHandle_; } - Serialization::TypeID typeId() const override { return pointerType_; } -protected: - - Serialization::TypeID baseType_; - string derivedTypeName_; - string derivedLabel_; - - // this member is available for instances deserialized from clipboard: - Serialization::IClassFactory* factory_; - const void* searchHandle_; - Serialization::TypeID pointerType_; - Color colorOverride_; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWPOINTER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFilePath.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFilePath.cpp deleted file mode 100644 index f766520662..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFilePath.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" - -#include - -#include "PropertyRowResourceFilePath.h" -#include "Serialization/ClassFactory.h" -#include -#include -#include -#include -#include -#include // for getting game folder. - -#include -#include -#include - -ResourceFilePathMenuHandler::ResourceFilePathMenuHandler(QPropertyTree* tree, PropertyRowResourceFilePath* self) - : self(self) - , tree(tree) -{ -} - - -void ResourceFilePathMenuHandler::onMenuClear() -{ - tree->model()->rowAboutToBeChanged(self); - self->clear(); - tree->model()->rowChanged(self); -} - -// Get filename relative to the asset folder, -// whether it came from the project or from a gem -QString AssetRelativePathFromAbsolutePath(const QString& absPath) -{ - return Path::FullPathToGamePath(absPath); -} - -bool PropertyRowResourceFilePath::onActivate(const PropertyActivationEvent& e) -{ - using namespace AzToolsFramework::AssetBrowser; - - if (e.reason == e.REASON_RELEASE) - { - return false; - } - - AssetSelectionModel selection; - if (m_group) - { - selection = AssetSelectionModel::AssetGroupSelection(filter_); - } - else - { - selection = AssetSelectionModel::AssetTypeSelection(filter_); - } - - AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection); - if (!selection.IsValid()) - { - return true; - } - - auto product = azrtti_cast(selection.GetResult()); - if (!product) - { - return true; - } - - AZStd::string relativeFilename = product->GetRelativePath(); - - if (flags_ & ResourceFilePath::STRIP_EXTENSION) - { - size_t ext = relativeFilename.rfind('.'); - if (ext != relativeFilename.npos) - { - relativeFilename.erase(ext, relativeFilename.length() - ext); - } - } - - e.tree->model()->rowAboutToBeChanged(this); - path_ = relativeFilename.c_str(); - e.tree->model()->rowChanged(this); - return true; -} -void PropertyRowResourceFilePath::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) -{ - ResourceFilePath* value = (ResourceFilePath*)ser.pointer(); - filter_ = value->filter.c_str(); - path_ = value->m_path->c_str(); - flags_ = value->flags; - handle_ = value->m_path; - m_group = value->group; -} - -bool PropertyRowResourceFilePath::assignTo(const Serialization::SStruct& ser) const -{ - ((ResourceFilePath*)ser.pointer())->SetPath(path_.c_str()); - return true; -} - -void PropertyRowResourceFilePath::serializeValue(Serialization::IArchive& ar) -{ - ar(filter_, "filter"); - ar(path_, "path"); - ar(startFolder_, "startFolder"); - ar(m_group, "group"); -} - -const QIcon& PropertyRowResourceFilePath::buttonIcon(const QPropertyTree* tree, [[maybe_unused]] int index) const -{ - #include "file_open.xpm" - static QIcon fileOpenIcon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_open_xpm)))); - return fileOpenIcon; -} - -string PropertyRowResourceFilePath::valueAsString() const -{ - return path_; -} - - -void PropertyRowResourceFilePath::clear() -{ - path_.clear(); -} - -bool PropertyRowResourceFilePath::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - QAction* action = menu.addAction("Clear"); - Serialization::SharedPtr selfPointer(this); - - ResourceFilePathMenuHandler* handler = new ResourceFilePathMenuHandler(tree, this); - QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuClear())); - tree->addMenuHandler(handler); - return true; -} - -bool PropertyRowResourceFilePath::processesKey(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - return true; - } - - return PropertyRowField::processesKey(tree, ev); -} - -bool PropertyRowResourceFilePath::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - tree->model()->rowAboutToBeChanged(this); - clear(); - tree->model()->rowChanged(this); - return true; - } - return PropertyRowField::onKeyDown(tree, ev); -} - -REGISTER_PROPERTY_ROW(ResourceFilePath, PropertyRowResourceFilePath); -DECLARE_SEGMENT(PropertyRowResourceFilePath) - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFilePath.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFilePath.h deleted file mode 100644 index 9a564a7bd9..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFilePath.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFILEPATH_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFILEPATH_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyDrawContext.h" -#include "PropertyRowField.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Serialization.h" -#include -#include -#include -#endif - -using Serialization::ResourceFilePath; - -class PropertyRowResourceFilePath - : public PropertyRowField -{ -public: - void clear(); - - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - bool assignTo(const Serialization::SStruct& ser) const override; - bool onActivate(const PropertyActivationEvent& e) override; - - int buttonCount() const override { return 1; } - virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override; - virtual bool usePathEllipsis() const override { return true; } - string valueAsString() const; - void serializeValue(Serialization::IArchive& ar); - const void* searchHandle() const override { return handle_; } - Serialization::TypeID typeId() const override { return Serialization::TypeID::get(); } - - bool onContextMenu(QMenu& menu, QPropertyTree* tree); - - bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; - -private: - string filter_; - string path_; - string startFolder_; - bool m_group; - int flags_; - const void* handle_; -}; - -struct ResourceFilePathMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - QPropertyTree * tree; - PropertyRowResourceFilePath* self; - - ResourceFilePathMenuHandler(QPropertyTree* tree, PropertyRowResourceFilePath* container); -public slots: - void onMenuClear(); -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFILEPATH_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFolderPath.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFolderPath.cpp deleted file mode 100644 index c67f9e4bc3..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFolderPath.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include -#include "PropertyRowResourceFolderPath.h" -#include "Serialization/ClassFactory.h" -#include -#include -#include -#include - -ResourceFolderPathMenuHandler::ResourceFolderPathMenuHandler(QPropertyTree* tree, PropertyRowResourceFolderPath* self) - : self(self) - , tree(tree) -{ -} - -void ResourceFolderPathMenuHandler::onMenuClear() -{ - tree->model()->rowAboutToBeChanged(self); - self->clear(); - tree->model()->rowChanged(self); -} - -bool PropertyRowResourceFolderPath::onActivate(const PropertyActivationEvent& e) -{ - if (e.reason == e.REASON_RELEASE) - { - return false; - } - if (!GetIEditor()) - { - return true; - } - - if (userReadOnly()) - { - return false; - } - - QString title; - if (labelUndecorated() && labelUndecorated()[0] != '\0') - { - title = QString("Choose folder for '") + QString::fromLocal8Bit(labelUndecorated()) + "'"; - } - else - { - title = "Choose folder"; - } - - QString gameFolder = QString::fromLocal8Bit(Path::GetEditingGameDataFolder().c_str()); - QString startFolder = gameFolder + QDir::separator(); - - if (path_.empty() || !QDir().exists(startFolder)) - { - startFolder += QString::fromLocal8Bit(startFolder_.c_str()); - } - else - { - startFolder += QString::fromLocal8Bit(path_.c_str()); - } - - QString filename = QFileDialog::getExistingDirectory(e.tree, title, startFolder, QFileDialog::ShowDirsOnly); - if (filename.isEmpty()) - { - return true; - } - - e.tree->model()->rowAboutToBeChanged(this); - QString result = QDir(gameFolder).relativeFilePath(filename); - path_ = result.toLocal8Bit().data(); - e.tree->model()->rowChanged(this); - return true; -} -void PropertyRowResourceFolderPath::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) -{ - ResourceFolderPath* value = (ResourceFolderPath*)(ser.pointer()); - path_ = value->m_path->c_str(); - startFolder_ = value->startFolder.c_str(); - handle_ = value->m_path; -} - -bool PropertyRowResourceFolderPath::assignTo(const Serialization::SStruct& ser) const -{ - ((ResourceFolderPath*)ser.pointer())->SetPath(path_.c_str()); - return true; -} - -const QIcon& PropertyRowResourceFolderPath::buttonIcon(const QPropertyTree* tree, [[maybe_unused]] int index) const -{ - #include "file_open.xpm" - static QIcon fileOpenIcon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_open_xpm)))); - return fileOpenIcon; -} - -string PropertyRowResourceFolderPath::valueAsString() const -{ - return path_; -} - -void PropertyRowResourceFolderPath::clear() -{ - path_.clear(); -} - -void PropertyRowResourceFolderPath::serializeValue(Serialization::IArchive& ar) -{ - ar(path_, "path"); - ar(startFolder_, "startFolder"); -} - -bool PropertyRowResourceFolderPath::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - ResourceFolderPathMenuHandler* handler = new ResourceFolderPathMenuHandler(tree, this); - QAction* action = menu.addAction("Clear", handler, SLOT(onMenuClear())); - action->setEnabled(!userReadOnly()); - SharedPtr selfPointer(this); - - tree->addMenuHandler(handler); - return true; -} - -bool PropertyRowResourceFolderPath::processesKey(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - return true; - } - - return PropertyRowField::processesKey(tree, ev); -} - -bool PropertyRowResourceFolderPath::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - tree->model()->rowAboutToBeChanged(this); - clear(); - tree->model()->rowChanged(this); - return true; - } - return PropertyRowField::onKeyDown(tree, ev); -} - -REGISTER_PROPERTY_ROW(ResourceFolderPath, PropertyRowResourceFolderPath); -DECLARE_SEGMENT(PropertyRowResourceFolderPath) - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFolderPath.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFolderPath.h deleted file mode 100644 index ed58c148e7..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceFolderPath.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFOLDERPATH_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFOLDERPATH_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyDrawContext.h" -#include "PropertyRowImpl.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Serialization.h" -#include -#include -#include -#include -#endif - -using Serialization::ResourceFolderPath; - -class PropertyRowResourceFolderPath - : public PropertyRowField -{ -public: - PropertyRowResourceFolderPath() - : handle_() {} - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - bool onActivate(const PropertyActivationEvent& e) override; - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - bool assignTo(const Serialization::SStruct& ser) const override; - string valueAsString() const; - bool onContextMenu(QMenu& menu, QPropertyTree* tree); - - int buttonCount() const override { return 1; } - virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override; - virtual bool usePathEllipsis() const override { return true; } - void serializeValue(Serialization::IArchive& ar) override; - const void* searchHandle() const override { return handle_; } - Serialization::TypeID typeId() const override { return Serialization::TypeID::get(); } - void clear(); - - bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; - -private: - string path_; - string startFolder_; - const void* handle_; -}; - -struct ResourceFolderPathMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - QPropertyTree * tree; - PropertyRowResourceFolderPath* self; - - ResourceFolderPathMenuHandler(QPropertyTree* tree, PropertyRowResourceFolderPath* container); -public slots: - void onMenuClear(); -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFOLDERPATH_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceSelector.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceSelector.cpp deleted file mode 100644 index 942691df04..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceSelector.cpp +++ /dev/null @@ -1,425 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowResourceSelector.h" -#include "Serialization/ClassFactory.h" -#include "Serialization/Decorators/Resources.h" -#include "Serialization/Decorators/INavigationProvider.h" -#include "Serialization/Decorators/IconXPM.h" -#include -#include "IEditor.h" -#include -#include -#include -#include -#include - -enum Button -{ - BUTTON_PICK, - BUTTON_CREATE -}; - -ResourceSelectorMenuHandler::ResourceSelectorMenuHandler(QPropertyTree* tree, PropertyRowResourceSelector* self) - : self(self) - , tree(tree) -{ -} - - -void ResourceSelectorMenuHandler::onMenuClear() -{ - tree->model()->rowAboutToBeChanged(self); - self->clear(); - tree->model()->rowChanged(self); -} - -void ResourceSelectorMenuHandler::onMenuPickResource() -{ - self->pickResource(tree); -} - -void ResourceSelectorMenuHandler::onMenuCreateFile() -{ - self->createFile(tree); -} - -void ResourceSelectorMenuHandler::onMenuJumpTo() -{ - self->jumpTo(tree); -} - -bool PropertyRowResourceSelector::onActivate(const PropertyActivationEvent& e) -{ - if (PropertyRowField::onActivate(e)) - { - return true; - } - - bool canSelect = !userReadOnly() && !multiValue() && provider_ && provider_->CanSelect(type_.c_str(), value_.c_str(), id_); - - if (!userReadOnly() && e.reason == e.REASON_DOUBLECLICK && provider_ && provider_->CanPickFile(type_.c_str(), id_)) - { - return pickResource(e.tree); - } - - if (canSelect) - { - jumpTo(e.tree); - return true; - } - else if (!userReadOnly()) - { - if (!provider_ && !userReadOnly()) - { - pickResource(e.tree); - } - } - return false; -} - -int PropertyRowResourceSelector::buttonCount() const -{ - if (!provider_) - { - return 1; - } - - int result = 0; - if (provider_->CanPickFile(type_.c_str(), id_)) - { - result = 1; - if (!multiValue() && value_.empty() && provider_->CanCreate(type_.c_str(), id_)) - { - result = 2; - } - } - return result; -} - -bool PropertyRowResourceSelector::onActivateButton(int button, const PropertyActivationEvent& e) -{ - if (userReadOnly()) - { - return false; - } - if (button == BUTTON_PICK) - { - return pickResource(e.tree); - } - else if (button == BUTTON_CREATE) - { - return createFile(e.tree); - } - return true; -} - -bool PropertyRowResourceSelector::getHoverInfo(PropertyHoverInfo* hover, const QPoint& cursorPos, const QPropertyTree* tree) const -{ - if (fieldRect(tree).contains(cursorPos) && provider_ && provider_->CanSelect(type_.c_str(), value_.c_str(), id_) && !provider_->IsSelected(type_.c_str(), value_.c_str(), id_)) - { - hover->cursor = QCursor(Qt::PointingHandCursor); - } - else - { - hover->cursor = QCursor(); - } - hover->toolTip = QString::fromLocal8Bit(value_.c_str()); - return true; -} - -void PropertyRowResourceSelector::jumpTo([[maybe_unused]] QPropertyTree* tree) -{ - if (multiValue()) - { - return; - } - if (provider_) - { - provider_->Select(type_.c_str(), value_.c_str(), id_); - } - return; -} - -bool PropertyRowResourceSelector::pickResource(QPropertyTree* tree) -{ - if (!GetIEditor()) - { - return false; - } - - context_.typeName = type_.c_str(); - context_.parentWidget = tree; - QString filename = GetIEditor()->GetResourceSelectorHost()->SelectResource(context_, value_.c_str()); - - tree->model()->rowAboutToBeChanged(this); - value_ = filename.toUtf8().constData(); - tree->model()->rowChanged(this); - - return true; -} - -QString convertMFCToQtFileFilter(QString* defaultSuffix, const char* mfcFilter); - -bool PropertyRowResourceSelector::createFile(QPropertyTree* tree) -{ - if (!provider_) - { - return false; - } - - QString title; - if (labelUndecorated()) - { - title = QString("Create file for '") + labelUndecorated() + "'"; - } - else - { - title = "Choose file"; - } - - string originalFilter; - originalFilter = provider_->GetFileSelectorMaskForType(type_.c_str()); - - QString gameFolder = QString::fromLocal8Bit(Path::GetEditingGameDataFolder().c_str()); - QDir gameFolderDir(QDir::fromNativeSeparators(gameFolder)); - QString defaultSuffix; - QString filter = convertMFCToQtFileFilter(&defaultSuffix, originalFilter.c_str()); - QString existingFile = QString::fromLocal8Bit(PathUtil::ReplaceExtension(defaultPath_.empty() ? value_.c_str() : defaultPath_.c_str(), defaultSuffix.toLocal8Bit().data())); - - QString existingFilePath = (existingFile.isEmpty() || QDir::isAbsolutePath(existingFile)) ? existingFile : gameFolderDir.absoluteFilePath(existingFile); - - // Not using QFileDialog().exec() as it implements custom file dialog that - // freezes for couple of seconds when being open. Scannign network drives? - QString result = QFileDialog::getSaveFileName(tree, title, existingFilePath.isEmpty() ? (gameFolder + "/") : existingFilePath, filter); - if (!result.isEmpty()) - { - QString relativeFilename = gameFolderDir.relativeFilePath(result); - - if (provider_->Create(type_.c_str(), relativeFilename.toLocal8Bit().data(), id_)) - { - tree->model()->rowAboutToBeChanged(this); - value_ = relativeFilename.toLocal8Bit().data(); - tree->model()->rowChanged(this); - } - } - return true; -} - -void PropertyRowResourceSelector::setValueAndContext(const Serialization::SStruct& ser, IArchive& ar) -{ - IResourceSelector* value = (IResourceSelector*)ser.pointer(); - if (type_ != value->resourceType) - { - type_ = value->resourceType; - const char* resourceIconPath = GetIEditor()->GetResourceSelectorHost()->ResourceIconPath(type_.c_str()); - icon_ = resourceIconPath[0] ? QIcon(QString::fromLocal8Bit(resourceIconPath)) : QIcon(); - } - value_ = value->GetValue(); - id_ = value->GetId(); - searchHandle_ = value->GetHandle(); - wrappedType_ = value->GetType(); - - provider_ = ar.FindContext(); - if (!provider_ || !provider_->IsRegistered(type_)) - { - provider_ = 0; - } - - Serialization::TypeID contextObjectType = GetIEditor()->GetResourceSelectorHost()->ResourceContextType(type_.c_str()); - if (contextObjectType != Serialization::TypeID()) - { - context_.contextObject = ar.FindContextByType(contextObjectType); - context_.contextObjectType = contextObjectType; - } - - if (Serialization::SNavigationContext* navigationContext = ar.FindContext()) - { - defaultPath_ = navigationContext->path.c_str(); - } - else - { - defaultPath_.clear(); - } -} - -bool PropertyRowResourceSelector::assignTo(const Serialization::SStruct& ser) const -{ - ((IResourceSelector*)ser.pointer())->SetValue(value_.c_str()); - return true; -} - -void PropertyRowResourceSelector::serializeValue(Serialization::IArchive& ar) -{ - ar(type_, "type"); - ar(value_, "value"); - ar(id_, "index"); - - if (ar.IsInput()) - { - const char* resourceIconPath = GetIEditor()->GetResourceSelectorHost()->ResourceIconPath(type_.c_str()); - icon_ = resourceIconPath[0] ? QIcon(QString::fromLocal8Bit(resourceIconPath)) : QIcon(); - } -} - -const QIcon& PropertyRowResourceSelector::buttonIcon(const QPropertyTree* tree, int index) const -{ - switch (index) - { - case BUTTON_PICK: - { - if (provider_ != 0 || icon_.isNull()) - { - #include "file_open.xpm" - static QIcon defaultIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_open_xpm)))); - return defaultIcon; - } - else - { - return icon_; - } - } - case BUTTON_CREATE: - { - static QIcon addIcon("Icons/animation/add.png"); - ; - return addIcon; - } - default: - { - static QIcon defaultIcon; - return defaultIcon; - } - } -} - -string PropertyRowResourceSelector::valueAsString() const -{ - return value_; -} - -void PropertyRowResourceSelector::clear() -{ - value_.clear(); -} - -bool PropertyRowResourceSelector::onContextMenu(QMenu& menu, QPropertyTree* tree) -{ - Serialization::SharedPtr selfPointer(this); - - ResourceSelectorMenuHandler* handler = new ResourceSelectorMenuHandler(tree, this); - if (!multiValue() && provider_ && provider_->CanSelect(type_.c_str(), value_.c_str(), id_)) - { - QAction* jumpToAction = menu.addAction("Jump to", handler, SLOT(onMenuJumpTo())); - menu.setDefaultAction(jumpToAction); - } - if (!userReadOnly()) - { - if (!provider_ || provider_->CanPickFile(type_.c_str(), id_)) - { - menu.addAction(buttonIcon(tree, 0), "Pick Resource...", handler, SLOT(onMenuPickResource()))->setEnabled(!userReadOnly()); - } - if (provider_ && provider_->CanCreate(type_.c_str(), id_)) - { - menu.addAction(buttonIcon(tree, 1), "Create...", handler, SLOT(onMenuCreateFile())); - } - menu.addAction("Clear", handler, SLOT(onMenuClear()))->setEnabled(!userReadOnly()); - } - tree->addMenuHandler(handler); - - PropertyRow::onContextMenu(menu, tree); - return true; -} - -static const wchar_t* getFilenameFromPath(const wchar_t* path) -{ - const wchar_t* lastSep = wcsrchr(path, L'/'); - if (!lastSep) - { - return path; - } - return lastSep + 1; -} - -void PropertyRowResourceSelector::redraw(const PropertyDrawContext& context) -{ - ////! TOFIX: THIS CODE IS DUPLICATED IN PropertyRowField.cpp: PropertyRowField::redraw()!!! - // - int buttonCount = this->buttonCount(); - int offset = 0; - for (int i = 0; i < buttonCount; ++i) - { - const QIcon& icon = buttonIcon(context.tree, i); - int width = 16; - QRect iconRect(context.widgetRect.right() - offset - width, context.widgetRect.top(), width, context.widgetRect.height()); - icon.paint(context.painter, iconRect, Qt::AlignCenter, userReadOnly() ? QIcon::Disabled : QIcon::Normal); - offset += width; - } - - int iconSpace = offset ? offset + 2 : 0; - // - //// - - QRect rect = context.widgetRect; - rect.setRight(rect.right() - iconSpace); - bool pressed = context.m_pressed || (provider_ ? provider_->IsSelected(type_.c_str(), value_.c_str(), id_) : false); - bool active = !provider_ || provider_->IsActive(type_.c_str(), value_.c_str(), id_); - bool modified = provider_ && provider_->IsModified(type_.c_str(), value_.c_str(), id_); - QIcon icon = icon_; - if (provider_) - { - icon = QIcon(provider_->GetIcon(type_.c_str(), value_.c_str())); - } - bool canSelect = !multiValue() && provider_ && provider_->CanSelect(type_.c_str(), value_.c_str(), id_); - - wstring text = multiValue() ? L"..." : wstring(modified ? L"*" : L"") + getFilenameFromPath(valueAsWString()); - if (provider_) - { - if (canSelect || !text.empty()) - { - context.drawButtonWithIcon(icon, rect, text.c_str(), selected(), pressed, selected(), !userReadOnly(), canSelect, active ? &context.tree->_boldFont() : &context.tree->font()); - } - } - else - { - context.drawEntry(text.c_str(), true, false, iconSpace); - } -} - -bool PropertyRowResourceSelector::processesKey(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - return true; - } - - return PropertyRowField::processesKey(tree, ev); -} - -bool PropertyRowResourceSelector::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - tree->model()->rowAboutToBeChanged(this); - clear(); - tree->model()->rowChanged(this); - return true; - } - return PropertyRowField::onKeyDown(tree, ev); -} - -REGISTER_PROPERTY_ROW(IResourceSelector, PropertyRowResourceSelector); -DECLARE_SEGMENT(PropertyRowResourceSelector) - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceSelector.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceSelector.h deleted file mode 100644 index 0a614cfaed..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowResourceSelector.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCESELECTOR_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCESELECTOR_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyDrawContext.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "PropertyRowField.h" -#include -#include "Serialization/Decorators/Resources.h" -#include "IResourceSelectorHost.h" -#include -#endif - -using Serialization::IResourceSelector; -namespace Serialization { - struct INavigationProvider; -} - -class PropertyRowResourceSelector - : public PropertyRowField -{ -public: - PropertyRowResourceSelector() - : provider_(0) - , id_(0) - , searchHandle_(0) {} - void clear(); - - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - - void jumpTo(QPropertyTree* tree); - bool createFile(QPropertyTree* tree); - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - bool assignTo(const Serialization::SStruct& ser) const override; - bool onActivate(const PropertyActivationEvent& ev) override; - bool onActivateButton(int button, const PropertyActivationEvent& e) override; - bool getHoverInfo(PropertyHoverInfo* hover, const QPoint& cursorPos, const QPropertyTree* tree) const override; - const void* searchHandle() const override { return searchHandle_; } - Serialization::TypeID typeId() const override { return wrappedType_; } - - int buttonCount() const override; - virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override; - virtual bool usePathEllipsis() const override { return true; } - string valueAsString() const; - void serializeValue(Serialization::IArchive& ar); - void redraw(const PropertyDrawContext& context); - - bool onContextMenu(QMenu& menu, QPropertyTree* tree); - bool pickResource(QPropertyTree* tree); - const char* typeNameForFilter([[maybe_unused]] QPropertyTree* tree) const override { return !type_.empty() ? type_.c_str() : "ResourceSelector"; } - - bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; - -private: - SResourceSelectorContext context_; - Serialization::INavigationProvider* provider_; - const void* searchHandle_; - Serialization::TypeID wrappedType_; - QIcon icon_; - - string type_; - string value_; - string defaultPath_; - int id_; -}; - -struct ResourceSelectorMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - QPropertyTree * tree; - PropertyRowResourceSelector* self; - - ResourceSelectorMenuHandler(QPropertyTree* tree, PropertyRowResourceSelector* container); -public slots: - void onMenuCreateFile(); - void onMenuJumpTo(); - void onMenuClear(); - void onMenuPickResource(); -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCESELECTOR_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSlider.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSlider.cpp deleted file mode 100644 index 6ac69973e0..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSlider.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "Serialization/ClassFactory.h" -#include "PropertyTreeModel.h" -#include "PropertyRowNumber.h" -#include "MathUtils.h" - -#include -#include -#include -#include -#include "QPropertyTree.h" -#include "PropertyRow.h" -#include "PropertyDrawContext.h" - -#include "Serialization.h" -#include "Serialization/Decorators/Slider.h" -#include "Serialization/Decorators/SliderImpl.h" -#include - -using Serialization::SSliderF; -using Serialization::SSliderI; - -class PropertyRowSliderF - : public PropertyRowNumberField -{ -public: - static const bool Custom = true; - PropertyRowSliderF(); - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - int floorHeight() const override { return 18; } - void redraw(const PropertyDrawContext& context) override; - - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onMouseDown(QPropertyTree* tree, QPoint point, bool& changed) override; - void onMouseDrag(const PropertyDragEvent& e) override; - void onMouseUp(QPropertyTree* tree, QPoint point) override; - bool assignTo(const Serialization::SStruct& ser) const override - { - if (ser.size() != sizeof(SSliderF)) - { - return false; - } - SSliderF* slider = (SSliderF*)(ser.pointer()); - *slider->valuePointer = clamp(localValue_, slider->minLimit, slider->maxLimit); - return true; - } - bool handleMouse(QPropertyTree* tree, QPoint point); - - bool setValueFromString(const char* str) override - { - float newValue = aznumeric_cast(atof(str)); - if (localValue_ != newValue) - { - localValue_ = newValue; - return true; - } - else - { - return false; - } - } - - string valueAsString() const override - { - return numberAsString(localValue_); - } - - void startIncrement() override - { - incrementStartValue_ = localValue_; - } - - void endIncrement(QPropertyTree* tree) override - { - if (localValue_ != incrementStartValue_) - { - float localValue = localValue_; - localValue_ = incrementStartValue_; - tree->model()->rowAboutToBeChanged(this); - localValue_ = localValue; - tree->model()->rowChanged(this); - } - } - - void incrementLog(float screenFraction, [[maybe_unused]] float valueFieldFraction) - { - double startPower = log10(fabs(double(incrementStartValue_) + 1.0)) - 3.0; - double power = startPower + fabs(screenFraction) * 10.0f; - double delta = powf(10.0f, aznumeric_cast(power)) - powf(10.0f, aznumeric_cast(startPower)) + 10.0f * fabsf(screenFraction); - double newValue; - if (screenFraction > 0.0f) - { - newValue = double(incrementStartValue_) + delta; - } - else - { - newValue = double(incrementStartValue_) - delta; - } - if (_isnan(newValue)) - { - if (screenFraction > 0.0f) - { - newValue = DBL_MAX; - } - else - { - newValue = -DBL_MAX; - } - } - clampToType(&localValue_, newValue); - } - - void serializeValue(Serialization::IArchive& ar) - { - ar(value_.minLimit, "min"); - ar(value_.maxLimit, "max"); - ar(localValue_, "value"); - } - - double sliderPosition() const override { return 0.0; } - - SSliderF value_; - float localValue_; - float incrementStartValue_; - bool captured_; -}; - -bool PropertyRowSliderF::handleMouse(QPropertyTree* tree, QPoint point) -{ - QStyleOptionSlider slider; - slider.rect = floorRect(tree); - QSlider widgetForContext; - QRect sliderGroove = tree->style()->subControlRect(QStyle::CC_Slider, &slider, QStyle::SC_SliderGroove, &widgetForContext); - QRect sliderHandle = tree->style()->subControlRect(QStyle::CC_Slider, &slider, QStyle::SC_SliderHandle, &widgetForContext); - - int sliderLength = sliderGroove.width() - sliderHandle.width(); - - float valRelative = float(point.x() - (sliderGroove.left() + sliderHandle.width() / 2)) / sliderLength; - if (valRelative < 0.0f) - { - valRelative = 0.0f; - } - if (valRelative > 1.0f) - { - valRelative = 1.0f; - } - float newValue = float(valRelative * (value_.maxLimit - value_.minLimit) + value_.minLimit); - if (newValue != localValue_) - { - localValue_ = newValue; - setMultiValue(false); - return true; - } - else - { - return false; - } -} - -bool PropertyRowSliderF::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - float step = (value_.maxLimit - value_.minLimit) * 0.01f; - if (ev->key() == Qt::Key_Left) - { - tree->model()->rowAboutToBeChanged(this); - localValue_ = clamp(localValue_ - step, value_.minLimit, value_.maxLimit); - tree->model()->rowChanged(this); - return true; - } - if (ev->key() == Qt::Key_Right) - { - tree->model()->rowAboutToBeChanged(this); - localValue_ = clamp(localValue_ + step, value_.minLimit, value_.maxLimit); - tree->model()->rowChanged(this); - return true; - } - return PropertyRowNumberField::onKeyDown(tree, ev); -} - -bool PropertyRowSliderF::onMouseDown(QPropertyTree* tree, QPoint point, [[maybe_unused]] bool& changed) -{ - if (floorRect(tree).contains(point) && !userReadOnly()) - { - tree->model()->rowAboutToBeChanged(this); - if (handleMouse(tree, point)) - { - tree->update(); - } - captured_ = true; - return true; - } - captured_ = false; - return true; -} - -void PropertyRowSliderF::onMouseDrag(const PropertyDragEvent& e) -{ - if (!captured_) - { - return; - } - if (userReadOnly()) - { - return; - } - if (handleMouse(e.tree, e.pos)) - { - e.tree->update(); - } -} - -void PropertyRowSliderF::onMouseUp(QPropertyTree* tree, QPoint point) -{ - if (!captured_) - { - return; - } - handleMouse(tree, point); - tree->model()->rowChanged(this); -} - -void PropertyRowSliderF::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) -{ - value_ = *(SSliderF*)ser.pointer(); - localValue_ = *value_.valuePointer; - value_.valuePointer = 0; -} - -static void drawSlider(const PropertyDrawContext& context, float relativeVal, bool userReadOnly, bool selected) -{ - // Eliminate x-shift offset in the control rect as it triggers a bug in - // Fusion theme, that causes blue area in the slider groove to stand out to - // the right from slider. - int xOffset = context.lineRect.left(); - context.painter->translate(xOffset, 0); - - QStyleOptionSlider sliderOptions; - sliderOptions.rect = context.lineRect.translated(-xOffset, 0); - sliderOptions.minimum = 0; - QSlider widgetForContext; - QRect sliderGroove = context.tree->style()->subControlRect(QStyle::CC_Slider, &sliderOptions, QStyle::SC_SliderGroove, &widgetForContext); - QRect sliderHandle = context.tree->style()->subControlRect(QStyle::CC_Slider, &sliderOptions, QStyle::SC_SliderHandle, &widgetForContext); - int width = sliderGroove.width() - sliderHandle.width() + 1; - sliderOptions.maximum = width; - sliderOptions.pageStep = width / 100; - sliderOptions.sliderPosition = aznumeric_cast(width * relativeVal); - sliderOptions.state = !userReadOnly ? (QStyle::State_Enabled | (selected ? QStyle::State_HasFocus : QStyle::State())) : QStyle::State(); - - context.tree->style()->drawComplexControl(QStyle::CC_Slider, &sliderOptions, context.painter, &widgetForContext); - - context.painter->translate(-xOffset, 0); -} - -void PropertyRowSliderF::redraw(const PropertyDrawContext& context) -{ - PropertyRowNumberField::redraw(context); - float val = localValue_; - float valRange = value_.maxLimit - value_.minLimit; - if (valRange == 0.0f) - { - valRange = 0.00001f; - } - float relativeVal = clamp((val - value_.minLimit) / valRange, 0.0f, 1.0f); - - drawSlider(context, relativeVal, userReadOnly(), selected()); -} - -PropertyRowSliderF::PropertyRowSliderF() - : captured_(false) - , localValue_() - , incrementStartValue_() -{ -} - -DECLARE_SEGMENT(PropertyRowSliderF) -REGISTER_PROPERTY_ROW(SSliderF, PropertyRowSliderF) - -// --------------------------------------------------------------------------- - -class PropertyRowSliderI - : public PropertyRowNumberField -{ -public: - static const bool Custom = true; - PropertyRowSliderI(); - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - int floorHeight() const override { return 18; } - void redraw(const PropertyDrawContext& context) override; - - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onMouseDown(QPropertyTree* tree, QPoint point, bool& changed) override; - void onMouseDrag(const PropertyDragEvent& e) override; - void onMouseUp(QPropertyTree* tree, QPoint point) override; - bool assignTo(const Serialization::SStruct& ser) const override - { - if (ser.size() != sizeof(SSliderI)) - { - return false; - } - SSliderI* slider = (SSliderI*)(ser.pointer()); - *slider->valuePointer = clamp(localValue_, slider->minLimit, slider->maxLimit); - return true; - } - bool handleMouse(QPropertyTree* tree, QPoint point); - - bool setValueFromString(const char* str) override - { - int newValue = atoi(str); - if (localValue_ != newValue) - { - localValue_ = newValue; - return true; - } - else - { - return false; - } - } - Serialization::string valueAsString() const override - { - return numberAsString(localValue_); - } - - void startIncrement() override - { - incrementStartValue_ = localValue_; - } - - void endIncrement(QPropertyTree* tree) override - { - if (localValue_ != incrementStartValue_) - { - int localValue = localValue_; - localValue_ = incrementStartValue_; - tree->model()->rowAboutToBeChanged(this); - localValue_ = localValue; - tree->model()->rowChanged(this); - } - } - - void incrementLog(float screenFraction, [[maybe_unused]] float valueFieldFraction) - { - double startPower = log10(fabs(double(incrementStartValue_) + 1.0)) - 3.0; - double power = startPower + fabs(screenFraction) * 10.0f; - double delta = powf(10.0f, aznumeric_cast(power)) - powf(10.0f, aznumeric_cast(startPower)) + 1000.0f * fabsf(screenFraction); - double newValue; - if (screenFraction > 0.0f) - { - newValue = double(incrementStartValue_) + delta; - } - else - { - newValue = double(incrementStartValue_) - delta; - } - if (_isnan(newValue)) - { - if (screenFraction > 0.0f) - { - newValue = DBL_MAX; - } - else - { - newValue = -DBL_MAX; - } - } - clampToType(&localValue_, newValue); - } - - void serializeValue(Serialization::IArchive& ar) - { - ar(value_.minLimit, "min"); - ar(value_.maxLimit, "max"); - ar(localValue_, "value"); - } - - double sliderPosition() const override { return 0.0; } - - SSliderI value_; - int localValue_; - int incrementStartValue_; - bool captured_; -}; - -bool PropertyRowSliderI::handleMouse(QPropertyTree* tree, QPoint point) -{ - QStyleOptionSlider slider; - slider.rect = floorRect(tree); - - QSlider widgetForContext; - QRect sliderGroove = tree->style()->subControlRect(QStyle::CC_Slider, &slider, QStyle::SC_SliderGroove, &widgetForContext); - QRect sliderHandle = tree->style()->subControlRect(QStyle::CC_Slider, &slider, QStyle::SC_SliderHandle, &widgetForContext); - - int sliderLength = sliderGroove.width() - sliderHandle.width(); - - float valRelative = float(point.x() - (sliderGroove.left() + sliderHandle.width() / 2)) / sliderLength; - if (valRelative < 0.0f) - { - valRelative = 0.0f; - } - if (valRelative > 1.0f) - { - valRelative = 1.0f; - } - int newValue = int(valRelative * (value_.maxLimit - value_.minLimit) + value_.minLimit); - if (newValue != localValue_) - { - localValue_ = newValue; - setMultiValue(false); - return true; - } - else - { - return false; - } -} - -bool PropertyRowSliderI::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - int step = aznumeric_cast((value_.maxLimit - value_.minLimit) * 0.01f); - if (ev->key() == Qt::Key_Left) - { - tree->model()->rowAboutToBeChanged(this); - localValue_ = clamp(localValue_ - step, value_.minLimit, value_.maxLimit); - tree->model()->rowChanged(this); - return true; - } - if (ev->key() == Qt::Key_Right) - { - tree->model()->rowAboutToBeChanged(this); - localValue_ = clamp(localValue_ + step, value_.minLimit, value_.maxLimit); - tree->model()->rowChanged(this); - return true; - } - return PropertyRowNumberField::onKeyDown(tree, ev); -} - -bool PropertyRowSliderI::onMouseDown(QPropertyTree* tree, QPoint point, [[maybe_unused]] bool& changed) -{ - if (floorRect(tree).contains(point) && !userReadOnly()) - { - tree->model()->rowAboutToBeChanged(this); - if (handleMouse(tree, point)) - { - tree->update(); - } - captured_ = true; - return true; - } - captured_ = false; - return true; -} - -void PropertyRowSliderI::onMouseDrag(const PropertyDragEvent& e) -{ - if (!captured_) - { - return; - } - if (userReadOnly()) - { - return; - } - if (handleMouse(e.tree, e.pos)) - { - e.tree->update(); - } -} - -void PropertyRowSliderI::onMouseUp(QPropertyTree* tree, QPoint point) -{ - if (!captured_) - { - return; - } - handleMouse(tree, point); - tree->model()->rowChanged(this); -} - -void PropertyRowSliderI::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) -{ - value_ = *(SSliderI*)ser.pointer(); - localValue_ = *value_.valuePointer; - value_.valuePointer = 0; -} - -void PropertyRowSliderI::redraw(const PropertyDrawContext& context) -{ - PropertyRowNumberField::redraw(context); - int val = localValue_; - int valRange = value_.maxLimit - value_.minLimit; - if (valRange == 0) - { - valRange = 1; - } - float relativeVal = clamp(float(val - value_.minLimit) / valRange, 0.0f, 1.0f); - - drawSlider(context, relativeVal, userReadOnly(), selected()); -} - -PropertyRowSliderI::PropertyRowSliderI() - : captured_(false) - , localValue_() - , incrementStartValue_() -{ -} - -DECLARE_SEGMENT(PropertyRowSliderI) -REGISTER_PROPERTY_ROW(SSliderI, PropertyRowSliderI) diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSprite.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSprite.cpp deleted file mode 100644 index 3a0afc103c..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSprite.cpp +++ /dev/null @@ -1,299 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "SpriteBorderEditorCommon.h" -#include "QPropertyTree.h" -#include "PropertyRowField.h" -#include "PropertyRowSprite.h" -#include "PropertyDrawContext.h" -#include "PropertyTreeModel.h" -#include -#include -#include -#include - -extern QString AssetRelativePathFromAbsolutePath(const QString& absPath); - -bool PropertyRowSprite::onActivateButton(int buttonIndex, const PropertyActivationEvent& ev) -{ - Show show = FromButtonIndexToShow( buttonIndex ); - - if( show == Show::kFilePicker ) - { - return showFilePicker( ev ); - } - - if( show == Show::kSpriteBorderEditor ) - { - return showSpriteBorderEditor( ev ); - } - - // This is to avoid a compiler warning. - // We should NEVER get here. - CRY_ASSERT( 0 ); - return false; -} - -bool PropertyRowSprite::onActivate(const PropertyActivationEvent& ev) -{ - if( PropertyRowField::onActivate( ev ) ) - { - // PropertyRowSprite::onActivateButton() has handled this event. - // Nothing else to do. - return true; - } - - return showFilePicker( ev ); -} - -void PropertyRowSprite::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) -{ - Serialization::Sprite* value = (Serialization::Sprite *)ser.pointer(); - - m_path = value->m_path->c_str(); -} - -bool PropertyRowSprite::assignTo(const Serialization::SStruct& ser) const -{ - if( ser.size() != sizeof(Serialization::Sprite) ) - { - return false; - } - - Serialization::Sprite* s = (Serialization::Sprite *)ser.pointer(); - - *s->m_path = m_path.c_str(); - - return true; -} - -void PropertyRowSprite::serializeValue(Serialization::IArchive& ar) -{ - ar(m_path, "path"); - ar(m_filter, "filter"); - ar(m_startFolder, "startFolder"); -} - -int PropertyRowSprite::buttonCount() const -{ - return ( CanBeEdited() ? 2 : 1 ); -} - -const QIcon& PropertyRowSprite::buttonIcon(const QPropertyTree* tree, int index) const -{ - Show show = FromButtonIndexToShow( index ); - - if( show == Show::kFilePicker ) - { - #include "file_open.xpm" - static QIcon icon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_open_xpm)))); - return icon; - } - - if( show == Show::kSpriteBorderEditor ) - { - #include "gear.xpm" - static QIcon icon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(gear_xpm)))); - return icon; - } - - // This is to avoid a compiler warning. - // We should NEVER get here. - CRY_ASSERT( 0 ); - - #include "gear.xpm" - static QIcon icon; - return icon; -} - -string PropertyRowSprite::valueAsString() const -{ - return m_path; -} - -void PropertyRowSprite::clear() -{ - m_path.clear(); -} - -bool PropertyRowSprite::onContextMenu(QMenu &menu, QPropertyTree* tree) -{ - QAction* action = nullptr; - - action = menu.addAction("Clear"); - QObject::connect( action, - &QAction::triggered, - tree, - [ this, tree ] - { - Clear( tree ); - } ); - - int buttonIndex = ( buttonCount() - 1 ); - - action = menu.addAction(buttonIcon(tree, buttonIndex--), "Pick Resource..."); - QObject::connect( action, - &QAction::triggered, - tree, - [ this, tree ] - { - PropertyActivationEvent ev; - ev.tree = tree; - showFilePicker( ev ); - } ); - - if( buttonIndex >= 0 ) - { - action = menu.addAction(buttonIcon(tree, buttonIndex), "Edit"); - QObject::connect( action, - &QAction::triggered, - tree, - [ this, tree ] - { - PropertyActivationEvent ev; - ev.tree = tree; - showSpriteBorderEditor( ev ); - } ); - } - - return true; -} - -bool PropertyRowSprite::processesKey(QPropertyTree* tree, const QKeyEvent* ev) -{ - if (ev->key() == Qt::Key_Delete) - { - return true; - } - - return PropertyRowField::processesKey(tree, ev); -} - -bool PropertyRowSprite::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) -{ - if( ev->key() == Qt::Key_Delete ) - { - Clear( tree ); - return true; - } - return PropertyRowField::onKeyDown(tree, ev); -} - -void PropertyRowSprite::Clear(QPropertyTree* tree) -{ - tree->model()->rowAboutToBeChanged(this); - clear(); - tree->model()->rowChanged(this); -} - -bool PropertyRowSprite::showFilePicker(const PropertyActivationEvent& ev) -{ - if (ev.reason == ev.REASON_RELEASE) - return false; - - // Open the file picker and get the filename the user selects - // (QFileDialog can traverse symlinks and shortcuts) - QString filename = QFileDialog::getOpenFileName(ev.tree, - "Choose file", - QString(), - "*.tif;;*.sprite" ); - - // Early out. - { - if (filename.isEmpty()) - { - // Nothing selected. - return true; - } - - QFileInfo fileInfo( filename ); - if( ! ( ( fileInfo.suffix() == "tif" ) || - ( fileInfo.suffix() == "sprite" ) ) ) - { - // Incompatible files selected. - return true; - } - } - - ev.tree->model()->rowAboutToBeChanged(this); - m_path = AssetRelativePathFromAbsolutePath(filename).toStdString().c_str();; - ev.tree->model()->rowChanged(this); - - return true; -} - -bool PropertyRowSprite::showSpriteBorderEditor(const PropertyActivationEvent& ev) -{ - SpriteBorderEditor sbe( m_path.c_str(), ev.tree ); - if (sbe.GetHasBeenInitializedProperly()) - { - sbe.exec(); - return true; - } - - return false; -} - -bool PropertyRowSprite::CanBeEdited() const -{ - return ( ! m_path.empty() ); -} - -PropertyRowSprite::Show PropertyRowSprite::FromButtonIndexToShow(int index) const -{ - bool showFile = false; - bool showGear = false; - - if( index ) - { - // Second icon from the right. - - showFile = true; - } - else - { - // First icon from the right (right-most icon). - - if( CanBeEdited() ) - { - showGear = true; - } - else - { - showFile = true; - } - } - - if( showFile ) - { - return Show::kFilePicker; - } - - if( showGear ) - { - return Show::kSpriteBorderEditor; - } - - // This is to avoid a compiler warning. - // We should NEVER get here. - CRY_ASSERT( 0 ); - return (Show)0; -} - -DECLARE_SEGMENT(PropertyRowSprite) -REGISTER_PROPERTY_ROW(Serialization::Sprite, PropertyRowSprite); - diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSprite.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSprite.h deleted file mode 100644 index e6f278023d..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowSprite.h +++ /dev/null @@ -1,70 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSPRITE_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSPRITE_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyRowField.h" -#endif - -class PropertyRowSprite -: public PropertyRowField -{ -public: - void clear(); - - bool isLeaf() const override{ return true; } - bool isStatic() const override{ return false; } - - void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override; - bool assignTo(const Serialization::SStruct& ser) const override; - bool onActivateButton(int buttonIndex, const PropertyActivationEvent& ev) override; - bool onActivate(const PropertyActivationEvent& ev) override; - - int buttonCount() const override; - virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override; - virtual bool usePathEllipsis() const override { return true; } - string valueAsString() const override; - void serializeValue(Serialization::IArchive& ar); - - bool onContextMenu(QMenu& menu, QPropertyTree* tree); - - bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override; - bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override; - -private: - - enum class Show - { - kFilePicker, - kSpriteBorderEditor - }; - - void Clear(QPropertyTree* tree); - bool showFilePicker(const PropertyActivationEvent& ev); - bool showSpriteBorderEditor(const PropertyActivationEvent& ev); - bool CanBeEdited() const; - Show FromButtonIndexToShow(int index) const; - - string m_path; - string m_filter; - string m_startFolder; - int m_flags; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSPRITE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowString.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowString.cpp deleted file mode 100644 index 200c75d09e..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowString.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include - -#include "PropertyRowString.h" -#include "PropertyTreeModel.h" -#include "PropertyDrawContext.h" -#include "QPropertyTree.h" - -#include "Serialization/IArchive.h" -#include "Serialization/ClassFactory.h" -#include -#include "Unicode.h" - -// --------------------------------------------------------------------------- -SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRowString, "PropertyRowString", "string"); - -bool PropertyRowString::assignTo(string& str) const -{ - str = fromWideChar(value_.c_str()); - return true; -} - -bool PropertyRowString::assignTo(wstring& str) const -{ - str = value_; - return true; -} - -PropertyRowWidget* PropertyRowString::createWidget(QPropertyTree* tree) -{ - return new PropertyRowWidgetString(this, tree); -} - -bool PropertyRowString::assignToByPointer(void* instance, const Serialization::TypeID& type) const -{ - if (type == Serialization::TypeID::get()) - { - assignTo(*(string*)instance); - return true; - } - else if (type == Serialization::TypeID::get()) - { - assignTo(*(wstring*)instance); - return true; - } - return false; -} - -string PropertyRowString::valueAsString() const -{ - return fromWideChar(value_.c_str()); -} - -void PropertyRowString::setValue(const wchar_t* str, const void* handle, const Serialization::TypeID& type) -{ - value_ = str; - serializer_.setPointer((void*)handle); - serializer_.setType(type); -} - -void PropertyRowString::setValue(const char* str, const void* handle, const Serialization::TypeID& type) -{ - value_ = toWideChar(str); - serializer_.setPointer((void*)handle); - serializer_.setType(type); -} - -void PropertyRowString::serializeValue(Serialization::IArchive& ar) -{ - ar(value_, "value", "Value"); -} - -#include -// vim:ts=4 sw=4: diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowString.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowString.h deleted file mode 100644 index 4a85466463..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowString.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRING_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRING_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyRowField.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Unicode.h" -#include "MathUtils.h" - -#include -#endif - -class PropertyRowString - : public PropertyRowField -{ -public: - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - using PropertyRowField::assignTo; - bool assignTo(string& str) const; - bool assignTo(wstring& str) const; - void setValue(const char* str, const void* handle, const Serialization::TypeID& typeId); - void setValue(const wchar_t* str, const void* handle, const Serialization::TypeID& typeId); - PropertyRowWidget* createWidget(QPropertyTree* tree); - string valueAsString() const; - wstring valueAsWString() const { return value_; } - WidgetPlacement widgetPlacement() const override { return WIDGET_VALUE; } - void serializeValue(Serialization::IArchive& ar) override; - const wstring& value() const{ return value_; } - bool assignToByPointer(void* instance, const Serialization::TypeID& type) const; -protected: - wstring value_; -}; - -class PropertyRowWidgetString - : public PropertyRowWidget -{ - Q_OBJECT -public: - PropertyRowWidgetString(PropertyRowString* row, QPropertyTree* tree) - : PropertyRowWidget(row, tree) - , entry_(new QLineEdit()) - , tree_(tree) - { - initialValue_ = QString(fromWideChar(row->value().c_str()).c_str()); - entry_->setText(initialValue_); - entry_->selectAll(); - connect(entry_.data(), SIGNAL(editingFinished()), this, SLOT(onEditingFinished())); - connect(entry_.data(), &QLineEdit::textChanged, this, [this, tree] { - QFontMetrics fm(entry_->font()); - int contentWidth = min((int)fm.horizontalAdvance(entry_->text()) + 8, tree->width() - entry_->x()); - if (contentWidth > entry_->width()) - { - entry_->resize(contentWidth, entry_->height()); - } - }); - } - ~PropertyRowWidgetString() - { - entry_->hide(); - entry_->setParent(0); - entry_.take()->deleteLater(); - } - - void commit() - { - onEditingFinished(); - } - QWidget* actualWidget() { return entry_.data(); } - -public slots: - void onEditingFinished() - { - PropertyRowString* row = static_cast(this->row()); - if (initialValue_ != entry_->text() || row_->multiValue()) - { - model()->rowAboutToBeChanged(row); - vector str; - QString text = entry_->text(); - str.resize(text.size() + 1, L'\0'); - if (!text.isEmpty()) - { - text.toWCharArray(&str[0]); - } - row->setValue(&str[0], row->searchHandle(), row->typeId()); - model()->rowChanged(row); - } - else - { - tree_->_cancelWidget(); - } - } -protected: - QPropertyTree* tree_; - QScopedPointer entry_; - QString initialValue_; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRING_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowStringListValue.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowStringListValue.cpp deleted file mode 100644 index 35d4589388..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowStringListValue.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "Factory.h" -#include "PropertyRowStringListValue.h" - -#include "Serialization/IArchive.h" -#include "Serialization/ClassFactory.h" - -using Serialization::StringList; -using Serialization::StringListValue; - -REGISTER_PROPERTY_ROW(StringListValue, PropertyRowStringListValue) - -PropertyRowWidget * PropertyRowStringListValue::createWidget(QPropertyTree * tree) -{ - return new PropertyRowWidgetStringListValue(this, tree); -} - -// --------------------------------------------------------------------------- -REGISTER_PROPERTY_ROW(StringListStaticValue, PropertyRowStringListStaticValue) - -PropertyRowWidget * PropertyRowStringListStaticValue::createWidget(QPropertyTree * tree) -{ - return new PropertyRowWidgetStringListValue(this, tree); -} - -DECLARE_SEGMENT(PropertyRowStringList) - -#include -// vim:ts=4 sw=4: diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowStringListValue.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowStringListValue.h deleted file mode 100644 index f8d31ac45b..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowStringListValue.h +++ /dev/null @@ -1,303 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRINGLISTVALUE_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRINGLISTVALUE_H -#pragma once -#if !defined(Q_MOC_RUN) -#include "PropertyRowImpl.h" -#include "PropertyTreeModel.h" -#include "PropertyDrawContext.h" -#include "QPropertyTree.h" -#include -#include -#include -#include -#include -#endif - -using Serialization::StringListValue; -class PropertyRowStringListValue - : public PropertyRow -{ -public: - PropertyRowStringListValue() - : handle_() {} - PropertyRowWidget* createWidget(QPropertyTree* tree) override; - string valueAsString() const override { return value_.c_str(); } - bool assignTo(const Serialization::SStruct& ser) const override - { - *((StringListValue*)ser.pointer()) = value_.c_str(); - return true; - } - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override - { - YASLI_ESCAPE(ser.size() == sizeof(StringListValue), return ); - const StringListValue& stringListValue = *((StringListValue*)(ser.pointer())); - stringList_ = stringListValue.stringList(); - value_ = stringListValue.c_str(); - handle_ = stringListValue.handle(); - type_ = stringListValue.type(); - } - - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - int widgetSizeMin(const QPropertyTree* tree) const override - { - if (userWidgetToContent()) - { - return widthCache_.getOrUpdate(tree, this, tree->_defaultRowHeight()); - } - else - { - return 80; - } - } - WidgetPlacement widgetPlacement() const override { return WIDGET_VALUE; } - const void* searchHandle() const override { return handle_; } - Serialization::TypeID typeId() const override { return type_; } - - void redraw(const PropertyDrawContext& context) override - { - if (multiValue()) - { - context.drawEntry(L" ... ", false, true, 0); - } - else if (userReadOnly()) - { - context.drawValueText(pulledSelected(), valueAsWString().c_str()); - } - else - { - QStyleOptionComboBox option; - option.editable = false; - option.frame = true; - option.currentText = QString(valueAsString().c_str()); - option.state |= QStyle::State_Enabled; - option.rect = QRect(0, 0, context.widgetRect.width(), context.widgetRect.height()); - // we have to translate painter here to work around bug in some themes - context.painter->translate(context.widgetRect.left(), context.widgetRect.top()); - - // create a real instance of a combo so that it has the style sheet applied. - QComboBox widgetForContext; - context.tree->style()->drawComplexControl(QStyle::CC_ComboBox, &option, context.painter, &widgetForContext); - context.painter->setPen(QPen(context.tree->palette().color(QPalette::WindowText))); - QRect textRect = context.tree->style()->subControlRect(QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, &widgetForContext); - - textRect.adjust(1, 0, -1, 0); - context.tree->_drawRowValue(*context.painter, valueAsWString().c_str(), &context.tree->font(), textRect, context.tree->palette().color(QPalette::WindowText), false, false); - context.painter->translate(-context.widgetRect.left(), -context.widgetRect.top()); - } - } - - - void serializeValue(Serialization::IArchive& ar) - { - ar(value_, "value", "Value"); - ar(stringList_, "stringList", "String List"); - } -private: - Serialization::StringList stringList_; - string value_; - const void* handle_; - Serialization::TypeID type_; - friend class PropertyRowWidgetStringListValue; - mutable RowWidthCache widthCache_; -}; - -using Serialization::StringListStaticValue; -class PropertyRowStringListStaticValue - : public PropertyRowImpl -{ -public: - PropertyRowStringListStaticValue() - : handle_() {} - PropertyRowWidget* createWidget(QPropertyTree* tree) override; - string valueAsString() const override { return value_.c_str(); } - bool assignTo(const Serialization::SStruct& ser) const override - { - *((StringListStaticValue*)ser.pointer()) = value_.c_str(); - return true; - } - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override - { - YASLI_ESCAPE(ser.size() == sizeof(StringListStaticValue), return ); - const StringListStaticValue& stringListValue = *((StringListStaticValue*)(ser.pointer())); - stringList_.resize(stringListValue.stringList().size()); - for (size_t i = 0; i < stringList_.size(); ++i) - { - stringList_[i] = stringListValue.stringList()[i]; - } - value_ = stringListValue.c_str(); - handle_ = stringListValue.handle(); - type_ = stringListValue.type(); - } - - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - int widgetSizeMin(const QPropertyTree* tree) const override - { - if (userWidgetToContent()) - { - return widthCache_.getOrUpdate(tree, this, tree->_defaultRowHeight()); - } - else - { - return 80; - } - } - WidgetPlacement widgetPlacement() const override { return WIDGET_VALUE; } - const void* searchHandle() const override { return handle_; } - Serialization::TypeID typeId() const override { return type_; } - void redraw(const PropertyDrawContext& context) override - { - if (multiValue()) - { - context.drawEntry(L" ... ", false, true, 0); - } - else if (userReadOnly()) - { - context.drawValueText(pulledSelected(), valueAsWString().c_str()); - } - else - { - QStyleOptionComboBox option; - option.currentText = QString(valueAsString().c_str()); - option.state |= QStyle::State_Enabled; - option.rect = context.widgetRect; - - // create a real instance of a combo so that it has the style sheet applied. - QComboBox widgetForContext; - context.tree->style()->drawComplexControl(QStyle::CC_ComboBox, &option, context.painter, &widgetForContext); - context.painter->setPen(QPen(context.tree->palette().color(QPalette::WindowText))); - QRect textRect = context.tree->style()->subControlRect(QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, &widgetForContext); - - textRect.adjust(1, 0, -1, 0); - context.tree->_drawRowValue(*context.painter, valueAsWString().c_str(), &context.tree->font(), textRect, context.tree->palette().color(QPalette::WindowText), false, false); - } - } - - - void serializeValue(Serialization::IArchive& ar) - { - ar(value_, "value", "Value"); - ar(stringList_, "stringList", "String List"); - } -private: - Serialization::StringList stringList_; - string value_; - const void* handle_; - Serialization::TypeID type_; - friend class PropertyRowWidgetStringListValue; - mutable RowWidthCache widthCache_; -}; - - -// --------------------------------------------------------------------------- - - -class PropertyRowWidgetStringListValue - : public PropertyRowWidget -{ - Q_OBJECT -public: - PropertyRowWidgetStringListValue(PropertyRowStringListValue* row, QPropertyTree* tree) - : PropertyRowWidget(row, tree) - , comboBox_(new QComboBox()) - { - const Serialization::StringList& stringList = row->stringList_; - for (size_t i = 0; i < stringList.size(); ++i) - { - comboBox_->addItem(stringList[i].c_str()); - } - comboBox_->setCurrentIndex(stringList.find(row->value_.c_str())); - connect(comboBox_, SIGNAL(activated(int)), this, SLOT(onChange(int))); - } - - PropertyRowWidgetStringListValue(PropertyRowStringListStaticValue* row, QPropertyTree* tree) - : PropertyRowWidget(row, tree) - , comboBox_(new QComboBox()) - { - const Serialization::StringList& stringList = row->stringList_; - for (size_t i = 0; i < stringList.size(); ++i) - { - comboBox_->addItem(stringList[i].c_str()); - } - comboBox_->setCurrentIndex(stringList.find(row->value_.c_str())); - connect(comboBox_, SIGNAL(currentIndexChanged(int)), this, SLOT(onChange(int))); - } - - void showPopup() override - { - // Here comboBox_->showPopup() should be sufficient, but sadly with Fusion - // theme ComboBox, when clicked, it fires a mouseReleseTimer, which doesn't - // happen with showPopup. It is used to distinguish click-and-hold from - // simple click. If timer is not fired following mouse release hides combo - // box. That's why the user click is emulated here. - QSize size = comboBox_->size(); - QPoint localPoint = QPoint(aznumeric_cast(size.width() * 0.5f), aznumeric_cast(size.height() * 0.5f)); - QMouseEvent ev(QMouseEvent::MouseButtonPress, localPoint, comboBox_->mapToGlobal(localPoint), Qt::LeftButton, Qt::LeftButton, Qt::KeyboardModifiers()); - QApplication::sendEvent(comboBox_, &ev); - } - - ~PropertyRowWidgetStringListValue() - { - comboBox_->hide(); - comboBox_->setParent(0); - comboBox_->deleteLater(); - comboBox_ = 0; - } - - - void commit(){} - QWidget* actualWidget() { return comboBox_; } -public slots: - void onChange(int) - { - if (strcmp(this->row()->typeName(), Serialization::TypeID::get().name()) == 0) - { - PropertyRowStringListValue* r = static_cast(this->row()); - QByteArray newValue = comboBox_->currentText().toUtf8(); - if (r->value_ != newValue.data()) - { - model()->rowAboutToBeChanged(r); - r->value_ = newValue.data(); - model()->rowChanged(r); - } - else - { - tree_->_cancelWidget(); - } - } - else if (strcmp(this->row()->typeName(), Serialization::TypeID::get().name()) == 0) - { - PropertyRowStringListStaticValue* r = static_cast(this->row()); - QByteArray newValue = comboBox_->currentText().toUtf8(); - if (r->value_ != newValue.data()) - { - model()->rowAboutToBeChanged(r); - r->value_ = newValue.data(); - model()->rowChanged(r); - } - else - { - tree_->_cancelWidget(); - } - } - } -protected: - QComboBox* comboBox_; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRINGLISTVALUE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowTagList.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowTagList.cpp deleted file mode 100644 index 832357bfc7..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowTagList.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "PropertyRowTagList.h" -#include "PropertyRowString.h" -#include "QPropertyTree.h" -#include "Serialization/Decorators/TagList.h" -#include "Serialization/ClassFactory.h" -#include "Serialization/IArchive.h" -#include "Serialization/Decorators/TagListImpl.h" -#include - -PropertyRowTagList::PropertyRowTagList() - : source_(0) -{ -} - -PropertyRowTagList::~PropertyRowTagList() -{ - if (source_) - { - source_->Release(); - } -} - -void PropertyRowTagList::generateMenu(QMenu& item, QPropertyTree* tree, [[maybe_unused]] bool addActions) -{ - if (userReadOnly() || isFixedSize()) - { - return; - } - - if (!source_) - { - return; - } - - TagListMenuHandler* handler = new TagListMenuHandler(); - handler->tree = tree; - handler->row = this; - tree->addMenuHandler(handler); - - unsigned int numGroups = source_->GroupCount(); - for (unsigned int group = 0; group < numGroups; ++group) - { - unsigned int tagCount = source_->TagCount(group); - if (tagCount == 0) - { - continue; - } - const char* groupName = source_->GroupName(group); - QString title = QString("From ") + groupName; - QMenu* menu = item.addMenu(title); - for (unsigned int tagIndex = 0; tagIndex < tagCount; ++tagIndex) - { - QString str; - str = source_->TagValue(group, tagIndex); - const char* desc = source_->TagDescription(group, tagIndex); - if (desc && desc[0] != '\0') - { - str += "\t"; - str += desc; - } - QAction* action = menu->addAction(str); - QString tag = QString::fromLocal8Bit(source_->TagValue(group, tagIndex)); - action->setData(QVariant(tag)); - QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuAddTag())); - } - } - - - QAction* action = item.addAction("Add"); - action->setData(QVariant(QString())); - QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuAddTag())); - - PropertyRowContainer::generateMenu(item, tree, false); -} - -void PropertyRowTagList::addTag(const char* tag, QPropertyTree* tree) -{ - Serialization::SharedPtr ref(this); - - PropertyRow* child = addElement(tree, false); - if (child && strcmp(child->typeName(), "string") == 0) - { - PropertyRowString* stringRow = static_cast(child); - tree->model()->rowAboutToBeChanged(stringRow); - stringRow->setValue(tag, stringRow->searchHandle(), stringRow->typeId()); - tree->model()->rowChanged(stringRow); - } -} - -void TagListMenuHandler::onMenuAddTag() -{ - if (QAction* action = qobject_cast(sender())) - { - QString str = action->data().toString(); - row->addTag(str.toLocal8Bit().data(), tree); - } -} - -void PropertyRowTagList::setValueAndContext(const Serialization::IContainer& value, Serialization::IArchive& ar) -{ - if (source_) - { - source_->Release(); - } - source_ = ar.FindContext(); - if (source_) - { - source_->AddRef(); - } - - PropertyRowContainer::setValueAndContext(value, ar); -} - - -REGISTER_PROPERTY_ROW(TagList, PropertyRowTagList) -DECLARE_SEGMENT(PropertyRowTagList) - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowTagList.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowTagList.h deleted file mode 100644 index 4ea032efa9..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowTagList.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWTAGLIST_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWTAGLIST_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "PropertyRowContainer.h" -#endif - -struct ITagSource; - -class PropertyRowTagList - : public PropertyRowContainer -{ -public: - PropertyRowTagList(); - ~PropertyRowTagList(); - void setValueAndContext(const Serialization::IContainer& value, Serialization::IArchive& ar) override; - void generateMenu(QMenu& item, QPropertyTree* tree, bool addActions) override; - void addTag(const char* tag, QPropertyTree* tree); - -private: - using PropertyRow::setValueAndContext; - ITagSource* source_; -}; - -struct TagListMenuHandler - : public PropertyRowMenuHandler -{ - Q_OBJECT -public: - - PropertyRowTagList * row; - QPropertyTree* tree; -public slots: - void onMenuAddTag(); -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWTAGLIST_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowToggleButton.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowToggleButton.cpp deleted file mode 100644 index 7ae3231673..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyRowToggleButton.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include "EditorCommon_precompiled.h" -#include - -#include "Serialization/ClassFactory.h" -#include "PropertyDrawContext.h" -#include "PropertyRowImpl.h" -#include "QPropertyTree.h" -#include "PropertyTreeModel.h" -#include "Serialization.h" -#include "Color.h" -#include "Unicode.h" -#include "Serialization/Decorators/ToggleButton.h" -using Serialization::ToggleButton; -using Serialization::RadioButton; - -class PropertyRowToggleButton - : public PropertyRow -{ -public: - PropertyRowToggleButton() - : underMouse_(false) - , value_(false) - { - } - - bool isLeaf() const{ return true; } - bool isStatic() const{ return false; } - bool isSelectable() const{ return true; } - - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override - { - ToggleButton* value = (ToggleButton*)(ser.pointer()); - value_ = *value->value; - } - - bool assignTo(const Serialization::SStruct& ser) const override - { - ToggleButton* value = (ToggleButton*)(ser.pointer()); - *value->value = value_; - return true; - } - wstring valueAsWString() const override { return L""; } - WidgetPlacement widgetPlacement() const override { return WIDGET_INSTEAD_OF_TEXT; } - void serializeValue([[maybe_unused]] Serialization::IArchive& ar) {} - int widgetSizeMin([[maybe_unused]] const QPropertyTree* tree) const override { return 36; } - - bool onActivate(const PropertyActivationEvent& e) override - { - if (e.reason == PropertyActivationEvent::REASON_KEYBOARD) - { - value_; - } - return true; - } - - bool onMouseDown(QPropertyTree* tree, QPoint point, [[maybe_unused]] bool& changed) override - { - if (widgetRect(tree).contains(point)) - { - underMouse_ = true; - pressed_ = true; - tree->update(); - return true; - } - return false; - } - - void onMouseDrag(const PropertyDragEvent& e) override - { - bool underMouse = widgetRect(e.tree).contains(e.pos); - if (underMouse != underMouse_) - { - underMouse_ = underMouse; - e.tree->update(); - } - } - - void onMouseUp(QPropertyTree* tree, QPoint point) override - { - if (widgetRect(tree).contains(point)) - { - tree->model()->rowAboutToBeChanged(this); - pressed_ = false; - value_ = !value_; - tree->model()->rowChanged(this); - } - } - - void redraw(const PropertyDrawContext& context) override - { - QRect rect = context.widgetRect; - - wstring text = toWideChar(labelUndecorated()); - int buttonFlags = BUTTON_CENTER; - if ((value_ || pressed_) && underMouse_) - { - buttonFlags |= BUTTON_PRESSED; - } - if (selected() || pressed_) - { - buttonFlags |= BUTTON_FOCUSED; - } - if (userReadOnly()) - { - buttonFlags |= BUTTON_DISABLED; - } - context.drawButton(rect, text.c_str(), buttonFlags, &context.tree->font()); - } -protected: - bool pressed_ : 1; - bool underMouse_ : 1; - bool value_ : 1; -}; - -class PropertyRowRadioButton - : public PropertyRow -{ -public: - - bool isLeaf() const override { return true; } - bool isStatic() const override { return false; } - bool isSelectable() const override { return false; } - - bool onActivate(const PropertyActivationEvent& e) override - { - if (!m_justSet) - { - e.tree->model()->rowAboutToBeChanged(this); - m_justSet = true; - e.tree->model()->rowChanged(this); - } - return true; - } - void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override - { - RadioButton* value = (RadioButton*)(ser.pointer()); - m_value = value->buttonValue; - m_toggled = m_value == *value->value; - m_justSet = false; - } - bool assignTo(const Serialization::SStruct& ser) const override - { - if (m_justSet) - { - *((RadioButton*)ser.pointer())->value = m_value; - } - return true; - } - wstring valueAsWString() const override { return L""; } - WidgetPlacement widgetPlacement() const override { return WIDGET_INSTEAD_OF_TEXT; } - void serializeValue(Serialization::IArchive& ar) override - { - bool oldToggled = m_toggled; - ar(m_toggled, "toggled"); - if (m_toggled && !oldToggled) - { - m_justSet = true; - } - ar(m_value, "value"); - } - int widgetSizeMin([[maybe_unused]] const QPropertyTree* tree) const override { return 40; } - - void redraw(const PropertyDrawContext& context) - { - QRect rect = context.widgetRect; - bool pressed = context.m_pressed || m_toggled || m_justSet; - - wstring text = toWideChar(labelUndecorated()); - int buttonFlags = BUTTON_CENTER; - if (pressed) - { - buttonFlags |= BUTTON_PRESSED; - } - if (selected()) - { - buttonFlags |= BUTTON_FOCUSED; - } - if (userReadOnly()) - { - buttonFlags |= BUTTON_DISABLED; - } - context.drawButton(rect, text.c_str(), buttonFlags, &context.tree->font()); - } -protected: - bool m_toggled; - bool m_justSet; - int m_value; -}; - -REGISTER_PROPERTY_ROW(ToggleButton, PropertyRowToggleButton); -REGISTER_PROPERTY_ROW(RadioButton, PropertyRowRadioButton); diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeMenuHandler.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeMenuHandler.h deleted file mode 100644 index 2d821266da..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeMenuHandler.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMENUHANDLER_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMENUHANDLER_H -#pragma once - -#include "PropertyRow.h" - -struct PropertyTreeMenuHandler - : PropertyRowMenuHandler -{ - Q_OBJECT -public: - PropertyRow * row; - QPropertyTree* tree; - - string filterName; - string filterValue; - string filterType; - -public slots: - void onMenuFilter(); - void onMenuFilterByName(); - void onMenuFilterByValue(); - void onMenuFilterByType(); - - void onMenuUndo(); - void onMenuRedo(); - - void onMenuCopy(); - void onMenuPaste(); -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMENUHANDLER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeModel.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeModel.cpp deleted file mode 100644 index 7192757ecc..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeModel.cpp +++ /dev/null @@ -1,445 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "PropertyTreeModel.h" -#include "QPropertyTree.h" -#include "Serialization.h" -#include "Serialization/ClassFactory.h" -#include "Serialization/Callback.h" - -PropertyTreeModel::PropertyTreeModel() -: expandLevels_(0) -, undoEnabled_(true) -, fullUndo_(false) -{ - clear(); -} - -PropertyTreeModel::~PropertyTreeModel() -{ - root_ = 0; - defaultTypes_.clear(); - defaultTypesPoly_.clear(); -} - -TreePath PropertyTreeModel::pathFromRow(PropertyRow* row) -{ - TreePath result; - if(row) - { - while(row->parent()){ - int childIndex = row->parent()->childIndex(row); - YASLI_ESCAPE(childIndex >= 0, return TreePath()); - result.insert(result.begin(), childIndex); - row = row->parent(); - } - } - return result; -} - -void PropertyTreeModel::selectRow(PropertyRow* row, bool select, bool exclusive) -{ - if(exclusive) - deselectAll(); - - row->setSelected(select); - - Selection::iterator it = std::find(selection_.begin(), selection_.end(), pathFromRow(row)); - if(select){ - if(it == selection_.end()) - selection_.push_back(pathFromRow(row)); - setFocusedRow(row); - } - else if(it != selection_.end()){ -#if !defined(NDEBUG) - PropertyRow* it_row = rowFromPath(*it); -#endif - YASLI_ASSERT(it_row->refCount() > 0 && it_row->refCount() < 0xFFFF); - selection_.erase(it); - } -} - -void PropertyTreeModel::deselectAll() -{ - Selection::iterator it; - for(it = selection_.begin(); it != selection_.end(); ++it){ - PropertyRow* row = rowFromPath(*it); - row->setSelected(false); - } - selection_.clear(); -} - -PropertyRow* PropertyTreeModel::rowFromPath(const TreePath& path) -{ - PropertyRow* row = root(); - if (!root()) - return 0; - TreePath::const_iterator it; - for(it = path.begin(); it != path.end(); ++it){ - int index = it->index; - if(index < int(row->count()) && index >= 0){ - PropertyRow* nextRow = row->childByIndex(index); - if(!nextRow) - return row; - else - row = nextRow; - } - else - return row; - } - return row; -} - -void PropertyTreeModel::setSelection(const Selection& selection) -{ - deselectAll(); - Selection::const_iterator it; - for(it = selection.begin(); it != selection.end(); ++it){ - const TreePath& path = *it; - PropertyRow* row = rowFromPath(path); - if(row) - selectRow(row, true, false); - } -} - -void PropertyTreeModel::clear() -{ - if(root_) - root_->clear(); - root_ = 0; - setRoot(new PropertyRow()); - root_->setNames("", "root", ""); - selection_.clear(); -} - -void PropertyTreeModel::onUpdated(const PropertyRows& rows, bool needApply) -{ - signalUpdated(rows, needApply); -} - -void PropertyTreeModel::applyOperator(PropertyTreeOperator* op) -{ - YASLI_ESCAPE(op, return); - PropertyRow *dest = rowFromPath(op->path_); - YASLI_ESCAPE(dest && "Unable to apply operator!", return); - if(op->type_ == PropertyTreeOperator::NONE) - return; - YASLI_ESCAPE(op->row_, return); - if(dest->parent()) - dest->parent()->replaceAndPreserveState(dest, op->row_, 0); - else{ - op->row_->assignRowProperties(root_); - root_ = op->row_; - } - PropertyRow* newRow = op->row_; - op->row_ = 0; - rowChanged(newRow); -} - -void PropertyTreeModel::undo() -{ - YASLI_ESCAPE(!undoOperators_.empty(), return); - - auto op = &undoOperators_.back(); - PropertyRow *dest = rowFromPath(op->path_); - PropertyTreeOperator redoOp = getCurrentStateTreeOperator(dest); - - applyOperator(op); - undoOperators_.pop_back(); - - pushRedo(redoOp); -} - -void PropertyTreeModel::redo() -{ - YASLI_ESCAPE(!redoOperators_.empty(), return); - - auto op = &redoOperators_.back(); - PropertyRow *dest = rowFromPath(op->path_); - PropertyTreeOperator undoOp = getCurrentStateTreeOperator(dest); - - applyOperator(op); - redoOperators_.pop_back(); - - pushUndo(undoOp); -} - -void PropertyTreeModel::clearUndo() -{ - undoOperators_.clear(); - redoOperators_.clear(); - - Q_EMIT signalUndoRedoStackChanged(false, false); -} - -PropertyTreeModel::UpdateLock PropertyTreeModel::lockUpdate() -{ - if(updateLock_) - return updateLock_; - else { - UpdateLock lock = new PropertyTreeModel::LockedUpdate(this);; - updateLock_ = lock; - lock->release(); - return lock; - } -} - -void PropertyTreeModel::dismissUpdate() -{ - if(updateLock_) - updateLock_->dismissUpdate(); -} - -void PropertyTreeModel::requestUpdate(const PropertyRows& rows, bool apply) -{ - if(updateLock_) - updateLock_->requestUpdate(rows, apply); - else - onUpdated(rows, apply); -} - -struct RowObtainer { - RowObtainer(std::vector& states) : states_(states) {} - ScanResult operator()(PropertyRow* row) - { - states_.push_back(row->expanded() ? 1 : 0); - return row->expanded() ? SCAN_CHILDREN_SIBLINGS : SCAN_SIBLINGS; - } -protected: - std::vector& states_; -}; - -struct RowExpander { - RowExpander(const std::vector& states) : states_(states), index_(0) {} - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, [[maybe_unused]] int index) - { - if(size_t(index_) >= states_.size()) - return SCAN_FINISHED; - - if(states_[index_++]){ - if(row->canBeToggled(tree)) - row->_setExpanded(true); - return SCAN_CHILDREN_SIBLINGS; - } - else{ - row->_setExpanded(false); - return SCAN_SIBLINGS; - } - } -protected: - int index_; - const std::vector& states_; -}; - -void PropertyTreeModel::Serialize(Serialization::IArchive& ar, QPropertyTree* tree) -{ - ar(focusedRow_, "focusedRow", 0); - ar(selection_, "selection", 0); - - if (root()) { - std::vector expanded; - if(ar.IsOutput()) { - RowObtainer op(expanded); - root()->scanChildren(op); - } - ar(expanded, "expanded", 0); - if(ar.IsInput()){ - Selection sel = selection_; - setSelection(sel); - RowExpander op(expanded); - root()->scanChildren(op, tree); - root()->setLayoutChanged(); - root()->setLayoutChangedToChildren(); - } - } -} - -void PropertyTreeModel::pushUndo(const PropertyTreeOperator& op) -{ - PropertyTreeOperator oper = op; - bool handled = false; - signalPushUndo(&oper, &handled); - if(!handled && oper.row_ != 0) - undoOperators_.push_back(oper); - - Q_EMIT signalUndoRedoStackChanged(!undoOperators_.empty(), !redoOperators_.empty()); -} - -void PropertyTreeModel::pushRedo(const PropertyTreeOperator& op) -{ - PropertyTreeOperator oper = op; - bool handled = false; - signalPushRedo(&oper, &handled); - if (!handled && oper.row_ != 0) - redoOperators_.push_back(oper); - - Q_EMIT signalUndoRedoStackChanged(!undoOperators_.empty(), !redoOperators_.empty()); -} - -PropertyTreeOperator PropertyTreeModel::getCurrentStateTreeOperator(PropertyRow* row) -{ - if (fullUndo_){ - if (undoEnabled_){ - SharedPtr clonedRow = root()->clone(constStrings()); - clonedRow->assignRowState(*root(), true); - return PropertyTreeOperator(TreePath(), clonedRow); - } - else{ - return PropertyTreeOperator(TreePath(), 0); - } - } - else{ - if (undoEnabled_){ - SharedPtr clonedRow = row->clone(constStrings()); - clonedRow->assignRowState(*row, true); - return PropertyTreeOperator(pathFromRow(row), clonedRow); - } - else{ - return PropertyTreeOperator(pathFromRow(row), 0); - } - } -} - -void PropertyTreeModel::rowAboutToBeChanged(PropertyRow* row) -{ - YASLI_ESCAPE(row, return); - pushUndo(getCurrentStateTreeOperator(row)); - - // clear the redo stack now - redoOperators_.clear(); - Q_EMIT signalUndoRedoStackChanged(true, false); -} - -void PropertyTreeModel::callRowCallback(PropertyRow* row) -{ - PropertyRow* current = row; - while (true) { - Serialization::ICallback* callback = current->callback(); - if (callback) { - auto applyFunc = [=](void* arg, [[maybe_unused]] const TypeID& type) { - current->assignToByPointer(arg, callback->Type()); - }; - callback->Call(applyFunc); - return; - } - current = current->parent(); - if (current) - current->handleChildrenChange(); - else - break; - } -} - -void PropertyTreeModel::rowChanged(PropertyRow* row, bool apply) -{ - callRowCallback(row); - - YASLI_ESCAPE(row, return); - row->setLabelChanged(); - row->setLayoutChanged(); - - PropertyRow* parentObj = row; - while (parentObj->parent() && !parentObj->isObject()) - parentObj = parentObj->parent(); - - row->setMultiValue(false); - - PropertyRows rows; - rows.push_back(parentObj); - requestUpdate(rows, apply); -} - -bool PropertyTreeModel::defaultTypeRegistered(const char* typeName) const -{ - return defaultTypes_.find(typeName) != defaultTypes_.end(); -} - -void PropertyTreeModel::addDefaultType(PropertyRow* row, const char* typeName) -{ - YASLI_ESCAPE(typeName != 0, return); - defaultTypes_[typeName] = row; -} - -PropertyRow* PropertyTreeModel::defaultType(const char* typeName) const -{ - DefaultTypes::const_iterator it = defaultTypes_.find(typeName); - YASLI_ESCAPE(it != defaultTypes_.end(), return 0); - return it->second; -} - -void PropertyTreeModel::addDefaultType(const TypeID& type, const PropertyDefaultDerivedTypeValue& value) -{ - YASLI_ASSERT(type != TypeID()); - - BaseClass& base = defaultTypesPoly_[type]; - for (DerivedTypes::iterator it = base.types.begin(); it != base.types.end(); ++it){ - if (it->registeredName == value.registeredName) { - YASLI_ASSERT(it->root == 0); - *it = value; - return; - } - } - - base.types.push_back(value); - base.strings.push_back(value.label.c_str()); -} - -const PropertyDefaultDerivedTypeValue* PropertyTreeModel::defaultType(const TypeID& baseType, int derivedIndex) const -{ - DefaultTypesPoly::const_iterator it = defaultTypesPoly_.find(baseType); - YASLI_ESCAPE(it != defaultTypesPoly_.end(), return 0); - const BaseClass& base = it->second; - YASLI_ESCAPE(size_t(derivedIndex) < base.types.size(), return 0); - return &base.types[derivedIndex]; -} - -bool PropertyTreeModel::defaultTypeRegistered(const TypeID& baseType, const char* derivedRegisteredName) const -{ - if (!derivedRegisteredName) - derivedRegisteredName = ""; - DefaultTypesPoly::const_iterator it = defaultTypesPoly_.find(baseType); - - if (it == defaultTypesPoly_.end()) - return false; - - const BaseClass& base = it->second; - DerivedTypes::const_iterator dit; - for (dit = base.types.begin(); dit != base.types.end(); ++dit){ - if (dit->registeredName == derivedRegisteredName) - return true; - } - return false; -} - -const Serialization::StringList& PropertyTreeModel::typeStringList(const TypeID& baseType) const -{ - DefaultTypesPoly::const_iterator it = defaultTypesPoly_.find(baseType); - - static Serialization::StringList empty; - YASLI_ESCAPE(it != defaultTypesPoly_.end(), return empty); - const BaseClass& base = it->second; - return base.strings; -} - -// ---------------------------------------------------------------------------------- - -bool Serialize(Serialization::IArchive& ar, TreePathLeaf& value, const char* name, const char* label) -{ - return ar(value.index, name, label); -} - -bool Serialize(Serialization::IArchive& ar, TreeSelection& value, const char* name, const char* label) -{ - return ar(static_cast&>(value), name, label); -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeModel.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeModel.h deleted file mode 100644 index 0b518f8171..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeModel.h +++ /dev/null @@ -1,208 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMODEL_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMODEL_H -#pragma once - - -#if !defined(Q_MOC_RUN) -#include -#include "PropertyRow.h" -#include "PropertyTreeOperator.h" -#include "Serialization/Pointers.h" -#endif - -using std::vector; -using std::map; - -struct TreeSelection : vector -{ - bool operator==(const TreeSelection& rhs){ - if(size() != rhs.size()) - return false; - for(int i = 0; i < int(size()); ++i) - if((*this)[i] != rhs[i]) - return false; - return true; - } -}; - -struct PropertyDefaultDerivedTypeValue -{ - string registeredName; - Serialization::SharedPtr root; - Serialization::IClassFactory* factory; - int factoryIndex; - std::string label; - - PropertyDefaultDerivedTypeValue() - : factoryIndex(-1) - , factory(0) - { - } -}; - -struct PropertyDefaultTypeValue -{ - Serialization::TypeID type; - string registedName; - Serialization::SharedPtr root; - Serialization::IClassFactory* factory; - int factoryIndex; - std::string label; - - PropertyDefaultTypeValue() - : factoryIndex(-1) - , factory(0) - { - } -}; - -// --------------------------------------------------------------------------- - -class PropertyTreeModel : public QObject -{ - Q_OBJECT -public: - class LockedUpdate : public Serialization::RefCounter{ - public: - LockedUpdate(PropertyTreeModel* model) - : model_(model) - , apply_(false) - {} - void requestUpdate(const PropertyRows& rows, bool apply) { - for (size_t i = 0; i < rows.size(); ++i) { - PropertyRow* row = rows[i]; - if (std::find(rows_.begin(), rows_.end(), row) == rows_.end()) - rows_.push_back(row); - } - if (apply) - apply_ = true; - } - void dismissUpdate(){ rows_.clear(); } - ~LockedUpdate(){ - model_->updateLock_ = 0; - if(!rows_.empty()) - model_->signalUpdated(rows_, apply_); - } - protected: - PropertyTreeModel* model_; - PropertyRows rows_; - bool apply_; - }; - typedef Serialization::SharedPtr UpdateLock; - - typedef TreeSelection Selection; - - PropertyTreeModel(); - ~PropertyTreeModel(); - - void clear(); - bool canUndo() const{ return !undoOperators_.empty(); } - void undo(); - bool canRedo() const{ return !redoOperators_.empty(); } - void redo(); - void clearUndo(); - - TreePath pathFromRow(PropertyRow* node); - PropertyRow* rowFromPath(const TreePath& path); - void setFocusedRow(PropertyRow* row) { focusedRow_ = pathFromRow(row); } - PropertyRow* focusedRow() { return rowFromPath(focusedRow_); } - - const Selection& selection() const{ return selection_; } - void setSelection(const Selection& selection); - - void setRoot(PropertyRow* root) { root_ = root; } - PropertyRow* root() { return root_; } - const PropertyRow* root() const { return root_; } - - void Serialize(Serialization::IArchive& ar, QPropertyTree* tree); - - UpdateLock lockUpdate(); - void requestUpdate(const PropertyRows& rows, bool needApply); - void dismissUpdate(); - - void selectRow(PropertyRow* row, bool selected, bool exclusive = true); - void deselectAll(); - - void rowAboutToBeChanged(PropertyRow* row); - void callRowCallback(PropertyRow* row); - void rowChanged(PropertyRow* row, bool apply = true); // be careful: it can destroy 'row' - - void setUndoEnabled(bool enabled) { undoEnabled_ = enabled; } - void setFullUndo(bool fullUndo) { fullUndo_ = fullUndo; } - void setExpandLevels(int levels) { expandLevels_ = levels; } - int expandLevels() const{ return expandLevels_; } - - void onUpdated(const PropertyRows& rows, bool needApply); - - // for defaultArchive - const Serialization::StringList& typeStringList(const Serialization::TypeID& baseType) const; - - bool defaultTypeRegistered(const char* typeName) const; - void addDefaultType(PropertyRow* propertyRow, const char* typeName); - PropertyRow* defaultType(const char* typeName) const; - - bool defaultTypeRegistered(const Serialization::TypeID& baseType, const char* derivedRegisteredName) const; - void addDefaultType(const Serialization::TypeID& baseType, const PropertyDefaultDerivedTypeValue& value); - const PropertyDefaultDerivedTypeValue* defaultType(const Serialization::TypeID& baseType, int index) const; - ConstStringList* constStrings() { return &constStrings_; } - -signals: - void signalUpdated(const PropertyRows& rows, bool needApply); - void signalPushUndo(PropertyTreeOperator* op, bool* result); - void signalPushRedo(PropertyTreeOperator* op, bool* result); - - void signalUndoRedoStackChanged(bool undosAvailable, bool redosAvailable); -private: - void applyOperator(PropertyTreeOperator* op); - void pushUndo(const PropertyTreeOperator& op); - void pushRedo(const PropertyTreeOperator& op); - - void clearObjectReferences(); - PropertyTreeOperator getCurrentStateTreeOperator(PropertyRow* row); - - TreePath focusedRow_; - Selection selection_; - - Serialization::SharedPtr root_; - UpdateLock updateLock_; - - typedef std::map > DefaultTypes; - DefaultTypes defaultTypes_; - - - typedef vector DerivedTypes; - struct BaseClass{ - Serialization::TypeID type; - std::string name; - Serialization::StringList strings; - DerivedTypes types; - }; - typedef map DefaultTypesPoly; - DefaultTypesPoly defaultTypesPoly_; - - int expandLevels_; - bool undoEnabled_; - bool fullUndo_; - - std::vector undoOperators_; - std::vector redoOperators_; - - ConstStringList constStrings_; - - friend class TreeImpl; -}; - -bool Serialize(Serialization::IArchive& ar, TreeSelection &selection, const char* name, const char* label); -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMODEL_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeOperator.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeOperator.cpp deleted file mode 100644 index 1c70b6d73c..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeOperator.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include "EditorCommon_precompiled.h" -#include "PropertyTreeOperator.h" -#include "PropertyRow.h" -#include "Serialization/Enum.h" -#include "Serialization/STL.h" -#include "Serialization/Pointers.h" -#include "Serialization/IArchive.h" -#include "Serialization/STLImpl.h" -#include "Serialization/PointersImpl.h" - -SERIALIZATION_ENUM_BEGIN_NESTED(PropertyTreeOperator, Type, "PropertyTreeOp") -SERIALIZATION_ENUM_VALUE_NESTED(PropertyTreeOperator, REPLACE, "Replace") -SERIALIZATION_ENUM_VALUE_NESTED(PropertyTreeOperator, ADD, "Add") -SERIALIZATION_ENUM_VALUE_NESTED(PropertyTreeOperator, REMOVE, "Remove") -SERIALIZATION_ENUM_END() - -PropertyTreeOperator::PropertyTreeOperator(const TreePath& path, PropertyRow* row) -: type_(REPLACE) -, path_(path) -, index_(-1) -, row_(row) -{ -} - -PropertyTreeOperator::PropertyTreeOperator() -: type_(NONE) -, index_(-1) -{ -} - -PropertyTreeOperator::~PropertyTreeOperator() -{ -} - -void PropertyTreeOperator::Serialize(Serialization::IArchive& ar) -{ - ar(type_, "type", "Type"); - ar(path_, "path", "Path"); - ar(row_, "row", "Row"); - ar(index_, "index", "Index"); -} - diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeOperator.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeOperator.h deleted file mode 100644 index 0316cfe7cd..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/PropertyTreeOperator.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEOPERATOR_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEOPERATOR_H -#pragma once - -#include -#include "Serialization/Pointers.h" - -namespace Serialization{ class IArchive; } - -class PropertyRow; - -struct TreePathLeaf -{ - int index; - - TreePathLeaf(int _index = -1) - : index(_index) - { - } - bool operator==(const TreePathLeaf& rhs) const{ - return index == rhs.index; - } - bool operator!=(const TreePathLeaf& rhs) const{ - return index != rhs.index; - } -}; -bool Serialize(Serialization::IArchive& ar, TreePathLeaf& value, const char* name, const char* label); - -typedef std::vector TreePath; -typedef std::vector TreePathes; - -class PropertyTreeOperator -{ -public: - enum Type{ - NONE, - REPLACE, - ADD, - REMOVE - }; - - PropertyTreeOperator(); - ~PropertyTreeOperator(); - PropertyTreeOperator(const TreePath& path, PropertyRow* row); - void Serialize(Serialization::IArchive& ar); -private: - Type type_; - TreePath path_; - Serialization::SharedPtr row_; - int index_; - friend class PropertyTreeModel; -}; - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEOPERATOR_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyDialog.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyDialog.cpp deleted file mode 100644 index 87db4de1b0..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyDialog.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "QPropertyDialog.h" -#include "QPropertyTree.h" -#include "Serialization/IArchive.h" -#include "Serialization/BinArchive.h" -#include "Serialization/JSONIArchive.h" -#include "Serialization/JSONOArchive.h" -#include -#include -#include - -#include - -#ifndef SERIALIZATION_STANDALONE -#include -#include -#else -namespace PathUtil -{ - string GetParentDirectory(const char* path) - { - const char* end = strrchr(path, '/'); - if (!end) - { - end = strrchr(path, '\\'); - } - if (end) - { - return string(path, end); - } - else - { - return string(); - } - } -}; -#endif - -#ifndef SERIALIZATION_STANDALONE -#include -#endif - -static string getFullStateFilename(const char* filename) -{ -#ifdef SERIALIZATION_STANDALONE - // use current folder - return filename; -#else - string path = GetIEditor()->GetResolvedUserFolder().toUtf8().data(); - if (!path.empty() && path[path.size() - 1] != '\\' && path[path.size() - 1] != '/') - { - path.push_back('\\'); - } - path += filename; - return path; -#endif -} - -bool QPropertyDialog::edit(Serialization::SStruct& ser, const char* title, const char* windowStateFilename, QWidget* parent) -{ - QPropertyDialog dialog(parent); - dialog.setSerializer(ser); - dialog.setWindowTitle(QString::fromLocal8Bit(title)); - dialog.setWindowStateFilename(windowStateFilename); - - return dialog.exec() == QDialog::Accepted; -} - -QPropertyDialog::QPropertyDialog(QWidget* parent) - : QDialog(parent) - , m_sizeHint(440, 500) - , m_layout(0) - , m_storeContent(false) -{ - connect(this, SIGNAL(accepted()), this, SLOT(onAccepted())); - connect(this, SIGNAL(rejected()), this, SLOT(onRejected())); - setModal(true); - setWindowModality(Qt::ApplicationModal); - - m_propertyTree = new QPropertyTree(this); - m_propertyTree->setExpandLevels(1); - - m_layout = new QBoxLayout(QBoxLayout::TopToBottom, this); - - m_layout->addWidget(m_propertyTree, 1); - QDialogButtonBox* buttons = new QDialogButtonBox(this); - buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttons, SIGNAL(rejected()), this, SLOT(reject())); - m_layout->addWidget(buttons, 0); -} - -QPropertyDialog::~QPropertyDialog() -{ -} - -void QPropertyDialog::revert() -{ - if (m_propertyTree) - { - m_propertyTree->revert(); - } -} - -void QPropertyDialog::setSerializer(const Serialization::SStruct& ser) -{ - if (!m_serializer) - { - m_serializer.reset(new Serialization::SStruct()); - } - *m_serializer = ser; -} - -void QPropertyDialog::setWindowStateFilename(const char* windowStateFilename) -{ - m_windowStateFilename = windowStateFilename; -} - -void QPropertyDialog::setSizeHint(const QSize& size) -{ - m_sizeHint = size; -} - -void QPropertyDialog::setStoreContent(bool storeContent) -{ - m_storeContent = storeContent; -} - -QSize QPropertyDialog::sizeHint() const -{ - return m_sizeHint; -} - -void QPropertyDialog::setVisible(bool visible) -{ - QDialog::setVisible(visible); - - if (visible) - { - string fullStateFilename = getFullStateFilename(m_windowStateFilename.c_str()); - if (!fullStateFilename.empty()) - { - Serialization::JSONIArchive ia; - if (ia.load(fullStateFilename.c_str())) - { - ia(*this); - } - } - - m_backup.reset(new Serialization::BinOArchive()); - if (m_serializer && *m_serializer) - { - const Serialization::SStruct& ser = *m_serializer; - (*m_backup)(ser, "backup"); - m_propertyTree->attach(*m_serializer); - } - } -} - -void QPropertyDialog::onAccepted() -{ - string fullStateFilename = getFullStateFilename(m_windowStateFilename.c_str()); - if (!fullStateFilename.empty()) - { - Serialization::JSONOArchive oa; - oa(*this); - - QDir().mkdir(QString::fromLocal8Bit(PathUtil::GetParentDirectory(fullStateFilename.c_str()).c_str())); - oa.save(fullStateFilename.c_str()); - } -} - -void QPropertyDialog::onRejected() -{ - if (m_backup.get() && m_serializer.get() && *m_serializer) - { - // restore previous object state - Serialization::BinIArchive ia; - if (ia.open(m_backup->buffer(), m_backup->length())) - { - const Serialization::SStruct& ser = *m_serializer; - ia(ser, "backup"); - } - } -} - -void QPropertyDialog::setArchiveContext(Serialization::SContextLink* context) -{ - m_propertyTree->setArchiveContext(context); -} - -void QPropertyDialog::Serialize(Serialization::IArchive& ar) -{ - if (m_storeContent && m_serializer.get()) - { - ar(*m_serializer, "content"); - } - - QByteArray geometry; - if (ar.IsOutput()) - { - geometry = saveGeometry(); - } - std::vector geometryVec(geometry.begin(), geometry.end()); - ar(geometryVec, "geometry"); - if (ar.IsInput() && !geometryVec.empty()) - { - restoreGeometry(QByteArray(geometryVec.data(), (int)geometryVec.size())); - } - - ar(*m_propertyTree, "propertyTree"); -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyDialog.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyDialog.h deleted file mode 100644 index a295ec188f..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyDialog.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYDIALOG_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYDIALOG_H -#pragma once - -#if !defined(Q_MOC_RUN) -#include "../EditorCommonAPI.h" -#include "Strings.h" -#include - -#include -#endif - -namespace Serialization -{ - struct SStruct; - struct SContextLink; - class BinOArchive; - class IArchive; -} - -class QPropertyTree; -class QBoxLayout; - -class EDITOR_COMMON_API QPropertyDialog - : public QDialog -{ - Q_OBJECT -public: - static bool edit(Serialization::SStruct& ser, const char* title, const char* windowStateFilename, QWidget* parent); - - QPropertyDialog(QWidget* parent); - ~QPropertyDialog(); - - void setSerializer(const Serialization::SStruct& ser); - void setArchiveContext(Serialization::SContextLink* context); - void setWindowStateFilename(const char* windowStateFilename); - void setSizeHint(const QSize& sizeHint); - void setStoreContent(bool storeContent); - - void revert(); - QBoxLayout* layout() { return m_layout; } - - void Serialize(Serialization::IArchive& ar); -protected slots: - void onAccepted(); - void onRejected(); - -protected: - QSize sizeHint() const override; - void setVisible(bool visible) override; -private: - QPropertyTree* m_propertyTree; - QBoxLayout* m_layout; - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - std::unique_ptr m_serializer; - std::unique_ptr m_backup; - string m_windowStateFilename; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - QSize m_sizeHint; - bool m_storeContent; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYDIALOG_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTree.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTree.cpp deleted file mode 100644 index 0af0b8368a..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTree.cpp +++ /dev/null @@ -1,3083 +0,0 @@ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -/** -* wWidgets - Lightweight UI Toolkit. -* Copyright (C) 2009-2011 Evgeny Andreeshchev -* Alexander Kotliar -* -* This code is distributed under the MIT License: -* http://www.opensource.org/licenses/MIT -*/ - - -#include "EditorCommon_precompiled.h" -#include "QPropertyTree.h" -#include "PropertyDrawContext.h" -#include "Serialization.h" -#include "Serialization/Decorators/Range.h" -using Serialization::Range; -#include "PropertyTreeModel.h" -#include "QPropertyTreeStyle.h" - -#include "PropertyOArchive.h" -#include "PropertyIArchive.h" -#include "Unicode.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "PropertyTreeMenuHandler.h" - -#include "MathUtils.h" - -#include -// only for clipboard: -#include -#include -#include "PropertyRowPointer.h" -#include "PropertyRowContainer.h" -// ^^^ -#include "PropertyRowObject.h" -#include - -using Serialization::SStructs; - -void PropertyTreeMenuHandler::onMenuFilter() -{ - tree->startFilter(""); -} - -void PropertyTreeMenuHandler::onMenuFilterByName() -{ - tree->startFilter(filterName.c_str()); -} - -void PropertyTreeMenuHandler::onMenuFilterByValue() -{ - tree->startFilter(filterValue.c_str()); -} - -void PropertyTreeMenuHandler::onMenuFilterByType() -{ - tree->startFilter(filterType.c_str()); -} - -void PropertyTreeMenuHandler::onMenuUndo() -{ - tree->model()->undo(); -} - -void PropertyTreeMenuHandler::onMenuRedo() -{ - tree->model()->redo(); -} - -static PropertyRow* findFirstLeafPulledRow(PropertyRow* row) -{ - if (row->isLeaf() && - row->widgetPlacement() != PropertyRow::WIDGET_ICON && - row->widgetPlacement() != PropertyRow::WIDGET_NONE) - return row; - - for (int i = 0; i < row->count(); ++i) - { - PropertyRow* child = row->childByIndex(i); - if (!child) - continue; - if (!child->pulledUp()) - continue; - PropertyRow* leaf = findFirstLeafPulledRow(child); - if (leaf) - return leaf; - } - - return 0; -} - -static QMimeData* propertyRowToMimeData(PropertyRow* row, ConstStringList* constStrings) -{ - PropertyRow::setConstStrings(constStrings); - SharedPtr clonedRow(row->clone(constStrings)); - Serialization::BinOArchive oa; - PropertyRow::setConstStrings(constStrings); - if (!oa(clonedRow, "row", "Row")) { - PropertyRow::setConstStrings(0); - return 0; - } - PropertyRow::setConstStrings(0); - - QByteArray byteArray(oa.buffer(), (int)oa.length()); - QMimeData* mime = new QMimeData; - mime->setData("binary/crypropertytree", byteArray); - if (clonedRow) - { - PropertyRow* textRow = findFirstLeafPulledRow(row); - if (textRow) - mime->setText(QString::fromWCharArray(textRow->valueAsWString().c_str())); - } - return mime; -} - -static bool smartPaste(PropertyRow* dest, SharedPtr& source, PropertyTreeModel* model, bool onlyCheck) -{ - bool result = false; - // content of the pulled container has a priority over the node itself - PropertyRowContainer* destPulledContainer = static_cast(dest->pulledContainer()); - if ((destPulledContainer && strcmp(destPulledContainer->elementTypeName(), source->typeName()) == 0)) { - PropertyRow* elementRow = model->defaultType(destPulledContainer->elementTypeName()); - YASLI_ESCAPE(elementRow, return false); - if (strcmp(elementRow->typeName(), source->typeName()) == 0){ - result = true; - if (!onlyCheck){ - PropertyRow* dest = elementRow; - if (dest->isPointer() && !source->isPointer()){ - PropertyRowPointer* d = static_cast(dest); - SharedPtr newSourceRoot = static_cast(d->clone(model->constStrings()).get()); - source->swapChildren(newSourceRoot, model); - source = newSourceRoot; - } - destPulledContainer->add(source.get()); - } - } - } - else if ((source->isContainer() && dest->isContainer() && - strcmp(static_cast(source.get())->elementTypeName(), - static_cast(dest)->elementTypeName()) == 0) || - (!source->isContainer() && !dest->isContainer() && strcmp(source->typeName(), dest->typeName()) == 0)){ - result = true; - if (!onlyCheck){ - if (dest->isPointer() && !source->isPointer()){ - PropertyRowPointer* d = static_cast(dest); - SharedPtr newSourceRoot = static_cast(d->clone(model->constStrings()).get()); - source->swapChildren(newSourceRoot, model); - source = newSourceRoot; - } - const char* name = dest->name(); - const char* nameAlt = dest->label(); - source->setName(name); - source->setLabel(nameAlt); - if (dest->parent()) - dest->parent()->replaceAndPreserveState(dest, source, model); - else{ - dest->swapChildren(source, model); - source->clear(); - } - source->setLabelChanged(); - } - } - else if (dest->isContainer()){ - if (model){ - PropertyRowContainer* container = static_cast(dest); - PropertyRow* elementRow = model->defaultType(container->elementTypeName()); - YASLI_ESCAPE(elementRow, return false); - if (strcmp(elementRow->typeName(), source->typeName()) == 0){ - result = true; - if (!onlyCheck){ - PropertyRow* dest = elementRow; - if (dest->isPointer() && !source->isPointer()){ - PropertyRowPointer* d = static_cast(dest); - SharedPtr newSourceRoot = static_cast(d->clone(model->constStrings()).get()); - source->swapChildren(newSourceRoot, model); - source = newSourceRoot; - } - - container->add(source.get()); - } - } - container->setLabelChanged(); - } - } - - return result; -} - -static bool propertyRowFromMimeData(SharedPtr& row, const QMimeData* mimeData, ConstStringList* constStrings) -{ - PropertyRow::setConstStrings(constStrings); - QStringList formats = mimeData->formats(); - QByteArray array = mimeData->data("binary/crypropertytree"); - if (array.isEmpty()) - return 0; - Serialization::BinIArchive ia; - if (!ia.open(array.data(), array.size())) - return 0; - - if (!ia(row, "row", "Row")) - return false; - - PropertyRow::setConstStrings(0); - return true; - -} - -bool propertyRowFromClipboard(SharedPtr& row, ConstStringList* constStrings) -{ - const QMimeData* mime = QApplication::clipboard()->mimeData(); - if (!mime) - return false; - return propertyRowFromMimeData(row, mime, constStrings); -} - -void PropertyTreeMenuHandler::onMenuCopy() -{ - QMimeData* mime = propertyRowToMimeData(row, tree->model()->constStrings()); - if (mime) - QApplication::clipboard()->setMimeData(mime); -} - -void PropertyTreeMenuHandler::onMenuPaste() -{ - if (!tree->canBePasted(row)) - return; - PropertyRow* parent = row->parent(); - - tree->model()->rowAboutToBeChanged(row); - - SharedPtr source; - if (!propertyRowFromClipboard(source, tree->model()->constStrings())) - return; - - if (!smartPaste(row, source, tree->model(), false)) - return; - - tree->model()->rowChanged(parent ? parent : tree->model()->root()); -} - -class FilterEntry : public QLineEdit -{ -public: - FilterEntry(QPropertyTree* tree) - : QLineEdit(tree) - , tree_(tree) - { - } -protected: - - void keyPressEvent(QKeyEvent * ev) - { - if (ev->key() == Qt::Key_Escape || ev->key() == Qt::Key_Return) - { - ev->accept(); - tree_->setFocus(); - tree_->keyPressEvent(ev); - } - - if (ev->key() == Qt::Key_Backspace && text().isEmpty()) - { - tree_->setFilterMode(false); - } - QLineEdit::keyPressEvent(ev); - } -private: - QPropertyTree* tree_; -}; - -// --------------------------------------------------------------------------- - -DragWindow::DragWindow(QPropertyTree* tree) - : tree_(tree) - , offset_(0, 0) -{ - QWidget::setWindowFlags(Qt::ToolTip); - QWidget::setWindowOpacity(192.0f / 256.0f); -} - -void DragWindow::set(QPropertyTree* tree, PropertyRow* row, const QRect& rowRect) -{ - QRect rect = tree->rect(); - rect.setTopLeft(tree->mapToGlobal(rect.topLeft())); - - offset_ = rect.topLeft(); - - row_ = row; - rect_ = rowRect; -} - -void DragWindow::setWindowPos([[maybe_unused]] bool visible) -{ - QWidget::move(rect_.left() + offset_.x() - 3, rect_.top() + offset_.y() - 3 + tree_->area_.top()); - QWidget::resize(rect_.width() + 5, rect_.height() + 5); -} - -void DragWindow::show() -{ - setWindowPos(true); - QWidget::show(); -} - -void DragWindow::move(int deltaX, int deltaY) -{ - offset_ += QPoint(deltaX, deltaY); - setWindowPos(isVisible()); -} - -void DragWindow::hide() -{ - setWindowPos(false); - QWidget::hide(); -} - -struct DrawRowVisitor -{ - DrawRowVisitor(QPainter& painter) : painter_(painter) {} - - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, int index) - { - if (row->pulledUp() && row->visible(tree)) { - row->drawRow(painter_, tree, index, true); - row->drawRow(painter_, tree, index, false); - } - - return SCAN_CHILDREN_SIBLINGS; - } - -protected: - QPainter& painter_; -}; - -void DragWindow::drawRow(QPainter& p) -{ - QRect entireRowRect(0, 0, rect_.width() + 4, rect_.height() + 4); - - p.setBrush(tree_->palette().button()); - p.setPen(QPen(tree_->palette().color(QPalette::WindowText))); - p.drawRect(entireRowRect); - - QPoint leftTop = row_->rect().topLeft(); - int offsetX = aznumeric_cast(-leftTop.x() - tree_->treeStyle().firstLevelIndent * tree_->_defaultRowHeight() + 3); - int offsetY = -leftTop.y() + 3; - p.translate(offsetX, offsetY); - int rowIndex = 0; - if (row_->parent()) - rowIndex = row_->parent()->childIndex(row_); - row_->drawRow(p, tree_, 0, true); - row_->drawRow(p, tree_, 0, false); - DrawRowVisitor visitor(p); - row_->scanChildren(visitor, tree_); - p.translate(-offsetX, -offsetY); -} - -void DragWindow::paintEvent([[maybe_unused]] QPaintEvent* ev) -{ - QPainter p(this); - - drawRow(p); -} - -// --------------------------------------------------------------------------- - -class QPropertyTree::DragController -{ -public: - DragController(QPropertyTree* tree) - : tree_(tree) - , captured_(false) - , dragging_(false) - , before_(false) - , row_(0) - , clickedRow_(0) - , window_(tree) - , hoveredRow_(0) - , destinationRow_(0) - { - } - - void beginDrag(PropertyRow* clickedRow, PropertyRow* draggedRow, QPoint pt) - { - row_ = draggedRow; - clickedRow_ = clickedRow; - startPoint_ = pt; - lastPoint_ = pt; - captured_ = true; - dragging_ = false; - } - - bool dragOn(QPoint screenPoint) - { - if (dragging_) - window_.move(screenPoint.x() - lastPoint_.x(), screenPoint.y() - lastPoint_.y()); - - bool needCapture = false; - if (!dragging_ && (startPoint_ - screenPoint).manhattanLength() >= 5) - if (row_->canBeDragged()){ - needCapture = true; - QRect rect = row_->rect(); - rect = QRect(rect.topLeft() - tree_->offset_ + QPoint(aznumeric_cast(tree_->treeStyle().firstLevelIndent * tree_->_defaultRowHeight()), 0), - rect.bottomRight() - tree_->offset_); - - window_.set(tree_, row_, rect); - window_.move(screenPoint.x() - startPoint_.x(), screenPoint.y() - startPoint_.y()); - window_.show(); - dragging_ = true; - } - - if (dragging_){ - QPoint point = tree_->mapFromGlobal(screenPoint); - trackRow(point); - } - lastPoint_ = screenPoint; - return needCapture; - } - - void interrupt() - { - captured_ = false; - dragging_ = false; - row_ = 0; - window_.hide(); - } - - void trackRow(QPoint pt) - { - hoveredRow_ = 0; - destinationRow_ = 0; - - QPoint point = pt; - PropertyRow* row = tree_->rowByPoint(point); - if (!row || !row_) - return; - - row = row->nonPulledParent(); - if (!row->parent() || row->isChildOf(row_) || row == row_) - return; - - float pos = (point.y() - row->rect().top()) / float(row->rect().height()); - if (row_->canBeDroppedOn(row->parent(), row, tree_)){ - if (pos < 0.25f){ - destinationRow_ = row->parent(); - hoveredRow_ = row; - before_ = true; - return; - } - if (pos > 0.75f){ - destinationRow_ = row->parent(); - hoveredRow_ = row; - before_ = false; - return; - } - } - if (row_->canBeDroppedOn(row, 0, tree_)) - hoveredRow_ = destinationRow_ = row; - } - - void drawUnder(QPainter& painter) - { - if (dragging_ && destinationRow_ == hoveredRow_ && hoveredRow_){ - QRect rowRect = hoveredRow_->rect(); - rowRect.setLeft(aznumeric_cast(rowRect.left() + tree_->treeStyle().firstLevelIndent * tree_->_defaultRowHeight())); - QBrush brush(true ? tree_->palette().highlight() : tree_->palette().shadow()); - QColor brushColor = brush.color(); - QColor borderColor(brushColor.alpha() / 4, brushColor.red(), brushColor.green(), brushColor.blue()); - fillRoundRectangle(painter, brush, rowRect, borderColor, 6); - } - } - - void drawOver(QPainter& painter) - { - if (!dragging_) - return; - - QRect rowRect = row_->rect(); - - if (destinationRow_ != hoveredRow_ && hoveredRow_){ - const int tickSize = 4; - QRect hoveredRect = hoveredRow_->rect(); - hoveredRect.setLeft(aznumeric_cast(hoveredRect.left() + tree_->treeStyle().firstLevelIndent * tree_->_defaultRowHeight())); - - if (!before_){ // previous - QRect rect(hoveredRect.left() - 1, hoveredRect.bottom() - 1, hoveredRect.width(), 2); - QRect rectLeft(hoveredRect.left() - 1, hoveredRect.bottom() - tickSize, 2, tickSize * 2); - QRect rectRight(hoveredRect.right() - 1, hoveredRect.bottom() - tickSize, 2, tickSize * 2); - painter.fillRect(rect, tree_->palette().highlight()); - painter.fillRect(rectLeft, tree_->palette().highlight()); - painter.fillRect(rectRight, tree_->palette().highlight()); - } - else{ // next - QRect rect(hoveredRect.left() - 1, hoveredRect.top() - 1, hoveredRect.width(), 2); - QRect rectLeft(hoveredRect.left() - 1, hoveredRect.top() - tickSize, 2, tickSize * 2); - QRect rectRight(hoveredRect.right() - 1, hoveredRect.top() - tickSize, 2, tickSize * 2); - painter.fillRect(rect, tree_->palette().highlight()); - painter.fillRect(rectLeft, tree_->palette().highlight()); - painter.fillRect(rectRight, tree_->palette().highlight()); - } - } - } - - bool drop([[maybe_unused]] QPoint screenPoint) - { - bool rowLayoutChanged = false; - if (row_ && hoveredRow_){ - YASLI_ASSERT(destinationRow_); - clickedRow_->setSelected(false); - row_->dropInto(destinationRow_, destinationRow_ == hoveredRow_ ? 0 : hoveredRow_, tree_, before_); - rowLayoutChanged = true; - } - - captured_ = false; - dragging_ = false; - row_ = 0; - window_.hide(); - hoveredRow_ = 0; - destinationRow_ = 0; - return rowLayoutChanged; - } - - bool captured() const{ return captured_; } - bool dragging() const{ return dragging_; } - PropertyRow* draggedRow() { return row_; } -protected: - DragWindow window_; - QPropertyTree* tree_; - PropertyRow* row_; - PropertyRow* clickedRow_; - PropertyRow* hoveredRow_; - PropertyRow* destinationRow_; - QPoint startPoint_; - QPoint lastPoint_; - bool captured_; - bool dragging_; - bool before_; -}; - -// --------------------------------------------------------------------------- - -AZ_PUSH_DISABLE_WARNING(4335, "-Wunknown-warning-option") -QPropertyTree::QPropertyTree(QWidget* parent) - : QWidget(parent) - , sizeHint_(180, 180) - , model_(0) - , cursorX_(0) - , attachedPropertyTree_(0) - , autoHideAttachedPropertyTree_(false) - , autoRevert_(true) - , dragController_(new DragController(this)) - , leftBorder_(0) - , rightBorder_(0) - , filterMode_(false) - - , applyTime_(0) - , revertTime_(0) - , updateHeightsTime_(0) - , paintTime_(0) - , pressPoint_(-1, -1) - , pressDelta_(0, 0) - , pointerMovedSincePress_(false) - , lastStillPosition_(-1, -1) - , pressedRow_(0) - , capturedRow_(0) - , iconCache_(new IconXPMCache()) - , dragCheckMode_(false) - , dragCheckValue_(false) - , archiveContext_(0) - , outlineMode_(false) - , sizeToContent_(false) - , hideSelection_(false) - , zoomLevel_(10) - , validatorBlock_(new ValidatorBlock) - , style_(new QPropertyTreeStyle()) - - , aggregateMouseEvents_(false) - , aggregatedMouseEventCount_(0) -{ - setFocusPolicy(Qt::WheelFocus); - setMouseTracking(true); // need to receive mouseMoveEvent to update mouse cursor and tooltip - - scrollBar_ = new QScrollBar(Qt::Vertical, this); - connect(scrollBar_, SIGNAL(valueChanged(int)), this, SLOT(onScroll(int))); - - model_.reset(new PropertyTreeModel()); - model_->setExpandLevels(config_.expandLevels); - model_->setUndoEnabled(config_.undoEnabled); - model_->setFullUndo(config_.fullUndo); - - connect(model_.data(), SIGNAL(signalUpdated(const PropertyRows&, bool)), this, SLOT(onModelUpdated(const PropertyRows&, bool))); - connect(model_.data(), SIGNAL(signalPushUndo(PropertyTreeOperator*, bool*)), this, SLOT(onModelPushUndo(PropertyTreeOperator*, bool*))); - connect(model_.data(), SIGNAL(signalPushRedo(PropertyTreeOperator*, bool*)), this, SLOT(onModelPushRedo(PropertyTreeOperator*, bool*))); - //model_->signalPushUndo().connect(this, &QPropertyTree::onModelPushUndo); - - filterEntry_.reset(new FilterEntry(this)); - QObject::connect(filterEntry_.data(), SIGNAL(textChanged(const QString&)), this, SLOT(onFilterChanged(const QString&))); - filterEntry_->hide(); - - mouseStillTimer_ = new QTimer(this); - mouseStillTimer_->setSingleShot(true); - connect(mouseStillTimer_, SIGNAL(timeout()), this, SLOT(onMouseStillTimeout())); - - boldFont_.setBold(true); - backgroundColor_ = palette().color(QPalette::Window); -} -AZ_POP_DISABLE_WARNING - -QPropertyTree::~QPropertyTree() -{ - clearMenuHandlers(); -} - -bool QPropertyTree::onRowKeyDown(PropertyRow* row, const QKeyEvent* ev) -{ - PropertyTreeMenuHandler handler; - handler.row = row; - handler.tree = this; - - if (row->onKeyDown(this, ev)) - return true; - if (row->pulledContainer() && static_cast(row->pulledContainer())->onKeyDownContainer(this, ev)) - return true; - - // NOTE: If you add a new key here, you also have to check for it in rowProcessesKey - - switch (ev->key()){ - case Qt::Key_C: - if (!row->userNonCopyable() && ev->modifiers() == Qt::CTRL) - handler.onMenuCopy(); - return true; - case Qt::Key_V: - if (!row->userNonCopyable() && ev->modifiers() == Qt::CTRL) - handler.onMenuPaste(); - return true; - case Qt::Key_Z: - if (config_.undoEnabled) - { - if (ev->modifiers() == (Qt::SHIFT | Qt::CTRL)) - { - if (model()->canRedo()) - { - handler.onMenuRedo(); - } - return true; - } - else if (ev->modifiers() == Qt::CTRL) - { - if (model()->canUndo()) - { - handler.onMenuUndo(); - } - return true; - } - } - else - { - if (ev->modifiers() == (Qt::SHIFT | Qt::CTRL)) - { - emit signalRedo(); - } - else if (ev->modifiers() == Qt::CTRL) - { - emit signalUndo(); - } - - return true; - } - break; - case Qt::Key_Y: - if (!config_.undoEnabled) - { - if (model()->canRedo()) - { - handler.onMenuRedo(); - } - } - else - { - if (ev->modifiers() == Qt::CTRL) - { - emit signalRedo(); - } - } - return true; - break; - - case Qt::Key_F2: - if (ev->modifiers() == Qt::NoModifier) { - if (selectedRow()) { - PropertyActivationEvent act; - act.tree = this; - act.force = true; - act.reason = PropertyActivationEvent::REASON_KEYBOARD; - selectedRow()->onActivate(act); - } - } - break; - case Qt::Key_Menu: - { - if (ev->modifiers() == Qt::NoModifier) { - QMenu menu(this); - - if (onContextMenu(row, menu)){ - QRect rect(row->rect()); - QPoint pt = _toScreen(QPoint(rect.left() + rect.height(), rect.bottom())); - menu.exec(pt); - } - return true; - } - break; - } - } - - PropertyRow* focusedRow = model()->focusedRow(); - if (!focusedRow) - return false; - PropertyRow* parentRow = focusedRow->nonPulledParent(); - int x = parentRow->horizontalIndex(this, focusedRow); - int y = model()->root()->verticalIndex(this, parentRow); - PropertyRow* selectedRow = 0; - switch (ev->key()){ - case Qt::Key_Up: - if (filterMode_ && y == 0) { - setFilterMode(true); - } - else { - selectedRow = model()->root()->rowByVerticalIndex(this, --y); - if (selectedRow) - selectedRow = selectedRow->rowByHorizontalIndex(this, cursorX_); - } - break; - case Qt::Key_Down: - if (filterMode_ && filterEntry_->hasFocus()) { - setFocus(); - } - else { - selectedRow = model()->root()->rowByVerticalIndex(this, ++y); - if (selectedRow) - selectedRow = selectedRow->rowByHorizontalIndex(this, cursorX_); - } - break; - case Qt::Key_Left: - selectedRow = parentRow->rowByHorizontalIndex(this, cursorX_ = --x); - if (selectedRow == focusedRow && parentRow->canBeToggled(this) && parentRow->expanded()){ - expandRow(parentRow, false); - selectedRow = model()->focusedRow(); - } - break; - case Qt::Key_Right: - selectedRow = parentRow->rowByHorizontalIndex(this, cursorX_ = ++x); - if (selectedRow == focusedRow && parentRow->canBeToggled(this) && !parentRow->expanded()){ - expandRow(parentRow, true); - selectedRow = model()->focusedRow(); - } - break; - case Qt::Key_Home: - if (ev->modifiers() == Qt::CTRL) { - selectedRow = parentRow->rowByHorizontalIndex(this, cursorX_ = INT_MIN); - } - else { - selectedRow = model()->root()->rowByVerticalIndex(this, 0); - if (selectedRow) - selectedRow = selectedRow->rowByHorizontalIndex(this, cursorX_); - } - break; - case Qt::Key_End: - if (ev->modifiers() == Qt::CTRL) { - selectedRow = parentRow->rowByHorizontalIndex(this, cursorX_ = INT_MAX); - } - else { - selectedRow = model()->root()->rowByVerticalIndex(this, INT_MAX); - if (selectedRow) - selectedRow = selectedRow->rowByHorizontalIndex(this, cursorX_); - } - break; - case Qt::Key_Space: - if (config_.filterWhenType) - break; - case Qt::Key_Return: - if (focusedRow->canBeToggled(this)) - expandRow(focusedRow, !focusedRow->expanded()); - else { - PropertyActivationEvent e; - e.tree = this; - e.reason = e.REASON_KEYBOARD; - e.force = false; - focusedRow->onActivate(e); - } - break; - } - if (selectedRow){ - onRowSelected(std::vector(1, selectedRow), false, false); - return true; - } - return false; -} - -bool QPropertyTree::rowProcessesKey(PropertyRow* row, const QKeyEvent* ev) -{ - if (row->processesKey(this, ev)) - { - return true; - } - - if (row->pulledContainer() && static_cast(row->pulledContainer())->processesKeyContainer(this, ev)) - { - return true; - } - - int modifiedKey = ev->key() | ev->modifiers(); - - switch (modifiedKey) - { - case (Qt::CTRL | Qt::Key_Z): - case (Qt::CTRL | Qt::SHIFT | Qt::Key_Z) : - case Qt::Key_Y: - case (Qt::CTRL | Qt::Key_V): - case (Qt::CTRL | Qt::Key_C): - case (Qt::CTRL | Qt::Key_F): - case Qt::Key_Menu: - case Qt::Key_F2: - return true; - break; - - default: - break; - } - - switch (ev->key()) - { - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Return: - return true; - break; - - default: - break; - } - - return false; -} - -struct FirstIssueVisitor -{ - ValidatorEntryType entryType_; - PropertyRow* startRow_; - PropertyRow* result; - - FirstIssueVisitor(ValidatorEntryType type, PropertyRow* startRow) - : entryType_(type) - , startRow_(startRow) - , result() - { - } - - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, int) - { - if ((row->pulledUp() || row->pulledBefore()) && row->nonPulledParent() == startRow_) - return SCAN_SIBLINGS; - if (row->validatorCount()) { - if (const ValidatorEntry* validatorEntries = tree->_validatorBlock()->GetEntry(row->validatorIndex(), row->validatorCount())) { - for (int i = 0; i < row->validatorCount(); ++i) { - const ValidatorEntry* validatorEntry = validatorEntries + i; - if (validatorEntry->type == entryType_) { - result = row; - return SCAN_FINISHED; - } - } - } - } - return SCAN_CHILDREN_SIBLINGS; - } -}; - -void QPropertyTree::jumpToNextHiddenValidatorIssue(bool isError, PropertyRow* start) -{ - FirstIssueVisitor op(isError ? VALIDATOR_ENTRY_ERROR : VALIDATOR_ENTRY_WARNING, start); - start->scanChildren(op, this); - - PropertyRow* row = op.result; - - vector parents; - while (row && row->parent()) { - parents.push_back(row); - row = row->parent(); - } - for (int i = (int)parents.size() - 1; i >= 0; --i) { - if (!parents[i]->visible(this)) - break; - row = parents[i]; - } - if (row) - setSelectedRow(row); - - updateValidatorIcons(); - updateHeights(); -} - -static void rowsInBetween(vector* rows, PropertyRow* a, PropertyRow* b) -{ - if (!a) - return; - if (!b) - return; - vector pathA; - PropertyRow* rootA = a; - while (rootA->parent()) { - pathA.push_back(rootA); - rootA = rootA->parent(); - } - - vector pathB; - PropertyRow* rootB = b; - while (rootB->parent()) { - pathB.push_back(rootB); - rootB = rootB->parent(); - } - - if (rootA != rootB) - return; - - const PropertyRow* commonParent = rootA; - int maxDepth = min((int)pathA.size(), (int)pathB.size()); - for (int i = 0; i < maxDepth; ++i) { - PropertyRow* parentA = pathA[(int)pathA.size() - 1 - i]; - PropertyRow* parentB = pathB[(int)pathB.size() - 1 - i]; - if (parentA != parentB) { - int indexA = commonParent->childIndex(parentA); - int indexB = commonParent->childIndex(parentB); - int minIndex = min(indexA, indexB); - int maxIndex = max(indexA, indexB); - for (int j = minIndex; j <= maxIndex; ++j) - rows->push_back((PropertyRow*)commonParent->childByIndex(j)); - return; - } - commonParent = parentA; - } -} - -bool QPropertyTree::onRowLMBDown(PropertyRow* row, [[maybe_unused]] const QRect& rowRect, QPoint point, bool controlPressed, bool shiftPressed) -{ - pressPoint_ = point; - pressDelta_ = QPoint(0, 0); - pointerMovedSincePress_ = false; - row = model()->root()->hit(this, point); - if (row){ - if (!row->isRoot()) { - if (row->plusRect(this).contains(point) && toggleRow(row)) - return true; - if (row->validatorWarningIconRect(this).contains(point)) { - jumpToNextHiddenValidatorIssue(false, row); - return true; - } - if (row->validatorErrorIconRect(this).contains(point)) { - jumpToNextHiddenValidatorIssue(true, row); - return true; - } - } - - PropertyRow* rowToSelect = row; - while (rowToSelect && !rowToSelect->isSelectable()) - rowToSelect = rowToSelect->parent(); - - if (rowToSelect) { - if (!shiftPressed || !multiSelectable()) { - onRowSelected(std::vector(1, rowToSelect), multiSelectable() && controlPressed, true); - lastSelectedRow_ = rowToSelect; - } - else { - vector rowsToSelect; - - rowsInBetween(&rowsToSelect, lastSelectedRow_, rowToSelect); - onRowSelected(rowsToSelect, false, true); - } - } - } - - PropertyTreeModel::UpdateLock lock = model()->lockUpdate(); - row = model()->root()->hit(this, point); - if (row && !row->isRoot()){ - bool changed = false; - if (row->widgetRect(this).contains(point)) { - DragCheckBegin dragCheck = row->onMouseDragCheckBegin(); - if (dragCheck != DRAG_CHECK_IGNORE) { - dragCheckValue_ = dragCheck == DRAG_CHECK_SET; - dragCheckMode_ = true; - changed = row->onMouseDragCheck(this, dragCheckValue_); - } - } - - if (!dragCheckMode_) { - bool capture = row->onMouseDown(this, point, changed); - if (!changed){ - if (capture) - return true; - else if (row->widgetRect(this).contains(point)){ - if (row->widgetPlacement() != PropertyRow::WIDGET_ICON) - interruptDrag(); - PropertyActivationEvent e; - e.force = false; - e.tree = this; - e.clickPoint = point; - row->onActivate(e); - return false; - } - } - } - } - return false; -} - -void QPropertyTree::onRowLMBUp(PropertyRow* row, [[maybe_unused]] const QRect& rowRect, QPoint point) -{ - onMouseStill(point); - row->onMouseUp(this, point); - - if (!pointerMovedSincePress_ && (pressPoint_ - point).manhattanLength() < 1 && row->widgetRect(this).contains(point)) { - PropertyActivationEvent e; - e.tree = this; - e.clickPoint = point; - e.reason = e.REASON_RELEASE; - row->onActivate(e); - } -} - -void QPropertyTree::onRowRMBDown(PropertyRow* row, [[maybe_unused]] const QRect& rowRect, QPoint point) -{ - SharedPtr handle = row; - PropertyRow* menuRow = 0; - - if (row->isSelectable()){ - menuRow = row; - } - else{ - if (row->parent() && row->parent()->isSelectable()) - menuRow = row->parent(); - } - - if (menuRow) { - onRowSelected(std::vector(1, menuRow), false, true); - QMenu menu(this); - clearMenuHandlers(); - if (onContextMenu(menuRow, menu)) - menu.exec(point); - } -} - -void QPropertyTree::expandParents(PropertyRow* row) -{ - bool hasChanges = false; - typedef std::vector Parents; - Parents parents; - PropertyRow* p = row->nonPulledParent()->parent(); - while (p){ - parents.push_back(p); - p = p->parent(); - } - Parents::iterator it; - for (it = parents.begin(); it != parents.end(); ++it) { - PropertyRow* row = *it; - row->_setExpanded(true); - hasChanges = true; - } - if (hasChanges) { - updateValidatorIcons(); - updateHeights(); - } -} - - -void QPropertyTree::expandAll(PropertyRow* root) -{ - if (!root){ - root = model()->root(); - for (PropertyRows::iterator it = root->begin(); it != root->end(); ++it){ - PropertyRow* row = *it; - row->setExpandedRecursive(this, true); - } - root->setLayoutChanged(); - } - else - root->setExpandedRecursive(this, true); - - for (PropertyRow* r = root; r != 0; r = r->parent()) - r->setLayoutChanged(); - - updateHeights(); -} - -void QPropertyTree::collapseAll(PropertyRow* root) -{ - if (!root){ - root = model()->root(); - - for (PropertyRows::iterator it = root->begin(); it != root->end(); ++it){ - PropertyRow* row = *it; - row->setExpandedRecursive(this, false); - } - } - else{ - root->setExpandedRecursive(this, false); - PropertyRow* row = model()->focusedRow(); - while (row){ - if (root == row){ - model()->selectRow(row, true); - break; - } - row = row->parent(); - } - } - - for (PropertyRow* r = root; r != 0; r = r->parent()) - r->setLayoutChanged(); - - updateHeights(); -} - - -void QPropertyTree::expandRow(PropertyRow* row, bool expanded, bool updateHeights) -{ - bool hasChanges = false; - if (row->expanded() != expanded) { - row->_setExpanded(expanded); - hasChanges = true; - } - - for (PropertyRow* r = row; r != 0; r = r->parent()) - r->setLayoutChanged(); - - if (!row->expanded()){ - PropertyRow* f = model()->focusedRow(); - while (f){ - if (row == f){ - model()->selectRow(row, true); - break; - } - f = f->parent(); - } - } - - if (hasChanges) - updateValidatorIcons(); - if (hasChanges && updateHeights) - this->updateHeights(); -} - -void QPropertyTree::interruptDrag() -{ - dragController_->interrupt(); -} - -void QPropertyTree::updateHeights(bool recalculateTextSize) -{ - QFontMetrics fm(font()); - defaultRowHeight_ = max(16, int(fm.lineSpacing() * 1.666f)); // to fit at least 16x16 icons - - QElapsedTimer timer; - timer.start(); - - model()->root()->updateLabel(this, 0, false); - - QRect widgetRect = this->rect(); - - int scrollBarW = 16; - int lb = 1; - int rb = widgetRect.right() - lb - scrollBarW - 2; - int availableWidth = widgetRect.width() - 4 - scrollBarW; - bool force = recalculateTextSize || lb != leftBorder_ || rb != rightBorder_; - leftBorder_ = lb; - rightBorder_ = rb; - model()->root()->calculateMinimalSize(this, leftBorder_, availableWidth, force, 0, 0, 0); - - updateValidatorIcons(); - - int totalHeight = 0; - model()->root()->adjustVerticalPosition(this, totalHeight); - totalHeight += 4; - QPoint oldSize = size_; - size_.setY(totalHeight); - - updateScrollBar(); - - area_.setLeft(widgetRect.left() + 2); - area_.setRight(widgetRect.right() - 2 - scrollBarW); - area_.setTop(widgetRect.top() + 2); - area_.setBottom(widgetRect.bottom() - 2); - size_.setX(area_.width()); - - int filterAreaHeight = 0; - if (filterMode_) - { - filterAreaHeight = filterEntry_ ? filterEntry_->height() : 0; - area_.setTop(area_.top() + filterAreaHeight + 2 + 2); - } - - _arrangeChildren(); - - int contentHeight = totalHeight + filterAreaHeight + 4; - if (sizeToContent_) - { - setMaximumHeight(contentHeight); - setMinimumHeight(contentHeight); - } - else - { - setMaximumHeight(QWIDGETSIZE_MAX); - setMinimumHeight(0); - } - - update(); - updateHeightsTime_ = aznumeric_cast(timer.elapsed()); - - QSize contentSize = QSize(area_.width(), contentHeight); - if (contentSize_.height() != contentSize.height()) - { - contentSize_ = contentSize; - signalSizeChanged(); - } - else - { - contentSize_ = contentSize; - } -} - -void QPropertyTree::setSizeToContent(bool sizeToContent) -{ - if (sizeToContent != sizeToContent_) - { - sizeToContent_ = sizeToContent; - updateHeights(); - } -} - - -bool QPropertyTree::updateScrollBar() -{ - int pageSize = rect().height(); - offset_.setX(max(0, min(offset_.x(), max(0, size_.x() - area_.right() - 1)))); - offset_.setY(max(0, min(offset_.y(), max(0, size_.y() - pageSize)))); - - if (pageSize < size_.y()) - { - scrollBar_->setRange(0, size_.y() - pageSize); - scrollBar_->setSliderPosition(offset_.y()); - scrollBar_->setPageStep(pageSize); - scrollBar_->show(); - scrollBar_->move(rect().right() - scrollBar_->width(), 0); - scrollBar_->resize(scrollBar_->width(), height()); - return true; - } - else - { - scrollBar_->hide(); - return false; - } -} - -QPoint QPropertyTree::treeSize() const -{ - return size_ + (compact() ? QPoint(0, 0) : QPoint(8, 8)); -} - -void QPropertyTree::onScroll([[maybe_unused]] int pos) -{ - offset_.setY(scrollBar_->sliderPosition()); - _arrangeChildren(); - repaint(); -} - -void QPropertyTree::Serialize(IArchive& ar) -{ - model()->Serialize(ar, this); - - if (ar.IsInput()){ - ensureVisible(model()->focusedRow()); - updateAttachedPropertyTree(false); - updateHeights(); - signalSelected(); - } -} - -void QPropertyTree::ensureVisible(PropertyRow* row, bool update, bool considerChildren) -{ - if (row == 0) - return; - if (row->isRoot()) - return; - - expandParents(row); - - QRect rect = considerChildren ? row->rectIncludingChildren(this) : row->rect(); - if (rect.bottom() > area_.bottom() + offset_.y()){ - offset_.setY(max(0, rect.bottom() - area_.bottom())); - } - if (rect.top() < area_.top() + offset_.y()){ - offset_.setY(max(0, rect.top() - area_.top())); - } - updateScrollBar(); - if (update) - this->update(); -} - -void QPropertyTree::onRowSelected(const std::vector& rows, bool addSelection, bool adjustCursorPos) -{ - for (size_t i = 0; i < rows.size(); ++i) { - PropertyRow* row = rows[i]; - if (!row->isRoot()) { - bool addRowToSelection = !(addSelection && row->selected() && model()->selection().size() > 1) || i > 0; - bool exclusiveSelection = !addSelection && i == 0; - model()->selectRow(row, addRowToSelection, exclusiveSelection); - } - } - if (!rows.empty()) { - ensureVisible(rows.back(), true, false); - if (adjustCursorPos) - cursorX_ = rows.back()->nonPulledParent()->horizontalIndex(this, rows.back()); - } - updateAttachedPropertyTree(false); - signalSelected(); -} - -bool QPropertyTree::attach(const Serialization::SStructs& serializers) -{ - bool changed = false; - if (attached_.size() != serializers.size()) - changed = true; - else { - for (size_t i = 0; i < serializers.size(); ++i) { - if (attached_[i].serializer() != serializers[i]) { - changed = true; - break; - } - } - } - - // We can't perform plain copying here, as it was before: - // attached_ = serializers; - // ...as move forwarder calls copying constructor with non-const argument - // which invokes second templated constructor of Serializer, which is not what we need. - if (changed) { - attached_.assign(serializers.begin(), serializers.end()); - model_->clearUndo(); - } - - revertNoninterrupting(); - - return changed; -} - -void QPropertyTree::attach(const Serialization::SStruct& serializer) -{ - if (attached_.size() != 1 || attached_[0].serializer() != serializer) { - attached_.clear(); - attached_.push_back(Serialization::Object(serializer)); - model_->clearUndo(); - } - revert(); -} - -void QPropertyTree::attach(const Serialization::Object& object) -{ - attached_.clear(); - attached_.push_back(object); - - revert(); -} - -void QPropertyTree::detach() -{ - if (widget_) - widget_.reset(); - attached_.clear(); - model()->root()->clear(); - update(); -} - -int QPropertyTree::revertObjects(vector objectAddresses) -{ - int result = 0; - for (size_t i = 0; i < objectAddresses.size(); ++i) { - if (revertObject(objectAddresses[i])) - ++result; - } - return result; -} - -bool QPropertyTree::revertObject(void* objectAddress) -{ - PropertyRow* row = model()->root()->findByAddress(objectAddress); - if (row && row->isObject()) { - // TODO: - // revertObjectRow(row); - return true; - } - return false; -} - - -void QPropertyTree::revert() -{ - interruptDrag(); - widget_.reset(); - capturedRow_ = 0; - - if (!attached_.empty()) { - validatorBlock_->Clear(); - - QElapsedTimer timer; - timer.start(); - - PropertyOArchive oa(model_.data(), model_->root(), validatorBlock_.data()); - oa.SetOutlineMode(outlineMode_); - if (archiveContext_) - oa.SetInnerContext(archiveContext_); - oa.SetFilter(config_.filter); - - Objects::iterator it = attached_.begin(); - signalAboutToSerialize(oa); - (*it)(oa); - signalSerialized(oa); - - PropertyTreeModel model2; - if (it != attached_.end()) { - while (++it != attached_.end()){ - PropertyOArchive oa2(&model2, model2.root(), validatorBlock_.data()); - oa2.SetOutlineMode(outlineMode_); - Serialization::SContext treeContext(oa2, this); - if (archiveContext_) - oa2.SetInnerContext(archiveContext_); - oa2.SetFilter(config_.filter); - signalAboutToSerialize(oa2); - (*it)(oa2); - signalSerialized(oa2); - model_->root()->intersect(model2.root()); - } - } - revertTime_ = int(timer.elapsed()); - - if (attached_.size() != 1) - validatorBlock_->Clear(); - applyValidation(); - } - else - model_->clear(); - - if (filterMode_) { - if (model_->root()) - model_->root()->updateLabel(this, 0, false); - onFilterChanged(QString()); - } - else { - updateHeights(); - } - - update(); - updateAttachedPropertyTree(true); - - signalReverted(); -} - -struct ValidatorVisitor -{ - ValidatorVisitor(ValidatorBlock* validator) - : validator_(validator) - { - } - - ScanResult operator()(PropertyRow* row, [[maybe_unused]] QPropertyTree* tree, int) - { - const void* rowHandle = row->searchHandle(); - int index = 0; - int count = 0; - Serialization::TypeID typeID = row->typeId(); - if (validator_->FindHandleEntries(&index, &count, rowHandle, typeID)) - { - validator_->MarkAsUsed(index, count); - if (row->setValidatorEntry(index, count)) - row->setLabelChanged(); - } - else - { - if (row->setValidatorEntry(0, 0)) - row->setLabelChanged(); - } - - return SCAN_CHILDREN_SIBLINGS; - } - -protected: - ValidatorBlock* validator_; -}; - -void QPropertyTree::applyValidation() -{ - if (!validatorBlock_->IsEnabled()) - return; - - ValidatorVisitor visitor(validatorBlock_.data()); - model()->root()->scanChildren(visitor, this); - - int rootFirst = 0; - int rootCount = 0; - Serialization::TypeID typeID = model()->root()->typeId(); - // Gather all the items with unknown handle/type pair at root level. - validatorBlock_->MergeUnusedItemsWithRootItems(&rootFirst, &rootCount, model()->root()->searchHandle(), typeID); - model()->root()->setValidatorEntry(rootFirst, rootCount); - model()->root()->setLabelChanged(); -} - -void QPropertyTree::revertNoninterrupting() -{ - if (!capturedRow_) - revert(); -} - -void QPropertyTree::apply(bool continuousUpdate) -{ - QElapsedTimer timer; - timer.start(); - - if (!attached_.empty()) { - Objects::iterator it; - for (it = attached_.begin(); it != attached_.end(); ++it) { - PropertyIArchive ia(model_.data(), model_->root()); - Serialization::SContext treeContext(ia, this); - ia.SetFilter(config_.filter); - if (archiveContext_) - ia.SetInnerContext(archiveContext_); - signalAboutToSerialize(ia); - (*it)(ia); - signalSerialized(ia); - } - } - - if (!continuousUpdate) - signalChanged(); - else - signalContinuousChange(); - applyTime_ = aznumeric_cast(timer.elapsed()); -} - -void QPropertyTree::applyInplaceEditor() -{ - if (widget_) - widget_->commit(); -} - -bool QPropertyTree::spawnWidget(PropertyRow* row, bool ignoreReadOnly) -{ - if (!widget_ || widget_->row() != row || !widget_->actualWidget()->isVisible()){ - interruptDrag(); - setWidget(0); - PropertyRowWidget* newWidget = 0; - if ((ignoreReadOnly && row->userReadOnlyRecurse()) || !row->userReadOnly()) - newWidget = row->createWidget(this); - setWidget(newWidget); - return newWidget != 0; - } - return false; -} - -void QPropertyTree::addMenuHandler(PropertyRowMenuHandler* handler) -{ - menuHandlers_.push_back(handler); -} - -void QPropertyTree::clearMenuHandlers() -{ - for (size_t i = 0; i < menuHandlers_.size(); ++i) - { - PropertyRowMenuHandler* handler = menuHandlers_[i]; - delete handler; - } - menuHandlers_.clear(); -} - -static string quoteIfNeeded(const char* str) -{ - if (!str) - return string(); - if (strchr(str, ' ') != 0) { - string result; - result = "\""; - result += str; - result += "\""; - return result; - } - else { - return string(str); - } -} - -bool QPropertyTree::onContextMenu(PropertyRow* r, QMenu& menu) -{ - SharedPtr row(r); - PropertyTreeMenuHandler* handler = new PropertyTreeMenuHandler(); - addMenuHandler(handler); - handler->tree = this; - handler->row = row; - - PropertyRow::iterator it; - for (it = row->begin(); it != row->end(); ++it){ - PropertyRow* child = *it; - if (child->isContainer() && child->pulledUp()) - child->onContextMenu(menu, this); - } - row->onContextMenu(menu, this); - if (config_.undoEnabled){ - if (!menu.isEmpty()) - menu.addSeparator(); - QAction* undo = menu.addAction("Undo", handler, SLOT(onMenuUndo())); - undo->setEnabled(model()->canUndo()); - undo->setShortcut(QKeySequence("Ctrl+Z")); - - QAction* redo = menu.addAction("Redo", handler, SLOT(onMenuRedo())); - redo->setEnabled(model()->canRedo()); - redo->setShortcut(QKeySequence("Ctrl+Shift+Z")); - } - if (!menu.isEmpty()) - menu.addSeparator(); - - if (!row->userNonCopyable()){ - menu.addAction("Copy", handler, SLOT(onMenuCopy()), QKeySequence("Ctrl+C")); - - if(!row->userReadOnly()){ - QAction* paste = menu.addAction("Paste", handler, SLOT(onMenuPaste()), QKeySequence("Ctrl+V")); - paste->setEnabled(canBePasted(row)); - } - - menu.addSeparator(); - } - - menu.addAction("Filter...", handler, SLOT(onMenuFilter()), QKeySequence("Ctrl+F")); - QMenu* filter = menu.addMenu("Filter by"); - { - string nameFilter = "#"; - nameFilter += quoteIfNeeded(row->labelUndecorated()); - handler->filterName = nameFilter; - filter->addAction((string("Name:\t") + nameFilter).c_str(), handler, SLOT(onMenuFilterByName())); - - string valueFilter = "="; - valueFilter += quoteIfNeeded(row->valueAsString().c_str()); - handler->filterValue = valueFilter; - filter->addAction((string("Value:\t") + valueFilter).c_str(), handler, SLOT(onMenuFilterByValue())); - - string typeFilter = ":"; - typeFilter += quoteIfNeeded(row->typeNameForFilter(this)); - handler->filterType = typeFilter; - filter->addAction((string("Type:\t") + typeFilter).c_str(), handler, SLOT(onMenuFilterByType())); - } - -#if 0 - menu.addSeparator(); - menu.addAction(TRANSLATE("Decompose"), row).connect(this, &QPropertyTree::onRowMenuDecompose); -#endif - return true; -} - -void QPropertyTree::onRowMouseMove(PropertyRow* row, [[maybe_unused]] const QRect& rowRect, QPoint point) -{ - PropertyDragEvent e; - e.tree = this; - e.pos = point; - e.start = pressPoint_; - e.totalDelta = pressDelta_; - row->onMouseDrag(e); - update(); -} - - -bool QPropertyTree::canBePasted(PropertyRow* destination) -{ - SharedPtr source; - if (!propertyRowFromClipboard(source, model_->constStrings())) - return false; - - if (!smartPaste(destination, source, model(), true)) - return false; - return true; -} - -bool QPropertyTree::canBePasted(const char* destinationType) -{ - SharedPtr source; - if (!propertyRowFromClipboard(source, model()->constStrings())) - return false; - - bool result = strcmp(source->typeName(), destinationType) == 0; - return result; -} - -struct DecomposeProxy -{ - DecomposeProxy(SharedPtr& row) : row(row) {} - - void Serialize(IArchive& ar) - { - ar(row, "row", "Row"); - } - - SharedPtr& row; -}; - -void QPropertyTree::onRowMenuDecompose([[maybe_unused]] PropertyRow* row) -{ - // SharedPtr clonedRow = row->clone(); - // DecomposeProxy proxy(clonedRow); - // edit(SStruct(proxy), 0, IMMEDIATE_UPDATE, this); -} - -void QPropertyTree::onModelUpdated([[maybe_unused]] const PropertyRows& rows, bool needApply) -{ - if (widget_) - widget_.reset(); - - if (config_.immediateUpdate){ - if (needApply) - apply(false); - - if (autoRevert_) - revert(); - else { - updateHeights(); - updateAttachedPropertyTree(true); - if (!config_.immediateUpdate) - onSignalChanged(); - } - } - else { - update(); - } -} - -void QPropertyTree::onModelPushUndo([[maybe_unused]] PropertyTreeOperator* op, [[maybe_unused]] bool* handled) -{ - signalPushUndo(); -} - -void QPropertyTree::onModelPushRedo([[maybe_unused]] PropertyTreeOperator* op, [[maybe_unused]] bool* handled) -{ - signalPushRedo(); -} - -void QPropertyTree::setWidget(PropertyRowWidget* widget) -{ - if (widget_){ - widget_->setParent(0); - } - widget_.reset(); - model()->dismissUpdate(); - - if (widget) - { - QWidget* actualWidget = widget->actualWidget(); - if (actualWidget) - { - actualWidget->setParent(this); - actualWidget->setFocus(); - } - - widget_.reset(widget); - _arrangeChildren(); - - if (widget_) - { - widget_->showPopup(); - } - } -} - -bool QPropertyTree::hasFocusOrInplaceHasFocus() const -{ - if (hasFocus()) - return true; - - if (widget_ && widget_->actualWidget() && widget_->actualWidget()->hasFocus()) - return true; - - return false; -} - -void QPropertyTree::setFilterMode(bool inFilterMode) -{ - bool changed = filterMode_ != inFilterMode; - filterMode_ = inFilterMode; - - if (filterMode_) - { - filterEntry_->show(); - filterEntry_->setFocus(); - filterEntry_->selectAll(); - } - else - filterEntry_->hide(); - - if (changed) - { - onFilterChanged(QString()); - } -} - -void QPropertyTree::startFilter(const char* filter) -{ - setFilterMode(true); - filterEntry_->setText(filter); - onFilterChanged(filter); -} - -void QPropertyTree::_arrangeChildren() -{ - if (widget_){ - PropertyRow* row = widget_->row(); - if (row->visible(this)){ - QWidget* w = widget_->actualWidget(); - YASLI_ASSERT(w); - if (w){ - QRect rect = row->widgetRect(this); - rect = QRect(rect.topLeft() - offset_ + area_.topLeft(), - rect.bottomRight() - offset_ + area_.topLeft()); - w->move(rect.topLeft()); - w->resize(rect.size()); - if (!w->isVisible()){ - w->show(); - w->setFocus(); - } - } - else{ - //YASLI_ASSERT(w); - } - } - else{ - widget_.reset(); - } - } - - if (filterEntry_) { - QSize size = rect().size(); - const int padding = 2; - QRect pos(padding, padding, size.width() - padding * 2, filterEntry_->height()); - filterEntry_->move(pos.topLeft()); - filterEntry_->resize(pos.size() - QSize(scrollBar_ ? scrollBar_->width() : 0, 0)); - } -} - - - -void QPropertyTree::setExpandLevels(int levels) -{ - config_.expandLevels = levels; - model()->setExpandLevels(levels); -} - -PropertyRow* QPropertyTree::selectedRow() -{ - const PropertyTreeModel::Selection &sel = model()->selection(); - if (sel.empty()) - return 0; - return model()->rowFromPath(sel.front()); -} - -int QPropertyTree::selectedRowCount() const -{ - return (int)model()->selection().size(); -} - -PropertyRow* QPropertyTree::selectedRowByIndex(int index) -{ - std::vector result; - const PropertyTreeModel::Selection &sel = model()->selection(); - if (size_t(index) >= sel.size()) - return 0; - - return model()->rowFromPath(sel[index]); -} - -bool QPropertyTree::getSelectedObject(Serialization::Object* object) -{ - const PropertyTreeModel::Selection &sel = model()->selection(); - if (sel.empty()) - return 0; - PropertyRow* row = model()->rowFromPath(sel.front()); - while (row && !row->isObject()) - row = row->parent(); - if (!row) - return false; - - if (row->isObject()) { - PropertyRowObject* obj = static_cast(row); - *object = obj->object(); - return true; - } - else { - return false; - } -} - -QPoint QPropertyTree::_toScreen(QPoint point) const -{ - QPoint pt(point.x() - offset_.x() + area_.left(), - point.y() - offset_.y() + area_.top()); - - return mapToGlobal(pt); -} - -bool QPropertyTree::setSelectedRow(PropertyRow* row) -{ - TreeSelection sel; - if (row) - sel.push_back(model()->pathFromRow(row)); - if (model()->selection() != sel) { - model()->setSelection(sel); - if (row) - ensureVisible(row); - updateAttachedPropertyTree(false); - repaint(); - return true; - } - return false; -} - -bool QPropertyTree::selectByAddress(const void* addr, bool keepSelectionIfChildSelected) -{ - if (model()->root()) { - PropertyRow* row = model()->root()->findByAddress(addr); - - bool keepSelection = false; - if (keepSelectionIfChildSelected && row && !model()->selection().empty()) { - keepSelection = true; - TreeSelection::const_iterator it; - for (it = model()->selection().begin(); it != model()->selection().end(); ++it){ - PropertyRow* selectedRow = model()->rowFromPath(*it); - if (!selectedRow) - continue; - if (!selectedRow->isChildOf(row)){ - keepSelection = false; - break; - } - } - } - - if (!keepSelection) - return setSelectedRow(row); - } - return false; -} - -bool QPropertyTree::selectByAddresses(const void* const* addresses, size_t addressCount, bool keepSelectionIfChildSelected) -{ - bool result = false; - if (model()->root()) { - bool keepSelection = false; - vector rows; - for (size_t i = 0; i < addressCount; ++i) { - const void* addr = addresses[i]; - PropertyRow* row = model()->root()->findByAddress(addr); - - if (keepSelectionIfChildSelected && row && !model()->selection().empty()) { - keepSelection = true; - TreeSelection::const_iterator it; - for (it = model()->selection().begin(); it != model()->selection().end(); ++it){ - PropertyRow* selectedRow = model()->rowFromPath(*it); - if (!selectedRow) - continue; - if (!selectedRow->isChildOf(row)){ - keepSelection = false; - break; - } - } - } - - if (row) - rows.push_back(row); - } - - if (!keepSelection) { - TreeSelection sel; - for (size_t j = 0; j < rows.size(); ++j) { - PropertyRow* row = rows[j]; - if (row) - sel.push_back(model()->pathFromRow(row)); - } - if (model()->selection() != sel) { - model()->setSelection(sel); - if (!rows.empty()) - ensureVisible(rows.back()); - update(); - result = true; - if (attachedPropertyTree_) - updateAttachedPropertyTree(false); - } - } - } - return result; -} - -void QPropertyTree::setUndoEnabled(bool enabled, bool full) -{ - config_.undoEnabled = enabled; - config_.fullUndo = full; - model()->setUndoEnabled(enabled); - model()->setFullUndo(full); -} - -void QPropertyTree::attachPropertyTree(QPropertyTree* propertyTree) -{ - if (attachedPropertyTree_) - disconnect(attachedPropertyTree_, SIGNAL(signalChanged()), this, SLOT(onAttachedTreeChanged())); - attachedPropertyTree_ = propertyTree; - if (attachedPropertyTree_) - connect(attachedPropertyTree_, SIGNAL(signalChanged()), this, SLOT(onAttachedTreeChanged())); - updateAttachedPropertyTree(true); -} - -void QPropertyTree::detachPropertyTree() -{ - attachPropertyTree(0); -} - -void QPropertyTree::setAutoHideAttachedPropertyTree(bool autoHide) -{ - autoHideAttachedPropertyTree_ = autoHide; -} - -void QPropertyTree::getSelectionSerializers(Serialization::SStructs* serializers) -{ - TreeSelection::const_iterator i; - for (i = model()->selection().begin(); i != model()->selection().end(); ++i){ - PropertyRow* row = model()->rowFromPath(*i); - if (!row) - continue; - - - while (row && ((row->pulledUp() || row->pulledBefore()) || row->isLeaf())) { - row = row->parent(); - } - if (outlineMode_) { - PropertyRow* topmostContainerElement = 0; - PropertyRow* r = row; - while (r && r->parent()) { - if (r->parent()->isContainer()) - topmostContainerElement = r; - r = r->parent(); - } - if (topmostContainerElement != 0) - row = topmostContainerElement; - } - Serialization::SStruct ser = row->serializer(); - - if (ser) - serializers->push_back(ser); - } -} - -void QPropertyTree::updateAttachedPropertyTree(bool revert) -{ - if (attachedPropertyTree_) { - Serialization::SStructs serializers; - getSelectionSerializers(&serializers); - if (!attachedPropertyTree_->attach(serializers) && revert) - attachedPropertyTree_->revertNoninterrupting(); - if (autoHideAttachedPropertyTree_) - attachedPropertyTree_->setVisible(!serializers.empty()); - } -} - -struct FilterVisitor -{ - const QPropertyTree::RowFilter& filter_; - - FilterVisitor(const QPropertyTree::RowFilter& filter) - : filter_(filter) - { - } - - static void markChildrenAsBelonging(PropertyRow* row, bool belongs) - { - int count = int(row->count()); - for (int i = 0; i < count; ++i) - { - PropertyRow* child = row->childByIndex(i); - child->setBelongsToFilteredRow(belongs); - - markChildrenAsBelonging(child, belongs); - } - } - - static bool hasMatchingChildren(PropertyRow* row) - { - int numChildren = (int)row->count(); - for (int i = 0; i < numChildren; ++i) - { - PropertyRow* child = row->childByIndex(i); - if (!child) - continue; - if (child->matchFilter()) - return true; - if (hasMatchingChildren(child)) - return true; - } - return false; - } - - ScanResult operator()(PropertyRow* row, QPropertyTree* tree) - { - const char* label = row->labelUndecorated(); - Serialization::string value = row->valueAsString(); - - bool matchFilter = filter_.match(label, filter_.NAME_VALUE, 0, 0) || filter_.match(value.c_str(), filter_.NAME_VALUE, 0, 0); - if (matchFilter && filter_.typeRelevant(filter_.NAME)) - filter_.match(label, filter_.NAME, 0, 0); - if (matchFilter && filter_.typeRelevant(filter_.VALUE)) - matchFilter = filter_.match(value.c_str(), filter_.VALUE, 0, 0); - if (matchFilter && filter_.typeRelevant(filter_.TYPE)) - matchFilter = filter_.match(row->typeNameForFilter(tree), filter_.TYPE, 0, 0); - - int numChildren = int(row->count()); - if (matchFilter) { - if (row->pulledBefore() || row->pulledUp()) { - // treat pulled rows as part of parent - PropertyRow* parent = row->parent(); - parent->setMatchFilter(true); - markChildrenAsBelonging(parent, true); - parent->setBelongsToFilteredRow(false); - } - else { - markChildrenAsBelonging(row, true); - row->setBelongsToFilteredRow(false); - row->setLayoutChanged(); - row->setLabelChanged(); - } - } - else { - bool belongs = hasMatchingChildren(row); - row->setBelongsToFilteredRow(belongs); - if (belongs) { - tree->expandRow(row, true, false); - for (int i = 0; i < numChildren; ++i) { - PropertyRow* child = row->childByIndex(i); - if (child->pulledUp()) - child->setBelongsToFilteredRow(true); - } - } - else { - row->_setExpanded(false); - row->setLayoutChanged(); - } - } - - row->setMatchFilter(matchFilter); - return SCAN_CHILDREN_SIBLINGS; - } - -protected: - string labelStart_; -}; - - - -void QPropertyTree::RowFilter::parse(const char* filter) -{ - for (int i = 0; i < NUM_TYPES; ++i) { - start[i].clear(); - substrings[i].clear(); - tillEnd[i] = false; - } - - YASLI_ESCAPE(filter != 0, return); - - vector filterBuf(filter, filter + strlen(filter) + 1); - for (size_t i = 0; i < filterBuf.size(); ++i) - filterBuf[i] = tolower(filterBuf[i]); - - const char* str = &filterBuf[0]; - - Type type = NAME_VALUE; - while (true) - { - bool fromStart = false; - while (*str == '^') { - fromStart = true; - ++str; - } - - const char* tokenStart = str; - - if (*str == '\"') - { - ++str; - while (*str != '\0' && *str != '\"') - ++str; - } - else - { - while (*str != '\0' && *str != ' ' && *str != '=' && *str != ':' && *str != '#') - ++str; - } - if (str != tokenStart) { - if (*tokenStart == '\"' && *str == '\"') { - start[type].assign(tokenStart + 1, str); - tillEnd[type] = true; - ++str; - } - else - { - if (fromStart) - start[type].assign(tokenStart, str); - else - substrings[type].push_back(string(tokenStart, str)); - } - } - while (*str == ' ') - ++str; - if (*str == '#') { - type = NAME; - ++str; - } - else if (*str == '=') { - type = VALUE; - ++str; - } - else if (*str == ':') { - type = TYPE; - ++str; - } - else if (*str == '\0') - break; - } -} - -bool QPropertyTree::RowFilter::match(const char* textOriginal, Type type, size_t* matchStart, size_t* matchEnd) const -{ - YASLI_ESCAPE(textOriginal, return false); - - char* text; - { - size_t textLen = strlen(textOriginal); - text = (char*)alloca((textLen + 1)); - memcpy(text, textOriginal, (textLen + 1)); - for (char* p = text; *p; ++p) - *p = tolower(*p); - } - - const string &startForType = this->start[type]; - if (tillEnd[type]){ - if (startForType == text) { - if (matchStart) - *matchStart = 0; - if (matchEnd) - *matchEnd = startForType.size(); - return true; - } - else - return false; - } - - const vector &substringsForType = this->substrings[type]; - - const char* startPos = text; - - if (matchStart) - *matchStart = 0; - if (matchEnd) - *matchEnd = 0; - if (!startForType.empty()) { - if (strncmp(text, startForType.c_str(), startForType.size()) != 0){ - //_freea(text); - return false; - } - if (matchEnd) - *matchEnd = startForType.size(); - startPos += startForType.size(); - } - - size_t numSubstrings = substringsForType.size(); - for (size_t i = 0; i < numSubstrings; ++i) { - const char* substr = strstr(startPos, substringsForType[i].c_str()); - if (!substr){ - return false; - } - startPos += substringsForType[i].size(); - if (matchStart && i == 0 && startForType.empty()) { - *matchStart = substr - text; - } - if (matchEnd) - *matchEnd = substr - text + substringsForType[i].size(); - } - return true; -} - -void QPropertyTree::onFilterChanged([[maybe_unused]] const QString& text) -{ - QByteArray arr = filterEntry_->text().toLocal8Bit(); - const char* filterStr = filterMode_ ? arr.data() : ""; - rowFilter_.parse(filterStr); - FilterVisitor visitor(rowFilter_); - model()->root()->scanChildrenBottomUp(visitor, this); - updateHeights(); -} - -void QPropertyTree::drawFilteredString(QPainter& p, const wchar_t* text, RowFilter::Type type, const QFont* font, const QRect& rect, const QColor& textColor, bool pathEllipsis, bool center) const -{ - int textLen = (int)wcslen(text); - - if (textLen == 0) - return; - - string textStr(fromWideChar(text)); - QString str(textStr.c_str()); - QFontMetrics fm(*font); - QRect textRect = rect; - int alignment; - if (center) - alignment = Qt::AlignHCenter | Qt::AlignVCenter; - else { - if (pathEllipsis && textRect.width() < fm.horizontalAdvance(str)) - alignment = Qt::AlignRight | Qt::AlignVCenter; - else - alignment = Qt::AlignLeft | Qt::AlignVCenter; - } - - if (filterMode_) { - size_t hiStart = 0; - size_t hiEnd = 0; - bool matched = rowFilter_.match(textStr.c_str(), type, &hiStart, &hiEnd) && hiStart != hiEnd; - if (!matched && (type == RowFilter::NAME || type == RowFilter::VALUE)) - matched = rowFilter_.match(textStr.c_str(), RowFilter::NAME_VALUE, &hiStart, &hiEnd); - if (matched && hiStart != hiEnd) { - QRectF boxFull; - QRectF boxStart; - QRectF boxEnd; - - boxFull = fm.boundingRect(textRect, alignment, str); - - if (hiStart > 0) - boxStart = fm.boundingRect(textRect, alignment, str.left(hiStart)); - else { - boxStart = fm.boundingRect(textRect, alignment, str); - boxStart.setWidth(0.0f); - } - boxEnd = fm.boundingRect(textRect, alignment, str.left(hiEnd)); - - QColor highlightColor, highlightBorderColor; - { - highlightColor = palette().color(QPalette::Highlight); - int h, s, v; - highlightColor.getHsv(&h, &s, &v); - h -= 175; - if (h < 0) - h += 360; - highlightColor.setHsv(h, min(255, int(s * 1.33f)), v, 255); - highlightBorderColor.setHsv(h, aznumeric_cast(s * 0.5f), v, 255); - } - - int left = int(boxFull.left() + boxStart.width()) - 1; - int top = int(boxFull.top()); - int right = int(boxFull.left() + boxEnd.width()); - int bottom = int(boxFull.top() + boxEnd.height()); - QRect highlightRect(left, top, right - left, bottom - top); - QBrush br(highlightColor); - p.setBrush(br); - p.setPen(highlightBorderColor); - bool oldAntialiasing = p.renderHints().testFlag(QPainter::Antialiasing); - p.setRenderHint(QPainter::Antialiasing, true); - - QRect intersectedHighlightRect = rect.intersected(highlightRect); - p.drawRoundedRect(intersectedHighlightRect, 4.0, 4.0); - p.setRenderHint(QPainter::Antialiasing, oldAntialiasing); - } - } - - QBrush textBrush(textColor); - p.setBrush(textBrush); - p.setPen(textColor); - QFont previousFont = p.font(); - p.setFont(*font); - p.drawText(textRect, alignment, str, 0); - p.setFont(previousFont); -} - -void QPropertyTree::_drawRowLabel(QPainter& p, const wchar_t* text, const QFont* font, const QRect& rect, const QColor& textColor) const -{ - drawFilteredString(p, text, RowFilter::NAME, font, rect, textColor, false, false); -} - -void QPropertyTree::_drawRowValue(QPainter& p, const wchar_t* text, const QFont* font, const QRect& rect, const QColor& textColor, bool pathEllipsis, bool center) const -{ - drawFilteredString(p, text, RowFilter::VALUE, font, rect, textColor, pathEllipsis, center); -} - -struct DrawVisitor -{ - DrawVisitor(QPainter& painter, const QRect& area, int scrollOffset, bool selectionPass) - : area_(area) - , painter_(painter) - , offset_(0) - , scrollOffset_(scrollOffset) - , lastParent_(0) - , selectionPass_(selectionPass) - {} - - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, int index) - { - if (row->visible(tree) && ((!row->parent() || (row->parent()->expanded() && !lastParent_)) || row->pulledUp())){ - QRect rect = row->rect(); - if (rect.top() > scrollOffset_ + area_.height()) - lastParent_ = row->parent(); - - int height = row->heightIncludingChildren(); - if ((height == USHRT_MAX || rect.top() + height > scrollOffset_) && rect.width() > 0) - row->drawRow(painter_, tree, index, selectionPass_); - - return SCAN_CHILDREN_SIBLINGS; - } - else - return SCAN_SIBLINGS; - } - -protected: - QPainter& painter_; - QRect area_; - int offset_; - int scrollOffset_; - PropertyRow* lastParent_; - bool selectionPass_; -}; - -QSize QPropertyTree::sizeHint() const -{ - if (sizeToContent_) - return minimumSize(); - else - return sizeHint_; -} - -bool QPropertyTree::event(QEvent* ev) -{ - if (ev->type() == QEvent::ShortcutOverride) - { - if (!widget_) - { - PropertyRow* row = model()->focusedRow(); - if (row) - { - QKeyEvent* keyEvent = static_cast(ev); - bool keyWillBeProcessed = false; - - int modifiedKey = keyEvent->key() | keyEvent->modifiers(); - switch (modifiedKey) - { - case (Qt::Key_F | Qt::CTRL): - case Qt::Key_Escape: - keyWillBeProcessed = true; - break; - - default: - keyWillBeProcessed = rowProcessesKey(row, keyEvent); - break; - } - - if (keyWillBeProcessed) - { - ev->accept(); - return true; - } - } - } - } - - return QWidget::event(ev); -} - -void QPropertyTree::paintEvent([[maybe_unused]] QPaintEvent* ev) -{ - QElapsedTimer timer; - timer.start(); - QPainter painter(this); - QRect clientRect = this->rect(); - - int clientHeight = clientRect.height(); - backgroundColor_ = palette().color(QPalette::Window); - painter.fillRect(clientRect, QBrush(backgroundColor_)); - - painter.translate(-offset_.x(), -offset_.y()); - - if (dragController_->captured()) - dragController_->drawUnder(painter); - - painter.translate(area_.left(), area_.top()); - - if (model()->root()) { - DrawVisitor selectionOp(painter, area_, offset_.y(), true); - model()->root()->scanChildren(selectionOp, this); - - DrawVisitor op(painter, area_, offset_.y(), false); - op(model()->root(), this, 0); - model()->root()->scanChildren(op, this); - } - - painter.translate(-area_.left(), -area_.top()); - painter.translate(offset_.x(), offset_.y()); - - //painter.setClipRect(rect()); - - if (size_.y() > clientHeight) - { - const int shadowHeight = int(_defaultRowHeight() * 0.3f); - QColor color1(0, 0, 0, 0); - QColor color2(0, 0, 0, 96); - - int visibleAreaWidth = area_.width() + 5; - - QRect upperRect(rect().left() + 1, rect().top(), visibleAreaWidth - 2, shadowHeight); - QLinearGradient upperGradient(upperRect.left(), upperRect.top(), upperRect.left(), upperRect.bottom()); - upperGradient.setColorAt(0.0f, color2); - upperGradient.setColorAt(1.0f, color1); - painter.fillRect(upperRect, QBrush(upperGradient)); - - QLinearGradient upperEdgeGradient(upperRect.left(), upperRect.top(), upperRect.left(), upperRect.bottom() + shadowHeight); - upperEdgeGradient.setColorAt(0.0f, color2); - upperEdgeGradient.setColorAt(1.0f, color1); - painter.fillRect(QRect(rect().left(), rect().top(), 1, shadowHeight * 2 + 1), QBrush(upperEdgeGradient)); - painter.fillRect(QRect(visibleAreaWidth - 1, rect().top(), 1, shadowHeight * 2 + 1), QBrush(upperEdgeGradient)); - - QRect lowerRect(rect().left() + 1, rect().bottom() - shadowHeight / 2, visibleAreaWidth - 2, shadowHeight / 2 + 1); - QLinearGradient lowerGradient(lowerRect.left(), lowerRect.top(), lowerRect.left(), lowerRect.bottom()); - lowerGradient.setColorAt(0.0f, color1); - lowerGradient.setColorAt(1.0f, color2); - QBrush lowerBrush(lowerGradient); - painter.fillRect(lowerRect, lowerGradient); - - QLinearGradient lowerEdgeGradient(lowerRect.left(), lowerRect.top() - shadowHeight, lowerRect.left(), lowerRect.bottom()); - lowerEdgeGradient.setColorAt(0.0f, color1); - lowerEdgeGradient.setColorAt(1.0f, color2); - painter.fillRect(QRect(rect().left(), rect().bottom() - shadowHeight * 2, 1, shadowHeight * 2 + 1), QBrush(lowerEdgeGradient)); - painter.fillRect(QRect(visibleAreaWidth - 1, rect().bottom() - shadowHeight * 2, 1, shadowHeight * 2 + 1), QBrush(lowerEdgeGradient)); - } - - if (dragController_->captured()) { - painter.translate(-offset_); - dragController_->drawOver(painter); - painter.translate(offset_); - } - else{ - // if(model()->focusedRow() != 0 && model()->focusedRow()->isRoot() && tree_->hasFocus()){ - // clientRect.left += 2; clientRect.top += 2; - // clientRect.right -= 2; clientRect.bottom -= 2; - // DrawFocusRect(dc, &clientRect); - // } - } - paintTime_ = aznumeric_cast(timer.elapsed()); -} - -QPropertyTree::HitTest QPropertyTree::hitTest(PropertyRow* row, const QPoint& pointInWindowSpace, const QRect& rowRect) -{ - QPoint point = pointToRootSpace(pointInWindowSpace); - - if (!row->hasVisibleChildren(this) && row->plusRect(this).contains(point)) - return TREE_HIT_PLUS; - - if (row->textRect(this).contains(point)) - return TREE_HIT_TEXT; - - if (rowRect.contains(point)) - return TREE_HIT_ROW; - - return TREE_HIT_NONE; - -} - -PropertyRow* QPropertyTree::rowByPoint(const QPoint& pt) -{ - if (!model_->root()) - return 0; - if (!area_.contains(pt)) - return 0; - return model_->root()->hit(this, pointToRootSpace(pt)); -} - -QPoint QPropertyTree::pointToRootSpace(const QPoint& point) const -{ - return QPoint(point.x() + offset_.x() - area_.left(), point.y() + offset_.y() - area_.top()); -} - -QPoint QPropertyTree::pointFromRootSpace(const QPoint& point) const -{ - return QPoint(point.x() - offset_.x() + area_.left(), point.y() - offset_.y() + area_.top()); -} - - -void QPropertyTree::moveEvent(QMoveEvent* ev) -{ - QWidget::moveEvent(ev); -} - -void QPropertyTree::resizeEvent(QResizeEvent* ev) -{ - QWidget::resizeEvent(ev); - - updateHeights(); -} - -void QPropertyTree::mousePressEvent(QMouseEvent* ev) -{ - //QWidget::mousePressEvent(ev); - setFocus(Qt::MouseFocusReason); - - if (ev->button() == Qt::LeftButton) - { - PropertyRow* row = rowByPoint(ev->pos()); - if (row && !row->isSelectable()) - row = row->parent(); - if (row){ - if (onRowLMBDown(row, row->rect(), pointToRootSpace(ev->pos()), ev->modifiers().testFlag(Qt::ControlModifier), ev->modifiers().testFlag(Qt::ShiftModifier))) { - capturedRow_ = row; - lastStillPosition_ = pointToRootSpace(ev->pos()); - } - else if (!dragCheckMode_){ - row = rowByPoint(ev->pos()); - PropertyRow* draggedRow = row; - while (draggedRow && (!draggedRow->isSelectable() || draggedRow->pulledUp() || draggedRow->pulledBefore())) - draggedRow = draggedRow->parent(); - if (draggedRow && !draggedRow->userReadOnly() && !widget_){ - dragController_->beginDrag(row, draggedRow, ev->globalPos()); - } - } - } - update(); - } - else if (ev->button() == Qt::RightButton) - { - QPoint point = ev->pos(); - PropertyRow* row = rowByPoint(point); - if (row){ - model()->setFocusedRow(row); - update(); - - onRowRMBDown(row, row->rect(), _toScreen(pointToRootSpace(point))); - } - else{ - QRect rect = this->rect(); - onRowRMBDown(model()->root(), rect, _toScreen(pointToRootSpace(point))); - } - } - else if (ev->button() == Qt::MiddleButton) - { - QPoint point = ev->pos(); - PropertyRow* row = rowByPoint(point); - if (row){ - switch (hitTest(row, point, row->rect())){ - case TREE_HIT_PLUS: - break; - case TREE_HIT_NONE: - default: - model()->setFocusedRow(row); - update(); - break; - } - - } - } -} - -void QPropertyTree::mouseReleaseEvent(QMouseEvent* ev) -{ - QWidget::mouseReleaseEvent(ev); - - if (ev->button() == Qt::LeftButton) - { - if (dragController_->captured()){ - if (dragController_->drop(QCursor::pos())) - updateHeights(); - else - update(); - } - if (dragCheckMode_) { - dragCheckMode_ = false; - } - else { - QPoint point = ev->pos(); - if (capturedRow_){ - QRect rowRect = capturedRow_->rect(); - onRowLMBUp(capturedRow_, rowRect, pointToRootSpace(ev->pos())); - mouseStillTimer_->stop(); - capturedRow_ = 0; - update(); - } - } - } - else if (ev->button() == Qt::RightButton) - { - - } - - unsetCursor(); -} - -void QPropertyTree::focusInEvent(QFocusEvent* ev) -{ - QWidget::focusInEvent(ev); - widget_.reset(); -} - -void QPropertyTree::keyPressEvent(QKeyEvent* ev) -{ - // NOTE: if you add any new key processing in here, make sure you update QPropertyTree::event() to handle - // it in the ShortcutOverride event. Otherwise, MainWindow/other shortcuts might take priority and eat it before - // it reaches this function. - - if (ev->key() == Qt::Key_F && ev->modifiers() == Qt::CTRL) { - setFilterMode(true); - } - - if (filterMode_) { - if (ev->key() == Qt::Key_Escape && ev->modifiers() == Qt::NoModifier) { - setFilterMode(false); - } - } - - bool result = false; - if (!widget_) { - PropertyRow* row = model()->focusedRow(); - if (row) - onRowKeyDown(row, ev); - } - update(); - if (!result) - QWidget::keyPressEvent(ev); -} - - -void QPropertyTree::mouseDoubleClickEvent(QMouseEvent* ev) -{ - QWidget::mouseDoubleClickEvent(ev); - - QPoint point = ev->pos(); - PropertyRow* row = rowByPoint(point); - if (row){ - PropertyActivationEvent e; - e.tree = this; - e.force = true; - e.reason = e.REASON_DOUBLECLICK; - PropertyRow* nonPulledParent = row; - while (nonPulledParent && nonPulledParent->pulledUp()) - nonPulledParent = nonPulledParent->parent(); - - if (row->widgetRect(this).contains(pointToRootSpace(point))){ - if (!row->onActivate(e)) - toggleRow(nonPulledParent); - } - else if (!toggleRow(row)) { - if (!row->onActivate(e)) - if (!toggleRow(nonPulledParent)) { - // activate first visible inline row - for (size_t i = 0; i < row->count(); ++i) { - PropertyRow* child = row->childByIndex(i); - if (child && child->pulledUp() && child->visible(this)) { - child->onActivate(e); - break; - } - } - } - } - } -} - -void QPropertyTree::onMouseStillTimeout() -{ - onMouseStill(mapFromGlobal(QCursor::pos())); -} - -void QPropertyTree::onMouseStill(QPoint point) -{ - if (capturedRow_) { - PropertyDragEvent e; - e.tree = this; - e.pos = point; - e.start = pressPoint_; - - capturedRow_->onMouseStill(e); - lastStillPosition_ = e.pos; - } -} - -void QPropertyTree::flushAggregatedMouseEvents() -{ - if (aggregatedMouseEventCount_ > 0) { - bool gotPendingEvent = aggregatedMouseEventCount_ > 1; - aggregatedMouseEventCount_ = 0; - if (gotPendingEvent && lastMouseMoveEvent_.data()) - mouseMoveEvent(lastMouseMoveEvent_.data()); - } -} - -void QPropertyTree::mouseMoveEvent(QMouseEvent* ev) -{ - if (ev->type() == QEvent::MouseMove && aggregateMouseEvents_) { - lastMouseMoveEvent_.reset(new QMouseEvent(QEvent::MouseMove, ev->localPos(), ev->windowPos(), ev->screenPos(), ev->button(), ev->buttons(), ev->modifiers())); - ev = lastMouseMoveEvent_.data(); - ++aggregatedMouseEventCount_; - if (aggregatedMouseEventCount_ > 1) - return; - } - - QCursor newCursor = QCursor(Qt::ArrowCursor); - QString newToolTip; - if (dragController_->captured() && !ev->buttons().testFlag(Qt::LeftButton)) - dragController_->interrupt(); - if (dragController_->captured()){ - QPoint pos = QCursor::pos(); - if (dragController_->dragOn(pos)) { - // SetCapture - } - update(); - } - else{ - QPoint point = ev->pos(); - PropertyRow* row = rowByPoint(point); - if (row && dragCheckMode_ && row->widgetRect(this).contains(pointToRootSpace(point))) { - row->onMouseDragCheck(this, dragCheckValue_); - } - else if (capturedRow_){ - onRowMouseMove(capturedRow_, QRect(), pointToRootSpace(point)); - if (config_.sliderUpdateDelay >= 0 && !mouseStillTimer_->isActive()) - mouseStillTimer_->start(config_.sliderUpdateDelay); - - if (cursor().shape() == Qt::BlankCursor) - { - pressDelta_ += pointToRootSpace(ev->pos()) - pressPoint_; - pointerMovedSincePress_ = true; - AzQtComponents::SetCursorPos(mapToGlobal(pointFromRootSpace(pressPoint_))); - } - else - { - pressDelta_ = pointToRootSpace(ev->pos()) - pressPoint_; - } - } - - PropertyRow* hoverRow = row; - if (capturedRow_) - hoverRow = capturedRow_; - PropertyHoverInfo hover; - if (hoverRow) { - QPoint pointInRootSpace = pointToRootSpace(point); - if (hoverRow->getHoverInfo(&hover, pointInRootSpace, this)) { - newCursor = hover.cursor; - newToolTip = hover.toolTip; - - PropertyRow* tooltipRow = hoverRow; - while (newToolTip.isEmpty() && tooltipRow->parent() && (tooltipRow->pulledUp() || tooltipRow->pulledBefore())) { - // check if parent of inlined property has a tooltip instead - tooltipRow = tooltipRow->parent(); - if (tooltipRow->getHoverInfo(&hover, pointInRootSpace, this)) - newToolTip = hover.toolTip; - } - } - - if (hoverRow->validatorWarningIconRect(this).contains(pointToRootSpace(point))) { - newCursor = QCursor(Qt::PointingHandCursor); - newToolTip = "Jump to next warning"; - } - if (hoverRow->validatorErrorIconRect(this).contains(pointToRootSpace(point))) { - newCursor = QCursor(Qt::PointingHandCursor); - newToolTip = "Jump to next error"; - } - } - } - setCursor(newCursor); - if (toolTip() != newToolTip) - setToolTip(newToolTip); - if (newToolTip.isEmpty()) - QToolTip::hideText(); -} - -void QPropertyTree::wheelEvent(QWheelEvent* ev) -{ - QWidget::wheelEvent(ev); - - float delta = ev->angleDelta().ry() / 360.0f; - if (ev->modifiers() & Qt::CTRL) { - if (delta > 0) - zoomLevel_ += 1; - else - zoomLevel_ -= 1; - if (zoomLevel_ < 8) - zoomLevel_ = 8; - if (zoomLevel_ > 30) - zoomLevel_ = 30; - float scale = zoomLevel_ * 0.1f; - QFont font; - font.setPointSizeF(font.pointSizeF() * scale); - setFont(font); - font.setBold(true); - boldFont_ = font; - - updateHeights(true); - } - else { - if (scrollBar_->isVisible() && scrollBar_->isEnabled()) - scrollBar_->setValue(scrollBar_->value() + -ev->angleDelta().y()); - } -} - -bool QPropertyTree::toggleRow(PropertyRow* row) -{ - if (!row->canBeToggled(this)) - return false; - expandRow(row, !row->expanded()); - updateHeights(); - return true; -} - -bool QPropertyTree::_isDragged(const PropertyRow* row) const -{ - if (!dragController_->dragging()) - return false; - if (dragController_->draggedRow() == row) - return true; - return false; -} - -bool QPropertyTree::_isCapturedRow(const PropertyRow* row) const -{ - return capturedRow_ == row; -} - -void QPropertyTree::setValueColumnWidth(float valueColumnWidth) -{ - if (style_->valueColumnWidth != valueColumnWidth) - { - style_->valueColumnWidth = valueColumnWidth; - updateHeights(); - update(); - } -} - -QPropertyTree::QPropertyTree(const QPropertyTree&) -{ -} - - -QPropertyTree& QPropertyTree::operator=(const QPropertyTree&) -{ - return *this; -} - -void QPropertyTree::onAttachedTreeChanged() -{ - revert(); -} - -struct ValidatorIconVisitor -{ - ScanResult operator()(PropertyRow* row, QPropertyTree* tree, int) - { - row->resetValidatorIcons(); - if (row->validatorCount()) { - bool hasErrors = false; - bool hasWarnings = false; - if (const ValidatorEntry* validatorEntries = tree->_validatorBlock()->GetEntry(row->validatorIndex(), row->validatorCount())) { - for (int i = 0; i < row->validatorCount(); ++i) { - const ValidatorEntry* validatorEntry = validatorEntries + i; - if (validatorEntry->type == VALIDATOR_ENTRY_ERROR) - hasErrors = true; - else if (validatorEntry->type == VALIDATOR_ENTRY_WARNING) - hasWarnings = true; - } - } - - if (hasErrors || hasWarnings) - { - PropertyRow* lastClosedParent = 0; - PropertyRow* current = row->parent(); - bool lastWasPulled = row->pulledUp() || row->pulledBefore(); - while (current && current->parent()) { - if (!current->expanded() && !lastWasPulled && current->visible(tree)) - lastClosedParent = current; - lastWasPulled = current->pulledUp() || current->pulledBefore(); - current = current->parent(); - } - if (lastClosedParent) - lastClosedParent->addValidatorIcons(hasWarnings, hasErrors); - } - } - return SCAN_CHILDREN_SIBLINGS; - } -}; - -void QPropertyTree::updateValidatorIcons() -{ - if (!validatorBlock_->IsEnabled()) - return; - ValidatorIconVisitor op; - model()->root()->scanChildren(op, this); - model()->root()->setLabelChangedToChildren(); -} - -void QPropertyTree::setTreeStyle(const QPropertyTreeStyle& style) -{ - *style_ = style; - updateHeights(true); -} - -void QPropertyTree::setPackCheckboxes(bool pack) -{ - style_->packCheckboxes = pack; - updateHeights(true); -} - -bool QPropertyTree::packCheckboxes() const -{ - return style_->packCheckboxes; -} - -void QPropertyTree::setCompact(bool compact) -{ - style_->compact = compact; - update(); -} - -bool QPropertyTree::compact() const -{ - return style_->compact; -} - -void QPropertyTree::setRowSpacing(float rowSpacing) -{ - style_->rowSpacing = rowSpacing; -} - -float QPropertyTree::rowSpacing() const -{ - return style_->rowSpacing; -} - -float QPropertyTree::valueColumnWidth() const -{ - return style_->valueColumnWidth; -} - -void QPropertyTree::setFullRowMode(bool fullRowMode) -{ - style_->fullRowMode = fullRowMode; - update(); -} - -bool QPropertyTree::fullRowMode() const -{ - return style_->fullRowMode; -} - -bool QPropertyTree::containsErrors() const -{ - return validatorBlock_->ContainsErrors(); -} - -void QPropertyTree::focusFirstError() -{ - jumpToNextHiddenValidatorIssue(true, model()->root()); -} - -void QPropertyTree::setBackgroundColor(const QColor& backgroundColor) -{ - backgroundColor_ = backgroundColor; -} - -#include -#include - -// vim:ts=4 sw=4: diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTree.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTree.h deleted file mode 100644 index e5c6caec99..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTree.h +++ /dev/null @@ -1,528 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYTREE_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYTREE_H -#pragma once - - - -#if !defined(Q_MOC_RUN) -#include "../EditorCommonAPI.h" -#include "ConstStringList.h" -#include "ValidatorBlock.h" -#include -#include "Serialization/Serializer.h" -#include "Serialization/IArchive.h" -#include "Serialization/Pointers.h" -#include "Serialization/Object.h" -#include "PropertyRow.h" -#include -#include -#endif - -namespace Serialization -{ - struct SContextLink; - class IClassFactory; -} - -class QMenu; -class QLineEdit; -class QScrollBar; - -struct Color; -class TreeImpl; -class PropertyTreeModel; -class PopupMenuItem; -class PropertyTreeModel; -class PropertyRow; -class PropertyRowWidget; -class PropertyTreeOperator; -class Entry; -struct IconXPMCache; - - -// --------------------------------------------------------------------------- -struct QPropertyTreeStyle; -struct PropertyTreeConfig -{ - bool immediateUpdate; - bool hideUntranslated; - bool showContainerIndices; - bool showContainerIndexLabels; - bool containerIndicesZeroBased; - bool filterWhenType; - int filter; - int sliderUpdateDelay; - int expandLevels; - bool undoEnabled; - bool fullUndo; - bool multiSelection; - bool copyPasteEnabled; - - PropertyTreeConfig() - : immediateUpdate(true) - , hideUntranslated(true) - , showContainerIndices(true) - , showContainerIndexLabels(false) - , containerIndicesZeroBased(true) - , filterWhenType(true) - , filter(0) - , sliderUpdateDelay(25) - , undoEnabled(true) - , fullUndo(true) - , multiSelection(true) - , copyPasteEnabled(true) - { - } -}; - -// --------------------------------------------------------------------------- - -struct PropertyRowMenuHandler; - -class DragWindow : public QWidget -{ - Q_OBJECT -public: - DragWindow(QPropertyTree* tree); - - void set(QPropertyTree* tree, PropertyRow* row, const QRect& rowRect); - void setWindowPos(bool visible); - void show(); - void move(int deltaX, int deltaY); - void hide(); - - void drawRow(QPainter& p); - void paintEvent(QPaintEvent* ev); - -protected: - bool useLayeredWindows_; - PropertyRow* row_; - QRect rect_; - QPropertyTree* tree_; - QPoint offset_; -}; - -class EDITOR_COMMON_API QPropertyTree : public QWidget -{ - Q_OBJECT -public: - explicit QPropertyTree(QWidget* parent = nullptr); - ~QPropertyTree(); - - // Used to attach an object to a PropertyTree widget. Attached object should implement - // Serialize method. Example of usage: - // - // struct MyType - // { - // void Serialize(Serialization::IArchive& ar); - // }; - // MyType object; - // - // propertyTree->attach(Serialization::SStruct(object)); - // - // Attached object will be serialized through PropertyOArchive to populate the tree. On - // every input made to the tree attached object will be deserialized through - // PropertyIArchive and serialized back again through PropertyOArchive to make sure that - // tree content is up-to-date. - // Property archives can be identified by calling ar.IsEdit(). - // SStruct stores a pointer to an actual object that should either outlive property tree - // or be detached on destruction. - void attach(const Serialization::SStruct& serializer); - // This form attaches an array of SStruct-s. This is used to edit multiple objects - // simultaneously. Only shared properties will be shown (i.e. intersection of all - // properties). Properties with different values will be shown as "..." or a gray - // checkbox. - bool attach(const Serialization::SStructs& serializers); - // Used for two-trees setup. In this case leader tree acts as an outliner, that shows - // top level of the data (either by using setOutlineMode or setting different filter). - // Attached, follower tree then shows properties ot the item selected in the main tree. - // Temporary structures (e.g. created on the stack) should not be used in this mode - // (except for decorators), as this may cause access to deallocated object when - // selecting it in the tree. - void attachPropertyTree(QPropertyTree* propertyTree); - void detachPropertyTree(); - void setAutoHideAttachedPropertyTree(bool autoHide); - // Effectively clears the tree. - void detach(); - bool attached() const { return !attached_.empty(); } - - // Forces serialization of attached object to update properties. Can be used to update - // property tree when attached object was changed for some reason. - void revert(); - // Same as revert(), except that it will but interrupt editing or mouse action in - // progress. - void revertNoninterrupting(); - // Forces deserialization of attached objects from property items. - void apply(bool continuousUpdate); - // Useful to apply edit boxes that are being edited at the moment. - // May be needed when click on toolbar button doesn't steal the focus, leaving input - // data effectively not saved. - void applyInplaceEditor(); - - // Reduces width of the tree by removing expansion arrow/plus on the first level of the - // tree (first level is always expanded). - void setCompact(bool compact); - bool compact() const; - // Puts checkboxes into two columns when possible. - void setPackCheckboxes(bool pack); - bool packCheckboxes() const; - // Changes distance between rows, multiplier of row height. - void setRowSpacing(float rowSpacing); - float rowSpacing() const; - // Sets default width of the value column, 0..1 (relative to widget width) - void setValueColumnWidth(float valueColumnWidth); - float valueColumnWidth() const; - // Allows to override background color, useful when placing on tabs or panels that have - // have different background. - void setBackgroundColor(const QColor& color); - const QColor& backgroundColor() const { return backgroundColor_; } - // Set number of levels to be expanded by default. Note that this function should be - // invoked before first call to attach attach() to have an effect. - void setExpandLevels(int levels); - // Can be used to control if container(array) elements have numbered labels. - void setShowContainerIndices(bool showContainerIndices) { config_.showContainerIndices = showContainerIndices; } - bool showContainerIndices() const{ return config_.showContainerIndices; } - // Can be used to control if container(array) elements should prepend the number to the existing label - void setShowContainerIndexLabels(bool showContainerIndexLabels) { config_.showContainerIndexLabels = showContainerIndexLabels; } - bool showContainerIndexLabels() const{ return config_.showContainerIndexLabels; } - // Can be used to control if container(array) elements should be zero- (default) or one-based - void setContainerIndicesZeroBased(bool containerIndicesZeroBased) { config_.containerIndicesZeroBased = containerIndicesZeroBased; } - bool containerIndicesZeroBased() const{ return config_.containerIndicesZeroBased; } - // Allows control of copy/paste functionality - void setCopyPasteEnabled(bool copyPasteEnabled) { config_.copyPasteEnabled = copyPasteEnabled; } - bool copyPasteEnabled() const{ return config_.copyPasteEnabled; } - - // Limits the rate at which sliders emit change signal. - void setSliderUpdateDelay(int delayMS) { config_.sliderUpdateDelay = delayMS; } - - // Limit number of mouse-movement updates per-frame. Used to prevent large tree updates - // from draining all the idle time. - void setAggregateMouseEvents(bool aggregate) { aggregateMouseEvents_ = aggregate; } - void flushAggregatedMouseEvents(); - - // Can be used to disable internal undo. - void setUndoEnabled(bool enabled, bool full = false); - // This can be used to disable automatic serialization after each deserialization call. - // May be useful to prevent double-revert when signalChange is connected to some - // external data model, which fires an event that reverts tree automatically. - void setAutoRevert(bool autoRevert) { autoRevert_ = autoRevert; } - // Default size. - void setSizeHint(const QSize& size) { sizeHint_ = size; } - // Sets minimal size of the widget to the size of the visible content of the tree. - void setSizeToContent(bool sizeToContent); - bool sizeToContent() const{ return sizeToContent_; } - // Retrieves size of the content, doesn't require sizeToContent to be set. - QSize contentSize() const{ return contentSize_; } - // When set filtering is started just by typing in the property tree - void setFilterWhenType(bool filterWhenType) { config_.filterWhenType = filterWhenType; } - - // Outline mode hides content of the elements of the container (excepted for - // inlined/pulled-up properties). Can be used together with second property - // tree through attachPropertyTree. - void setOutlineMode(bool outlineMode) { outlineMode_ = outlineMode; } - bool outlineMode() const{ return outlineMode_; } - // Hide selection when widget is out of focus. Disables selection for parent of inline items. - void setHideSelection(bool hideSelection) { hideSelection_ = hideSelection; } - bool hideSelection() const{ return hideSelection_; } - // Can be used to disable selection of multiple properties at the same time. - void setMultiSelection(bool multiSelection) { config_.multiSelection = multiSelection; } - bool multiSelection() const{ return config_.multiSelection; } - - // Sets head of the context-list. Can be used to pass additional data to nested decorators. - void setArchiveContext(Serialization::SContextLink* context) { archiveContext_ = context; } - // Sets archive filter. Filter is a bit mask stored within archive that can be used to - // affect behavior of serialization. For example one can have two trees that shows - // different portions of the same object. - void setFilter(int filter) { config_.filter = filter; } - - // This methods returns array of SStruct-s for all selected properties. - // This is useful for manual implementation of attachPropertyTree behavior - // with type filtering or special logic. - void getSelectionSerializers(Serialization::SStructs* serializers); - // Can be used to select once serialized object(s) in the tree. - bool selectByAddress(const void*, bool keepSelectionIfChildSelected = false); - bool selectByAddresses(const void* const* addresses, size_t addressCount, bool keepSelectionIfChildSelected); - // Can be used to query information about selection in the tree. - bool setSelectedRow(PropertyRow* row); - PropertyRow* selectedRow(); - int selectedRowCount() const; - PropertyRow* selectedRowByIndex(int index); - - // Reports if serialized data contains errors. Errors are reported - // through IArchive::Error() method. - bool containsErrors() const; - void focusFirstError(); - - void ensureVisible(PropertyRow* row, bool update = true, bool considerChildren = true); - void expandRow(PropertyRow* row, bool expanded = true, bool updateHeights = true); - - // PropertyTreeStyle used to customize visual appearance of the property tree - const QPropertyTreeStyle& treeStyle() const{ return *style_; } - void setTreeStyle(const QPropertyTreeStyle& style); - - // Config used to store behavioral settings - const PropertyTreeConfig& config() const{ return config_; } - - // Instance of PropertyTree can be serialized. In this case the expansion state - // of the rows and list of selected rows will be saved (not the property values). - void Serialize(Serialization::IArchive& ar); - - // OBSOLETE: Serialization::Object will be gone - void attach(const Serialization::Object& object); - int revertObjects(vector objectAddresses); - bool revertObject(void* objectAddress); -signals: - // Emited for every finished changed of the value. E.g. when you drag a slider, - // signalChanged will be invoked when you release a mouse button. - void signalChanged(); - // Used fast-pace changes, like movement of the slider before mouse gets released. - void signalContinuousChange(); - // Invoked whenever selection changed. - void signalSelected(); - // Invoked after each revert() call (can be caused by user intput). - void signalReverted(); - // Invoked before any change is going to occur and can be used to store current version - // of data for own undo stack. - void signalPushUndo(); - void signalPushRedo(); - - // Called before and after serialization is invoked. Can be used to update context list - // in archive. - void signalAboutToSerialize(Serialization::IArchive& ar); - void signalSerialized(Serialization::IArchive& ar); - - // OBSOLETE: do not use - void signalObjectChanged(const Serialization::Object& obj); - - // Called when visual size of the tree changes, i.e. when things are deserialized and - // and when rows are expanded/collapsed. - void signalSizeChanged(); - - // Called when undo/redo are triggered via keyboard shortcut - void signalUndo(); - void signalRedo(); -public slots: - void expandAll(PropertyRow* root = 0); - void collapseAll(PropertyRow* root = 0); - void onAttachedTreeChanged(); -public: - // internal methods: - void setFullRowMode(bool fullRowMode); - bool fullRowMode() const; - void setHideUntranslated(bool hideUntranslated) { config_.hideUntranslated = hideUntranslated; } - bool hideUntranslated() const{ return config_.hideUntranslated; } - void setImmediateUpdate(bool immediateUpdate) { config_.immediateUpdate = immediateUpdate; } - bool immediateUpdate() const{ return config_.immediateUpdate; } - int _defaultRowHeight() const { return defaultRowHeight_; } - PropertyTreeModel* model() { return model_.data(); } - const PropertyTreeModel* model() const { return model_.data(); } - - QPoint treeSize() const; - int leftBorder() const { return leftBorder_; } - int rightBorder() const { return rightBorder_; } - bool multiSelectable() const { return attachedPropertyTree_ != 0 || config_.multiSelection; } - void expandParents(PropertyRow* row); - bool spawnWidget(PropertyRow* row, bool ignoreReadOnly); - bool getSelectedObject(Serialization::Object* object); - void onSignalChanged() { signalChanged(); } - - void onRowSelected(const std::vector& row, bool addSelection, bool adjustCursorPos); - const ValidatorBlock* _validatorBlock() const { return validatorBlock_.data(); } - QPoint _toScreen(QPoint point) const; - void _cancelWidget(){ widget_.reset(); } - void _drawRowLabel(QPainter& p, const wchar_t* text, const QFont* font, const QRect& rect, const QColor& color) const; - void _drawRowValue(QPainter& p, const wchar_t* text, const QFont* font, const QRect& rect, const QColor& color, bool pathEllipsis, bool center) const; - QRect _visibleRect() const; - bool _isDragged(const PropertyRow* row) const; - bool _isCapturedRow(const PropertyRow* row) const; - PropertyRow* _pressedRow() const { return pressedRow_; } - void _setPressedRow(PropertyRow* row) { pressedRow_ = row; } - int _applyTime() const{ return applyTime_; } - int _revertTime() const{ return revertTime_; } - int _updateHeightsTime() const{ return updateHeightsTime_; } - int _paintTime() const{ return paintTime_; } - const QFont& _boldFont() const{ return boldFont_; } - bool hasFocusOrInplaceHasFocus() const; - void addMenuHandler(PropertyRowMenuHandler* handler); - IconXPMCache* _iconCache() const{ return iconCache_.data(); } -public slots: - void onFilterChanged(const QString& str); -protected slots: - void onScroll(int pos); - void onModelUpdated(const PropertyRows& rows, bool apply); - void onModelPushUndo(PropertyTreeOperator* op, bool* handled); - void onModelPushRedo(PropertyTreeOperator* op, bool* handled); - void onMouseStillTimeout(); - -private: - QPropertyTree(const QPropertyTree&); - QPropertyTree& operator=(const QPropertyTree&); -protected: - class DragController; - enum HitTest{ - TREE_HIT_PLUS, - TREE_HIT_TEXT, - TREE_HIT_ROW, - TREE_HIT_NONE - }; - PropertyRow* rowByPoint(const QPoint& point); - HitTest hitTest(PropertyRow* row, const QPoint& pointInWindowSpace, const QRect& rowRect); - void onRowMenuDecompose(PropertyRow* row); - void onMouseStill(QPoint point); - - QSize sizeHint() const override; - bool event(QEvent* ev) override; - void paintEvent(QPaintEvent* ev) override; - void moveEvent(QMoveEvent* ev) override; - void resizeEvent(QResizeEvent* ev) override; - void mousePressEvent(QMouseEvent* ev) override; - void mouseReleaseEvent(QMouseEvent* ev) override; - void mouseDoubleClickEvent(QMouseEvent* ev) override; - void mouseMoveEvent(QMouseEvent* ev) override; - void wheelEvent(QWheelEvent* ev) override; - void keyPressEvent(QKeyEvent* ev) override; - void focusInEvent(QFocusEvent* ev) override; - - void updateArea(); - bool toggleRow(PropertyRow* row); - - struct RowFilter { - enum Type { - NAME_VALUE, - NAME, - VALUE, - TYPE, - NUM_TYPES - }; - - string start[NUM_TYPES]; - bool tillEnd[NUM_TYPES]; - std::vector substrings[NUM_TYPES]; - - void parse(const char* filter); - bool match(const char* text, Type type, size_t* matchStart, size_t* matchEnd) const; - bool typeRelevant(Type type) const{ - return !start[type].empty() || !substrings[type].empty(); - } - - RowFilter() - { - for (int i = 0; i < NUM_TYPES; ++i) - tillEnd[i] = false; - } - }; - - QPoint pointToRootSpace(const QPoint& pointInWindowSpace) const; - QPoint pointFromRootSpace(const QPoint& point) const; - - void interruptDrag(); - void updateHeights(bool recalculateTextSize=false); - void updateValidatorIcons(); - bool updateScrollBar(); - void applyValidation(); - void jumpToNextHiddenValidatorIssue(bool isError, PropertyRow* start); - - bool onContextMenu(PropertyRow* row, QMenu& menu); - void clearMenuHandlers(); - bool onRowKeyDown(PropertyRow* row, const QKeyEvent* ev); - bool rowProcessesKey(PropertyRow* row, const QKeyEvent* ev); - // points here are specified in root-row space - bool onRowLMBDown(PropertyRow* row, const QRect& rowRect, QPoint point, bool controlPressed, bool shiftPressed); - void onRowLMBUp(PropertyRow* row, const QRect& rowRect, QPoint point); - void onRowRMBDown(PropertyRow* row, const QRect& rowRect, QPoint point); - void onRowMouseMove(PropertyRow* row, const QRect& rowRect, QPoint point); - - bool canBePasted(PropertyRow* destination); - bool canBePasted(const char* destinationType); - - void setFilterMode(bool inFilterMode); - void startFilter(const char* filter); - void setWidget(PropertyRowWidget* widget); - void _arrangeChildren(); - - void updateAttachedPropertyTree(bool revert); - void drawFilteredString(QPainter& p, const wchar_t* text, RowFilter::Type type, const QFont* font, const QRect& rect, const QColor& color, bool pathEllipsis, bool center) const; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - QScopedPointer model_; - int cursorX_; - - QScopedPointer widget_; // in-place widget - vector menuHandlers_; - - typedef vector Objects; - Objects attached_; - QPropertyTree* attachedPropertyTree_; - bool autoHideAttachedPropertyTree_; - - bool filterMode_; - RowFilter rowFilter_; - QScopedPointer filterEntry_; - QScopedPointer iconCache_; - Serialization::SContextLink* archiveContext_; - QScopedPointer validatorBlock_; - bool outlineMode_; - bool sizeToContent_; - bool hideSelection_; - - bool autoRevert_; - bool needUpdate_; - - QScrollBar* scrollBar_; - QFont boldFont_; - QColor backgroundColor_; - QRect area_; - int leftBorder_; - int rightBorder_; - QPoint size_; - QPoint offset_; - QSize sizeHint_; - QSize contentSize_; - DragController* dragController_; - Serialization::SharedPtr lastSelectedRow_; - QPoint pressPoint_; - QPoint pressDelta_; - bool pointerMovedSincePress_; - QPoint lastStillPosition_; - PropertyRow* capturedRow_; - PropertyRow* pressedRow_; - QTimer* mouseStillTimer_; - - bool aggregateMouseEvents_; - int aggregatedMouseEventCount_; - QScopedPointer lastMouseMoveEvent_; - - PropertyTreeConfig config_; - QScopedPointer style_; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - int defaultRowHeight_; - - int applyTime_; - int revertTime_; - int updateHeightsTime_; - int paintTime_; - int zoomLevel_; - bool dragCheckMode_; - bool dragCheckValue_; - - friend class TreeImpl; - friend class FilterEntry; - friend class DragWindow; - friend struct FilterVisitor; - friend struct PropertyTreeMenuHandler; -}; - -wstring generateDigest(Serialization::SStruct& ser); -// vim: tw=90: - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYTREE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTreeStyle.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTreeStyle.h deleted file mode 100644 index 82577c1b90..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/QPropertyTreeStyle.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "Serialization.h" -#include "Serialization/Decorators/Range.h" - -struct QPropertyTreeStyle -{ - bool compact; - bool packCheckboxes; - bool fullRowMode; - bool showHorizontalLines; - bool doNotIndentSecondLevel; - bool groupShadows; - bool groupRectangle; - bool alignLabelsToRight; - float valueColumnWidth; - float rowSpacing; - unsigned char levelShadowOpacity; - float levelIndent; - float firstLevelIndent; - float groupShade; - float sliderSaturation; - - QPropertyTreeStyle() - : compact(false) - , packCheckboxes(true) - , fullRowMode(false) - , valueColumnWidth(.59f) - , rowSpacing(1.1f) - , showHorizontalLines(false) - , firstLevelIndent(0.75f) - , levelIndent(0.75f) - , levelShadowOpacity(36) - , doNotIndentSecondLevel(false) - , groupShadows(false) - , sliderSaturation(0.0f) - , groupShade(0.15f) - , groupRectangle(false) - , alignLabelsToRight(false) - { - } - - void Serialize(Serialization::IArchive& ar) - { - ar.Doc("Here you can define appearance of QPropertyTree control."); - - ar(valueColumnWidth, "valueColumnWidth", "Value Column Width"); - ar.Doc("Defines a ratio of the value / name columns. Normalized."); - ar(Serialization::Range(rowSpacing, 0.5f, 3.0f), "rowSpacing", "Row Spacing"); - ar.Doc("Height of one row (line) in text-height units."); - ar(alignLabelsToRight, "alignLabelsToRight", "Right Alignment"); - ar(Serialization::Range(levelIndent, 0.0f, 3.0f), "levelIndent", "Level Indent"); - ar.Doc("Indentation of a every next level in text-height units."); - - ar(Serialization::Range(firstLevelIndent, 0.0f, 3.0f), "firstLevelIndent", "First Level Indent"); - ar.Doc("Indentation of a very first level in text-height units."); - ar(Serialization::Range(sliderSaturation, 0.0f, 1.0f), "sliderSaturation", "Slider Saturation"); - ar(levelShadowOpacity, "levelShadowOpacity", "Level Shadow Opacity"); - ar.Doc("Amount of background darkening that gets added to each next nested level."); - - ar(compact, "compact", "Compact"); - ar.Doc("Compact mode removes expansion pluses from the level and reduces inner padding. Useful for narrowing the widget."); - ar(packCheckboxes, "packCheckboxes", "Pack Checkboxes"); - ar.Doc("Arranges checkboxes in two columns, when possible."); - - ar(showHorizontalLines, "showHorizontalLines", "Horizontal Lines"); - ar.Doc("Show thin line that connects row name with its value."); - - ar(doNotIndentSecondLevel, "doNotIndentSecondLevel", "Do not indent second level"); - ar(groupShadows, "groupShadows", "Group Shadows"); - ar(groupRectangle, "groupRectangle", "Group Rectangle"); - - ar(Serialization::Range(groupShade, -1.0f, 1.0f), "groupShade", "Group Shade"); - ar.Doc("Shade of the group."); - } -}; - diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Serialization.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Serialization.h deleted file mode 100644 index 3ce0c2c8f2..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Serialization.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_SERIALIZATION_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_SERIALIZATION_H -#pragma once - - -#include "Serialization/STL.h" -#include "Serialization/Pointers.h" -#include "Serialization/ClassFactory.h" -#include "Serialization/StringList.h" - -#include "Serialization/IArchive.h" -#include "Serialization/BinArchive.h" - -using Serialization::IArchive; -using Serialization::SStruct; -using Serialization::TypeID; -using Serialization::SharedPtr; - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_SERIALIZATION_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerEdit.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerEdit.cpp deleted file mode 100644 index 640197ca45..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerEdit.cpp +++ /dev/null @@ -1,56 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "SpriteBorderEditorCommon.h" - -SlicerEdit::SlicerEdit( SpriteBorder border, - QSize& unscaledPixmapSize, - ISprite* sprite ) -: QLineEdit() -, m_manipulator( nullptr ) -{ - bool isVertical = IsBorderVertical( border ); - - float totalUnscaledSizeInPixels = aznumeric_cast( isVertical ? unscaledPixmapSize.width() : unscaledPixmapSize.height() ); - - setPixelPosition( GetBorderValueInPixels( sprite, border, totalUnscaledSizeInPixels ) ); - - setValidator( new QDoubleValidator( 0.0f, totalUnscaledSizeInPixels, 1 ) ); - - QObject::connect( this, - &SlicerEdit::editingFinished, this, - [ this, border, sprite, totalUnscaledSizeInPixels ]() - { - float p = text().toFloat(); - - m_manipulator->setPixelPosition( p ); - - SetBorderValue( sprite, border, p, totalUnscaledSizeInPixels ); - } ); -} - -void SlicerEdit::SetManipulator(SlicerManipulator* manipulator) -{ - m_manipulator = manipulator; -} - -void SlicerEdit::setPixelPosition(float p) -{ - setText( QString::number( p ) ); -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerEdit.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerEdit.h deleted file mode 100644 index 88d47d3817..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerEdit.h +++ /dev/null @@ -1,46 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_SLICEREDIT_H -#define CRYINCLUDE_EDITORCOMMON_SLICEREDIT_H - -#if !defined(Q_MOC_RUN) -#include - -#include "SpriteBorderEditorCommon.h" -#endif - -class SlicerEdit -: public QLineEdit -{ - Q_OBJECT - -public: - - SlicerEdit( SpriteBorder border, - QSize& unscaledPixmapSize, - ISprite* sprite ); - - void SetManipulator(SlicerManipulator* manipulator); - - void setPixelPosition(float p); - -private: - - SlicerManipulator* m_manipulator; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_SLICEREDIT_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerManipulator.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerManipulator.cpp deleted file mode 100644 index d516f30e7d..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerManipulator.cpp +++ /dev/null @@ -1,143 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "SpriteBorderEditorCommon.h" - -#define CRYINCLUDE_EDITORCOMMON_DRAW_SELECTABLE_AREA_OF_SLICERMANIPULATOR ( 0 ) -#define CRYINCLUDE_EDITORCOMMON_ARBITRARILY_LARGE_NUMBER ( 10000.0f ) -#define CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_WIDTH ( 2.0f ) - -SlicerManipulator::SlicerManipulator( SpriteBorder border, - QSize& unscaledPixmapSize, - QSize& scaledPixmapSize, - float thicknessInPixels, - ISprite* sprite, - QGraphicsScene* scene ) -: QGraphicsRectItem() -, m_border( border ) -, m_isVertical( IsBorderVertical( m_border ) ) -, m_unscaledPixmapSize( unscaledPixmapSize ) -, m_scaledPixmapSize( scaledPixmapSize ) -, m_sprite( sprite ) -, m_unscaledOverScaledFactor( ( (float)m_unscaledPixmapSize.width() / (float)m_scaledPixmapSize.width() ), - ( (float)m_unscaledPixmapSize.height() / (float)m_scaledPixmapSize.height() ) ) -, m_scaledOverUnscaledFactor( ( 1.0f / m_unscaledOverScaledFactor.x() ), - ( 1.0f / m_unscaledOverScaledFactor.y() ) ) -, m_color( Qt::white ) -, m_edit( nullptr ) -{ - setAcceptHoverEvents( true ); - - scene->addItem( this ); - - setRect( ( m_isVertical ? - ( thicknessInPixels * 0.5f ) : - CRYINCLUDE_EDITORCOMMON_ARBITRARILY_LARGE_NUMBER ), - ( m_isVertical ? - CRYINCLUDE_EDITORCOMMON_ARBITRARILY_LARGE_NUMBER : - ( thicknessInPixels * 0.5f ) ), - ( m_isVertical ? thicknessInPixels : ( 3.0f * CRYINCLUDE_EDITORCOMMON_ARBITRARILY_LARGE_NUMBER ) ), - ( m_isVertical ? ( 3.0f * CRYINCLUDE_EDITORCOMMON_ARBITRARILY_LARGE_NUMBER ) : thicknessInPixels ) ); - - setPixelPosition( GetBorderValueInPixels( m_sprite, m_border, aznumeric_cast( m_isVertical ? m_unscaledPixmapSize.width() : m_unscaledPixmapSize.height() ) ) ); - - setFlag( QGraphicsItem::ItemIsMovable, true ); - setFlag( QGraphicsItem::ItemIsSelectable, true ); // This allows using the CTRL key to select multiple manipulators and move them simultaneously. - setFlag( QGraphicsItem::ItemSendsScenePositionChanges, true ); -} - -void SlicerManipulator::SetEdit( SlicerEdit *edit ) -{ - m_edit = edit; -} - -void SlicerManipulator::paint(QPainter* painter, [[maybe_unused]] const QStyleOptionGraphicsItem* option, [[maybe_unused]] QWidget* widget) -{ -#if CRYINCLUDE_EDITORCOMMON_DRAW_SELECTABLE_AREA_OF_SLICERMANIPULATOR - QGraphicsRectItem::paint( painter, option, widget ); -#endif // CRYINCLUDE_EDITORCOMMON_DRAW_SELECTABLE_AREA_OF_SLICERMANIPULATOR - - QPen pen; - pen.setStyle( isSelected() ? Qt::DashLine : Qt::DotLine ); - pen.setWidthF( CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_WIDTH ); - - // Draw a thin line in the middle of the selectable area. - if( m_isVertical ) - { - float x = aznumeric_cast( ( ( rect().left() + rect().right() ) * 0.5f ) - CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_WIDTH ); - - pen.setColor( m_color ); - painter->setPen( pen ); - painter->drawLine(aznumeric_cast(x), aznumeric_cast(rect().top()), aznumeric_cast(x), aznumeric_cast(rect().bottom()) ); - - x += CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_WIDTH; - pen.setColor( Qt::black ); - painter->setPen( pen ); - painter->drawLine(aznumeric_cast(x), aznumeric_cast(rect().top()), aznumeric_cast(x), aznumeric_cast(rect().bottom()) ); - } - else - { - float y = aznumeric_cast( ( ( rect().top() + rect().bottom() ) * 0.5f ) - CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_WIDTH ); - - pen.setColor( m_color ); - painter->setPen( pen ); - painter->drawLine(aznumeric_cast(rect().left()), aznumeric_cast(y), aznumeric_cast(rect().right()), aznumeric_cast(y) ); - - y += CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_WIDTH; - pen.setColor( Qt::black ); - painter->setPen( pen ); - painter->drawLine(aznumeric_cast(rect().left()), aznumeric_cast(y), aznumeric_cast(rect().right()), aznumeric_cast(y) ); - } -} - -void SlicerManipulator::setPixelPosition(float p) -{ - setPos( ( m_isVertical ? ( p * m_scaledOverUnscaledFactor.x() ) : 0.0f ), - ( m_isVertical ? 0.0f : ( p * m_scaledOverUnscaledFactor.y() ) ) ); -} - -QVariant SlicerManipulator::itemChange(GraphicsItemChange change, const QVariant& value) -{ - if( ( change == ItemPositionChange ) && - scene() ) - { - float totalScaledSizeInPixels = aznumeric_cast( m_isVertical ? m_scaledPixmapSize.width() : m_scaledPixmapSize.height() ); - - float p = clamp_tpl(aznumeric_cast( m_isVertical ? value.toPointF().x() : value.toPointF().y() ), - 0.0f, - totalScaledSizeInPixels ); - - m_edit->setPixelPosition( m_isVertical ? aznumeric_cast( p * m_unscaledOverScaledFactor.x() ) : aznumeric_cast( p * m_unscaledOverScaledFactor.y() ) ); - - SetBorderValue( m_sprite, m_border, p, totalScaledSizeInPixels ); - - return QPointF( ( m_isVertical ? p : 0.0f ), - ( m_isVertical ? 0.0f : p ) ); - } - - return QGraphicsItem::itemChange( change, value ); -} - -void SlicerManipulator::hoverEnterEvent([[maybe_unused]] QGraphicsSceneHoverEvent* event) -{ - setCursor( m_isVertical ? Qt::SizeHorCursor : Qt::SizeVerCursor ); - m_color = Qt::yellow; - update(); -} - -void SlicerManipulator::hoverLeaveEvent([[maybe_unused]] QGraphicsSceneHoverEvent* event) -{ - setCursor(Qt::ArrowCursor); - m_color = Qt::white; - update(); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerManipulator.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerManipulator.h deleted file mode 100644 index 7f4f21506e..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerManipulator.h +++ /dev/null @@ -1,58 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_H -#define CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_H - -class SlicerManipulator -: public QGraphicsRectItem -{ -public: - - SlicerManipulator( SpriteBorder border, - QSize& unscaledPixmapSize, - QSize& scaledPixmapSize, - float thicknessInPixels, - ISprite* sprite, - QGraphicsScene* scene ); - - void SetEdit(SlicerEdit* edit); - - void setPixelPosition(float p); - -protected: - - QVariant itemChange(GraphicsItemChange change, const QVariant& value) override; - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; - void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override; - void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override; - -private: - - SpriteBorder m_border; - bool m_isVertical; - QSize m_unscaledPixmapSize; - QSize m_scaledPixmapSize; - ISprite* m_sprite; - QPointF m_unscaledOverScaledFactor; - QPointF m_scaledOverUnscaledFactor; - QColor m_color; - - SlicerEdit* m_edit; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_SLICERMANIPULATOR_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerView.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerView.cpp deleted file mode 100644 index 7ec2ec4c8c..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerView.cpp +++ /dev/null @@ -1,25 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "SpriteBorderEditorCommon.h" - -SlicerView::SlicerView(QGraphicsScene* scene, QWidget* parent) -: QGraphicsView( scene, parent ) -{ - setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerView.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerView.h deleted file mode 100644 index f2644123ce..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SlicerView.h +++ /dev/null @@ -1,34 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_SLICERVIEW_H -#define CRYINCLUDE_EDITORCOMMON_SLICERVIEW_H - -class SlicerView -: public QGraphicsView -{ -public: - - SlicerView(QGraphicsScene* scene, QWidget* parent = nullptr); - -protected: - - // This is intentionally empty. - void scrollContentsBy([[maybe_unused]] int dx, [[maybe_unused]] int dy) override {}; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_SLICERVIEW_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditor.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditor.cpp deleted file mode 100644 index d67936de3f..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditor.cpp +++ /dev/null @@ -1,175 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "SpriteBorderEditorCommon.h" -#include // for Getting the game folder - -//------------------------------------------------------------------------------- - -#define VIEW_WIDTH ( 200 ) -#define VIEW_HEIGHT ( 200 ) -#define MANIPULATOR_THICKNESS_IN_PIXELS ( 24 ) - -//------------------------------------------------------------------------------- - -SpriteBorderEditor::SpriteBorderEditor(const char* path, QWidget* parent) -: QDialog( parent ) -, hasBeenInitializedProperly( true ) -{ - ISprite* sprite = gEnv->pLyShine->LoadSprite( path ); - CRY_ASSERT( sprite ); - - // The layout. - QGridLayout* outerGrid = new QGridLayout(this); - - QGridLayout* innerGrid = new QGridLayout(); - outerGrid->addLayout( innerGrid, 0, 0, 1, 2 ); - - // The scene. - QGraphicsScene* scene( new QGraphicsScene( 0.0f, 0.0f, VIEW_WIDTH, VIEW_HEIGHT, this ) ); - - // The view. - innerGrid->addWidget( new SlicerView( scene, this ), 0, 0, 6, 1 ); - - // The image. - QGraphicsPixmapItem* pixmapItem = nullptr; - QSize unscaledPixmapSize; - QSize scaledPixmapSize; - { - // assets can be in gems as well as in the current project. Qpixmap requires a path to - // the asset and doesn't know about such concepts. So adjust the pathname to something - // that Qpixmap can open. - QString fullPath = Path::GamePathToFullPath(sprite->GetTexturePathname().c_str()); - QPixmap unscaledPixmap(fullPath); - - bool isVertical = ( unscaledPixmap.size().height() > unscaledPixmap.size().width() ); - - // Scale-to-fit, while preserving aspect ratio. - pixmapItem = scene->addPixmap( isVertical ? unscaledPixmap.scaledToHeight( VIEW_HEIGHT ) : unscaledPixmap.scaledToWidth( VIEW_WIDTH ) ); - - unscaledPixmapSize = unscaledPixmap.size(); - scaledPixmapSize = pixmapItem->pixmap().size(); - } - - // Add text fields and manipulators. - { - int row = 0; - - innerGrid->addWidget( new QLabel( QString( "Texture is %1 x %2" ).arg( QString::number( unscaledPixmapSize.width() ), - QString::number( unscaledPixmapSize.height() ) ), - this ), - row++, - 1 ); - - for( SpriteBorder b : SpriteBorder() ) - { - SlicerEdit* edit = new SlicerEdit( b, - unscaledPixmapSize, - sprite ); - - SlicerManipulator* manipulator = new SlicerManipulator( b, - unscaledPixmapSize, - scaledPixmapSize, - MANIPULATOR_THICKNESS_IN_PIXELS, - sprite, - scene ); - - edit->SetManipulator( manipulator ); - manipulator->SetEdit( edit ); - - innerGrid->addWidget( new QLabel( SpriteBorderToString( b ), this ), row, 1 ); - innerGrid->addWidget( edit, row, 2 ); - innerGrid->addWidget( new QLabel( "pixels", this ), row, 3 ); - ++row; - } - } - - // Add buttons. - { - // Save button. - QPushButton* saveButton = new QPushButton( "Save", this ); - QObject::connect( saveButton, - &QPushButton::clicked, this, - [ this, sprite ]([[maybe_unused]] bool checked ) - { - // Sanitize values. - // - // This is the simplest way to sanitize the - // border values. Otherwise, we need to prevent - // flipping the manipulators in the UI. - { - ISprite::Borders b = sprite->GetBorders(); - - if( b.m_top > b.m_bottom ) - { - std::swap( b.m_top, b.m_bottom ); - } - - if( b.m_left > b.m_right ) - { - std::swap( b.m_left, b.m_right ); - } - - sprite->SetBorders( b ); - } - - QString fullPath = Path::GamePathToFullPath(sprite->GetPathname().c_str()); - bool result = sprite->SaveToXml(fullPath.toUtf8().data()); - - if (result) - { - close(); - } - else - { - QMessageBox box(QMessageBox::Critical, - "Error", - "Unable to save file", - QMessageBox::Ok); - box.exec(); - } - } ); - outerGrid->addWidget( saveButton, 1, 0 ); - - // Cancel button. - ISprite::Borders originalBorders = sprite->GetBorders(); - QPushButton* cancelButton = new QPushButton( "Cancel", this ); - QObject::connect( cancelButton, - &QPushButton::clicked, this, - [ this, sprite, originalBorders ]([[maybe_unused]] bool checked ) - { - // Restore original borders. - sprite->SetBorders( originalBorders ); - - close(); - } ); - outerGrid->addWidget( cancelButton, 1, 1 ); - } - - setWindowTitle( "SpriteBorderEditor" ); - setModal( true ); - setWindowModality( Qt::ApplicationModal ); - - layout()->setSizeConstraint( QLayout::SetFixedSize ); -} - -bool SpriteBorderEditor::GetHasBeenInitializedProperly() -{ - return hasBeenInitializedProperly; -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditor.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditor.h deleted file mode 100644 index b670d75af8..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditor.h +++ /dev/null @@ -1,41 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_SPRITEBORDEREDITOR_H -#define CRYINCLUDE_EDITORCOMMON_SPRITEBORDEREDITOR_H - -#if !defined(Q_MOC_RUN) -#include -#endif - -class SpriteBorderEditor -: public QDialog -{ - Q_OBJECT - -public: - - SpriteBorderEditor(const char* path, QWidget* parent = nullptr); - - bool GetHasBeenInitializedProperly(); - -private: - - bool hasBeenInitializedProperly; -}; - -#endif // CRYINCLUDE_EDITORCOMMON_SPRITEBORDEREDITOR_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditorCommon.cpp b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditorCommon.cpp deleted file mode 100644 index 305f9dafa7..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditorCommon.cpp +++ /dev/null @@ -1,120 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "SpriteBorderEditorCommon.h" - -bool IsBorderVertical(SpriteBorder border) -{ - return ( ( border == SpriteBorder::Left ) || - ( border == SpriteBorder::Right ) ); -} - -float GetBorderValueInPixels(ISprite* sprite, SpriteBorder b, float totalSizeInPixels) -{ - // IMPORTANT: We CAN'T replace totalSizeInPixels with - // sprite->GetTexture()->GetWidth()/GetHeight() because - // it DOESN'T return the original texture file's size. - - ISprite::Borders sb = sprite->GetBorders(); - - float *f = nullptr; - - if( b == SpriteBorder::Top ) - { - f = &sb.m_top; - } - else if( b == SpriteBorder::Bottom ) - { - f = &sb.m_bottom; - } - else if( b == SpriteBorder::Left ) - { - f = &sb.m_left; - } - else if( b == SpriteBorder::Right ) - { - f = &sb.m_right; - } - else - { - CRY_ASSERT( 0 ); - f = nullptr; - } - - return ( *f * totalSizeInPixels ); -} - -void SetBorderValue(ISprite* sprite, SpriteBorder b, float pixelPosition, float totalSizeInPixels) -{ - // IMPORTANT: We CAN'T replace totalSizeInPixels with - // sprite->GetTexture()->GetWidth()/GetHeight() because - // it DOESN'T return the original texture file's size. - - ISprite::Borders sb = sprite->GetBorders(); - - float *f = nullptr; - - if( b == SpriteBorder::Top ) - { - f = &sb.m_top; - } - else if( b == SpriteBorder::Bottom ) - { - f = &sb.m_bottom; - } - else if( b == SpriteBorder::Left ) - { - f = &sb.m_left; - } - else if( b == SpriteBorder::Right ) - { - f = &sb.m_right; - } - else - { - CRY_ASSERT( 0 ); - f = nullptr; - } - - *f = ( pixelPosition / totalSizeInPixels ); - sprite->SetBorders( sb ); -} - -const char* SpriteBorderToString(SpriteBorder b) -{ - if( b == SpriteBorder::Top ) - { - return "Top"; - } - else if( b == SpriteBorder::Bottom ) - { - return "Bottom"; - } - else if( b == SpriteBorder::Left ) - { - return "Left"; - } - else if( b == SpriteBorder::Right ) - { - return "Right"; - } - else - { - CRY_ASSERT( 0 ); - return "UNKNOWN"; - } -} diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditorCommon.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditorCommon.h deleted file mode 100644 index de85c71e5a..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/SpriteBorderEditorCommon.h +++ /dev/null @@ -1,78 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_SPRITEBORDEREDITORCOMMON_H -#define CRYINCLUDE_EDITORCOMMON_SPRITEBORDEREDITORCOMMON_H - -#include // required to be included before platform.h -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class SlicerEdit; -class SlicerManipulator; -class SlicerView; -class SpriteBorderEditor; - -enum class SpriteBorder -{ - Top, - Bottom, - Left, - Right -}; - -// This allows iterating over an enum class. -#define ADD_ENUM_CLASS_ITERATION_OPERATORS( CLASS_NAME, FIRST_VALUE, LAST_VALUE ) \ - \ - inline CLASS_NAME operator++(CLASS_NAME &m){ return m = (CLASS_NAME)(std::underlying_type::type(m) + 1); } \ - inline CLASS_NAME operator*(CLASS_NAME m){ return m; } \ - inline CLASS_NAME begin([[maybe_unused]] CLASS_NAME m){ return FIRST_VALUE; } \ - inline CLASS_NAME end([[maybe_unused]] CLASS_NAME m){ return (CLASS_NAME)(std::underlying_type::type(LAST_VALUE) + 1); } - -ADD_ENUM_CLASS_ITERATION_OPERATORS( SpriteBorder, - SpriteBorder::Top, - SpriteBorder::Right ); - -#include "SlicerEdit.h" -#include "SlicerManipulator.h" -#include "SlicerView.h" -#include "SpriteBorderEditor.h" - -bool IsBorderVertical(SpriteBorder border); -float GetBorderValueInPixels(ISprite* sprite, SpriteBorder b, float totalSizeInPixels); -void SetBorderValue(ISprite* sprite, SpriteBorder b, float pixelPosition, float totalSizeInPixels); -const char* SpriteBorderToString(SpriteBorder b); - -#endif // CRYINCLUDE_EDITORCOMMON_SPRITEBORDEREDITORCOMMON_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Strings.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Strings.h deleted file mode 100644 index 5f52145f41..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Strings.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_STRINGS_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_STRINGS_H -#pragma once - -#ifndef SERIALIZATION_STANDALONE -#include - -typedef CryStringT string; -typedef CryStringT wstring; -#else -#include -using std::string; -using std::wstring; -#endif - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_STRINGS_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Unicode.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Unicode.h deleted file mode 100644 index 71f9830d0e..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/Unicode.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * wWidgets - Lightweight UI Toolkit. - * Copyright (C) 2009-2011 Evgeny Andreeshchev - * Alexander Kotliar - * - * This code is distributed under the MIT License: - * http://www.opensource.org/licenses/MIT - */ -// Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_UNICODE_H -#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_UNICODE_H -#pragma once - -#include "Strings.h" -#include - -string fromWideChar(const wchar_t* wideCharString); -wstring toWideChar(const char* multiByteString); -wstring fromANSIToWide(const char* ansiString); -string toANSIFromWide(const wchar_t* wstr); - - -#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_UNICODE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ValidatorBlock.h b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ValidatorBlock.h deleted file mode 100644 index db1480225c..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/ValidatorBlock.h +++ /dev/null @@ -1,172 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "Strings.h" -#include -#include -#include - -enum ValidatorEntryType -{ - VALIDATOR_ENTRY_WARNING, - VALIDATOR_ENTRY_ERROR -}; - -struct ValidatorEntry -{ - const void* handle; - Serialization::TypeID typeId; - - ValidatorEntryType type; - string message; - - bool operator<(const ValidatorEntry& rhs) const - { - if (handle != rhs.handle) - { - return handle < rhs.handle; - } - return typeId < rhs.typeId; - } - - ValidatorEntry(ValidatorEntryType type, const void* handle, const Serialization::TypeID& typeId, const char* message) - : type(type) - , handle(handle) - , message(message) - , typeId(typeId) - { - } - - ValidatorEntry() - : handle() - , type(VALIDATOR_ENTRY_WARNING) - { - } -}; -typedef std::vector ValidatorEntries; - -class ValidatorBlock -{ -public: - ValidatorBlock() - : m_enabled(false) - { - } - - void Clear() - { - m_entries.clear(); - m_used.clear(); - } - - void AddEntry(const ValidatorEntry& entry) - { - ValidatorEntries::iterator it = std::upper_bound(m_entries.begin(), m_entries.end(), entry); - m_used.insert(m_used.begin() + (it - m_entries.begin()), false); - m_entries.insert(it, entry); - m_enabled = true; - } - - bool IsEnabled() const { return m_enabled; } - - const ValidatorEntry* GetEntry(int index, int count) const - { - if (size_t(index) >= m_entries.size()) - { - return 0; - } - if (size_t(index + count) > m_entries.size()) - { - return 0; - } - return &m_entries[index]; - } - - bool FindHandleEntries(int* outIndex, int* outCount, const void* handle, Serialization::TypeID& typeId) - { - if (handle == 0) - { - return false; - } - ValidatorEntry e; - e.handle = handle; - e.typeId = typeId; - ValidatorEntries::iterator begin = std::lower_bound(m_entries.begin(), m_entries.end(), e); - ValidatorEntries::iterator end = std::upper_bound(m_entries.begin(), m_entries.end(), e); - if (begin != end) - { - *outIndex = int(begin - m_entries.begin()); - *outCount = int(end - begin); - return true; - } - return false; - } - - void MarkAsUsed(int start, int count) - { - if (start < 0) - { - return; - } - if (start + count > m_entries.size()) - { - return; - } - for (int i = start; i < start + count; ++i) - { - m_used[i] = true; - } - } - - void MergeUnusedItemsWithRootItems(int* firstUnusedItem, int* count, const void* newHandle, Serialization::TypeID& typeId) - { - size_t numItems = m_used.size(); - for (size_t i = 0; i < numItems; ++i) - { - if (m_entries[i].handle == newHandle) - { - m_entries.push_back(m_entries[i]); - m_used.push_back(true); - m_entries[i].typeId = Serialization::TypeID(); - } - if (!m_used[i]) - { - m_entries.push_back(m_entries[i]); - m_used.push_back(true); - m_entries.back().handle = newHandle; - m_entries.back().typeId = typeId; - } - } - *firstUnusedItem = (int)numItems; - *count = int(m_entries.size() - numItems); - } - - bool ContainsErrors() const - { - for (size_t i = 0; i < m_entries.size(); ++i) - { - if (m_entries[i].type == VALIDATOR_ENTRY_ERROR) - { - return true; - } - } - return false; - } - -private: - ValidatorEntries m_entries; - std::vector m_used; - bool m_enabled; -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/error.xpm b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/error.xpm deleted file mode 100644 index c26942bda9..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/error.xpm +++ /dev/null @@ -1,126 +0,0 @@ -/* XPM */ -static const char * error_xpm[] = { -"16 16 107 2", -" c None", -". c #F98267", -"+ c #F78065", -"@ c #F57E63", -"# c #F37C61", -"$ c #F98268", -"% c #EE836E", -"& c #F4A692", -"* c #F8B4A0", -"= c #F3A691", -"- c #E97D68", -"; c #EB7359", -"> c #F88166", -", c #F19784", -"' c #FBBDA9", -") c #F8A38A", -"! c #F6896B", -"~ c #F8A289", -"{ c #FABCA8", -"] c #EC927F", -"^ c #E46C52", -"/ c #F67F65", -"( c #F09783", -"_ c #F58263", -": c #FFFFFF", -"< c #F37E61", -"[ c #F37C60", -"} c #F9B9A6", -"| c #EA8D7B", -"1 c #DE644A", -"2 c #EC816C", -"3 c #F58162", -"4 c #F48062", -"5 c #F17A5F", -"6 c #F0785F", -"7 c #EF765D", -"8 c #F8B5A5", -"9 c #DD705D", -"0 c #F8A188", -"a c #EE735C", -"b c #EC705B", -"c c #F19382", -"d c #EC9889", -"e c #D2583E", -"f c #ED765B", -"g c #F8B6A1", -"h c #F48467", -"i c #EB6E5A", -"j c #EA6C59", -"k c #E96F5F", -"l c #F1A89B", -"m c #CE533A", -"n c #E97157", -"o c #F7B3A0", -"p c #F28065", -"q c #FAD9D3", -"r c #E86958", -"s c #E76757", -"t c #E76C5D", -"u c #F1A599", -"v c #CA4F35", -"w c #E56D52", -"x c #F09F8E", -"y c #F49984", -"z c #F19D90", -"A c #F3AFA6", -"B c #E66556", -"C c #E56255", -"D c #EB897D", -"E c #E79185", -"F c #C64A31", -"G c #E07360", -"H c #F7B3A4", -"I c #E36154", -"J c #E25F53", -"K c #F2A99F", -"L c #D16150", -"M c #DA6046", -"N c #E68878", -"O c #F5B0A3", -"P c #ED9289", -"Q c #EC9288", -"R c #E15D52", -"S c #DD7D6F", -"T c #C0442B", -"U c #D3593F", -"V c #E38475", -"W c #F4ACA1", -"X c #EC8B7F", -"Y c #E4675C", -"Z c #E3665B", -"` c #EA877D", -" . c #F1A89F", -".. c #DD7C6F", -"+. c #BF4329", -"@. c #CC5238", -"#. c #D46452", -"$. c #E79084", -"%. c #EEA095", -"&. c #ED9F95", -"*. c #E58E83", -"=. c #CE5D4C", -"-. c #BD4128", -";. c #C4482F", -">. c #C2462C", -",. c #C0442A", -"'. c #BE4228", -" ", -" . + @ # ", -" $ % & * * = - ; ", -" > , ' ) ! ! ~ { ] ^ ", -" / ( ' _ _ : : < [ } | 1 ", -" 2 ' _ 3 4 : : 5 6 7 8 9 ", -" 5 = 0 4 < [ : : 7 a b c d e ", -" f g h [ 5 6 : : b i j k l m ", -" n o p 6 7 a q : j r s t u v ", -" w x y a b i z A s B C D E F ", -" G H i j r : : C I J K L ", -" M N O s B P Q J R K S T ", -" U V W X Y Z ` ...+. ", -" @.#.$.%.&.*.=.-. ", -" ;.>.,.'. ", -" "}; diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/file_open.xpm b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/file_open.xpm deleted file mode 100644 index cd355e8dd4..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/file_open.xpm +++ /dev/null @@ -1,142 +0,0 @@ -/* XPM */ -static const char * file_open_xpm[] = { -"16 16 123 2", -" c None", -". c #E0C259", -"+ c #E2C361", -"@ c #E3C463", -"# c #E3C462", -"$ c #E0C056", -"% c #DBB53C", -"& c #FEFEFD", -"* c #FFFFFE", -"= c #FFFEFE", -"- c #FFFEFD", -"; c #FBF7EA", -"> c #E5C86E", -", c #E4C96F", -"' c #E7CF7D", -") c #E8D084", -"! c #DCB441", -"~ c #FEFCF7", -"{ c #F8E48E", -"] c #F5DE91", -"^ c #F5E09F", -"/ c #F6E1AC", -"( c #FEFBEF", -"_ c #FEFDF4", -": c #FEFCF3", -"< c #FEFCF1", -"[ c #FEFBEE", -"} c #FFFDFA", -"| c #E0BC58", -"1 c #DCAE40", -"2 c #FDFAF1", -"3 c #F5DE94", -"4 c #F4DC93", -"5 c #F2D581", -"6 c #EDCA6A", -"7 c #EACB6C", -"8 c #EFD385", -"9 c #EFD280", -"0 c #EFD07A", -"a c #EECF76", -"b c #EECF72", -"c c #FBF7E9", -"d c #DCB23E", -"e c #DBAD39", -"f c #FBF6E8", -"g c #EFD494", -"h c #EECE88", -"i c #E9C173", -"j c #F6E9C9", -"k c #FEFCF2", -"l c #FEFCF0", -"m c #DBAE3C", -"n c #DBA83B", -"o c #FFFDF8", -"p c #FFFDF6", -"q c #FFFCF5", -"r c #FCF6D8", -"s c #F8E694", -"t c #F7E385", -"u c #F6DF76", -"v c #F5DB68", -"w c #F4D85C", -"x c #FCF4D7", -"y c #DBA73B", -"z c #DBA33B", -"A c #FEFCF6", -"B c #FCF2C8", -"C c #FBEFB9", -"D c #FAECAC", -"E c #F9E89C", -"F c #F7E38B", -"G c #F6E07C", -"H c #F6DC6C", -"I c #F5D95D", -"J c #F4D64F", -"K c #F3D344", -"L c #FCF3D0", -"M c #DBA23B", -"N c #DB9D3C", -"O c #FDFAF2", -"P c #FAEDB3", -"Q c #F9E9A4", -"R c #F8E695", -"S c #F7E285", -"T c #F6DE76", -"U c #F5DB65", -"V c #F4D757", -"W c #F3D449", -"X c #F2D13B", -"Y c #F1CE30", -"Z c #FBF2CC", -"` c #DB9B3B", -" . c #DB973B", -".. c #FEFAEF", -"+. c #F9E9A1", -"@. c #F8E591", -"#. c #F7E181", -"$. c #F6DE72", -"%. c #F5DA63", -"&. c #F4D754", -"*. c #F3D347", -"=. c #F2D039", -"-. c #F1CD2E", -";. c #F0CB26", -">. c #FBF2CA", -",. c #DD9947", -"'. c #FAF1DE", -"). c #F4DDA8", -"!. c #F4DB9E", -"~. c #F3DA96", -"{. c #F3D88E", -"]. c #F3D786", -"^. c #F2D47F", -"/. c #F2D379", -"(. c #F1D272", -"_. c #F1D06C", -":. c #F1CF69", -"<. c #F8EAC2", -"[. c #DB953F", -"}. c #DB913E", -"|. c #D98C34", -"1. c #D98B34", -"2. c #DA8F39", -" ", -" ", -" . + @ @ @ # $ ", -" % & * = - * ; > , , , ' ) ", -" ! ~ { ] ^ / ( _ : < ( [ } | ", -" 1 2 3 4 5 6 7 8 9 0 a b c d ", -" e f g h i j k : k l ( [ * m ", -" n * o p q : r s t u v w x y ", -" z A B C D E F G H I J K L M ", -" N O P Q R S T U V W X Y Z ` ", -" N O P Q R S T U V W X Y Z ` ", -" ...+.@.#.$.%.&.*.=.-.;.>. . ", -" ,.'.).!.~.{.].^./.(._.:.<.[. ", -" ,.}.|.|.|.|.|.|.|.|.1.2. ", -" ", -" "}; diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/file_save.xpm b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/file_save.xpm deleted file mode 100644 index 0f44467069..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/file_save.xpm +++ /dev/null @@ -1,168 +0,0 @@ -/* XPM */ -static const char * file_save_xpm[] = { -"16 16 149 2", -" c None", -". c #8DABD9", -"+ c #5E89C9", -"@ c #4375C0", -"# c #3A6EBD", -"$ c #376CBB", -"% c #366BBB", -"& c #366ABB", -"* c #396CBC", -"= c #3B6EBD", -"- c #3A6DBB", -"; c #4474BF", -"> c #658DC9", -", c #85A5D6", -"' c #D1E0F6", -") c #D1E0F7", -"! c #F8FBFE", -"~ c #F7FBFE", -"{ c #F6F9FD", -"] c #F0F5FC", -"^ c #EDF2FB", -"/ c #F7FAFD", -"( c #EBF1FB", -"_ c #DFE9F8", -": c #BED1EC", -"< c #6A92CD", -"[ c #5582C6", -"} c #D1DFF6", -"| c #80AAE9", -"1 c #F6FAFE", -"2 c #F6FAFD", -"3 c #648CC8", -"4 c #EEF3FB", -"5 c #F2F6FC", -"6 c #F1F6FC", -"7 c #E2ECF9", -"8 c #DBE7F8", -"9 c #BAD0EE", -"0 c #BDD0EC", -"a c #4374BD", -"b c #4274C0", -"c c #D0DFF6", -"d c #7EA8E8", -"e c #E9F1FA", -"f c #E8F0FA", -"g c #DDE8F8", -"h c #DBE6F7", -"i c #7AA3E1", -"j c #C3D5EF", -"k c #366AB7", -"l c #CCDDF5", -"m c #7EA8E7", -"n c #668DC9", -"o c #E9F0FA", -"p c #F8FAFE", -"q c #EFF4FC", -"r c #DFE9F9", -"s c #DBE7F7", -"t c #D9E5F7", -"u c #78A2E0", -"v c #A9C2E7", -"w c #3568B6", -"x c #C9DCF4", -"y c #7DA7E7", -"z c #E1ECF9", -"A c #E3EDF9", -"B c #EEF4FC", -"C c #F3F7FD", -"D c #E5EDFA", -"E c #D8E5F6", -"F c #77A0DE", -"G c #A4BEE4", -"H c #3467B4", -"I c #C7D9F4", -"J c #7DA6E6", -"K c #678EC9", -"L c #6C92CB", -"M c #6990CA", -"N c #658CC8", -"O c #749CDA", -"P c #9FBAE1", -"Q c #3466B3", -"R c #C5D8F2", -"S c #7BA4E3", -"T c #7AA3E3", -"U c #7AA4E3", -"V c #7BA4E2", -"W c #7BA3E2", -"X c #79A2E1", -"Y c #77A0DF", -"Z c #769FDE", -"` c #749EDD", -" . c #729CDB", -".. c #749DDC", -"+. c #9AB5DD", -"@. c #3465B1", -"#. c #BED2F0", -"$. c #7AA3E2", -"%. c #7BA3E1", -"&. c #779FDE", -"*. c #769FDD", -"=. c #729BD9", -"-. c #7199D8", -";. c #7099D6", -">. c #8EABD5", -",. c #3363AD", -"'. c #366ABA", -"). c #BBD0EF", -"!. c #7AA2E2", -"~. c #6D96D3", -"{. c #8AA7D2", -"]. c #3262AB", -"^. c #386BBB", -"/. c #B8CEEF", -"(. c #F7FAFE", -"_. c #88C062", -":. c #6A93CF", -"<. c #84A3CE", -"[. c #3261AA", -"}. c #386CBB", -"|. c #B6CCEE", -"1. c #7AA2E1", -"2. c #C2DCBF", -"3. c #6890CD", -"4. c #819ECC", -"5. c #3261A8", -"6. c #386CBA", -"7. c #B3CAED", -"8. c #7AA2E0", -"9. c #658DCA", -"0. c #7C9BC9", -"a. c #3261A7", -"b. c #4F7DC3", -"c. c #ADC6EB", -"d. c #ADC5EA", -"e. c #7C9AC8", -"f. c #7998C7", -"g. c #406BAD", -"h. c #7095CD", -"i. c #4273BD", -"j. c #3568B7", -"k. c #3568B5", -"l. c #3466B2", -"m. c #3364AE", -"n. c #3263AC", -"o. c #3262AA", -"p. c #3261A9", -"q. c #3160A8", -"r. c #3C69AB", -" . + @ # $ % & * = - ; > ", -" , ' ) ! ~ { ] ^ { / ( _ : < ", -" [ } | 1 2 3 4 5 ! 6 7 8 9 0 a ", -" b c d 6 6 3 e / { f g h i j k ", -" # l m f f n o p q r s t u v w ", -" $ x y z z A B C D s t E F G H ", -" % I J 3 > K L M N 3 3 3 O P Q ", -" & R S T U V W X Y Z ` ...+.@.", -" & #.$.$.i W %.&.*...=.-.;.>.,.", -" '.).!.! ! ! ! ! ! ! ! ! ~.{.].", -" ^./.X (._._._._._._._.{ :.<.[.", -" }.|.1.(.2.2.2.2.2.2.2.{ 3.4.5.", -" 6.7.8.(._._._._._._._.{ 9.0.a.", -" b.c.d.! ! ! ! ! ! ! ! ! e.f.g.", -" h.i.j.k.H l.m.n.o.p.q.a.r. ", -" "}; diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/gear.xpm b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/gear.xpm deleted file mode 100644 index edebbc4367..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/gear.xpm +++ /dev/null @@ -1,24 +0,0 @@ -/* XPM */ -static const char * gear_xpm[] = { -/* columns rows colors chars-per-pixel */ -"16 16 2 1", -" c #000000", -". c None", -/* pixels */ -"....... .......", -"....... .......", -".. .. .. ..", -".. ..", -"... .... ...", -"... ...... ...", -".. ........ ..", -" ........ ", -" ........ ", -".. ........ ..", -"... ...... ...", -"... .... ...", -".. ..", -".. .. .. ..", -"....... .......", -"....... ......." -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/wWidgets_NOTICES.txt b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/wWidgets_NOTICES.txt deleted file mode 100644 index 5e8ea4b43e..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/wWidgets_NOTICES.txt +++ /dev/null @@ -1,49 +0,0 @@ -Portions based on WWidgets and Yasli Serialization Library - -wWidgets - Lightweight UI Toolkit. -Copyright (C) 2009-2011 Evgeny Andreeshchev - Alexander Kotliar - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - - -Yasli Serialization Library -Copyright (c) 2007 Eugene Andreeshchev - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/warning.xpm b/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/warning.xpm deleted file mode 100644 index 84626cbd9c..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QPropertyTree/warning.xpm +++ /dev/null @@ -1,134 +0,0 @@ -/* XPM */ -static const char * warning_xpm[] = { -"16 16 115 2", -" c None", -". c #EBBC3C", -"+ c #EABA3A", -"@ c #F1D485", -"# c #F0D182", -"$ c #E7B537", -"% c #E9BA3A", -"& c #FDFAF1", -"* c #FAEFD5", -"= c #E6B235", -"- c #E9B93A", -"; c #F2D894", -"> c #FEFCF3", -", c #FEFAE7", -"' c #F0D38F", -") c #E3AC31", -"! c #E8B738", -"~ c #FFFDF9", -"{ c #F9E994", -"] c #FAEB9E", -"^ c #FEFAEC", -"/ c #E1A92F", -"( c #F4DFA9", -"_ c #FDF9ED", -": c #D6A33E", -"< c #FCF5D4", -"[ c #F1D7A2", -"} c #DEA32B", -"| c #E6B436", -"1 c #EDC871", -"2 c #FFFEF9", -"3 c #F4DC5E", -"4 c #D5A23E", -"5 c #F4D95C", -"6 c #FEFBED", -"7 c #E5BB68", -"8 c #D99924", -"9 c #F7EAC8", -"0 c #FDFAE6", -"a c #F4DA5D", -"b c #D5A13D", -"c c #F2D757", -"d c #FCF3C7", -"e c #F4E3C0", -"f c #E6B336", -"g c #F0D28C", -"h c #FEFBEA", -"i c #F8E694", -"j c #F4DA5C", -"k c #DDB147", -"l c #F2D756", -"m c #F5DB5C", -"n c #FDF8DE", -"o c #E7C07D", -"p c #D48E1D", -"q c #E5B134", -"r c #FEFBF3", -"s c #FBF2C3", -"t c #F6DC5C", -"u c #F6DF64", -"v c #EBCB57", -"w c #F2D655", -"x c #F5D954", -"y c #F8E794", -"z c #FBF4E3", -"A c #D08717", -"B c #E5B034", -"C c #F1D79D", -"D c #FDF9E7", -"E c #F8E58B", -"F c #F6DB5A", -"G c #F4DA5B", -"H c #F2D654", -"I c #F5D852", -"J c #F4D650", -"K c #FCF6D8", -"L c #E5BF88", -"M c #C9790E", -"N c #E3AD31", -"O c #E8BF62", -"P c #FEFCF4", -"Q c #FAEFB5", -"R c #F5DA58", -"S c #F3D857", -"T c #F2D758", -"U c #F2D658", -"V c #F4D957", -"W c #F5D851", -"X c #F4D74E", -"Y c #F6DA62", -"Z c #D29344", -"` c #C36D06", -" . c #F5E3BE", -".. c #FEFBEF", -"+. c #FEFBEE", -"@. c #FEFCEF", -"#. c #FEFBEC", -"$. c #FEFCF2", -"%. c #EBCEAB", -"&. c #C16803", -"*. c #E2AA2F", -"=. c #E0A72D", -"-. c #DFA42B", -";. c #DDA129", -">. c #DC9E27", -",. c #DA9B25", -"'. c #D99823", -"). c #D69320", -"!. c #D38C1B", -"~. c #CF8516", -"{. c #CC7E11", -"]. c #C9770D", -"^. c #C67109", -"/. c #C36C06", -"(. c #BF6400", -" ", -" . + ", -" . @ # $ ", -" % & * = ", -" - ; > , ' ) ", -" ! ~ { ] ^ / ", -" ! ( _ : : < [ } ", -" | 1 2 3 4 4 5 6 7 8 ", -" | 9 0 a b b c d e 8 ", -" f g h i j k b l m n o p ", -" q r s t j u v w x y z A ", -" B C D E F G b b H I J K L M ", -"N O P Q R R S T U V W X Y h Z ` ", -"N .P ..+.+.@.@...+.6 6 #.$.%.&.", -"*.=.-.;.>.,.'.).!.~.{.].^./.&.(.", -" "}; diff --git a/Code/Sandbox/Plugins/EditorCommon/QViewport.cpp b/Code/Sandbox/Plugins/EditorCommon/QViewport.cpp deleted file mode 100644 index 36f9511e60..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QViewport.cpp +++ /dev/null @@ -1,913 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "QViewport.h" -#include "QViewportEvents.h" -#include "QViewportConsumer.h" -#include "QViewportSettings.h" -#include "Serialization.h" - -#include -#include -#include - -#include - -// Class to implement the WindowRequestBus::Handler instead of the QViewport class. -// This is to bypass a link warning that occurs in unity builds if EditorCommon dll -// is linked along with a gem that also implements WindowRequestBus::Handler. The -// issue is that QViewport has a dllexport so it causes duplicate code to be linked -// in and a warning that there will be two of the same symbol in memory -class QViewportRequests - : public AzFramework::WindowRequestBus::Handler -{ -public: - QViewportRequests(QViewport& viewport) - : m_viewport(viewport) - { - } - - ~QViewportRequests() override - { - AzFramework::WindowRequestBus::Handler::BusDisconnect(); - } - - // WindowRequestBus::Handler... - void SetWindowTitle(const AZStd::string& title) override - { - m_viewport.SetWindowTitle(title); - } - - AzFramework::WindowSize GetClientAreaSize() const override - { - return m_viewport.GetClientAreaSize(); - } - - void ResizeClientArea(AzFramework::WindowSize clientAreaSize) override - { - m_viewport.ResizeClientArea(clientAreaSize); - } - - bool GetFullScreenState() const override - { - return m_viewport.GetFullScreenState(); - } - - void SetFullScreenState(bool fullScreenState) override - { - m_viewport.SetFullScreenState(fullScreenState); - } - - bool CanToggleFullScreenState() const override - { - return m_viewport.CanToggleFullScreenState(); - } - - void ToggleFullScreenState() override - { - m_viewport.ToggleFullScreenState(); - } - -private: - QViewport& m_viewport; -}; - -struct QViewport::SPreviousContext -{ - CCamera renderCamera; - CCamera systemCamera; - int width; - int height; - HWND window; - bool isMainViewport; -}; - -struct QViewport::SPrivate -{ - CDLight m_VPLight0; - CDLight m_sun; -}; - -QViewport::QViewport(QWidget* parent, StartupMode startupMode) - : QWidget(parent) - , m_renderContextCreated(false) - , m_updating(false) - , m_width(0) - , m_height(0) - , m_fastMode(false) - , m_slowMode(false) - , m_lastTime(0) - , m_lastFrameTime(0.0f) - , m_averageFrameTime(0.0f) - , m_sceneDimensions(1.0f, 1.0f, 1.0f) - , m_creatingRenderContext(false) - , m_timer(0) - , m_cameraSmoothPosRate(0) - , m_cameraSmoothRotRate(0) - , m_settings(new SViewportSettings()) - , m_state(new SViewportState()) - , m_useArrowsForNavigation(true) - , m_mouseMovementsSinceLastFrame(0) - , m_private(new SPrivate()) - , m_cameraControlMode(CameraControlMode::NONE) -{ - m_viewportRequests = AZStd::make_unique(*this); - - if (startupMode & StartupMode_Immediate) - Startup(); -} - -void QViewport::Startup() -{ - m_frameTimer = new QElapsedTimer(); - - m_camera.reset(new CCamera()); - ResetCamera(); - - m_mousePressPos = QCursor::pos(); - - UpdateBackgroundColor(); - - setUpdatesEnabled(false); - setMouseTracking(true); - m_LightRotationRadian = 0; - m_frameTimer->start(); -} - -QViewport::~QViewport() -{ - m_viewportRequests.reset(); -} - -void QViewport::UpdateBackgroundColor() -{ - QPalette pal(palette()); - pal.setColor(QPalette::Window, QColor(m_settings->background.topColor.r, - m_settings->background.topColor.g, - m_settings->background.topColor.b, - m_settings->background.topColor.a)); - setPalette(pal); - setAutoFillBackground(true); -} - -bool QViewport::ScreenToWorldRay(Ray* ray, int x, int y) -{ - AZ_UNUSED(ray); - AZ_UNUSED(x); - AZ_UNUSED(y); - return false; -} - -QPoint QViewport::ProjectToScreen(const Vec3&) -{ - return QPoint(0, 0); -} - -void QViewport::LookAt(const Vec3& target, float radius, bool snap) -{ - QuatT cameraTarget = m_state->cameraTarget; - CreateLookAt(target, radius, cameraTarget); - CameraMoved(cameraTarget, snap); -} - -int QViewport::Width() const -{ - return rect().width(); -} - -int QViewport::Height() const -{ - return rect().height(); -} - -void QViewport::Serialize(IArchive& ar) -{ - if (!ar.IsEdit()) - { - ar(m_state->cameraTarget, "cameraTarget", "Camera Target"); - } -} - -struct AutoBool -{ - AutoBool(bool* value) - : m_value(value) - { - * m_value = true; - } - - ~AutoBool() - { - * m_value = false; - } - - bool* m_value; -}; - -void QViewport::Update() -{ - int64 time = m_frameTimer->elapsed(); - if (m_lastTime == 0) - { - m_lastTime = time; - } - m_lastFrameTime = (time - m_lastTime) * 0.001f; - m_lastTime = time; - if (m_averageFrameTime == 0.0f) - { - m_averageFrameTime = m_lastFrameTime; - } - else - { - m_averageFrameTime = 0.01f * m_lastFrameTime + 0.99f * m_averageFrameTime; - } -} - -void QViewport::CaptureMouse() -{ - grabMouse(); -} - -void QViewport::ReleaseMouse() -{ - releaseMouse(); -} - -void QViewport::SetForegroundUpdateMode([[maybe_unused]] bool foregroundUpdate) -{ - //m_timer->setInterval(foregroundUpdate ? 2 : 50); -} - -CCamera* QViewport::Camera() const -{ - return m_camera.get(); -} - -void QViewport::SetSceneDimensions(const Vec3& size) -{ - m_sceneDimensions = size; -} - -const SViewportSettings& QViewport::GetSettings() const -{ - return *m_settings; -} - -const SViewportState& QViewport::GetState() const -{ - return *m_state; -} - -void QViewport::SetSize(const QSize& size) -{ - m_width = size.width(); - m_height = size.height(); -} - -float QViewport::GetLastFrameTime() -{ - return m_lastFrameTime; -} - - -void QViewport::ProcessMouse() -{ - QPoint point = mapFromGlobal(QCursor::pos()); - - if (point == m_mousePressPos) - { - return; - } - - if (m_cameraControlMode == CameraControlMode::ZOOM) - { - if (!(m_settings->camera.transformRestraint & eCameraTransformRestraint_Zoom)) - { - float speedScale = CalculateMoveSpeed(m_fastMode, m_slowMode, true); - - // Zoom. - QuatT qt = m_state->cameraTarget; - Vec3 ydir = qt.GetColumn1().GetNormalized(); - Vec3 pos = qt.t; - pos = pos - 0.2f * ydir * aznumeric_cast(m_mousePressPos.y() - point.y()) * speedScale; - qt.t = pos; - CameraMoved(qt, false); - - // Check to see if the orbit target is behind the camera's view - // position - Vec3 target = m_state->orbitTarget; - Vec3 at = target - pos; - float isAlmostBehind = at * ydir; - if (isAlmostBehind < 0.01f) - { - // Force the orbit target to be slightly in front of the view - // position - m_state->orbitRadius = 0.01f; - m_state->orbitTarget = qt.t + ydir * 0.01f; - } - else - { - m_state->orbitRadius = at.GetLength(); - } - - AzQtComponents::SetCursorPos(mapToGlobal(m_mousePressPos)); - } - } - else if (m_cameraControlMode == CameraControlMode::ROTATE) - { - if (!(m_settings->camera.transformRestraint & eCameraTransformRestraint_Rotation)) - { - Ang3 angles(aznumeric_cast(-point.y() + m_mousePressPos.y()), 0, aznumeric_cast(-point.x() + m_mousePressPos.x())); - angles = angles * 0.001f * m_settings->camera.rotationSpeed; - - QuatT qt = m_state->cameraTarget; - Ang3 ypr = CCamera::CreateAnglesYPR(Matrix33(qt.q)); - ypr.x += angles.z; - ypr.y += angles.x; - ypr.y = clamp_tpl(ypr.y, -1.5f, 1.5f); - - qt.q = Quat(CCamera::CreateOrientationYPR(ypr)); - - // Move the orbit target with the rotate operation. - float distanceFromTarget = (qt.t - m_state->orbitTarget).GetLength(); - Vec3 ydir = qt.GetColumn1().GetNormalized(); - m_state->orbitTarget = qt.t + ydir * distanceFromTarget; - - CameraMoved(qt, false); - - AzQtComponents::SetCursorPos(mapToGlobal(m_mousePressPos)); - } - } - else if (m_cameraControlMode == CameraControlMode::PAN) - { - if (!(m_settings->camera.transformRestraint & eCameraTransformRestraint_Panning)) - { - float speedScale = CalculateMoveSpeed(m_fastMode, m_slowMode, true) * 3; - speedScale = max(0.1f, speedScale); - - // Slide. - QuatT qt = m_state->cameraTarget; - Vec3 xdir = qt.GetColumn0().GetNormalized(); - Vec3 zdir = qt.GetColumn2().GetNormalized(); - - Vec3 delta = 0.0025f * xdir * aznumeric_cast(point.x() - m_mousePressPos.x()) * speedScale + 0.0025f * zdir * aznumeric_cast(m_mousePressPos.y() - point.y()) * speedScale; - qt.t += delta; - - // Move the orbit target with the pan operation. This ensures the - // center of the orbit moves with the camera as it pans. - m_state->orbitTarget += delta; - - CameraMoved(qt, false); - - AzQtComponents::SetCursorPos(mapToGlobal(m_mousePressPos)); - } - } - else if (m_cameraControlMode == CameraControlMode::ORBIT) - { - // Rotate around orbit target. - QuatT cameraTarget = m_state->cameraTarget; - Vec3 at = cameraTarget.t - m_state->orbitTarget; - float distanceFromTarget = at.GetLength(); - if (distanceFromTarget > 0.001f) - { - at /= distanceFromTarget; - } - else - { - at = Vec3(0.0f, m_state->orbitRadius, 0.0f); - distanceFromTarget = m_state->orbitRadius; - } - - Vec3 up = Vec3(0.0f, 0.0f, 1.0f); - const Vec3 right = at.Cross(up).GetNormalized(); - up = right.Cross(at).GetNormalized(); - - Ang3 angles = CCamera::CreateAnglesYPR(Matrix33::CreateFromVectors(right, at, up)); - const Ang3 delta = Ang3(aznumeric_cast(-point.y() + m_mousePressPos.y()), 0.0f, aznumeric_cast(-point.x() + m_mousePressPos.x())) * 0.002f * m_settings->camera.rotationSpeed; - angles.x += delta.z; - angles.y -= delta.x; - angles.y = clamp_tpl(angles.y, -1.5f, 1.5f); - - cameraTarget.t = m_state->orbitTarget + CCamera::CreateOrientationYPR(angles).TransformVector(Vec3(0.0f, distanceFromTarget, 0.0f)); - m_state->orbitRadius = distanceFromTarget; - - CameraMoved(cameraTarget, true); - - AzQtComponents::SetCursorPos(mapToGlobal(m_mousePressPos)); - } -} - -void QViewport::ProcessKeys() -{ - if (!m_renderContextCreated) - { - return; - } - - float deltaTime = m_lastFrameTime; - - if (deltaTime > 0.1f) - { - deltaTime = 0.1f; - } - - QuatT qt = m_state->cameraTarget; - Vec3 ydir = qt.GetColumn1().GetNormalized(); - Vec3 xdir = qt.GetColumn0().GetNormalized(); - Vec3 pos = qt.t; - - float moveSpeed = CalculateMoveSpeed(m_fastMode, m_slowMode); - bool hasPressedKey = false; - - if ((m_useArrowsForNavigation && CheckVirtualKey(Qt::Key_Up)) || CheckVirtualKey(Qt::Key_W)) - { - hasPressedKey = true; - Vec3 delta = deltaTime * moveSpeed * ydir; - qt.t += delta; - m_state->orbitTarget += delta; - CameraMoved(qt, false); - } - - if ((m_useArrowsForNavigation && CheckVirtualKey(Qt::Key_Down)) || CheckVirtualKey(Qt::Key_S)) - { - hasPressedKey = true; - Vec3 delta = deltaTime * moveSpeed * ydir; - qt.t -= delta; - m_state->orbitTarget -= delta; - CameraMoved(qt, false); - } - - if (m_cameraControlMode != CameraControlMode::ORBIT && ((m_useArrowsForNavigation && CheckVirtualKey(Qt::Key_Left)) || CheckVirtualKey(Qt::Key_A))) - { - hasPressedKey = true; - Vec3 delta = deltaTime * moveSpeed * xdir; - qt.t -= delta; - m_state->orbitTarget -= delta; - CameraMoved(qt, false); - } - - if (m_cameraControlMode != CameraControlMode::ORBIT && ((m_useArrowsForNavigation && CheckVirtualKey(Qt::Key_Right)) || CheckVirtualKey(Qt::Key_D))) - { - hasPressedKey = true; - Vec3 delta = deltaTime * moveSpeed * xdir; - qt.t += delta; - m_state->orbitTarget += delta; - CameraMoved(qt, false); - } - - if (CheckVirtualKey(Qt::RightButton) | CheckVirtualKey(Qt::MiddleButton)) - { - hasPressedKey = true; - } -} - -void QViewport::CameraMoved(QuatT qt, bool snap) -{ - if (m_cameraControlMode == CameraControlMode::ORBIT) - { - CreateLookAt(m_state->orbitTarget, m_state->orbitRadius, qt); - } - m_state->cameraTarget = qt; - if (snap) - { - m_state->lastCameraTarget = qt; - } - SignalCameraMoved(qt); -} - -void QViewport::OnKeyEvent(const SKeyEvent& ev) -{ - for (size_t i = 0; i < m_consumers.size(); ++i) - { - m_consumers[i]->OnViewportKey(ev); - } - SignalKey(ev); -} - -void QViewport::OnMouseEvent(const SMouseEvent& ev) -{ - if (ev.type == SMouseEvent::EType::TYPE_MOVE) - { - // Make sure we don't process more than one mouse event per frame, so we don't - // end up consuming all the "idle" time - ++m_mouseMovementsSinceLastFrame; - - if (m_mouseMovementsSinceLastFrame > 1) - { - // we can't discard all movement events, the last one should be delivered. - m_pendingMouseMoveEvent = ev; - return; - } - } - - for (size_t i = 0; i < m_consumers.size(); ++i) - { - m_consumers[i]->OnViewportMouse(ev); - } - SignalMouse(ev); -} - -void QViewport::PreRender() -{ - SRenderContext rc; - rc.camera = m_camera.get(); - rc.viewport = this; - - SignalPreRender(rc); - - - const float fov = DEG2RAD(m_settings->camera.fov); - const float fTime = m_lastFrameTime; - float lastRotWeight = 0.0f; - - QuatT targetTM = m_state->cameraTarget; - QuatT currentTM = m_state->lastCameraTarget; - - if ((targetTM.t - currentTM.t).len() > 0.0001f) - { - SmoothCD(currentTM.t, m_cameraSmoothPosRate, fTime, targetTM.t, m_settings->camera.smoothPos); - } - else - { - m_cameraSmoothPosRate = Vec3(0); - } - - SmoothCD(lastRotWeight, m_cameraSmoothRotRate, fTime, 1.0f, m_settings->camera.smoothRot); - - if (lastRotWeight >= 1.0f) - { - m_cameraSmoothRotRate = 0.0f; - } - - currentTM = QuatT(Quat::CreateNlerp(currentTM.q, targetTM.q, lastRotWeight), currentTM.t); - - m_state->lastCameraParentFrame = m_state->cameraParentFrame; - m_state->lastCameraTarget = currentTM; - - m_camera->SetFrustum(m_width, m_height, fov, m_settings->camera.nearClip); - m_camera->SetMatrix(Matrix34(m_state->cameraParentFrame * currentTM)); -} - -void QViewport::Render() -{ -} - -void QViewport::RenderInternal() -{ -} - -void QViewport::SetWindowTitle(const AZStd::string& title) -{ - // Do not support the WindowRequestBus changing the editor window title - AZ_UNUSED(title); -} - -AzFramework::WindowSize QViewport::GetClientAreaSize() const -{ - const QWidget* window = this->window(); - QSize windowSize = window->size(); - return AzFramework::WindowSize(windowSize.width(), windowSize.height()); -} - -void QViewport::ResizeClientArea(AzFramework::WindowSize clientAreaSize) -{ - QWidget* window = this->window(); - window->resize(aznumeric_cast(clientAreaSize.m_width), aznumeric_cast(clientAreaSize.m_height)); -} - -bool QViewport::GetFullScreenState() const -{ - // QViewport does not currently support full screen. - return false; -} - -void QViewport::SetFullScreenState([[maybe_unused]]bool fullScreenState) -{ - // QViewport does not currently support full screen. -} - -bool QViewport::CanToggleFullScreenState() const -{ - // QViewport does not currently support full screen. - return false; -} - -void QViewport::ToggleFullScreenState() -{ - // QViewport does not currently support full screen. -} - -void QViewport::ResetCamera() -{ - *m_state = SViewportState(); - m_camera->SetMatrix(Matrix34(m_state->cameraTarget)); -} - -void QViewport::SetSettings(const SViewportSettings& settings) -{ - *m_settings = settings; -} - -void QViewport::SetState(const SViewportState& state) -{ - *m_state = state; -} - -float QViewport::CalculateMoveSpeed(bool shiftPressed, bool ctrlPressed, bool scaleWithOrbitDistance) const -{ - // The value used to caculate speedScale respects the value used in RenderViewPort. - // Please refer to the function: CRenderViewport::ProcessKeys().-- Vera, Confetti - float speedScale = 20; - - speedScale *= m_settings->camera.moveSpeed; - - float moveSpeed = speedScale; - - if (shiftPressed) - { - moveSpeed *= m_settings->camera.fastMoveMultiplier; - } - if (ctrlPressed) - { - moveSpeed *= m_settings->camera.slowMoveMultiplier; - } - if (scaleWithOrbitDistance) - { - // Slow the movement down as we get closer to the orbit target - QuatT qt = m_state->cameraTarget; - float distanceFromTarget = (qt.t - m_state->orbitTarget).GetLength(); - moveSpeed *= distanceFromTarget * 0.01f; - // Prevent the speed from going too close to 0, which would prevent movement - moveSpeed = max(0.001f, moveSpeed); - } - - return moveSpeed; -} - -void QViewport::CreateLookAt(const Vec3& target, float radius, QuatT& cameraTarget) const -{ - Vec3 at = target - cameraTarget.t; - float distanceFromTarget = at.GetLength(); - if (distanceFromTarget > 0.001f) - { - at /= distanceFromTarget; - } - else - { - at = Vec3(0.0f, radius, 0.0f); - distanceFromTarget = radius; - } - if (distanceFromTarget < radius) - { - distanceFromTarget = radius; - cameraTarget.t = target - (at * radius); - } - Vec3 up = Vec3(0.0f, 0.0f, 1.0f); - const Vec3 right = at.Cross(up).GetNormalized(); - up = right.Cross(at).GetNormalized(); - cameraTarget.q = Quat(Matrix33::CreateFromVectors(right, at, up)); -} - -void QViewport::UpdateCameraControlMode(QMouseEvent* ev) -{ - Qt::MouseButton mouseButton = ev->button(); - Qt::KeyboardModifiers modifiers = ev->modifiers(); - if (mouseButton & Qt::RightButton && mouseButton & Qt::MiddleButton) - { - m_cameraControlMode = CameraControlMode::ZOOM; - } - else if (mouseButton == Qt::MiddleButton) - { - if (modifiers & Qt::ALT) - { - m_cameraControlMode = CameraControlMode::ORBIT; - } - else - { - if (m_cameraControlMode == CameraControlMode::ROTATE) - { - m_cameraControlMode = CameraControlMode::ZOOM; - } - else - { - m_cameraControlMode = CameraControlMode::PAN; - } - } - } - else if (mouseButton == Qt::RightButton) - { - if (m_cameraControlMode == CameraControlMode::PAN || (modifiers & Qt::ALT)) - { - m_cameraControlMode = CameraControlMode::ZOOM; - } - else - { - m_cameraControlMode = CameraControlMode::ROTATE; - } - } - else - { - m_cameraControlMode = CameraControlMode::NONE; - } -} - -void QViewport::mousePressEvent(QMouseEvent* ev) -{ - SMouseEvent me; - me.type = SMouseEvent::TYPE_PRESS; - me.button = SMouseEvent::EButton(ev->button()); - me.x = ev->x(); - me.y = ev->y(); - me.viewport = this; - me.shift = (ev->modifiers() & Qt::SHIFT) != 0; - me.control = (ev->modifiers() & Qt::CTRL) != 0; - OnMouseEvent(me); - - QWidget::mousePressEvent(ev); - setFocus(); - - m_mousePressPos = ev->pos(); - - UpdateCameraControlMode(ev); - if (m_cameraControlMode != CameraControlMode::NONE) - { - QApplication::setOverrideCursor(Qt::BlankCursor); - } -} - -void QViewport::mouseReleaseEvent(QMouseEvent* ev) -{ - SMouseEvent me; - me.type = SMouseEvent::TYPE_RELEASE; - me.button = SMouseEvent::EButton(ev->button()); - me.x = ev->x(); - me.y = ev->y(); - me.viewport = this; - OnMouseEvent(me); - - m_cameraControlMode = CameraControlMode::NONE; - QWidget::mouseReleaseEvent(ev); - QApplication::restoreOverrideCursor(); -} - -void QViewport::wheelEvent(QWheelEvent* ev) -{ - QuatT qt = m_state->cameraTarget; - Vec3 ydir = qt.GetColumn1().GetNormalized(); - Vec3 pos = qt.t; - const float wheelSpeed = m_settings->camera.zoomSpeed * (m_fastMode ? m_settings->camera.fastMoveMultiplier : 1.0f) * (m_slowMode ? m_settings->camera.slowMoveMultiplier : 1.0f); - pos += 0.01f * ydir * aznumeric_cast(ev->angleDelta().y()) * wheelSpeed; - qt.t = pos; - CameraMoved(qt, false); -} - -void QViewport::mouseMoveEvent(QMouseEvent* ev) -{ - SMouseEvent me; - me.type = SMouseEvent::TYPE_MOVE; - me.button = SMouseEvent::EButton(ev->button()); - me.x = ev->x(); - me.y = ev->y(); - me.viewport = this; - m_fastMode = (ev->modifiers() & Qt::SHIFT) != 0; - m_slowMode = (ev->modifiers() & Qt::CTRL) != 0; - OnMouseEvent(me); - - QWidget::mouseMoveEvent(ev); -} - -void QViewport::keyPressEvent(QKeyEvent* ev) -{ - SKeyEvent event; - event.type = SKeyEvent::TYPE_PRESS; - event.key = ev->key() | ev->modifiers(); - m_fastMode = (ev->modifiers() & Qt::SHIFT) != 0; - m_slowMode = (ev->modifiers() & Qt::CTRL) != 0; - OnKeyEvent(event); - - QWidget::keyPressEvent(ev); -} - -void QViewport::keyReleaseEvent(QKeyEvent* ev) -{ - SKeyEvent event; - event.type = SKeyEvent::TYPE_RELEASE; - event.key = ev->key() | ev->modifiers(); - m_fastMode = (ev->modifiers() & Qt::SHIFT) != 0; - m_slowMode = (ev->modifiers() & Qt::CTRL) != 0; - OnKeyEvent(event); - QWidget::keyReleaseEvent(ev); -} - -void QViewport::resizeEvent(QResizeEvent* ev) -{ - QWidget::resizeEvent(ev); - -#if defined(AZ_PLATFORM_WINDOWS) - // Needed for high DPI mode on windows - const qreal ratio = devicePixelRatioF(); -#else - const qreal ratio = 1.0f; -#endif - int cx = aznumeric_cast(ev->size().width() * ratio); - int cy = aznumeric_cast(ev->size().height() * ratio); - if (cx == 0 || cy == 0) - { - return; - } - - m_width = cx; - m_height = cy; - - GetIEditor()->GetEnv()->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_RESIZE, cx, cy); - SignalUpdate(); - Update(); -} - -void QViewport::showEvent(QShowEvent* ev) -{ - QWidget::showEvent(ev); -} - -void QViewport::moveEvent(QMoveEvent* ev) -{ - QWidget::moveEvent(ev); - - GetIEditor()->GetEnv()->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_MOVE, ev->pos().x(), ev->pos().y()); -} - -bool QViewport::event(QEvent* ev) -{ - bool result = QWidget::event(ev); - - if (ev->type() == QEvent::ShortcutOverride) - { - // When a shortcut is matched, Qt's event processing sends out a shortcut override event - // to allow other systems to override it. If it's not overridden, then the key events - // get processed as a shortcut, even if the widget that's the target has a keyPress event - // handler. So, we need to communicate that we've processed the shortcut override - // which will tell Qt not to process it as a shortcut and instead pass along the - // keyPressEvent. - - QKeyEvent* keyEvent = static_cast(ev); - QKeySequence key(keyEvent->key() | keyEvent->modifiers()); - - for (size_t i = 0; i < m_consumers.size(); ++i) - { - if (m_consumers[i]->ProcessesViewportKey(key)) - { - ev->accept(); - return true; - } - } - } - - return result; -} - -void QViewport::paintEvent(QPaintEvent* ev) -{ - QWidget::paintEvent(ev); -} - -void QViewport::AddConsumer(QViewportConsumer* consumer) -{ - RemoveConsumer(consumer); - m_consumers.push_back(consumer); -} - -void QViewport::RemoveConsumer(QViewportConsumer* consumer) -{ - m_consumers.erase(std::remove(m_consumers.begin(), m_consumers.end(), consumer), m_consumers.end()); -} - -void QViewport::SetUseArrowsForNavigation(bool useArrowsForNavigation) -{ - m_useArrowsForNavigation = useArrowsForNavigation; -} - diff --git a/Code/Sandbox/Plugins/EditorCommon/QViewport.h b/Code/Sandbox/Plugins/EditorCommon/QViewport.h deleted file mode 100644 index 5566edc126..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QViewport.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#include - -#include -#include -#include "EditorCommonAPI.h" -#include "QViewportEvents.h" - -#include - -class CImageEx; -struct DisplayContext; -class CCamera; -struct SRenderingPassInfo; -struct SRendParams; -struct Ray; -struct IRenderer; -struct SSystemGlobalEnvironment; -namespace Serialization { - class IArchive; -} -using Serialization::IArchive; -using std::unique_ptr; - -struct SKeyEvent; -struct SMouseEvent; -struct SViewportSettings; -struct SViewportState; -class QElapsedTimer; -class QViewportRequests; - -class EDITOR_COMMON_API QViewport; -struct SRenderContext -{ - CCamera* camera; - QViewport* viewport; - SRendParams* renderParams; - SRenderingPassInfo* passInfo; -}; - -enum class CameraControlMode -{ - NONE, - PAN, - ROTATE, - ZOOM, - ORBIT -}; - - -class QViewportConsumer; -AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -class EDITOR_COMMON_API QViewport - : public QWidget -{ - Q_OBJECT -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING -public: - - enum StartupMode { - StartupMode_Immediate = 1, // Startup() will be called by QViewport's CTOR - StartupMode_Manual // Startup() will be called by the derived class - }; - - explicit QViewport(QWidget* parent, StartupMode startupMode = StartupMode_Immediate); - virtual ~QViewport(); - void Startup(); - - void AddConsumer(QViewportConsumer* consumer); - void RemoveConsumer(QViewportConsumer* consumer); - - void CaptureMouse(); - void ReleaseMouse(); - void SetForegroundUpdateMode(bool foregroundUpdate); - CCamera* Camera() const; - void ResetCamera(); - void Serialize(IArchive& ar); - - void SetUseArrowsForNavigation(bool useArrowsForNavigation); - void SetSceneDimensions(const Vec3& size); - void SetSettings(const SViewportSettings& settings); - const SViewportSettings& GetSettings() const; - void SetState(const SViewportState& state); - const SViewportState& GetState() const; - bool ScreenToWorldRay(Ray* ray, int x, int y); - QPoint ProjectToScreen(const Vec3& point); - void LookAt(const Vec3& target, float radius, bool snap); - - int Width() const; - int Height() const; - void SetSize(const QSize& size); - - // WindowRequestBus::Handler... (handler moved to cpp to resolve link issues in unity builds) - void SetWindowTitle(const AZStd::string& title); - AzFramework::WindowSize GetClientAreaSize() const; - void ResizeClientArea(AzFramework::WindowSize clientAreaSize); - bool GetFullScreenState() const; - void SetFullScreenState(bool fullScreenState); - bool CanToggleFullScreenState() const; - void ToggleFullScreenState(); - -public slots: - void Update(); -protected slots: - void RenderInternal(); -signals: - void SignalPreRender(const SRenderContext&); - void SignalRender(const SRenderContext&); - void SignalKey(const SKeyEvent&); - void SignalMouse(const SMouseEvent&); - void SignalUpdate(); - void SignalCameraMoved(const QuatT& qt); -protected: - void mousePressEvent(QMouseEvent* ev) override; - void mouseReleaseEvent(QMouseEvent* ev) override; - void wheelEvent(QWheelEvent* ev) override; - void mouseMoveEvent(QMouseEvent* ev) override; - void keyPressEvent(QKeyEvent* ev) override; - void keyReleaseEvent(QKeyEvent* ev) override; - void resizeEvent(QResizeEvent* ev) override; - void showEvent(QShowEvent* ev) override; - void moveEvent(QMoveEvent* ev) override; - void paintEvent(QPaintEvent* ev) override; - bool event(QEvent* ev) override; - - void CameraMoved(QuatT qt, bool snap); //Confetti: Jurecka ... making this protected so can adjust camera to focus on items in derived class. - - float GetLastFrameTime(); -private: - struct SPrivate; - -private: - void UpdateBackgroundColor(); - - void ProcessMouse(); - void ProcessKeys(); - void PreRender(); - void Render(); - void OnMouseEvent(const SMouseEvent& ev); - void OnKeyEvent(const SKeyEvent& ev); - float CalculateMoveSpeed(bool shiftPressed, bool ctrlPressed, bool scaleWithOrbitDistance = false) const; - void CreateLookAt(const Vec3& target, float radius, QuatT& cameraTarget) const; - void UpdateCameraControlMode(QMouseEvent* ev); - - struct SPreviousContext; - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - std::vector m_previousContexts; - std::unique_ptr m_camera; - QElapsedTimer* m_frameTimer; - QTimer* m_timer; - int m_width; - int m_height; - QPoint m_mousePressPos; - int64 m_lastTime; - float m_lastFrameTime; - float m_averageFrameTime; - bool m_useArrowsForNavigation; - bool m_renderContextCreated; - bool m_creatingRenderContext; - bool m_updating; - bool m_fastMode; - bool m_slowMode; - CameraControlMode m_cameraControlMode; - - Vec3 m_cameraSmoothPosRate; - float m_cameraSmoothRotRate; - int m_mouseMovementsSinceLastFrame; - f32 m_LightRotationRadian; - SMouseEvent m_pendingMouseMoveEvent; - - Vec3 m_sceneDimensions; - std::unique_ptr m_private; - std::unique_ptr m_settings; - std::unique_ptr m_state; - std::vector m_consumers; - AZStd::unique_ptr m_viewportRequests; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -}; diff --git a/Code/Sandbox/Plugins/EditorCommon/QViewportConsumer.h b/Code/Sandbox/Plugins/EditorCommon/QViewportConsumer.h deleted file mode 100644 index 61d81b8dbf..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QViewportConsumer.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_QVIEWPORTCONSUMER_H -#define CRYINCLUDE_EDITORCOMMON_QVIEWPORTCONSUMER_H - -struct SRenderContext; -struct SKeyEvent; -struct SMouseEvent; -class QKeySequence; - -class QViewportConsumer -{ -public: - virtual ~QViewportConsumer() = default; - virtual void OnViewportRender([[maybe_unused]] const SRenderContext& rc) {} - - // If you're overriding OnViewportKey, you should also override ProcessesViewportKey and return true if you're interested in a particular key. - // If you don't, then registered shortcuts get keyPressed events first, and in many cases will never get passed to OnViewportKey - virtual void OnViewportKey([[maybe_unused]] const SKeyEvent& ev) {} - virtual bool ProcessesViewportKey([[maybe_unused]] const QKeySequence& key) { return false; } - - virtual void OnViewportMouse([[maybe_unused]] const SMouseEvent& ev) {} -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QVIEWPORTCONSUMER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QViewportEvents.h b/Code/Sandbox/Plugins/EditorCommon/QViewportEvents.h deleted file mode 100644 index 8e6e96c62d..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QViewportEvents.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QVIEWPORTEVENTS_H -#define CRYINCLUDE_EDITORCOMMON_QVIEWPORTEVENTS_H -#pragma once - -#include "EditorCommonAPI.h" -class EDITOR_COMMON_API QViewport; - -struct SMouseEvent -{ - enum EType - { - TYPE_NONE, - TYPE_PRESS, - TYPE_RELEASE, - TYPE_MOVE - }; - - enum EButton - { - BUTTON_NONE, - BUTTON_LEFT, - BUTTON_RIGHT, - BUTTON_MIDDLE - }; - - EType type; - int x; - int y; - EButton button; - bool shift; - bool control; - QViewport* viewport; - - SMouseEvent() - : type(TYPE_NONE) - , x(INT_MIN) - , y(INT_MIN) - , button(BUTTON_NONE) - , viewport(0) - , shift(false) - , control(false) - { - } -}; - -struct SSelectionID -{ -}; - -struct SInteractionEvent -{ - enum EType - { - TYPE_NONE, - TYPE_ENTER, - TYPE_LEAVE, - TYPE_DRAG - }; - - SSelectionID selection; - Vec3 start; - Vec3 end; -}; - -struct SKeyEvent -{ - enum EType - { - TYPE_NONE, - TYPE_PRESS, - TYPE_RELEASE - }; - - EType type; - int key; - - SKeyEvent() - : type(TYPE_NONE) - { - } -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QVIEWPORTEVENTS_H diff --git a/Code/Sandbox/Plugins/EditorCommon/QViewportSettings.h b/Code/Sandbox/Plugins/EditorCommon/QViewportSettings.h deleted file mode 100644 index 2a2111144e..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/QViewportSettings.h +++ /dev/null @@ -1,269 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_QVIEWPORTSETTINGS_H -#define CRYINCLUDE_EDITORCOMMON_QVIEWPORTSETTINGS_H -#pragma once - -#include -#include -#include "EditorCommonAPI.h" -#include "Serialization.h" -#include - -namespace Serialization -{ - class IArchive; -}; - -enum ECameraTransformRestraint -{ - eCameraTransformRestraint_Rotation = 0x01, - eCameraTransformRestraint_Panning = 0x02, - eCameraTransformRestraint_Zoom = 0x04 -}; - -struct SViewportState -{ - QuatT cameraTarget; - QuatT cameraParentFrame; - QuatT gridOrigin; - Vec3 gridCellOffset; - QuatT lastCameraTarget; - QuatT lastCameraParentFrame; - - Vec3 orbitTarget; - float orbitRadius; - - - SViewportState() - : cameraParentFrame(IDENTITY) - , gridOrigin(IDENTITY) - , gridCellOffset(0) - , lastCameraTarget(IDENTITY) - , lastCameraParentFrame(IDENTITY) - , orbitTarget(ZERO) - { - // This eye position is similar to Maya's initial camera position - AZ::Transform transform = AZ::Transform::CreateLookAt( - AZ::Vector3(-3.5f, 3.625f, 2.635f), // Eye position - AZ::Vector3(LYVec3ToAZVec3(orbitTarget)) - ); - cameraTarget = AZTransformToLYQuatT(transform); - orbitRadius = cameraTarget.t.GetLength(); - - lastCameraTarget = cameraTarget; - } -}; - -struct SViewportRenderingSettings -{ - bool wireframe; - bool sunlight; // Add setting for time of day feature - Vera, Confetti - bool fps; - - SViewportRenderingSettings() - : wireframe(false) - , fps(true) - , sunlight(false) - { - } - - void Serialize(Serialization::IArchive& ar) - { - ar(wireframe, "wireframe", "Wireframe"); - ar(fps, "fps", "Framerate"); - ar(sunlight, "sunlight", "Sunlight"); - } -}; - -struct SViewportCameraSettings -{ - bool showViewportOrientation; - - float fov; - float nearClip; - float smoothPos; - float smoothRot; - - float moveSpeed; - float rotationSpeed; - float zoomSpeed; - float fastMoveMultiplier; - float slowMoveMultiplier; - - int transformRestraint; - - SViewportCameraSettings() - : showViewportOrientation(true) - , fov(60) - , nearClip(0.01f) - , smoothPos(0.07f) - , smoothRot(0.05f) - , moveSpeed(0.7f) - , rotationSpeed(2.0f) - , zoomSpeed(0.1f) - , fastMoveMultiplier(3.0f) - , slowMoveMultiplier(0.1f) - , transformRestraint(0) - { - } - - void Serialize(Serialization::IArchive& ar) - { - ar(showViewportOrientation, "showViewportOrientation", "Show Viewport Orientation"); - ar(Serialization::Range(fov, 20.0f, 120.0f), "fov", "FOV"); - ar(Serialization::Range(nearClip, 0.01f, 0.5f), "nearClip", "Near Clip"); - ar(Serialization::Range(moveSpeed, 0.1f, 3.0f), "moveSpeed", "Move Speed"); - ar(transformRestraint, "TransformRestraint", "Transform Restraint"); - ar.Doc("Relative to the scene size"); - ar(Serialization::Range(rotationSpeed, 0.1f, 4.0f), "rotationSpeed", "Rotation Speed"); - ar.Doc("Degrees per 1000 px"); - if (ar.OpenBlock("movementSmoothing", "+Movement Smoothing")) - { - ar(smoothPos, "smoothPos", "Position"); - ar(smoothRot, "smoothRot", "Rotation"); - ar.CloseBlock(); - } - } -}; - - -struct SViewportGridSettings -{ - bool showGrid; - bool circular; - ColorB mainColor; - ColorB middleColor; - int alphaFalloff; - float spacing; - uint16 count; - uint16 interCount; - bool origin; - ColorB originColor; - - SViewportGridSettings() - : showGrid(true) - , circular(true) - , mainColor(255, 255, 255, 50) - , middleColor(255, 255, 255, 10) - , alphaFalloff(100) - , spacing(1.0f) - , count(10) - , interCount(10) - , origin(false) - , originColor(10, 10, 10, 255) - { - } - - void Serialize(Serialization::IArchive& ar) - { - ar(showGrid, "showGrid", "Show Grid"); - if (showGrid) - { - ar(circular, "circular", 0); - } - ar(mainColor, "mainColor", "Main Color"); - ar(middleColor, "middleColor", "Middle Color"); - ar(Serialization::Range(alphaFalloff, 0, 100), "alphaFalloff", 0); - ar(spacing, "spacing", "Spacing"); - ar(count, "count", "Main Lines"); - ar(interCount, "interCount", "Middle Lines"); - ar(origin, "origin", "Origin"); - ar(originColor, "originColor", origin ? "Origin Color" : 0); - } -}; - -struct SViewportLightingSettings -{ - f32 m_brightness; - ColorB m_ambientColor; - - bool m_useLightRotation; - f32 m_lightMultiplier; - f32 m_lightSpecMultiplier; - - ColorB m_directionalLightColor; - - SViewportLightingSettings() - { - m_brightness = 1.0f; - m_ambientColor = ColorB(128, 128, 128, 255); - - m_useLightRotation = 0; - m_lightMultiplier = 3.0; - m_lightSpecMultiplier = 2.0f; - - m_directionalLightColor = ColorB(255, 255, 255, 255); - } - - void Serialize(Serialization::IArchive& ar) - { - ar(Serialization::Range(m_brightness, 0.0f, 200.0f), "brightness", "Brightness"); - ar(m_ambientColor, "ambientColor", "Ambient Color"); - - ar(m_useLightRotation, "rotatelight", "Rotate Light"); - ar(m_lightMultiplier, "lightMultiplier", "Light Multiplier"); - ar(m_lightSpecMultiplier, "lightSpecMultiplier", "Light Spec Multiplier"); - - ar(m_directionalLightColor, "directionalLightColor", "Directional Light Color"); - } -}; - -struct SViewportBackgroundSettings -{ - bool useGradient; - ColorB topColor; - ColorB bottomColor; - - SViewportBackgroundSettings() - : useGradient(true) - , topColor(128, 128, 128, 255) - , bottomColor(32, 32, 32, 255) - { - } - - void Serialize(Serialization::IArchive& ar) - { - ar(useGradient, "useGradient", "Use Gradient"); - if (useGradient) - { - ar(topColor, "topColor", "Top Color"); - ar(bottomColor, "bottomColor", "Bottom Color"); - } - else - { - ar(topColor, "topColor", "Color"); - } - } -}; - -struct SViewportSettings -{ - SViewportRenderingSettings rendering; - SViewportCameraSettings camera; - SViewportGridSettings grid; - SViewportLightingSettings lighting; - SViewportBackgroundSettings background; - - void Serialize(Serialization::IArchive& ar) - { - ar(rendering, "debug", "Debug"); - ar(camera, "camera", "Camera"); - ar(grid, "grid", "Grid"); - ar(lighting, "lighting", "Lighting"); - ar(background, "background", "Background"); - } -}; - -#endif // CRYINCLUDE_EDITORCOMMON_QVIEWPORTSETTINGS_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization.cpp b/Code/Sandbox/Plugins/EditorCommon/Serialization.cpp deleted file mode 100644 index 6d3db713c5..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "Serialization.h" diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization.h b/Code/Sandbox/Plugins/EditorCommon/Serialization.h deleted file mode 100644 index b017376355..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_H - -#include -#include - -namespace Serialization { - class IArchive; -} - -struct SkeletonAlias; -bool Serialize(Serialization::IArchive& ar, SkeletonAlias& value, const char* name, const char* label); - -#include -#include -#include -#include -using Serialization::BitFlags; -#include -#include -#include "Serialization/Decorators/ToggleButton.h" -#include "Serialization/Qt.h" -#include -#include - -#include - -using Serialization::IArchive; - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/BinArchive.cpp b/Code/Sandbox/Plugins/EditorCommon/Serialization/BinArchive.cpp deleted file mode 100644 index 9ee929ec55..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/BinArchive.cpp +++ /dev/null @@ -1,839 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "BinArchive.h" -#include -#include "Serialization/ClassFactory.h" - -namespace Serialization { - static const unsigned char SIZE16 = 254; - static const unsigned char SIZE32 = 255; - - static const unsigned int BIN_MAGIC = 0xb1a4c17f; - - //#ifdef _DEBUG - //typedef std::map HashMap; - //static HashMap hashMap; - //#endif - - BinOArchive::BinOArchive() - : IArchive(OUTPUT | BINARY) - { - clear(); - } - - void BinOArchive::clear() - { - stream_.clear(); - stream_.write((const char*)&BIN_MAGIC, sizeof(BIN_MAGIC)); - } - - size_t BinOArchive::length() const - { - return stream_.position(); - } - - bool BinOArchive::save(const char* filename) - { - FILE* f = nullptr; - azfopen(&f, filename, "wb"); - if (!f) - { - return false; - } - - if (fwrite(buffer(), 1, length(), f) != length()) - { - fclose(f); - return false; - } - - fclose(f); - return true; - } - - inline void BinOArchive::openNode(const char* name, bool size8) - { - if (!strlen(name)) - { - return; - } - - unsigned short hash = calcHash(name); - stream_.write(hash); - - blockSizeOffsets_.push_back(int(stream_.position())); - stream_.write((unsigned char)0); - if (!size8) - { - stream_.write((unsigned short)0); - } - -#ifdef _DEBUG - // HashMap::iterator i = hashMap.find(hash); - // if(i != hashMap.end() && i->second != name) - // ASSERT_STR(0, name); - // hashMap[hash] = name; -#endif - } - - inline void BinOArchive::closeNode(const char* name, bool size8) - { - if (!strlen(name)) - { - return; - } - - unsigned int offset = blockSizeOffsets_.back(); - unsigned int size = (unsigned int)(stream_.position() - offset - sizeof(unsigned char) - (size8 ? 0 : sizeof(unsigned short))); - blockSizeOffsets_.pop_back(); - unsigned char* sizePtr = (unsigned char*)(stream_.buffer() + offset); - - if (size < SIZE16) - { - *sizePtr = size; - if (!size8) - { - unsigned char* buffer = sizePtr + 3; - memmove(buffer - 2, buffer, size); - stream_.setPosition(stream_.position() - 2); - } - } - else - { - YASLI_ASSERT(!size8); - if (size < 0x10000) - { - *sizePtr = SIZE16; - *((unsigned short*)(sizePtr + 1)) = size; - } - else - { - unsigned char* buffer = sizePtr + 3; - stream_.write((unsigned short)0); - *sizePtr = SIZE32; - memmove(buffer + 2, buffer, size); - *((unsigned int*)(sizePtr + 1)) = size; - } - } - } - - bool BinOArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - bool size8 = strlen(value.get()) + 1 < SIZE16; - openNode(name, size8); - stream_ << value.get(); - stream_.write(char(0)); - closeNode(name, size8); - return true; - } - - bool BinOArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - bool size8 = (wcslen(value.get()) + 1) * 2 < SIZE16; - openNode(name, size8); - stream_ << value.get(); - stream_.write(short(0)); - closeNode(name, size8); - return true; - } - - bool BinOArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - ser(*this); - closeNode(name, false); - return true; - } - - bool BinOArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - - unsigned int size = (unsigned int)ser.size(); - if (size < SIZE16) - { - stream_.write((unsigned char)size); - } - else if (size < 0x10000) - { - stream_.write(SIZE16); - stream_.write((unsigned short)size); - } - else - { - stream_.write(SIZE32); - stream_.write(size); - } - - if (strlen(name)) - { - if (size > 0) - { - int i = 0; - do - { - char elementName[16]; - azitoa(i++, elementName, AZ_ARRAY_SIZE(elementName), 10); - ser(*this, elementName, ""); - } while (ser.next()); - } - - closeNode(name, false); - } - else - { - if (size > 0) - { - do - { - ser(*this, "", ""); - } - while (ser.next()); - } - } - - return true; - } - - bool BinOArchive::operator()(IPointer& ptr, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - - const char* typeName = ptr.registeredTypeName(); - if (!typeName) - { - typeName = ""; - } - if (ptr.get() && typeName[0] == '\0') - { - CRY_ASSERT_MESSAGE(0, "Writing unregistered class. Use SERIALIZATION_CLASS_NAME macro for registration."); - } - - TypeID baseType = ptr.baseType(); - - if (ptr.get()) - { - stream_ << typeName; - stream_.write(char(0)); - ptr.serializer()(*this); - } - else - { - stream_.write(char(0)); - } - - closeNode(name, false); - return true; - } - - - ////////////////////////////////////////////////////////////////////////// - - BinIArchive::BinIArchive() - : IArchive(INPUT | BINARY) - , loadedData_(0) - { - } - - BinIArchive::~BinIArchive() - { - close(); - } - - bool BinIArchive::load(const char* filename) - { - close(); - - FILE* f = nullptr; - azfopen(&f, filename, "rb"); - if (!f) - { - return false; - } - fseek(f, 0, SEEK_END); - size_t length = ftell(f); - fseek(f, 0, SEEK_SET); - if (length == 0) - { - fclose(f); - return false; - } - loadedData_ = new char[length]; - if (fread((void*)loadedData_, 1, length, f) != length || !open(loadedData_, length)) - { - close(); - fclose(f); - return false; - } - fclose(f); - return true; - } - - bool BinIArchive::open(const char* buffer, size_t size) - { - if (size < sizeof(int)) - { - return false; - } - if (*(unsigned*)(buffer) != BIN_MAGIC) - { - return false; - } - buffer += sizeof(unsigned int); - size -= sizeof(unsigned int); - - blocks_.push_back(Block(buffer, (unsigned int)size)); - return true; - } - - void BinIArchive::close() - { - if (loadedData_) - { - delete [] loadedData_; - } - loadedData_ = 0; - } - - bool BinIArchive::openNode(const char* name) - { - Block block(0, 0); - if (currentBlock().get(name, block)) - { - blocks_.push_back(block); - return true; - } - return false; - } - - void BinIArchive::closeNode([[maybe_unused]] const char* name, [[maybe_unused]] bool check) - { - YASLI_ASSERT(!check || currentBlock().validToClose()); - blocks_.pop_back(); - } - - bool BinIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - string str; - read(str); - value.set(str.c_str()); - return true; - } - - if (!openNode(name)) - { - return false; - } - - string str; - read(str); - value.set(str.c_str()); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - wstring str; - read(str); - value.set(str.c_str()); - return true; - } - - if (!openNode(name)) - { - return false; - } - - wstring str; - read(str); - value.set(str.c_str()); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - - bool BinIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - ser(*this); - return true; - } - - if (!openNode(name)) - { - return false; - } - - ser(*this); - closeNode(name, false); - return true; - } - - bool BinIArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (strlen(name)) - { - if (!openNode(name)) - { - return false; - } - - size_t size = currentBlock().readPackedSize(); - ser.resize(size); - - if (size > 0) - { - int i = 0; - do - { - char elementName[16]; - azitoa(i++, elementName, AZ_ARRAY_SIZE(elementName), 10); - ser(*this, elementName, ""); - } - while (ser.next()); - } - closeNode(name); - return true; - } - else - { - size_t size = currentBlock().readPackedSize(); - ser.resize(size); - if (size > 0) - { - do - { - ser(*this, "", ""); - } - while (ser.next()); - } - return true; - } - } - - bool BinIArchive::operator()(IPointer& ptr, const char* name, [[maybe_unused]] const char* label) - { - if (strlen(name) && !openNode(name)) - { - return false; - } - - string typeName; - read(typeName); - if (ptr.get() && (typeName.empty() || (typeName != ptr.registeredTypeName()))) - { - ptr.create(""); // 0 - } - if (!typeName.empty() && !ptr.get()) - { - ptr.create(typeName.c_str()); - } - - if (SStruct ser = ptr.serializer()) - { - ser(*this); - } - - if (strlen(name)) - { - closeNode(name); - } - return true; - } - - unsigned int BinIArchive::Block::readPackedSize() - { - unsigned char size8; - read(size8); - if (size8 < SIZE16) - { - return size8; - } - if (size8 == SIZE16) - { - unsigned short size16; - read(size16); - return size16; - } - unsigned int size32; - read(size32); - return size32; - } - - bool BinIArchive::Block::get(const char* name, Block& block) - { - if (begin_ == end_) - { - return false; - } - complex_ = true; - unsigned short hashName = calcHash(name); - const char* currInitial = curr_; - bool restarted = false; - for (;; ) - { - if (curr_ >= end_) - { - return false; - } - - unsigned short hash; - read(hash); - unsigned int size = readPackedSize(); - - const char* currPrev = curr_; - if ((curr_ += size) == end_) - { - if (restarted) - { - return false; - } - curr_ = begin_; - restarted = true; - } - - //ASSERT(curr_ < end_); - - if (hash == hashName) - { - block = Block(currPrev, size); - return true; - } - - if (curr_ == currInitial) - { - return false; - } - } - } -} diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/BinArchive.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/BinArchive.h deleted file mode 100644 index 09285bf2fc..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/BinArchive.h +++ /dev/null @@ -1,183 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// For tags 16-bit xor-hash is used, with check for uniquness in debug -// Block size is automatic: 8, 16 or 32 bits - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_BINARCHIVE_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_BINARCHIVE_H -#pragma once - -#include "Serialization/IArchive.h" -#include "MemoryWriter.h" -#include "EditorCommonAPI.h" - -namespace Serialization { - inline unsigned short calcHash(const char* str) - { - unsigned short hash = 0; - const unsigned short* p = (const unsigned short*)(str); - for (;; ) - { - unsigned short w = *p++; - if (!(w & 0xff)) - { - break; - } - hash ^= w; - if (!(w & 0xff00)) - { - break; - } - } - return hash; - } - - class BinOArchive - : public IArchive - { - public: - BinOArchive(); - ~BinOArchive() {} - - void clear(); - size_t length() const; - const char* buffer() const { return stream_.buffer(); } - bool save(const char* fileName); - - bool operator()(bool& value, const char* name, const char* label); - bool operator()(IString& value, const char* name, const char* label); - bool operator()(IWString& value, const char* name, const char* label); - bool operator()(float& value, const char* name, const char* label); - bool operator()(double& value, const char* name, const char* label); - bool operator()(int32& value, const char* name, const char* label); - bool operator()(uint32& value, const char* name, const char* label); - bool operator()(int16& value, const char* name, const char* label); - bool operator()(uint16& value, const char* name, const char* label); - bool operator()(int64& value, const char* name, const char* label); - bool operator()(uint64& value, const char* name, const char* label); - - bool operator()(int8& value, const char* name, const char* label); - bool operator()(uint8& value, const char* name, const char* label); - bool operator()(char& value, const char* name, const char* label); - - bool operator()(const SStruct& ser, const char* name, const char* label); - bool operator()(IContainer& ser, const char* name, const char* label); - bool operator()(IPointer& ptr, const char* name, const char* label); - - using IArchive::operator(); - - private: - void openContainer(const char* name, int size, const char* typeName); - void openNode(const char* name, bool size8 = true); - void closeNode(const char* name, bool size8 = true); - - std::vector blockSizeOffsets_; - MemoryWriter stream_; - }; - - ////////////////////////////////////////////////////////////////////////// - - class BinIArchive - : public IArchive - { - public: - BinIArchive(); - ~BinIArchive(); - - bool load(const char* fileName); - bool open(const char* buffer, size_t length); // doesn't copy the buffer - bool open(const BinOArchive& ar) { return open(ar.buffer(), ar.length()); } - void close(); - - bool operator()(bool& value, const char* name, const char* label); - bool operator()(IString& value, const char* name, const char* label); - bool operator()(IWString& value, const char* name, const char* label); - bool operator()(float& value, const char* name, const char* label); - bool operator()(double& value, const char* name, const char* label); - bool operator()(int16& value, const char* name, const char* label); - bool operator()(uint16& value, const char* name, const char* label); - bool operator()(int32& value, const char* name, const char* label); - bool operator()(uint32& value, const char* name, const char* label); - bool operator()(int64& value, const char* name, const char* label); - bool operator()(uint64& value, const char* name, const char* label); - - bool operator()(int8& value, const char* name, const char* label); - bool operator()(uint8& value, const char* name, const char* label); - bool operator()(char& value, const char* name, const char* label); - - bool operator()(const SStruct& ser, const char* name, const char* label); - bool operator()(IContainer& ser, const char* name, const char* label); - bool operator()(IPointer& ptr, const char* name, const char* label); - - using IArchive::operator(); - - private: - class Block - { - public: - Block(const char* data, int size) - : begin_(data) - , curr_(data) - , end_(data + size) - , complex_(false) {} - - bool get(const char* name, Block& block); - - void read(void* data, int size) - { - YASLI_ASSERT(curr_ + size <= end_); - memcpy(data, curr_, size); - curr_ += size; - } - - template - void read(T& x){ read(&x, sizeof(x)); } - - void read(string& s) - { - YASLI_ASSERT(curr_ + strlen(curr_) < end_); - s = curr_; - curr_ += strlen(curr_) + 1; - } - void read(wstring& s) - { - YASLI_ASSERT(curr_ + sizeof(wchar_t) * wcslen((wchar_t*)curr_) < end_); - s = (wchar_t*)curr_; - curr_ += (wcslen((wchar_t*)curr_) + 1) * sizeof(wchar_t); - } - - unsigned int readPackedSize(); - - bool validToClose() const { return complex_ || curr_ == end_; } - - private: - const char* begin_; - const char* end_; - const char* curr_; - bool complex_; - }; - - typedef std::vector Blocks; - Blocks blocks_; - const char* loadedData_; - - bool openNode(const char* name); - void closeNode(const char* name, bool check = true); - Block& currentBlock() { return blocks_.back(); } - template - void read(T& t) { currentBlock().read(t); } - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_BINARCHIVE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/EditorActionButton.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/EditorActionButton.h deleted file mode 100644 index 77d064203b..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/EditorActionButton.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include -#include - -namespace Serialization -{ - typedef AZStd::function StdFunctionActionButtonCalback; - - struct StdFunctionActionButton - : public IActionButton - { - StdFunctionActionButtonCalback callback; - string icon; - - explicit StdFunctionActionButton(const StdFunctionActionButtonCalback& callback, const char* icon = "") - : callback(callback) - , icon(icon) - { - } - - // IActionButton - - virtual void Callback() const override - { - if (callback) - { - callback(); - } - } - - virtual const char* Icon() const override - { - return icon.c_str(); - } - - virtual IActionButtonPtr Clone() const override - { - return IActionButtonPtr(new StdFunctionActionButton(callback, icon.c_str())); - } - - // ~IActionButton - }; - - inline bool Serialize(Serialization::IArchive& ar, StdFunctionActionButton& button, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(button)), name, label); - } - else - { - return false; - } - } - - inline StdFunctionActionButton ActionButton(const StdFunctionActionButtonCalback& callback, const char* icon = "") - { - return StdFunctionActionButton(callback, icon); - } -} - diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/IGizmoSink.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/IGizmoSink.h deleted file mode 100644 index c0d402e484..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/IGizmoSink.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_IGIZMOSINK_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_IGIZMOSINK_H -#pragma once - - -namespace Serialization { - struct LocalPosition; - struct LocalFrame; - struct LocalOrientation; - - struct GizmoFlags - { - bool visible; - bool selected; - - GizmoFlags() - : visible(true) - , selected(false) {} - }; - - struct IGizmoSink - { - virtual ~IGizmoSink() = default; - virtual int CurrentGizmoIndex() const = 0; - virtual int Write(const LocalPosition&, const GizmoFlags& flags, const void* handle) = 0; - virtual int Write(const LocalOrientation&, const GizmoFlags& flags, const void* handle) = 0; - virtual int Write(const LocalFrame&, const GizmoFlags& flags, const void* handle) = 0; - virtual void SkipRead() = 0; - virtual bool Read(LocalPosition* position, GizmoFlags* flags, const void* handle) = 0; - virtual bool Read(LocalOrientation* position, GizmoFlags* flags, const void* handle) = 0; - virtual bool Read(LocalFrame* position, GizmoFlags* flags, const void* handle) = 0; - virtual void Reset(const void* handle) = 0; - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_IGIZMOSINK_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/INavigationProvider.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/INavigationProvider.h deleted file mode 100644 index 8efe913c03..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/INavigationProvider.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_INAVIGATIONPROVIDER_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_INAVIGATIONPROVIDER_H -#pragma once - -namespace Serialization -{ - struct SNavigationContext - { - string path; - }; - - struct INavigationProvider - { - virtual ~INavigationProvider() = default; - virtual const char* GetIcon(const char* type, const char* path) const = 0; - virtual const char* GetFileSelectorMaskForType(const char* type) const = 0; - virtual const char* GetEngineTypeForInputType(const char* extension) const { return extension; } - virtual bool IsSelected(const char* type, const char* path, int index) const = 0; - virtual bool IsActive(const char* type, const char* path, int index) const = 0; - virtual bool IsModified(const char* type, const char* path, int index) const = 0; - virtual bool Select(const char* type, const char* path, int index) const = 0; - virtual bool CanSelect([[maybe_unused]] const char* type, [[maybe_unused]] const char* path, [[maybe_unused]] int index) const { return false; } - virtual bool CanPickFile([[maybe_unused]] const char* type, [[maybe_unused]] int index) const { return true; } - virtual bool CanCreate([[maybe_unused]] const char* type, [[maybe_unused]] int index) const { return false; } - virtual bool Create([[maybe_unused]] const char* type, [[maybe_unused]] const char* path, [[maybe_unused]] int index) const { return false; } - virtual bool IsRegistered([[maybe_unused]] const char* type) const { return false; } - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_INAVIGATIONPROVIDER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/IconXPM.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/IconXPM.h deleted file mode 100644 index 17154e3c6f..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/IconXPM.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_ICONXPM_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_ICONXPM_H -#pragma once - -namespace Serialization { - class IArchive; - - // Icon, stored in XPM format - struct IconXPM - { - const char* const* source; - int lineCount; - - IconXPM() - : source(0) - , lineCount(0) - { - } - template - explicit IconXPM(const char* (&xpm)[Size]) - { - source = xpm; - lineCount = Size; - } - - void Serialize([[maybe_unused]] Serialization::IArchive& ar) {} - bool operator<(const IconXPM& rhs) const { return source < rhs.source; } - }; - - struct IconXPMToggle - { - bool* variable_; - bool value_; - IconXPM iconTrue_; - IconXPM iconFalse_; - - template - IconXPMToggle(bool& variable, char* (&xpmTrue)[Size1], char* (&xpmFalse)[Size2]) - : iconTrue_(xpmTrue) - , iconFalse_(xpmFalse) - , variable_(&variable) - , value_(variable) - { - } - - IconXPMToggle(bool& variable, const IconXPM& iconTrue, const IconXPM& iconFalse) - : iconTrue_(iconTrue) - , iconFalse_(iconFalse) - , variable_(&variable) - , value_(variable) - { - } - - IconXPMToggle(const IconXPMToggle& orig) - : variable_(0) - , value_(orig.value_) - , iconTrue_(orig.iconTrue_) - , iconFalse_(orig.iconFalse_) - { - } - - IconXPMToggle() - : variable_(0) - { - } - IconXPMToggle& operator=(const IconXPMToggle& rhs) - { - value_ = rhs.value_; - return *this; - } - ~IconXPMToggle() - { - if (variable_) - { - * variable_ = value_; - } - } - - template - void Serialize(TArchive& ar) - { - ar(value_, "value", "Value"); - } - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_ICONXPM_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/ToggleButton.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/ToggleButton.h deleted file mode 100644 index dfbc210f87..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/ToggleButton.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_TOGGLEBUTTON_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_TOGGLEBUTTON_H -#pragma once - -namespace Serialization -{ - class IArchive; - - struct ToggleButton - { - bool* value; - - ToggleButton(bool& value) - : value(&value) - { - } - }; - - struct RadioButton - { - int* value; - int buttonValue; - - RadioButton(int& value, int buttonValue) - : value(&value) - , buttonValue(buttonValue) - { - } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::ToggleButton& button, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::RadioButton& button, const char* name, const char* label); -} - -#include "ToggleButtonImpl.h" - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_TOGGLEBUTTON_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/ToggleButtonImpl.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/ToggleButtonImpl.h deleted file mode 100644 index a691d1a33a..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Decorators/ToggleButtonImpl.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_TOGGLEBUTTONIMPL_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_TOGGLEBUTTONIMPL_H -#pragma once - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::ToggleButton& button, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(button), name, label); - } - else - { - return ar(*button.value, name, label); - } - } - - inline bool Serialize(Serialization::IArchive& ar, Serialization::RadioButton& button, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(button), name, label); - } - else - { - return false; - } - } -} -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_DECORATORS_TOGGLEBUTTONIMPL_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONIArchive.cpp b/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONIArchive.cpp deleted file mode 100644 index 874f70f581..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONIArchive.cpp +++ /dev/null @@ -1,1522 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include -#include -#include -#include "Serialization/ClassFactory.h" -#include "Serialization/STL.h" -#include "JSONIArchive.h" -#include "Serialization/BlackBox.h" -#include "MemoryReader.h" -#include "MemoryWriter.h" - -#if 0 -# define DEBUG_TRACE(fmt, ...) printf(fmt "\n", __VA_ARGS__) -# define DEBUG_TRACE_TOKENIZER(fmt, ...) printf(fmt "\n", __VA_ARGS__) -#else -# define DEBUG_TRACE(...) -# define DEBUG_TRACE_TOKENIZER(...) -#endif - -namespace Serialization { - static char hexValueTable[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, - - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - static void unescapeString(std::vector& buf, string& out, const char* begin, const char* end) - { - if (begin >= end) - { - out.clear(); - return; - } - // TODO: use stack string - buf.resize(end - begin); - char* ptr = &buf[0]; - while (begin != end) - { - if (*begin != '\\') - { - *ptr = *begin; - ++ptr; - } - else - { - ++begin; - if (begin == end) - { - break; - } - - switch (*begin) - { - case '0': - *ptr = '\0'; - ++ptr; - break; - case 't': - *ptr = '\t'; - ++ptr; - break; - case 'n': - *ptr = '\n'; - ++ptr; - break; - case 'r': - *ptr = '\r'; - ++ptr; - break; - case '\\': - *ptr = '\\'; - ++ptr; - break; - case '\"': - *ptr = '\"'; - ++ptr; - break; - case '\'': - *ptr = '\''; - ++ptr; - break; - case 'x': - if (begin + 2 < end) - { - *ptr = (hexValueTable[int(begin[1])] << 4) + hexValueTable[int(begin[2])]; - ++ptr; - begin += 2; - break; - } - default: - *ptr = *begin; - ++ptr; - break; - } - } - ++begin; - } - buf.resize(ptr - &buf[0]); - if (!buf.empty()) - { - out.assign(&buf[0], &buf[0] + buf.size()); - } - else - { - out.clear(); - } - } - - // --------------------------------------------------------------------------- - - class JSONTokenizer - { - public: - JSONTokenizer(); - - Token operator()(const char* text) const; - private: - inline bool isSpace(char c) const; - inline bool isWordPart(unsigned char c) const; - inline bool isComment(char c) const; - inline bool isQuoteOpen(int& quoteIndex, char c) const; - inline bool isQuoteClose(int quoteIndex, char c) const; - inline bool isQuote(char c) const; - }; - - JSONTokenizer::JSONTokenizer() - { - } - - inline bool JSONTokenizer::isSpace(char c) const - { - return c == ' ' || c == '\t' || c == '\n' || c == '\r'; - } - - inline bool JSONTokenizer::isComment(char c) const - { - return c == '#'; - } - - - inline bool JSONTokenizer::isQuote(char c) const - { - return c == '\"'; - } - - static const char charTypes[256] = { - 0 /* 0x00: */, - 0 /* 0x01: */, - 0 /* 0x02: */, - 0 /* 0x03: */, - 0 /* 0x04: */, - 0 /* 0x05: */, - 0 /* 0x06: */, - 0 /* 0x07: */, - 0 /* 0x08: */, - 0 /* 0x09: \t */, - 0 /* 0x0A: \n */, - 0 /* 0x0B: */, - 0 /* 0x0C: */, - 0 /* 0x0D: */, - 0 /* 0x0E: */, - 0 /* 0x0F: */, - - - 0 /* 0x10: */, - 0 /* 0x11: */, - 0 /* 0x12: */, - 0 /* 0x13: */, - 0 /* 0x14: */, - 0 /* 0x15: */, - 0 /* 0x16: */, - 0 /* 0x17: */, - 0 /* 0x18: */, - 0 /* 0x19: */, - 0 /* 0x1A: */, - 0 /* 0x1B: */, - 0 /* 0x1C: */, - 0 /* 0x1D: */, - 0 /* 0x1E: */, - 0 /* 0x1F: */, - - - 0 /* 0x20: */, - 0 /* 0x21: ! */, - 0 /* 0x22: " */, - 0 /* 0x23: # */, - 0 /* 0x24: $ */, - 0 /* 0x25: % */, - 0 /* 0x26: & */, - 0 /* 0x27: ' */, - 0 /* 0x28: ( */, - 0 /* 0x29: ) */, - 0 /* 0x2A: * */, - 0 /* 0x2B: + */, - 0 /* 0x2C: , */, - 1 /* 0x2D: - */, - 1 /* 0x2E: . */, - 0 /* 0x2F: / */, - - - 1 /* 0x30: 0 */, - 1 /* 0x31: 1 */, - 1 /* 0x32: 2 */, - 1 /* 0x33: 3 */, - 1 /* 0x34: 4 */, - 1 /* 0x35: 5 */, - 1 /* 0x36: 6 */, - 1 /* 0x37: 7 */, - 1 /* 0x38: 8 */, - 1 /* 0x39: 9 */, - 0 /* 0x3A: : */, - 0 /* 0x3B: ; */, - 0 /* 0x3C: < */, - 0 /* 0x3D: = */, - 0 /* 0x3E: > */, - 0 /* 0x3F: ? */, - - - 0 /* 0x40: @ */, - 1 /* 0x41: A */, - 1 /* 0x42: B */, - 1 /* 0x43: C */, - 1 /* 0x44: D */, - 1 /* 0x45: E */, - 1 /* 0x46: F */, - 1 /* 0x47: G */, - 1 /* 0x48: H */, - 1 /* 0x49: I */, - 1 /* 0x4A: J */, - 1 /* 0x4B: K */, - 1 /* 0x4C: L */, - 1 /* 0x4D: M */, - 1 /* 0x4E: N */, - 1 /* 0x4F: O */, - - - 1 /* 0x50: P */, - 1 /* 0x51: Q */, - 1 /* 0x52: R */, - 1 /* 0x53: S */, - 1 /* 0x54: T */, - 1 /* 0x55: U */, - 1 /* 0x56: V */, - 1 /* 0x57: W */, - 1 /* 0x58: X */, - 1 /* 0x59: Y */, - 1 /* 0x5A: Z */, - 0 /* 0x5B: [ */, - 0 /* 0x5C: \ */, - 0 /* 0x5D: ] */, - 0 /* 0x5E: ^ */, - 1 /* 0x5F: _ */, - - - 0 /* 0x60: ` */, - 1 /* 0x61: a */, - 1 /* 0x62: b */, - 1 /* 0x63: c */, - 1 /* 0x64: d */, - 1 /* 0x65: e */, - 1 /* 0x66: f */, - 1 /* 0x67: g */, - 1 /* 0x68: h */, - 1 /* 0x69: i */, - 1 /* 0x6A: j */, - 1 /* 0x6B: k */, - 1 /* 0x6C: l */, - 1 /* 0x6D: m */, - 1 /* 0x6E: n */, - 1 /* 0x6F: o */, - - - 1 /* 0x70: p */, - 1 /* 0x71: q */, - 1 /* 0x72: r */, - 1 /* 0x73: s */, - 1 /* 0x74: t */, - 1 /* 0x75: u */, - 1 /* 0x76: v */, - 1 /* 0x77: w */, - 1 /* 0x78: x */, - 1 /* 0x79: y */, - 1 /* 0x7A: z */, - 0 /* 0x7B: { */, - 0 /* 0x7C: | */, - 0 /* 0x7D: } */, - 0 /* 0x7E: ~ */, - 0 /* 0x7F: */, - - - 0 /* 0x80: */, - 0 /* 0x81: */, - 0 /* 0x82: */, - 0 /* 0x83: */, - 0 /* 0x84: */, - 0 /* 0x85: */, - 0 /* 0x86: */, - 0 /* 0x87: */, - 0 /* 0x88: */, - 0 /* 0x89: */, - 0 /* 0x8A: */, - 0 /* 0x8B: */, - 0 /* 0x8C: */, - 0 /* 0x8D: */, - 0 /* 0x8E: */, - 0 /* 0x8F: */, - - - 0 /* 0x90: */, - 0 /* 0x91: */, - 0 /* 0x92: */, - 0 /* 0x93: */, - 0 /* 0x94: */, - 0 /* 0x95: */, - 0 /* 0x96: */, - 0 /* 0x97: */, - 0 /* 0x98: */, - 0 /* 0x99: */, - 0 /* 0x9A: */, - 0 /* 0x9B: */, - 0 /* 0x9C: */, - 0 /* 0x9D: */, - 0 /* 0x9E: */, - 0 /* 0x9F: */, - - - 0 /* 0xA0: */, - 0 /* 0xA1: */, - 0 /* 0xA2: */, - 0 /* 0xA3: */, - 0 /* 0xA4: */, - 0 /* 0xA5: */, - 0 /* 0xA6: */, - 0 /* 0xA7: */, - 0 /* 0xA8: */, - 0 /* 0xA9: */, - 0 /* 0xAA: */, - 0 /* 0xAB: */, - 0 /* 0xAC: */, - 0 /* 0xAD: */, - 0 /* 0xAE: */, - 0 /* 0xAF: */, - - - 0 /* 0xB0: */, - 0 /* 0xB1: */, - 0 /* 0xB2: */, - 0 /* 0xB3: */, - 0 /* 0xB4: */, - 0 /* 0xB5: */, - 0 /* 0xB6: */, - 0 /* 0xB7: */, - 0 /* 0xB8: */, - 0 /* 0xB9: */, - 0 /* 0xBA: */, - 0 /* 0xBB: */, - 0 /* 0xBC: */, - 0 /* 0xBD: */, - 0 /* 0xBE: */, - 0 /* 0xBF: */, - - - 0 /* 0xC0: */, - 0 /* 0xC1: */, - 0 /* 0xC2: */, - 0 /* 0xC3: */, - 0 /* 0xC4: */, - 0 /* 0xC5: */, - 0 /* 0xC6: */, - 0 /* 0xC7: */, - 0 /* 0xC8: */, - 0 /* 0xC9: */, - 0 /* 0xCA: */, - 0 /* 0xCB: */, - 0 /* 0xCC: */, - 0 /* 0xCD: */, - 0 /* 0xCE: */, - 0 /* 0xCF: */, - - - 0 /* 0xD0: */, - 0 /* 0xD1: */, - 0 /* 0xD2: */, - 0 /* 0xD3: */, - 0 /* 0xD4: */, - 0 /* 0xD5: */, - 0 /* 0xD6: */, - 0 /* 0xD7: */, - 0 /* 0xD8: */, - 0 /* 0xD9: */, - 0 /* 0xDA: */, - 0 /* 0xDB: */, - 0 /* 0xDC: */, - 0 /* 0xDD: */, - 0 /* 0xDE: */, - 0 /* 0xDF: */, - - - 0 /* 0xE0: */, - 0 /* 0xE1: */, - 0 /* 0xE2: */, - 0 /* 0xE3: */, - 0 /* 0xE4: */, - 0 /* 0xE5: */, - 0 /* 0xE6: */, - 0 /* 0xE7: */, - 0 /* 0xE8: */, - 0 /* 0xE9: */, - 0 /* 0xEA: */, - 0 /* 0xEB: */, - 0 /* 0xEC: */, - 0 /* 0xED: */, - 0 /* 0xEE: */, - 0 /* 0xEF: */, - - - 0 /* 0xF0: */, - 0 /* 0xF1: */, - 0 /* 0xF2: */, - 0 /* 0xF3: */, - 0 /* 0xF4: */, - 0 /* 0xF5: */, - 0 /* 0xF6: */, - 0 /* 0xF7: */, - 0 /* 0xF8: */, - 0 /* 0xF9: */, - 0 /* 0xFA: */, - 0 /* 0xFB: */, - 0 /* 0xFC: */, - 0 /* 0xFD: */, - 0 /* 0xFE: */, - 0 /* 0xFF: */ - }; - - inline bool JSONTokenizer::isWordPart(unsigned char c) const - { - return charTypes[c] != 0; - } - - Token JSONTokenizer::operator()(const char* ptr) const - { - while (isSpace(*ptr)) - { - ++ptr; - } - Token cur(ptr, ptr); - while (!cur && *ptr != '\0') - { - while (isComment(*cur.end)) - { - while (*cur.end && *cur.end != '\n') - { - ++cur.end; - } - while (isSpace(*cur.end)) - { - ++cur.end; - } - DEBUG_TRACE_TOKENIZER("Got comment: '%s'", string(commentStart, cur.end).c_str()); - cur.start = cur.end; - } - CRY_ASSERT(!isSpace(*cur.end)); - if (isQuote(*cur.end)) - { - ++cur.end; - while (*cur.end) - { - if (*cur.end == '\\') - { - ++cur.end; - if (*cur.end) - { - if (*cur.end != 'x' && *cur.end != 'X') - { - ++cur.end; - } - else - { - ++cur.end; - if (*cur.end) - { - ++cur.end; - } - } - continue; - } - } - if (isQuote(*cur.end)) - { - ++cur.end; - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - else - { - ++cur.end; - } - } - } - else - { - if (!*cur.end) - { - return cur; - } - - DEBUG_TRACE_TOKENIZER("%c", *cur.end); - if (isWordPart(*cur.end)) - { - do - { - ++cur.end; - } while (isWordPart(*cur.end) != 0); - } - else - { - ++cur.end; - return cur; - } - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - } - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - - - // --------------------------------------------------------------------------- - - JSONIArchive::JSONIArchive() - : IArchive(INPUT | TEXT) - , buffer_(0) - { - } - - JSONIArchive::~JSONIArchive() - { - if (buffer_) - { - free(buffer_); - buffer_ = 0; - } - stack_.clear(); - reader_.reset(); - } - - bool JSONIArchive::open(const char* buffer, size_t length, bool free) - { - if (!length) - { - return false; - } - - if (buffer) - { - reader_.reset(new MemoryReader(buffer, length, free)); - } - buffer_ = 0; - - token_ = Token(reader_->begin(), reader_->begin()); - stack_.clear(); - - stack_.push_back(Level()); - readToken(); - putToken(); - stack_.back().start = token_.end; - return true; - } - - - bool JSONIArchive::load(const char* filename) - { - FILE* file = nullptr; - azfopen(&file, filename, "rb"); - if (file) - { - fseek(file, 0, SEEK_END); - long fileSize = ftell(file); - fseek(file, 0, SEEK_SET); - - void* buffer = 0; - if (fileSize > 0) - { - buffer = malloc(fileSize + 1); - CRY_ASSERT(buffer != 0); - memset(buffer, 0, fileSize + 1); - size_t elementsRead = fread(buffer, fileSize, 1, file); - CRY_ASSERT(((char*)(buffer))[fileSize] == '\0'); - if (elementsRead != 1) - { - free(buffer); - return false; - } - } - fclose(file); - - filename_ = filename; - buffer_ = buffer; - if (fileSize > 0) - { - return open((char*)buffer, fileSize, false); - } - else - { - return false; - } - } - else - { - return false; - } - } - - void JSONIArchive::readToken() - { - JSONTokenizer tokenizer; - token_ = tokenizer(token_.end); - DEBUG_TRACE(" ~ read token '%s' at %i", token_.str().c_str(), token_.start - reader_->begin()); - } - - void JSONIArchive::putToken() - { - DEBUG_TRACE(" putToken: '%s'", token_.str().c_str()); - token_ = Token(token_.start, token_.start); - } - - int JSONIArchive::line(const char* position) const - { - return int(std::count(reader_->begin(), position, '\n') + 1); - } - - bool JSONIArchive::isName(Token token) const - { - if (!token) - { - return false; - } - char firstChar = token.start[0]; - if (firstChar == '"') - { - return true; - } - return false; - } - - - bool JSONIArchive::expect(char token) - { - if (token_ != token) - { - const char* lineEnd = token_.start; - while (lineEnd && *lineEnd != '\0' && *lineEnd != '\r' && *lineEnd != '\n') - { - ++lineEnd; - } - - MemoryWriter msg; - msg << "Error parsing file, expected ':' at line " << line(token_.start) << ":\n" - << string(token_.start, lineEnd).c_str(); - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - return true; - } - - void JSONIArchive::skipBlock() - { - DEBUG_TRACE("Skipping block from %i ...", token_.end - reader_->begin()); - if (openBracket() || openContainerBracket()) - { - closeBracket(); // Skipping entire block - } - else - { - readToken(); // Skipping value - } - readToken(); - if (token_ != ',') - { - putToken(); - } - DEBUG_TRACE(" ...till %i", token_.end - reader_->begin()); - } - - bool JSONIArchive::findName(const char* name, Token* outName) - { - DEBUG_TRACE(" * finding name '%s'", name); - DEBUG_TRACE(" started at byte %i", int(token_.start - reader_->begin())); - if (stack_.empty()) - { - // TODO: diagnose - return false; - } - if (stack_.back().isKeyValue) - { - return true; - } - const char* start = 0; - const char* blockBegin = stack_.back().start; - if (*blockBegin == '\0') - { - return false; - } - - readToken(); - if (token_ == ',') - { - readToken(); - } - if (!token_) - { - start = blockBegin; - token_.set(blockBegin, blockBegin); - readToken(); - } - - if (stack_.size() == 1 || stack_.back().isContainer || outName != 0) - { - if (token_ == ']' || token_ == '}') - { - DEBUG_TRACE("Got close bracket..."); - putToken(); - return false; - } - else - { - DEBUG_TRACE("Got unnamed value: '%s'", token_.str().c_str()); - putToken(); - return true; - } - } - else - { - if (isName(token_)) - { - DEBUG_TRACE("Seems to be a name '%s'", token_.str().c_str()); - Token nameContent(token_.start + 1, token_.end - 1); - if (nameContent == name) - { - readToken(); - expect(':'); - DEBUG_TRACE("Got one"); - return true; - } - else - { - start = token_.start; - - readToken(); - expect(':'); - skipBlock(); - } - } - else - { - start = token_.start; - if (token_ == ']' || token_ == '}') - { - token_ = Token(blockBegin, blockBegin); - } - else - { - putToken(); - skipBlock(); - } - } - } - - while (true) - { - readToken(); - if (!token_) - { - token_.set(blockBegin, blockBegin); - continue; - } - //return false; // Reached end of file while searching for name - DEBUG_TRACE("'%s'", token_.str().c_str()); - DEBUG_TRACE("Checking for loop: %i and %i", token_.start - reader_->begin(), start - reader_->begin()); - CRY_ASSERT(start != 0); - if (token_.start == start) - { - putToken(); - DEBUG_TRACE("unable to find..."); - return false; // Reached a full circle: unable to find name - } - - if (token_ == '}' || token_ == ']') // CONVERSION - { - DEBUG_TRACE("Going to begin of block, from %i", token_.start - reader_->begin()); - token_ = Token(blockBegin, blockBegin); - DEBUG_TRACE(" to %i", token_.start - reader_->begin()); - continue; // Reached '}' or ']' while searching for name, continue from begin of block - } - - if (name[0] == '\0') - { - if (isName(token_)) - { - readToken(); - if (!token_) - { - return false; // Reached end of file while searching for name - } - expect(':'); - skipBlock(); - } - else - { - putToken(); // Not a name - put it back - return true; - } - } - else - { - if (isName(token_)) - { - Token nameContent(token_.start + 1, token_.end - 1); - readToken(); - expect(':'); - if (nameContent == name) - { - return true; - } - else - { - skipBlock(); - } - } - else - { - putToken(); - skipBlock(); - } - } - } - - return false; - } - - bool JSONIArchive::openBracket() - { - readToken(); - if (token_ == '{') - { - return true; - } - putToken(); - return false; - } - - bool JSONIArchive::closeBracket() - { - int relativeLevel = 0; - while (true) - { - readToken(); - if (token_ == ',') - { - readToken(); - } - if (!token_) - { - MemoryWriter msg; - CRY_ASSERT(!stack_.empty()); - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while no matching bracket found"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - else if (token_ == '}' || token_ == ']') // CONVERSION - { - if (relativeLevel == 0) - { - return true; - } - else - { - --relativeLevel; - } - } - else if (token_ == '{' || token_ == '[') // CONVERSION - { - ++relativeLevel; - } - } - return false; - } - - bool JSONIArchive::openContainerBracket() - { - readToken(); - if (token_ == '[') - { - return true; - } - putToken(); - return false; - } - - bool JSONIArchive::closeContainerBracket() - { - readToken(); - if (token_ == ']') - { - DEBUG_TRACE("closeContainerBracket(): ok"); - return true; - } - else - { - DEBUG_TRACE("closeContainerBracket(): failed ('%s')", token_.str().c_str()); - putToken(); - return false; - } - } - - bool JSONIArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - } - else if (openContainerBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - stack_.back().isContainer = true; - } - else - { - return false; - } - - ser(*this); - CRY_ASSERT(!stack_.empty()); - stack_.pop_back(); -#if !defined(NDEBUG) - bool closed = -#endif - closeBracket(); - CRY_ASSERT(closed); - return true; - } - return false; - } - - bool JSONIArchive::operator()(const SBlackBox& box, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket() || openContainerBracket()) - { - const char* start = token_.start; - putToken(); - skipBlock(); - const char* end = token_.start; - if (end < start) - { - CRY_ASSERT(0); - return false; - } - while (end > start && - (*(end - 1) == ' ' - || *(end - 1) == '\r' - || *(end - 1) == '\n' - || *(end - 1) == '\t')) - { - --end; - } - // box has to be const in the interface so we can serialize - // temporary variables (i.e. function call result or structures - // constructed on the stack) - const_cast(box).set("json", (void*)start, end - start); - return true; - } - } - return false; - } - - bool JSONIArchive::operator()(IKeyValue& keyValue, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) - { - Token nextName; - if (!stack_.empty() && stack_.back().isContainer) - { - readToken(); - if (isName(token_) && checkStringValueToken()) - { - string key; - unescapeString(unescapeBuffer_, key, token_.start + 1, token_.end - 1); - keyValue.set(key.c_str()); - readToken(); - if (!expect(':')) - { - return false; - } - if (!keyValue.serializeValue(*this, "", 0)) - { - return false; - } - return true; - } - else - { - putToken(); - return false; - } - } - else if (findName("", &nextName)) - { - string key; - unescapeString(unescapeBuffer_, key, nextName.start + 1, nextName.end - 1); - keyValue.set(key.c_str()); - stack_.push_back(Level()); - stack_.back().isKeyValue = true; - - bool result = keyValue.serializeValue(*this, "", 0); - if (stack_.empty()) - { - // TODO: diagnose - return false; - } - stack_.pop_back(); - return result; - } - return false; - } - - - bool JSONIArchive::operator()(IPointer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - stack_.back().isKeyValue = true; - - readToken(); - if (isName(token_)) - { - if (checkStringValueToken()) - { - string typeName; - unescapeString(unescapeBuffer_, typeName, token_.start + 1, token_.end - 1); - if (strcmp(ser.registeredTypeName(), typeName.c_str()) != 0) - { - ser.create(typeName.c_str()); - } - readToken(); - expect(':'); - operator()(ser.serializer(), "", 0); - } - } - else - { - putToken(); - - ser.create(""); - } - closeBracket(); - stack_.pop_back(); - return true; - } - } - return false; - } - - - bool JSONIArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - bool containerBracket = openContainerBracket(); - bool dictionaryBracket = false; - if (!containerBracket) - { - dictionaryBracket = openBracket(); - } - if (containerBracket || dictionaryBracket) - { - stack_.push_back(Level()); - stack_.back().isContainer = true; - stack_.back().start = token_.end; - - std::size_t size = ser.size(); - std::size_t index = 0; - - while (true) - { - readToken(); - if (token_ == ',') - { - readToken(); - } - if (token_ == '}' || token_ == ']') - { - break; - } - else if (!token_) - { - CRY_ASSERT(0 && "Reached end of file while reading container!"); - return false; - } - putToken(); - if (index == size) - { - size = index + 1; - } - if (index < size) - { - if (!ser(*this, "", "")) - { - // We've got a named item within a container, - // i.e. looks like a dictionary but not a container. - // Bail out, it is nothing we can do here. - closeBracket(); - break; - } - } - else - { - skipBlock(); - } - ser.next(); - ++index; - } - if (size > index) - { - ser.resize(index); - } - - CRY_ASSERT(!stack_.empty()); - stack_.pop_back(); - return true; - } - } - return false; - } - - void JSONIArchive::checkValueToken() - { - if (!token_) - { - CRY_ASSERT(!stack_.empty()); - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while reading element's value"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - } - } - - bool JSONIArchive::checkStringValueToken() - { - if (!token_) - { - return false; - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while reading element's value"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - if (token_.start[0] != '"' || token_.end[-1] != '"') - { - return false; - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": Expected string"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - return true; - } - - bool JSONIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = strtoul(token_.start, 0, 10); - return true; - } - return false; - } - - - bool JSONIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (int16)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (uint16)strtoul(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = _strtoi64(token_.start, 0, 10); -#else - value = strtoll(token_.start, 0, 10); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = _strtoui64(token_.start, 0, 10); -#else - value = strtoull(token_.start, 0, 10); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = float(std::atof(token_.str().c_str())); -#else - value = strtof(token_.start, 0); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = std::atof(token_.str().c_str()); -#else - value = strtod(token_.start, 0); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - if (checkStringValueToken()) - { - string buf; - unescapeString(unescapeBuffer_, buf, token_.start + 1, token_.end - 1); - value.set(buf.c_str()); - } - else - { - return false; - } - return true; - } - return false; - } - - - inline size_t utf8InUtf16Len(const char* p) - { - size_t result = 0; - - for (; *p; ++p) - { - unsigned char ch = (unsigned char)(*p); - - if (ch < 0x80 || (ch >= 0xC0 && ch < 0xFC)) - { - ++result; - } - } - - return result; - } - - inline const char* readUtf16FromUtf8(unsigned int* ch, const char* s) - { - const unsigned char byteMark = 0x80; - const unsigned char byteMaskRead = 0x3F; - - const unsigned char* str = (const unsigned char*)s; - - size_t len; - if (*str < byteMark) - { - *ch = *str; - return s + 1; - } - else if (*str < 0xC0) - { - *ch = ' '; - return s + 1; - } - else if (*str < 0xE0) - { - len = 2; - } - else if (*str < 0xF0) - { - len = 3; - } - else if (*str < 0xF8) - { - len = 4; - } - else if (*str < 0xFC) - { - len = 5; - } - else - { - *ch = ' '; - return s + 1; - } - - const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - *ch = (*str++ & ~firstByteMark[len]); - - switch (len) - { - case 5: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 4: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 3: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 2: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - } - - return (const char*)str; - } - - - inline void utf8ToUtf16(wstring* out, const char* in) - { - out->clear(); - out->reserve(utf8InUtf16Len(in)); - - for (; *in; ) - { - unsigned int character; - in = readUtf16FromUtf8(&character, in); - (*out) += (wchar_t)character; - } - } - - - bool JSONIArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - if (checkStringValueToken()) - { - string buf; - unescapeString(unescapeBuffer_, buf, token_.start + 1, token_.end - 1); - wstring wbuf; - utf8ToUtf16(&wbuf, buf.c_str()); - value.set(wbuf.c_str()); - } - else - { - return false; - } - return true; - } - return false; - } - - bool JSONIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - if (token_ == "true") - { - value = true; - } - else if (token_ == "false") - { - value = false; - } - else - { - CRY_ASSERT(0 && "Invalid boolean value"); - } - return true; - } - return false; - } - - bool JSONIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (int8)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (uint8)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (char)strtol(token_.start, 0, 10); - return true; - } - return false; - } -} -// vim:ts=4 sw=4: diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONIArchive.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONIArchive.h deleted file mode 100644 index 60ce90672c..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONIArchive.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_JSONIARCHIVE_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_JSONIARCHIVE_H -#pragma once - -#include "Pointers.h" -#include "Serialization/IArchive.h" -#include "Serialization/MemoryReader.h" -#include "Token.h" -#include "EditorCommonAPI.h" -#include -#include - -namespace Serialization { - class MemoryReader; - - class JSONIArchive - : public IArchive - { - public: - JSONIArchive(); - ~JSONIArchive(); - - bool load(const char* filename); - bool open(const char* buffer, size_t length, bool free = false); - - // virtuals: - bool operator()(bool& value, const char* name = "", const char* label = 0); - bool operator()(IString& value, const char* name = "", const char* label = 0); - bool operator()(IWString& value, const char* name = "", const char* label = 0); - bool operator()(float& value, const char* name = "", const char* label = 0); - bool operator()(double& value, const char* name = "", const char* label = 0); - bool operator()(int16& value, const char* name = "", const char* label = 0); - bool operator()(uint16& value, const char* name = "", const char* label = 0); - bool operator()(int32& value, const char* name = "", const char* label = 0); - bool operator()(uint32& value, const char* name = "", const char* label = 0); - bool operator()(int64& value, const char* name = "", const char* label = 0); - bool operator()(uint64& value, const char* name = "", const char* label = 0); - - bool operator()(int8& value, const char* name = "", const char* label = 0); - bool operator()(uint8& value, const char* name = "", const char* label = 0); - bool operator()(char& value, const char* name = "", const char* label = 0); - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0); - bool operator()(const SBlackBox& ser, const char* name = "", const char* label = 0); - bool operator()(IContainer& ser, const char* name = "", const char* label = 0); - bool operator()(IKeyValue& ser, const char* name = "", const char* label = 0); - bool operator()(IPointer& ser, const char* name = "", const char* label = 0); - - using IArchive::operator(); - - private: - bool findName(const char* name, Token* outName = 0); - bool openBracket(); - bool closeBracket(); - - bool openContainerBracket(); - bool closeContainerBracket(); - - void checkValueToken(); - bool checkStringValueToken(); - void readToken(); - void putToken(); - int line(const char* position) const; - bool isName(Token token) const; - - bool expect(char token); - void skipBlock(); - - struct Level - { - const char* start; - const char* firstToken; - bool isContainer; - bool isKeyValue; - Level() - : isContainer(false) - , isKeyValue(false) {} - }; - typedef std::vector Stack; - Stack stack_; - - std::unique_ptr reader_; - Token token_; - std::vector unescapeBuffer_; - AZStd::string filename_; - void* buffer_; - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_JSONIARCHIVE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONOArchive.cpp b/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONOArchive.cpp deleted file mode 100644 index fa71eee245..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONOArchive.cpp +++ /dev/null @@ -1,828 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "JSONOArchive.h" -#include "MemoryWriter.h" -#include "Serialization/KeyValue.h" -#include "Serialization/ClassFactory.h" -#include "Serialization/BlackBox.h" -#include - -namespace Serialization { - // Some of non-latin1 characters here are not escaped to - // keep compatibility with 8-bit local encoding (e.g. windows-1251) - static const char* escapeTable[256] = { - "\\0" /* 0x00: */, - "\\x01" /* 0x01: */, - "\\x02" /* 0x02: */, - "\\x03" /* 0x03: */, - "\\x04" /* 0x04: */, - "\\x05" /* 0x05: */, - "\\x06" /* 0x06: */, - "\\x07" /* 0x07: */, - "\\x08" /* 0x08: */, - "\\t" /* 0x09: \t */, - "\\n" /* 0x0A: \n */, - "\\x0B" /* 0x0B: */, - "\\x0C" /* 0x0C: */, - "\\r" /* 0x0D: */, - "\\x0E" /* 0x0E: */, - "\\x0F" /* 0x0F: */, - - - "\\x10" /* 0x10: */, - "\\x11" /* 0x11: */, - "\\x12" /* 0x12: */, - "\\x13" /* 0x13: */, - "\\x14" /* 0x14: */, - "\\x15" /* 0x15: */, - "\\x16" /* 0x16: */, - "\\x17" /* 0x17: */, - "\\x18" /* 0x18: */, - "\\x19" /* 0x19: */, - "\\x1A" /* 0x1A: */, - "\\x1B" /* 0x1B: */, - "\\x1C" /* 0x1C: */, - "\\x1D" /* 0x1D: */, - "\\x1E" /* 0x1E: */, - "\\x1F" /* 0x1F: */, - - - " " /* 0x20: */, - "!" /* 0x21: ! */, - "\\\"" /* 0x22: " */, - "#" /* 0x23: # */, - "$" /* 0x24: $ */, - "%" /* 0x25: % */, - "&" /* 0x26: & */, - "'" /* 0x27: ' */, - "(" /* 0x28: ( */, - ")" /* 0x29: ) */, - "*" /* 0x2A: * */, - "+" /* 0x2B: + */, - "," /* 0x2C: , */, - "-" /* 0x2D: - */, - "." /* 0x2E: . */, - "/" /* 0x2F: / */, - - - "0" /* 0x30: 0 */, - "1" /* 0x31: 1 */, - "2" /* 0x32: 2 */, - "3" /* 0x33: 3 */, - "4" /* 0x34: 4 */, - "5" /* 0x35: 5 */, - "6" /* 0x36: 6 */, - "7" /* 0x37: 7 */, - "8" /* 0x38: 8 */, - "9" /* 0x39: 9 */, - ":" /* 0x3A: : */, - ";" /* 0x3B: ; */, - "<" /* 0x3C: < */, - "=" /* 0x3D: = */, - ">" /* 0x3E: > */, - "?" /* 0x3F: ? */, - - - "@" /* 0x40: @ */, - "A" /* 0x41: A */, - "B" /* 0x42: B */, - "C" /* 0x43: C */, - "D" /* 0x44: D */, - "E" /* 0x45: E */, - "F" /* 0x46: F */, - "G" /* 0x47: G */, - "H" /* 0x48: H */, - "I" /* 0x49: I */, - "J" /* 0x4A: J */, - "K" /* 0x4B: K */, - "L" /* 0x4C: L */, - "M" /* 0x4D: M */, - "N" /* 0x4E: N */, - "O" /* 0x4F: O */, - - - "P" /* 0x50: P */, - "Q" /* 0x51: Q */, - "R" /* 0x52: R */, - "S" /* 0x53: S */, - "T" /* 0x54: T */, - "U" /* 0x55: U */, - "V" /* 0x56: V */, - "W" /* 0x57: W */, - "X" /* 0x58: X */, - "Y" /* 0x59: Y */, - "Z" /* 0x5A: Z */, - "[" /* 0x5B: [ */, - "\\\\" /* 0x5C: \ */, - "]" /* 0x5D: ] */, - "^" /* 0x5E: ^ */, - "_" /* 0x5F: _ */, - - - "`" /* 0x60: ` */, - "a" /* 0x61: a */, - "b" /* 0x62: b */, - "c" /* 0x63: c */, - "d" /* 0x64: d */, - "e" /* 0x65: e */, - "f" /* 0x66: f */, - "g" /* 0x67: g */, - "h" /* 0x68: h */, - "i" /* 0x69: i */, - "j" /* 0x6A: j */, - "k" /* 0x6B: k */, - "l" /* 0x6C: l */, - "m" /* 0x6D: m */, - "n" /* 0x6E: n */, - "o" /* 0x6F: o */, - - - "p" /* 0x70: p */, - "q" /* 0x71: q */, - "r" /* 0x72: r */, - "s" /* 0x73: s */, - "t" /* 0x74: t */, - "u" /* 0x75: u */, - "v" /* 0x76: v */, - "w" /* 0x77: w */, - "x" /* 0x78: x */, - "y" /* 0x79: y */, - "z" /* 0x7A: z */, - "{" /* 0x7B: { */, - "|" /* 0x7C: | */, - "}" /* 0x7D: } */, - "~" /* 0x7E: ~ */, - "\x7F" /* 0x7F: */, // for utf-8 - - - "\x80" /* 0x80: */, - "\x81" /* 0x81: */, - "\x82" /* 0x82: */, - "\x83" /* 0x83: */, - "\x84" /* 0x84: */, - "\x85" /* 0x85: */, - "\x86" /* 0x86: */, - "\x87" /* 0x87: */, - "\x88" /* 0x88: */, - "\x89" /* 0x89: */, - "\x8A" /* 0x8A: */, - "\x8B" /* 0x8B: */, - "\x8C" /* 0x8C: */, - "\x8D" /* 0x8D: */, - "\x8E" /* 0x8E: */, - "\x8F" /* 0x8F: */, - - - "\x90" /* 0x90: */, - "\x91" /* 0x91: */, - "\x92" /* 0x92: */, - "\x93" /* 0x93: */, - "\x94" /* 0x94: */, - "\x95" /* 0x95: */, - "\x96" /* 0x96: */, - "\x97" /* 0x97: */, - "\x98" /* 0x98: */, - "\x99" /* 0x99: */, - "\x9A" /* 0x9A: */, - "\x9B" /* 0x9B: */, - "\x9C" /* 0x9C: */, - "\x9D" /* 0x9D: */, - "\x9E" /* 0x9E: */, - "\x9F" /* 0x9F: */, - - - "\xA0" /* 0xA0: */, - "\xA1" /* 0xA1: */, - "\xA2" /* 0xA2: */, - "\xA3" /* 0xA3: */, - "\xA4" /* 0xA4: */, - "\xA5" /* 0xA5: */, - "\xA6" /* 0xA6: */, - "\xA7" /* 0xA7: */, - "\xA8" /* 0xA8: */, - "\xA9" /* 0xA9: */, - "\xAA" /* 0xAA: */, - "\xAB" /* 0xAB: */, - "\xAC" /* 0xAC: */, - "\xAD" /* 0xAD: */, - "\xAE" /* 0xAE: */, - "\xAF" /* 0xAF: */, - - - "\xB0" /* 0xB0: */, - "\xB1" /* 0xB1: */, - "\xB2" /* 0xB2: */, - "\xB3" /* 0xB3: */, - "\xB4" /* 0xB4: */, - "\xB5" /* 0xB5: */, - "\xB6" /* 0xB6: */, - "\xB7" /* 0xB7: */, - "\xB8" /* 0xB8: */, - "\xB9" /* 0xB9: */, - "\xBA" /* 0xBA: */, - "\xBB" /* 0xBB: */, - "\xBC" /* 0xBC: */, - "\xBD" /* 0xBD: */, - "\xBE" /* 0xBE: */, - "\xBF" /* 0xBF: */, - - - "\xC0" /* 0xC0: */, - "\xC1" /* 0xC1: */, - "\xC2" /* 0xC2: */, - "\xC3" /* 0xC3: */, - "\xC4" /* 0xC4: */, - "\xC5" /* 0xC5: */, - "\xC6" /* 0xC6: */, - "\xC7" /* 0xC7: */, - "\xC8" /* 0xC8: */, - "\xC9" /* 0xC9: */, - "\xCA" /* 0xCA: */, - "\xCB" /* 0xCB: */, - "\xCC" /* 0xCC: */, - "\xCD" /* 0xCD: */, - "\xCE" /* 0xCE: */, - "\xCF" /* 0xCF: */, - - - "\xD0" /* 0xD0: */, - "\xD1" /* 0xD1: */, - "\xD2" /* 0xD2: */, - "\xD3" /* 0xD3: */, - "\xD4" /* 0xD4: */, - "\xD5" /* 0xD5: */, - "\xD6" /* 0xD6: */, - "\xD7" /* 0xD7: */, - "\xD8" /* 0xD8: */, - "\xD9" /* 0xD9: */, - "\xDA" /* 0xDA: */, - "\xDB" /* 0xDB: */, - "\xDC" /* 0xDC: */, - "\xDD" /* 0xDD: */, - "\xDE" /* 0xDE: */, - "\xDF" /* 0xDF: */, - - - "\xE0" /* 0xE0: */, - "\xE1" /* 0xE1: */, - "\xE2" /* 0xE2: */, - "\xE3" /* 0xE3: */, - "\xE4" /* 0xE4: */, - "\xE5" /* 0xE5: */, - "\xE6" /* 0xE6: */, - "\xE7" /* 0xE7: */, - "\xE8" /* 0xE8: */, - "\xE9" /* 0xE9: */, - "\xEA" /* 0xEA: */, - "\xEB" /* 0xEB: */, - "\xEC" /* 0xEC: */, - "\xED" /* 0xED: */, - "\xEE" /* 0xEE: */, - "\xEF" /* 0xEF: */, - - - "\xF0" /* 0xF0: */, - "\xF1" /* 0xF1: */, - "\xF2" /* 0xF2: */, - "\xF3" /* 0xF3: */, - "\xF4" /* 0xF4: */, - "\xF5" /* 0xF5: */, - "\xF6" /* 0xF6: */, - "\xF7" /* 0xF7: */, - "\xF8" /* 0xF8: */, - "\xF9" /* 0xF9: */, - "\xFA" /* 0xFA: */, - "\xFB" /* 0xFB: */, - "\xFC" /* 0xFC: */, - "\xFD" /* 0xFD: */, - "\xFE" /* 0xFE: */, - "\xFF" /* 0xFF: */ - }; - - static void escapeString(MemoryWriter& dest, const char* begin, const char* end) - { - while (begin != end) - { - const char* str = escapeTable[(unsigned char)(*begin)]; - dest.write(str); - ++begin; - } - } - - // --------------------------------------------------------------------------- - - static const int TAB_WIDTH = 2; - - JSONOArchive::JSONOArchive(int textWidth, const char* header) - : IArchive(OUTPUT | TEXT) - , header_(header) - , textWidth_(textWidth) - , compactOffset_(0) - { - buffer_.reset(new MemoryWriter(1024, true)); - if (header_) - { - (*buffer_) << header_; - } - - YASLI_ASSERT(stack_.empty()); - stack_.push_back(Level(false, 0, 0)); - } - - JSONOArchive::~JSONOArchive() - { - } - - bool JSONOArchive::save(const char* fileName) - { - YASLI_ESCAPE(fileName && strlen(fileName) > 0, return false); - YASLI_ESCAPE(stack_.size() == 1, return false); - YASLI_ESCAPE(buffer_.get() != 0, return false); - YASLI_ESCAPE(buffer_->position() <= buffer_->size(), return false); - stack_.pop_back(); - FILE* file = nullptr; - azfopen(&file, fileName, "wb"); - if (file) - { - if (fwrite(buffer_->c_str(), 1, buffer_->position(), file) != buffer_->position()) - { - fclose(file); - return false; - } - fclose(file); - return true; - } - else - { - return false; - } - } - - const char* JSONOArchive::c_str() const - { - return buffer_->c_str(); - } - - size_t JSONOArchive::length() const - { - return buffer_->position(); - } - - void JSONOArchive::openBracket() - { - *buffer_ << "{"; - } - - void JSONOArchive::closeBracket() - { - *buffer_ << "}"; - } - - void JSONOArchive::openContainerBracket() - { - *buffer_ << "["; - } - - void JSONOArchive::closeContainerBracket() - { - *buffer_ << "]"; - } - - void JSONOArchive::placeName(const char* name) - { - if (stack_.back().isKeyValue) - { - return; - } - if ((name[0] != '\0' || !stack_.back().isContainer) && stack_.size() > 1) - { - *buffer_ << "\""; - *buffer_ << name; - *buffer_ << "\": "; - stack_.back().nameIndex += 1; - } - } - - void JSONOArchive::placeIndent(bool putComma) - { - if (stack_.back().isKeyValue) - { - return; - } - if (putComma && stack_.back().elementIndex > 0) - { - *buffer_ << ","; - } - if (buffer_->position() > 0) - { - *buffer_ << "\n"; - } - int count = int(stack_.size() - 1); - stack_.back().indentCount += count; - stack_.back().elementIndex += 1; - for (int i = 0; i < count; ++i) - { - *buffer_ << "\t"; - } - compactOffset_ = 0; - } - - void JSONOArchive::placeIndentCompact(bool putComma) - { - if (stack_.back().isKeyValue) - { - return; - } - if (putComma && stack_.back().elementIndex > 0) - { - *buffer_ << ","; - } - if ((compactOffset_ % 32) != 0 && stack_.back().isContainer) - { - *buffer_ << " "; - compactOffset_ += 1; - stack_.back().elementIndex += 1; - } - else if (buffer_->size()) - { - *buffer_ << "\n"; - int count = int(stack_.size() - 1); - stack_.back().indentCount += count /* * TAB_WIDTH*/; - stack_.back().elementIndex += 1; - for (int i = 0; i < count; ++i) - { - *buffer_ << "\t"; - } - compactOffset_ = 1; - } - } - - bool JSONOArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - *buffer_ << (value ? "true" : "false"); - return true; - } - - - bool JSONOArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - (*buffer_) << "\""; - const char* str = value.get(); - escapeString(*buffer_, str, str + strlen(value.get())); - (*buffer_) << "\""; - return true; - } - - inline char* writeUtf16ToUtf8(char* s, unsigned int ch) - { - const unsigned char byteMark = 0x80; - const unsigned char byteMask = 0xBF; - - size_t len; - - if (ch < 0x80) - { - len = 1; - } - else if (ch < 0x800) - { - len = 2; - } - else if (ch < 0x10000) - { - len = 3; - } - else if (ch < 0x200000) - { - len = 4; - } - else - { - return s; - } - - s += len; - - const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - switch (len) - { - case 4: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 3: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 2: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 1: - *--s = (char)(ch | firstByteMark[len]); - } - - return s + len; - } - - bool JSONOArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - (*buffer_) << "\""; - - const wchar_t* in = value.get(); - for (; *in; ++in) - { - char buf[6]; - escapeString(*buffer_, buf, writeUtf16ToUtf8(buf, *in)); - } - - (*buffer_) << "\""; - return true; - } - - bool JSONOArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - std::size_t position = buffer_->position(); - openBracket(); - stack_.push_back(Level(false, position, int(strlen(name) + 2 * (name[0] & 1) + (stack_.size() - 1) * TAB_WIDTH + 2))); - - YASLI_ASSERT(ser); - ser(*this); - - bool joined = joinLinesIfPossible(); - bool noNames = stack_.back().nameIndex == 0; - if (noNames) - { - if (stack_.size() != 2) - { - buffer_->buffer()[stack_.back().startPosition] = '['; - } - } - stack_.pop_back(); - if (!joined) - { - placeIndent(false); - } - else - { - *buffer_ << " "; - } - if (noNames) - { - closeContainerBracket(); - } - else - { - closeBracket(); - } - return true; - } - - bool JSONOArchive::operator()(const SBlackBox& box, const char* name, [[maybe_unused]] const char* label) - { - if (strcmp(box.format, "json") != 0) - { - return false; - } - if (box.size == 0) - { - return false; - } - - placeIndent(); - placeName(name); - return buffer_->write(box.data, box.size); - } - - bool JSONOArchive::operator()(IKeyValue& keyValue, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - - *buffer_ << "\""; - *buffer_ << keyValue.get(); - *buffer_ << "\": "; - stack_.back().nameIndex += 1; - - stack_.back().isKeyValue = true; - keyValue.serializeValue(*this, "", 0); - stack_.back().isKeyValue = false; - if (stack_.back().isContainer) - { - stack_.back().isDictionary = true; - } - return true; - } - - bool JSONOArchive::operator()(IPointer& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - openBracket(); - const char* registeredTypeName = ser.registeredTypeName(); - if (registeredTypeName && registeredTypeName[0] != '\0') - { - *buffer_ << " "; - placeName(registeredTypeName); - stack_.back().isKeyValue = true; - operator()(ser.serializer(), ""); - stack_.back().isKeyValue = false; - *buffer_ << " "; - } - closeBracket(); - return true; - } - - bool JSONOArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - std::size_t position = buffer_->position(); - openContainerBracket(); - stack_.push_back(Level(true, position, int(strlen(name) + 2 * (name[0] & 1) + stack_.size() - 1 * TAB_WIDTH + 2))); - - std::size_t size = ser.size(); - if (size > 0) - { - do - { - ser(*this, "", ""); - } while (ser.next()); - } - - bool joined = joinLinesIfPossible(); - bool isDictionary = stack_.back().isDictionary; - if (isDictionary) - { - buffer_->buffer()[stack_.back().startPosition] = '{'; - } - stack_.pop_back(); - if (!joined) - { - placeIndent(false); - } - else - { - *buffer_ << " "; - } - - if (isDictionary) - { - closeBracket(); - } - else - { - closeContainerBracket(); - } - return true; - } - - static char* joinLines(char* start, char* end) - { - YASLI_ASSERT(start <= end); - char* next = start; - while (next != end) - { - if (*next != '\t' && *next != '\r') - { - if (*next != '\n') - { - *start = *next; - } - else - { - *start = ' '; - } - ++start; - } - ++next; - } - return start; - } - - bool JSONOArchive::joinLinesIfPossible() - { - YASLI_ASSERT(!stack_.empty()); - std::size_t startPosition = stack_.back().startPosition; - YASLI_ASSERT(startPosition < buffer_->size()); - int indentCount = stack_.back().indentCount; - //YASLI_ASSERT(startPosition >= indentCount); - if (buffer_->position() - startPosition - indentCount < std::size_t(textWidth_)) - { - char* buffer = buffer_->buffer(); - char* start = buffer + startPosition; - char* end = buffer + buffer_->position(); - end = joinLines(start, end); - std::size_t newPosition = end - buffer; - YASLI_ASSERT(newPosition <= buffer_->position()); - buffer_->setPosition(newPosition); - return true; - } - return false; - } -} -// vim:ts=4 sw=4: diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONOArchive.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONOArchive.h deleted file mode 100644 index 085e1abf16..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/JSONOArchive.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_JSONOARCHIVE_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_JSONOARCHIVE_H -#pragma once - -#include "Serialization/IArchive.h" -#include "Serialization/MemoryWriter.h" -#include "EditorCommonAPI.h" -#include - -namespace Serialization { - class MemoryWriter; - - class JSONOArchive - : public IArchive - { - public: - // header = 0 - default header, use "" to omit - JSONOArchive(int textWidth = 80, const char* header = 0); - ~JSONOArchive(); - - bool save(const char* fileName); - - const char* c_str() const; - const char* buffer() const { return c_str(); } - size_t length() const; - - // from Archive: - bool operator()(bool& value, const char* name = "", const char* label = 0); - bool operator()(IString& value, const char* name = "", const char* label = 0); - bool operator()(IWString& value, const char* name = "", const char* label = 0); - bool operator()(float& value, const char* name = "", const char* label = 0); - bool operator()(double& value, const char* name = "", const char* label = 0); - bool operator()(int16& value, const char* name = "", const char* label = 0); - bool operator()(uint16& value, const char* name = "", const char* label = 0); - bool operator()(int32& value, const char* name = "", const char* label = 0); - bool operator()(uint32& value, const char* name = "", const char* label = 0); - bool operator()(int64& value, const char* name = "", const char* label = 0); - bool operator()(uint64& value, const char* name = "", const char* label = 0); - - bool operator()(char& value, const char* name = "", const char* label = 0); - bool operator()(int8& value, const char* name = "", const char* label = 0); - bool operator()(uint8& value, const char* name = "", const char* label = 0); - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0); - bool operator()(const SBlackBox& box, const char* name = "", const char* label = 0); - bool operator()(IContainer& ser, const char* name = "", const char* label = 0); - bool operator()(IKeyValue& keyValue, const char* name = "", const char* label = 0); - bool operator()(IPointer& ser, const char* name = "", const char* label = 0); - // ^^^ - - using IArchive::operator(); - - private: - void openBracket(); - void closeBracket(); - void openContainerBracket(); - void closeContainerBracket(); - void placeName(const char* name); - void placeIndent(bool putComma = true); - void placeIndentCompact(bool putComma = true); - - bool joinLinesIfPossible(); - - struct Level - { - Level(bool _isContainer, std::size_t position, int column) - : isContainer(_isContainer) - , isKeyValue(false) - , isDictionary(false) - , startPosition(position) - , indentCount(-column) - , elementIndex(0) - , nameIndex(0) - {} - bool isKeyValue; - bool isContainer; - bool isDictionary; - std::size_t startPosition; - int nameIndex; - int elementIndex; - int indentCount; - }; - - typedef std::vector Stack; - Stack stack_; - std::unique_ptr buffer_; - const char* header_; - int textWidth_; - string fileName_; - int compactOffset_; - bool isKeyValue_; - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_JSONOARCHIVE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryReader.cpp b/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryReader.cpp deleted file mode 100644 index 995064a57a..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryReader.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include -#include "Serialization/Assert.h" -#include "MemoryReader.h" -#include -#include - -namespace Serialization { - MemoryReader::MemoryReader() - : size_(0) - , position_(0) - , memory_(0) - , ownedMemory_(false) - { - } - - - MemoryReader::MemoryReader(const void* memory, std::size_t size, bool ownAndFree) - : size_(size) - , position_((const char*)(memory)) - , memory_((const char*)(memory)) - , ownedMemory_(ownAndFree) - { - } - - MemoryReader::~MemoryReader() - { - if (ownedMemory_) - { - free(const_cast(memory_)); - memory_ = 0; - size_ = 0; - } - } - - void MemoryReader::setPosition(const char* position) - { - position_ = position; - } - - void MemoryReader::read(void* data, std::size_t size) - { - YASLI_ASSERT(memory_ && position_); - YASLI_ASSERT(position_ - memory_ + size <= size_); - memcpy(data, position_, size); - position_ += size; - } - - bool MemoryReader::checkedRead(void* data, std::size_t size) - { - if (!memory_ || !position_) - { - return false; - } - if (position_ - memory_ + size > size_) - { - return false; - } - - memcpy(data, position_, size); - position_ += size; - return true; - } - - bool MemoryReader::checkedSkip(std::size_t size) - { - if (!memory_ || !position_) - { - return false; - } - if (position_ - memory_ + size > size_) - { - return false; - } - - position_ += size; - return true; - } -} diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryReader.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryReader.h deleted file mode 100644 index 1785574285..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryReader.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_MEMORYREADER_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_MEMORYREADER_H -#pragma once - - -#include - -namespace Serialization { - class MemoryReader - { - public: - MemoryReader(); - MemoryReader(const void* memory, size_t size, bool ownAndFree = false); - ~MemoryReader(); - - void setPosition(const char* position); - const char* position() { return position_; } - - template - void read(T& value) - { - read(reinterpret_cast(&value), sizoef(value)); - } - void read(void* data, size_t size); - bool checkedSkip(size_t size); - bool checkedRead(void* data, size_t size); - template - bool checkedRead(T& t) - { - return checkedRead((void*)&t, sizeof(t)); - } - - const char* buffer() const { return memory_; } - size_t size() const { return size_; } - - const char* begin() const { return memory_; } - const char* end() const { return memory_ + size_; } - - - private: - size_t size_; - const char* position_; - const char* memory_; - bool ownedMemory_; - }; -} -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_MEMORYREADER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryWriter.cpp b/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryWriter.cpp deleted file mode 100644 index 7cb515bb10..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryWriter.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include -#include "Serialization/Assert.h" -#include -#include -#include -#include -#ifdef _MSC_VER -# include -# define isnan _isnan -#endif - -#include "MemoryWriter.h" - -#undef YASLI_ASSERT -#define YASLI_ASSERT(x) - -namespace Serialization { - MemoryWriter::MemoryWriter(std::size_t size, bool reallocate) - : size_(size) - , reallocate_(reallocate) - , digits_(5) - { - allocate(size); - } - - MemoryWriter::~MemoryWriter() - { - position_ = 0; - free(memory_); - } - - void MemoryWriter::allocate(std::size_t initialSize) - { - memory_ = (char*)malloc(initialSize + 1); - position_ = memory_; - } - - void MemoryWriter::reallocate(std::size_t newSize) - { - YASLI_ASSERT(newSize > size_); - std::size_t pos = position(); - memory_ = (char*)realloc(memory_, newSize + 1); - YASLI_ASSERT(memory_ != 0); - position_ = memory_ + pos; - size_ = newSize; - } - - MemoryWriter& MemoryWriter::operator<<(int value) - { - // TODO: optimize - char buffer[12]; - sprintf_s(buffer, "%i", value); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(long value) - { - // TODO: optimize - char buffer[12]; -#ifdef _MSC_VER - sprintf_s(buffer, "%i", value); -#else - sprintf_s(buffer, "%li", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned long value) - { - // TODO: optimize - char buffer[12]; -#ifdef _MSC_VER - sprintf_s(buffer, "%u", value); -#else - sprintf_s(buffer, "%lu", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(long long value) - { - // TODO: optimize - char buffer[24]; -#ifdef _MSC_VER - sprintf_s(buffer, "%I64i", value); -#else - sprintf_s(buffer, "%lli", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned long long value) - { - // TODO: optimize - char buffer[24]; -#ifdef _MSC_VER - sprintf_s(buffer, "%I64u", value); -#else - sprintf_s(buffer, "%llu", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned int value) - { - // TODO: optimize - char buffer[12]; - sprintf_s(buffer, "%u", value); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(signed char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - inline void cutRightZeros(const char* str) - { - for (char* p = (char*)str + strlen(str) - 1; p >= str; --p) - { - if (*p == '0') - { - *p = 0; - } - else - { - return; - } - } - } - - MemoryWriter& MemoryWriter::operator<<(double value) - { - // YASLI_ASSERT(!isnan(value)); disabled, because physics data is not always initialized - - int point = 0; - int sign = 0; - -#ifdef _MSC_VER - char buf[_CVTBUFSIZE]; - _fcvt_s(buf, value, digits_, &point, &sign); -#else - const char* buf = fcvt(value, digits_, &point, &sign); -#endif - - if (sign != 0) - { - write("-"); - } - if (point <= 0) - { - cutRightZeros(buf); - if (strlen(buf)) - { - write("0."); - while (point < 0) - { - write("0"); - ++point; - } - write(buf); - } - else - { - write("0"); - } - *position_ = '\0'; - } - else - { - write(buf, point); - write("."); - cutRightZeros(buf + point); - operator<<(buf + point); - } - return *this; - } - - MemoryWriter& MemoryWriter::operator<<(const char* value) - { - write((void*)value, strlen(value)); - YASLI_ASSERT(position() < size()); - *position_ = '\0'; - return *this; - } - - MemoryWriter& MemoryWriter::operator<<(const wchar_t* value) - { - write((void*)value, wcslen(value) * sizeof(wchar_t)); - YASLI_ASSERT(position() < size()); - *position_ = '\0'; - return *this; - } - - void MemoryWriter::setPosition(std::size_t pos) - { - YASLI_ASSERT(pos < size_); - YASLI_ASSERT(memory_ + pos <= position_); - position_ = memory_ + pos; - } - - void MemoryWriter::write(const char* value) - { - write((void*)value, strlen(value)); - } - - bool MemoryWriter::write(const void* data, std::size_t size) - { - YASLI_ASSERT(memory_ <= position_); - YASLI_ASSERT(position() < this->size()); - if (size_ - position() > size) - { - memcpy(position_, data, size); - position_ += size; - } - else - { - if (!reallocate_) - { - return false; - } - - reallocate(size_ * 2); - write(data, size); - } - YASLI_ASSERT(position() < this->size()); - return true; - } - - void MemoryWriter::write(char c) - { - if (size_ - position() > 1) - { - *(char*)(position_) = c; - ++position_; - } - else - { - YASLI_ESCAPE(reallocate_, return ); - reallocate(size_ * 2); - write(c); - } - YASLI_ASSERT(position() < this->size()); - } -} diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryWriter.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryWriter.h deleted file mode 100644 index acd852cb62..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/MemoryWriter.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_MEMORYWRITER_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_MEMORYWRITER_H -#pragma once - - -#include -#include "Pointers.h" -#include "EditorCommonAPI.h" - -namespace Serialization { - class MemoryWriter - : public RefCounter - { - public: - MemoryWriter(std::size_t size = 128, bool reallocate = true); - ~MemoryWriter(); - - const char* c_str() { return memory_; }; - const wchar_t* w_str() { return (wchar_t*)memory_; }; - char* buffer() { return memory_; } - const char* buffer() const { return memory_; } - std::size_t size() const{ return size_; } - void clear() { position_ = memory_; } - - // String interface (after this calls '\0' is always written) - MemoryWriter& operator<<(int value); - MemoryWriter& operator<<(long value); - MemoryWriter& operator<<(unsigned long value); - MemoryWriter& operator<<(unsigned int value); - MemoryWriter& operator<<(long long value); - MemoryWriter& operator<<(unsigned long long value); - MemoryWriter& operator<<(float value) { return (*this) << double(value); } - MemoryWriter& operator<<(double value); - MemoryWriter& operator<<(signed char value); - MemoryWriter& operator<<(unsigned char value); - MemoryWriter& operator<<(char value); - MemoryWriter& operator<<(const char* value); - MemoryWriter& operator<<(const wchar_t* value); - - // Binary interface (does not writes trailing '\0') - template - void write(const T& value) - { - write(reinterpret_cast(&value), sizeof(value)); - } - void write(char c); - void write(const char* str); - bool write(const void* data, std::size_t size); - - std::size_t position() const { return position_ - memory_; } - void setPosition(std::size_t pos); - - MemoryWriter& setDigits(int digits) { digits_ = (unsigned char)digits; return *this; } - - private: - void allocate(std::size_t initialSize); - void reallocate(std::size_t newSize); - - std::size_t size_; - char* position_; - char* memory_; - bool reallocate_; - unsigned char digits_; - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_MEMORYWRITER_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Pointers.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Pointers.h deleted file mode 100644 index db674701d4..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Pointers.h +++ /dev/null @@ -1,265 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_POINTERS_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_POINTERS_H -#pragma once - -#include "Serialization/Assert.h" - -namespace Serialization { - class RefCounter - { - public: - RefCounter() - : refCounter_(0) - {} - ~RefCounter() {}; - - int refCount() const { return refCounter_; } - - void acquire() { ++refCounter_; } - int release() { return --refCounter_; } - private: - int refCounter_; - }; - - class PolyRefCounter - : public RefCounter - { - public: - virtual ~PolyRefCounter() {} - }; - - class PolyPtrBase - { - public: - PolyPtrBase() - : ptr_(0) - { - } - void release() - { - if (ptr_) - { - if (!ptr_->release()) - { - delete ptr_; - } - ptr_ = 0; - } - } - void set(PolyRefCounter* const ptr) - { - if (ptr_ != ptr) - { - release(); - ptr_ = ptr; - if (ptr_) - { - ptr_->acquire(); - } - } - } - protected: - PolyRefCounter* ptr_; - }; - - template - class PolyPtr - : public PolyPtrBase - { - public: - PolyPtr() - : PolyPtrBase() - { - } - - PolyPtr(PolyRefCounter* ptr) - { - set(ptr); - } - - template - PolyPtr(U* ptr) - { - // TODO: replace with static_assert - YASLI_ASSERT("PolyRefCounter must be a first base when used with multiple inheritance." && - static_cast(ptr) == reinterpret_cast(ptr)); - set(static_cast(ptr)); - } - - PolyPtr(const PolyPtr& ptr) - : PolyPtrBase() - { - set(ptr.ptr_); - } - ~PolyPtr() - { - release(); - } - operator T*() const { - return get(); - } - template - operator PolyPtr() const { - return PolyPtr(get()); - } - operator bool() const { - return ptr_ != 0; - } - - PolyPtr& operator=(const PolyPtr& ptr) - { - set(ptr.ptr_); - return *this; - } - T* get() const { return reinterpret_cast(ptr_); } - T& operator*() const - { - return *get(); - } - T* operator->() const { return get(); } - }; - - class IArchive; - template - class SharedPtr - { - public: - SharedPtr() - : ptr_(0) {} - SharedPtr(T* const ptr) - : ptr_(0) - { - set(ptr); - } - SharedPtr(const SharedPtr& ptr) - : ptr_(0) - { - set(ptr.ptr_); - } - ~SharedPtr() - { - release(); - } - operator T*() const { - return get(); - } - template - operator SharedPtr() const { - return SharedPtr(get()); - } - SharedPtr& operator=(const SharedPtr& ptr) - { - set(ptr.ptr_); - return *this; - } - T* get() { return ptr_; } - T* get() const { return ptr_; } - T& operator*() - { - return *get(); - } - T* operator->() const { return get(); } - void release() - { - if (ptr_) - { - if (!ptr_->release()) - { - delete ptr_; - } - ptr_ = 0; - } - } - template - void set(_T* const ptr) { reset(ptr); } - template - void reset(_T* const ptr) - { - if (ptr_ != ptr) - { - release(); - ptr_ = ptr; - if (ptr_) - { - ptr_->acquire(); - } - } - } - protected: - T* ptr_; - }; - - - template - class AutoPtr - { - public: - AutoPtr() - : ptr_(0) - { - } - AutoPtr(T* ptr) - : ptr_(0) - { - set(ptr); - } - ~AutoPtr() - { - release(); - } - AutoPtr& operator=(T* ptr) - { - set(ptr); - return *this; - } - void set(T* ptr) - { - if (ptr_ && ptr_ != ptr) - { - release(); - } - ptr_ = ptr; - } - T* get() const { return ptr_; } - operator T*() const { - return get(); - } - void detach() - { - ptr_ = 0; - } - void release() - { - delete ptr_; - ptr_ = 0; - } - T& operator*() const { return *get(); } - T* operator->() const { return get(); } - private: - T* ptr_; - }; - - class IArchive; -} - -template -bool Serialize(Serialization::IArchive& ar, Serialization::SharedPtr& ptr, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, Serialization::PolyPtr& ptr, const char* name, const char* label); - -#include -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_POINTERS_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/PointersImpl.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/PointersImpl.h deleted file mode 100644 index 3d5d5d0c72..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/PointersImpl.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_POINTERSIMPL_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_POINTERSIMPL_H -#pragma once - - -#include "Pointers.h" -#include "Serialization/IClassFactory.h" -#include "Serialization/ClassFactory.h" - -namespace Serialization { - template - class SharedPtrSerializer - : public IPointer - { - public: - SharedPtrSerializer(SharedPtr& ptr) - : ptr_(ptr) - {} - - const char* registeredTypeName() const - { - if (ptr_) - { - return ClassFactory::the().getRegisteredTypeName(ptr_.get()); - } - else - { - return ""; - } - } - void create(const char* typeName) const - { - YASLI_ASSERT(!ptr_ || ptr_->refCount() == 1); - if (typeName && typeName[0] != '\0') - { - ptr_.set(factory()->create(typeName)); - } - else - { - ptr_.set((T*)0); - } - } - TypeID baseType() const { return TypeID::get(); } - virtual SStruct serializer() const - { - return SStruct(*ptr_); - } - void* get() const - { - return reinterpret_cast(ptr_.get()); - } - const void* handle() const - { - return &ptr_; - } - TypeID pointerType() const - { - return TypeID::get >(); - } - virtual ClassFactory* factory() const{ return &ClassFactory::the(); } - - protected: - SharedPtr& ptr_; - }; - - template - class PolyPtrSerializer - : public IPointer - { - public: - PolyPtrSerializer(PolyPtr& ptr) - : ptr_(ptr) - {} - - TypeID type() const - { - if (ptr_) - { - return TypeID::get(ptr_.get()); - } - else - { - return TypeID(); - } - } - void create(TypeID type) const - { - // YASLI_ASSERT(!ptr_ || ptr_->refCount() == 1); not necessary to be true - if (type) - { - ptr_.set(ClassFactory::the().create(type)); - } - else - { - ptr_.set((T*)0); - } - } - TypeID baseType() const { return TypeID::get(); } - virtual SStruct serializer() const - { - return SStruct(*ptr_); - } - void* get() const - { - return reinterpret_cast(ptr_.get()); - } - IClassFactory* factory() const { return &ClassFactory::the(); } - - protected: - PolyPtr& ptr_; - }; -} - -template -bool Serialize(Serialization::IArchive& ar, Serialization::SharedPtr& ptr, const char* name, const char* label) -{ - return ar(static_cast(Serialization::SharedPtrSerializer(ptr)), name, label); -} - -template -bool Serialize(Serialization::IArchive& ar, Serialization::PolyPtr& ptr, const char* name, const char* label) -{ - return ar(static_cast(Serialization::PolyPtrSerializer(ptr)), name, label); -} -// vim:sw=4 ts=4: - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_POINTERSIMPL_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Qt.cpp b/Code/Sandbox/Plugins/EditorCommon/Serialization/Qt.cpp deleted file mode 100644 index f3001b95da..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Qt.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "EditorCommonAPI.h" -#include "Serialization/Serializer.h" -#include "Serialization/Qt.h" -#include "Serialization/STL.h" -#include "Serialization/IArchive.h" -#include -#include -#include -#include -#include - -class StringQt - : public Serialization::IWString -{ -public: - StringQt(QString& str) - : str_(str) {} - - void set(const wchar_t* value) { str_.setUnicode((const QChar*)value, (int)wcslen(value)); } - const wchar_t* get() const { return (wchar_t*)str_.data(); } - const void* handle() const { return &str_; } - Serialization::TypeID type() const{ return Serialization::TypeID::get(); } -private: - QString& str_; -}; - -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QString& value, const char* name, const char* label) -{ - StringQt str(value); - return ar(static_cast(str), name, label); -} - -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QByteArray& byteArray, const char* name, const char* label) -{ - std::vector temp(byteArray.begin(), byteArray.end()); - if (!ar(temp, name, label)) - { - return false; - } - if (ar.IsInput()) - { - byteArray = QByteArray(temp.empty() ? (char*)0 : (char*)&temp[0], (int)temp.size()); - } - return true; -} - -QString GetIndexPath(QAbstractItemModel* model, const QModelIndex& index) -{ - QString path; - - QModelIndex cur = index; - while (cur.isValid() && cur != QModelIndex()) - { - if (!path.isEmpty()) - { - path = QString("|") + path; - } - path = model->data(cur).toString() + path; - cur = model->parent(cur); - } - return path; -} - -QModelIndex FindIndexChildByText(QAbstractItemModel* model, const QModelIndex& parent, const QString& text) -{ - int rowCount = model->rowCount(parent); - for (int i = 0; i < rowCount; ++i) - { - QModelIndex child = model->index(i, 0, parent); - QString childText = model->data(child).toString(); - if (childText == text) - { - return child; - } - } - return QModelIndex(); -} - -QModelIndex GetIndexByPath(QAbstractItemModel* model, const QString& path) -{ - QStringList items = path.split('|'); - QModelIndex cur = QModelIndex(); - for (int i = 0; i < items.size(); ++i) - { - cur = FindIndexChildByText(model, cur, items[i]); - if (!cur.isValid()) - { - return QModelIndex(); - } - } - return cur; -} - -std::vector GetIndexPaths(QAbstractItemModel* model, const QModelIndexList& indices) -{ - std::vector result; - for (int i = 0; i < indices.size(); ++i) - { - QString path = GetIndexPath(model, indices[i]); - if (!path.isEmpty()) - { - result.push_back(path); - } - } - return result; -} - -QModelIndexList GetIndicesByPath(QAbstractItemModel* model, const std::vector& paths) -{ - QModelIndexList result; - for (int i = 0; i < paths.size(); ++i) - { - QModelIndex index = GetIndexByPath(model, paths[i]); - if (index.isValid()) - { - result.push_back(index); - } - } - return result; -} - -struct QTreeViewStateSerializer -{ - QTreeView* treeView; - QTreeViewStateSerializer(QTreeView* treeView) - : treeView(treeView) {} - - void Serialize(Serialization::IArchive& ar) - { - QAbstractItemModel* model = treeView->model(); - - std::vector expandedItems; - if (ar.IsOutput()) - { - std::vector stack; - stack.push_back(QModelIndex()); - while (!stack.empty()) - { - QModelIndex index = stack.back(); - stack.pop_back(); - - int rowCount = model->rowCount(index); - for (int i = 0; i < rowCount; ++i) - { - QModelIndex child = model->index(i, 0, index); - if (treeView->isExpanded(child)) - { - stack.push_back(child); - expandedItems.push_back(GetIndexPath(model, child)); - } - } - } - } - ar(expandedItems, "expandedItems"); - if (ar.IsInput()) - { - treeView->collapseAll(); - for (size_t i = 0; i < expandedItems.size(); ++i) - { - QModelIndex index = GetIndexByPath(model, expandedItems[i]); - if (index.isValid()) - { - treeView->expand(index); - } - } - } - - std::vector selectedItems; - if (ar.IsOutput()) - { - selectedItems = GetIndexPaths(model, treeView->selectionModel()->selectedIndexes()); - } - ar(selectedItems, "selectedItems"); - if (ar.IsInput()) - { - QModelIndexList indices = GetIndicesByPath(model, selectedItems); - if (!indices.empty()) - { - treeView->selectionModel()->select(QModelIndex(), QItemSelectionModel::ClearAndSelect); - for (int i = 0; i < indices.size(); ++i) - { - treeView->selectionModel()->select(indices[i], QItemSelectionModel::Select); - } - } - } - - QString currentItem; - if (ar.IsOutput()) - { - currentItem = GetIndexPath(model, treeView->selectionModel()->currentIndex()); - } - ar(currentItem, "currentItem"); - if (ar.IsInput()) - { - QModelIndex currentIndex = GetIndexByPath(model, currentItem); - treeView->scrollTo(currentIndex, QAbstractItemView::PositionAtCenter); - treeView->selectionModel()->setCurrentIndex(currentIndex, QItemSelectionModel::Current); - } - - std::vector sectionsHidden; - std::vector sectionsVisible; - if (ar.IsOutput()) - { - for (int i = 0; i < treeView->model()->columnCount(); ++i) - { - if (treeView->header()->isSectionHidden(i)) - { - sectionsHidden.push_back(i); - } - else - { - sectionsVisible.push_back(i); - } - } - } - ar(sectionsHidden, "sectionsHidden"); - ar(sectionsVisible, "sectionsVisible"); - if (ar.IsInput()) - { - int columnCount = treeView->model()->columnCount(); - for (int i = 0; i < sectionsHidden.size(); ++i) - { - int section = sectionsHidden[i]; - if (section >= 0 && section < columnCount) - { - treeView->header()->hideSection(section); - } - } - for (int i = 0; i < sectionsVisible.size(); ++i) - { - int section = sectionsVisible[i]; - if (section >= 0 && section < columnCount) - { - treeView->header()->showSection(section); - } - } - } - } -}; - -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QTreeView* treeView, const char* name, const char* label) -{ - return ar(QTreeViewStateSerializer(treeView), name, label); -} - - -static const char* g_paletteColorGroupNames[QPalette::NColorGroups] = { - "Active", "Disabled", "Inactive" -}; - -static const char* g_paletteColorRoleNames[QPalette::NColorRoles] = { - "WindowText", "Button", "Light", "Midlight", "Dark", "Mid", - "Text", "BrightText", "ButtonText", "Base", "Window", "Shadow", - "Highlight", "HighlightedText", - "Link", "LinkVisited", - "AlternateBase", - "NoRole", - "ToolTipBase", "ToolTipText", -#if !defined(AZ_PLATFORM_LINUX) - "PlaceholderText", -#endif // !defined(AZ_PLATFORM_LINUX) -}; - -struct QPaletteSerializable -{ - QPalette& palette; - QPaletteSerializable(QPalette& palette) - : palette(palette) - { - } - - struct SRole - { - int role; - QPalette& palette; - - SRole(QPalette& palette, int role) - : palette(palette) - , role(role) - { - } - - void Serialize(Serialization::IArchive& ar) - { - for (int group = 0; group < QPalette::NColorGroups; ++group) - { - QColor color = palette.color(QPalette::ColorGroup(group), QPalette::ColorRole(role)); - ar(color, g_paletteColorGroupNames[group], g_paletteColorGroupNames[group]); - if (ar.IsInput()) - { - palette.setColor(QPalette::ColorGroup(group), QPalette::ColorRole(role), color); - } - } - } - }; - - void Serialize(Serialization::IArchive& ar) - { - for (int roleIndex = 0; roleIndex < QPalette::NColorRoles; ++roleIndex) - { - SRole role(palette, roleIndex); - ar(role, g_paletteColorRoleNames[roleIndex], g_paletteColorRoleNames[roleIndex]); - } - } -}; - -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QPalette& palette, const char* name, const char* label) -{ - QPaletteSerializable serializer(palette); - return ar(serializer, name, label); -} - -struct QColorSerializable -{ - QColor& color; - QColorSerializable(QColor& color) - : color(color) {} - - void Serialize(Serialization::IArchive& ar) - { - // this is not comprehensive, as QColor can store color components - // in diffrent models, depending on the way they were specified - unsigned char r = color.red(); - unsigned char g = color.green(); - unsigned char b = color.blue(); - unsigned char a = color.alpha(); - ar(r, "r", "^R"); - ar(g, "g", "^G"); - ar(b, "b", "^B"); - ar(a, "a", "^A"); - if (ar.IsInput()) - { - color.setRed(r); - color.setGreen(g); - color.setBlue(b); - color.setAlpha(a); - } - } -}; - -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QColor& color, const char* name, const char* label) -{ - QColorSerializable serializer(color); - return ar(serializer, name, label); -} - -struct QSplitterSerializer -{ - QSplitter& splitter; - - QSplitterSerializer(QSplitter& splitter) - : splitter(splitter) {} - - void Serialize(Serialization::IArchive& ar) - { - QList qsizes = splitter.sizes(); - std::vector sizes(qsizes.begin(), qsizes.end()); - ar(sizes, "sizes", "Sizes"); - if (ar.IsInput()) - { - qsizes.clear(); - for (int i = 0; i < sizes.size(); ++i) - { - qsizes.push_back(sizes[i]); - } - splitter.setSizes(qsizes); - } - } -}; - -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QSplitter* splitter, const char* name, const char* label) -{ - if (!splitter) - { - return false; - } - QSplitterSerializer serializer(*splitter); - return ar(serializer, name, label); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Qt.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Qt.h deleted file mode 100644 index c315567bb0..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Qt.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_QT_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_QT_H -#pragma once - -#include "EditorCommonAPI.h" - -class QByteArray; -class QColor; -class QPalette; -class QSplitter; -class QString; -class QTreeView; - -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QSplitter* splitter, const char* name, const char* label); -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QByteArray& value, const char* name, const char* label); -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QString& value, const char* name, const char* label); -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QTreeView* treeViewState, const char* name, const char* label); -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QPalette& palette, const char* name, const char* label); -bool EDITOR_COMMON_API Serialize(Serialization::IArchive& ar, QColor& color, const char* name, const char* label); -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_QT_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/QtImpl.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/QtImpl.h deleted file mode 100644 index 299e9be568..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/QtImpl.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_QTIMPL_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_QTIMPL_H -#pragma once - -#include "Serialization/Serializer.h" - -namespace Serialization { -} - - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_QTIMPL_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/Token.h b/Code/Sandbox/Plugins/EditorCommon/Serialization/Token.h deleted file mode 100644 index 1c9f803e55..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/Token.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_SERIALIZATION_TOKEN_H -#define CRYINCLUDE_EDITORCOMMON_SERIALIZATION_TOKEN_H -#pragma once - -#include - -#include "Serialization/Strings.h" - -namespace Serialization { - struct Token - { - Token(const char* _str = 0) - : start(_str) - , end(_str ? _str + strlen(_str) : 0) - { - } - - Token(const char* _str, size_t _len) - : start(_str) - , end(_str + _len) {} - Token(const char* _start, const char* _end) - : start(_start) - , end(_end) {} - - void set(const char* _start, const char* _end) { start = _start; end = _end; } - std::size_t length() const{ return end - start; } - - bool operator==(const Token& rhs) const - { - if (length() != rhs.length()) - { - return false; - } - return memcmp(start, rhs.start, length()) == 0; - } - bool operator==(const string& rhs) const - { - if (length() != rhs.size()) - { - return false; - } - return memcmp(start, rhs.c_str(), length()) == 0; - } - - bool operator==(const char* text) const - { - if (strncmp(text, start, length()) == 0) - { - return text[length()] == '\0'; - } - return false; - } - bool operator!=(const char* text) const - { - if (strncmp(text, start, length()) == 0) - { - return text[length()] != '\0'; - } - return true; - } - bool operator==(char c) const - { - return length() == 1 && *start == c; - } - bool operator!=(char c) const - { - return length() != 1 || *start != c; - } - - operator bool() const{ - return start != end; - } - string str() const{ return string(start, end); } - - const char* start; - const char* end; - }; -} - -#endif // CRYINCLUDE_EDITORCOMMON_SERIALIZATION_TOKEN_H diff --git a/Code/Sandbox/Plugins/EditorCommon/Serialization/yasli_NOTICES.txt b/Code/Sandbox/Plugins/EditorCommon/Serialization/yasli_NOTICES.txt deleted file mode 100644 index 5e8ea4b43e..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Serialization/yasli_NOTICES.txt +++ /dev/null @@ -1,49 +0,0 @@ -Portions based on WWidgets and Yasli Serialization Library - -wWidgets - Lightweight UI Toolkit. -Copyright (C) 2009-2011 Evgeny Andreeshchev - Alexander Kotliar - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - - -Yasli Serialization Library -Copyright (c) 2007 Eugene Andreeshchev - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/Code/Sandbox/Plugins/EditorCommon/Timeline.cpp b/Code/Sandbox/Plugins/EditorCommon/Timeline.cpp deleted file mode 100644 index 49a3a07f35..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Timeline.cpp +++ /dev/null @@ -1,2728 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "Timeline.h" -#include "QtUtil.h" -#include "DrawingPrimitives/TimeSlider.h" -#include "DrawingPrimitives/Ruler.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef min -#undef min -#endif - -#ifdef max -#undef max -#endif - -int STimelineViewState::ScrollOffset(float origin) const -{ - return int((origin / visibleDistance + 0.5f) * widthPixels); -} - -int STimelineViewState::TimeToLayout(float time) const -{ - return int((time / visibleDistance) * widthPixels + 0.5f); -} - -int STimelineViewState::TimeToLocal(float time) const -{ - return TimeToLayout(time) + treeWidth + scrollPixels.x(); -} - -float STimelineViewState::LayoutToTime(int x) const -{ - return (float(x) - 0.5f) / widthPixels * visibleDistance; -} - -float STimelineViewState::LocalToTime(int x) const -{ - return LayoutToTime(x - treeWidth - scrollPixels.x()); -} - -QPoint STimelineViewState::LocalToLayout(const QPoint& p) const -{ - return p - scrollPixels - QPoint(treeWidth, 0); -} - -QPoint STimelineViewState::LayoutToLocal(const QPoint& p) const -{ - return p + scrollPixels + QPoint(treeWidth, 0); -} - -enum -{ - THUMB_WIDTH = 12, - THUMB_HEIGHT = 24, - - RULER_HEIGHT = 16, - RULER_SHADOW_HEIGHT = 6, - RULER_MARK_HEIGHT = 8, - - TRACK_MARK_HEIGHT = 6, - - DEFAULT_KEY_WIDTH = 8, - VERTICAL_PADDING = 4, - TRACK_DESCRIPTION_INDENT = 8, - - SELECTION_WIDTH = 4, - SCROLL_SHADOW_WIDTH = 8, - - MAX_PUSH_OUT = VERTICAL_PADDING * 2, - PUSH_OUT_DISTANCE = 3, - - SPLITTER_WIDTH = 10, - - DEFAULT_TREE_WIDTH = 200, - TREE_LEFT_MARGIN = 6, - TREE_INDENT_MULTIPLIER = 12, - TREE_BRANCH_INDICATOR_SIZE = 8 -}; - -namespace -{ - const float DEFAULT_KEY_RADIUS = 0.1f; - const int TIMELINE_PADDING = 20; -} - -struct STimelineContentElementRef -{ - STimelineContentElementRef() - : pTrack(nullptr) - , index(0) - {} - - STimelineContentElementRef(STimelineTrack* pTrack, size_t index) - : pTrack(pTrack) - , index(index) - {} - - STimelineElement& GetElement() const - { - return pTrack->elements[index]; - } - - bool IsValid() const { return pTrack != 0 && index < pTrack->elements.size(); } - - bool operator<(const STimelineContentElementRef& rhs) const - { - if (pTrack == rhs.pTrack) - { - return index < rhs.index; - } - else - { - if (!pTrack && rhs.pTrack) - { - return true; - } - else if (pTrack && !rhs.pTrack) - { - return false; - } - else if (pTrack && rhs.pTrack) - { - return pTrack->name < rhs.pTrack->name; - } - return false; - } - } - - STimelineTrack* pTrack; - size_t index; -}; - -struct SElementLayout -{ - STimelineElement::EType type; - int caps; - float pushOutDistance; - QRect rect; - ColorB color; - string description; - - STimelineContentElementRef elementRef; - std::vector subElements; - - bool IsSelected() const - { - if ((elementRef.pTrack->caps & STimelineTrack::CAP_COMPOUND_TRACK) == 0) - { - return elementRef.GetElement().selected; - } - else - { - bool bSelected = false; - const size_t numSubElements = subElements.size(); - - for (size_t i = 0; i < numSubElements; ++i) - { - bSelected = bSelected || subElements[i].GetElement().selected; - } - - return bSelected; - } - } - - void SetSelected(const bool bSelected) const - { - if ((elementRef.pTrack->caps & STimelineTrack::CAP_COMPOUND_TRACK) == 0) - { - elementRef.GetElement().selected = bSelected; - } - else - { - const size_t numSubElements = subElements.size(); - for (size_t i = 0; i < numSubElements; ++i) - { - subElements[i].GetElement().selected = bSelected; - } - } - } - - SElementLayout() - : pushOutDistance(0.0f) - , caps(0) - , type(STimelineElement::KEY) - {} -}; - -struct STrackLayout; -typedef std::vector STrackLayouts; - -struct STrackLayout -{ - QRect rect; - int indent; - - STimelineTrack* pTimelineTrack; - - std::vector elements; - STrackLayouts tracks; - - STrackLayout() - : indent(0) - , pTimelineTrack(0) - { - } -}; - -struct STimelineLayout -{ - int thumbPositionX; - STrackLayouts tracks; - SAnimTime minStartTime; - SAnimTime maxEndTime; - QSize size; - - STimelineLayout() - : thumbPositionX(0) - , minStartTime(0.0f) - , maxEndTime(1.0f) - , size(1, 1) - { - } -}; - -namespace -{ - QColor InterpolateColor(const QColor& a, const QColor& b, float k) - { - float mk = 1.0f - k; - return QColor(aznumeric_cast(a.red() * mk + b.red() * k), - aznumeric_cast(a.green() * mk + b.green() * k), - aznumeric_cast(a.blue() * mk + b.blue() * k), - aznumeric_cast(a.alpha() * mk + b.alpha() * k)); - } - - void ClampViewOrigin(STimelineViewState* viewState, const STimelineLayout& layout) - { - float zoomOffset = viewState->visibleDistance * 0.5f; - - const float padding = viewState->LayoutToTime(TIMELINE_PADDING); - float maxViewOrigin = layout.minStartTime.ToFloat() - zoomOffset + padding; - float minViewOrigin = std::min(viewState->visibleDistance - layout.maxEndTime.ToFloat() - zoomOffset - padding, maxViewOrigin); - - viewState->viewOrigin = clamp_tpl(viewState->viewOrigin, minViewOrigin, maxViewOrigin); - } - - SElementLayout& AddElementToTrackLayout(STimelineTrack& track, STrackLayout& trackLayout, const STimelineElement& element, - const STimelineViewState& viewState, uint keyWidth, [[maybe_unused]] int treeWidth, int& currentTop, size_t elementIndex) - { - trackLayout.elements.push_back(SElementLayout()); - SElementLayout& elementl = trackLayout.elements.back(); - elementl.color = element.color; - elementl.type = element.type; - elementl.caps = element.caps; - elementl.description = element.description; - elementl.elementRef.pTrack = &track; - elementl.elementRef.index = elementIndex; - - if (element.type == STimelineElement::KEY) - { - int left = (viewState.TimeToLayout(element.start.ToFloat()) - keyWidth / 2); - int right = left + keyWidth; - elementl.rect = QRect(left, currentTop + VERTICAL_PADDING, right - left, track.height - VERTICAL_PADDING * 2); - } - else - { - int left = viewState.TimeToLayout(element.start.ToFloat()); - int right = viewState.TimeToLayout(element.end.ToFloat()); - elementl.rect = QRect(left, currentTop + VERTICAL_PADDING, right - left, track.height - VERTICAL_PADDING * 2); - } - - return elementl; - } - - void AddCompoundElementsToTrackLayout(STimelineTrack& track, STimelineLayout* layout, const STimelineViewState& viewState, int trackId, uint keyWidth, int treeWidth, int& currentTop) - { - const size_t numSubTracks = track.tracks.size(); - SAnimTime currentElementTime = SAnimTime::Min(); - size_t* pCurrentSubTrackIndices = static_cast(alloca(sizeof(size_t) * numSubTracks)); - memset(pCurrentSubTrackIndices, 0, sizeof(size_t) * numSubTracks); - - while (true) - { - bool bElementFound = false; - SAnimTime minElementTime = SAnimTime::Max(); - - // First search for minimum element time for current track positions - for (size_t i = 0; i < numSubTracks; ++i) - { - const STimelineTrack& subTrack = *track.tracks[i]; - const STimelineElements& elements = subTrack.elements; - const size_t numTrackElements = elements.size(); - const size_t index = pCurrentSubTrackIndices[i]; - - if (index < numTrackElements) - { - const SAnimTime elementTime = elements[index].start; - minElementTime = min(elementTime, minElementTime); - bElementFound = true; - } - } - - if (!bElementFound) - { - break; - } - - STimelineElement compoundElement; - compoundElement.start = minElementTime; - compoundElement.end = minElementTime; - - // If elements were found create a compound element - STrackLayout& trackLayout = layout->tracks[trackId]; - SElementLayout& compoundElementLayout = AddElementToTrackLayout(track, trackLayout, compoundElement, viewState, keyWidth, treeWidth, currentTop, 0); - currentElementTime = minElementTime; - - compoundElementLayout.description = "("; - - // Advance track positions and add elements IDs to compound element if times match - for (size_t i = 0; i < numSubTracks; ++i) - { - STimelineTrack* pSubTrack = track.tracks[i]; - const STimelineElements& elements = pSubTrack->elements; - const size_t numTrackElements = elements.size(); - size_t& index = pCurrentSubTrackIndices[i]; - - if (index < numTrackElements) - { - const SAnimTime elementTime = elements[index].start; - - if (elementTime == minElementTime) - { - STimelineContentElementRef ref; - ref.pTrack = pSubTrack; - ref.index = index; - compoundElementLayout.subElements.push_back(ref); - compoundElementLayout.description += elements[index].description; - ++index; - } - else - { - compoundElementLayout.description += "-"; - } - - if ((i + 1) < numSubTracks) - { - compoundElementLayout.description += ", "; - } - } - } - - compoundElementLayout.description += ")"; - } - } - - bool FilterTracks(const STimelineTrack& track, std::unordered_set& invisibleTracks, const char* filterString) - { - bool bAnyChildVisible = false; - const bool bNameMatchesFilter = CryStringUtils::stristr(track.name, filterString) != nullptr; - - if (!bNameMatchesFilter) - { - const size_t numChildTracks = track.tracks.size(); - for (size_t i = 0; i < numChildTracks; ++i) - { - bAnyChildVisible = FilterTracks(*track.tracks[i], invisibleTracks, filterString) || bAnyChildVisible; - } - } - - if (!bNameMatchesFilter && !bAnyChildVisible) - { - invisibleTracks.insert(&track); - } - - return bNameMatchesFilter || bAnyChildVisible; - } - - void CalculateMinMaxTime(STimelineLayout* layout, STimelineTrack& parentTrack) - { - layout->minStartTime = min(layout->minStartTime, parentTrack.startTime); - layout->maxEndTime = max(layout->maxEndTime, parentTrack.endTime); - - const size_t numTracks = parentTrack.tracks.size(); - for (size_t i = 0; i < numTracks; ++i) - { - STimelineTrack& track = *parentTrack.tracks[i]; - CalculateMinMaxTime(layout, track); - } - } - - void CalculateTrackLayout(STimelineLayout* layout, int& currentTop, int currentIndent, STimelineTrack& parentTrack, const STimelineViewState& viewState, - float thumbTime, uint keyWidth, int treeWidth, const std::unordered_set& invisibleTracks) - { - const size_t numTracks = parentTrack.tracks.size(); - for (size_t i = 0; i < numTracks; ++i) - { - STimelineTrack& track = *parentTrack.tracks[i]; - - if (stl::find(invisibleTracks, &track)) - { - continue; - } - - layout->tracks.push_back(STrackLayout()); - STrackLayout& trackLayout = layout->tracks.back(); - trackLayout.elements.reserve(track.elements.size()); - trackLayout.indent = currentIndent; - trackLayout.pTimelineTrack = &track; - - const bool bIsCompositeTrack = (track.caps & STimelineTrack::CAP_COMPOUND_TRACK) != 0; - - if (bIsCompositeTrack) - { - const int trackLayoutId = layout->tracks.size() - 1; - AddCompoundElementsToTrackLayout(track, layout, viewState, trackLayoutId, keyWidth, treeWidth, currentTop); - } - else - { - for (size_t i2 = 0; i2 < track.elements.size(); ++i2) - { - const STimelineElement& element = track.elements[i2]; - AddElementToTrackLayout(track, trackLayout, element, viewState, keyWidth, treeWidth, currentTop, i2); - } - } - - int left = viewState.TimeToLayout(track.startTime.ToFloat()); - int right = viewState.TimeToLayout(track.endTime.ToFloat()); - trackLayout.rect = QRect(left, currentTop, right - left, track.height); - currentTop += track.height; - - if (track.expanded) - { - CalculateTrackLayout(layout, currentTop, currentIndent + 1, track, viewState, thumbTime, keyWidth, treeWidth, invisibleTracks); - } - } - } - - void ApplyPushOut(STimelineLayout* layout, uint keyWidth) - { - float maxPushOut = 0.0f; - - const size_t numLayoutTracks = layout->tracks.size(); - for (size_t i = 0; i < numLayoutTracks; ++i) - { - STrackLayout& track = layout->tracks[i]; - - const size_t numElements = track.elements.size(); - for (size_t i2 = 0; i2 < numElements; ++i2) - { - if (track.elements[i2].type != STimelineElement::KEY) - { - continue; - } - - for (size_t j = 0; j < numElements; ++j) - { - if ((track.elements[j].type != STimelineElement::KEY) || (j == i2)) - { - continue; - } - - float distance = aznumeric_cast(track.elements[j].rect.left() - track.elements[i2].rect.left()); - float delta = clamp_tpl(1.0f - fabsf(distance) / keyWidth, 0.0f, 1.0f); - - if (delta == 0.0f) - { - continue; - } - - float& pushOutDistance = track.elements[i2].pushOutDistance; - pushOutDistance += (i2 < j) ? -delta : delta; - - if (fabsf(pushOutDistance) > maxPushOut) - { - maxPushOut = fabsf(pushOutDistance); - } - } - } - } - - float maxPushOutNormalized = float(MAX_PUSH_OUT) / PUSH_OUT_DISTANCE; - float pushOutScale = 1.0f; - - if (maxPushOut > maxPushOutNormalized && maxPushOut > 0.0f) - { - pushOutScale = maxPushOutNormalized / maxPushOut; - } - - for (size_t i = 0; i < numLayoutTracks; ++i) - { - STrackLayout& track = layout->tracks[i]; - - for (size_t j = 0; j < track.elements.size(); ++j) - { - track.elements[j].rect.translate(QPoint(0, int(pushOutScale * track.elements[j].pushOutDistance * PUSH_OUT_DISTANCE))); - } - } - } - - void CalculateLayout(STimelineLayout* layout, STimelineContent& content, const STimelineViewState& viewState, const QLineEdit* pFilterLineEdit, float thumbTime, uint keyWidth, bool treeVisible) - { - layout->thumbPositionX = viewState.TimeToLayout(thumbTime); - - if (!content.track.tracks.empty()) - { - layout->minStartTime = SAnimTime::Max(); - layout->maxEndTime = SAnimTime::Min(); - } - else - { - layout->minStartTime = SAnimTime(0.0f); - layout->maxEndTime = SAnimTime(1.0f); - } - - int currentTop = RULER_HEIGHT + VERTICAL_PADDING; - const int treeWidth = treeVisible ? viewState.treeWidth : 0; - - std::unordered_set invisibleTracks; - if (pFilterLineEdit && !pFilterLineEdit->text().isEmpty()) - { - FilterTracks(content.track, invisibleTracks, QtUtil::ToString(pFilterLineEdit->text())); - } - - CalculateMinMaxTime(layout, content.track); - CalculateTrackLayout(layout, currentTop, 0, content.track, viewState, thumbTime, keyWidth, treeWidth, invisibleTracks); - - layout->size = QSize(viewState.TimeToLayout(layout->maxEndTime.ToFloat()), currentTop + VERTICAL_PADDING); - } - - STrackLayout* HitTestTrack(STrackLayouts& tracks, const QPoint& point) - { - auto findIter = std::upper_bound(tracks.begin(), tracks.end(), point.y(), [&](int y, const STrackLayout& track) - { - return y < track.rect.bottom(); - }); - - if (findIter != tracks.end() && findIter->rect.contains(point)) - { - return &(*findIter); - } - - return nullptr; - } - - void ForEachTrack(STimelineTrack& track, AZStd::function fun) - { - fun(track); - - for (size_t i = 0; i < track.tracks.size(); ++i) - { - STimelineTrack& subTrack = *track.tracks[i]; - ForEachTrack(subTrack, fun); - } - } - - void ForEachElement(STimelineTrack& track, AZStd::function fun) - { - ForEachTrack(track, [&](STimelineTrack& subTrack) - { - for (size_t i = 0; i < subTrack.elements.size(); ++i) - { - fun(subTrack, subTrack.elements[i]); - } - }); - } - - void ForEachElementWithIndex(STimelineTrack& track, AZStd::function fun) - { - ForEachTrack(track, [&](STimelineTrack& subTrack) - { - for (size_t i = 0; i < subTrack.elements.size(); ++i) - { - fun(subTrack, subTrack.elements[i], i); - } - }); - } - - void ClearTrackSelection(STimelineTrack& track) - { - ForEachTrack(track, [](STimelineTrack& track) - { - track.selected = false; - }); - } - - void GetSelectedTracks(STimelineTrack& track, std::vector& tracks) - { - ForEachTrack(track, [&](STimelineTrack& track) - { - if (track.selected) - { - tracks.push_back(&track); - } - }); - } - - void ClearElementSelection(STimelineTrack& track) - { - ForEachElement(track, [](STimelineTrack& track, STimelineElement& element) - { - track.keySelectionChanged = track.keySelectionChanged || element.selected; - element.selected = false; - }); - } - - void SetSelectedElementTimes(STimelineTrack& track, const std::vector& times) - { - auto iter = times.begin(); - ForEachElement(track, [&](STimelineTrack& track, STimelineElement& element) - { - if (element.selected) - { - track.modified = true; - element.start = *(iter++); - } - }); - } - - std::vector GetSelectedElementTimes(STimelineTrack& track) - { - std::vector times; - ForEachElement(track, [&]([[maybe_unused]] STimelineTrack& track, STimelineElement& element) - { - if (element.selected) - { - times.push_back(element.start); - } - }); - return times; - } - - VectorSet GetSelectedElementsTimeSet(STimelineTrack& track) - { - VectorSet timeSet; - ForEachElement(track, [&]([[maybe_unused]] STimelineTrack& track, STimelineElement& element) - { - if (element.selected) - { - timeSet.insert(element.start); - } - }); - return timeSet; - } - - typedef std::vector > TSelectedElements; - TSelectedElements GetSelectedElements(STimelineTrack& track) - { - TSelectedElements elements; - - ForEachElement(track, [&](STimelineTrack& track, STimelineElement& element) - { - if (element.selected) - { - elements.push_back(std::make_pair(&track, &element)); - } - }); - - return elements; - } - - void MoveSelectedElements(STimelineTrack& track, SAnimTime delta) - { - ForEachElement(track, [&](STimelineTrack& track, STimelineElement& element) - { - if (element.selected) - { - track.modified = true; - element.start += delta; - } - }); - } - - void DeletedMarkedElements(STimelineTrack& track) - { - ForEachTrack(track, [&](STimelineTrack& track) - { - for (auto iter = track.elements.begin(); iter != track.elements.end(); ) - { - if (iter->deleted) - { - iter = track.elements.erase(iter); - } - else - { - ++iter; - } - } - }); - } - - void SelectElementsInRect(const STrackLayouts& tracks, const QRect& rect) - { - for (size_t j = 0; j < tracks.size(); ++j) - { - const STrackLayout& track = tracks[j]; - - for (size_t i = 0; i < track.elements.size(); ++i) - { - const SElementLayout& element = track.elements[i]; - - if ((element.caps & STimelineElement::CAP_SELECT) == 0) - { - continue; - } - - STimelineTrack* pTimelineTrack = element.elementRef.pTrack; - const bool bIsCompoundTrack = (pTimelineTrack->caps & STimelineTrack::CAP_COMPOUND_TRACK) != 0; - - if (element.rect.intersects(rect)) - { - if (!bIsCompoundTrack) - { - if (!element.elementRef.GetElement().selected) - { - element.elementRef.GetElement().selected = true; - element.elementRef.pTrack->keySelectionChanged = true; - } - } - else - { - const size_t numSubElements = element.subElements.size(); - - for (size_t k = 0; k < numSubElements; ++k) - { - if (!element.subElements[k].GetElement().selected) - { - element.subElements[k].GetElement().selected = true; - element.subElements[k].pTrack->keySelectionChanged = true; - } - } - } - } - } - - SelectElementsInRect(track.tracks, rect); - } - } - - typedef std::vector SElementLayoutPtrs; - bool HitTestElements(STrackLayouts& tracks, const QRect& rect, SElementLayoutPtrs& out) - { - bool bHit = false; - - for (size_t j = 0; j < tracks.size(); ++j) - { - STrackLayout& track = tracks[j]; - - for (size_t i = 0; i < track.elements.size(); ++i) - { - SElementLayout& element = track.elements[i]; - - if (element.rect.intersects(rect)) - { - out.push_back(&element); - bHit = true; - } - } - - bHit = bHit || HitTestElements(track.tracks, rect, out); - } - - return bHit; - } - - enum EPass - { - PASS_BACKGROUND, - PASS_SELECTION, - PASS_SHADOW, - PASS_MAIN, - NUM_PASSES - }; - - QBrush PickTrackBrush(const QPalette& palette, const STrackLayout& track) - { - const QColor trackColor = InterpolateColor(palette.color(QPalette::Mid), palette.color(QPalette::Window), 0.96f); - const QColor descriptionTrackColor = InterpolateColor(palette.color(QPalette::Mid), palette.color(QPalette::Window), 0.9f); - const QColor compositeTrackColor = InterpolateColor(palette.color(QPalette::Mid), palette.color(QPalette::Window), 0.85f); - const QColor selectionColor = InterpolateColor(palette.color(QPalette::Highlight), palette.color(QPalette::Window), 0.5f); - - const bool bIsDescriptionTrack = (track.pTimelineTrack->caps & STimelineTrack::CAP_DESCRIPTION_TRACK) != 0; - const bool bIsCompositeTrack = (track.pTimelineTrack->caps & STimelineTrack::CAP_COMPOUND_TRACK) != 0; - - const QColor color = bIsDescriptionTrack ? descriptionTrackColor : (bIsCompositeTrack ? compositeTrackColor : trackColor); - return QBrush(track.pTimelineTrack->selected ? InterpolateColor(color, selectionColor, 0.3f) : color); - } - - struct SElementLayoutIntCompareLeft - { - const bool operator()(const SElementLayout& a, int b) { return a.rect.left() < b; } - const bool operator()(int a, const SElementLayout& b) { return a < b.rect.left(); } - }; - - struct SElementLayoutIntCompareRight - { - const bool operator()(const SElementLayout& a, int b) { return a.rect.right() < b; } - const bool operator()(int a, const SElementLayout& b) { return a < b.rect.right(); } - }; - - void DrawTracks(QPainter& painter, const uint startPass, const uint endPass, const STimelineLayout& layout, const STimelineViewState& viewState, - const QPalette& palette, [[maybe_unused]] const QPoint& mousePos, bool hasFocus, int width, float keyRadius, float timeUnitScale, bool drawMarkers) - { - const STrackLayouts& tracks = layout.tracks; - - const int trackAreaLeft = viewState.LocalToLayout(QPoint(viewState.treeWidth, 0)).x(); - const int trackAreaRight = trackAreaLeft + width; - - const QColor textColor = palette.buttonText().color(); - QPen descriptionTextPen = QPen(InterpolateColor(textColor, palette.color(QPalette::Window), 0.5f)); - - DrawingPrimitives::STickOptions markOptions; - markOptions.m_rect = QRect(-viewState.scrollPixels.x(), 0, width - viewState.treeWidth, 0); - markOptions.m_visibleRange = Range(viewState.LocalToTime(viewState.treeWidth) * timeUnitScale, viewState.LocalToTime(width) * timeUnitScale); - markOptions.m_rulerRange = Range(layout.minStartTime.ToFloat() * timeUnitScale, layout.maxEndTime.ToFloat() * timeUnitScale); - markOptions.m_markHeight = TRACK_MARK_HEIGHT; - - // Precalculate ticks because they are the same for all tracks - std::vector ticks = DrawingPrimitives::CalculateTicks(markOptions.m_rect.width(), markOptions.m_visibleRange, markOptions.m_rulerRange, nullptr, nullptr); - - for (int i = startPass; i <= endPass; ++i) - { - EPass pass = (EPass)i; - - for (size_t j = 0; j < tracks.size(); ++j) - { - const STrackLayout& track = tracks[j]; - - const bool bIsDescriptionTrack = (track.pTimelineTrack->caps & STimelineTrack::CAP_DESCRIPTION_TRACK) != 0; - const bool bIsCompositeTrack = (track.pTimelineTrack->caps & STimelineTrack::CAP_COMPOUND_TRACK) != 0; - const bool bIsToggleTrack = (track.pTimelineTrack->caps & STimelineTrack::CAP_TOGGLE_TRACK) != 0; - - std::vector sortedElements = track.elements; - std::sort(sortedElements.begin(), sortedElements.end(), [](const SElementLayout& a, const SElementLayout& b) { return a.rect.left() < b.rect.left(); }); - const uint numElements = sortedElements.size(); - - if (pass == PASS_BACKGROUND) - { - painter.setPen(Qt::NoPen); - painter.setBrush(PickTrackBrush(palette, track)); - QRect backgroundRect = track.rect; - backgroundRect.setLeft(-viewState.scrollPixels.x()); - backgroundRect.setWidth(width); - painter.drawRect(backgroundRect); - - if (bIsDescriptionTrack) - { - painter.setPen(descriptionTextPen); - QRect textRect = track.rect; - textRect.moveLeft(textRect.left() - viewState.scrollPixels.x() + TRACK_DESCRIPTION_INDENT); - textRect.setWidth(width); - textRect.moveTop(textRect.top() + 1); - painter.drawText(textRect, QString(track.pTimelineTrack->name)); - } - - const int lineY = track.rect.bottom() + 1; - painter.setPen(QPen(InterpolateColor(palette.color(QPalette::Mid), palette.color(QPalette::Window), 0.75f))); - painter.drawLine(QPoint(trackAreaLeft, lineY), QPoint(trackAreaRight, lineY)); - - if (drawMarkers && !bIsDescriptionTrack) - { - markOptions.m_rect.setTop(track.rect.top()); - markOptions.m_rect.setBottom(track.rect.bottom()); - DrawingPrimitives::DrawTicks(ticks, painter, palette, markOptions); - } - - if (bIsToggleTrack) - { - const QColor toggleColor = InterpolateColor(QColor(255, 255, 255), palette.color(QPalette::Mid), 0.5f); - - const uint drawStart = track.pTimelineTrack->toggleDefaultState ? 0 : 1; - - painter.setBrush(QBrush(toggleColor)); - QRect toggleRect = track.rect; - toggleRect.setTop(toggleRect.top() + 2); - toggleRect.setBottom(toggleRect.bottom() - 2); - - for (uint i2 = drawStart; i2 <= numElements; i2 += 2) - { - const int left = (i2 == 0) ? (-viewState.scrollPixels.x()) : sortedElements[i2 - 1].rect.right(); - const int right = (i2 == numElements) ? (-viewState.scrollPixels.x() + width) : sortedElements[i2].rect.left(); - - toggleRect.setLeft(left); - toggleRect.setRight(right); - painter.drawRect(toggleRect); - } - } - - continue; - } - - auto begin = std::lower_bound(sortedElements.begin(), sortedElements.end(), -viewState.scrollPixels.x(), SElementLayoutIntCompareRight()); - auto end = std::upper_bound(sortedElements.begin(), sortedElements.end(), width - viewState.scrollPixels.x(), SElementLayoutIntCompareLeft()); - - if (begin != sortedElements.begin()) - { - --begin; - } - if (end != sortedElements.end()) - { - ++end; - } - - for (auto iter = begin; iter != end; ++iter) - { - const SElementLayout& element = *iter; - QRectF rect = QRectF(element.rect); - float ratio = 1.0f; - - if (rect.width() != 0) - { - ratio = rect.height() != 0 ? aznumeric_cast(rect.width() / float(rect.height())) : 1.0f; - } - - const bool bSelected = element.IsSelected(); - - if (element.type == STimelineElement::KEY) - { - float rx = keyRadius * 200.0f / ratio; - float ry = keyRadius * 200.0f; - - if (pass == PASS_SELECTION) - { - if (bSelected) - { - QRectF selectionRect = rect.adjusted(-SELECTION_WIDTH * 0.5f + 0.5f, -SELECTION_WIDTH * 0.5f + 0.5f, SELECTION_WIDTH * 0.5f - 0.5f, SELECTION_WIDTH * 0.5f - 0.5f); - painter.setPen(QPen(palette.color(hasFocus ? QPalette::Highlight : QPalette::Shadow), SELECTION_WIDTH)); - painter.setBrush(QBrush(Qt::NoBrush)); - painter.drawRoundedRect(selectionRect, rx, ry, Qt::RelativeSize); - } - } - else if (pass != PASS_SHADOW) - { - QRectF shadowRect = rect.adjusted(-1.0f, -0.5f, 1.0f, 1.5f); - painter.setPen(QPen(QColor(0, 0, 0, 128), 2.0f)); - painter.setBrush(QBrush(Qt::NoBrush)); - painter.drawRoundedRect(shadowRect, rx, ry, Qt::RelativeSize); - - painter.setPen(QPen(QColor(element.color.r, element.color.g, element.color.b, 255))); - painter.setBrush(QBrush(QColor(element.color.r, element.color.g, element.color.b, 255))); - painter.drawRoundedRect(rect, rx, ry, Qt::RelativeSize); - - QRect textRect = track.rect; - textRect.moveLeft(aznumeric_cast(rect.right() + TRACK_DESCRIPTION_INDENT)); - textRect.setTop(textRect.top() + 1); - - if ((iter + 1) != sortedElements.end()) - { - textRect.setRight((iter + 1)->rect.left() - 6); - } - - painter.setPen(descriptionTextPen); - const QString elidedText = painter.fontMetrics().elidedText(element.description.c_str(), Qt::ElideRight, textRect.width()); - painter.drawText(textRect, Qt::TextSingleLine, elidedText); - } - } - else - { - float radius = 0.2f; - float rx = radius * 200.0f / ratio; - float ry = radius * 200.0f; - - if (pass == PASS_SELECTION) - { - if (bSelected) - { - QRectF selectionRect = rect.adjusted(-SELECTION_WIDTH * 0.5f + 0.5f, -SELECTION_WIDTH * 0.5f + 0.5f, SELECTION_WIDTH * 0.5f - 0.5f, SELECTION_WIDTH * 0.5f - 0.5f); - painter.setPen(QPen(palette.color(hasFocus ? QPalette::Highlight : QPalette::Shadow), SELECTION_WIDTH)); - painter.setBrush(QBrush(Qt::NoBrush)); - painter.drawRoundedRect(selectionRect, rx, ry, Qt::RelativeSize); - } - } - else if (pass == PASS_SHADOW) - { - QRectF shadowRect = rect.adjusted(0.0f, 0.0f, 0.0f, 1.0f); - painter.setPen(QPen(QColor(0, 0, 0, 128), 2.0f)); - painter.setBrush(QBrush(Qt::NoBrush)); - painter.drawRoundedRect(shadowRect, radius * 200.0f / ratio, radius * 200.0f, Qt::RelativeSize); - } - else - { - painter.setPen(QPen(QColor(element.color.r, element.color.g, element.color.b, 255))); - painter.setBrush(QBrush(QColor(element.color.r, element.color.g, element.color.b, 128))); - painter.drawRoundedRect(rect, radius * 200.0f / ratio, radius * 200.0f, Qt::RelativeSize); - } - } - } - } - } - } - - void DrawSelectionLines(QPainter& painter, const QPalette& palette, const STimelineViewState& viewState, STimelineContent& content, [[maybe_unused]] int rulerPrecision, [[maybe_unused]] int width, int height, [[maybe_unused]] float time, [[maybe_unused]] float timeUnitScale, bool hasFocus) - { - const VectorSet times = GetSelectedElementsTimeSet(content.track); - - QColor indicatorColor = palette.color(hasFocus ? QPalette::Highlight : QPalette::Shadow); - indicatorColor.setAlpha(70); - - for (auto iter = times.begin(); iter != times.end(); ++iter) - { - const float indicatorX = viewState.TimeToLocal(iter->ToFloat()) + 0.5f; - painter.setPen(indicatorColor); - painter.drawLine(QPointF(indicatorX, 0), QPointF(indicatorX, height)); - } - } - - void DrawTree(QPainter& painter, const QRect& treeRect, const QPalette& palette, QWidget* timeline, [[maybe_unused]] const STimelineContent& content, const STrackLayouts& tracks, const STimelineViewState& viewState, int scroll) - { - painter.save(); - - painter.setClipRect(treeRect); - painter.setClipping(true); - - painter.translate(0, -scroll); - - QTextOption textOption; - textOption.setWrapMode(QTextOption::NoWrap); - - const QColor textColor = palette.buttonText().color(); - - QStyleOptionFrame opt; - opt.palette = palette; - opt.state = QStyle::State_Enabled; - opt.rect = QRect(treeRect.left(), treeRect.top() - 1, treeRect.width(), treeRect.height() + 2); - - // Draw frame around tree - timeline->style()->drawPrimitive(QStyle::PE_Frame, &opt, &painter, timeline); - - for (size_t i = 0; i < tracks.size(); ++i) - { - const STrackLayout& track = tracks[i]; - - const QRect backgroundRect(1, track.rect.top() + 1, viewState.treeWidth - SPLITTER_WIDTH - 1, track.rect.height() - 1); - - const bool bIsDescriptionTrack = (track.pTimelineTrack->caps & STimelineTrack::CAP_DESCRIPTION_TRACK) != 0; - const bool bIsCompositeTrack = (track.pTimelineTrack->caps & STimelineTrack::CAP_COMPOUND_TRACK) != 0; - - painter.setPen(Qt::NoPen); - painter.setBrush(PickTrackBrush(palette, track)); - painter.drawRect(backgroundRect); - - const int branchLeft = TREE_LEFT_MARGIN + track.indent * TREE_INDENT_MULTIPLIER; - - if (track.pTimelineTrack->tracks.size() > 0) - { - QStyleOptionViewItem opt2; - opt2.rect = QRect(branchLeft, track.rect.top() + 1, TREE_BRANCH_INDICATOR_SIZE, track.rect.height() - 2); - opt2.state = QStyle::State_Enabled | QStyle::State_Children; - opt2.state |= track.pTimelineTrack->expanded ? QStyle::State_Open : QStyle::State_None; - - timeline->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt2, &painter, timeline); - } - - const int textLeft = branchLeft + TREE_BRANCH_INDICATOR_SIZE + 4; - const int textWidth = std::max(treeRect.width() - textLeft - 4, 0); - const QRect textRect(textLeft, track.rect.top() + 1, textWidth, track.rect.height() - 2); - painter.setPen(QPen(textColor)); - painter.drawText(textRect, QString(track.pTimelineTrack->name), textOption); - } - - for (size_t i = 0; i < tracks.size(); ++i) - { - const STrackLayout& track = tracks[i]; - - const int lineY = track.rect.bottom() + 1; - painter.setPen(QPen(InterpolateColor(palette.color(QPalette::Mid), palette.color(QPalette::Window), 0.75f))); - painter.drawLine(QPoint(0, lineY), QPoint(treeRect.width(), lineY)); - } - - painter.restore(); - } - - void DrawSplitter(QPainter& painter, const QRect& splitterRect, const QPalette& palette, QWidget* timeline) - { - painter.fillRect(splitterRect, palette.color(QPalette::Window)); - - // Draw frame around splitter - QStyleOptionFrame frameOpt; - frameOpt.palette = palette; - frameOpt.state = QStyle::State_Enabled; - frameOpt.rect = QRect(splitterRect.left(), splitterRect.top(), splitterRect.width(), splitterRect.height() + 2); - timeline->style()->drawPrimitive(QStyle::PE_Frame, &frameOpt, &painter, timeline); - - // Draw resize handle dots - QStyleOption option; - option.palette = palette; - option.rect = QRect(splitterRect.left(), splitterRect.top() - 1, splitterRect.width() - 2, splitterRect.height() + 2); - timeline->style()->drawPrimitive(QStyle::PE_IndicatorDockWidgetResizeHandle, &option, &painter, timeline); - } -} - -struct CTimeline::SMouseHandler -{ - virtual ~SMouseHandler() = default; - virtual void mousePressEvent([[maybe_unused]] QMouseEvent* ev) {} - virtual void mouseDoubleClickEvent([[maybe_unused]] QMouseEvent* ev) {} - virtual void mouseMoveEvent([[maybe_unused]] QMouseEvent* ev) {} - virtual void mouseReleaseEvent([[maybe_unused]] QMouseEvent* ev) {} - virtual void focusOutEvent([[maybe_unused]] QFocusEvent* ev) {} - virtual void paintOver([[maybe_unused]] QPainter& painter) {} -}; - -struct CTimeline::SSelectionHandler - : SMouseHandler -{ - CTimeline* m_timeline; - QPoint m_startPoint; - QRect m_rect; - bool m_add; - TSelectedElements m_oldSelectedElements; - - SSelectionHandler(CTimeline* timeline, bool add) - : m_timeline(timeline) - , m_add(add) - { - if (m_timeline->m_pContent) - { - m_oldSelectedElements = GetSelectedElements(m_timeline->m_pContent->track); - } - } - - void mousePressEvent(QMouseEvent* ev) override - { - const int scroll = m_timeline->m_scrollBar ? m_timeline->m_scrollBar->value() : 0; - const QPoint pos(ev->pos().x(), ev->pos().y() + scroll); - m_startPoint = m_timeline->m_viewState.LocalToLayout(pos); - m_rect = QRect(m_startPoint, m_startPoint + QPoint(1, 1)); - } - - void mouseMoveEvent(QMouseEvent* ev) override - { - const int scroll = m_timeline->m_scrollBar ? m_timeline->m_scrollBar->value() : 0; - const QPoint pos(ev->pos().x(), ev->pos().y() + scroll); - m_rect = QRect(m_startPoint, m_timeline->m_viewState.LocalToLayout(pos) + QPoint(1, 1)); - Apply(true); - } - - void Apply(bool continuous) - { - if (m_timeline->m_pContent) - { - const TSelectedElements selectedElements = GetSelectedElements(m_timeline->m_pContent->track); - - ClearElementSelection(m_timeline->m_pContent->track); - SelectElementsInRect(m_timeline->m_layout->tracks, m_rect); - - const TSelectedElements newSelectedElements = GetSelectedElements(m_timeline->m_pContent->track); - if ((continuous && selectedElements != newSelectedElements) - || (!continuous && m_oldSelectedElements != newSelectedElements)) - { - m_timeline->SignalSelectionChanged(continuous); - } - } - } - - void mouseReleaseEvent([[maybe_unused]] QMouseEvent* ev) override - { - Apply(false); - } - - void paintOver(QPainter& painter) override - { - painter.save(); - QColor highlightColor = m_timeline->palette().color(QPalette::Highlight); - QColor highlightColorA = QColor(highlightColor.red(), highlightColor.green(), highlightColor.blue(), 128); - painter.setPen(QPen(highlightColor)); - painter.setBrush(QBrush(highlightColorA)); - painter.drawRect(QRectF(m_rect)); - painter.restore(); - } -}; - -static STimelineElement* NextSelectedElement(const SElementLayoutPtrs& array, STimelineElement* nextToValue, STimelineElement* defaultValue) -{ - for (size_t i = 0; i < array.size(); ++i) - { - if (&array[i]->elementRef.GetElement() == nextToValue) - { - return &array[(i + 1) % array.size()]->elementRef.GetElement(); - } - } - return defaultValue; -} - -struct CTimeline::SMoveHandler - : SMouseHandler -{ - CTimeline* m_timeline; - QPoint m_startPoint; - bool m_cycleSelection; - SAnimTime m_startTime; - SAnimTime m_newTime; - std::vector m_elementTimes; - - SMoveHandler(CTimeline* timeline, bool cycleSelection) - : m_timeline(timeline) - , m_cycleSelection(cycleSelection) {} - - void mousePressEvent(QMouseEvent* ev) override - { - m_startTime = m_timeline->m_time; - m_newTime = m_startTime; - - const int scroll = m_timeline->m_scrollBar ? m_timeline->m_scrollBar->value() : 0; - const QPoint currentPos(ev->pos().x(), ev->pos().y() + scroll); - - m_startPoint = m_timeline->m_viewState.LocalToLayout(QPoint(currentPos)); - m_elementTimes = GetSelectedElementTimes(m_timeline->m_pContent->track); - } - - void mouseMoveEvent(QMouseEvent* ev) override - { - if (m_timeline->m_viewState.widthPixels == 0) - { - return; - } - - const int scroll = m_timeline->m_scrollBar ? m_timeline->m_scrollBar->value() : 0; - const QPoint currentPos(ev->pos().x(), ev->pos().y() + scroll); - - int delta = m_timeline->m_viewState.LocalToLayout(currentPos).x() - m_startPoint.x(); - - const TSelectedElements selectedElements = GetSelectedElements(m_timeline->m_pContent->track); - - SetSelectedElementTimes(m_timeline->m_pContent->track, m_elementTimes); - - SAnimTime minDeltaTime = SAnimTime::Min(); - SAnimTime maxDeltaTime = SAnimTime::Max(); - SAnimTime minKeyTime = SAnimTime::Min(); - - for (size_t i = 0; i < selectedElements.size(); ++i) - { - const STimelineTrack& track = *selectedElements[i].first; - const STimelineElement& element = *selectedElements[i].second; - - SAnimTime minStartDelta = track.startTime - element.start; - minDeltaTime = max(minStartDelta, minDeltaTime); - SAnimTime maxEndDelta = track.endTime - (element.type == element.CLIP ? element.end : element.start); - maxDeltaTime = min(maxEndDelta, maxDeltaTime); - - minKeyTime = min(element.start, minKeyTime); - } - - SAnimTime deltaTime = SAnimTime(float(delta) / m_timeline->m_viewState.widthPixels * m_timeline->m_viewState.visibleDistance); - if (m_timeline->m_snapKeys) - { - SAnimTime newMinKeyTime = minKeyTime + deltaTime; - newMinKeyTime = newMinKeyTime.SnapToNearest(m_timeline->m_frameRate); - deltaTime = newMinKeyTime - minKeyTime; - } - - deltaTime = clamp_tpl(deltaTime, minDeltaTime, maxDeltaTime); - - m_newTime = m_startTime + deltaTime; - - MoveSelectedElements(m_timeline->m_pContent->track, deltaTime); - - m_timeline->ContentChanged(true); - - m_timeline->setCursor(Qt::SizeHorCursor); - m_cycleSelection = false; - } - - void focusOutEvent([[maybe_unused]] QFocusEvent* ev) - { - SetSelectedElementTimes(m_timeline->m_pContent->track, m_elementTimes); - m_timeline->UpdateLayout(); - } - - void mouseReleaseEvent(QMouseEvent* ev) - { - if (m_cycleSelection) - { - SElementLayoutPtrs hitElements; - - const int scroll = m_timeline->m_scrollBar ? m_timeline->m_scrollBar->value() : 0; - const QPoint currentPos(ev->pos().x(), ev->pos().y() + scroll); - - QPoint posInLayoutSpace = m_timeline->m_viewState.LocalToLayout(currentPos); - HitTestElements(m_timeline->m_layout->tracks, QRect(posInLayoutSpace - QPoint(2, 2), posInLayoutSpace + QPoint(2, 2)), hitElements); - - if (!hitElements.empty()) - { - TSelectedElements selectedElements = GetSelectedElements(m_timeline->m_pContent->track); - if (selectedElements.size() == 1) - { - STimelineElement* lastSelection = selectedElements[0].second; - - ClearElementSelection(m_timeline->m_pContent->track); - NextSelectedElement(hitElements, lastSelection, &hitElements.back()->elementRef.GetElement())->selected = true; - m_timeline->SignalSelectionChanged(false); - } - else - { - ClearElementSelection(m_timeline->m_pContent->track); - hitElements.back()->elementRef.GetElement().selected = true; - m_timeline->SignalSelectionChanged(false); - } - } - } - - m_timeline->ContentChanged(false); - } -}; - -struct CTimeline::SPanHandler - : SMouseHandler -{ - CTimeline* m_timeline; - QPoint m_startPoint; - float m_startOrigin; - - SPanHandler(CTimeline* timeline) - : m_timeline(timeline) - { - } - - void mousePressEvent(QMouseEvent* ev) override - { - m_startPoint = QPoint(int(ev->x()), int(ev->y())); - m_startOrigin = m_timeline->m_viewState.viewOrigin; - } - - void mouseMoveEvent(QMouseEvent* ev) override - { - QPoint pos(int(ev->x()), int(ev->y())); - float delta = 0.0f; - - if (m_timeline->m_viewState.widthPixels != 0) - { - delta = (pos - m_startPoint).x() * m_timeline->m_viewState.visibleDistance / m_timeline->m_viewState.widthPixels; - } - - m_timeline->m_viewState.viewOrigin = m_startOrigin + delta; - ClampViewOrigin(&m_timeline->m_viewState, *m_timeline->m_layout); - } - - void mouseReleaseEvent([[maybe_unused]] QMouseEvent* ev) override - { - } -}; - -struct CTimeline::SScrubHandler - : SMouseHandler -{ - CTimeline* m_timeline; - SScrubHandler(CTimeline* timeline) - : m_timeline(timeline) {} - SAnimTime m_startThumbPosition; - QPoint m_startPoint; - - void SetThumbPositionX(int positionX) - { - SAnimTime time = SAnimTime(m_timeline->m_viewState.LayoutToTime(positionX)); - - m_timeline->ClampAndSetTime(time, false); - } - - void mousePressEvent(QMouseEvent* ev) override - { - QPoint point = QPoint(ev->pos().x(), ev->pos().y()); - - QPoint posInLayout = m_timeline->m_viewState.LocalToLayout(point); - - int thumbPositionX = m_timeline->m_viewState.TimeToLayout(m_timeline->m_time.ToFloat()); - QRect thumbRect(thumbPositionX - THUMB_WIDTH / 2, 0, THUMB_WIDTH, THUMB_HEIGHT); - - if (!thumbRect.contains(posInLayout)) - { - SetThumbPositionX(m_timeline->m_viewState.LocalToLayout(point).x()); - } - - m_startThumbPosition = m_timeline->m_time; - m_startPoint = point; - } - - void Apply(QMouseEvent* ev, [[maybe_unused]] bool continuous) - { - QPoint point = QPoint(ev->pos().x(), ev->pos().y()); - - bool shift = ev->modifiers().testFlag(Qt::ShiftModifier); - bool control = ev->modifiers().testFlag(Qt::ControlModifier); - - float delta = 0.0f; - - if (m_timeline->m_viewState.widthPixels != 0) - { - delta = (point.x() - m_startPoint.x()) * m_timeline->m_viewState.visibleDistance / m_timeline->m_viewState.widthPixels; - } - - if (shift) - { - delta *= 0.01f; - } - - if (control) - { - delta *= 0.1f; - } - - m_timeline->ClampAndSetTime(m_startThumbPosition + SAnimTime(delta), true); - } - - void mouseMoveEvent(QMouseEvent* ev) override - { - Apply(ev, true); - } - - void mouseReleaseEvent(QMouseEvent* ev) override - { - Apply(ev, false); - } -}; - -struct CTimeline::SSplitterHandler - : SMouseHandler -{ - CTimeline* m_timeline; - int m_offset; - bool m_movedSlider; - - SSplitterHandler(CTimeline* timeline) - : m_timeline(timeline) - , m_offset(0) - , m_movedSlider(false) {} - - void mousePressEvent(QMouseEvent* ev) override - { - m_offset = m_timeline->m_viewState.treeWidth - ev->pos().x(); - } - - void mouseReleaseEvent([[maybe_unused]] QMouseEvent* ev) override - { - if (!m_movedSlider) - { - STimelineViewState& viewState = m_timeline->m_viewState; - - if (viewState.treeWidth == SPLITTER_WIDTH) - { - viewState.treeWidth = viewState.treeLastOpenedWidth; - } - else - { - viewState.treeLastOpenedWidth = viewState.treeWidth; - viewState.treeWidth = SPLITTER_WIDTH; - } - - m_timeline->UpdateLayout(); - m_timeline->update(); - } - } - - void mouseMoveEvent(QMouseEvent* ev) override - { - m_timeline->setCursor(QCursor(Qt::SplitHCursor)); - uint treeWidth = clamp_tpl(ev->pos().x(), SPLITTER_WIDTH, m_timeline->width()) + m_offset; - m_timeline->m_viewState.treeWidth = treeWidth; - m_timeline->m_viewState.treeLastOpenedWidth = treeWidth; - m_timeline->UpdateLayout(); - m_timeline->update(); - m_movedSlider = true; - } -}; - -struct CTimeline::STreeMouseHandler - : SMouseHandler -{ - CTimeline* m_timeline; - STreeMouseHandler(CTimeline* timeline) - : m_timeline(timeline) {} - - void mousePressEvent(QMouseEvent* ev) override - { - const bool bCtrlPressed = (ev->modifiers() & Qt::CTRL) != 0; - const bool bShiftPressed = (ev->modifiers() & Qt::SHIFT) != 0; - - const int scroll = m_timeline->m_scrollBar ? m_timeline->m_scrollBar->value() : 0; - const QPoint pos(ev->pos().x(), ev->pos().y() + scroll); - - STrackLayout* pTrackLayout = m_timeline->GetTrackLayoutFromPos(pos); - - if (!pTrackLayout) - { - if (!bShiftPressed && !bCtrlPressed) - { - ClearTrackSelection(m_timeline->m_pContent->track); - } - } - else - { - const int left = TREE_LEFT_MARGIN + pTrackLayout->indent * TREE_INDENT_MULTIPLIER; - const int right = left + TREE_BRANCH_INDICATOR_SIZE; - - const int x = pos.x(); - - if (x >= left && x <= right) - { - ToggleTrackExpansion(pTrackLayout); - } - else - { - const bool bPreviousState = pTrackLayout->pTimelineTrack->selected; - - if (!bCtrlPressed) - { - ClearTrackSelection(m_timeline->m_pContent->track); - } - - if (bCtrlPressed) - { - pTrackLayout->pTimelineTrack->selected = !bPreviousState; - } - else if (bShiftPressed) - { - STrackLayouts& tracks = m_timeline->m_layout->tracks; - - auto startFindIter = std::find_if(tracks.begin(), tracks.end(), [=](const STrackLayout& track) { return (pTrackLayout == &track); }); - auto endFindIter = std::find_if(tracks.begin(), tracks.end(), [=](const STrackLayout& track) { return (m_timeline->m_pLastSelectedTrack == &track); }); - - if (startFindIter != tracks.end() && endFindIter != tracks.end()) - { - if (startFindIter > endFindIter) - { - std::swap(startFindIter, endFindIter); - } - - for (auto iter = startFindIter; iter <= endFindIter; ++iter) - { - iter->pTimelineTrack->selected = true; - } - } - } - else - { - pTrackLayout->pTimelineTrack->selected = true; - } - - if (!bShiftPressed && pTrackLayout->pTimelineTrack->selected) - { - m_timeline->m_pLastSelectedTrack = pTrackLayout; - } - - m_timeline->SignalTrackSelectionChanged(); - } - } - } - - void mouseDoubleClickEvent(QMouseEvent* ev) override - { - if (ev->modifiers() == 0) - { - STrackLayout* pTrackLayout = m_timeline->GetTrackLayoutFromPos(ev->pos()); - ToggleTrackExpansion(pTrackLayout); - } - } - -private: - void ToggleTrackExpansion(STrackLayout* pTrackLayout) - { - if (pTrackLayout && pTrackLayout->pTimelineTrack) - { - pTrackLayout->pTimelineTrack->expanded = !pTrackLayout->pTimelineTrack->expanded; - m_timeline->UpdateLayout(); - m_timeline->update(); - } - } -}; - -// --------------------------------------------------------------------------- - -CTimeline::CTimeline(QWidget* parent) - : QWidget(parent) - , m_cycled(true) - , m_sizeToContent(false) - , m_snapTime(false) - , m_snapKeys(false) - , m_treeVisible(false) - , m_selIndicators(false) - , m_verticalScrollbarVisible(false) - , m_drawMarkers(false) - , m_layout(new STimelineLayout) - , m_keyWidth(DEFAULT_KEY_WIDTH) - , m_keyRadius(DEFAULT_KEY_RADIUS) - , m_cornerWidget(nullptr) - , m_scrollBar(nullptr) - , m_cornerWidgetWidth(0) - , m_pContent(nullptr) - , m_timeUnitScale(1.0f) - , m_timeStepNum(1) - , m_timeStepIndex(0) - , m_frameRate(SAnimTime::eFrameRate_30fps) - , m_time(0.0f) - , m_pFilterLineEdit(nullptr) - , m_pLastSelectedTrack(nullptr) -{ - setMinimumWidth(THUMB_WIDTH * 3); - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum); - setFocusPolicy(Qt::WheelFocus); - setMouseTracking(true); - - m_viewState.visibleDistance = 1.0f; -} - -CTimeline::~CTimeline() -{ -} - -void CTimeline::paintEvent([[maybe_unused]] QPaintEvent* ev) -{ - const QPoint mousePos = mapFromGlobal(QCursor::pos()); - - QPainter painter(this); - painter.save(); - painter.translate(0.5f, 0.5f); - - if (m_viewState.visibleDistance != 0) - { - SAnimTime totalDuration = m_layout->maxEndTime - m_layout->minStartTime; - m_viewState.scrollPixels = QPoint(m_viewState.ScrollOffset(m_viewState.viewOrigin), 0); - m_viewState.maxScrollX = int(m_viewState.widthPixels * totalDuration.ToFloat() / m_viewState.visibleDistance) - m_viewState.widthPixels; - } - else - { - m_viewState.scrollPixels = QPoint(0, 0); - m_viewState.maxScrollX = 0; - } - - const int scroll = m_scrollBar ? m_scrollBar->value() : 0; - const QPoint localToLayoutTranslate = m_viewState.LayoutToLocal(QPoint(0, -scroll)); - - int rulerPrecision = 0; - - painter.translate(localToLayoutTranslate); - painter.setRenderHint(QPainter::Antialiasing); - - DrawTracks(painter, PASS_BACKGROUND, PASS_BACKGROUND, *m_layout, m_viewState, - palette(), mousePos, hasFocus(), width(), m_keyRadius, m_timeUnitScale, m_drawMarkers); - - DrawTracks(painter, PASS_SELECTION, PASS_MAIN, *m_layout, m_viewState, - palette(), mousePos, hasFocus(), width(), m_keyRadius, m_timeUnitScale, m_drawMarkers); - - painter.translate(-localToLayoutTranslate); - - DrawingPrimitives::SRulerOptions rulerOptions; - rulerOptions.m_rect = QRect(m_viewState.treeWidth, -1, size().width() - m_viewState.treeWidth, RULER_HEIGHT + 2); - rulerOptions.m_visibleRange = Range(m_viewState.LocalToTime(m_viewState.treeWidth) * m_timeUnitScale, m_viewState.LocalToTime(size().width()) * m_timeUnitScale); - rulerOptions.m_rulerRange = Range(m_layout->minStartTime.ToFloat() * m_timeUnitScale, m_layout->maxEndTime.ToFloat() * m_timeUnitScale); - rulerOptions.m_markHeight = RULER_MARK_HEIGHT; - rulerOptions.m_shadowSize = RULER_SHADOW_HEIGHT; - DrawingPrimitives::DrawRuler(painter, palette(), rulerOptions, &rulerPrecision); - - if (m_pContent && isEnabled()) - { - DrawingPrimitives::STimeSliderOptions timeSliderOptions; - timeSliderOptions.m_rect = rect(); - timeSliderOptions.m_precision = rulerPrecision; - timeSliderOptions.m_position = m_viewState.TimeToLocal(m_time.ToFloat()); - timeSliderOptions.m_time = m_time.ToFloat() * m_timeUnitScale; - timeSliderOptions.m_bHasFocus = hasFocus(); - DrawingPrimitives::DrawTimeSlider(painter, palette(), timeSliderOptions); - - DrawSelectionLines(painter, palette(), m_viewState, *m_pContent, rulerPrecision, width(), height(), m_time.ToFloat(), m_timeUnitScale, hasFocus()); - } - - painter.translate(localToLayoutTranslate); - - if (m_mouseHandler) - { - m_mouseHandler->paintOver(painter); - } - - painter.translate(-localToLayoutTranslate); - - if (m_viewState.scrollPixels.x() < 0) - { - QRect rect(m_viewState.treeWidth, 0, SCROLL_SHADOW_WIDTH, height()); - QLinearGradient grad(rect.left(), rect.top(), rect.right(), rect.top()); - grad.setColorAt(0.0f, QColor(0, 0, 0, 96)); - grad.setColorAt(1.0f, QColor(0, 0, 0, 0)); - painter.fillRect(rect, QBrush(grad)); - } - - SAnimTime totalDuration = m_layout->maxEndTime - m_layout->minStartTime; - - if (m_viewState.scrollPixels.x() > -m_viewState.maxScrollX) - { - QRect rect(width() - SCROLL_SHADOW_WIDTH, 0, SCROLL_SHADOW_WIDTH, height()); - QLinearGradient grad(rect.left(), rect.top(), rect.right(), rect.top()); - grad.setColorAt(0.0f, QColor(0, 0, 0, 0)); - grad.setColorAt(1.0f, QColor(0, 0, 0, 96)); - painter.fillRect(rect, QBrush(grad)); - } - - { - QColor color = palette().color(QPalette::Dark); - color.setAlpha(128); - painter.setPen(QPen(color)); - painter.drawLine(QPoint(0, 0), QPoint(0, height())); - painter.drawLine(QPoint(width() - 1, 0), QPoint(width() - 1, height())); - painter.drawLine(QPoint(1, 0), QPoint(width() - 1, 0)); - painter.drawLine(QPoint(0, height()), QPoint(width() - 1, height())); - } - - painter.restore(); - - if (m_treeVisible) - { - if (m_pContent) - { - QRect treeRect(0, 0, m_viewState.treeWidth - SPLITTER_WIDTH + 1, height()); - DrawTree(painter, treeRect, palette(), this, *m_pContent, m_layout->tracks, m_viewState, scroll); - } - - QRect splitterRect(m_viewState.treeWidth - SPLITTER_WIDTH, 0, SPLITTER_WIDTH, height()); - DrawSplitter(painter, splitterRect, palette(), this); - } - - if (!isEnabled()) - { - QColor disabledOverlayColor = palette().color(QPalette::Disabled, QPalette::Button); - disabledOverlayColor.setAlpha(128); - painter.fillRect(0, 0, width(), height(), QBrush(disabledOverlayColor)); - } -} - -void CTimeline::keyPressEvent(QKeyEvent* ev) -{ - const QPoint mousePos = mapFromGlobal(QCursor::pos()); - QMouseEvent mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton, Qt::NoButton, ev->modifiers()); - mouseMoveEvent(&mouseEvent); - int rawKey = ev->key() | ev->modifiers(); - QKeySequence key(rawKey); - - if (key == QKeySequence(Qt::Key_Z | Qt::CTRL)) - { - SignalUndo(); - } - else if (key == QKeySequence(Qt::Key_Y | Qt::CTRL) || (key == QKeySequence(Qt::Key_Z | Qt::CTRL | Qt::SHIFT))) - { - SignalRedo(); - } - else - { - HandleKeyEvent(rawKey); - } -} - -void CTimeline::keyReleaseEvent(QKeyEvent* ev) -{ - const QPoint mousePos = mapFromGlobal(QCursor::pos()); - QMouseEvent mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton, Qt::NoButton, ev->modifiers()); - mouseMoveEvent(&mouseEvent); -} - -bool CTimeline::HandleKeyEvent(int k) -{ - QKeySequence key(k); - - if (key == QKeySequence(Qt::Key_Delete)) - { - OnMenuDelete(); - return true; - } - - if (key == QKeySequence(Qt::Key_D)) - { - OnMenuDuplicate(); - return true; - } - - if (key == QKeySequence(Qt::Key_Home)) - { - m_time = SAnimTime(0); - update(); - SignalScrub(false); - return true; - } - if (key == QKeySequence(Qt::Key_End)) - { - SAnimTime endTime = SAnimTime(0); - for (size_t i = 0; i < m_pContent->track.tracks.size(); ++i) - { - endTime = std::max(endTime, m_pContent->track.tracks[i]->endTime); - } - m_time = endTime; - update(); - SignalScrub(false); - return true; - } - if (key == QKeySequence(Qt::Key_X) || key == QKeySequence(Qt::Key_PageUp)) - { - OnMenuPreviousKey(); - return true; - } - if (key == QKeySequence(Qt::Key_C) || key == QKeySequence(Qt::Key_PageDown)) - { - OnMenuNextKey(); - return true; - } - - if (k == Qt::Key_Comma || k == Qt::Key_Left) - { - OnMenuPreviousFrame(); - return true; - } - - if (k == Qt::Key_Period || k == Qt::Key_Right) - { - OnMenuNextFrame(); - return true; - } - - if (key == QKeySequence(Qt::Key_Space)) - { - OnMenuPlay(); - return true; - } - - // shortcut is Ctrl+# - int maskedKey = ((~Qt::KeyboardModifierMask) & k); - if (((k & Qt::CTRL) != 0) && (maskedKey >= Qt::Key_0 && maskedKey <= Qt::Key_9)) - { - int number = maskedKey - int(Qt::Key_0); - SignalNumberHotkey(number); - return true; - } - - return false; -} - -bool CTimeline::ProcessesKey(const QKeySequence& key) -{ - static QSet customShortcuts = { - QKeySequence(Qt::Key_Delete), - QKeySequence(Qt::Key_D), - QKeySequence(Qt::Key_Home), - QKeySequence(Qt::Key_End), - QKeySequence(Qt::Key_PageUp), - QKeySequence(Qt::Key_X), - QKeySequence(Qt::Key_PageDown), - QKeySequence(Qt::Key_C), - QKeySequence(Qt::Key_Comma), - QKeySequence(Qt::Key_Left), - QKeySequence(Qt::Key_Period), - QKeySequence(Qt::Key_Right), - QKeySequence(Qt::Key_Space), - QKeySequence(Qt::CTRL | Qt::Key_0), - QKeySequence(Qt::CTRL | Qt::Key_1), - QKeySequence(Qt::CTRL | Qt::Key_2), - QKeySequence(Qt::CTRL | Qt::Key_3), - QKeySequence(Qt::CTRL | Qt::Key_4), - QKeySequence(Qt::CTRL | Qt::Key_5), - QKeySequence(Qt::CTRL | Qt::Key_6), - QKeySequence(Qt::CTRL | Qt::Key_7), - QKeySequence(Qt::CTRL | Qt::Key_8), - QKeySequence(Qt::CTRL | Qt::Key_9) - }; - - return customShortcuts.contains(key); -} - -void CTimeline::mousePressEvent(QMouseEvent* ev) -{ - setFocus(); - - const bool bInTreeArea = m_treeVisible && (ev->x() <= m_viewState.treeWidth); - - if (ev->button() == Qt::LeftButton) - { - QPoint posInLayout = m_viewState.LocalToLayout(ev->pos()); - - if (bInTreeArea) - { - const bool bOverSplitter = ev->x() >= (m_viewState.treeWidth - SPLITTER_WIDTH); - - if (bOverSplitter) - { - m_mouseHandler.reset(new SSplitterHandler(this)); - m_mouseHandler->mousePressEvent(ev); - update(); - } - else - { - m_mouseHandler.reset(new STreeMouseHandler(this)); - m_mouseHandler->mousePressEvent(ev); - update(); - } - } - else if (ev->y() < RULER_HEIGHT) - { - m_mouseHandler.reset(new SScrubHandler(this)); - m_mouseHandler->mousePressEvent(ev); - update(); - } - else - { - QPoint posInLayoutSpace = m_viewState.LocalToLayout(ev->pos()); - - SElementLayoutPtrs hitElements; - bool bHit = HitTestElements(m_layout->tracks, QRect(posInLayoutSpace - QPoint(2, 2), posInLayoutSpace + QPoint(2, 2)), hitElements); - - if (ev->modifiers() & Qt::SHIFT || ev->modifiers() & Qt::CTRL) - { - if (bHit) - { - hitElements.back()->SetSelected(hitElements.back()->IsSelected()); - mouseMoveEvent(ev); - update(); - } - else - { - m_mouseHandler.reset(new SSelectionHandler(this, true)); - m_mouseHandler->mousePressEvent(ev); - } - } - else - { - if (bHit) - { - bool useExistingSelection = std::any_of(hitElements.begin(), hitElements.end(), [](const SElementLayout* element) { return element->IsSelected(); }); - - if (!useExistingSelection) - { - const TSelectedElements selectedElements = GetSelectedElements(m_pContent->track); - - ClearElementSelection(m_pContent->track); - hitElements.back()->SetSelected(true); - - if (selectedElements != GetSelectedElements(m_pContent->track)) - { - SignalSelectionChanged(false); - } - } - - bool cycleSelection = useExistingSelection; - m_mouseHandler.reset(new SMoveHandler(this, cycleSelection)); - m_mouseHandler->mousePressEvent(ev); - update(); - } - else - { - m_mouseHandler.reset(new SSelectionHandler(this, false)); - m_mouseHandler->mousePressEvent(ev); - update(); - } - } - } - } - else if (ev->button() == Qt::MiddleButton) - { - if (!bInTreeArea) - { - m_mouseHandler.reset(new SPanHandler(this)); - m_mouseHandler->mousePressEvent(ev); - update(); - } - } - else if (ev->button() == Qt::RightButton) - { - if (bInTreeArea) - { - std::vector selectedTracks; - GetSelectedTracks(m_pContent->track, selectedTracks); - - STrackLayout* pLayout = GetTrackLayoutFromPos(ev->pos()); - if (pLayout) - { - if (!stl::find(selectedTracks, pLayout->pTimelineTrack)) - { - ClearTrackSelection(m_pContent->track); - pLayout->pTimelineTrack->selected = true; - } - - SignalTreeContextMenu(mapToGlobal(ev->pos())); - } - } - else - { - QMenu menu; - bool hasSelection = false; - ForEachElement(m_pContent->track, [&]([[maybe_unused]] STimelineTrack& t, STimelineElement& e) - { - if (e.selected) - { - hasSelection = true; - } - }); - - menu.addAction("Selection to Cursor", this, SLOT(OnMenuSelectionToCursor()))->setEnabled(hasSelection); - QAction* duplicateAction = menu.addAction("Duplicate", this, SLOT(OnMenuDuplicate()), QKeySequence("D")); - duplicateAction->setEnabled(hasSelection); - menu.addSeparator(); - menu.addAction("Delete Event(s)", this, SLOT(OnMenuDelete()), QKeySequence("Delete"))->setEnabled(hasSelection); - menu.addSeparator(); - menu.addAction("Play / Pause", this, SLOT(OnMenuPlay()), QKeySequence("Space")); - menu.addAction("Previous Frame", this, SLOT(OnMenuPreviousFrame()), QKeySequence(",")); - menu.addAction("Next Frame", this, SLOT(OnMenuNextFrame()), QKeySequence(".")); - menu.addAction("Jump to Previous Event", this, SLOT(OnMenuPreviousKey()), QKeySequence("X")); - menu.addAction("Jump to Next Event", this, SLOT(OnMenuNextKey()), QKeySequence("C")); - menu.exec(QCursor::pos(), duplicateAction); - } - } -} - -void CTimeline::AddKeyToTrack(STimelineTrack& track, SAnimTime time) -{ - if (m_snapKeys) - { - time = time.SnapToNearest(m_frameRate); - } - - track.modified = true; - track.elements.push_back(track.defaultElement); - track.elements.back().added = true; - SAnimTime length = track.defaultElement.end - track.defaultElement.start; - track.elements.back().start = time; - track.elements.back().end = length; - track.elements.back().selected = true; -} - -void CTimeline::mouseDoubleClickEvent(QMouseEvent* ev) -{ - if (ev->button() == Qt::LeftButton) - { - QPoint posInLayout = m_viewState.LocalToLayout(ev->pos()); - - const bool bInTreeArea = m_treeVisible && (ev->x() <= m_viewState.treeWidth); - - if (bInTreeArea) - { - const bool bOverSplitter = ev->x() >= (m_viewState.treeWidth - SPLITTER_WIDTH); - - if (!bOverSplitter) - { - m_mouseHandler.reset(new STreeMouseHandler(this)); - m_mouseHandler->mouseDoubleClickEvent(ev); - update(); - } - } - - QPoint layoutPoint = m_viewState.LocalToLayout(ev->pos()); - STrackLayout* track = HitTestTrack(m_layout->tracks, layoutPoint); - - if (track) - { - SElementLayoutPtrs hitElements; - const bool bHit = HitTestElements(m_layout->tracks, QRect(layoutPoint - QPoint(2, 2), layoutPoint + QPoint(2, 2)), hitElements); - - if (!bHit) - { - float time = m_viewState.LayoutToTime(layoutPoint.x()); - STimelineTrack& timelineTrack = *track->pTimelineTrack; - - if ((timelineTrack.caps & STimelineTrack::CAP_COMPOUND_TRACK) == 0) - { - AddKeyToTrack(timelineTrack, SAnimTime(time)); - } - else - { - const size_t numSubTracks = timelineTrack.tracks.size(); - for (size_t i = 0; i < numSubTracks; ++i) - { - STimelineTrack& subTrack = *timelineTrack.tracks[i]; - AddKeyToTrack(subTrack, SAnimTime(time)); - } - } - - ContentChanged(false); - m_mouseHandler.reset(); - mouseMoveEvent(ev); - } - } - } -} - -void CTimeline::UpdateCursor(QMouseEvent* ev) -{ - const int scroll = m_scrollBar ? m_scrollBar->value() : 0; - const QPoint pos(ev->pos().x(), ev->pos().y() + scroll); - - QPoint posInLayoutSpace = m_viewState.LocalToLayout(pos); - - SElementLayoutPtrs hitElements; - HitTestElements(m_layout->tracks, QRect(posInLayoutSpace - QPoint(2, 2), posInLayoutSpace + QPoint(2, 2)), hitElements); - const bool bOverSelected = !hitElements.empty() && hitElements.back()->IsSelected(); - const bool bInTreeArea = m_treeVisible && (ev->x() <= m_viewState.treeWidth); - - bool shift = ev->modifiers().testFlag(Qt::ShiftModifier); - bool control = ev->modifiers().testFlag(Qt::ControlModifier); - - if (m_mouseHandler) - { - m_mouseHandler->mouseMoveEvent(ev); - update(); - } - else if (m_treeVisible && (ev->x() <= m_viewState.treeWidth) && (ev->x() >= (m_viewState.treeWidth - SPLITTER_WIDTH))) - { - setCursor(QCursor(Qt::SplitHCursor)); - } - else if (!bInTreeArea && bOverSelected && !(shift || control)) - { - setCursor(QCursor(Qt::SizeHorCursor)); - } - else - { - setCursor(QCursor()); - } -} - -void CTimeline::mouseMoveEvent(QMouseEvent* ev) -{ - UpdateCursor(ev); -} - -void CTimeline::mouseReleaseEvent(QMouseEvent* ev) -{ - if (ev->button() == Qt::LeftButton || ev->button() == Qt::MiddleButton) - { - if (m_mouseHandler.get()) - { - m_mouseHandler->mouseReleaseEvent(ev); - m_mouseHandler.reset(); - update(); - } - } - UpdateCursor(ev); -} - -void CTimeline::focusOutEvent(QFocusEvent* ev) -{ - if (m_mouseHandler.get()) - { - m_mouseHandler->focusOutEvent(ev); - m_mouseHandler.reset(); - } - - update(); -} - -void CTimeline::wheelEvent(QWheelEvent* ev) -{ - int pixelDelta = ev->pixelDelta().manhattanLength(); - - if (pixelDelta == 0) - { - pixelDelta = ev->angleDelta().y(); - } - - const float fractionOfView = std::min(m_viewState.widthPixels != 0 ? float(pixelDelta) / m_viewState.widthPixels : 0.0f, 0.5f); - - SetVisibleDistance(m_viewState.visibleDistance - m_viewState.visibleDistance * fractionOfView); -} - -QSize CTimeline::sizeHint() const -{ - return QSize(m_layout->size); -} - -void CTimeline::resizeEvent([[maybe_unused]] QResizeEvent* ev) -{ - UpdateLayout(); -} - -SAnimTime CTimeline::ClampAndSnapTime(SAnimTime time, bool snapToFrames) const -{ - SAnimTime minTime = m_layout->minStartTime; - SAnimTime maxTime = m_layout->maxEndTime; - SAnimTime unclampedTime = time; - SAnimTime deltaTime = maxTime - minTime; - - if (m_cycled) - { - while (unclampedTime < minTime) - { - unclampedTime += deltaTime; - } - - unclampedTime = ((unclampedTime - minTime) % deltaTime) + minTime; - } - - SAnimTime clampedTime = clamp_tpl(unclampedTime, minTime, maxTime); - - if (!snapToFrames) - { - return clampedTime; - } - else - { - int timeStepIndex = static_cast(floor(clampedTime.ToFloat() * static_cast(m_timeStepNum) + 0.05f)); - float normalizedTime = static_cast(timeStepIndex) / static_cast(m_timeStepNum); - return SAnimTime(normalizedTime); - } -} - -void CTimeline::ClampAndSetTime(SAnimTime time, bool scrubThrough) -{ - SAnimTime newTime = ClampAndSnapTime(time, m_snapTime); - - if (newTime != m_time) - { - m_time = newTime; - UpdateLayout(); - update(); - SignalScrub(scrubThrough); - } -} - -void CTimeline::SetTimeUnitScale(float scale, float step) -{ - m_timeUnitScale = scale; - m_timeStepNum = static_cast(scale / step); - update(); -} - -void CTimeline::SetTime(SAnimTime time) -{ - m_time = time; - update(); -} - -void CTimeline::SetCycled(bool cycled) -{ - m_cycled = cycled; -} - -void CTimeline::SetContent(STimelineContent* pContent) -{ - m_pContent = pContent; - - UpdateLayout(); - update(); -} - -void CTimeline::UpdateLayout() -{ - m_layout->tracks.clear(); - - m_viewState.widthPixels = width(); - - if (m_treeVisible) - { - m_viewState.widthPixels -= m_viewState.treeWidth; - m_viewState.widthPixels = std::max(m_viewState.widthPixels, 0); - } - - if (m_verticalScrollbarVisible) - { - if (!m_scrollBar) - { - m_scrollBar = new QScrollBar(Qt::Vertical, this); - connect(m_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(OnVerticalScroll(int))); - } - - const uint scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, this); - m_scrollBar->setGeometry(width() - scrollbarWidth, 0, scrollbarWidth, height()); - - m_viewState.widthPixels -= scrollbarWidth; - m_viewState.widthPixels = std::max(m_viewState.widthPixels, 0); - } - else if (!m_verticalScrollbarVisible && m_scrollBar) - { - SAFE_DELETE(m_scrollBar); - } - - ClampViewOrigin(&m_viewState, *m_layout); - - if (m_pContent) - { - CalculateLayout(m_layout.get(), *m_pContent, m_viewState, m_pFilterLineEdit, m_time.ToFloat(), m_keyWidth, m_treeVisible); - ApplyPushOut(m_layout.get(), m_keyWidth); - } - - if (m_scrollBar) - { - const int timelineHeight = rect().height(); - const int scrollBarRange = m_layout->size.height() - timelineHeight; - - if (scrollBarRange > 0) - { - m_scrollBar->setRange(0, scrollBarRange); - m_scrollBar->show(); - } - else - { - m_scrollBar->setValue(0); - m_scrollBar->hide(); - } - } - - if (m_sizeToContent) - { - setMaximumHeight(m_layout->size.height()); - setMinimumHeight(m_layout->size.height()); - } - else - { - setMinimumHeight(RULER_HEIGHT + 1); - setMaximumHeight(QWIDGETSIZE_MAX); - } - - if (m_treeVisible) - { - if (!m_pFilterLineEdit) - { - m_pFilterLineEdit = new QLineEdit(this); - connect(m_pFilterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnFilterChanged())); - } - - const uint cornerWidgetWidth = m_cornerWidget ? m_cornerWidgetWidth : 0; - m_pFilterLineEdit->resize(m_viewState.treeWidth - SPLITTER_WIDTH - cornerWidgetWidth, RULER_HEIGHT + VERTICAL_PADDING); - - if (m_cornerWidget) - { - m_cornerWidget->setGeometry(m_viewState.treeWidth - SPLITTER_WIDTH - cornerWidgetWidth, 0, cornerWidgetWidth, RULER_HEIGHT + VERTICAL_PADDING); - } - } - else if (!m_treeVisible && m_pFilterLineEdit) - { - SAFE_DELETE(m_pFilterLineEdit); - } -} - -void CTimeline::SetSizeToContent(bool sizeToContent) -{ - m_sizeToContent = sizeToContent; - - UpdateLayout(); -} - -void CTimeline::ContentChanged(bool continuous) -{ - SignalContentChanged(continuous); - - DeletedMarkedElements(m_pContent->track); - - if (!continuous) - { - ForEachElement(m_pContent->track, [](STimelineTrack& track, STimelineElement& element) - { - track.modified = false; - element.added = false; - }); - } - - UpdateLayout(); - update(); -} - -void CTimeline::OnMenuSelectionToCursor() -{ - TSelectedElements elements = GetSelectedElements(m_pContent->track); - - for (size_t i = 0; i < elements.size(); ++i) - { - STimelineTrack& track = *elements[i].first; - STimelineElement& element = *elements[i].second; - SAnimTime length = element.end - element.start; - element.start = m_time; - element.end = element.start + length; - if (element.type == element.CLIP) - { - if (length > track.endTime) - { - element.start = track.endTime - length; - } - } - if (element.start < track.startTime) - { - element.start = track.startTime; - } - } - - ContentChanged(false); -} - -void CTimeline::OnMenuDuplicate() -{ - TSelectedElements selectedElements = GetSelectedElements(m_pContent->track); - if (selectedElements.empty()) - { - return; - } - - typedef std::vector > TTrackElements; - - TTrackElements elements; - - ForEachElement(m_pContent->track, [&](STimelineTrack& track, STimelineElement& element) - { - if (element.selected) - { - elements.push_back(std::make_pair(&track, element)); - element.selected = false; - } - }); - - for (size_t i = 0; i < elements.size(); ++i) - { - STimelineTrack* track = elements[i].first; - const STimelineElement& element = elements[i].second; - track->elements.push_back(element); - STimelineElement& e = track->elements.back(); - e.userId = 0; - e.added = true; - e.sideLoadChanged = true; - e.selected = true; - } - - ContentChanged(false); - SignalSelectionChanged(false); -} - -void CTimeline::OnMenuCopy() -{ -} - -void CTimeline::OnMenuPaste() -{ -} - -void CTimeline::OnMenuDelete() -{ - ForEachElement(m_pContent->track, [](STimelineTrack& track, STimelineElement& element) - { - if (element.selected) - { - track.modified = true; - element.deleted = true; - } - }); - - ContentChanged(false); -} - -void CTimeline::OnMenuPlay() -{ - SignalPlay(); -} - -typedef std::vector > TimeToId; -static void GetAllTimes(TimeToId* times, const STimelineTrack& track) -{ - for (size_t i = 0; i < track.tracks.size(); ++i) - { - GetAllTimes(times, *track.tracks[i]); - } -} - -static void GetAllTimes(TimeToId* times, STimelineContent& content) -{ - ForEachTrack(content.track, [&](STimelineTrack& track) - { - times->push_back(std::make_pair(track.startTime, STimelineContentElementRef())); - times->push_back(std::make_pair(track.endTime, STimelineContentElementRef())); - }); - - ForEachElementWithIndex(content.track, [=](STimelineTrack& track, STimelineElement& element, size_t i) - { - STimelineContentElementRef ref(&track, i); - times->push_back(std::make_pair(element.start, ref)); - if (element.type == STimelineElement::CLIP) - { - times->push_back(std::make_pair(element.end, ref)); - } - }); - - std::sort(times->begin(), times->end()); -} - -static STimelineContentElementRef SelectedIdAtTime(const std::vector& selection, [[maybe_unused]] const STimelineContent& content, SAnimTime time) -{ - for (size_t i = 0; i < selection.size(); ++i) - { - const STimelineContentElementRef& id = selection[i]; - const STimelineElement& element = id.GetElement(); - if (element.start == time || element.end == time) - { - return id; - } - } - return STimelineContentElementRef(); -} - -void CTimeline::OnMenuPreviousKey() -{ - if (!m_pContent) - { - return; - } - TimeToId times; - GetAllTimes(×, *m_pContent); - - std::vector selection; - ForEachElementWithIndex(m_pContent->track, [&](STimelineTrack& t, STimelineElement& e, size_t i) - { - if (e.selected) - { - selection.push_back(STimelineContentElementRef(&t, i)); - } - }); - - STimelineContentElementRef selectedId = SelectedIdAtTime(selection, *m_pContent, m_time); - - TimeToId::iterator it = std::lower_bound(times.begin(), times.end(), std::make_pair(m_time, selectedId)); - if (it != times.end()) - { - if (it != times.begin()) - { - --it; - } - - ClearElementSelection(m_pContent->track); - if (it->second.IsValid()) - { - it->second.GetElement().selected = true; - } - - m_time = it->first; - - SignalSelectionChanged(false); - SignalScrub(false); - update(); - } -} - -void CTimeline::OnMenuNextKey() -{ - if (!m_pContent) - { - return; - } - TimeToId times; - GetAllTimes(×, *m_pContent); - - std::vector selection; - ForEachElementWithIndex(m_pContent->track, [&](STimelineTrack& t, STimelineElement& e, size_t i) - { - if (e.selected) - { - selection.push_back(STimelineContentElementRef(&t, i)); - } - }); - - STimelineContentElementRef selectedId = SelectedIdAtTime(selection, *m_pContent, m_time); - - TimeToId::iterator it = std::upper_bound(times.begin(), times.end(), std::make_pair(m_time, selectedId)); - if (it != times.end()) - { - ClearElementSelection(m_pContent->track); - if (it->second.IsValid()) - { - it->second.GetElement().selected = true; - } - - m_time = it->first; - - SignalSelectionChanged(false); - SignalScrub(false); - update(); - } -} - -void CTimeline::OnMenuPreviousFrame() -{ - m_timeStepIndex = static_cast(floor(m_time.ToFloat() * static_cast(m_timeStepNum) + 0.05f)) - 1; - if (m_timeStepIndex < 0) - { - m_timeStepIndex = m_timeStepNum; - } - float normalizedTime = static_cast(m_timeStepIndex) / static_cast(m_timeStepNum); - m_time = SAnimTime(normalizedTime); - SignalScrub(false); - update(); -} - -void CTimeline::OnMenuNextFrame() -{ - m_timeStepIndex = static_cast(floor(m_time.ToFloat() * static_cast(m_timeStepNum) + 0.05f)) + 1; - if (m_timeStepIndex > m_timeStepNum) - { - m_timeStepIndex = 0; - } - float normalizedTime = static_cast(m_timeStepIndex) / static_cast(m_timeStepNum); - m_time = SAnimTime(normalizedTime); - SignalScrub(false); - update(); -} - -void CTimeline::OnFilterChanged() -{ - UpdateLayout(); - update(); -} - -void CTimeline::OnVerticalScroll([[maybe_unused]] int value) -{ - update(); -} - -bool CTimeline::event(QEvent* e) -{ - switch (e->type()) - { - case QEvent::ShortcutOverride: - { - // When a shortcut is matched, Qt's event processing sends out a shortcut override event - // to allow other systems to override it. If it's not overridden, then the key events - // get processed as a shortcut, even if the widget that's the target has a keyPress event - // handler. So, we need to communicate that we've processed the shortcut override - // which will tell Qt not to process it as a shortcut and instead pass along the - // keyPressEvent. - - QKeyEvent* keyEvent = static_cast(e); - QKeySequence keySequence = keyEvent->key() | keyEvent->modifiers(); - - // special case undo/redo, because they're only handled in CTimeline::keyPressEvent() - // and not in HandleKeyEvent: - static QSet customShortcuts = { - QKeySequence(Qt::CTRL | Qt::Key_Z), - QKeySequence(Qt::CTRL | Qt::Key_Y), - QKeySequence(Qt::Key_Z | Qt::CTRL | Qt::SHIFT) - }; - - if (ProcessesKey(keySequence) || customShortcuts.contains(keySequence)) - { - e->accept(); - return true; - } - } - break; - } - - return QWidget::event(e); -} - -void CTimeline::SetTreeVisible(bool visible) -{ - m_treeVisible = visible; - m_viewState.treeWidth = visible ? DEFAULT_TREE_WIDTH : 0; - - UpdateLayout(); - update(); -} - -STrackLayout* CTimeline::GetTrackLayoutFromPos(const QPoint& pos) const -{ - if (pos.y() < RULER_HEIGHT) - { - return nullptr; - } - - STrackLayouts& tracks = m_layout->tracks; - - auto findIter = std::upper_bound(tracks.begin(), tracks.end(), pos.y(), [&](int y, const STrackLayout& track) - { - return y < track.rect.bottom(); - }); - - if (findIter != tracks.end() && pos.y() <= findIter->rect.bottom()) - { - return &(*findIter); - } - - return nullptr; -} - -void CTimeline::SetCustomTreeCornerWidget(QWidget* pWidget, uint width) -{ - SAFE_DELETE(m_cornerWidget); - - m_cornerWidget = pWidget; - m_cornerWidgetWidth = width; - - if (m_cornerWidget) - { - m_cornerWidget->setCursor(QCursor()); - } - - UpdateLayout(); - update(); -} - -void CTimeline::SetVerticalScrollbarVisible(bool bVisible) -{ - m_verticalScrollbarVisible = bVisible; - UpdateLayout(); - update(); -} - -void CTimeline::SetDrawTrackTimeMarkers(bool bDrawMarkers) -{ - m_drawMarkers = bDrawMarkers; - update(); -} - -void CTimeline::SetVisibleDistance(float distance) -{ - const float totalDuration = (m_layout->maxEndTime - m_layout->minStartTime).ToFloat(); - const float padding = (float(TIMELINE_PADDING) - 0.5f) / m_viewState.widthPixels * totalDuration; - m_viewState.visibleDistance = clamp_tpl(distance, 0.01f, totalDuration + 2.0f * padding); - - UpdateLayout(); - update(); -} diff --git a/Code/Sandbox/Plugins/EditorCommon/Timeline.h b/Code/Sandbox/Plugins/EditorCommon/Timeline.h deleted file mode 100644 index 7449841695..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/Timeline.h +++ /dev/null @@ -1,216 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_EDITORCOMMON_TIMELINE_H -#define CRYINCLUDE_EDITORCOMMON_TIMELINE_H - -#include -#include - -#include "TimelineContent.h" - -class QPainter; -class QPaintEvent; -class QLineEdit; -class QScrollBar; - -struct STimelineLayout; - -struct STimelineViewState -{ - float viewOrigin; - float visibleDistance; - float clampedViewOrigin; - int widthPixels; - QPoint scrollPixels; - int maxScrollX; - int treeWidth; - int treeLastOpenedWidth; - - STimelineViewState() - : viewOrigin(0.0f) - , clampedViewOrigin(0.0f) - , visibleDistance(1.0f) - , scrollPixels(0, 0) - , maxScrollX(0) - , treeWidth(0) - , widthPixels(1) - { - } - - QPoint LocalToLayout(const QPoint& p) const; - QPoint LayoutToLocal(const QPoint& p) const; - - int ScrollOffset(float origin) const; - int TimeToLayout(float time) const; - float LocalToTime(int x) const; - int TimeToLocal(float time) const; - float LayoutToTime(int x) const; -}; - -struct STrackLayout; - -class EDITOR_COMMON_API CTimeline - : public QWidget -{ - Q_OBJECT -public: - CTimeline(QWidget* parent); - ~CTimeline(); - - void SetContent(STimelineContent* pContent); - STimelineContent* Content() const { return m_pContent; } - - void ContentUpdated() { UpdateLayout(); update(); } - - bool IsDragged() const { return m_mouseHandler.get() != 0; } - - // make it possible to have actual time in normalized units, but different display units - void SetTimeUnitScale(float timeUnitScale, float step); - void SetTime(SAnimTime time); - void SetCycled(bool cycled); - void SetSizeToContent(bool sizeToContent); - void SetFrameRate(SAnimTime::EFrameRate frameRate) { m_frameRate = frameRate; } - void SetTimeSnapping(bool snapTime) { m_snapTime = snapTime; } - void SetKeySnapping(bool snapKeys) { m_snapKeys = snapKeys; } - void SetKeyWidth(uint width) { m_keyWidth = width; UpdateLayout(); update(); } - void SetKeyRadius(float radius) { m_keyRadius = radius; UpdateLayout(); update(); } - void SetTreeVisible(bool visible); - void SetDrawSelectionIndicators(bool visible) { m_selIndicators = visible; update(); } - void SetCustomTreeCornerWidget(QWidget* pWidget, uint width); - void SetVerticalScrollbarVisible(bool bVisible); - void SetDrawTrackTimeMarkers(bool bDrawMarkers); - void SetVisibleDistance(float distance); - - SAnimTime Time() const { return m_time; } - - bool HandleKeyEvent(int key); - bool ProcessesKey(const QKeySequence& key); - - void paintEvent(QPaintEvent* ev) override; - void mousePressEvent(QMouseEvent* ev) override; - void mouseMoveEvent(QMouseEvent* ev) override; - void mouseReleaseEvent(QMouseEvent* ev) override; - void focusOutEvent(QFocusEvent* ev) override; - void mouseDoubleClickEvent(QMouseEvent* ev) override; - - void AddKeyToTrack(STimelineTrack& subTrack, SAnimTime time); - - void keyPressEvent(QKeyEvent* ev) override; - void keyReleaseEvent(QKeyEvent* ev) override; - void resizeEvent(QResizeEvent* ev) override; - void wheelEvent(QWheelEvent* ev) override; - QSize sizeHint() const override; - -signals: - void SignalScrub(bool scrubThrough); - void SignalContentChanged(bool continuous); - void SignalSelectionChanged(bool continuous); - void SignalTrackSelectionChanged(); - void SignalPlay(); - void SignalNumberHotkey(int number); - void SignalTreeContextMenu(const QPoint& point); - - void SignalUndo(); - void SignalRedo(); - -protected slots: - void OnMenuSelectionToCursor(); - void OnMenuDuplicate(); - void OnMenuCopy(); - void OnMenuPaste(); - void OnMenuDelete(); - void OnMenuPlay(); - void OnMenuNextKey(); - void OnMenuPreviousKey(); - void OnMenuNextFrame(); - void OnMenuPreviousFrame(); - void OnFilterChanged(); - void OnVerticalScroll(int value); - -protected: - - bool event(QEvent* e) override; - -private: - struct SMouseHandler; - struct SSelectionHandler; - struct SMoveHandler; - struct SPanHandler; - struct SScrubHandler; - struct SSplitterHandler; - struct STreeMouseHandler; - - void ContentChanged(bool continuous); - void UpdateLayout(); - void UpdateCursor(QMouseEvent* ev); - void DrawMarkers(QPainter& painter, int offsetY); - SAnimTime ClampAndSnapTime(SAnimTime time, bool snapToFrames) const; - void ClampAndSetTime(SAnimTime time, bool scrubThrough); - STrackLayout* GetTrackLayoutFromPos(const QPoint& pos) const; - - // Exposed parameters - float m_timeUnitScale; - int m_timeStepNum; - int m_timeStepIndex; - SAnimTime::EFrameRate m_frameRate; - bool m_cycled : 1; - bool m_sizeToContent : 1; - bool m_snapTime : 1; - bool m_snapKeys : 1; - bool m_treeVisible : 1; - bool m_selIndicators : 1; - bool m_verticalScrollbarVisible : 1; - bool m_drawMarkers : 1; - uint m_keyWidth; - float m_keyRadius; - uint m_cornerWidgetWidth; - - // Widgets - QScrollBar* m_scrollBar; - QWidget* m_cornerWidget; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - STimelineViewState m_viewState; - STimelineContent* m_pContent; - SAnimTime m_time; - std::unique_ptr m_layout; - std::unique_ptr m_mouseHandler; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - // Filtering - QLineEdit* m_pFilterLineEdit; - - // Track selection - STrackLayout* m_pLastSelectedTrack; - - friend class CTimelineTracks; -}; - -class CTimelineTracks - : public QWidget -{ - Q_OBJECT -public: - CTimelineTracks(QWidget* widget) - : QWidget(widget) {} - void ConnectToTimeline(CTimeline* timeline) { m_timeline = timeline; } - -private: - CTimeline* m_timeline; -}; - - - -#endif // CRYINCLUDE_EDITORCOMMON_TIMELINE_H diff --git a/Code/Sandbox/Plugins/EditorCommon/TimelineContent.cpp b/Code/Sandbox/Plugins/EditorCommon/TimelineContent.cpp deleted file mode 100644 index 8ee8c3acf6..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/TimelineContent.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "TimelineContent.h" -#include "Serialization.h" - -SERIALIZATION_ENUM_BEGIN_NESTED(STimelineElement, ECaps, "Capabilities") -SERIALIZATION_ENUM_VALUE_NESTED(STimelineElement, CAP_SELECT, "Select") -SERIALIZATION_ENUM_VALUE_NESTED(STimelineElement, CAP_MOVE, "Move") -SERIALIZATION_ENUM_VALUE_NESTED(STimelineElement, CAP_DELETE, "Delete") -SERIALIZATION_ENUM_VALUE_NESTED(STimelineElement, CAP_CHANGE_DURATION, "Change Duration") -SERIALIZATION_ENUM_END() diff --git a/Code/Sandbox/Plugins/EditorCommon/TimelineContent.h b/Code/Sandbox/Plugins/EditorCommon/TimelineContent.h deleted file mode 100644 index a2d89f9c7d..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/TimelineContent.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITORCOMMON_TIMELINECONTENT_H -#define CRYINCLUDE_EDITORCOMMON_TIMELINECONTENT_H -#pragma once - -#include "QPropertyTree/Color.h" -#include "Serialization/Strings.h" -#include "Serialization/SmartPtr.h" -#include "Serialization.h" - -#include -#include - -using Serialization::string; - -struct STimelineElement -{ - enum EType - { - KEY, - CLIP - }; - - enum ECaps - { - CAP_SELECT = BIT(0), - CAP_DELETE = BIT(1), - - // not implemented: - CAP_MOVE = BIT(2), - CAP_CHANGE_DURATION = BIT(3) - }; - - EType type; - int caps; - SAnimTime start; - SAnimTime end; - ColorB color; - float baseWeight; - uint64 userId; - string description; - DynArray userSideLoad; - // state flags - bool selected : 1; - bool added : 1; - bool deleted : 1; - bool sideLoadChanged : 1; - - STimelineElement() - : type(KEY) - , start(0.0f) - , end(0.1f) - , color(212, 212, 212, 255) - , caps(CAP_SELECT | CAP_MOVE | CAP_CHANGE_DURATION) - , selected(false) - , added(false) - , deleted(false) - , sideLoadChanged(false) - , userId(0) - { - } - - void Serialize(IArchive& ar) - { - ar(type, "type", "^>80>"); - ar(start, "start", "^"); - if (type == CLIP) - { - ar(end, "end", "^"); - } - ar(BitFlags(caps), "caps", "Capabilities"); - ar(color, "color", "Color"); - } -}; -typedef std::vector STimelineElements; - -struct STimelineTrack; -typedef std::vector<_smart_ptr > STimelineTracks; - -struct STimelineTrack - : public _i_reference_target_t -{ - enum ECaps - { - CAP_ADD_ELEMENTS = BIT(0), - CAP_DESCRIPTION_TRACK = BIT(1), // No keys - CAP_COMPOUND_TRACK = BIT(2), // No own keys, but will show combined keys for child tracks - CAP_TOGGLE_TRACK = BIT(3), // For boolean tracks that are either on or off between keys. Used to key visibility etc. - }; - bool expanded : 1; - bool modified : 1; - bool selected : 1; - bool deleted : 1; - bool keySelectionChanged : 1; - bool toggleDefaultState : 1; // Default state for toggle tracks (on or off) - int height; - int caps; - SAnimTime startTime; - SAnimTime endTime; - string type; - string name; - DynArray userSideLoad; - STimelineElements elements; - STimelineElement defaultElement; - STimelineTracks tracks; - - STimelineTrack() - : expanded(true) - , modified(false) - , selected(false) - , deleted(false) - , keySelectionChanged(false) - , height(64) - , startTime(0.0f) - , endTime(1.0f) - , caps(CAP_ADD_ELEMENTS) - {} - - void Serialize(IArchive& ar) - { - ar(name, "name", "^"); - ar(type, "type", "^"); - ar(height, "height", "Height"); - ar(startTime, "startTime", "Start Time"); - ar(endTime, "endTime", "End Time"); - ar(elements, "elements", "Elements"); - ar(tracks, "tracks", "+Tracks"); - } -}; - -struct STimelineContent -{ - STimelineTrack track; - DynArray userSideLoad; - - void Serialize(IArchive& ar) - { - ar(track, "track", "Track"); - } -}; - -#endif // CRYINCLUDE_EDITORCOMMON_TIMELINECONTENT_H diff --git a/Code/Sandbox/Plugins/EditorCommon/UnsavedChangesDialog.cpp b/Code/Sandbox/Plugins/EditorCommon/UnsavedChangesDialog.cpp deleted file mode 100644 index 71acb24c3c..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/UnsavedChangesDialog.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include "UnsavedChangesDialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -CUnsavedChangedDialog::CUnsavedChangedDialog(QWidget* parent) - : QDialog(parent) -{ - setWindowTitle("Unsaved Changes"); - setModal(true); - - auto layout = new QBoxLayout(QBoxLayout::TopToBottom); - auto label = new QLabel("The following files were modified.\n\nWould you like to save them before closing?"); - layout->addWidget(label, 0); - - m_list = new QListWidget(); - layout->addWidget(m_list, 1); - - auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel, Qt::Horizontal); - layout->addWidget(buttonBox, 0); - - connect(buttonBox, &QDialogButtonBox::clicked, this, [this, buttonBox](QAbstractButton* button) - { - done(buttonBox->buttonRole(button)); - }); - - setLayout(layout); - resize(500, 350); - - if (parent) - { - QPoint center = parent->mapToGlobal(parent->geometry().center()); - const QRect screenDimensions = QApplication::screenAt(center)->geometry(); - if (screenDimensions.contains(center)) - { - QPoint dialogPosition = center - QPoint(width() / 2, height() / 2); - if (screenDimensions.contains(dialogPosition)) - { - move(dialogPosition); - } - else - { - move(center); - } - } - else - { - move((screenDimensions.width() - width()) / 2, (screenDimensions.height() - height()) / 2); - } - } -} - -bool CUnsavedChangedDialog::Exec(DynArray* selectedFiles, const DynArray& files) -{ - m_list->clear(); - - std::vector items(files.size(), nullptr); - - for (size_t i = 0; i < files.size(); ++i) - { - auto item = new QListWidgetItem(files[i].c_str(), m_list); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - item->setCheckState(Qt::Checked); - items[i] = item; - } - - selectedFiles->clear(); - - int result = exec(); - if (result == QDialogButtonBox::YesRole) - { - for (size_t i = 0; i < items.size(); ++i) - { - if (items[i]->checkState() == Qt::Checked) - { - selectedFiles->push_back(files[i].c_str()); - } - } - return true; - } - else if (result == QDialogButtonBox::NoRole) - { - return true; - } - else - { - return false; - } -} - -bool EDITOR_COMMON_API UnsavedChangesDialog(QWidget* parent, DynArray* selectedFiles, const DynArray& files) -{ - CUnsavedChangedDialog dialog(parent); - return dialog.Exec(selectedFiles, files); -} - -#include diff --git a/Code/Sandbox/Plugins/EditorCommon/UnsavedChangesDialog.h b/Code/Sandbox/Plugins/EditorCommon/UnsavedChangesDialog.h deleted file mode 100644 index 999b226845..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/UnsavedChangesDialog.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#if !defined(Q_MOC_RUN) -#include "EditorCommonAPI.h" -#include "Serialization/Strings.h" -#include "Serialization/DynArray.h" - -#include -#endif -class QListWidget; - -// Supposed to be used through -// ConfirmSaveDialog function. -class CUnsavedChangedDialog - : public QDialog -{ - Q_OBJECT -public: - CUnsavedChangedDialog(QWidget* parent); - - bool Exec(DynArray* selectedFiles, const DynArray& files); -private: - QListWidget* m_list; - int m_result; -}; - -// Returns true if window should be closed (Yes/No). False for Cancel. -// selectedFiles contains list of files that should be saved (empty in No case). -bool EDITOR_COMMON_API UnsavedChangesDialog(QWidget* parent, DynArray* selectedFiles, const DynArray& files); diff --git a/Code/Sandbox/Plugins/EditorCommon/editorcommon_files.cmake b/Code/Sandbox/Plugins/EditorCommon/editorcommon_files.cmake index 5551c07be1..a7b3860905 100644 --- a/Code/Sandbox/Plugins/EditorCommon/editorcommon_files.cmake +++ b/Code/Sandbox/Plugins/EditorCommon/editorcommon_files.cmake @@ -13,16 +13,8 @@ set(FILES EditorCommon.h EditorCommon.cpp EditorCommon.rc - EditorCommon.qrc EditorCommonAPI.h - moc.cpp - QViewportConsumer.h - TimelineContent.h EditorCommon_precompiled.h - CurveEditorControl.cpp - CurveEditorControl.h - DisplayViewportAdapter.cpp - DisplayViewportAdapter.h ActionOutput.h ActionOutput.cpp UiEditorDLLBus.h @@ -30,140 +22,16 @@ set(FILES DockTitleBarWidget.h SaveUtilities/AsyncSaveRunner.h SaveUtilities/AsyncSaveRunner.cpp - Events/EventManager.cpp - Events/EventManager.h AxisHelper.cpp DisplayContext.cpp - QPropertyTree/PropertyRowSlider.cpp - BatchFileDialog.cpp - BatchFileDialog.h DeepFilterProxyModel.cpp DeepFilterProxyModel.h - QAbstractQVariantTreeDataModel.h - QAbstractQVariantTreeDataModel.cpp - UnsavedChangesDialog.h - UnsavedChangesDialog.cpp Resource.h DrawingPrimitives/Ruler.cpp DrawingPrimitives/Ruler.h DrawingPrimitives/TimeSlider.cpp DrawingPrimitives/TimeSlider.h - Timeline.cpp - Timeline.h - CurveEditor.cpp - CurveEditor.h - CurveEditorContent.h WinWidget/WinWidget.h WinWidget/WinWidgetManager.h WinWidget/WinWidgetManager.cpp - QPropertyTree/Color.cpp - QPropertyTree/Color.h - QPropertyTree/ConstStringList.cpp - QPropertyTree/ConstStringList.h - QPropertyTree/Factory.h - QPropertyTree/MathUtils.h - QPropertyTree/PropertyDrawContext.cpp - QPropertyTree/PropertyDrawContext.h - QPropertyTree/PropertyIArchive.cpp - QPropertyTree/PropertyIArchive.h - QPropertyTree/PropertyOArchive.cpp - QPropertyTree/PropertyOArchive.h - QPropertyTree/PropertyRow.cpp - QPropertyTree/PropertyRow.h - QPropertyTree/PropertyRowActionButton.cpp - QPropertyTree/PropertyRowBool.cpp - QPropertyTree/PropertyRowBool.h - QPropertyTree/PropertyRowColor.cpp - QPropertyTree/PropertyRowColor.h - QPropertyTree/PropertyRowColorPicker.cpp - QPropertyTree/PropertyRowColorPicker.h - QPropertyTree/PropertyRowContainer.cpp - QPropertyTree/PropertyRowContainer.h - QPropertyTree/PropertyRowField.cpp - QPropertyTree/PropertyRowField.h - QPropertyTree/PropertyRowIconXPM.cpp - QPropertyTree/PropertyRowImpl.h - QPropertyTree/PropertyRowLocalFrame.cpp - QPropertyTree/PropertyRowLocalFrame.h - QPropertyTree/PropertyRowNumber.cpp - QPropertyTree/PropertyRowNumber.h - QPropertyTree/PropertyRowNumberField.cpp - QPropertyTree/PropertyRowNumberField.h - QPropertyTree/PropertyRowObject.cpp - QPropertyTree/PropertyRowObject.h - QPropertyTree/PropertyRowPointer.cpp - QPropertyTree/PropertyRowPointer.h - QPropertyTree/PropertyRowSprite.cpp - QPropertyTree/PropertyRowSprite.h - QPropertyTree/PropertyRowString.h - QPropertyTree/PropertyRowString.cpp - QPropertyTree/PropertyRowStringListValue.cpp - QPropertyTree/PropertyRowStringListValue.h - QPropertyTree/PropertyRowTagList.cpp - QPropertyTree/PropertyRowTagList.h - QPropertyTree/PropertyRowToggleButton.cpp - QPropertyTree/PropertyTreeMenuHandler.h - QPropertyTree/PropertyTreeModel.cpp - QPropertyTree/PropertyTreeModel.h - QPropertyTree/PropertyTreeOperator.cpp - QPropertyTree/PropertyTreeOperator.h - QPropertyTree/QPropertyTree.cpp - QPropertyTree/QPropertyTree.h - QPropertyTree/QPropertyTreeStyle.h - QPropertyTree/Serialization.h - QPropertyTree/Strings.h - QPropertyTree/Unicode.h - QPropertyTree/ContextList.h - QPropertyTree/file_open.xpm - QPropertyTree/file_save.xpm - QPropertyTree/SlicerEdit.cpp - QPropertyTree/SlicerEdit.h - QPropertyTree/SlicerManipulator.cpp - QPropertyTree/SlicerManipulator.h - QPropertyTree/SlicerView.cpp - QPropertyTree/SlicerView.h - QPropertyTree/SpriteBorderEditor.cpp - QPropertyTree/SpriteBorderEditor.h - QPropertyTree/SpriteBorderEditorCommon.cpp - QPropertyTree/SpriteBorderEditorCommon.h - QPropertyTree/ValidatorBlock.h - ListSelectionDialog.cpp - ListSelectionDialog.h - QViewport.cpp - QViewport.h - QViewportEvents.h - QViewportSettings.h - QPropertyTree/PropertyRowResourceFilePath.cpp - QPropertyTree/PropertyRowResourceFilePath.h - QPropertyTree/PropertyRowResourceFolderPath.cpp - QPropertyTree/PropertyRowResourceFolderPath.h - QPropertyTree/PropertyRowResourceSelector.cpp - QPropertyTree/PropertyRowResourceSelector.h - QPropertyTree/PropertyRowOutputFilePath.cpp - QPropertyTree/PropertyRowOutputFilePath.h - QPropertyTree/QPropertyDialog.cpp - QPropertyTree/QPropertyDialog.h - Serialization.cpp - Serialization.h - Serialization/BinArchive.cpp - Serialization/BinArchive.h - Serialization/JSONIArchive.cpp - Serialization/JSONIArchive.h - Serialization/JSONOArchive.cpp - Serialization/JSONOArchive.h - Serialization/MemoryReader.cpp - Serialization/MemoryReader.h - Serialization/MemoryWriter.cpp - Serialization/MemoryWriter.h - Serialization/Pointers.h - Serialization/PointersImpl.h - Serialization/Qt.cpp - Serialization/Qt.h - Serialization/QtImpl.h - Serialization/Token.h - Serialization/Decorators/ToggleButton.h - Serialization/Decorators/ToggleButtonImpl.h - Serialization/Decorators/IGizmoSink.h - Serialization/Decorators/IconXPM.h - Serialization/Decorators/INavigationProvider.h ) diff --git a/Code/Sandbox/Plugins/EditorCommon/moc.cpp b/Code/Sandbox/Plugins/EditorCommon/moc.cpp deleted file mode 100644 index ce9570b673..0000000000 --- a/Code/Sandbox/Plugins/EditorCommon/moc.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorCommon_precompiled.h" -#include -#include -#include - -#include -#include -#include diff --git a/Gems/AudioEngineWwise/Code/Platform/Android/AudioEngineWwise_Traits_Android.h b/Gems/AudioEngineWwise/Code/Platform/Android/AudioEngineWwise_Traits_Android.h index 336d6e78c0..b753d321da 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Android/AudioEngineWwise_Traits_Android.h +++ b/Gems/AudioEngineWwise/Code/Platform/Android/AudioEngineWwise_Traits_Android.h @@ -22,7 +22,6 @@ #endif #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE 32 << 10 /* 32 MiB */ #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE_DEFAULT_TEXT "32768 (32 MiB)" -#define AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE_DEFAULT_TEXT "0 (0 MiB)" #define AZ_TRAIT_AUDIOENGINEWWISE_STREAMER_DEVICE_MEMORY_POOL_SIZE 2 << 10 /* 2 MiB */ diff --git a/Gems/AudioEngineWwise/Code/Platform/Linux/AudioEngineWwise_Traits_Linux.h b/Gems/AudioEngineWwise/Code/Platform/Linux/AudioEngineWwise_Traits_Linux.h index 6df576637b..a7900484e3 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Linux/AudioEngineWwise_Traits_Linux.h +++ b/Gems/AudioEngineWwise/Code/Platform/Linux/AudioEngineWwise_Traits_Linux.h @@ -26,7 +26,6 @@ #endif #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE 128 << 10 /* 128 MiB */ #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE_DEFAULT_TEXT "131072 (128 MiB)" -#define AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE_DEFAULT_TEXT "0 (0 MiB)" #define AZ_TRAIT_AUDIOENGINEWWISE_STREAMER_DEVICE_MEMORY_POOL_SIZE 2 << 10 /* 2 MiB */ diff --git a/Gems/AudioEngineWwise/Code/Platform/Mac/AudioEngineWwise_Traits_Mac.h b/Gems/AudioEngineWwise/Code/Platform/Mac/AudioEngineWwise_Traits_Mac.h index 6df576637b..a7900484e3 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Mac/AudioEngineWwise_Traits_Mac.h +++ b/Gems/AudioEngineWwise/Code/Platform/Mac/AudioEngineWwise_Traits_Mac.h @@ -26,7 +26,6 @@ #endif #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE 128 << 10 /* 128 MiB */ #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE_DEFAULT_TEXT "131072 (128 MiB)" -#define AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE_DEFAULT_TEXT "0 (0 MiB)" #define AZ_TRAIT_AUDIOENGINEWWISE_STREAMER_DEVICE_MEMORY_POOL_SIZE 2 << 10 /* 2 MiB */ diff --git a/Gems/AudioEngineWwise/Code/Platform/Windows/AudioEngineWwise_Traits_Windows.h b/Gems/AudioEngineWwise/Code/Platform/Windows/AudioEngineWwise_Traits_Windows.h index c1c51482fb..b71f0b7d0d 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Windows/AudioEngineWwise_Traits_Windows.h +++ b/Gems/AudioEngineWwise/Code/Platform/Windows/AudioEngineWwise_Traits_Windows.h @@ -26,7 +26,6 @@ #endif #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE 128 << 10 /* 128 MiB */ #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE_DEFAULT_TEXT "131072 (128 MiB)" -#define AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE_DEFAULT_TEXT "0 (0 MiB)" #define AZ_TRAIT_AUDIOENGINEWWISE_STREAMER_DEVICE_MEMORY_POOL_SIZE 2 << 10 /* 2 MiB */ diff --git a/Gems/AudioEngineWwise/Code/Platform/iOS/AudioEngineWwise_Traits_iOS.h b/Gems/AudioEngineWwise/Code/Platform/iOS/AudioEngineWwise_Traits_iOS.h index 336d6e78c0..b753d321da 100644 --- a/Gems/AudioEngineWwise/Code/Platform/iOS/AudioEngineWwise_Traits_iOS.h +++ b/Gems/AudioEngineWwise/Code/Platform/iOS/AudioEngineWwise_Traits_iOS.h @@ -22,7 +22,6 @@ #endif #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE 32 << 10 /* 32 MiB */ #define AZ_TRAIT_AUDIOENGINEWWISE_PRIMARY_POOL_SIZE_DEFAULT_TEXT "32768 (32 MiB)" -#define AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE 0 #define AZ_TRAIT_AUDIOENGINEWWISE_SECONDARY_POOL_SIZE_DEFAULT_TEXT "0 (0 MiB)" #define AZ_TRAIT_AUDIOENGINEWWISE_STREAMER_DEVICE_MEMORY_POOL_SIZE 2 << 10 /* 2 MiB */ diff --git a/Gems/AudioEngineWwise/Code/Source/AudioEngineWwiseGemSystemComponent.cpp b/Gems/AudioEngineWwise/Code/Source/AudioEngineWwiseGemSystemComponent.cpp index faaf4d5c75..c5dae7de75 100644 --- a/Gems/AudioEngineWwise/Code/Source/AudioEngineWwiseGemSystemComponent.cpp +++ b/Gems/AudioEngineWwise/Code/Source/AudioEngineWwiseGemSystemComponent.cpp @@ -36,10 +36,6 @@ namespace Audio { CAudioLogger g_audioImplLogger_wwise; -#if AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL - TMemoryPoolReferenced g_audioImplMemoryPoolSecondary_wwise; -#endif // AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL - namespace Platform { void* InitializeSecondaryMemoryPool(size_t& secondarySize); @@ -154,13 +150,6 @@ namespace AudioEngineWwiseGem m_engineWwise = AZStd::make_unique(assetPlatform.c_str()); if (m_engineWwise) { - #if AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL - size_t secondarySize = 0; - void* secondaryMemoryPtr = Audio::Platform::InitializeSecondaryMemoryPool(secondarySize); - - Audio::g_audioImplMemoryPoolSecondary_wwise.InitMem(secondarySize, static_cast(secondaryMemoryPtr)); - #endif // AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL - Audio::g_audioImplLogger_wwise.Log(Audio::eALT_ALWAYS, "AudioEngineWwise created!"); Audio::SAudioRequest oAudioRequestData; diff --git a/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.h b/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.h index e35b225fc6..ee7b54217d 100644 --- a/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.h +++ b/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.h @@ -35,12 +35,6 @@ namespace AudioControls bool HasProperties() override { return true; } - void Serialize(Serialization::IArchive& ar) override - { - ar(m_mult, "mult", "Multiply"); - ar(m_shift, "shift", "Shift"); - } - float m_mult; float m_shift; }; @@ -61,11 +55,6 @@ namespace AudioControls bool HasProperties() override { return true; } - void Serialize(Serialization::IArchive& ar) override - { - ar(m_value, "value", "Value"); - } - float m_value; }; diff --git a/Gems/AudioEngineWwise/Code/Source/Engine/AudioSystemImpl_wwise.cpp b/Gems/AudioEngineWwise/Code/Source/Engine/AudioSystemImpl_wwise.cpp index 89afb0bf33..2e11c7a810 100644 --- a/Gems/AudioEngineWwise/Code/Source/Engine/AudioSystemImpl_wwise.cpp +++ b/Gems/AudioEngineWwise/Code/Source/Engine/AudioSystemImpl_wwise.cpp @@ -1757,16 +1757,9 @@ namespace Audio memoryInfo.nPrimaryPoolSize = AZ::AllocatorInstance::Get().Capacity(); memoryInfo.nPrimaryPoolUsedSize = memoryInfo.nPrimaryPoolSize - AZ::AllocatorInstance::Get().GetUnAllocatedMemory(); memoryInfo.nPrimaryPoolAllocations = 0; - - #if AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL - memoryInfo.nSecondaryPoolSize = g_audioImplMemoryPoolSecondary_wwise.MemSize(); - memoryInfo.nSecondaryPoolUsedSize = memoryInfo.nSecondaryPoolSize - g_audioImplMemoryPoolSecondary_wwise.MemFree(); - memoryInfo.nSecondaryPoolAllocations = g_audioImplMemoryPoolSecondary_wwise.FragmentCount(); - #else memoryInfo.nSecondaryPoolSize = 0; memoryInfo.nSecondaryPoolUsedSize = 0; memoryInfo.nSecondaryPoolAllocations = 0; - #endif // AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/AudioEngineWwise/Code/Source/Engine/Common_wwise.h b/Gems/AudioEngineWwise/Code/Source/Engine/Common_wwise.h index 7f67196dc6..2e806a80e9 100644 --- a/Gems/AudioEngineWwise/Code/Source/Engine/Common_wwise.h +++ b/Gems/AudioEngineWwise/Code/Source/Engine/Common_wwise.h @@ -19,20 +19,6 @@ #include #include - -#if AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL - #include - #include - - using TMemoryPoolReferenced = NCryPoolAlloc::CThreadSafe, NCryPoolAlloc::CListItemReference>>; - - namespace Audio - { - extern TMemoryPoolReferenced g_audioImplMemoryPoolSecondary_wwise; - } -#endif // AZ_TRAIT_AUDIOENGINEWWISE_PROVIDE_IMPL_SECONDARY_POOL - - #define WWISE_IMPL_VERSION_STRING "Wwise " AK_WWISESDK_VERSIONNAME #define ASSERT_WWISE_OK(x) (AKASSERT((x) == AK_Success)) diff --git a/Gems/AudioSystem/Code/Include/Editor/IAudioConnection.h b/Gems/AudioSystem/Code/Include/Editor/IAudioConnection.h index 5191f211b8..084b14bd18 100644 --- a/Gems/AudioSystem/Code/Include/Editor/IAudioConnection.h +++ b/Gems/AudioSystem/Code/Include/Editor/IAudioConnection.h @@ -14,8 +14,6 @@ #pragma once #include -#include -#include namespace AudioControls { @@ -40,10 +38,6 @@ namespace AudioControls return false; } - virtual void Serialize([[maybe_unused]] Serialization::IArchive& ar) - { - } - private: CID m_id; }; diff --git a/Gems/AudioSystem/Code/Source/Editor/AudioControl.h b/Gems/AudioSystem/Code/Source/Editor/AudioControl.h index 878cf269c6..a974c5f556 100644 --- a/Gems/AudioSystem/Code/Source/Editor/AudioControl.h +++ b/Gems/AudioSystem/Code/Source/Editor/AudioControl.h @@ -19,6 +19,7 @@ #include #include +#include #include namespace AudioControls diff --git a/Gems/AudioSystem/Code/Source/Editor/AudioResourceSelectors.cpp b/Gems/AudioSystem/Code/Source/Editor/AudioResourceSelectors.cpp index 6edf80e3fe..101454db58 100644 --- a/Gems/AudioSystem/Code/Source/Editor/AudioResourceSelectors.cpp +++ b/Gems/AudioSystem/Code/Source/Editor/AudioResourceSelectors.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/Gems/AudioSystem/Code/Source/Editor/ConnectionsWidget.ui b/Gems/AudioSystem/Code/Source/Editor/ConnectionsWidget.ui index e2043df679..120df694bc 100644 --- a/Gems/AudioSystem/Code/Source/Editor/ConnectionsWidget.ui +++ b/Gems/AudioSystem/Code/Source/Editor/ConnectionsWidget.ui @@ -120,28 +120,6 @@ 6 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - @@ -153,12 +131,6 @@ QListWidget
    QConnectionListWidget.h
    - - QPropertyTree - QWidget -
    QPropertyTree/QPropertyTree.h
    - 1 -
    diff --git a/Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp b/Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp index 27e810202d..ab025d5b2d 100644 --- a/Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp +++ b/Gems/AudioSystem/Code/Source/Editor/QConnectionsWidget.cpp @@ -26,8 +26,6 @@ #include #include #include -#include -#include namespace AudioControls { @@ -40,10 +38,6 @@ namespace AudioControls { setupUi(this); - m_connectionProperties->setSizeToContent(true); - m_connectionPropertiesFrame->setHidden(true); - connect(m_connectionProperties, SIGNAL(signalChanged()), this, SLOT(CurrentConnectionModified())); - m_connectionList->viewport()->installEventFilter(this); m_connectionList->installEventFilter(this); @@ -131,17 +125,6 @@ namespace AudioControls } } } - - if (connection && connection->HasProperties()) - { - m_connectionProperties->attach(Serialization::SStruct(*connection.get())); - m_connectionPropertiesFrame->setHidden(false); - } - else - { - m_connectionProperties->detach(); - m_connectionPropertiesFrame->setHidden(true); - } } //-------------------------------------------------------------------------------------------// diff --git a/Gems/GameEffectSystem/preview.png b/Gems/GameEffectSystem/preview.png deleted file mode 100644 index b3a5a5880e..0000000000 --- a/Gems/GameEffectSystem/preview.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fed875535032ff47526dd94870fc171028f3126a5c1d98f773f7da8083d495e4 -size 40620 diff --git a/Gems/LyShine/Code/Editor/ViewportWidget.cpp b/Gems/LyShine/Code/Editor/ViewportWidget.cpp index 753e207288..89c5a0bb50 100644 --- a/Gems/LyShine/Code/Editor/ViewportWidget.cpp +++ b/Gems/LyShine/Code/Editor/ViewportWidget.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/Gems/Maestro/Code/Source/Cinematics/CryMovie.cpp b/Gems/Maestro/Code/Source/Cinematics/CryMovie.cpp deleted file mode 100644 index cec0fd5f01..0000000000 --- a/Gems/Maestro/Code/Source/Cinematics/CryMovie.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Maestro_precompiled.h" -#include "CryMovie.h" -#include "Movie.h" -#include - -#include -#include -#include - -#undef GetClassName - -////////////////////////////////////////////////////////////////////////// -struct CSystemEventListner_Movie - : public ISystemEventListener -{ -public: - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - STLALLOCATOR_CLEANUP; - CLightAnimWrapper::ReconstructCache(); - break; - } - } - } -}; - -static CSystemEventListner_Movie g_system_event_listener_movie; - -////////////////////////////////////////////////////////////////////////// -class CEngineModule_CryMovie - : public IEngineModule -{ - CRYINTERFACE_SIMPLE(IEngineModule) - CRYGENERATE_SINGLETONCLASS(CEngineModule_CryMovie, "EngineModule_CryMovie", 0xdce26beebdc6400f, 0xa0e9b42839f2dd5b) - - ////////////////////////////////////////////////////////////////////////// - virtual const char* GetName() const { - return "CryMovie"; - }; - virtual const char* GetCategory() const { return "CryEngine"; }; - - ////////////////////////////////////////////////////////////////////////// - virtual bool Initialize(SSystemGlobalEnvironment& env, const SSystemInitParams& initParams) - { - ISystem* pSystem = env.pSystem; - - pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_movie); - - env.pMovieSystem = aznew CMovieSystem(pSystem); - return true; - } -}; - -CRYREGISTER_SINGLETON_CLASS(CEngineModule_CryMovie) - -CEngineModule_CryMovie::CEngineModule_CryMovie() -{ -}; - -CEngineModule_CryMovie::~CEngineModule_CryMovie() -{ -}; diff --git a/Gems/Maestro/Code/Source/Cinematics/CryMovie.def b/Gems/Maestro/Code/Source/Cinematics/CryMovie.def deleted file mode 100644 index fc5c3c91cd..0000000000 --- a/Gems/Maestro/Code/Source/Cinematics/CryMovie.def +++ /dev/null @@ -1,3 +0,0 @@ -EXPORTS - ModuleInitISystem @2 - CryModuleGetMemoryInfo @8 diff --git a/Gems/Maestro/Code/Source/Cinematics/CryMovie.h b/Gems/Maestro/Code/Source/Cinematics/CryMovie.h deleted file mode 100644 index 6936f4e1fb..0000000000 --- a/Gems/Maestro/Code/Source/Cinematics/CryMovie.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -// The following ifdef block is the standard way of creating macros which make exporting -// from a DLL simpler. All files within this DLL are compiled with the CRYMOVIE_EXPORTS -// symbol defined on the command line. this symbol should not be defined on any project -// that uses this DLL. This way any other project whose source files include this file see -// CRYMOVIE_API functions as being imported from a DLL, wheras this DLL sees symbols -// defined with this macro as being exported. - -#ifndef CRYINCLUDE_CRYMOVIE_CRYMOVIE_H -#define CRYINCLUDE_CRYMOVIE_CRYMOVIE_H -#pragma once - -#ifdef CRYMOVIE_EXPORTS - #define CRYMOVIE_API DLL_EXPORT -#else - #define CRYMOVIE_API DLL_IMPORT -#endif - -struct ISystem; -struct IMovieSystem; - -extern "C" -{ -CRYMOVIE_API IMovieSystem* CreateMovieSystem(ISystem* pSystem); -CRYMOVIE_API void DeleteMovieSystem(IMovieSystem* pMM); -} -#endif // CRYINCLUDE_CRYMOVIE_CRYMOVIE_H diff --git a/Gems/Maestro/Code/Source/Cinematics/CryMovie.rc b/Gems/Maestro/Code/Source/Cinematics/CryMovie.rc deleted file mode 100644 index 5730d0a537..0000000000 --- a/Gems/Maestro/Code/Source/Cinematics/CryMovie.rc +++ /dev/null @@ -1,111 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -#ifdef _WIN32 -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(1251) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Russian resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "Amazon.com, Inc." - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." - VALUE "ProductName", "Lumberyard" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // German (Germany) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Gems/SVOGI/preview.png b/Gems/SVOGI/preview.png deleted file mode 100644 index 2f1ed47754..0000000000 --- a/Gems/SVOGI/preview.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d6204c6730e5675791765ca194e9b1cbec282208e280507de830afc2805e5fa -size 41127 diff --git a/cmake/TestImpactFramework/ConsoleFrontendConfig.in b/cmake/TestImpactFramework/ConsoleFrontendConfig.in index 5f3908671e..2371d7fb7f 100644 --- a/cmake/TestImpactFramework/ConsoleFrontendConfig.in +++ b/cmake/TestImpactFramework/ConsoleFrontendConfig.in @@ -50,7 +50,6 @@ include_filter = [ { target = "LmbrCentral.Editor.Tests", policy = "test_interleaved" }, { target = "EditorLib.Tests", policy = "test_interleaved" }, { target = "PhysX.Tests", policy = "test_interleaved" }, -{ target = "ImageProcessing.Tests", policy = "test_interleaved" }, { target = "Atom_RPI.Tests", policy = "test_interleaved" }, { target = "Atom_RHI.Tests", policy = "test_interleaved" }, { target = "AzManipulatorFramework.Tests", policy = "test_interleaved" }, diff --git a/scripts/build/package/Platform/Windows/package_filelists/atom.json b/scripts/build/package/Platform/Windows/package_filelists/atom.json index 885eff8504..f084173cb2 100644 --- a/scripts/build/package/Platform/Windows/package_filelists/atom.json +++ b/scripts/build/package/Platform/Windows/package_filelists/atom.json @@ -93,7 +93,6 @@ "GraphCanvas": "#include", "GraphModel": "#include", "HttpRequestor": "#include", - "ImageProcessing": "#include", "ImGui": "#include", "InAppPurchases": "#include", "LandscapeCanvas": "#include", diff --git a/scripts/commit_validation/commit_validation/pal_allowedlist.txt b/scripts/commit_validation/commit_validation/pal_allowedlist.txt index 278262d59c..e3bf4be52e 100644 --- a/scripts/commit_validation/commit_validation/pal_allowedlist.txt +++ b/scripts/commit_validation/commit_validation/pal_allowedlist.txt @@ -59,7 +59,6 @@ */Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/StandardPluginsConfig.h */Gems/EMotionFX/Code/MCore/Source/Config.h */Gems/GameStateSamples/Code/Include/GameStateSamples/GameStateLocalUserLobby.inl -*/Gems/ImageProcessing/Code/Tests/AtlasBuilderTest.cpp */Gems/PhysX/Code/Source/System/PhysXSystem.cpp */Gems/SaveData/Code/Tests/SaveDataTest.cpp */Gems/WhiteBox/Code/Source/Rendering/Legacy/WhiteBoxLegacyRenderMesh.cpp From dff8de94a5f4c235fc14587c58cfe146640947cb Mon Sep 17 00:00:00 2001 From: greerdv Date: Tue, 11 May 2021 16:57:23 +0100 Subject: [PATCH 106/225] making both colliders and shape colliders check m_simulating in IsPhysicsEnabled --- Gems/PhysX/Code/Source/EditorColliderComponent.cpp | 9 ++++++++- Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp index 2785ab19e1..2cf5835a1f 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp @@ -1057,7 +1057,14 @@ namespace PhysX bool EditorColliderComponent::IsPhysicsEnabled() const { - return m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle; + if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) + { + if (auto* body = m_sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorBodyHandle)) + { + return body->m_simulating; + } + } + return false; } AZ::Aabb EditorColliderComponent::GetAabb() const diff --git a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp index 2c86a18301..b71bd47288 100644 --- a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp @@ -752,7 +752,14 @@ namespace PhysX bool EditorShapeColliderComponent::IsPhysicsEnabled() const { - return m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle; + if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) + { + if (auto* body = m_sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorBodyHandle)) + { + return body->m_simulating; + } + } + return false; } AZ::Aabb EditorShapeColliderComponent::GetAabb() const From 3ebf23211f8631c27ebe388830d471651f65ca66 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 11 May 2021 09:37:34 -0700 Subject: [PATCH 107/225] Update Mutliplayer Autocomponent to add Get/Set behavior context methods for any Network Properties with GenerateEventBindings=true. Known issues: not tested with container types, some jinja whitespace --- .../Source/AutoGen/AutoComponent_Header.jinja | 1 + .../Source/AutoGen/AutoComponent_Source.jinja | 62 +++++++++++++++---- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja index 14a68cddf1..137a544a34 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja @@ -410,6 +410,7 @@ namespace {{ Component.attrib['Namespace'] }} static void Reflect(AZ::ReflectContext* context); static void ReflectToEditContext(AZ::ReflectContext* context); + static void ReflectToBehaviorContext(AZ::ReflectContext* context); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index fb802541ce..6467119b89 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -661,18 +661,42 @@ enum class NetworkProperties {# #} -{% macro DefineNetworkPropertyBehaviorReflection(Component, ReplicateFrom, ReplicateTo, ClassType) %} +{% macro DefineNetworkPropertyBehaviorReflection(Component, ReplicateFrom, ReplicateTo, ClassName) %} {% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %} -{% if (Property.attrib['IsPublic'] | booleanTrue == true) %} -{% if Property.attrib['Container'] == 'Array' %} -->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }}) -{% elif Property.attrib['Container'] == 'Vector' %} -->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }}) -->Event("{{ Property.attrib['Name'] }}GetBack", &{{ ClassType }}Bus::Events::{{ Property.attrib['Name'] }}GetBack) -->Event("{{ Property.attrib['Name'] }}GetSize", &{{ ClassType }}Bus::Events::{{ Property.attrib['Name'] }}GetSize) -{% else %} -->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }}) -{% endif %} +{% if (Property.attrib['IsPublic'] | booleanTrue == true) and (Property.attrib['GenerateEventBindings'] | booleanTrue == true) %} + ->Method("Get{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id) -> {{ Property.attrib['Type'] }} + { + AZ::Entity* entity; + AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id); + + if (entity) + { + if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>()) + { + return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}(); + } + } + + return {{ Property.attrib['Type'] }}(); + }) + ->Method("Set{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id, const {{ Property.attrib['Type'] }}& {{ LowerFirst(Property.attrib['Name']) }}) -> void + { + AZ::Entity* entity; + AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id); + + if (entity) + { + return; + } + + if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>()) + { + if (auto* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController())) + { + controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }}); + } + } + }) {% endif %} {% endcall -%} {% endmacro %} @@ -805,6 +829,7 @@ m_{{ LowerFirst(Service.attrib['Name']) }} = FindComponent<{{ UpperFirst(Service {% endmacro %} {# + #} {% macro DefineNetworkPropertyEditConstruction(Component, ReplicateFrom, ReplicateTo, ClassName) %} {% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %} @@ -1131,6 +1156,7 @@ namespace {{ Component.attrib['Namespace'] }} {{ DefineArchetypePropertyReflection(Component, ComponentBaseName)|indent(16) }}; } ReflectToEditContext(context); + ReflectToBehaviorContext(context); } void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToEditContext(AZ::ReflectContext* context) @@ -1155,6 +1181,20 @@ namespace {{ Component.attrib['Namespace'] }} } } + void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToBehaviorContext(AZ::ReflectContext* context) + { + if (auto* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}") + {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}} +{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Server', ComponentName)|indent(16) -}} +{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Client', ComponentName)|indent(16) -}} +{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Autonomous', ComponentName)|indent(16) -}} +{{ DefineNetworkPropertyBehaviorReflection(Component, 'Autonomous', 'Authority', ComponentName)|indent(16) }} + {{ DefineArchetypePropertyBehaviorReflection(Component, ComponentName)|indent(16) }}; + } + } + void {{ ComponentBaseName }}::{{ ComponentBaseName }}::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC_CE("{{ ComponentName }}Service")); From 26d886792d0b060c20b6c979db8718bcfa25684f Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Tue, 11 May 2021 09:48:11 -0700 Subject: [PATCH 108/225] Initial Python bindings pass for ProjectManager Adds dependency on pybind and interface to call o3de.py functions from c++ --- Code/Tools/ProjectManager/CMakeLists.txt | 15 ++ .../Common/Clang/projectmanager_clang.cmake | 15 ++ .../Common/MSVC/projectmanager_msvc.cmake | 15 ++ .../Platform/Linux/PAL_linux.cmake | 1 + .../Platform/Linux/PAL_linux_files.cmake | 14 ++ .../Platform/Linux/Python_linux.cpp | 42 +++++ .../Platform/Mac/PAL_mac_files.cmake | 14 ++ .../Platform/Mac/Python_mac.cpp | 43 +++++ .../Platform/Windows/PAL_windows.cmake | 5 + .../Platform/Windows/PAL_windows_files.cmake | 14 ++ .../Platform/Windows/Python_windows.cpp | 43 +++++ .../Source/GemCatalog/GemInfo.h | 1 + .../ProjectManager/Source/ProjectInfo.cpp | 24 +++ .../Tools/ProjectManager/Source/ProjectInfo.h | 36 ++++ .../Source/ProjectManagerWindow.cpp | 3 + .../Source/ProjectManagerWindow.h | 3 +- .../ProjectManager/Source/ProjectsHome.cpp | 5 + .../ProjectManager/Source/PythonBindings.cpp | 155 ++++++++++++++++++ .../ProjectManager/Source/PythonBindings.h | 41 +++++ .../Source/PythonBindingsInterface.h | 39 +++++ Code/Tools/ProjectManager/Source/main.cpp | 34 ++-- .../project_manager_files.cmake | 5 + 22 files changed, 553 insertions(+), 14 deletions(-) create mode 100644 Code/Tools/ProjectManager/Platform/Common/Clang/projectmanager_clang.cmake create mode 100644 Code/Tools/ProjectManager/Platform/Common/MSVC/projectmanager_msvc.cmake create mode 100644 Code/Tools/ProjectManager/Platform/Linux/PAL_linux_files.cmake create mode 100644 Code/Tools/ProjectManager/Platform/Linux/Python_linux.cpp create mode 100644 Code/Tools/ProjectManager/Platform/Mac/PAL_mac_files.cmake create mode 100644 Code/Tools/ProjectManager/Platform/Mac/Python_mac.cpp create mode 100644 Code/Tools/ProjectManager/Platform/Windows/PAL_windows_files.cmake create mode 100644 Code/Tools/ProjectManager/Platform/Windows/Python_windows.cpp create mode 100644 Code/Tools/ProjectManager/Source/ProjectInfo.cpp create mode 100644 Code/Tools/ProjectManager/Source/ProjectInfo.h create mode 100644 Code/Tools/ProjectManager/Source/PythonBindings.cpp create mode 100644 Code/Tools/ProjectManager/Source/PythonBindings.h create mode 100644 Code/Tools/ProjectManager/Source/PythonBindingsInterface.h diff --git a/Code/Tools/ProjectManager/CMakeLists.txt b/Code/Tools/ProjectManager/CMakeLists.txt index e4354bac32..e2b5aaf696 100644 --- a/Code/Tools/ProjectManager/CMakeLists.txt +++ b/Code/Tools/ProjectManager/CMakeLists.txt @@ -13,6 +13,13 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() +# This will set python_package_name to whatever the package 'Python' is associated with +ly_get_package_association(Python python_package_name) +if (NOT python_package_name) + set(python_package_name "python-no-package-assocation-found") + message(WARNING "Python was not found in the package assocation list. Did someone call ly_associate_package(xxxxxxx Python) ?") +endif() + ly_add_target( NAME ProjectManager APPLICATION OUTPUT_NAME o3de @@ -22,7 +29,13 @@ ly_add_target( AUTORCC FILES_CMAKE project_manager_files.cmake + Platform/${PAL_PLATFORM_NAME}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake + PLATFORM_INCLUDE_FILES Platform/${PAL_PLATFORM_NAME}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake + Platform/Common/${PAL_TRAIT_COMPILER_ID}/projectmanager_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake + COMPILE_DEFINITIONS + PRIVATE + PY_PACKAGE="${python_package_name}" INCLUDE_DIRECTORIES PUBLIC . @@ -34,6 +47,8 @@ ly_add_target( 3rdParty::Qt::Core 3rdParty::Qt::Concurrent 3rdParty::Qt::Widgets + 3rdParty::Python + 3rdParty::pybind11 AZ::AzCore AZ::AzFramework AZ::AzToolsFramework diff --git a/Code/Tools/ProjectManager/Platform/Common/Clang/projectmanager_clang.cmake b/Code/Tools/ProjectManager/Platform/Common/Clang/projectmanager_clang.cmake new file mode 100644 index 0000000000..fb85a6cf2a --- /dev/null +++ b/Code/Tools/ProjectManager/Platform/Common/Clang/projectmanager_clang.cmake @@ -0,0 +1,15 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_COMPILE_OPTIONS + PRIVATE + -fexceptions # The macro PYBIND11_EMBEDDED_MODULE uses a try catch block +) diff --git a/Code/Tools/ProjectManager/Platform/Common/MSVC/projectmanager_msvc.cmake b/Code/Tools/ProjectManager/Platform/Common/MSVC/projectmanager_msvc.cmake new file mode 100644 index 0000000000..669f14eae4 --- /dev/null +++ b/Code/Tools/ProjectManager/Platform/Common/MSVC/projectmanager_msvc.cmake @@ -0,0 +1,15 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_COMPILE_OPTIONS + PRIVATE + /EHsc # The macro PYBIND11_EMBEDDED_MODULE uses a try catch block +) diff --git a/Code/Tools/ProjectManager/Platform/Linux/PAL_linux.cmake b/Code/Tools/ProjectManager/Platform/Linux/PAL_linux.cmake index 4d5680a30d..f5b9ea77a2 100644 --- a/Code/Tools/ProjectManager/Platform/Linux/PAL_linux.cmake +++ b/Code/Tools/ProjectManager/Platform/Linux/PAL_linux.cmake @@ -8,3 +8,4 @@ # remove or modify any license notices. This file is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # + diff --git a/Code/Tools/ProjectManager/Platform/Linux/PAL_linux_files.cmake b/Code/Tools/ProjectManager/Platform/Linux/PAL_linux_files.cmake new file mode 100644 index 0000000000..a07534ee39 --- /dev/null +++ b/Code/Tools/ProjectManager/Platform/Linux/PAL_linux_files.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(FILES + Python_linux.cpp +) diff --git a/Code/Tools/ProjectManager/Platform/Linux/Python_linux.cpp b/Code/Tools/ProjectManager/Platform/Linux/Python_linux.cpp new file mode 100644 index 0000000000..64ab9c9ca7 --- /dev/null +++ b/Code/Tools/ProjectManager/Platform/Linux/Python_linux.cpp @@ -0,0 +1,42 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include +#include + +namespace Platform +{ + extern bool InsertPythonLibraryPath(AZStd::unordered_set& paths, const char* pythonPackage, const char* engineRoot, const char* subPath); + + bool InsertPythonBinaryLibraryPaths(AZStd::unordered_set& paths, const char* pythonPackage, const char* engineRoot) + { + bool succeeded = true; + + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/python/lib"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/python/lib/python3.7/lib-dynload"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/python/lib/python3.7"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/python/lib/python3.7/site-packages"); + return succeeded; + } + + AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot) + { + // append lib path to Python paths + AZ::IO::FixedMaxPath libPath = engineRoot; + libPath /= AZ::IO::FixedMaxPathString::format("python/runtime/%s/python", pythonPackage); + libPath = libPath.LexicallyNormal(); + return libPath.String(); + } +} diff --git a/Code/Tools/ProjectManager/Platform/Mac/PAL_mac_files.cmake b/Code/Tools/ProjectManager/Platform/Mac/PAL_mac_files.cmake new file mode 100644 index 0000000000..83124b6315 --- /dev/null +++ b/Code/Tools/ProjectManager/Platform/Mac/PAL_mac_files.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(FILES + Python_mac.cpp +) diff --git a/Code/Tools/ProjectManager/Platform/Mac/Python_mac.cpp b/Code/Tools/ProjectManager/Platform/Mac/Python_mac.cpp new file mode 100644 index 0000000000..d3d55d6d5d --- /dev/null +++ b/Code/Tools/ProjectManager/Platform/Mac/Python_mac.cpp @@ -0,0 +1,43 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include +#include + +namespace Platform +{ + extern bool InsertPythonLibraryPath(AZStd::unordered_set& paths, const char* pythonPackage, const char* engineRoot, const char* subPath); + + bool InsertPythonBinaryLibraryPaths(AZStd::unordered_set& paths, const char* pythonPackage, const char* engineRoot) + { + bool succeeded = true; + + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/Python.framework/Versions/3.7/lib"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/Python.framework/Versions/3.7/lib/python3.7/lib-dynload"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/Python.framework/Versions/3.7/lib/python3.7"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/Python.framework/Versions/3.7/lib/python3.7/site-packages"); + + return succeeded; + } + + AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot) + { + // append lib path to Python paths + AZ::IO::FixedMaxPath libPath = engineRoot; + libPath /= AZ::IO::FixedMaxPathString::format("python/runtime/%s/Python.framework/Versions/3.7", pythonPackage); + libPath = libPath.LexicallyNormal(); + return libPath.String(); + } +} diff --git a/Code/Tools/ProjectManager/Platform/Windows/PAL_windows.cmake b/Code/Tools/ProjectManager/Platform/Windows/PAL_windows.cmake index 4d5680a30d..dfcc107f4d 100644 --- a/Code/Tools/ProjectManager/Platform/Windows/PAL_windows.cmake +++ b/Code/Tools/ProjectManager/Platform/Windows/PAL_windows.cmake @@ -8,3 +8,8 @@ # remove or modify any license notices. This file is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # + +set(LY_COMPILE_DEFINITIONS + PRIVATE + HAVE_ROUND # defined for Windows since http://p-nand-q.com/python/building-python-33-with-vs2013.html +) diff --git a/Code/Tools/ProjectManager/Platform/Windows/PAL_windows_files.cmake b/Code/Tools/ProjectManager/Platform/Windows/PAL_windows_files.cmake new file mode 100644 index 0000000000..de083bc91a --- /dev/null +++ b/Code/Tools/ProjectManager/Platform/Windows/PAL_windows_files.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(FILES + Python_windows.cpp +) diff --git a/Code/Tools/ProjectManager/Platform/Windows/Python_windows.cpp b/Code/Tools/ProjectManager/Platform/Windows/Python_windows.cpp new file mode 100644 index 0000000000..2ea143c63d --- /dev/null +++ b/Code/Tools/ProjectManager/Platform/Windows/Python_windows.cpp @@ -0,0 +1,43 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include +#include + +namespace Platform +{ + extern bool InsertPythonLibraryPath(AZStd::unordered_set& paths, const char* pythonPackage, const char* engineRoot, const char* subPath); + + bool InsertPythonBinaryLibraryPaths(AZStd::unordered_set& paths, const char* pythonPackage, const char* engineRoot) + { + bool succeeded = true; + + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/python"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/python/lib"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/python/lib/site-packages"); + succeeded = succeeded && InsertPythonLibraryPath(paths, pythonPackage, engineRoot, "python/runtime/%s/python/DLLs"); + + return succeeded; + } + + AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot) + { + // append lib path to Python paths + AZ::IO::FixedMaxPath libPath = engineRoot; + libPath /= AZ::IO::FixedMaxPathString::format("python/runtime/%s/python", pythonPackage); + libPath = libPath.LexicallyNormal(); + return libPath.String(); + } +} diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h index 8c5040eb84..4766187d2a 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h @@ -37,6 +37,7 @@ namespace O3DE::ProjectManager GemInfo(const QString& name, const QString& creator, const QString& summary, Platforms platforms, bool isAdded); + QString m_path; QString m_name; QString m_displayName; AZ::Uuid m_uuid; diff --git a/Code/Tools/ProjectManager/Source/ProjectInfo.cpp b/Code/Tools/ProjectManager/Source/ProjectInfo.cpp new file mode 100644 index 0000000000..b3bdb87224 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectInfo.cpp @@ -0,0 +1,24 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include "ProjectInfo.h" + +namespace O3DE::ProjectManager +{ + ProjectInfo::ProjectInfo(const QString& path, const QString& projectName, const QString& productName, const AZ::Uuid projectId) + : m_path(path) + , m_projectName(projectName) + , m_productName(productName) + , m_projectId(projectId) + { + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectInfo.h b/Code/Tools/ProjectManager/Source/ProjectInfo.h new file mode 100644 index 0000000000..e5dca97d5e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectInfo.h @@ -0,0 +1,36 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#endif + +namespace O3DE::ProjectManager +{ + class ProjectInfo + { + public: + ProjectInfo() = default; + ProjectInfo(const QString& path, const QString& projectName, const QString& productName, const AZ::Uuid projectId); + + // from o3de_manifest.json and o3de_projects.json + QString m_path; + + // from project.json + QString m_projectName; + QString m_productName; + AZ::Uuid m_projectId; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp index 12980fc836..c86ebeee86 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp @@ -28,6 +28,8 @@ namespace O3DE::ProjectManager { m_ui->setupUi(this); + m_pythonBindings = AZStd::make_unique(engineRootPath); + ConnectSlotsAndSignals(); QDir rootDir = QString::fromUtf8(engineRootPath.Native().data(), aznumeric_cast(engineRootPath.Native().size())); @@ -44,6 +46,7 @@ namespace O3DE::ProjectManager ProjectManagerWindow::~ProjectManagerWindow() { + m_pythonBindings.reset(); } void ProjectManagerWindow::BuildScreens() diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.h b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.h index 9e5761fbd2..6a17c4464c 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.h +++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.h @@ -17,7 +17,7 @@ #include #include -#include +#include #endif namespace Ui @@ -52,6 +52,7 @@ namespace O3DE::ProjectManager private: QScopedPointer m_ui; + AZStd::unique_ptr m_pythonBindings; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsHome.cpp b/Code/Tools/ProjectManager/Source/ProjectsHome.cpp index 1a451f3d10..a45b923946 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsHome.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectsHome.cpp @@ -14,6 +14,8 @@ #include +#include + namespace O3DE::ProjectManager { ProjectsHome::ProjectsHome(ProjectManagerWindow* window) @@ -23,6 +25,9 @@ namespace O3DE::ProjectManager m_ui->setupUi(this); ConnectSlotsAndSignals(); + + // example of how to get the current project name + ProjectInfo currentProject = PythonBindingsInterface::Get()->GetCurrentProject(); } ProjectsHome::~ProjectsHome() diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp new file mode 100644 index 0000000000..cc14e9e4de --- /dev/null +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -0,0 +1,155 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include + +// Qt defines slots, which interferes with the use here. +#pragma push_macro("slots") +#undef slots +#include +#include +#include +#include +#include +#pragma pop_macro("slots") + +#include +#include +#include +#include + +namespace Platform +{ + bool InsertPythonLibraryPath( + AZStd::unordered_set& paths, const char* pythonPackage, const char* engineRoot, const char* subPath) + { + // append lib path to Python paths + AZ::IO::FixedMaxPath libPath = engineRoot; + libPath /= AZ::IO::FixedMaxPathString::format(subPath, pythonPackage); + libPath = libPath.LexicallyNormal(); + if (AZ::IO::SystemFile::Exists(libPath.c_str())) + { + paths.insert(libPath.c_str()); + return true; + } + + AZ_Warning("python", false, "Python library path should exist. path:%s", libPath.c_str()); + return false; + } + + // Implemented in each different platform's PAL implentation files, as it differs per platform. + AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot); + +} // namespace Platform + +namespace O3DE::ProjectManager +{ + PythonBindings::PythonBindings(const AZ::IO::PathView& enginePath) + : m_enginePath(enginePath) + { + StartPython(); + } + + PythonBindings::~PythonBindings() + { + StopPython(); + } + + bool PythonBindings::StartPython() + { + if (Py_IsInitialized()) + { + AZ_Warning("python", false, "Python is already active"); + return false; + } + + // set PYTHON_HOME + AZStd::string pyBasePath = Platform::GetPythonHomePath(PY_PACKAGE, m_enginePath.c_str()); + if (!AZ::IO::SystemFile::Exists(pyBasePath.c_str())) + { + AZ_Warning("python", false, "Python home path must exist. path:%s", pyBasePath.c_str()); + return false; + } + + AZStd::wstring pyHomePath; + AZStd::to_wstring(pyHomePath, pyBasePath); + Py_SetPythonHome(pyHomePath.c_str()); + + // display basic Python information + AZ_TracePrintf("python", "Py_GetVersion=%s \n", Py_GetVersion()); + AZ_TracePrintf("python", "Py_GetPath=%ls \n", Py_GetPath()); + AZ_TracePrintf("python", "Py_GetExecPrefix=%ls \n", Py_GetExecPrefix()); + AZ_TracePrintf("python", "Py_GetProgramFullPath=%ls \n", Py_GetProgramFullPath()); + + try + { + // ignore system location for sites site-packages + Py_IsolatedFlag = 1; // -I - Also sets Py_NoUserSiteDirectory. If removed PyNoUserSiteDirectory should be set. + Py_IgnoreEnvironmentFlag = 1; // -E + + const bool initializeSignalHandlers = true; + pybind11::initialize_interpreter(initializeSignalHandlers); + + // Acquire GIL before calling Python code + AZStd::lock_guard lock(m_lock); + pybind11::gil_scoped_acquire acquire; + + // Setup sys.path + int result = PyRun_SimpleString("import sys"); + AZ_Warning("ProjectManagerWindow", result != -1, "Import sys failed"); + result = PyRun_SimpleString(AZStd::string::format("sys.path.append('%s')", m_enginePath.c_str()).c_str()); + AZ_Warning("ProjectManagerWindow", result != -1, "Append to sys path failed"); + + return result == 0 && !PyErr_Occurred(); + } catch ([[maybe_unused]] const std::exception& e) + { + AZ_Warning("python", false, "Py_Initialize() failed with %s", e.what()); + return false; + } + } + + bool PythonBindings::StopPython() + { + if (Py_IsInitialized()) + { + pybind11::finalize_interpreter(); + } + else + { + AZ_Warning("python", false, "Did not finalize since Py_IsInitialized() was false"); + } + return !PyErr_Occurred(); + } + + void PythonBindings::ExecuteWithLock(AZStd::function executionCallback) + { + AZStd::lock_guard lock(m_lock); + pybind11::gil_scoped_release release; + pybind11::gil_scoped_acquire acquire; + executionCallback(); + } + + ProjectInfo PythonBindings::GetCurrentProject() + { + ProjectInfo project; + + ExecuteWithLock([&] { + auto currentProjectTool = pybind11::module::import("cmake.Tools.current_project"); + auto getCurrentProject = currentProjectTool.attr("get_current_project"); + auto currentProject = getCurrentProject(m_enginePath.c_str()); + + project.m_path = currentProject.cast().c_str(); + }); + + return project; + } +} diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.h b/Code/Tools/ProjectManager/Source/PythonBindings.h new file mode 100644 index 0000000000..ac55fffe80 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/PythonBindings.h @@ -0,0 +1,41 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ +#pragma once + +#include +#include +#include + +namespace O3DE::ProjectManager +{ + class PythonBindings + : public PythonBindingsInterface::Registrar + { + public: + PythonBindings() = default; + PythonBindings(const AZ::IO::PathView& enginePath); + ~PythonBindings() override; + + // PythonBindings overrides + ProjectInfo GetCurrentProject() override; + + private: + AZ_DISABLE_COPY_MOVE(PythonBindings); + + void ExecuteWithLock(AZStd::function executionCallback); + bool StartPython(); + bool StopPython(); + + AZ::IO::FixedMaxPath m_enginePath; + AZStd::recursive_mutex m_lock; + }; +} diff --git a/Code/Tools/ProjectManager/Source/PythonBindingsInterface.h b/Code/Tools/ProjectManager/Source/PythonBindingsInterface.h new file mode 100644 index 0000000000..78c3625415 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/PythonBindingsInterface.h @@ -0,0 +1,39 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace O3DE::ProjectManager +{ + //! Interface used to interact with the o3de cli python functions + class IPythonBindings + { + public: + AZ_RTTI(O3DE::ProjectManager::IPythonBindings, "{C2B72CA4-56A9-4601-A584-3B40E83AA17C}"); + AZ_DISABLE_COPY_MOVE(IPythonBindings); + + IPythonBindings() = default; + virtual ~IPythonBindings() = default; + + //! Get the current project + virtual ProjectInfo GetCurrentProject() = 0; + }; + + using PythonBindingsInterface = AZ::Interface; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/main.cpp b/Code/Tools/ProjectManager/Source/main.cpp index 149da79491..3d8bb71a0c 100644 --- a/Code/Tools/ProjectManager/Source/main.cpp +++ b/Code/Tools/ProjectManager/Source/main.cpp @@ -35,21 +35,29 @@ int main(int argc, char* argv[]) QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware); - QApplication app(argc, argv); - // Need to use settings registry to get EngineRootFolder - AZ::IO::FixedMaxPath engineRootPath; + AZ::AllocatorInstance::Create(); + int runSuccess = 0; { - AZ::ComponentApplication componentApplication; - auto settingsRegistry = AZ::SettingsRegistry::Get(); - settingsRegistry->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder); + QApplication app(argc, argv); + + // Need to use settings registry to get EngineRootFolder + AZ::IO::FixedMaxPath engineRootPath; + { + AZ::ComponentApplication componentApplication; + auto settingsRegistry = AZ::SettingsRegistry::Get(); + settingsRegistry->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder); + } + + AzQtComponents::StyleManager styleManager(&app); + styleManager.initialize(&app, engineRootPath); + + O3DE::ProjectManager::ProjectManagerWindow window(nullptr, engineRootPath); + window.show(); + + runSuccess = app.exec(); } + AZ::AllocatorInstance::Destroy(); - AzQtComponents::StyleManager styleManager(&app); - styleManager.initialize(&app, engineRootPath); - - O3DE::ProjectManager::ProjectManagerWindow window(nullptr, engineRootPath); - window.show(); - - return app.exec(); + return runSuccess; } diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 073e220810..da0b7cdec7 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -19,9 +19,14 @@ set(FILES Source/FirstTimeUse.h Source/FirstTimeUse.cpp Source/FirstTimeUse.ui + Source/ProjectInfo.h + Source/ProjectInfo.cpp Source/ProjectManagerWindow.h Source/ProjectManagerWindow.cpp Source/ProjectManagerWindow.ui + Source/PythonBindings.h + Source/PythonBindings.cpp + Source/PythonBindingsInterface.h Source/NewProjectSettings.h Source/NewProjectSettings.cpp Source/NewProjectSettings.ui From 1cbcfa75e89de3f27e61eb19209f2be654e08ac0 Mon Sep 17 00:00:00 2001 From: Nicholas Lawson <70027408+lawsonamzn@users.noreply.github.com> Date: Tue, 11 May 2021 10:40:31 -0700 Subject: [PATCH 109/225] Fixes a crash on mac in the SourceFileRelocatorTest (#688) Note that this test should crash on windows too but its a read-beyond-the-edge-of-array memory issue which could be intermittent. --- .../native/AssetManager/SourceFileRelocator.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Code/Tools/AssetProcessor/native/AssetManager/SourceFileRelocator.cpp b/Code/Tools/AssetProcessor/native/AssetManager/SourceFileRelocator.cpp index a242c6377c..49c7ef7f20 100644 --- a/Code/Tools/AssetProcessor/native/AssetManager/SourceFileRelocator.cpp +++ b/Code/Tools/AssetProcessor/native/AssetManager/SourceFileRelocator.cpp @@ -190,9 +190,8 @@ Please note that only those seed files will get updated that are active for your void SourceFileRelocator::HandleMetaDataFiles(QStringList pathMatches, QHash& sourceIndexMap, const ScanFolderInfo* scanFolderInfo, SourceFileRelocationContainer& metadataFiles, bool excludeMetaDataFiles) const { QSet metaDataFileEntries; - for (QStringList::Iterator fileIter = pathMatches.begin(); fileIter != pathMatches.end();) + for (QString file : pathMatches) { - QString file = *fileIter; for (int idx = 0; idx < m_platformConfig->MetaDataFileTypesCount(); idx++) { QPair metaInfo = m_platformConfig->GetMetaDataFileTypeAt(idx); @@ -203,8 +202,7 @@ Please note that only those seed files will get updated that are active for your { AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Metadata file %s will be ignored because --excludeMetadataFiles was specified in the command line.\n", file.toUtf8().constData()); - fileIter = pathMatches.erase(fileIter); - continue; + break; // don't check it against other metafile entries, we've already ascertained its a metafile. } else { @@ -263,8 +261,6 @@ Please note that only those seed files will get updated that are active for your } } } - - fileIter++; } } From 703f9deee0f01c0d00ff636ee8ce18d2c9a3646c Mon Sep 17 00:00:00 2001 From: Aristo7 <5432499+Aristo7@users.noreply.github.com> Date: Tue, 11 May 2021 12:43:30 -0500 Subject: [PATCH 110/225] Testing jenkins break --- Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt index 33873e0dfa..06b4e2a7fe 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt @@ -104,5 +104,14 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) Gem::ImguiAtom Gem::AtomFont Gem::AtomToolsFramework.Editor + + # Testing jenkins issue + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_Vulkan.Builders + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_DX12.Builders + Gem::Atom_RHI_Null.Private + Gem::Atom_RHI_Null.Builders + Gem::Atom_RHI_Metal.Builders ) endif() From 9d244b6e2be08732922cd519b370894e44438c07 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Tue, 11 May 2021 12:50:38 -0500 Subject: [PATCH 111/225] Removing test dependency from EditorTests --- AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 11ee414b36..3124f1048a 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -366,7 +366,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ Legacy::Editor AZ::AssetProcessor AutomatedTesting.Assets - 3rdParty::Qt::Test COMPONENT Editor ) From 4a5d7730347d09e8c21833a4089f7ae6391ab12f Mon Sep 17 00:00:00 2001 From: Terry Michaels <81711813+tjmichaels@users.noreply.github.com> Date: Tue, 11 May 2021 12:55:00 -0500 Subject: [PATCH 112/225] Removed environment and debug mode buttons --- Code/Sandbox/Editor/MainWindow.cpp | 133 ------------------------- Code/Sandbox/Editor/MainWindow.h | 5 - Code/Sandbox/Editor/ToolbarManager.cpp | 4 - 3 files changed, 142 deletions(-) diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index b1d85c2999..e9b27ee9b8 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -695,8 +695,6 @@ void MainWindow::InitActions() am->AddAction(ID_TOOLBAR_WIDGET_REDO, QString()); am->AddAction(ID_TOOLBAR_WIDGET_SNAP_ANGLE, QString()); am->AddAction(ID_TOOLBAR_WIDGET_SNAP_GRID, QString()); - am->AddAction(ID_TOOLBAR_WIDGET_ENVIRONMENT_MODE, QString()); - am->AddAction(ID_TOOLBAR_WIDGET_DEBUG_MODE, QString()); am->AddAction(ID_TOOLBAR_WIDGET_SPACER_RIGHT, QString()); // File actions @@ -1253,44 +1251,6 @@ QToolButton* MainWindow::CreateUndoRedoButton(int command) return button; } -QToolButton* MainWindow::CreateEnvironmentModeButton() -{ - QToolButton* environmentModeButton = new QToolButton(this); - environmentModeButton->setAutoRaise(true); - environmentModeButton->setPopupMode(QToolButton::InstantPopup); - environmentModeButton->setIcon(Style::icon("Environment")); - environmentModeButton->setStatusTip(tr("Select from a variety of environment mode options")); - environmentModeButton->setToolTip(tr("Environment modes")); - - CVarMenu* environmentModeMenu = new CVarMenu(this); - connect(environmentModeMenu, &QMenu::aboutToShow, [this, environmentModeMenu]() - { - InitEnvironmentModeMenu(environmentModeMenu); - }); - environmentModeButton->setMenu(environmentModeMenu); - - return environmentModeButton; -} - -QToolButton* MainWindow::CreateDebugModeButton() -{ - QToolButton* debugModeButton = new QToolButton(this); - debugModeButton->setAutoRaise(true); - debugModeButton->setPopupMode(QToolButton::InstantPopup); - debugModeButton->setIcon(Style::icon("Debugging")); - debugModeButton->setStatusTip(tr("Select from a variety of debug/view mode options")); - debugModeButton->setToolTip(tr("Debug modes")); - - CVarMenu* debugModeMenu = new CVarMenu(this); - connect(debugModeMenu, &QMenu::aboutToShow, [this, debugModeMenu]() - { - InitDebugModeMenu(debugModeMenu); - }); - debugModeButton->setMenu(debugModeMenu); - - return debugModeButton; -} - QWidget* MainWindow::CreateSpacerRightWidget() { QWidget* spacer = new QWidget(this); @@ -1299,93 +1259,6 @@ QWidget* MainWindow::CreateSpacerRightWidget() return spacer; } -void MainWindow::InitEnvironmentModeMenu(CVarMenu* environmentModeMenu) -{ - environmentModeMenu->clear(); - environmentModeMenu->AddCVarToggleItem({ "e_Fog", tr("Hide Global Fog"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "r_FogVolumes", tr("Hide Fog Volumes"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_Clouds", tr("Hide Clouds"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_Wind", tr("Hide Wind"), 0, 1 }); - environmentModeMenu->AddSeparator(); - environmentModeMenu->AddCVarToggleItem({ "e_Sun", tr("Hide Sun"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_Skybox", tr("Hide Skybox"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "r_SSReflections", tr("Hide Screen Space Reflection"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_Shadows", tr("Hide Shadows"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "r_TransparentPasses", tr("Hide Transparent Objects"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "r_ssdo", tr("Hide Screen Space Directional Occlusion"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_DynamicLights", tr("Hide All Dynamic Lights"), 0, 1 }); - environmentModeMenu->AddSeparator(); - environmentModeMenu->AddCVarToggleItem({ "e_Entities", tr("Hide Entities"), 0, 1 }); - environmentModeMenu->AddSeparator(); - environmentModeMenu->AddCVarToggleItem({ "e_Vegetation", tr("Hide Vegetation"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_Terrain", tr("Hide Terrain"), 0, 1 }); - environmentModeMenu->AddSeparator(); - environmentModeMenu->AddCVarToggleItem({ "e_Particles", tr("Hide Particles"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_Flares", tr("Hide Flares"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_Decals", tr("Hide Decals"), 0, 1 }); - environmentModeMenu->AddSeparator(); - environmentModeMenu->AddCVarToggleItem({ "e_WaterOcean", tr("Hide Ocean Water (for legacy)"), 0, 1 }); - environmentModeMenu->AddCVarToggleItem({ "e_WaterVolumes", tr("Hide Water Volumes"), 0, 1 }); - environmentModeMenu->AddSeparator(); - environmentModeMenu->AddCVarToggleItem({ "e_BBoxes", tr("Hide BBoxes"), 0, 1 }); - environmentModeMenu->AddSeparator(); - environmentModeMenu->AddResetCVarsItem(); -} - -void MainWindow::InitDebugModeMenu(CVarMenu* debugModeMenu) -{ - debugModeMenu->clear(); - debugModeMenu->AddCVarValuesItem("r_DebugGBuffer", tr("GBuffers"), - { - {tr("Full Shading Mode (Default)"), 0}, - {tr("Normal Visualization"), 1}, - {tr("Smoothness"), 2}, - {tr("Reflectance"), 3}, - {tr("Albedo"), 4}, - {tr("Lighting Model"), 5}, - {tr("Translucency"), 6}, - {tr("Sun Self Shadowing"), 7}, - {tr("Subsurface Scattering"), 8}, - {tr("Specular Validation Overlay"), 9} - }, 0); - debugModeMenu->AddSeparator(); - debugModeMenu->AddCVarValuesItem("r_Stats", tr("Profiling"), - { - {tr("Frame Timing"), 1}, - {tr("Object Timing"), 3}, - {tr("Instance Draw Calls"), 6}, - }, 0); - debugModeMenu->AddSeparator(); - debugModeMenu->AddUniqueCVarsItem(tr("Wireframe"), - { - {"r_wireframe", tr("Wireframe Rendering Mode"), 1, 0}, - {"r_showlines", tr("Wireframe Overlay"), 1, 0} - }), - debugModeMenu->AddCVarValuesItem("e_debugdraw", tr("Art Info"), - { - {tr("Texture Memory Usage"), 4}, - {tr("Renderable Material Count"), 5}, - {tr("LOD Vertex Count"), 22} - }, 0); - - debugModeMenu->AddSeparator(); - debugModeMenu->AddCVarValuesItem("e_defaultmaterial", tr("Default Material on all Objects"), - { - {tr("Gray Material with Normal Maps"), 1}, - }, 0); - - debugModeMenu->AddCVarValuesItem("r_DeferredShadingTiledDebugAlbedo", tr("Debug Visualization of Deferred Lighting"), - { - {tr("White Albedo"), 1}, - }, 0); - - debugModeMenu->AddCVarToggleItem({ "r_ShowTangents", tr("Show Tangents"), 1, 0 }); - debugModeMenu->AddCVarToggleItem({ "p_draw_helpers", tr("Show Collision Shapes (Proxy)"), 1, 0 }); - - debugModeMenu->AddSeparator(); - debugModeMenu->AddResetCVarsItem(); -} - UndoRedoToolButton::UndoRedoToolButton(QWidget* parent) : QToolButton(parent) { @@ -2150,12 +2023,6 @@ QWidget* MainWindow::CreateToolbarWidget(int actionId) case ID_TOOLBAR_WIDGET_SNAP_ANGLE: w = CreateSnapToAngleWidget(); break; - case ID_TOOLBAR_WIDGET_ENVIRONMENT_MODE: - w = CreateEnvironmentModeButton(); - break; - case ID_TOOLBAR_WIDGET_DEBUG_MODE: - w = CreateDebugModeButton(); - break; case ID_TOOLBAR_WIDGET_SPACER_RIGHT: w = CreateSpacerRightWidget(); break; diff --git a/Code/Sandbox/Editor/MainWindow.h b/Code/Sandbox/Editor/MainWindow.h index ca8cc11677..ab60b0e0d4 100644 --- a/Code/Sandbox/Editor/MainWindow.h +++ b/Code/Sandbox/Editor/MainWindow.h @@ -208,11 +208,6 @@ private: QToolButton* CreateUndoRedoButton(int command); - QToolButton* CreateEnvironmentModeButton(); - QToolButton* CreateDebugModeButton(); - void InitEnvironmentModeMenu(CVarMenu* environmentModeMenu); - void InitDebugModeMenu(CVarMenu* debugModeMenu); - private Q_SLOTS: void ShowKeyboardCustomization(); void ExportKeyboardShortcuts(); diff --git a/Code/Sandbox/Editor/ToolbarManager.cpp b/Code/Sandbox/Editor/ToolbarManager.cpp index bbb3ef6790..5aa039189d 100644 --- a/Code/Sandbox/Editor/ToolbarManager.cpp +++ b/Code/Sandbox/Editor/ToolbarManager.cpp @@ -595,10 +595,6 @@ AmazonToolbar ToolbarManager::GetEditModeToolbar() const t.AddAction(ID_TOOLBAR_WIDGET_SNAP_GRID, ORIGINAL_TOOLBAR_VERSION); t.AddAction(ID_TOOLBAR_WIDGET_SNAP_ANGLE, ORIGINAL_TOOLBAR_VERSION); - t.AddAction(ID_TOOLBAR_SEPARATOR, ORIGINAL_TOOLBAR_VERSION); - t.AddAction(ID_TOOLBAR_WIDGET_ENVIRONMENT_MODE, ORIGINAL_TOOLBAR_VERSION); - t.AddAction(ID_TOOLBAR_WIDGET_DEBUG_MODE, ORIGINAL_TOOLBAR_VERSION); - return t; } From b11234097d8cc4741ef3e786a6823966633eb8ae Mon Sep 17 00:00:00 2001 From: srikappa Date: Tue, 11 May 2021 11:30:16 -0700 Subject: [PATCH 113/225] Fixed a capitalization issue --- .../Prefab/Instance/InstanceToTemplatePropagator.cpp | 2 +- .../AzToolsFramework/Prefab/PrefabPublicHandler.cpp | 4 ++-- .../AzToolsFramework/Prefab/PrefabPublicHandler.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp index 6f812df89b..a21c5301aa 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp @@ -282,7 +282,7 @@ namespace AzToolsFramework /* If the original allocator the patches were created with gets destroyed, then the patches would become garbage in the linkDom. Since we cannot guarantee the lifecycle of the patch allocators, we are doing a copy of the patches here to - associate them with the linkDom's allocator. This is a limitation with rapidjson. + associate them with the linkDom's allocator. */ PrefabDom patchesCopy; patchesCopy.CopyFrom(patches, linkDom.GetAllocator()); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index fee455b710..02fa2d14fc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -295,7 +295,7 @@ namespace AzToolsFramework void PrefabPublicHandler::CreateLink( const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId, - UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool IsUndoRedoSupportNeeded) + UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool isUndoRedoSupportNeeded) { AZ::EntityId containerEntityId = sourceInstance.GetContainerEntityId(); AZ::Entity* containerEntity = GetEntityById(containerEntityId); @@ -322,7 +322,7 @@ namespace AzToolsFramework m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId); LinkId linkId; - if (IsUndoRedoSupportNeeded) + if (isUndoRedoSupportNeeded) { linkId = PrefabUndoHelpers::CreateLink( sourceInstance.GetTemplateId(), targetTemplateId, AZStd::move(patch), sourceInstance.GetInstanceAlias(), undoBatch); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 31937cf028..138bc84aa0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -77,11 +77,11 @@ namespace AzToolsFramework * \param targetInstance The id of the target template. * \param undoBatch The undo batch to set as parent for this create link action. * \param commonRootEntityId The id of the entity that the source instance should be parented under. - * \param IsUndoRedoSupportNeeded The flag indicating whether the link should be created with undo/redo support or not. + * \param isUndoRedoSupportNeeded The flag indicating whether the link should be created with undo/redo support or not. */ void CreateLink( const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId, - UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool IsUndoRedoSupportNeeded = true); + UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool isUndoRedoSupportNeeded = true); /** * Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId. From 6b72646b614b0daafd0f926b38e336cf177f52b9 Mon Sep 17 00:00:00 2001 From: sconel Date: Tue, 11 May 2021 11:42:35 -0700 Subject: [PATCH 114/225] Updated PrefabBuilder to not error when prefabs are present at end --- .../PrefabBuilder/PrefabBuilderComponent.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp index 2b97b8a63d..a95ec60d61 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp @@ -261,21 +261,15 @@ namespace AZ::Prefab if (context.HasCompletedSuccessfully()) { AZ_TracePrintf("Prefab Builder", "Finalizing products.\n"); - if (!context.HasPrefabs()) + + if (StoreProducts(tempDirPath, context.GetProcessedObjects(), + context.GetRegisteredProductAssetDependencies(), jobProducts)) { - if (StoreProducts(tempDirPath, context.GetProcessedObjects(), - context.GetRegisteredProductAssetDependencies(), jobProducts)) - { - return true; - } - else - { - AZ_Error("Prefab Builder", false, "One or more objects couldn't be committed to disk."); - } + return true; } else { - AZ_Error("Prefab Builder", false, "After processing there were still Prefabs left."); + AZ_Error("Prefab Builder", false, "One or more objects couldn't be committed to disk."); } } else From 7ff5c0e10526a1297e5248f8819c8e5f61604c9d Mon Sep 17 00:00:00 2001 From: nvsickle Date: Tue, 11 May 2021 12:18:04 -0700 Subject: [PATCH 115/225] Add multiline spacing and GetTextSize to Atom Font --- Code/CryEngine/CryCommon/IFont.h | 4 + .../AzFramework/Font/FontInterface.h | 4 + .../AtomLyIntegration/AtomFont/FFont.h | 14 +++ .../AtomFont/Code/Source/FFont.cpp | 93 ++++++++++++------- 4 files changed, 83 insertions(+), 32 deletions(-) diff --git a/Code/CryEngine/CryCommon/IFont.h b/Code/CryEngine/CryCommon/IFont.h index c8634fa854..7d573308aa 100644 --- a/Code/CryEngine/CryCommon/IFont.h +++ b/Code/CryEngine/CryCommon/IFont.h @@ -150,6 +150,7 @@ struct STextDrawContext Vec2 m_size; Vec2i m_requestSize; float m_widthScale; + float m_lineSpacing; float m_clipX; float m_clipY; @@ -180,6 +181,7 @@ struct STextDrawContext , m_size(16.0f, 16.0f) , m_requestSize(static_cast(m_size.x), static_cast(m_size.y)) , m_widthScale(1.0f) + , m_lineSpacing(0.f) , m_clipX(0) , m_clipY(0) , m_clipWidth(0) @@ -214,11 +216,13 @@ struct STextDrawContext void SetTransform(const Matrix34& transform) { m_transform = transform; } void SetBaseState(int baseState) { m_baseState = baseState; } void SetOverrideViewProjMatrices(bool overrideViewProjMatrices) { m_overrideViewProjMatrices = overrideViewProjMatrices; } + void SetLineSpacing(float lineSpacing) { m_lineSpacing = lineSpacing; } float GetCharWidth() const { return m_size.x; } float GetCharHeight() const { return m_size.y; } float GetCharWidthScale() const { return m_widthScale; } int GetFlags() const { return m_drawTextFlags; } + float GetLineSpacing() const { return m_lineSpacing; } bool IsColorOverridden() const { return m_colorOverride.a != 0; } }; diff --git a/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h b/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h index 7c5bcce6d6..48fa5bc2d2 100644 --- a/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h +++ b/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h @@ -44,6 +44,7 @@ namespace AzFramework AZ::Vector3 m_position; //! world space position for 3d draws, screen space x,y,depth for 2d. AZ::Color m_color = AZ::Colors::White; //! Color to draw the text AZ::Vector2 m_scale = AZ::Vector2(1.0f); //! font scale + float m_lineSpacing; //! Spacing between new lines, as a percentage of m_scale. TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //! Horizontal text alignment TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //! Vertical text alignment bool m_monospace = false; //! disable character proportional spacing @@ -67,6 +68,9 @@ namespace AzFramework virtual void DrawScreenAlignedText3d( const TextDrawParameters& params, const AZStd::string_view& string) = 0; + virtual AZ::Vector2 GetTextSize( + const TextDrawParameters& params, + const AZStd::string_view& string) = 0; }; class FontQueryInterface diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h index fd66534197..83273633be 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h +++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h @@ -213,6 +213,10 @@ namespace AZ const AzFramework::TextDrawParameters& params, const AZStd::string_view& string) override; + AZ::Vector2 GetTextSize( + const AzFramework::TextDrawParameters& params, + const AZStd::string_view& string) override; + public: FFont(AtomFont* atomFont, const char* fontName); @@ -282,6 +286,16 @@ namespace AZ RPI::WindowContextSharedPtr GetDefaultWindowContext() const; RPI::ViewportContextPtr GetDefaultViewportContext() const; + struct DrawParameters + { + TextDrawContext m_ctx; + AZ::Vector2 m_position; + AZ::Vector2 m_size; + AZ::RPI::ViewportContext* m_viewportContext; + const AZ::RHI::Viewport* m_viewport; + }; + DrawParameters ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize); + private: static constexpr uint32_t NumBuffers = 2; static constexpr float WindowScaleWidth = 800.0f; diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp index 40684640d6..48d24f0473 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp @@ -505,7 +505,7 @@ Vec2 AZ::FFont::GetTextSizeUInternal( } charX = offset.x; - charY += size.y; + charY += size.y * (1.f + ctx.GetLineSpacing()); if (charY > maxH) { @@ -944,7 +944,7 @@ int AZ::FFont::CreateQuadsForText(const RHI::Viewport& viewport, float x, float case '\n': { charX = baseXY.x + offset.x; - charY += size.y; + charY += size.y * (1.f + ctx.GetLineSpacing()); continue; } break; @@ -1674,47 +1674,47 @@ static void SetCommonContextFlags(AZ::TextDrawContext& ctx, const AzFramework::T } } -void AZ::FFont::DrawScreenAlignedText2d( - const AzFramework::TextDrawParameters& params, - const AZStd::string_view& string) +AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize) { + DrawParameters internalParams; if (params.m_drawViewportId == AzFramework::InvalidViewportId || string.empty()) { - return; + return internalParams; } //Code mostly duplicated from CRenderer::Draw2dTextWithDepth float posX = params.m_position.GetX(); float posY = params.m_position.GetY(); - AZ::RPI::ViewportContext* viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId).get(); - const AZ::RHI::Viewport& viewport = viewportContext->GetWindowContext()->GetViewport(); + internalParams.m_viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId).get(); + const AZ::RHI::Viewport& viewport = internalParams.m_viewportContext->GetWindowContext()->GetViewport(); + internalParams.m_viewport = &viewport; if (params.m_virtual800x600ScreenSize) { posX *= WindowScaleWidth / (viewport.m_maxX - viewport.m_minX); posY *= WindowScaleHeight / (viewport.m_maxY - viewport.m_minY); } - TextDrawContext ctx; - ctx.SetBaseState(GS_NODEPTHTEST); - ctx.SetColor(AZColorToLYColorF(params.m_color)); - ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f); - ctx.EnableFrame(false); - ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow); - ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize); - ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale)); + internalParams.m_ctx.SetBaseState(GS_NODEPTHTEST); + internalParams.m_ctx.SetColor(AZColorToLYColorF(params.m_color)); + internalParams.m_ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f); + internalParams.m_ctx.EnableFrame(false); + internalParams.m_ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow); + internalParams.m_ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize); + internalParams.m_ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale)); + internalParams.m_ctx.SetLineSpacing(params.m_lineSpacing); if (params.m_monospace || !params.m_scaleWithWindow) { ScaleCoord(viewport, posX, posY); } if (params.m_hAlign != AzFramework::TextHorizontalAlignment::Left || - params.m_vAlign != AzFramework::TextVerticalAlignment::Top) + params.m_vAlign != AzFramework::TextVerticalAlignment::Top || + forceCalculateSize) { - Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, ctx); - + Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, internalParams.m_ctx); // If we're using virtual 800x600 coordinates, convert the text size from // pixels to that before using it as an offset. - if (ctx.m_sizeIn800x600) + if (internalParams.m_ctx.m_sizeIn800x600) { float width = 1.0f; float height = 1.0f; @@ -1740,19 +1740,33 @@ void AZ::FFont::DrawScreenAlignedText2d( { posY -= textSize.y; } + internalParams.m_size = AZ::Vector2{textSize.x, textSize.y}; + } + SetCommonContextFlags(internalParams.m_ctx, params); + internalParams.m_ctx.m_drawTextFlags |= eDrawText_2D; + internalParams.m_position = AZ::Vector2{posX, posY}; + return internalParams; +} + +void AZ::FFont::DrawScreenAlignedText2d( + const AzFramework::TextDrawParameters& params, + const AZStd::string_view& string) +{ + DrawParameters internalParams = ExtractDrawParameters(params, string, false); + if (!internalParams.m_viewportContext) + { + return; } - SetCommonContextFlags(ctx, params); - ctx.m_drawTextFlags |= eDrawText_2D; DrawStringUInternal( - viewport, - viewportContext, - posX, - posY, + *internalParams.m_viewport, + internalParams.m_viewportContext, + internalParams.m_position.GetX(), + internalParams.m_position.GetY(), params.m_position.GetZ(), // Z string.data(), params.m_multiline, - ctx + internalParams.m_ctx ); } @@ -1760,13 +1774,12 @@ void AZ::FFont::DrawScreenAlignedText3d( const AzFramework::TextDrawParameters& params, const AZStd::string_view& string) { - if (params.m_drawViewportId == AzFramework::InvalidViewportId || - string.empty()) + DrawParameters internalParams = ExtractDrawParameters(params, string, false); + if (!internalParams.m_viewportContext) { return; } - AZ::RPI::ViewportContext* viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId).get(); - AZ::RPI::ViewPtr currentView = viewportContext->GetDefaultView(); + AZ::RPI::ViewPtr currentView = internalParams.m_viewportContext->GetDefaultView(); if (!currentView) { return; @@ -1778,7 +1791,23 @@ void AZ::FFont::DrawScreenAlignedText3d( ); AzFramework::TextDrawParameters param2d = params; param2d.m_position = positionNDC; - DrawScreenAlignedText2d(param2d, string); + + DrawStringUInternal( + *internalParams.m_viewport, + internalParams.m_viewportContext, + internalParams.m_position.GetX(), + internalParams.m_position.GetY(), + params.m_position.GetZ(), // Z + string.data(), + params.m_multiline, + internalParams.m_ctx + ); +} + +AZ::Vector2 AZ::FFont::GetTextSize(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string) +{ + DrawParameters sizeParams = ExtractDrawParameters(params, string, true); + return sizeParams.m_size; } #endif //USE_NULLFONT_ALWAYS From fe2931829338c9e6805050533056417a2f2d2686 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Tue, 11 May 2021 12:18:49 -0700 Subject: [PATCH 116/225] Make ScriptTimePoint::Get const correct --- Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h b/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h index 7cb81829ef..08c997de2d 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h +++ b/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h @@ -43,7 +43,7 @@ namespace AZ return AZStd::string::format("Time %llu", m_timePoint.time_since_epoch().count()); } - const AZStd::chrono::system_clock::time_point& Get() { return m_timePoint; } + const AZStd::chrono::system_clock::time_point& Get() const { return m_timePoint; } // Returns the time point in seconds double GetSeconds() const From 4d8ed6c0cb09b2abe43b01eea5003ab989377c6a Mon Sep 17 00:00:00 2001 From: zsolleci Date: Tue, 11 May 2021 14:19:45 -0500 Subject: [PATCH 117/225] T92563569 completed and suite updated --- .../scripting/Node_HappyPath_DuplicateNode.py | 116 ++++++++++++++++++ .../PythonTests/scripting/TestSuite_Active.py | 10 +- 2 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py b/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py new file mode 100644 index 0000000000..9d8cccd027 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py @@ -0,0 +1,116 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + open_sc_window = ("Script Canvas window is opened", "Failed to open Script Canvas window") + node_added = ("Successfully added node to graph", "Failed to add node to graph") + node_duplicated = ("Successfully duplicated node", "Failed to duplicate the node") +# fmt: on + + +def Node_HappyPath_DuplicateNode(): + """ + Summary: + Duplicating node in graph + + Expected Behavior: + Upon selecting a node and pressing Ctrl+D, the node will be duplicated + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Open a new graph + 3) Add node to graph + 4) Select node in graph to verify existence + 5) Mock Ctrl+D to duplicate node + 6) Verify the node was duplicated + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from PySide2 import QtWidgets, QtTest + from PySide2.QtCore import Qt + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + import editor_python_test_tools.pyside_utils as pyside_utils + + import azlmbr.legacy.general as general + + WAIT_FRAMES = 200 + + NODE_NAME = "Print" + NODE_CATEGORY = "Debug" + EXPECTED_STRING = f"{NODE_NAME} - {NODE_CATEGORY} (2 Selected)" + + def command_line_input(command_str): + cmd_action = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_ViewCommandLine", "type": QtWidgets.QAction} + ) + cmd_action.trigger() + textbox = sc.findChild(QtWidgets.QLineEdit, "commandText") + QtTest.QTest.keyClicks(textbox, command_str) + QtTest.QTest.keyClick(textbox, Qt.Key_Enter, Qt.NoModifier) + + def grab_title_text(): + scroll_area = node_inspector.findChild(QtWidgets.QScrollArea, "") + QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES) + general.idle_wait(1.0) + background = scroll_area.findChild(QtWidgets.QFrame, "Background") + title = background.findChild(QtWidgets.QLabel, "Title") + text = title.findChild(QtWidgets.QLabel, "Title") + print(text.text()) + return text.text() + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # # 2) Open a new graph + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + sc_main = sc.findChild(QtWidgets.QMainWindow) + create_new_graph = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} + ) + node_inspector = sc.findChild(QtWidgets.QDockWidget, "NodeInspector") + create_new_graph.trigger() + + # 3) Add node + command_line_input("add_node Print") + + # 4) Select node in graph to verify existence + graph_view = sc.findChild(QtWidgets.QFrame, "graphicsViewFrame") + graph = graph_view.findChild(QtWidgets.QWidget, "") + + # 5) Duplicate node + sc_main.activateWindow() + QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES) + QtTest.QTest.keyClick(graph, "d", Qt.ControlModifier, WAIT_FRAMES) + + # 6) Verify the node was duplicated + after_dup = grab_title_text() + Report.result(Tests.node_duplicated, after_dup == EXPECTED_STRING) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from editor_python_test_tools.utils import Report + + Report.start_test(Node_HappyPath_DuplicateNode) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py index dda75f0a0c..2cd41d1980 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py @@ -84,7 +84,7 @@ class TestAutomation(TestAutomationBase): file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) from . import OnEntityActivatedDeactivated_PrintMessage as test_module self._run_test(request, workspace, editor, test_module) - + @pytest.mark.test_case_id("T92562993") def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project): from . import NodePalette_ClearSelection as test_module @@ -122,7 +122,7 @@ class TestAutomation(TestAutomationBase): def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project): from . import NodeInspector_RenameVariable as test_module self._run_test(request, workspace, editor, test_module) - + @pytest.mark.test_case_id("T92569137") def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): from . import Debugging_TargetMultipleGraphs as test_module @@ -195,7 +195,7 @@ class TestAutomation(TestAutomationBase): def test_NodeCategory_ExpandOnClick(self, request, workspace, editor, launcher_platform): from . import NodeCategory_ExpandOnClick as test_module self._run_test(request, workspace, editor, test_module) - + def test_NodePalette_SearchText_Deletion(self, request, workspace, editor, launcher_platform): from . import NodePalette_SearchText_Deletion as test_module self._run_test(request, workspace, editor, test_module) @@ -204,6 +204,10 @@ class TestAutomation(TestAutomationBase): from . import VariableManager_UnpinVariableType_Works as test_module self._run_test(request, workspace, editor, test_module) + def test_Node_HappyPath_DuplicateNode(self, request, workspace, editor, launcher_platform): + from . import Node_HappyPath_DuplicateNode as test_module + self._run_test(request, workspace, editor, test_module) + # NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method # fails because of pyside_utils import @pytest.mark.SUITE_periodic From 3c5659668a0cd4343b7b7f86f56a3092328a4714 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Tue, 11 May 2021 12:19:56 -0700 Subject: [PATCH 118/225] Add AZ::RPI::ViewportContextRequests alias for the full interface --- Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h index bc7e5a4b1d..377c1d5c4e 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h @@ -92,6 +92,8 @@ namespace AZ virtual ViewPtr GetCurrentView(const Name& contextName) const = 0; }; + using ViewportContextRequests = AZ::Interface; + class ViewportContextManagerNotifications : public AZ::EBusTraits { From 899d4c438d602f5379d504ac01d8da4a7cbe7e1e Mon Sep 17 00:00:00 2001 From: mbalfour Date: Tue, 11 May 2021 14:25:25 -0500 Subject: [PATCH 119/225] Move ThumbnailerNullComponent into AzToolsFramework so that it can be used by other tools that need it. SerializeContextTools will soon rely on this. --- .../AzToolsFramework/AzToolsFrameworkModule.cpp | 2 ++ .../Thumbnails}/ThumbnailerNullComponent.cpp | 6 +++--- .../Thumbnails}/ThumbnailerNullComponent.h | 8 ++++++-- .../AzToolsFramework/aztoolsframework_files.cmake | 2 ++ Code/Tools/Standalone/Source/LuaIDEApplication.cpp | 6 +++--- Code/Tools/Standalone/lua_ide_files.cmake | 2 -- 6 files changed, 16 insertions(+), 10 deletions(-) rename Code/{Tools/Standalone/Source => Framework/AzToolsFramework/AzToolsFramework/Thumbnails}/ThumbnailerNullComponent.cpp (95%) rename Code/{Tools/Standalone/Source => Framework/AzToolsFramework/AzToolsFramework/Thumbnails}/ThumbnailerNullComponent.h (89%) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp index 373787e7dd..3a84c4249c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -91,6 +92,7 @@ namespace AzToolsFramework AzToolsFramework::AssetBundleComponent::CreateDescriptor(), AzToolsFramework::SliceDependencyBrowserComponent::CreateDescriptor(), AzToolsFramework::Thumbnailer::ThumbnailerComponent::CreateDescriptor(), + AzToolsFramework::Thumbnailer::ThumbnailerNullComponent::CreateDescriptor(), AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor(), AzToolsFramework::EditorInteractionSystemComponent::CreateDescriptor(), AzToolsFramework::Components::EditorComponentAPIComponent::CreateDescriptor(), diff --git a/Code/Tools/Standalone/Source/ThumbnailerNullComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Thumbnails/ThumbnailerNullComponent.cpp similarity index 95% rename from Code/Tools/Standalone/Source/ThumbnailerNullComponent.cpp rename to Code/Framework/AzToolsFramework/AzToolsFramework/Thumbnails/ThumbnailerNullComponent.cpp index e33cb8aa51..d156ae7c04 100644 --- a/Code/Tools/Standalone/Source/ThumbnailerNullComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Thumbnails/ThumbnailerNullComponent.cpp @@ -12,16 +12,16 @@ #include #include -#include "ThumbnailerNullComponent.h" +#include #include #include -namespace LUAEditor +namespace AzToolsFramework { namespace Thumbnailer { ThumbnailerNullComponent::ThumbnailerNullComponent() : - m_nullThumbnail(new AzToolsFramework::Thumbnailer::MissingThumbnail()) + m_nullThumbnail() { } diff --git a/Code/Tools/Standalone/Source/ThumbnailerNullComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Thumbnails/ThumbnailerNullComponent.h similarity index 89% rename from Code/Tools/Standalone/Source/ThumbnailerNullComponent.h rename to Code/Framework/AzToolsFramework/AzToolsFramework/Thumbnails/ThumbnailerNullComponent.h index 9d0c638305..d8386235e5 100644 --- a/Code/Tools/Standalone/Source/ThumbnailerNullComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Thumbnails/ThumbnailerNullComponent.h @@ -15,7 +15,11 @@ #include #include -namespace LUAEditor +// ThumbnailerNullComponent is an alternative to ThumbnailerComponent that can be used by tools that don't use Qt. +// It doesn't do anything (hence "null"), but it allows the system and editor components that rely on the ThumbnailService +// to start up and function. + +namespace AzToolsFramework { namespace Thumbnailer { @@ -53,4 +57,4 @@ namespace LUAEditor AzToolsFramework::Thumbnailer::SharedThumbnail m_nullThumbnail; }; } // Thumbnailer -} // namespace LUAEditor +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index a7fcf2e711..06f78ecdd3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -72,6 +72,8 @@ set(FILES AssetCatalog/PlatformAddressedAssetCatalogManager.cpp Thumbnails/ThumbnailerComponent.cpp Thumbnails/ThumbnailerComponent.h + Thumbnails/ThumbnailerNullComponent.cpp + Thumbnails/ThumbnailerNullComponent.h Thumbnails/LoadingThumbnail.cpp Thumbnails/LoadingThumbnail.h Thumbnails/MissingThumbnail.cpp diff --git a/Code/Tools/Standalone/Source/LuaIDEApplication.cpp b/Code/Tools/Standalone/Source/LuaIDEApplication.cpp index cd72fda4e3..8e52bb4d95 100644 --- a/Code/Tools/Standalone/Source/LuaIDEApplication.cpp +++ b/Code/Tools/Standalone/Source/LuaIDEApplication.cpp @@ -22,9 +22,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -55,7 +55,7 @@ namespace LUAEditor RegisterComponentDescriptor(AzToolsFramework::Components::PropertyManagerComponent::CreateDescriptor()); RegisterComponentDescriptor(AzFramework::AssetSystem::AssetSystemComponent::CreateDescriptor()); RegisterComponentDescriptor(AzToolsFramework::AssetSystem::AssetSystemComponent::CreateDescriptor()); - RegisterComponentDescriptor(LUAEditor::Thumbnailer::ThumbnailerNullComponent::CreateDescriptor()); + RegisterComponentDescriptor(AzToolsFramework::Thumbnailer::ThumbnailerNullComponent::CreateDescriptor()); RegisterComponentDescriptor(AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor()); RegisterComponentDescriptor(AzToolsFramework::Components::EditorSelectionAccentSystemComponent::CreateDescriptor()); @@ -75,7 +75,7 @@ namespace LUAEditor EnsureComponentCreated(AzToolsFramework::Components::PropertyManagerComponent::RTTI_Type()); EnsureComponentCreated(AzFramework::AssetSystem::AssetSystemComponent::RTTI_Type()); EnsureComponentCreated(AzToolsFramework::AssetSystem::AssetSystemComponent::RTTI_Type()); - EnsureComponentCreated(LUAEditor::Thumbnailer::ThumbnailerNullComponent::RTTI_Type()); + EnsureComponentCreated(AzToolsFramework::Thumbnailer::ThumbnailerNullComponent::RTTI_Type()); EnsureComponentCreated(AzToolsFramework::AssetBrowser::AssetBrowserComponent::RTTI_Type()); EnsureComponentCreated(AzToolsFramework::Components::EditorSelectionAccentSystemComponent::RTTI_Type()); } diff --git a/Code/Tools/Standalone/lua_ide_files.cmake b/Code/Tools/Standalone/lua_ide_files.cmake index c6e2c538f2..ff2196db62 100644 --- a/Code/Tools/Standalone/lua_ide_files.cmake +++ b/Code/Tools/Standalone/lua_ide_files.cmake @@ -14,8 +14,6 @@ set(FILES Source/LuaIDEApplication.cpp Source/AssetDatabaseLocationListener.h Source/AssetDatabaseLocationListener.cpp - Source/ThumbnailerNullComponent.h - Source/ThumbnailerNullComponent.cpp Source/Editor/LuaEditor.h Source/Editor/LuaEditor.cpp Source/LUA/BasicScriptChecker.h From c41ee23ea481c4b3977e708a6ed521ce58006fd9 Mon Sep 17 00:00:00 2001 From: mnaumov Date: Tue, 11 May 2021 12:40:37 -0700 Subject: [PATCH 120/225] PR feedback --- .../Types/EnhancedPBR_ForwardPass.azsl | 3 +-- .../Types/MaterialInputs/ParallaxInput.azsli | 17 +++++++++++++---- .../StandardMultilayerPBR_ForwardPass.azsl | 7 +++---- .../StandardMultilayerPBR_Shadowmap_WithPS.azsl | 6 +++--- .../Types/StandardPBR_ForwardPass.azsl | 7 +++---- .../Atom/Features/ParallaxMapping.azsli | 6 ++++-- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index 34c57db974..f7926df818 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -150,7 +150,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_depthFactor, MaterialSrg::m_depthOffset, ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth, displacementIsClipped); + IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth, displacementIsClipped, IN.m_position.w); // Apply second part of the offset to the detail UV (see comment above) IN.m_detailUv[MaterialSrg::m_parallaxUvIndex] -= IN.m_uv[MaterialSrg::m_parallaxUvIndex]; @@ -163,7 +163,6 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float { DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, IN.m_shadowCoords); } - IN.m_position.w = mul(ViewSrg::m_viewProjectionMatrix, IN.m_worldPosition).z; } } diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxInput.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxInput.azsli index ab601429e8..ffd7c18045 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxInput.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxInput.azsli @@ -32,7 +32,7 @@ option bool prefix##o_useDepthMap; void GetParallaxInput(float3 normal, float3 tangent, float3 bitangent, float depthFactor, float depthOffset, float4x4 objectWorldMatrix, float3x3 uvMatrix, float3x3 uvMatrixInverse, - inout float2 uv, inout float3 worldPosition, inout float depth, out bool isClipped) + inout float2 uv, inout float3 worldPosition, inout float depthNDC, inout float depthCS, out bool isClipped) { if(o_parallax_feature_enabled) { @@ -72,7 +72,8 @@ void GetParallaxInput(float3 normal, float3 tangent, float3 bitangent, float dep objectWorldMatrix, ViewSrg::m_viewProjectionMatrix); - depth = pdo.m_depth; + depthCS = pdo.m_depthCS; + depthNDC = pdo.m_depthNDC; worldPosition = pdo.m_worldPosition; } @@ -82,9 +83,17 @@ void GetParallaxInput(float3 normal, float3 tangent, float3 bitangent, float dep void GetParallaxInput(float3 normal, float3 tangent, float3 bitangent, float depthFactor, float depthOffset, float4x4 objectWorldMatrix, float3x3 uvMatrix, float3x3 uvMatrixInverse, - inout float2 uv, inout float3 worldPosition, inout float depth) + inout float2 uv, inout float3 worldPosition, inout float depthNDC, inout float depthCS) { bool isClipped; - GetParallaxInput(normal, tangent, bitangent, depthFactor, depthOffset, objectWorldMatrix, uvMatrix, uvMatrixInverse, uv, worldPosition, depth, isClipped); + GetParallaxInput(normal, tangent, bitangent, depthFactor, depthOffset, objectWorldMatrix, uvMatrix, uvMatrixInverse, uv, worldPosition, depthNDC, depthCS, isClipped); +} + +void GetParallaxInput(float3 normal, float3 tangent, float3 bitangent, float depthFactor, float depthOffset, + float4x4 objectWorldMatrix, float3x3 uvMatrix, float3x3 uvMatrixInverse, + inout float2 uv, inout float3 worldPosition, inout float depthNDC) +{ + float depthCS; + GetParallaxInput(normal, tangent, bitangent, depthFactor, depthOffset, objectWorldMatrix, uvMatrix, uvMatrixInverse, uv, worldPosition, depthNDC, depthCS); } diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl index 9cc0047b72..bc32aa1370 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ForwardPass.azsl @@ -130,9 +130,9 @@ VSOutput ForwardPassVS(VSInput IN) // ---------- Pixel Shader ---------- -PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depth) +PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depthNDC) { - depth = IN.m_position.z; + depthNDC = IN.m_position.z; // ------- Tangents & Bitangets ------- @@ -185,7 +185,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float float parallaxOverallFactor = MaterialSrg::m_displacementMax - MaterialSrg::m_displacementMin; GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], parallaxOverallFactor, parallaxOverallOffset, ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth, displacementIsClipped); + IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depthNDC, IN.m_position.w, displacementIsClipped); // Adjust directional light shadow coorinates for parallax correction if(o_parallax_enablePixelDepthOffset) @@ -195,7 +195,6 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float { DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, IN.m_shadowCoords); } - IN.m_position.w = mul(ViewSrg::m_viewProjectionMatrix, IN.m_worldPosition).z; } } diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl index 325937b228..c76dd15975 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_Shadowmap_WithPS.azsl @@ -109,7 +109,7 @@ PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace) GetDepth_Setup(IN.m_blendMask); - float depth; + float depthNDC; float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); @@ -118,9 +118,9 @@ PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace) float parallaxOverallFactor = MaterialSrg::m_displacementMax - MaterialSrg::m_displacementMin; GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], parallaxOverallFactor, parallaxOverallOffset, ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth); + IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depthNDC); - OUT.m_depth = depth; + OUT.m_depth = depthNDC; } return OUT; diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl index 8621865f54..f362349a7b 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl @@ -105,7 +105,7 @@ VSOutput StandardPbr_ForwardPassVS(VSInput IN) // ---------- Pixel Shader ---------- -PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depth) +PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depthNDC) { // ------- Tangents & Bitangets ------- @@ -125,7 +125,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // ------- Depth & Parallax ------- - depth = IN.m_position.z; + depthNDC = IN.m_position.z; bool displacementIsClipped = false; @@ -137,7 +137,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3(); GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_depthFactor, MaterialSrg::m_depthOffset, ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth, displacementIsClipped); + IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depthNDC, IN.m_position.w, displacementIsClipped); // Adjust directional light shadow coorinates for parallax correction if(o_parallax_enablePixelDepthOffset) @@ -147,7 +147,6 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float { DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, IN.m_shadowCoords); } - IN.m_position.w = mul(ViewSrg::m_viewProjectionMatrix, IN.m_worldPosition).z; } } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli index 1d2beb0f10..8b1efc8eea 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli @@ -398,7 +398,8 @@ ParallaxOffset GetParallaxOffset( float depthFactor, struct PixelDepthOffset { - float m_depth; + float m_depthNDC; //!< The new depth value, in normalized device coordinates (used for final depth output) + float m_depthCS; //!< The new depth value, in clip space (can be used for other operations like light culling) float3 m_worldPosition; }; @@ -432,7 +433,8 @@ PixelDepthOffset CalcPixelDepthOffset( float depthFactor, float4 clipOffsetPosition = mul(viewProjectionMatrix, float4(worldOffsetPosition, 1.0)); PixelDepthOffset pdo; - pdo.m_depth = clipOffsetPosition.z / clipOffsetPosition.w; + pdo.m_depthCS = clipOffsetPosition.z; + pdo.m_depthNDC = clipOffsetPosition.z / clipOffsetPosition.w; pdo.m_worldPosition = worldOffsetPosition; return pdo; } From b4f7038d6aded8d6feb917518b536e100e41d41c Mon Sep 17 00:00:00 2001 From: mnaumov Date: Tue, 11 May 2021 12:42:37 -0700 Subject: [PATCH 121/225] param ordering --- .../Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index f7926df818..a91e88afad 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -150,7 +150,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_depthFactor, MaterialSrg::m_depthOffset, ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse, - IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth, displacementIsClipped, IN.m_position.w); + IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth, IN.m_position.w, displacementIsClipped); // Apply second part of the offset to the detail UV (see comment above) IN.m_detailUv[MaterialSrg::m_parallaxUvIndex] -= IN.m_uv[MaterialSrg::m_parallaxUvIndex]; From 3e13dd52d18b33b1f5ba2f0c0c70323e26ad11a1 Mon Sep 17 00:00:00 2001 From: karlberg Date: Tue, 11 May 2021 12:47:15 -0700 Subject: [PATCH 122/225] First pass, removing gridmate touchpoints from AzFramework and non inclusive terminology purge --- .../AzFramework/Application/Application.cpp | 30 - .../AzFramework/Application/Application.h | 7 - .../AzFramework/AzFrameworkModule.cpp | 4 - .../Components/TransformComponent.cpp | 4 +- .../Components/TransformComponent.h | 10 +- .../DynamicSerializableFieldMarshaler.h | 146 -- .../AzFramework/Network/EntityIdMarshaler.h | 76 - .../Network/InterestManagerComponent.cpp | 187 --- .../Network/InterestManagerComponent.h | 120 -- .../AzFramework/Network/NetBindable.cpp | 111 -- .../AzFramework/Network/NetBindable.h | 799 --------- .../Network/NetBindingComponent.cpp | 287 ---- .../AzFramework/Network/NetBindingComponent.h | 85 - .../Network/NetBindingComponentChunk.cpp | 254 --- .../Network/NetBindingComponentChunk.h | 112 -- .../AzFramework/Network/NetBindingEventsBus.h | 51 - .../Network/NetBindingHandlerBus.h | 112 -- .../AzFramework/Network/NetBindingSystemBus.h | 119 -- .../Network/NetBindingSystemComponent.cpp | 66 - .../Network/NetBindingSystemComponent.h | 53 - .../Network/NetBindingSystemImpl.cpp | 957 ----------- .../Network/NetBindingSystemImpl.h | 311 ---- .../AzFramework/Network/NetSystemBus.h | 38 - .../AzFramework/Network/NetworkContext.cpp | 378 ----- .../AzFramework/Network/NetworkContext.h | 969 ----------- .../AzFramework/Script/ScriptComponent.cpp | 275 +--- .../AzFramework/Script/ScriptComponent.h | 19 +- .../AzFramework/Script/ScriptMarshal.cpp | 573 ------- .../AzFramework/Script/ScriptMarshal.h | 94 -- .../AzFramework/Script/ScriptNetBindings.cpp | 1427 ----------------- .../AzFramework/Script/ScriptNetBindings.h | 320 ---- .../TargetManagementComponent.cpp | 2 +- .../AzFramework/azframework_files.cmake | 24 - .../ToolsComponents/TransformComponent.cpp | 17 +- .../GridMate/Carrier/SecureSocketDriver.cpp | 2 +- .../Carrier/StreamSecureSocketDriver.cpp | 2 +- .../GridMate/GridMate/Replica/DataSet.cpp | 2 +- .../GridMate/GridMate/Replica/DataSet.h | 12 +- .../GridMate/Replica/DeltaCompressedDataSet.h | 4 +- .../Interest/BitmaskInterestHandler.cpp | 2 +- .../Replica/Interest/InterestManager.cpp | 2 +- .../Interest/ProximityInterestHandler.cpp | 2 +- .../GridMate/Replica/MigrationSequence.cpp | 4 +- .../GridMate/Replica/RemoteProcedureCall.h | 6 +- .../GridMate/GridMate/Replica/Replica.cpp | 4 +- .../GridMate/GridMate/Replica/Replica.h | 10 +- .../GridMate/Replica/ReplicaChunk.cpp | 18 +- .../GridMate/GridMate/Replica/ReplicaChunk.h | 10 +- .../GridMate/Replica/ReplicaDrillerEvents.h | 6 +- .../GridMate/GridMate/Replica/ReplicaMgr.cpp | 46 +- .../GridMate/GridMate/Replica/ReplicaMgr.h | 8 +- .../GridMate/GridMate/Replica/ReplicaStatus.h | 4 +- .../GridMate/Replica/SystemReplicas.cpp | 6 +- .../Replica/Tasks/ReplicaMarshalTasks.cpp | 2 +- .../Replica/Tasks/ReplicaUpdateTasks.h | 2 +- .../GridMate/GridMate/Session/Session.cpp | 14 +- Code/Framework/GridMate/Tests/Interest.cpp | 18 +- Code/Framework/GridMate/Tests/Replica.cpp | 190 +-- .../GridMate/Tests/ReplicaBehavior.cpp | 18 +- .../GridMate/Tests/ReplicaMedium.cpp | 210 +-- .../Framework/GridMate/Tests/ReplicaSmall.cpp | 12 +- Code/Framework/Tests/GridMocks.h | 58 - .../Tests/InterestManagerComponentTests.cpp | 151 -- Code/Framework/Tests/NetBinding.cpp | 600 ------- Code/Framework/Tests/NetBindingMocks.h | 335 ---- .../Tests/NetBindingSystemImplTest.cpp | 605 ------- Code/Framework/Tests/NetworkContext.cpp | 801 --------- Code/Framework/Tests/NetworkMarshal.cpp | 552 ------- .../Tests/Script/ScriptComponentTests.cpp | 62 - Code/Framework/Tests/TransformComponent.cpp | 31 - .../Tests/frameworktests_files.cmake | 6 - 71 files changed, 360 insertions(+), 11494 deletions(-) delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindable.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h delete mode 100644 Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp delete mode 100644 Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h delete mode 100644 Code/Framework/Tests/GridMocks.h delete mode 100644 Code/Framework/Tests/InterestManagerComponentTests.cpp delete mode 100644 Code/Framework/Tests/NetBinding.cpp delete mode 100644 Code/Framework/Tests/NetBindingMocks.h delete mode 100644 Code/Framework/Tests/NetBindingSystemImplTest.cpp delete mode 100644 Code/Framework/Tests/NetworkContext.cpp delete mode 100644 Code/Framework/Tests/NetworkMarshal.cpp diff --git a/Code/Framework/AzFramework/AzFramework/Application/Application.cpp b/Code/Framework/AzFramework/AzFramework/Application/Application.cpp index ba313812ce..dc6ae684cf 100644 --- a/Code/Framework/AzFramework/AzFramework/Application/Application.cpp +++ b/Code/Framework/AzFramework/AzFramework/Application/Application.cpp @@ -52,8 +52,6 @@ #include #include #include -#include -#include #include #include #include @@ -66,7 +64,6 @@ #include #include #include -#include #include #include #include @@ -197,7 +194,6 @@ namespace AzFramework ApplicationRequests::Bus::Handler::BusConnect(); AZ::UserSettingsFileLocatorBus::Handler::BusConnect(); - NetSystemRequestBus::Handler::BusConnect(); } Application::~Application() @@ -207,7 +203,6 @@ namespace AzFramework Stop(); } - NetSystemRequestBus::Handler::BusDisconnect(); AZ::UserSettingsFileLocatorBus::Handler::BusDisconnect(); ApplicationRequests::Bus::Handler::BusDisconnect(); @@ -285,13 +280,6 @@ namespace AzFramework m_pimpl.reset(); - /* The following line of code is a temporary fix. - * GridMate's ReplicaChunkDescriptor is stored in a global environment variable 'm_globalDescriptorTable' - * which does not get cleared when Application shuts down. We need to un-reflect here to clear ReplicaChunkDescriptor - * so that ReplicaChunkDescriptor::m_vdt doesn't get flooded when we repeatedly instantiate Application in unit tests. - */ - AZ::ReflectionEnvironment::GetReflectionManager()->RemoveReflectContext(); - // Free any memory owned by the command line container. m_commandLine = CommandLine(); @@ -320,8 +308,6 @@ namespace AzFramework azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), - azrtti_typeid(), - azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), @@ -457,9 +443,6 @@ namespace AzFramework void Application::CreateReflectionManager() { ComponentApplication::CreateReflectionManager(); - - // Setup NetworkContext - AZ::ReflectionEnvironment::GetReflectionManager()->AddReflectContext(); } //////////////////////////////////////////////////////////////////////////// @@ -479,19 +462,6 @@ namespace AzFramework return uuid; } - //////////////////////////////////////////////////////////////////////////// - NetworkContext* Application::GetNetworkContext() - { - NetworkContext* result = nullptr; - - if (auto reflectionManager = AZ::ReflectionEnvironment::GetReflectionManager()) - { - result = reflectionManager->GetReflectContext(); - } - - return result; - } - void Application::ResolveEnginePath(AZStd::string& engineRelativePath) const { AZ::IO::FixedMaxPath fullPath = m_engineRoot / engineRelativePath; diff --git a/Code/Framework/AzFramework/AzFramework/Application/Application.h b/Code/Framework/AzFramework/AzFramework/Application/Application.h index 4d7e45a423..6b1283be34 100644 --- a/Code/Framework/AzFramework/AzFramework/Application/Application.h +++ b/Code/Framework/AzFramework/AzFramework/Application/Application.h @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -49,7 +48,6 @@ namespace AzFramework : public AZ::ComponentApplication , public AZ::UserSettingsFileLocatorBus::Handler , public ApplicationRequests::Bus::Handler - , public NetSystemRequestBus::Handler { public: // Base class for platform specific implementations of the application. @@ -138,11 +136,6 @@ namespace AzFramework // Convenience function that should be called instead of the standard exit() function to ensure platform requirements are met. static void Exit(int errorCode) { ApplicationRequests::Bus::Broadcast(&ApplicationRequests::TerminateOnError, errorCode); } - ////////////////////////////////////////////////////////////////////////// - //! NetSystemEventBus::Handler - ////////////////////////////////////////////////////////////////////////// - NetworkContext* GetNetworkContext() override; - protected: /** diff --git a/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp b/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp index 644a7d099d..d1e4b4977a 100644 --- a/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp +++ b/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp @@ -22,8 +22,6 @@ #include #include #include -#include -#include #include #include #include @@ -42,8 +40,6 @@ namespace AzFramework AzFramework::AssetCatalogComponent::CreateDescriptor(), AzFramework::CustomAssetTypeComponent::CreateDescriptor(), AzFramework::FileTag::ExcludeFileComponent::CreateDescriptor(), - AzFramework::NetBindingComponent::CreateDescriptor(), - AzFramework::NetBindingSystemComponent::CreateDescriptor(), AzFramework::TransformComponent::CreateDescriptor(), AzFramework::NonUniformScaleComponent::CreateDescriptor(), AzFramework::GameEntityContextComponent::CreateDescriptor(), diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp index 5605fe567c..284df15eb9 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp @@ -878,15 +878,13 @@ namespace AzFramework AZ::SerializeContext* serializeContext = azrtti_cast(reflection); if (serializeContext) { - serializeContext->Class() + serializeContext->Class() ->Version(4, &TransformComponentVersionConverter) ->Field("Parent", &TransformComponent::m_parentId) ->Field("Transform", &TransformComponent::m_worldTM) ->Field("LocalTransform", &TransformComponent::m_localTM) ->Field("ParentActivationTransformMode", &TransformComponent::m_parentActivationTransformMode) ->Field("IsStatic", &TransformComponent::m_isStatic) - ->Field("InterpolatePosition", &TransformComponent::m_interpolatePosition) - ->Field("InterpolateRotation", &TransformComponent::m_interpolateRotation) ; } diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h index abea0bd4dd..0dd53d84ed 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h @@ -17,7 +17,6 @@ #include #include #include -#include namespace AzToolsFramework { @@ -41,10 +40,9 @@ namespace AzFramework , public AZ::TransformBus::Handler , public AZ::TransformNotificationBus::Handler , private AZ::TransformHierarchyInformationBus::Handler - , public NetBindable { public: - AZ_COMPONENT(TransformComponent, AZ::TransformComponentTypeId, NetBindable, AZ::TransformInterface); + AZ_COMPONENT(TransformComponent, AZ::TransformComponentTypeId, AZ::TransformInterface); friend class AzToolsFramework::Components::TransformComponent; @@ -218,11 +216,5 @@ namespace AzFramework bool m_parentActive = false; ///< Keeps track of the state of the parent entity. bool m_onNewParentKeepWorldTM = true; ///< If set, recompute localTM instead of worldTM when parent becomes active. bool m_isStatic = false; ///< If true, the transform is static and doesn't move while entity is active. - - //! @deprecated - //! @{ - AZ::InterpolationMode m_interpolatePosition = AZ::InterpolationMode::NoInterpolation; - AZ::InterpolationMode m_interpolateRotation = AZ::InterpolationMode::NoInterpolation; - //! @} }; } // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h b/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h deleted file mode 100644 index 3e69454f59..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h +++ /dev/null @@ -1,146 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once -#ifndef AZFRAMEWORK_NETWORK_DYNAMICSERIALIZABLEFIELDMARSHALER_H -#define AZFRAMEWORK_NETWORK_DYNAMICSERIALIZABLEFIELDMARSHALER_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace GridMate -{ - /** - * Marshaler for DynamicSerializableField, contains a template param for allocating the memory buffer that it's going to use to write to. - */ - template - class DynamicSerializableFieldMarshaler - { - public: - DynamicSerializableFieldMarshaler() - : m_serializeContext(nullptr) - { - EBUS_EVENT_RESULT(m_serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - } - - // Mainly here for unit test purposes. - DynamicSerializableFieldMarshaler(AZ::SerializeContext* context) - : m_serializeContext(context) - { - } - - AZ_FORCE_INLINE void Marshal(WriteBuffer& wb, const AZ::DynamicSerializableField& value) const - { - AZ_Error("DynamicSerializableFieldMarshaler", m_serializeContext, "Unknown SerializationContext. Aborting Marshal attempt.\n"); - if (m_serializeContext) - { - Marshaler sizeMarshaler; - Marshaler uuidMarshaler; - - AZStd::vector memoryBuffer(BufferSize); - - // Start buffer in write mode. - AZ::IO::ByteContainerStream memoryStream(&memoryBuffer); - - AZ::u32 bufferSize = 0; - - if (m_serializeContext->FindClassData(value.m_typeId)) - { - if (AZ::Utils::SaveObjectToStream(memoryStream, AZ::DataStream::StreamType::ST_BINARY, value.m_data, value.m_typeId, m_serializeContext)) - { - bufferSize = static_cast(memoryStream.GetCurPos()); - } - } - else - { - AZ_Error("DynamicSerializableFieldMarshaler", !value.IsValid(), "Could not save object to stream because type Id %s is not registered with the serializer.\n", value.m_typeId.ToString().c_str()); - } - - sizeMarshaler.Marshal(wb, bufferSize); - uuidMarshaler.Marshal(wb, value.m_typeId); - wb.WriteRaw(memoryBuffer.data(), bufferSize); - } - } - - AZ_FORCE_INLINE void Unmarshal(AZ::DynamicSerializableField& value, ReadBuffer& rb) const - { - value.DestroyData(m_serializeContext); - - AZ_Error("DynamicSerializableFieldMarshaler", m_serializeContext, "Unknown SerializationContext. Aborting Unmarshal attempt.\n"); - if (m_serializeContext) - { - Marshaler sizeMarshaler; - AZ::u32 marshaledBufferSize = 0; - sizeMarshaler.Unmarshal(marshaledBufferSize, rb); - - AZ_Assert(marshaledBufferSize <= BufferSize,"Trying to deserialize too much data for the allocated buffer size\n"); - - // Marshal out the TypeId so I can use it on the receiving end. - Marshaler uuidMarshaler; - uuidMarshaler.Unmarshal(value.m_typeId, rb); - - if (marshaledBufferSize > 0) - { - // See if there's some nice way to use this. - // - Can't make this a member variable, since both these methods are const. - AZStd::vector memoryBuffer(marshaledBufferSize + 1); - - if (rb.ReadRaw(memoryBuffer.data(), marshaledBufferSize)) - { - // Start buffer in read mode. - AZ::IO::ByteContainerStream memoryStream(&memoryBuffer); - - // we'll use a strict filter here, one that doesn't allow deserialization to automatically start loading assets, nor tolerates errors. - // this is becuase this is coming from a network interface and should always be error-free. - AZ::ObjectStream::FilterDescriptor filterToUse(&AZ::Data::AssetFilterNoAssetLoading, AZ::ObjectStream::FILTERFLAG_STRICT); - value.m_data = AZ::Utils::LoadObjectFromStream(memoryStream, m_serializeContext, &value.m_typeId, filterToUse); - } - } - } - } - - private: - AZ::SerializeContext* m_serializeContext; - }; - - /** - * Specialized marshaler for AZ::DynamicSerializableField - * Mainly here to hook into the DataSet Marshaler auto detection logic, and provide a default buffer size for the actual marshaler - */ - template<> - class Marshaler - : public DynamicSerializableFieldMarshaler<1024> - { - public: - - Marshaler() - { - } - - // Mainly here for unit test purposes. - Marshaler(AZ::SerializeContext* context) - : DynamicSerializableFieldMarshaler(context) - { - } - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h b/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h deleted file mode 100644 index 0116020cc0..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once -#ifndef AZFRAMEWORK_NETWORK_ENTITYIDMARSHALER_H -#define AZFRAMEWORK_NETWORK_ENTITYIDMARSHALER_H - -#include -#include - -#include -#include - -namespace GridMate -{ - template<> - class Marshaler - { - public: - AZ_TYPE_INFO_LEGACY( Marshaler, "{23F4722F-D104-4E30-9342-43F4DDD1894D}", AZ::EntityId ); - - void Marshal(GridMate::WriteBuffer& wb, const AZ::EntityId& source) const - { - Marshaler idMarshaler; - idMarshaler.Marshal(wb,static_cast(source)); - } - - void Unmarshal(AZ::EntityId& target, GridMate::ReadBuffer& rb) const - { - AZ::u64 id = 0; - - Marshaler idMarshaler; - idMarshaler.Unmarshal(id,rb); - - target = AZ::EntityId(id); - } - }; - - template<> - class Marshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, const AZ::NamedEntityId& source) const - { - Marshaler idMarshaler; - idMarshaler.Marshal(wb, static_cast(source)); - - Marshaler stringMarshaler; - stringMarshaler.Marshal(wb, source.GetName()); - } - - void Unmarshal(AZ::NamedEntityId& target, GridMate::ReadBuffer& rb) const - { - AZ::u64 id = 0; - - Marshaler idMarshaler; - idMarshaler.Unmarshal(id, rb); - - AZStd::string name; - Marshaler stringMarshaler; - stringMarshaler.Unmarshal(name, rb); - - target = AZ::NamedEntityId(AZ::EntityId(id), name); - } - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp deleted file mode 100644 index 6aa32158f1..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include - -#include -#include -#include - -#include -#include -#include -#include - -using namespace GridMate; - -namespace AzFramework -{ - void InterestManagerComponent::Reflect(AZ::ReflectContext* context) - { - if (context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1); - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "InterestManagerComponent", "Interest manager instance") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)); - } - } - - // We need to register the chunk types for each handler here at reflect time - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(ProximityInterestChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(BitmaskInterestChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } - - void InterestManagerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("InterestManager", 0x79993873)); - } - - void InterestManagerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("InterestManager", 0x79993873)); - } - - - - InterestManagerComponent::InterestManagerComponent() - : m_im(nullptr) - , m_bitmaskHandler(nullptr) - , m_proximityHandler(nullptr) - , m_session(nullptr) - { - - } - - void InterestManagerComponent::Activate() - { - InterestManagerRequestsBus::Handler::BusConnect(); - NetBindingSystemEventsBus::Handler::BusConnect(); - AZ::SystemTickBus::Handler::BusConnect(); - } - - void InterestManagerComponent::Deactivate() - { - AZ::SystemTickBus::Handler::BusDisconnect(); - NetBindingSystemEventsBus::Handler::BusDisconnect(); - InterestManagerRequestsBus::Handler::BusDisconnect(); - - ShutdownInterestManager(); - } - - void InterestManagerComponent::OnSystemTick() - { - if (m_im && m_im->IsReady()) - { - m_im->Update(); - } - } - - InterestManager* InterestManagerComponent::GetInterestManager() - { - return m_im.get(); - } - - BitmaskInterestHandler* InterestManagerComponent::GetBitmaskInterest() - { - return m_bitmaskHandler.get(); - } - - ProximityInterestHandler* InterestManagerComponent::GetProximityInterest() - { - return m_proximityHandler.get(); - } - - void InterestManagerComponent::OnNetworkSessionActivated(GridSession* session) - { - AZ_Assert(m_session == nullptr, "Already bound to the session"); - - AZ_TracePrintf("AzFramework", "Interest manager hooked up to the session '%s'\n", session->GetId().c_str()); - - m_session = session; - m_session->GetReplicaMgr()->SetAutoBroadcast(false); - - InitInterestManager(); - } - - void InterestManagerComponent::OnNetworkSessionDeactivated(GridSession* session) - { - if (m_session && m_session == session) - { - AZ_TracePrintf("AzFramework", "Interest manager disconnected from the session '%s'\n", session ? session->GetId().c_str() : "nullptr"); - - if (m_session->GetReplicaMgr()) - { - m_session->GetReplicaMgr()->SetAutoBroadcast(true); - } - - m_session = nullptr; - ShutdownInterestManager(); - } - else - { - AZ_Warning("AzFramework", false, "Interest manager was never active for session '%s'\n", session ? session->GetId().c_str() : "nullptr"); - } - } - - void InterestManagerComponent::InitInterestManager() - { - AZ_Assert(m_im == nullptr, "Already initialized interest manager"); - m_im = AZStd::make_unique(); - - InterestManagerDesc desc; - desc.m_rm = m_session->GetReplicaMgr(); - m_im->Init(desc); - - m_bitmaskHandler = AZStd::make_unique(); - m_im->RegisterHandler(m_bitmaskHandler.get()); - - m_proximityHandler = AZStd::make_unique(); - m_im->RegisterHandler(m_proximityHandler.get()); - - InterestManagerEventsBus::Broadcast( - &InterestManagerEventsBus::Events::OnInterestManagerActivate, m_im.get()); - } - - void InterestManagerComponent::ShutdownInterestManager() - { - if (m_im) - { - InterestManagerEventsBus::Broadcast( - &InterestManagerEventsBus::Events::OnInterestManagerDeactivate, m_im.get()); - - m_im->UnregisterHandler(m_bitmaskHandler.get()); - m_im->UnregisterHandler(m_proximityHandler.get()); - - m_bitmaskHandler = nullptr; - m_proximityHandler = nullptr; - m_im = nullptr; - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h b/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h deleted file mode 100644 index de45c78d43..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H -#define AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H - - -#include -#include -#include - -#include - -#include - -namespace GridMate -{ - class InterestManager; - class GridSession; - class BitmaskInterestHandler; - class ProximityInterestHandler; -} - -namespace AzFramework -{ - class InterestManagerSystemRequests - : public AZ::EBusTraits - { - public: - virtual ~InterestManagerSystemRequests() {} - - // Returns interest manager instance - virtual GridMate::InterestManager* GetInterestManager() = 0; - - // Returns interest manager instance - virtual GridMate::BitmaskInterestHandler* GetBitmaskInterest() = 0; - - // Returns interest manager instance - virtual GridMate::ProximityInterestHandler* GetProximityInterest() = 0; - }; - - // Interface Bus - using InterestManagerRequestsBus = AZ::EBus; - - class InterestManagerEvents - : public AZ::EBusTraits - { - public: - virtual ~InterestManagerEvents() {} - - // Called when interest manager is initialized and ready to use - virtual void OnInterestManagerActivate(GridMate::InterestManager* im) { (void)im; } - - // Called when interest manager is deactivated - virtual void OnInterestManagerDeactivate(GridMate::InterestManager* im) { (void)im; } - }; - - // Interface Bus - using InterestManagerEventsBus = AZ::EBus; - - /** - * Interest manager component. - * When component is activated replicas will go through interest filtering before being sent to other peers - */ - class InterestManagerComponent - : public AZ::Component - , public AZ::SystemTickBus::Handler - , public InterestManagerRequestsBus::Handler - , public NetBindingSystemEventsBus::Handler - { - public: - AZ_COMPONENT(InterestManagerComponent, "{55371FA7-2942-4A3C-A3EA-27FF2C7DB6C5}"); - - static void Reflect(AZ::ReflectContext* context); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - - InterestManagerComponent(); - - void Activate() override; - void Deactivate() override; - - protected: - - // AZ::SystemTickBus::Listener interface implementation - void OnSystemTick() override; - - // InterestManagerSystemRequests implementation - GridMate::InterestManager* GetInterestManager() override; - GridMate::BitmaskInterestHandler* GetBitmaskInterest() override; - GridMate::ProximityInterestHandler* GetProximityInterest() override; - - // SessionEventBus - void OnNetworkSessionActivated(GridMate::GridSession* session) override; - void OnNetworkSessionDeactivated(GridMate::GridSession* session) override; - - void InitInterestManager(); - void ShutdownInterestManager(); - - // Interest handlers - AZStd::unique_ptr m_im; - AZStd::unique_ptr m_bitmaskHandler; - AZStd::unique_ptr m_proximityHandler; - - GridMate::GridSession* m_session; ///< currently bound session - - private: - InterestManagerComponent(const InterestManagerComponent&) = delete; //Cannot use default due to unique_ptr. - }; -} // namesapce AzFramework - -#endif // AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp deleted file mode 100644 index eb0e6efa47..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - //////////////// - // NetBindable - //////////////// - - NetBindable::NetBindable() - : m_isSyncEnabled(true) - { - } - - NetBindable::~NetBindable() - { - if (m_chunk) - { - // NetBindable is a base class for handlers for replica chunks, so we have to clear the handler since this object is about to go away - m_chunk->SetHandler(nullptr); - m_chunk = nullptr; - } - } - - GridMate::ReplicaChunkPtr NetBindable::GetNetworkBinding() - { - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - m_chunk = netContext->CreateReplicaChunk(azrtti_typeid(this)); - netContext->Bind(this, m_chunk, NetworkContextBindMode::Authoritative); - return m_chunk; - } - - return nullptr; - } - - void NetBindable::SetNetworkBinding (GridMate::ReplicaChunkPtr chunk) - { - m_chunk = chunk; - - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - netContext->Bind(this, m_chunk, NetworkContextBindMode::NonAuthoritative); - } - } - - void NetBindable::UnbindFromNetwork() - { - if (m_chunk) - { - // NetworkContext-reflected chunks need access to the handler when they are being destroyed, so we won't null handler in here - m_chunk = nullptr; - } - } - - void NetBindable::NetInit() - { - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - netContext->Bind(this, nullptr, NetworkContextBindMode::NonAuthoritative); - } - } - - void NetBindable::Reflect(AZ::ReflectContext* reflection) - { - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - if (serializeContext) - { - serializeContext->Class() - ->Field("m_isSyncEnabled", &NetBindable::m_isSyncEnabled); - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "Network Bindable", "Network-bindable components are synchronized over the network.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Networking") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->DataElement(AZ::Edit::UIHandlers::Default, &NetBindable::m_isSyncEnabled, "Bind To network", "Enable binding to the network."); - } - } - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h deleted file mode 100644 index 39a05c4fc1..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h +++ /dev/null @@ -1,799 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDABLE_H -#define AZFRAMEWORK_NET_BINDABLE_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * Including common GridMate marshallers. - * Otherwise, users of NetBindable/NetworkContext have to find and include them themselves. - */ -#include -#include -#include -#include -#include -#include -#include - -namespace AZ -{ - class ReflectContext; - namespace Internal - { - template - class AzFrameworkNetBindableFieldContainer; - } -} - -namespace AzFramework -{ - using GridMate::DataSetBase; - using GridMate::DataSet; - using GridMate::Marshaler; - using GridMate::BasicThrottle; - using GridMate::RpcBase; - using GridMate::TimeContext; - using GridMate::RpcContext; - using GridMate::RpcDefaultTraits; - - enum class NetworkContextBindMode - { - Authoritative, - NonAuthoritative - }; - - /** - * Components that want to be synchronized over the network should implement NetBindable. - * The NetBindable interface is obtained via AZ_RTTI so components need to make sure to - * declare NetBindable as a base class in their AZ_RTTI declaration (or AZ_COMPONENT declaration), - * as well as to declare both AZ::Component and NetBindable as base classes in the reflection. - * - * For example, here is how to mark a component for network replication in its class declaration: - * - * class TestFieldComponent - * : public AZ::Component - * , public AzFramework::NetBindable - * { - * public: - * AZ_COMPONENT(TestFieldComponent, "{DD02A926-F6B3-4820-9587-62EED9EEBB3F}", NetBindable); - * - * static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - * { - * required.push_back(AZ_CRC("ReplicaChunkService")); - * } - * - * Note, you should declare a dependency on NetBindingComponent as it is done above with "ReplicaChunkService." - * NetBindingComponent is required for an entity to be considered for network replication and replicate your NetBindable-components. - */ - class NetBindable - : public GridMate::ReplicaChunkInterface - { - public: - AZ_RTTI(NetBindable, "{80206665-D429-4703-B42E-94434F82F381}"); - - NetBindable(); - virtual ~NetBindable(); - - void NetInit(); - - //! Called during network binding on the master. The default implementation will use the - //! NetworkContext to create a chunk. User implementations should create and return a new binding. - virtual GridMate::ReplicaChunkPtr GetNetworkBinding(); - - //! Called during network binding on proxies. - virtual void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk); - - //! Called when network is unbound. Implementations should release their references to the binding, if they held a reference. - virtual void UnbindFromNetwork(); - - static void Reflect(AZ::ReflectContext* reflection); - - template , typename ThrottlerType = BasicThrottle > - class Field; - - template , typename ThrottlerType = BasicThrottle > - class BoundField; - - template - class Rpc; - - inline bool IsSyncEnabled() const { return m_isSyncEnabled; } - //! Can be used to disabled net sync on a per component basis - inline void SetSyncEnabled(bool enabled) { m_isSyncEnabled = enabled; } - protected: - bool m_isSyncEnabled; - GridMate::ReplicaChunkPtr m_chunk = nullptr; - }; - - class NetBindableFieldBase - { - public: - virtual ~NetBindableFieldBase() = default; - virtual void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) = 0; - }; - - /** - * \brief NetBindable provides a simplified network interface to mark a member variable inside AZ::Component - * as a network field that will be replicated by GridMate. - * - * \tparam DataType data type of the field, can be either a common C++ type or a custom type - * \tparam MarshalerType optional, marshaler type that provides custom marshal and unmarshal logic, i.e. how to write @DataType to the network and back, see @GridMate::Marshaler - * \tparam ThrottlerType optional, throttler provides the ability to detect if a value is to be considered changed significantly enough for GridMate to replicate its state, see @GridMate::BasicThrottle - * - * Example: - * - * class TestFieldComponent : public AZ::Component , public AzFramework::NetBindable - * { - * public: - * Field m_testInt; - * - * And it must be reflected to SerializeContext _and_ NetworkContext: - * - * void TestFieldComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt) - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt); - * } - * } - * - * Then you can simply write to it as it was an integer: - * - * m_testInt = 3; - * // or - * m_testInt = *m_testInt + 1; - */ - template - class NetBindable::Field - : public NetBindableFieldBase - { - friend class AZ::Internal::AzFrameworkNetBindableFieldContainer >; - public: - using DataSetType = DataSet; - using ValueType = DataType; - - explicit Field(const DataType& value = DataType()) - : m_dataSet(nullptr) - , m_value(value) - {} - ~Field() override = default; - - /* - * Disabling copy and move constructors in order to allow for a common use of fields, for example: - * m_field = m_field + 1; - */ - Field (const Field& other) = delete; - Field (Field&& other) = delete; - Field& operator= (const Field& other) = delete; - Field& operator= (Field&& other) = delete; - - const DataType& Get() const - { - return m_dataSet ? m_dataSet->Get() : m_value; - } - - virtual operator const DataType&() const - { - return Get(); - } - - virtual const DataType& operator*() const - { - return Get(); - } - - virtual Field& operator=(const DataType& val) - { - if (m_dataSet) - { - m_dataSet->Set(val); - } - else - { - m_value = val; - } - return *this; - } - - virtual Field& operator=(const DataType&& val) - { - if (m_dataSet) - { - m_dataSet->Set(AZStd::forward(val)); - } - else - { - m_value = AZStd::move(val); - } - return *this; - } - - void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) override - { - BindDataSet(static_cast(dataSet), mode); - } - - static void ConstructDataSet(void* mem, const char* name) - { - new (mem) DataSetType(name, DataType(), MarshalerType(), ThrottlerType()); - } - - static void DestructDataSet(void* mem) - { - DataSetType* dataSet = reinterpret_cast(mem); - dataSet->~DataSetType(); - } - - protected: - template - void BindDataSet(DST* dataSet, NetworkContextBindMode mode) - { - if (m_dataSet) - { - m_value = m_dataSet->Get(); - } - m_dataSet = dataSet; - if (m_dataSet) - { - if (mode == NetworkContextBindMode::Authoritative) - { - /* - * If we are binding Field<> or BoundField<> on a component of an authoritative entity, - * then we want to bring over the value of the field in the component. This occurs during GetNetworkBinding(). - * - * Whereas on a client's (non-authoritative entities and their components) dataSet already has the desired value - * and should not be overwritten here. - */ - m_dataSet->Set(AZStd::move(m_value)); - } - m_value = DataType(); - } - } - - DataType* CacheValue() - { - if (m_dataSet) - { - m_value = m_dataSet->Get(); - } - return &m_value; - } - - const DataType& GetCachedValue() const - { - return m_value; - } - - private: - DataSet* m_dataSet; - DataType m_value; - }; - - /** - * \brief An extension of @NetBindable::Field with an ability to invoke a callback whenever the value changes on both authoritative and non-authoritative components. - * Or in other terms, on both the server and clients (when GridMate is setup to run in server-authoritative mode). - * - * \tparam DataType data type, same as @NetBindable::Field - * \tparam InterfaceType Component type class that holds this @BoundField - * \tparam FuncPtr member function pointer to the callback to invoke when this value is updated on non-authoritative components. - * \tparam MarshalerType optional, same as @NetBindable::Field - * \tparam ThrottlerType optional, same as @NetBindable::Field - * - * Example: - * - * BoundField m_testInt; - * - * And it must be reflected to SerializeContext _and_ NetworkContext just like @NetBindable::Field - * - * void TestFieldComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt) - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt); - * } - * } - */ - template - class NetBindable::BoundField - : public NetBindable::Field - { - using BaseClass = NetBindable::Field; - friend class AZ::Internal::AzFrameworkNetBindableFieldContainer >; - public: - AZ_TYPE_INFO_LEGACY(BoundField, "{5151CEAF-6AC0-45D7-AEDF-8B6C46CE07B9}", DataType, InterfaceType, MarshalerType, ThrottlerType); - using DataSetType = typename DataSet::template BindInterface; - - explicit BoundField(const DataType& value = DataType()) - : BaseClass(value) - {} - ~BoundField() override = default; - - /* - * Disabling copy and move constructors in order to allow for a common use of fields, for example: - * m_field = m_field + 1; - */ - BoundField (const BoundField& other) = delete; - BoundField (BoundField&& other) = delete; - BoundField& operator= (const BoundField& other) = delete; - BoundField& operator= (BoundField&& other) = delete; - - operator DataType() const - { - return BaseClass::Get(); - } - - const DataType& operator*() const override - { - return BaseClass::Get(); - } - - BaseClass& operator=(const DataType& val) override - { - BaseClass::operator=(val); - return *this; - } - - BaseClass& operator=(const DataType&& val) override - { - BaseClass::operator=(val); - return *this; - } - - void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) override - { - BaseClass::BindDataSet(static_cast(dataSet), mode); - } - - static void ConstructDataSet(void* mem, const char* name) - { - new (mem) DataSetType(name, DataType(), MarshalerType(), ThrottlerType()); - } - - static void DestructDataSet(void* mem) - { - DataSetType* dataSet = reinterpret_cast(mem); - dataSet->~DataSetType(); - } - }; - - class NetBindableRpcBase - { - public: - virtual ~NetBindableRpcBase() = default; - virtual void Bind(RpcBase* rpc) = 0; - virtual void Bind(NetBindable* handler) = 0; - }; - - /** - * \brief NetBindable::Rpc::Binder should be used for any RPC in a NetBindable that you want - * to be able to call remotely. If the object is not network bound, RPC - * calls will dispatch directly, as if the object was authoritative. - * - * \tparam Args any custom parameters for the remote procedure calls. - * - * Here is an example: - * - * // callback - * bool OnRpc(float value, const GridMate::RpcContext& rc); - * - * // Rpc declaration - * Rpc::Binder m_testRpc; - * - * Rpc needs to be reflected in NetworkContext like this: - * - * void TestRPCComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->RPC("Test RPC", &TestRPCComponent::m_testRpc); - * } - * } - * - * It can be invoked as if it was a method: - * - * m_testRpc(deltaTime); - */ - template - class NetBindable::Rpc - { - public: - /** - * \brief Binds rpc callback to a pointer to member function of AZ::Component derived from AzFramework::NetBindable - * See @NetBindable::Rpc - */ - template - class Binder - : public NetBindableRpcBase - { - friend class NetworkContext; - public: - using BindInterfaceType = typename GridMate::Rpc...>::template BindInterface; - - Binder() - : m_rpc(nullptr) - , m_instance(nullptr) - {} - - void Bind(RpcBase* rpc) override - { - m_rpc = static_cast(rpc); - m_instance = nullptr; - } - - void Bind(NetBindable* bindable) override - { - m_instance = static_cast(bindable); - m_rpc = nullptr; - } - - template - void operator()(CallArgs&& ... args) - { - AZ_Assert(m_instance || m_rpc, "Cannot call an RPC without either a local instance or a network bound handler, did you forget to register with NetworkContext()?"); - if (m_rpc) // connected to network - { - (*m_rpc)(AZStd::forward(args) ...); - } - else if (m_instance) // local dispatch - { - (*m_instance.*FuncPtr)(AZStd::forward(args) ..., RpcContext()); - } - } - - protected: - static void ConstructRpc(void* mem, const char* name) - { - new (mem) BindInterfaceType(name); - } - - static void DestructRpc(void*) { } - - private: - BindInterfaceType* m_rpc; - InterfaceType* m_instance; - }; - - Rpc() = delete; - }; -} // namespace AzFramework - -namespace AZ -{ - AZ_TYPE_INFO_TEMPLATE_WITH_NAME(AzFramework::NetBindable::Field, "Field", "{00D56FA7-F8BD-402B-97FB-0E2599897056}", AZ_TYPE_INFO_CLASS, AZ_TYPE_INFO_TYPENAME, AZ_TYPE_INFO_TYPENAME); - - namespace Internal - { - template - class AzFrameworkNetBindableFieldContainer - : public SerializeContext::IDataContainer - { - using ValueType = typename FieldType::ValueType; - public: - AzFrameworkNetBindableFieldContainer() - { - m_classElement.m_name = GetDefaultElementName(); - m_classElement.m_nameCrc = GetDefaultElementNameCrc(); - m_classElement.m_dataSize = sizeof(ValueType); - m_classElement.m_offset = 0; - m_classElement.m_azRtti = GetRttiHelper(); - m_classElement.m_flags = AZStd::is_pointer::value ? SerializeContext::ClassElement::FLG_POINTER : 0; - m_classElement.m_genericClassInfo = SerializeGenericTypeInfo::GetGenericInfo(); - m_classElement.m_typeId = SerializeGenericTypeInfo::GetClassTypeId(); - m_classElement.m_editData = nullptr; - } - - /// Returns the element generic (offsets are mostly invalid 0xbad0ffe0, there are exceptions). Null if element with this name can't be found. - virtual const SerializeContext::ClassElement* GetElement(AZ::u32 elementNameCrc) const override - { - if (elementNameCrc == m_classElement.m_nameCrc) - { - return &m_classElement; - } - return nullptr; - } - - bool GetElement(SerializeContext::ClassElement& classElement, const SerializeContext::DataElement& dataElement) const override - { - if (dataElement.m_nameCrc == m_classElement.m_nameCrc) - { - classElement = m_classElement; - return true; - } - return false; - } - - /// Enumerate elements in the array - virtual void EnumElements(void* instance, const ElementCB& cb) override - { - FieldType* field = reinterpret_cast(instance); - // We can't mess with the internal storage of the dataset safely, so we copy it into - // the field's local value cache temporarily, then hand that to the callback - // This will modify the local value cache, but that shouldn't matter as it will never - // be used as long as a dataset is bound - // If this turns out to be a perf problem due to copies of complex types, then - // the easy solution is to get DataSets to expose a pointer to their underlying - // data storage, and then we can return a pointer to that and modify it directly - // if the field is bound to the network - ValueType* valPtr = field->CacheValue(); - cb(valPtr, m_classElement.m_typeId, m_classElement.m_genericClassInfo ? m_classElement.m_genericClassInfo->GetClassData() : nullptr, &m_classElement); - // Ensure that the dataset is updated if changes happened - *field = *valPtr; - } - - void EnumTypes(const ElementTypeCB& cb) override - { - cb(m_classElement.m_typeId, &m_classElement); - } - - /// Return number of elements in the container. - virtual size_t Size(void*) const override - { - return 1; - } - - /// Returns the capacity of the container. Returns 0 for objects without fixed capacity. - virtual size_t Capacity(void* instance) const override - { - (void)instance; - return 1; - } - - /// Returns true if elements pointers don't change on add/remove. If false you MUST enumerate all elements. - virtual bool IsStableElements() const override { return true; } - - /// Returns true if the container is fixed size, otherwise false. - virtual bool IsFixedSize() const override { return true; } - - /// Returns if the container is fixed capacity, otherwise false - virtual bool IsFixedCapacity() const override { return true; } - - /// Returns true if the container is a smart pointer. - virtual bool IsSmartPointer() const override { return true; } - - /// Returns true if the container elements can be addressed by index, otherwise false. - virtual bool CanAccessElementsByIndex() const override { return false; } - - /// Reserve element - virtual void* ReserveElement(void* instance, const SerializeContext::ClassElement*) override - { - FieldType* field = reinterpret_cast(instance); - *field = ValueType(); - return field->CacheValue(); // return the local value, should be accurate as the field will be unbound at serialization time - } - - /// Get an element's address by its index (called before the element is loaded). - virtual void* GetElementByIndex(void*, const SerializeContext::ClassElement*, size_t) override - { - return nullptr; - } - - /// Store element - virtual void StoreElement(void* instance, void*) override - { - // force store the value again, just in case the field is bound to a dataset - FieldType* field = reinterpret_cast(instance); - *field = field->GetCachedValue(); - } - - /// Remove element in the container. - virtual bool RemoveElement(void* instance, const void*, SerializeContext*) override - { - FieldType* field = reinterpret_cast(instance); - *field = ValueType(); - return false; // you can't remove element from this container. - } - - /// Remove elements (removed array of elements) regardless if the container is Stable or not (IsStableElements) - virtual size_t RemoveElements(void* instance, const void**, size_t, SerializeContext*) override - { - RemoveElement(instance, nullptr, nullptr); - return 0; // you can't remove elements from this container. - } - - /// Clear elements in the instance. - virtual void ClearElements(void* instance, SerializeContext*) override - { - RemoveElement(instance, nullptr, nullptr); - } - - SerializeContext::ClassElement m_classElement; ///< Generic class element covering as must as possible of the element (offset, and some other fields are invalid) - }; - } - - template - struct SerializeGenericTypeInfo< AzFramework::NetBindable::Field > - { - typedef typename AzFramework::NetBindable::Field ContainerType; - - class GenericClassNetBindableField - : public GenericClassInfo - { - public: - AZ_TYPE_INFO(GenericClassNetBindableField, "{C1D4DD97-5DD7-42ED-969C-7435F27F5D8C}"); - GenericClassNetBindableField() - : m_classData{ SerializeContext::ClassData::Create("AzFramework::NetBindable::Field", GetSpecializedTypeId(), Internal::NullFactory::GetInstance(), nullptr, &m_containerStorage) } - { - } - - SerializeContext::ClassData* GetClassData() override - { - return &m_classData; - } - - size_t GetNumTemplatedArguments() override - { - return 1; - } - - const Uuid& GetTemplatedTypeId(size_t) override - { - return SerializeGenericTypeInfo::GetClassTypeId(); - } - - const Uuid& GetSpecializedTypeId() const override - { - return azrtti_typeid(); - } - - const Uuid& GetGenericTypeId() const override - { - return TYPEINFO_Uuid(); - } - - const Uuid& GetLegacySpecializedTypeId() const override - { - return AZ::AzTypeInfo::template Uuid(); - } - - void Reflect(SerializeContext* serializeContext) - { - if (serializeContext) - { - serializeContext->RegisterGenericClassInfo(GetSpecializedTypeId(), this, &AnyTypeInfoConcept::CreateAny); - if (GenericClassInfo* containerGenericClassInfo = m_containerStorage.m_classElement.m_genericClassInfo) - { - containerGenericClassInfo->Reflect(serializeContext); - } - } - } - - protected: - Internal::AzFrameworkNetBindableFieldContainer m_containerStorage; - SerializeContext::ClassData m_classData; - }; - - using ClassInfoType = GenericClassNetBindableField; - - static ClassInfoType* GetGenericInfo() - { - return GetCurrentSerializeContextModule().CreateGenericClassInfo(); - } - - static const Uuid& GetClassTypeId() - { - return GetGenericInfo()->GetClassData()->m_typeId; - } - }; - - template - struct SerializeGenericTypeInfo< typename AzFramework::NetBindable::BoundField > - { - typedef typename AzFramework::NetBindable::BoundField ContainerType; - - class GenericClassNetBindableBoundField - : public GenericClassInfo - { - public: - AZ_TYPE_INFO(GenericClassNetBindableBoundField, "{EFD64FE7-9432-401A-B7A1-1767F4C5A7F0}"); - GenericClassNetBindableBoundField() - : m_classData{ SerializeContext::ClassData::Create("AzFramework::NetBindable::BoundField", GetSpecializedTypeId(), Internal::NullFactory::GetInstance(), nullptr, &m_containerStorage) } - { - } - - SerializeContext::ClassData* GetClassData() override - { - return &m_classData; - } - - size_t GetNumTemplatedArguments() override - { - return 1; - } - - const Uuid& GetTemplatedTypeId(size_t) override - { - return SerializeGenericTypeInfo::GetClassTypeId(); - } - - const Uuid& GetSpecializedTypeId() const override - { - return azrtti_typeid(); - } - - const Uuid& GetGenericTypeId() const override - { - return TYPEINFO_Uuid(); - } - - const Uuid& GetLegacySpecializedTypeId() const override - { - return AZ::AzTypeInfo::template Uuid(); - } - - void Reflect(SerializeContext* serializeContext) - { - if (serializeContext) - { - serializeContext->RegisterGenericClassInfo(GetSpecializedTypeId(), this, &AnyTypeInfoConcept::CreateAny); - if (GenericClassInfo* containerGenericClassInfo = m_containerStorage.m_classElement.m_genericClassInfo) - { - containerGenericClassInfo->Reflect(serializeContext); - } - } - } - - protected: - Internal::AzFrameworkNetBindableFieldContainer m_containerStorage; - SerializeContext::ClassData m_classData; - }; - - using ClassInfoType = GenericClassNetBindableBoundField; - - static ClassInfoType* GetGenericInfo() - { - return GetCurrentSerializeContextModule().CreateGenericClassInfo(); - } - - static const Uuid& GetClassTypeId() - { - return GetGenericInfo()->GetClassData()->m_typeId; - } - }; -} - -#endif // AZFRAMEWORK_NET_BINDABLE_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp deleted file mode 100644 index 90613daabe..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - void NetBindingComponent::Reflect(AZ::ReflectContext* reflection) - { - NetBindable::Reflect(reflection); - - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - if (serializeContext) - { - serializeContext->Class() - ; - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "Network Binding", "The Network Binding component marks an entity as able to be replicated across the network") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Networking") - ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NetBinding.svg") - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/NetBinding.png") - ->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-network-binding.html") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)); - } - } - - AZ::BehaviorContext* behaviorContext = azrtti_cast(reflection); - - if (behaviorContext) - { - behaviorContext->EBus("NetBindingHandlerBus") - ->Event("IsEntityBoundToNetwork", &NetBindingHandlerBus::Events::IsEntityBoundToNetwork) - ->Event("IsEntityAuthoritative", &NetBindingHandlerBus::Events::IsEntityAuthoritative) - - // Desired, but currently unsupported events. - // Seems to be an unsupported type(AZ::u16) - //->Event("SetReplicaPriority", &NetBindingHandlerBus::Events::SetReplicaPriority) - //->Event("GetReplicaPriority", &NetBindingHandlerBus::Events::GetReplicaPriority) - ; - } - - // We also need to register the chunk type, and this would be a good time to do so. - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(NetBindingComponentChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - - NetBindingComponent::NetBindingComponent() - : m_isLevelSliceEntity(false) - { - } - - void NetBindingComponent::Activate() - { - NetBindingHandlerBus::Handler::BusConnect(GetEntityId()); - - if (!IsEntityBoundToNetwork()) - { - bool shouldBind = false; - NetBindingSystemBus::BroadcastResult( shouldBind, &NetBindingSystemBus::Events::ShouldBindToNetwork); - if (shouldBind) - { - BindToNetwork(nullptr); - } - else - { - /* - * This is the Editor path. We still need to call NetBindable::NetInit() in order - * to initialize NetworkContext Fields and RPCs, so that they behave as - * authoritative in game editor mode. Without this call RPCs callbacks won't invoke inside the Editor. - * For example: - * - * static void Reflect(...) - * { - * NetworkContext->Class()->RPC("my rpc", &MyNetworkComponent::m_myRpc); - * } - * ... - * m_myRpc(); // <--- will not invoke the callback inside the Editor unless NetInit() is called below. - */ - for (Component* component : GetEntity()->GetComponents()) - { - if (NetBindable* netBindable = azrtti_cast(component)) - { - netBindable->NetInit(); - } - } - } - } - } - - void NetBindingComponent::Deactivate() - { - NetBindingHandlerBus::Handler::BusDisconnect(); - if (IsEntityBoundToNetwork()) - { - static_cast(m_chunk.get())->SetBinding(nullptr); - if (m_chunk->IsMaster()) - { - m_chunk->GetReplica()->Destroy(); - } - m_chunk = nullptr; - } - } - - bool NetBindingComponent::IsEntityBoundToNetwork() - { - return m_chunk && m_chunk->GetReplica(); - } - - bool NetBindingComponent::IsEntityAuthoritative() - { - return !m_chunk || m_chunk->IsMaster(); - } - - void NetBindingComponent::BindToNetwork(GridMate::ReplicaPtr bindTo) - { - AZ_Assert(!IsEntityBoundToNetwork(), "We shouldn't be bound to the network if the network is just starting!"); - - if (bindTo) - { - NetBindingComponentChunkPtr bindingChunk = bindTo->FindReplicaChunk(); - AZ_Assert(bindingChunk, "Can't find NetBindingComponentChunk!"); - m_chunk = bindingChunk; - bindingChunk->SetBinding(this); - - GridMate::Replica* replica = bindingChunk->GetReplica(); - size_t nChunks = replica->GetNumChunks(); - size_t nBindings = bindingChunk->m_bindMap.Get().size(); - AZ_Assert(nChunks == nBindings, "Number of chunks received is not the same as the size of the bind map!"); - nBindings = AZ::GetMin(nBindings, nChunks); - for (size_t i = 0; i < nBindings; ++i) - { - AZ::ComponentId bindToId = bindingChunk->m_bindMap.Get()[i]; - if (bindToId != AZ::InvalidComponentId) - { - AZ::Component* component = GetEntity()->FindComponent(bindToId); - NetBindable* netBindable = azrtti_cast(component); - AZ_Assert(netBindable, "Can't find net bindable component with id %llu to be bound to chunk type %s!", bindToId, replica->GetChunkByIndex(i)->GetDescriptor()->GetChunkName()); - if (netBindable && netBindable->IsSyncEnabled()) - { - netBindable->SetNetworkBinding(replica->GetChunkByIndex(i)); - } - } - } - } - else - { - GridMate::ReplicaPtr replica = GridMate::Replica::CreateReplica(GetEntity()->GetName().c_str()); - NetBindingComponentChunk* chunk = GridMate::CreateReplicaChunk(); - m_chunk = chunk; - chunk->SetBinding(this); - replica->AttachReplicaChunk(chunk); - - chunk->m_bindMap.Modify([&](AZStd::vector& bindMap) - { - // Mark the chunks already in the replica as non-components. - bindMap.resize(replica->GetNumChunks(), AZ::InvalidComponentId); - - // Collect the bindings and add the to the replica - AZ::Entity* entity = GetEntity(); - for (Component* component : entity->GetComponents()) - { - NetBindable* netBindable = azrtti_cast(component); - if (netBindable && netBindable->IsSyncEnabled()) - { - GridMate::ReplicaChunkPtr bindingChunk = netBindable->GetNetworkBinding(); - if (bindingChunk) - { - bindMap.push_back(component->GetId()); - replica->AttachReplicaChunk(bindingChunk); - } - } - } - return true; - }); - - // Add replica to session replica manager (may be deferred) - NetBindingSystemBus::Broadcast( &NetBindingSystemBus::Events::AddReplicaMaster, GetEntity(), replica); - } - } - - void NetBindingComponent::UnbindFromNetwork() - { - if (m_chunk) - { - for (Component* component : GetEntity()->GetComponents()) - { - NetBindable* netBindable = azrtti_cast(component); - if (netBindable && netBindable->IsSyncEnabled()) - { - netBindable->UnbindFromNetwork(); - } - } - - NetBindingComponentChunkPtr chunk = static_cast(m_chunk.get()); - chunk->SetBinding(nullptr); - m_chunk = nullptr; - if (chunk->IsProxy()) - { - EntityContextId contextId = EntityContextId::CreateNull(); - EntityIdContextQueryBus::EventResult( contextId, GetEntityId(), &EntityIdContextQueryBus::Events::GetOwningContextId); - if (contextId.IsNull()) - { - delete GetEntity(); - } - else if (!IsLevelSliceEntity()) - { - NetBindingSystemBus::Broadcast( &NetBindingSystemBus::Events::UnbindGameEntity, GetEntityId(), m_sliceInstanceId); - } - } - } - } - - void NetBindingComponent::MarkAsLevelSliceEntity() - { - AZ_Assert(!IsEntityBoundToNetwork(), "MarkAsLevelSliceEntity() has to be called before the entity is bound to the network!"); - m_isLevelSliceEntity = true; - } - - void NetBindingComponent::SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - m_sliceInstanceId = sliceInstanceId; - } - - void NetBindingComponent::RequestEntityChangeOwnership(GridMate::PeerId peerId) - { - if (m_chunk && m_chunk->GetReplica()) - { - m_chunk->GetReplica()->RequestChangeOwnership(peerId); - } - } - - void NetBindingComponent::SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) - { - if (m_chunk) - { - m_chunk->SetPriority(replicaPriority); - } - } - - GridMate::ReplicaPriority NetBindingComponent::GetReplicaPriority() const - { - if (m_chunk && m_chunk->GetReplica()) - { - return m_chunk->GetReplica()->GetPriority(); - } - else - { - AZ_Error("NetBindingComponent",false,"Trying to gather ReplicaPriority without having a Replica."); - return GridMate::k_replicaPriorityLowest; - } - } - - bool NetBindingComponent::IsLevelSliceEntity() const - { - return m_isLevelSliceEntity; - } -} // namespace AzFramework - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h deleted file mode 100644 index 5f4ec1c7f3..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_COMPONENT_H -#define AZFRAMEWORK_NET_BINDING_COMPONENT_H - -#include -#include - -namespace AzFramework -{ - /** - * NetBindingComponent enables network synchronization for the entity. - * It works in conjunction with NetBindingComponentChunk and NetBindingSystemComponent - * to perform network binding and notifies other components on the entity to bind - * their ReplicaChunks via the NetBindable interface. - * - * Entities bound to proxy replicas will be automatically destroyed when they are - * unbound from the network. - */ - class NetBindingComponent - : public AZ::Component - , public NetBindingHandlerBus::Handler - { - friend class NetBindingComponentChunk; - - public: - AZ_COMPONENT(NetBindingComponent, "{E9CA5D63-ED2D-4B59-B3C4-EBCD4A0013E4}", NetBindingHandlerInterface); - - NetBindingComponent(); - - protected: - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("ReplicaChunkService", 0xf86b88a8)); - } - - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("ReplicaChunkService", 0xf86b88a8)); - } - - /////////////////////////////////////////////////////////////////////// - // AZ::Component - static void Reflect(AZ::ReflectContext* reflection); - void Activate() override; - void Deactivate() override; - /////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////// - // NetBindingHandlerBus::Handler - void BindToNetwork(GridMate::ReplicaPtr bindTo) override; - void UnbindFromNetwork() override; - bool IsEntityBoundToNetwork() override; - bool IsEntityAuthoritative() override; - void MarkAsLevelSliceEntity() override; - void SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) override; - void RequestEntityChangeOwnership(GridMate::PeerId peerId = GridMate::InvalidReplicaPeerId) override; - - void SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) override; - GridMate::ReplicaPriority GetReplicaPriority() const override; - /////////////////////////////////////////////////////////////////////// - - //! Returns if the entity belongs to the level slice for binding purposes. - bool IsLevelSliceEntity() const; - - //! Points to the NetBindingComponentChunk counterpart. - GridMate::ReplicaChunkPtr m_chunk; - bool m_isLevelSliceEntity; - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_COMPONENT_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp deleted file mode 100644 index 6ebfe63507..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - NetBindingComponentChunk::SpawnInfo::SpawnInfo() - : m_runtimeEntityId(AZ::EntityId::InvalidEntityId) - , m_owningContextId(UnspecifiedNetBindingContextSequence) - , m_staticEntityId(AZ::EntityId::InvalidEntityId) - , m_sliceInstanceId(UnspecifiedSliceInstanceId) - , m_sliceAssetId(UnspecifiedSliceInstanceId, 0) - { - } - - bool NetBindingComponentChunk::SpawnInfo::operator==(const SpawnInfo& rhs) - { - return m_owningContextId == rhs.m_owningContextId - && m_runtimeEntityId == rhs.m_runtimeEntityId - && m_staticEntityId == rhs.m_staticEntityId - && m_serializedState == rhs.m_serializedState - && m_sliceAssetId == rhs.m_sliceAssetId; - } - - bool NetBindingComponentChunk::SpawnInfo::ContainsSerializedState() const - { - return !m_serializedState.empty(); - } - - void NetBindingComponentChunk::SpawnInfo::Marshaler::Marshal(GridMate::WriteBuffer& wb, const SpawnInfo& data) - { - wb.Write(data.m_owningContextId, GridMate::VlqU32Marshaler()); - wb.Write(data.m_runtimeEntityId); - - bool useSerializedState = data.ContainsSerializedState(); - wb.Write(useSerializedState); - if (useSerializedState) - { - wb.Write(data.m_serializedState); - } - else - { - wb.Write(data.m_sliceAssetId); - wb.Write(data.m_staticEntityId); - wb.Write(data.m_sliceInstanceId); - } - } - - void NetBindingComponentChunk::SpawnInfo::Marshaler::Unmarshal(SpawnInfo& data, GridMate::ReadBuffer& rb) - { - rb.Read(data.m_owningContextId, GridMate::VlqU32Marshaler()); - rb.Read(data.m_runtimeEntityId); - - bool hasSerializedState = false; - rb.Read(hasSerializedState); - if (hasSerializedState) - { - rb.Read(data.m_serializedState); - } - else - { - rb.Read(data.m_sliceAssetId); - rb.Read(data.m_staticEntityId); - rb.Read(data.m_sliceInstanceId); - } - } - - NetBindingComponentChunk::NetBindingComponentChunk() - : m_bindingComponent(nullptr) - , m_spawnInfo("SpawnInfo") - , m_bindMap("ComponentBindMap") - { - m_spawnInfo.SetMaxIdleTime(0.f); - m_bindMap.SetMaxIdleTime(0.f); - } - - void NetBindingComponentChunk::OnReplicaActivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - if (IsMaster()) - { - // Get and store entity spawn data - AZ_Assert(m_bindingComponent, "Entity binding is invalid!"); - - m_spawnInfo.Modify([&](SpawnInfo& spawnInfo) - { - spawnInfo.m_runtimeEntityId = static_cast(m_bindingComponent->GetEntity()->GetId()); - - bool isProceduralEntity = true; - AZ::SliceComponent::SliceInstanceAddress sliceInfo; - - EntityContextId contextId = EntityContextId::CreateNull(); - const AZ::EntityId bindingComponentEntityId = m_bindingComponent->GetEntityId(); - EntityIdContextQueryBus::EventResult(contextId, bindingComponentEntityId, - &EntityIdContextQueryBus::Events::GetOwningContextId); - if (!contextId.IsNull()) - { - EBUS_EVENT_RESULT(spawnInfo.m_owningContextId, NetBindingSystemBus, GetCurrentContextSequence); - SliceEntityRequestBus::EventResult(sliceInfo, bindingComponentEntityId, - &SliceEntityRequestBus::Events::GetOwningSlice); - bool isDynamicSliceEntity = sliceInfo.IsValid(); - - isProceduralEntity = !m_bindingComponent->IsLevelSliceEntity() && !isDynamicSliceEntity; - } - - if (isProceduralEntity) - { - // write cloning info - AZ::SerializeContext* sc = nullptr; - EBUS_EVENT_RESULT(sc, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(sc, "Can't find SerializeContext!"); - AZ::IO::ByteContainerStream> spawnDataStream(&spawnInfo.m_serializedState); - AZ::ObjectStream* objStream = AZ::ObjectStream::Create(&spawnDataStream, *sc, AZ::DataStream::ST_BINARY); - objStream->WriteClass(m_bindingComponent->GetEntity()); - objStream->Finalize(); - } - else - { - // write slice info - if (sliceInfo.IsValid()) - { - AZ::Data::AssetId sliceAssetId = sliceInfo.GetReference()->GetSliceAsset().GetId(); - spawnInfo.m_sliceAssetId = AZStd::make_pair(sliceAssetId.m_guid, sliceAssetId.m_subId); - } - if (sliceInfo.GetInstance()) - { - spawnInfo.m_sliceInstanceId = sliceInfo.GetInstance()->GetId(); - } - - AZ::EntityId staticEntityId; - EBUS_EVENT_RESULT(staticEntityId, NetBindingSystemBus, GetStaticIdFromEntityId, m_bindingComponent->GetEntity()->GetId()); - spawnInfo.m_staticEntityId = static_cast(staticEntityId); - } - - return true; - }); - } - else - { - AZ::EntityId runtimeEntityId(m_spawnInfo.Get().m_runtimeEntityId); - NetBindingContextSequence owningContextId = m_spawnInfo.Get().m_owningContextId; - - //TODO Move to Filter Hook - // Reject and cancel sessions with duplicate MachineIds? - // Reject and cancel sessions with duplicate entity ID creation requests? - //Check MachineId collision - bool collision = AZ::Entity::GetProcessSignature() == (m_spawnInfo.Get().m_runtimeEntityId & 0xFFFFFFFF); - AZ_Error("GridMate", !collision, "Replica received with duplicate Entity Machine IDs. Ignoring"); - - if (!collision) - { - //Check EntityID collision - AZ::Entity* entity = nullptr; - EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, runtimeEntityId); - - /* - * Only false if no machine ID collision and no entity ID collision - * And the entity is already active, it's possible the entity already exists in deactivated state as a cache mechanism - */ - collision = (entity != nullptr) && (entity->GetState() == AZ::Entity::State::Active); - } - - /** - * Special case - static entities should not count as duplicates. - * Static entities are loaded with the level and will be bounded here. - */ - if (collision) - { - AZ::EntityId staticEntityId; - EBUS_EVENT_RESULT(staticEntityId, NetBindingSystemBus, GetStaticIdFromEntityId, runtimeEntityId); - if (staticEntityId == runtimeEntityId) - { - collision = false; - } - } - - if (!collision) //Ignore duplicate runtime entity IDs - { - if (m_spawnInfo.Get().ContainsSerializedState()) - { - // Spawn the entity from stream input data - AZ::IO::MemoryStream spawnData(m_spawnInfo.Get().m_serializedState.data(), m_spawnInfo.Get().m_serializedState.size()); - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromStream, spawnData, runtimeEntityId, GetReplicaId(), owningContextId); - } - else - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = owningContextId; - spawnContext.m_sliceAssetId = AZ::Data::AssetId(m_spawnInfo.Get().m_sliceAssetId.first, m_spawnInfo.Get().m_sliceAssetId.second); - spawnContext.m_runtimeEntityId = runtimeEntityId; - spawnContext.m_staticEntityId = AZ::EntityId(m_spawnInfo.Get().m_staticEntityId); - spawnContext.m_sliceInstanceId = m_spawnInfo.Get().m_sliceInstanceId; - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, GetReplicaId(), spawnContext); - } - } - else //Fail early to prevent unnecessary spawning of duplicate entity IDs - { - //Misconfiguration or potential cheating/DoS? - AZ_Warning("NetBinding", false, "Received duplicate Entity ID %llu. Ignoring.", runtimeEntityId); - } - } - } - - void NetBindingComponentChunk::OnReplicaDeactivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - if (m_bindingComponent) - { - m_bindingComponent->UnbindFromNetwork(); - } - } - - bool NetBindingComponentChunk::AcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) - { - bool result = true; - - if (m_bindingComponent) - { - EBUS_EVENT_ID_RESULT(result, m_bindingComponent->GetEntityId(), NetBindingEventsBus, OnEntityAcceptChangeOwnership, requestor, rc); - } - - return result; - } - - void NetBindingComponentChunk::OnReplicaChangeOwnership(const GridMate::ReplicaContext& rc) - { - if (m_bindingComponent) - { - EBUS_EVENT_ID(m_bindingComponent->GetEntityId(), NetBindingEventsBus, OnEntityChangeOwnership, rc); - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h deleted file mode 100644 index 5a0f023fa2..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H -#define AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H - -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - class NetBindingComponent; - class NetBindingComponentChunkDescriptor; - - /** - * NetBindingComponentChunk is the counterpart of NetBindingComponent on the network side. - * It contains entity spawn data. It is created by NetBindingComponent during network - * binding on the master and initiates entity creation and binding on the proxy side. - */ - class NetBindingComponentChunk - : public GridMate::ReplicaChunk - { - friend NetBindingComponent; - friend NetBindingComponentChunkDescriptor; - - public: - AZ_CLASS_ALLOCATOR(NetBindingComponentChunk, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingComponentChunk"; } - - NetBindingComponentChunk(); - - void SetBinding(NetBindingComponent* bindingComponent) { m_bindingComponent = bindingComponent; } - NetBindingComponent* GetBinding() const { return m_bindingComponent; } - - protected: - /////////////////////////////////////////////////////////////////////// - // ReplicaChunk - bool IsReplicaMigratable() override { return true; } - void OnReplicaActivate(const GridMate::ReplicaContext& rc) override; - void OnReplicaDeactivate(const GridMate::ReplicaContext& rc) override; - bool AcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) override; - void OnReplicaChangeOwnership(const GridMate::ReplicaContext& rc) override; - /////////////////////////////////////////////////////////////////////// - - NetBindingComponent* m_bindingComponent; - - class SpawnInfo - { - public: - class Marshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, const SpawnInfo& data); - void Unmarshal(SpawnInfo& data, GridMate::ReadBuffer& rb); - }; - - class Throttle - { - public: - //! Always return true because SpawnInfo never changes - bool WithinThreshold(const SpawnInfo&) const { return true; } - void UpdateBaseline(const SpawnInfo& baseline) { (void)baseline; } - }; - - SpawnInfo(); - - bool operator==(const SpawnInfo& rhs); - - bool ContainsSerializedState() const; - - /** - * \brief Same as m_staticEntityId on authoritative entity with master replica - */ - AZ::u64 m_runtimeEntityId; - NetBindingContextSequence m_owningContextId; - AZStd::vector m_serializedState; - - /** - * \brief EntityId of authoritative entity with master replica - */ - AZ::u64 m_staticEntityId; - - AZStd::pair m_sliceAssetId; - /** - * \brief uniquely identifies the slice instance that this entity is being replicated from - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; - - GridMate::DataSet m_spawnInfo; - GridMate::DataSet > m_bindMap; - }; - typedef AZStd::intrusive_ptr NetBindingComponentChunkPtr; -} // namespace AZ - -#endif // AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h deleted file mode 100644 index f3089947dc..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H -#define AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H - -#include -#include -#include - -namespace AzFramework -{ - /** - * NetBindingEventsBus - * Throws networking related entity events - */ - class NetBindingEvents - : public AZ::EBusTraits - { - public: - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - typedef AZ::EntityId BusIdType; - - virtual ~NetBindingEvents() {} - - /** - * Called on authoritative(Master) entity when ownership of this entity is about to be transferred to another peer - * Returning false from this call will result in denying request for ownership transfer - */ - virtual bool OnEntityAcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) { (void)requestor; (void)rc; return true; } - - /** - * Called when ownership transfer of an entity is finished. - */ - virtual void OnEntityChangeOwnership(const GridMate::ReplicaContext& rc) { (void)rc; } - }; - - typedef AZ::EBus NetBindingEventsBus; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h deleted file mode 100644 index 55fa4c0217..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H -#define AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H - -#include -#include -#include -#include -#include - -namespace AzFramework -{ - /** - * The NetBindingSystemComponent notifies net binding handlers of binding events on this bus. - * The net binding component implements this interface and listens on the NetBindingHandlerBus. - */ - class NetBindingHandlerInterface - : public AZ::EBusTraits - { - public: - AZ_RTTI(NetBindingHandlerInterface, "{9F84E9FE-81A0-4105-9C51-6C42C83FECAF}"); - - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - typedef AZ::EntityId BusIdType; - - virtual ~NetBindingHandlerInterface() {} - - /** - * Called to let the entity know that it should bind to the network. - * If bindTo is set, it means that the entity is a proxy and the handler - * should bind the entity to the specified - * replica, otherwise it should bind to a new replica and add it via - * NetBindingSystemBus::AddReplicaMaster. - */ - virtual void BindToNetwork(GridMate::ReplicaPtr bindTo) = 0; - - /** - * Called to let the entity know that it should unbind from the network. - */ - virtual void UnbindFromNetwork() = 0; - - /** - * Returns true if the entity is bound to the network. - */ - virtual bool IsEntityBoundToNetwork() = 0; - - /** - * Returns true if the entity is authoritative on the local node. - */ - virtual bool IsEntityAuthoritative() = 0; - - /** - * Flags the entity as part of the level slice. - */ - virtual void MarkAsLevelSliceEntity() = 0; - - /** - * Set the slice instance id that this entity was spawned by and belongs to. - */ - virtual void SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) = 0; - - /** - * Sets the Replica Priority - */ - virtual void SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) = 0; - - /** - * Request entity ownership to a given peer (by default to local peer) - */ - virtual void RequestEntityChangeOwnership(GridMate::PeerId peerId = GridMate::InvalidReplicaPeerId) = 0; - - /** - * Gets the Replica Priority - */ - virtual GridMate::ReplicaPriority GetReplicaPriority() const = 0; - }; - typedef AZ::EBus NetBindingHandlerBus; - - /** - * Set of queries that might want to be made about the networking system - * mainly wraps up EBus calls to keep the implementing code a bit more readable - */ - class NetQuery - { - public: - AZ_RTTI(NetQuery, "{AA4C5699-889D-4A73-9AD2-53EB03D8BB99}"); - - virtual ~NetQuery() = default; - - static AZ_FORCE_INLINE bool IsEntityAuthoritative(AZ::EntityId entityId) - { - bool result = true; - EBUS_EVENT_ID_RESULT(result,entityId,NetBindingHandlerBus,IsEntityAuthoritative); - return result; - } - }; - -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h deleted file mode 100644 index c26c6d6350..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#ifndef AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H -#define AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H - -#include -#include -#include -#include -#include -#include - -namespace AZ -{ - namespace IO - { - class GenericStream; - } -} - -namespace AzFramework -{ - const AZ::SliceComponent::SliceInstanceId UnspecifiedSliceInstanceId = AZ::Uuid::CreateNull(); - - /** - */ - typedef AZ::u32 NetBindingContextSequence; - const NetBindingContextSequence UnspecifiedNetBindingContextSequence = 0; - - /** - */ - struct NetBindingSliceContext - { - NetBindingContextSequence m_contextSequence; - AZ::Data::AssetId m_sliceAssetId; - AZ::EntityId m_staticEntityId; - AZ::EntityId m_runtimeEntityId; - /** - * \brief uniquely identifies the slice instance that this entity is being replicated from - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; - - /** - * The net binding system implements this interface and listens on the NetBindingSystemBus. - * - * Network binding is activated when OnNetworkSessionActivated event is received with the binding session, - * and is deactivated by the OnNetworkSessionDeactivated event. - */ - class NetBindingSystemInterface - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - virtual ~NetBindingSystemInterface() {} - - //! Returns true if a network session is available and entities should bind themselves to the network. - virtual bool ShouldBindToNetwork() = 0; - - //! Returns the current entity context sequence - virtual NetBindingContextSequence GetCurrentContextSequence() = 0; - - //! Get a level entity's static id. - virtual AZ::EntityId GetStaticIdFromEntityId(AZ::EntityId entity) = 0; - - //! Get a level entity's id based on the static id - virtual AZ::EntityId GetEntityIdFromStaticId(AZ::EntityId staticEntityId) = 0; - - //! Adds a bound replica to the network session as master. - virtual void AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) = 0; - - //! Spawn and bind an entity from a slice - virtual void SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) = 0; - - //! Spawn and bind an entity from stream - virtual void SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) = 0; - - //! De-spawn an entity: deactivates or removes the entity. - /** - * /note @sliceInstanceId is the slice instance that the entity belongs to. If it's a level entity, then this should be AZ::Uuid::CreateNull() - */ - virtual void UnbindGameEntity(AZ::EntityId entity, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) = 0; - }; - typedef AZ::EBus NetBindingSystemBus; - - class NetBindingSystemEvents - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - //! Notification that a network session is created - virtual void OnNetworkSessionCreated(GridMate::GridSession* session) { (void)session; } - - //! Notification that a network session is ready - virtual void OnNetworkSessionActivated(GridMate::GridSession* session) { (void)session; } - - //! Notification that a network session is no longer available - virtual void OnNetworkSessionDeactivated(GridMate::GridSession* session) { (void)session; } - }; - typedef AZ::EBus NetBindingSystemEventsBus; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp deleted file mode 100644 index 85081d1637..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include - -namespace AzFramework -{ - NetBindingSystemComponent::NetBindingSystemComponent() - { - } - - NetBindingSystemComponent::~NetBindingSystemComponent() - { - } - - void NetBindingSystemComponent::Activate() - { - NetBindingSystemImpl::Init(); - } - - void NetBindingSystemComponent::Deactivate() - { - NetBindingSystemImpl::Shutdown(); - } - - void NetBindingSystemComponent::Reflect(AZ::ReflectContext* context) - { - NetBindingSystemImpl::Reflect(context); - - if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ; - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class( - "NetBinding System", "Performs network binding for game entities.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Engine") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) - ; - } - } - } - - void NetBindingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("NetBindingSystemService", 0xa0ad6656)); - } - - void NetBindingSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("NetBindingSystemService", 0xa0ad6656)); - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h deleted file mode 100644 index 03ff6aa86f..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H -#define AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H - -#include -#include - -namespace AZ -{ - class ReflectContext; -} - -namespace AzFramework -{ - /** - * NetBindingSystemComponent exposes NetBindingSystemImpl as a component - */ - class NetBindingSystemComponent - : public AZ::Component - , public NetBindingSystemImpl - { - friend class NetBindingSystemContextData; - public: - AZ_COMPONENT(NetBindingSystemComponent, "{B96548CC-0866-4BB3-A87B-BF0C4F69E8AC}"); - - NetBindingSystemComponent(); - ~NetBindingSystemComponent() override; - - ////////////////////////////////////////////////////////////////////////// - // Component overrides - void Activate() override; - void Deactivate() override; - static void Reflect(AZ::ReflectContext* context); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - ////////////////////////////////////////////////////////////////////////// - }; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H -#pragma once - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp deleted file mode 100644 index bb40432ffb..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp +++ /dev/null @@ -1,957 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#define Extra_Tracing -#undef Extra_Tracing - -#if defined(Extra_Tracing) -#include -#define AZ_ExtraTracePrintf(window, ...) AZ::Debug::Trace::Instance().Printf(window, __VA_ARGS__); -#else -#define AZ_ExtraTracePrintf(window, ...) -#endif - -namespace AzFramework -{ - const AZStd::chrono::milliseconds NetBindingSystemImpl::s_sliceBindingTimeout = AZStd::chrono::milliseconds(5000); - - namespace - { - NetBindingHandlerInterface* GetNetBindingHandler(AZ::Entity* entity) - { - NetBindingHandlerInterface* handler = nullptr; - for (AZ::Component* component : entity->GetComponents()) - { - handler = azrtti_cast(component); - if (handler) - { - break; - } - } - return handler; - } - } - - NetBindingSliceInstantiationHandler::~NetBindingSliceInstantiationHandler() - { - // m_bindRequests in NetBindingSystemImpl could be cleaned before slice instantiation finished - if (m_state == State::Spawning) - { - AzFramework::SliceInstantiationResultBus::Handler::BusDisconnect(); - SliceGameEntityOwnershipServiceRequestBus::Broadcast( - &SliceGameEntityOwnershipServiceRequests::CancelDynamicSliceInstantiation, m_ticket - ); - } - - for (AZ::Entity* entity : m_boundEntities) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Cleanup - deleting %llu\n", entity->GetId()); - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, entity->GetId()); - } - } - - void NetBindingSliceInstantiationHandler::InstantiateEntities() - { - if (m_sliceAssetId.IsValid()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "InstantiateEntities sliceid %s\n", - m_sliceInstanceId.ToString(false, false).c_str()); - - if (AZ::Data::AssetManager::IsReady()) - { - auto remapFunc = [bindingQueue=m_bindingQueue](AZ::EntityId originalId, bool /*isEntityId*/, const AZStd::function&) -> AZ::EntityId - { - auto iter = bindingQueue.find(originalId); - if (iter != bindingQueue.end()) - { - return iter->second.m_desiredRuntimeEntityId; - } - return AZ::Entity::MakeId(); - }; - - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset(m_sliceAssetId, AZ::Data::AssetLoadBehavior::Default); - - SliceGameEntityOwnershipServiceRequestBus::BroadcastResult(m_ticket, - &SliceGameEntityOwnershipServiceRequests::InstantiateDynamicSlice, asset, AZ::Transform::Identity(), remapFunc); - SliceInstantiationResultBus::Handler::BusConnect(m_ticket); - - m_state = State::Spawning; - } - else - { - AZ_Warning("NetBindingSystemImpl", false, "AssetManager was not ready when attempting to instantiate sliceid %s\n", - m_sliceInstanceId.ToString(false, false).c_str()); - InstantiationFailureCleanup(); - } - } - } - - bool NetBindingSliceInstantiationHandler::IsInstantiated() const - { - return m_state == State::Spawned; - } - - bool NetBindingSliceInstantiationHandler::IsANewSliceRequest() const - { - return m_state == State::NewRequest && m_sliceAssetId.IsValid() && !m_ticket.IsValid(); - } - - bool NetBindingSliceInstantiationHandler::IsBindingComplete() const - { - return !SliceInstantiationResultBus::Handler::BusIsConnected() && m_bindingQueue.empty(); - } - - bool NetBindingSliceInstantiationHandler::HasActiveEntities() const - { - for (const AZ::Entity* entity : m_boundEntities) - { - if (entity->GetState() == AZ::Entity::State::Active) - { - return true; - } - } - - return false; - } - - void NetBindingSliceInstantiationHandler::OnSlicePreInstantiate(const AZ::Data::AssetId& /*sliceAssetId*/, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) - { - const auto& entityMapping = sliceAddress.GetInstance()->GetEntityIdToBaseMap(); - - const AZ::SliceComponent::EntityList& sliceEntities = sliceAddress.GetInstance()->GetInstantiated()->m_entities; - for (AZ::Entity *sliceEntity : sliceEntities) - { - auto it = entityMapping.find(sliceEntity->GetId()); - AZ_Assert(it != entityMapping.end(), "Failed to retrieve static entity id for a slice entity!"); - const AZ::EntityId staticEntityId = it->second; - - auto itBindRecord = m_bindingQueue.find(staticEntityId); - if (itBindRecord != m_bindingQueue.end()) - { - AZ_Assert(GetNetBindingHandler(sliceEntity), "Slice entity matched the static id of replicated entity, but there is no valid NetBindingHandlerInterface on it!"); - - itBindRecord->second.m_actualRuntimeEntityId = sliceEntity->GetId(); - } - else if (GetNetBindingHandler(sliceEntity)) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "OnSlicePreInstantiate late bindRequest, slice %s, staticid %llu, spawned %llu\n", - m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(staticEntityId), - static_cast(sliceEntity->GetId())); - - BindRequest& request = m_bindingQueue[staticEntityId]; - request.m_desiredRuntimeEntityId = staticEntityId; - request.m_actualRuntimeEntityId = sliceEntity->GetId(); - request.m_requestTime = m_bindTime; - request.m_state = BindRequest::State::PlaceholderBind; - } - - sliceEntity->SetRuntimeActiveByDefault(false); - } - } - - void NetBindingSliceInstantiationHandler::OnSliceInstantiated(const AZ::Data::AssetId& /*sliceAssetId*/, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) - { - SliceInstantiationResultBus::Handler::BusDisconnect(); - - CloseEntityMap(sliceAddress.GetInstance()->GetEntityIdMap()); - - const AZ::SliceComponent::EntityList sliceEntities = sliceAddress.GetInstance()->GetInstantiated()->m_entities; - for (AZ::Entity *sliceEntity : sliceEntities) - { - auto it = sliceAddress.GetInstance()->GetEntityIdToBaseMap().find(sliceEntity->GetId()); - AZ_Assert(it != sliceAddress.GetInstance()->GetEntityIdToBaseMap().end(), "Failed to retrieve static entity id for a slice entity!"); - const AZ::EntityId staticEntityId = it->second; - const auto itUnbound = m_bindingQueue.find(staticEntityId); - if (itUnbound == m_bindingQueue.end()) - { - /* - * Remove entities that aren't meant to be net bounded. - */ - if (!GetNetBindingHandler(sliceEntity)) - { - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, sliceEntity->GetId()); - continue; - } - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Adding %llu \n", sliceEntity->GetId()); - m_boundEntities.push_back(sliceEntity); - } - - m_state = State::Spawned; - } - - void NetBindingSliceInstantiationHandler::OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId) - { - SliceInstantiationResultBus::Handler::BusDisconnect(); - - AZ_UNUSED(sliceAssetId); - AZ_TracePrintf("NetBindingSystemImpl", "Failed to instantiate a slice %s!", sliceAssetId.ToString().c_str()); - - InstantiationFailureCleanup(); - } - - void NetBindingSliceInstantiationHandler::InstantiationFailureCleanup() - { - m_boundEntities.clear(); - m_bindingQueue.clear(); - - // With m_bindingQueue empty, this slice instance handler will be removed on the next tick of NetBindingSystemImpl - m_state = State::Failed; - } - - void NetBindingSliceInstantiationHandler::UseCacheFor(BindRequest& request, const AZ::EntityId& staticEntityId) - { - AZ_Warning("NetBindingSystemImpl", !m_staticToRuntimeEntityMap.empty(), "An empty slice, really? static %llu", - static_cast(staticEntityId)); - - const auto actualRuntimeIter = m_staticToRuntimeEntityMap.find(staticEntityId); - if (actualRuntimeIter == m_staticToRuntimeEntityMap.end()) - { - AZ_Warning("NetBindingSystemImpl", false, "Wrong mapping, expected cache to have entity %llu for slice %s \n", - static_cast(staticEntityId), - m_sliceInstanceId.ToString(false, false).c_str()); - -#if defined(Extra_Tracing) - for (auto& item: m_staticToRuntimeEntityMap) - { - AZ_UNUSED(item); - AZ_ExtraTracePrintf("NetBindingSystemImpl", "mapping had %llu to %llu \n", - static_cast(item.first), - static_cast(item.second)); - } -#endif - - return; - } - - const AZ::EntityId actualRuntimeEntityId = actualRuntimeIter->second; - const auto itCache = AZStd::find_if(m_boundEntities.begin(), m_boundEntities.end(), [&actualRuntimeEntityId](AZ::Entity* entity) { - return entity->GetId() == actualRuntimeEntityId; - }); - - if (itCache != m_boundEntities.end()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "OnSlicePreInstantiate late bindRequest, slice %s, staticid %llu, spawned %llu\n", - m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(staticEntityId), - static_cast(actualRuntimeEntityId)); - - request.m_actualRuntimeEntityId = actualRuntimeEntityId; - request.m_desiredRuntimeEntityId = staticEntityId; - } - else - { - AZ_Warning("NetBindingSystemImpl", false, "Expected cache to have entity %llu for slice %s \n", - static_cast(request.m_desiredRuntimeEntityId), - m_sliceInstanceId.ToString(false, false).c_str()); - } - } - - void NetBindingSliceInstantiationHandler::CloseEntityMap( - const AZ::SliceComponent::EntityIdToEntityIdMap& staticToRuntimeMap) - { - m_staticToRuntimeEntityMap.clear(); - for (auto& item : staticToRuntimeMap) - { - m_staticToRuntimeEntityMap[item.first] = item.second; - } - } - - NetBindingSystemContextData::NetBindingSystemContextData() - : m_bindingContextSequence("BindingContextSequence", UnspecifiedNetBindingContextSequence) - { - } - - void NetBindingSystemContextData::OnReplicaActivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - NetBindingSystemImpl* system = static_cast(NetBindingSystemBus::FindFirstHandler()); - AZ_Assert(system, "NetBindingSystemContextData requires a valid NetBindingSystemComponent to function!"); - system->OnContextDataActivated(this); - } - - void NetBindingSystemContextData::OnReplicaDeactivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - NetBindingSystemImpl* system = static_cast(NetBindingSystemBus::FindFirstHandler()); - if (system) - { - system->OnContextDataDeactivated(this); - } - } - - - NetBindingSystemImpl::NetBindingSystemImpl() - : m_bindingSession(nullptr) - , m_currentBindingContextSequence(UnspecifiedNetBindingContextSequence) - , m_isAuthoritativeRootSliceLoad(false) - , m_overrideRootSliceLoadAuthoritative(false) - { - } - - NetBindingSystemImpl::~NetBindingSystemImpl() - { - } - - void NetBindingSystemImpl::Init() - { - NetBindingSystemBus::Handler::BusConnect(); - NetBindingSystemEventsBus::Handler::BusConnect(); - - // Start listening for game context events - EntityContextId gameContextId = EntityContextId::CreateNull(); - EBUS_EVENT_RESULT(gameContextId, GameEntityContextRequestBus, GetGameEntityContextId); - if (!gameContextId.IsNull()) - { - EntityContextEventBus::Handler::BusConnect(gameContextId); - } - } - - void NetBindingSystemImpl::Shutdown() - { - EntityContextEventBus::Handler::BusDisconnect(); - NetBindingSystemEventsBus::Handler::BusDisconnect(); - NetBindingSystemBus::Handler::BusDisconnect(); - - m_contextData.reset(); - } - - bool NetBindingSystemImpl::ShouldBindToNetwork() - { - return m_contextData && m_contextData->ShouldBindToNetwork(); - } - - NetBindingContextSequence NetBindingSystemImpl::GetCurrentContextSequence() - { - return m_currentBindingContextSequence; - } - - bool NetBindingSystemImpl::ReadyToAddReplica() const - { - return m_bindingSession && m_bindingSession->GetReplicaMgr(); - } - - void NetBindingSystemImpl::AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) - { - bool addReplica = ShouldBindToNetwork(); - AZ_Assert(addReplica, "Entities shouldn't be binding to the network right now!"); - if (addReplica) - { - if (ReadyToAddReplica()) - { - m_bindingSession->GetReplicaMgr()->AddMaster(replica); - } - else - { - m_addMasterRequests.push_back(AZStd::make_pair(entity->GetId(), replica)); - } - } - } - - - AZ::EntityId NetBindingSystemImpl::GetStaticIdFromEntityId(AZ::EntityId entityId) - { - AZ::EntityId staticId = entityId; // if no static id mapping is found, then the static id is the same as the runtime id - - // If entity came from a slice, try to get the mapping from it - AZ::SliceComponent::SliceInstanceAddress sliceInfo; - SliceEntityRequestBus::EventResult(sliceInfo, entityId, &SliceEntityRequestBus::Events::GetOwningSlice); - AZ::SliceComponent::SliceInstance* sliceInstance = sliceInfo.GetInstance(); - if (sliceInstance) - { - const auto it = sliceInstance->GetEntityIdToBaseMap().find(entityId); - if (it != sliceInstance->GetEntityIdToBaseMap().end()) - { - staticId = it->second; - } - } - - return staticId; - } - - AZ::EntityId NetBindingSystemImpl::GetEntityIdFromStaticId(AZ::EntityId staticEntityId) - { - AZ::EntityId runtimeId = AZ::EntityId(); - - // if we can find an entity with the static id, then the static id is the same as the runtime id. - AZ::Entity* entity = nullptr; - EBUS_EVENT(AZ::ComponentApplicationBus, FindEntity, staticEntityId); - if (entity) - { - runtimeId = staticEntityId; - } - - return runtimeId; - } - - void NetBindingSystemImpl::SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) - { - auto& sliceQueue = m_bindRequests[bindToContext.m_contextSequence]; - - const bool slicePresent = sliceQueue.find(bindToContext.m_sliceInstanceId) != sliceQueue.end(); - - auto iterSliceRequest = sliceQueue.insert_key(bindToContext.m_sliceInstanceId); - NetBindingSliceInstantiationHandler& sliceHandler = iterSliceRequest.first->second; - sliceHandler.m_sliceAssetId = bindToContext.m_sliceAssetId; - sliceHandler.m_sliceInstanceId = bindToContext.m_sliceInstanceId; - - BindRequest& request = sliceHandler.m_bindingQueue[bindToContext.m_staticEntityId]; - - if (!slicePresent) - { - request.m_state = BindRequest::State::FirstBindInSlice; - } - else - { - request.m_state = BindRequest::State::LateBind; - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "SpawnEntityFromSlice late, slice %s, static %llu, desired %llu, state %d \n", - bindToContext.m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(bindToContext.m_staticEntityId), - static_cast(bindToContext.m_runtimeEntityId), - request.m_state); - - sliceHandler.m_bindTime = Now(); - - request.m_bindTo = bindTo; - request.m_desiredRuntimeEntityId = bindToContext.m_runtimeEntityId; - request.m_requestTime = Now(); - - if (sliceHandler.IsInstantiated()) - { - // The slice has been instantiated now, thus we have to use the cache to populated the request with the entity. - sliceHandler.UseCacheFor(request, bindToContext.m_staticEntityId); - } - } - - void NetBindingSystemImpl::SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) - { - auto& requestQueue = m_spawnRequests[addToContext]; - requestQueue.push_back(); - SpawnRequest& request = requestQueue.back(); - request.m_bindTo = bindTo; - request.m_useEntityId = useEntityId; - request.m_spawnDataBuffer.resize_no_construct(spawnData.GetLength()); - spawnData.Read(request.m_spawnDataBuffer.size(), request.m_spawnDataBuffer.data()); - } - - void NetBindingSystemImpl::OnNetworkSessionActivated(GridMate::GridSession* session) - { - AZ_Assert(!m_bindingSession, "We already have an active session! Was the previous session deactivated?"); - if (!m_bindingSession) - { - m_bindingSession = session; - - if (m_bindingSession->IsHost()) - { - GridMate::Replica* replica = CreateSystemReplica(); - session->GetReplicaMgr()->AddMaster(replica); - } - } - } - - void NetBindingSystemImpl::OnNetworkSessionDeactivated(GridMate::GridSession* session) - { - if (session == m_bindingSession) - { - m_bindingSession = nullptr; - } - } - - void NetBindingSystemImpl::UnbindGameEntity(AZ::EntityId entityId, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - if (!m_bindRequests.empty()) - { - const auto itCurrentContextQueue = m_bindRequests.lower_bound(GetCurrentContextSequence()); - - if (itCurrentContextQueue != m_bindRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - const auto itSliceHandler = itCurrentContextQueue->second.find(sliceInstanceId); - if (itSliceHandler != itCurrentContextQueue->second.end()) - { - NetBindingSliceInstantiationHandler& sliceHandler = itSliceHandler->second; - for (AZ::Entity* entity : sliceHandler.m_boundEntities) - { - if (entity->GetId() == entityId) - { - entity->Deactivate(); - return; - } - } - - // clean any relevant bind requests as well - const auto bindQueueItem = sliceHandler.m_bindingQueue.find(entityId); - if (bindQueueItem != sliceHandler.m_bindingQueue.end()) - { - sliceHandler.m_bindingQueue.erase(bindQueueItem); - return; - } - } - } - } - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Not in cache - deleting %llu \n", entityId); - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, entityId); - } - - void NetBindingSystemImpl::OnEntityContextReset() - { - const bool isContextOwner = m_contextData && m_contextData->IsMaster() && m_bindingSession && m_bindingSession->IsHost(); - if (isContextOwner) - { - ++m_currentBindingContextSequence; - NetBindingSystemContextData* context = static_cast(m_contextData.get()); - context->m_bindingContextSequence.Set(m_currentBindingContextSequence); - } - } - - bool NetBindingSystemImpl::IsAuthoritateLoad() const - { - if (m_overrideRootSliceLoadAuthoritative) - { - return m_isAuthoritativeRootSliceLoad; - } - - return !m_bindingSession || m_bindingSession->IsHost(); - } - - void NetBindingSystemImpl::UpdateClock(float deltaTime) - { - m_currentTime += AZStd::chrono::milliseconds(aznumeric_cast(deltaTime * AZStd::milli::den)); - } - - AZStd::chrono::system_clock::time_point NetBindingSystemImpl::Now() const - { - return m_currentTime; - } - - void NetBindingSystemImpl::OnEntityContextLoadedFromStream(const AZ::SliceComponent::EntityList& contextEntities) - { - const bool isAuthoritativeLoad = IsAuthoritateLoad(); - - for (AZ::Entity* entity : contextEntities) - { - NetBindingHandlerInterface* netBinder = GetNetBindingHandler(entity); - if (netBinder) - { - netBinder->MarkAsLevelSliceEntity(); - } - - if (!isAuthoritativeLoad && netBinder) - { - entity->SetRuntimeActiveByDefault(false); - - auto& slicesQueue = m_bindRequests[GetCurrentContextSequence()]; - auto& sliceHandler = slicesQueue[UnspecifiedSliceInstanceId]; - BindRequest& request = sliceHandler.m_bindingQueue[entity->GetId()]; - request.m_actualRuntimeEntityId = entity->GetId(); - request.m_requestTime = Now(); - } - } - } - - void NetBindingSystemImpl::OnTick(float deltaTime, AZ::ScriptTimePoint time) - { - AZ_UNUSED(time); - - UpdateClock(deltaTime); - UpdateContextSequence(); - -#if defined(Extra_Tracing) - static AZ::Debug::Timer sTimer; - sTimer.Stamp(); -#endif - ProcessBindRequests(); -#if defined(Extra_Tracing) - const float seconds = sTimer.StampAndGetDeltaTimeInSeconds(); - - static float debugPeriod = 2.f; - static float accumulator = 0; - static float totalTimeTaken = 0; - static AZ::u32 totalTicks = 0; - accumulator += deltaTime; - totalTimeTaken += seconds; - totalTicks++; - - if (accumulator >= debugPeriod) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "ProcessBindRequests() took %f sec \n", totalTicks > 0 ? totalTimeTaken / totalTicks : 0); - - accumulator -= debugPeriod; - totalTimeTaken = 0; - totalTicks = 0; - } -#endif - - ProcessSpawnRequests(); - } - - int NetBindingSystemImpl::GetTickOrder() - { - return AZ::TICK_PLACEMENT + 1; - } - - void NetBindingSystemImpl::UpdateContextSequence() - { - NetBindingSystemContextData* contextChunk = static_cast(m_contextData.get()); - if (m_currentBindingContextSequence != contextChunk->m_bindingContextSequence.Get()) - { - m_currentBindingContextSequence = contextChunk->m_bindingContextSequence.Get(); - } - } - - GridMate::Replica* NetBindingSystemImpl::CreateSystemReplica() - { - AZ_Assert(m_bindingSession->IsHost(), "CreateSystemReplica should only be called on the host!"); - GridMate::Replica* replica = GridMate::Replica::CreateReplica("NetBindingSystem"); - NetBindingSystemContextData* contextChunk = GridMate::CreateReplicaChunk(); - replica->AttachReplicaChunk(contextChunk); - - return replica; - } - - void NetBindingSystemImpl::OnContextDataActivated(GridMate::ReplicaChunkPtr contextData) - { - AZ_Assert(!m_contextData, "We already have our context!"); - m_contextData = contextData; - - // Make sure we always have the unspecified entry. This should also - // be the lower_bound in the map and assuming it is always there - // makes things simpler. - m_spawnRequests.insert(UnspecifiedNetBindingContextSequence); - m_bindRequests.insert(UnspecifiedNetBindingContextSequence); - - if (contextData->IsMaster()) - { - ++m_currentBindingContextSequence; - static_cast(contextData.get())->m_bindingContextSequence.Set(m_currentBindingContextSequence); - } - else - { - UpdateContextSequence(); - } - AZ::TickBus::Handler::BusConnect(); - EBUS_EVENT(AzFramework::NetBindingHandlerBus, BindToNetwork, nullptr); - } - - void NetBindingSystemImpl::OnContextDataDeactivated(GridMate::ReplicaChunkPtr contextData) - { - AZ_Assert(m_contextData == contextData, "This is not our context!"); - m_contextData = nullptr; - - AZ::TickBus::Handler::BusDisconnect(); - m_spawnRequests.clear(); - m_bindRequests.clear(); - m_addMasterRequests.clear(); - m_currentBindingContextSequence = UnspecifiedNetBindingContextSequence; - } - - void NetBindingSystemImpl::ProcessSpawnRequests() - { - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "NetBindingSystemComponent requires a valid SerializeContext in order to spawn entities!"); - const auto spawnFunc = [=](SpawnRequest& spawnData, AZ::EntityId useEntityId, bool addToContext) - { - AZ::Entity* proxyEntity = nullptr; - AZ::ObjectStream::ClassReadyCB readyCB([&](void* classPtr, const AZ::Uuid& classId, AZ::SerializeContext* sc) - { - (void)classId; - (void)sc; - proxyEntity = static_cast(classPtr); - }); - AZ::IO::ByteContainerStream > stream(&spawnData.m_spawnDataBuffer); - AZ::ObjectStream::LoadBlocking(&stream, *serializeContext, readyCB); - - AZ_Warning("NetBindingSystemImpl", proxyEntity, "Could not spawn entity from stream %llu", useEntityId); - if (proxyEntity) - { - proxyEntity->SetId(useEntityId); - if (!BindAndActivate(proxyEntity, spawnData.m_bindTo, addToContext, AZ::Uuid::CreateNull())) - { - AzFramework::EntityContextId contextId = AzFramework::EntityContextId::CreateNull(); - AzFramework::EntityIdContextQueryBus::EventResult( - contextId, proxyEntity->GetId(), &AzFramework::EntityIdContextQueryBus::Events::GetOwningContextId); - - if (contextId.IsNull()) - { - delete proxyEntity; - } - else - { - GameEntityContextRequestBus::Broadcast( - &GameEntityContextRequestBus::Events::DestroyGameEntity, proxyEntity->GetId()); - } - - } - } - }; - - if (!m_spawnRequests.empty()) - { - SpawnRequestContextContainerType::iterator itContextQueue = m_spawnRequests.lower_bound(UnspecifiedNetBindingContextSequence); - AZ_Assert(itContextQueue->first == UnspecifiedNetBindingContextSequence, "We should always have the unspecified (aka global entity) spawn queue!");// - - // Process requests for global entities (not part of any context) - SpawnRequestContainerType& globalQueue = itContextQueue->second; - for (SpawnRequest& request : globalQueue) - { - spawnFunc(request, request.m_useEntityId, false); - } - globalQueue.clear(); - - if (GetCurrentContextSequence() != UnspecifiedNetBindingContextSequence) - { - ++itContextQueue; - - // Clear any obsolete requests (any contexts below the current context sequence) - SpawnRequestContextContainerType::iterator itCurrentContextQueue = m_spawnRequests.lower_bound(GetCurrentContextSequence()); - if (itContextQueue != itCurrentContextQueue) - { - m_spawnRequests.erase(itContextQueue, itCurrentContextQueue); - } - - // Spawn any entities for the current context - if (itCurrentContextQueue != m_spawnRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - for (SpawnRequest& request : itCurrentContextQueue->second) - { - spawnFunc(request, request.m_useEntityId, true); - } - itCurrentContextQueue->second.clear(); - } - } - } - } - } - - void NetBindingSystemImpl::ProcessBindRequests() - { - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "NetBindingSystemComponent requires a valid SerializeContext in order to spawn entities!"); - - if (!m_bindRequests.empty()) - { - BindRequestContextContainerType::iterator itContextQueue = m_bindRequests.lower_bound(UnspecifiedNetBindingContextSequence); - AZ_Assert(itContextQueue->first == UnspecifiedNetBindingContextSequence, "We should always have the unspecified/global spawn queue!"); - - if (GetCurrentContextSequence() != UnspecifiedNetBindingContextSequence) - { - ++itContextQueue; - - // Clear any obsolete requests (any contexts below the current context sequence) - BindRequestContextContainerType::iterator itCurrentContextQueue = m_bindRequests.lower_bound(GetCurrentContextSequence()); - if (itContextQueue != itCurrentContextQueue) - { - m_bindRequests.erase(itContextQueue, itCurrentContextQueue); - } - - // Spawn any proxy entities for the current context - if (itCurrentContextQueue != m_bindRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - for (auto itSliceHandler = itCurrentContextQueue->second.begin(); itSliceHandler != itCurrentContextQueue->second.end(); /*++itSliceHandler*/) - { - NetBindingSliceInstantiationHandler& sliceHandler = itSliceHandler->second; - - // If this is a new slice request, instantiate it - if (sliceHandler.IsANewSliceRequest()) - { - sliceHandler.InstantiateEntities(); - } - /* - * A slice instance is kept alive for caching purposes. As we check each bind request for its readiness, - * we are also going to check if the slice instance itself has become inactive and needs to be removed. - */ - bool mightBeInactiveSlice = true; - if (sliceHandler.m_bindingQueue.empty() && sliceHandler.HasActiveEntities()) - { - // The slice instance is spawned and full bound. - mightBeInactiveSlice = false; - } - - // If the entity is ready to be bound to the network, bind it. - // NOTE: It is possible for entities spawned from a slice containing multiple entities with net binding - // to never receive their replica counterpart, either because the replica was destroyed, or was interest - // filtered. We don't have a very good pipeline to prevent these slices from being authored, so if we - // encounter them, we will delete them after a timeout. - for (auto itRequest = sliceHandler.m_bindingQueue.begin(); itRequest != sliceHandler.m_bindingQueue.end(); /*++itRequest*/) - { - BindRequest& request = itRequest->second; - - if (request.m_bindTo != GridMate::InvalidReplicaId && request.m_actualRuntimeEntityId.IsValid()) - { - AZ::Entity* proxyEntity = nullptr; - EBUS_EVENT_RESULT(proxyEntity, AZ::ComponentApplicationBus, FindEntity, request.m_actualRuntimeEntityId); - AZ_Warning("NetBindingSystemImpl", proxyEntity, "Could not find entity for binding %llu", request.m_actualRuntimeEntityId); - if (proxyEntity) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "BindAndActivate desired id %llu, actual %llu, slice %s \n", - static_cast(request.m_desiredRuntimeEntityId), - static_cast(request.m_actualRuntimeEntityId), - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str()); - - BindAndActivate(proxyEntity, request.m_bindTo, false, sliceHandler.m_sliceInstanceId); - } - itRequest = sliceHandler.m_bindingQueue.erase(itRequest); - - // The slice instance is not fully bound. It may remain for a while for caching purposes. - mightBeInactiveSlice = false; - } - else if (AZStd::chrono::milliseconds(Now() - request.m_requestTime) > s_sliceBindingTimeout) - { - // If the real request never showed up, then no need for a trace - if (request.m_state == BindRequest::State::FirstBindInSlice || - request.m_state == BindRequest::State::LateBind) - { - AZ_TracePrintf("NetBindingSystemImpl", "Entity with static id [%llu], slice [%s]\n is still unbound after %llu ms. Discarding unbound entity.\n", - static_cast(request.m_actualRuntimeEntityId), - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str(), - s_sliceBindingTimeout.count()); - } - - switch (sliceHandler.m_state) - { - case NetBindingSliceInstantiationHandler::State::NewRequest: - case NetBindingSliceInstantiationHandler::State::Spawning: - // The slice instance isn't ready yet. We will wait to consider the timing logic until it is ready. - mightBeInactiveSlice = false; - break; - case NetBindingSliceInstantiationHandler::State::Spawned: - case NetBindingSliceInstantiationHandler::State::Failed: - // Now the timing logic for removing the slice instance becomes valid. - mightBeInactiveSlice = true; - break; - default: - break; - } - - ++itRequest; - } - else - { - mightBeInactiveSlice = false; - ++itRequest; - } - } - - if (mightBeInactiveSlice && !sliceHandler.HasActiveEntities()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Removing inactive slice %s \n", - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str()); - - itSliceHandler = itCurrentContextQueue->second.erase(itSliceHandler); - } - else - { - ++itSliceHandler; - } - } - } - } - } - } - - // Spawn replicas for any local entities that are still valid - for (auto& addRequest : m_addMasterRequests) - { - AZ::Entity* entity = nullptr; - EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, addRequest.first); - if (entity) - { - m_bindingSession->GetReplicaMgr()->AddMaster(addRequest.second); - } - } - m_addMasterRequests.clear(); - } - - bool NetBindingSystemImpl::BindAndActivate(AZ::Entity* entity, GridMate::ReplicaId replicaId, bool addToContext, - const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - bool success = false; - - if ( ShouldBindToNetwork() ) - { - const GridMate::ReplicaPtr bindTo = m_contextData->GetReplicaManager()->FindReplica(replicaId); - if (bindTo) - { - if (addToContext) - { - EBUS_EVENT(GameEntityContextRequestBus, AddGameEntity, entity); - } - - if (entity->GetState() == AZ::Entity::State::Constructed) - { - entity->Init(); - } - - NetBindingHandlerInterface* binding = GetNetBindingHandler(entity); - AZ_Warning("NetBindingSystemImpl", binding, "Can't find NetBindingComponent on entity %llu (%s)!", static_cast(entity->GetId()), entity->GetName().c_str()); - if (binding) - { - binding->BindToNetwork(bindTo); - binding->SetSliceInstanceId(sliceInstanceId); - - entity->Activate(); - success = true; - } - } - else - { - // NOTE: It is possible for entities spawned from a slice containing multiple entities with net binding - // to never receive their replica counterpart, either because the replica was destroyed, or was interest - // filtered. - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Failed to bind entity %llu - could not find replica %u", entity->GetId(), replicaId); - } - } - - return success; - } - - void NetBindingSystemImpl::Reflect(AZ::ReflectContext* context) - { - if (context) - { - // We need to register the chunk type, and this would be a good time to do so. - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(NetBindingSystemContextData::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h deleted file mode 100644 index 543d9544ce..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h +++ /dev/null @@ -1,311 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - /** - * \brief Represents a request to bind a particular replica to an entity - */ - class BindRequest - { - public: - BindRequest() - : m_bindTo(GridMate::InvalidReplicaId) - , m_state(State::None) - { - } - - GridMate::ReplicaId m_bindTo; - AZ::EntityId m_desiredRuntimeEntityId; - AZ::EntityId m_actualRuntimeEntityId; - AZStd::chrono::system_clock::time_point m_requestTime; - - /** - * \brief Represents the state of this bind request and it's relation to the slice instantiation process - */ - enum class State : AZ::u8 - { - None, - /** - * \brief This is the first request that led to instantiating a slice - */ - FirstBindInSlice, - /** - * \brief The request is a placeholder in case a real bind request arrives later. - * Some part of the slice may never be bound (e.g. if a replica is omitted by Interest Manager) - */ - PlaceholderBind, - /** - * \brief The real request did arrive to replace a placeholder request. - */ - LateBind, - }; - - State m_state; - }; - - typedef AZStd::unordered_map BindRequestContainerType; - - /** - * \brief Represents a slice instance being instantiated and bound to replicas - * \note It's possible that only some of the entities are activated and bound to replicas. - */ - class NetBindingSliceInstantiationHandler - : public SliceInstantiationResultBus::Handler - { - public: - ~NetBindingSliceInstantiationHandler() override; - - void InstantiateEntities(); - bool IsInstantiated() const; - bool IsANewSliceRequest() const; - bool IsBindingComplete() const; - - /** - * \note Returns false if there are no entities in the slice or the slice instance isn't ready yet. - * \return true if any of the entities from the slice are active - */ - bool HasActiveEntities() const; - - ////////////////////////////////////////////////////////////////////////// - // SliceInstantiationResultBus - void OnSlicePreInstantiate(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) override; - void OnSliceInstantiated(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) override; - void OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId) override; - ////////////////////////////////////////////////////////////////////////// - - void InstantiationFailureCleanup(); - void UseCacheFor(BindRequest& request, const AZ::EntityId& staticEntityId); - void CloseEntityMap(const AZ::SliceComponent::EntityIdToEntityIdMap& staticToRuntimeMap); - - AZ::Data::AssetId m_sliceAssetId; - BindRequestContainerType m_bindingQueue; - SliceInstantiationTicket m_ticket; - - /** - * \breif a cache of entities that might be networked at some point - * \note they might be bound and unbound if their replicas leave and come back in the view - */ - AZStd::vector m_boundEntities; - - /** - * \brief identifies which slice instance the instantiation will be performed for - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - /** - * \brief when was the request to spawn a slice and bind it made - */ - AZStd::chrono::system_clock::time_point m_bindTime; - - AZ::SliceComponent::EntityIdToEntityIdMap m_staticToRuntimeEntityMap; - - /** - * \brief The state of the slice instance. - */ - enum class State - { - /** - * \brief Has not started instantiating the slice instance. - */ - NewRequest, - /** - * \brief Waiting on the slice to spawn. - */ - Spawning, - /** - * \brief Successfully spawned the slice assets. - */ - Spawned, - /** - * \brief Failed to spawn the slice. - */ - Failed - }; - - State m_state = State::NewRequest; - }; - - /** - * NetBindingSystemImpl works in conjunction with NetBindingComponent and - * NetBindingComponentChunk to perform network binding for game entities. - * - * It is responsible for adding entity replicas to the network on the master side - * and servicing entity spawn requests from the network on the proxy side, as - * well as detecting network availability and triggering network binding/unbinding. - * - * The system is first activated on the host side when OnNetworkSessionActivated event - * is received, and NetBindingSystemContextData is created. - * The system becomes fully operational when the NetBindingSystemContextData is activated - * and bound to the system, and remains operational as long as the NetBindingSystemContextData - * remains valid. - * - * Level switching is tracked by a monotonically increasing context sequence number controlled - * by the host. Spawn and bind operations are deferred until the correct sequence number - * is reached. Spawning is always performed from the game thread. - */ - class NetBindingSystemImpl - : public NetBindingSystemBus::Handler - , public NetBindingSystemEventsBus::Handler - , public EntityContextEventBus::Handler - , public AZ::TickBus::Handler - { - friend class NetBindingSystemContextData; - - public: - NetBindingSystemImpl(); - ~NetBindingSystemImpl() override; - - static void Reflect(AZ::ReflectContext* context); - - virtual void Init(); - virtual void Shutdown(); - - static const AZStd::chrono::milliseconds s_sliceBindingTimeout; - - ////////////////////////////////////////////////////////////////////////// - // NetBindingSystemBus - bool ShouldBindToNetwork() override; - NetBindingContextSequence GetCurrentContextSequence() override; - void AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) override; - AZ::EntityId GetStaticIdFromEntityId(AZ::EntityId entity) override; - AZ::EntityId GetEntityIdFromStaticId(AZ::EntityId staticEntityId) override; - void SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) override; - void SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) override; - void OnNetworkSessionActivated(GridMate::GridSession* session) override; - void OnNetworkSessionDeactivated(GridMate::GridSession* session) override; - void UnbindGameEntity(AZ::EntityId entity, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // EntityContextEventBus::Handler - void OnEntityContextReset() override; - void OnEntityContextLoadedFromStream(const AZ::SliceComponent::EntityList& contextEntities) override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // TickBus::Handler - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; - int GetTickOrder() override; - ////////////////////////////////////////////////////////////////////////// - - protected: - //! Called by the NetBindingContext chunk when it is activated - void OnContextDataActivated(GridMate::ReplicaChunkPtr contextData); - - //! Called by the NetBindingContext chunk when it is deactivated - void OnContextDataDeactivated(GridMate::ReplicaChunkPtr contextData); - - //! Update the current binding context sequence - virtual void UpdateContextSequence(); - - //! Process pending spawn requests - virtual void ProcessSpawnRequests(); - - //! Process pending bind requests - virtual void ProcessBindRequests(); - - //! Performs final stage of entity spawning process - virtual bool BindAndActivate(AZ::Entity* entity, GridMate::ReplicaId replicaId, bool addToContext, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId); - - //! Called on the host to spawn the net binding system replica - virtual GridMate::Replica* CreateSystemReplica(); - - AZ_FORCE_INLINE bool ReadyToAddReplica() const; - - class SpawnRequest - { - public: - GridMate::ReplicaId m_bindTo; - AZ::EntityId m_useEntityId; - AZStd::vector m_spawnDataBuffer; - }; - - typedef AZStd::list SpawnRequestContainerType; - typedef AZStd::map SpawnRequestContextContainerType; - - typedef AZStd::unordered_map SliceRequestContainerType; - typedef AZStd::map BindRequestContextContainerType; - - GridMate::GridSession* m_bindingSession; - GridMate::ReplicaChunkPtr m_contextData; - NetBindingContextSequence m_currentBindingContextSequence; - SpawnRequestContextContainerType m_spawnRequests; - BindRequestContextContainerType m_bindRequests; - AZStd::list> m_addMasterRequests; - - /** - * \brief override how root slice entities' replicas should be loaded - * - * We occasionally get GameContextBridge replica (that tells us what level to load) before we get - * a replica that tells us that we are connecting to a network sessions, thus we may not figure out in time if we - * need to load the root slice entities with NetBindingComponent as master replicas or proxy replicas. - * This is a fix until proper order is established. - * - * \param isAuthoritative true if root slice entities with NetBindingComponents to be loaded authoritatively - */ - void OverrideRootSliceLoadMode(bool isAuthoritative) - { - m_isAuthoritativeRootSliceLoad = isAuthoritative; - m_overrideRootSliceLoadAuthoritative = true; - } - - private: - /** - * \brief True if the root slice is to be loaded authoritatively - */ - bool m_isAuthoritativeRootSliceLoad; - /** - * \brief True if root slice loading mode was overriden, otherwise the mode would be determined via m_bindingSession - */ - bool m_overrideRootSliceLoadAuthoritative; - /** - * \brief A helper method to figure the mode of loading root slice entities' replicas - * \return True if the root slice entities is to be loaded authoritatively - */ - bool IsAuthoritateLoad() const; - - void UpdateClock(float deltaTime); - AZStd::chrono::system_clock::time_point Now() const; - - AZStd::chrono::system_clock::time_point m_currentTime; - }; - - class NetBindingSystemContextData - : public GridMate::ReplicaChunk - { - public: - AZ_CLASS_ALLOCATOR(NetBindingSystemContextData, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingSystemContextData"; } - - NetBindingSystemContextData(); - - bool IsReplicaMigratable() override { return true; } - bool IsBroadcast() override { return true; } - - void OnReplicaActivate(const GridMate::ReplicaContext& rc) override; - - void OnReplicaDeactivate(const GridMate::ReplicaContext& rc) override; - - GridMate::DataSet m_bindingContextSequence; - }; -} // namespace AzFramework - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h deleted file mode 100644 index 788eacf8b5..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace AzFramework -{ - class NetworkContext; - - /** - * The NetSystemRequestBus services requests for global networking systems in AzFramework - */ - class NetSystemRequests - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - NetSystemRequests() = default; - virtual ~NetSystemRequests() = default; - - virtual NetworkContext* GetNetworkContext() = 0; - }; - - using NetSystemRequestBus = AZ::EBus; -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp deleted file mode 100644 index 98ef897d29..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include - - -namespace AzFramework -{ - NetworkContext::DescBase::DescBase(const char* name, ptrdiff_t offset) - : m_name(name) - , m_offset(offset) - { - } - - NetworkContext::FieldDescBase::FieldDescBase(const char* name, ptrdiff_t offset) - : DescBase(name, offset) - , m_dataSetIdx(static_cast(-1)) - { - } - - NetworkContext::RpcDescBase::RpcDescBase(const char* name, ptrdiff_t offset) - : DescBase(name, offset) - , m_rpcIdx(static_cast(-1)) - { - } - - NetworkContext::CtorDataBase::CtorDataBase(const char* name) - : m_name(name) - { - } - - NetworkContext::ClassBuilder::ClassBuilder(NetworkContext* context, ClassDescPtr binding) - : m_binding(binding) - , m_context(context) - { - } - - NetworkContext::ClassBuilder::~ClassBuilder() - { - if (m_context->IsRemovingReflection()) - { - if (m_binding->UnregisterChunkType) - { - m_binding->UnregisterChunkType(); - } - } - else - { - if (m_binding->RegisterChunkType) - { - m_binding->RegisterChunkType(); - } - } - } - - NetworkContext::ClassDesc::ClassDesc(const char* name, const AZ::Uuid& typeId /* = AZ::Uuid() */) - : m_name(name) - , m_typeId(typeId) - { - } - - /////////////////////////////////////////////////////////////////////////// - /// NetworkContext - /////////////////////////////////////////////////////////////////////////// - NetworkContext::NetworkContext() - { - } - - NetworkContext::~NetworkContext() - { - } - - size_t NetworkContext::GetReflectedChunkSize(const AZ::Uuid& typeId) const - { - size_t totalSize = 0; - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - for (const auto& field : binding->m_chunkDesc.m_fields) - { - totalSize += field->GetDataSetSize(); - } - - for (const auto& rpc : binding->m_chunkDesc.m_rpcs) - { - totalSize += rpc->GetRpcSize(); - } - } - - return totalSize; - } - - bool NetworkContext::UsesSelfAsChunk(const AZ::Uuid& typeId) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - return !binding->m_chunkDesc.m_external && binding->m_chunkDesc.m_fields.size() > 0; - } - return false; - } - - bool NetworkContext::UsesExternalChunk(const AZ::Uuid& typeId) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - return binding->m_chunkDesc.m_external && (AZ::u32(binding->m_chunkDesc.m_chunkId) != 0); - } - return false; - } - - ReplicaChunkBase* NetworkContext::CreateReplicaChunk(const AZ::Uuid& typeId) - { - const auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ClassDescPtr binding = it->second; - if (binding->CreateReplicaChunk) - { - ReplicaChunkDescriptor* descriptor = ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(binding->m_chunkDesc.m_chunkId); - AZ_Assert(descriptor, "NetworkContext cannot find replica chunk descriptor for %s. Did you remember to register the chunk type?", binding->m_name); - ReplicaChunkDescriptorTable::Get().BeginConstructReplicaChunk(descriptor); - ReplicaChunkBase* chunk = binding->CreateReplicaChunk(); - ReplicaChunkDescriptorTable::Get().EndConstructReplicaChunk(); - chunk->Init(descriptor); - return chunk; - } - } - - /* - * Special case: empty declarations such as: - * - * static void Reflect() { - * .... - * NetworkContext->Class(); - * } - * - * Result in no ReplicaChunks being created. It's treated as a no-op. No replication will be performed. - */ - return nullptr; - } - - void NetworkContext::DestroyReplicaChunk(ReplicaChunkBase* chunk) - { - ReplicaChunkClassId chunkId = chunk->GetDescriptor()->GetChunkTypeId(); - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - ClassDescPtr binding = it->second; - binding->DestroyReplicaChunk(chunk); - return; - } - - AZ_Warning("NetworkContext", false, "DestroyReplicaChunk could not find a binding for %s", chunk->GetDescriptor()->GetChunkName()); - } - - void NetworkContext::Bind(NetBindable* instance, ReplicaChunkPtr chunk, NetworkContextBindMode mode) - { - const AZ::Uuid& typeId = instance->RTTI_GetType(); - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - if (chunk) - { - ReplicaChunkClassId chunkId = chunk->GetDescriptor()->GetChunkTypeId(); - AZ_Assert(binding->m_chunkDesc.m_chunkId == chunkId, "NetworkContext detected a type mismatch while trying to bind an instance to a ReplicaChunk"); - if (binding->m_chunkDesc.m_chunkId == chunkId) - { - if (!binding->m_chunkDesc.m_external) - { - ReflectedReplicaChunkBase* refChunk = static_cast(chunk.get()); - refChunk->Bind(instance, mode); - } - } - } - else - { - if (binding->BindRpcs) - { - binding->BindRpcs(instance); - } - } - } - } - - void NetworkContext::EnumerateFields(const ReplicaChunkClassId& chunkId, FieldVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& field : chunkDesc.m_fields) - { - visitor(field.get()); - } - } - } - - void NetworkContext::EnumerateFields(const AZ::Uuid& typeId, FieldVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& field : chunkDesc.m_fields) - { - visitor(field.get()); - } - } - } - - void NetworkContext::EnumerateRpcs(const ReplicaChunkClassId& chunkId, RpcVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& rpc : chunkDesc.m_rpcs) - { - visitor(rpc.get()); - } - } - } - - void NetworkContext::EnumerateRpcs(const AZ::Uuid& typeId, RpcVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& rpc : chunkDesc.m_rpcs) - { - visitor(rpc.get()); - } - } - } - - void NetworkContext::EnumerateCtorData(const ReplicaChunkClassId& chunkId, CtorVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& ctor : chunkDesc.m_ctors) - { - visitor(ctor.get()); - } - } - } - - void NetworkContext::EnumerateCtorData(const AZ::Uuid& typeId, CtorVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& ctor : chunkDesc.m_ctors) - { - visitor(ctor.get()); - } - } - } - - /////////////////////////////////////////////////////////////////////////// - ReflectedReplicaChunkBase::ReflectedReplicaChunkBase() - : m_ctorBuffer(GridMate::EndianType::IgnoreEndian, 0) - { - } - - /////////////////////////////////////////////////////////////////////////// - NetworkContextChunkDescriptor::NetworkContextChunkDescriptor(const char* name, size_t size, const AZ::Uuid& typeId) - : ReplicaChunkDescriptor(name, size) - , m_typeId(typeId) - { - } - - ReplicaChunkBase* NetworkContextChunkDescriptor::CreateFromStream(UnmarshalContext& ctx) - { - AZ_Assert(!m_typeId.IsNull(), "No typeid associated with NetworkContextChunkDescriptor, cannot spawn Chunk"); - if (!m_typeId.IsNull()) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to construct ReflectedReplicaChunk"); - - ReplicaChunkBase* replicaChunk = netContext->CreateReplicaChunk(m_typeId); - if (ctx.m_hasCtorData && ctx.m_iBuf) - { - NetworkContextChunkDescriptor* netChunkDesc = static_cast(replicaChunk->GetDescriptor()); - if (netChunkDesc->IsAuto()) - { - // copy each ctor data field into the ctor buffer - ReflectedReplicaChunkBase* refChunk = static_cast(replicaChunk); - netContext->EnumerateCtorData(m_typeId, - [&ctx, refChunk](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Copy(*ctx.m_iBuf, refChunk->m_ctorBuffer); - }); - } - } - return replicaChunk; - } - return nullptr; - } - - void NetworkContextChunkDescriptor::DeleteReplicaChunk(ReplicaChunkBase* chunk) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to destroy ReflectedReplicaChunk"); - netContext->DestroyReplicaChunk(chunk); - } - - void NetworkContextChunkDescriptor::MarshalCtorData(ReplicaChunkBase* chunk, WriteBuffer& buffer) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to collect ctor data for ReflectedReplicaChunk"); - NetBindable* netBindable = static_cast(chunk->GetHandler()); - NetworkContextChunkDescriptor* netChunkDesc = static_cast(chunk->GetDescriptor()); - if (!netChunkDesc->IsAuto()) - { - return; - } - - if (netBindable) // chunk is bound, get source data from the netBindable - { - netContext->EnumerateCtorData(m_typeId, - [netBindable, &buffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Marshal(netBindable, buffer); - }); - } - else // chunk is not bound yet, copy the ctor data for forwarding - { - ReflectedReplicaChunkBase* refChunk = static_cast(chunk); - ReadBuffer src(refChunk->m_ctorBuffer.GetEndianType(), refChunk->m_ctorBuffer.Get(), refChunk->m_ctorBuffer.Size()); - netContext->EnumerateCtorData(m_typeId, - [&src, &buffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Copy(src, buffer); - }); - } - } - - void NetworkContextChunkDescriptor::DiscardCtorStream(UnmarshalContext& ctx) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to skip ctor data for ReflectedReplicaChunk"); - if (ctx.m_hasCtorData) - { - // Iterate over all of the ctor data and unmarshal it with no destination, - // which will advance the buffer past the ctor data for this object - netContext->EnumerateCtorData(m_typeId, - [&ctx](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Unmarshal(*ctx.m_iBuf, nullptr); - }); - } - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h b/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h deleted file mode 100644 index 5b6d420a79..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h +++ /dev/null @@ -1,969 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace AzFramework -{ - class NetBindable; - - using GridMate::ReplicaChunkInterface; - using GridMate::ReplicaChunkBase; - using GridMate::ReplicaChunk; - using GridMate::ReplicaChunkDescriptor; - using GridMate::DefaultReplicaChunkDescriptor; - using GridMate::ReplicaChunkDescriptorTable; - using GridMate::ReplicaChunkClassId; - using GridMate::ReplicaChunkPtr; - using GridMate::Rpc; - using GridMate::ZoneMask; - using GridMate::ZoneMask_All; - using GridMate::UnmarshalContext; - using GridMate::ReadBuffer; - using GridMate::WriteBuffer; - using GridMate::WriteBufferDynamic; - - /////////////////////////////////////////////////////////////////////////// - // GridMate ReplicaChunk/ReplicaChunkDescriptors - /////////////////////////////////////////////////////////////////////////// - class ReflectedReplicaChunkBase - : public ReplicaChunkBase - , public ReplicaChunkInterface - { - friend NetworkContext; - public: - ReflectedReplicaChunkBase(); - bool IsReplicaMigratable() override { return true; } - - /// Returns the chunk type name, e.g. "ReflectedReplicaChunk" - virtual const char* GetName() const = 0; - /// Returns the linear size of the chunk including DataSets and RPCs - virtual size_t GetSize() const = 0; - /// Returns a pointer to the start of the DataSet/RPC storage allocated with the chunk - virtual AZ::u8* GetDataStart() const = 0; - /// Binds an instance of the reflected class to this chunk - virtual void Bind(NetBindable* instance, NetworkContextBindMode mode) = 0; - /// Removes network bindings from the bound NetBindable - virtual void Unbind() = 0; - - WriteBufferDynamic m_ctorBuffer; ///< Buffer to hold ctor data before the chunk is bound - }; - - /// This will be the header for a blob in memory: - /// The layout looks like: - /// * ReflectedReplicaChunk - /// * DataSets - /// * RPCs - template - class ReflectedReplicaChunk - : public ReflectedReplicaChunkBase - { - friend NetworkContext; - public: - static const char* GetChunkName(); - static size_t GetChunkSize(); - - public: - AZ_CLASS_ALLOCATOR(ReflectedReplicaChunk, AZ::SystemAllocator, 0); - ReflectedReplicaChunk() - : m_dataSets(reinterpret_cast(this) + sizeof(*this)) - { - } - - const char* GetName() const override { return GetChunkName(); } - size_t GetSize() const override { return GetChunkSize(); } - AZ::u8* GetDataStart() const override { return const_cast(m_dataSets); } - void Bind(NetBindable* instance, NetworkContextBindMode mode) override; - void Unbind() override; - - private: - const AZ::u8* m_dataSets; ///< Points to the beginning of the datasets for this chunk - }; - - class NetworkContextChunkDescriptor - : public ReplicaChunkDescriptor - { - public: - NetworkContextChunkDescriptor(const char* name, size_t size, const AZ::Uuid& typeId = AZ::Uuid()); - - ReplicaChunkBase* CreateFromStream(UnmarshalContext& ctx) override; - void DeleteReplicaChunk(ReplicaChunkBase* chunkInstance) override; - void DiscardCtorStream(UnmarshalContext&) override; - void MarshalCtorData(ReplicaChunkBase*, WriteBuffer&) override; - - void Bind(const AZ::Uuid& typeId) { m_typeId = typeId; } - virtual bool IsAuto() const { return false; } - - private: - AZ::Uuid m_typeId; ///< TypeId of the class this descriptor represents (not the chunk type) - }; - - template - class AutoChunkDescriptor - : public NetworkContextChunkDescriptor - { - public: - AutoChunkDescriptor() - : NetworkContextChunkDescriptor(ReflectedReplicaChunk::GetChunkName(), ReflectedReplicaChunk::GetChunkSize(), AZ::RttiTypeId()) - { - } - - ZoneMask GetZoneMask() const override { return mask; } - - bool IsAuto() const override { return true; } - }; - - template - class ExternalChunkDescriptor - : public NetworkContextChunkDescriptor - { - public: - ExternalChunkDescriptor() - : NetworkContextChunkDescriptor(ChunkType::GetChunkName(), sizeof(ChunkType)) - {} - - ZoneMask GetZoneMask() const override { return mask; } - }; - - /////////////////////////////////////////////////////////////////////////// - /// NetworkContext can be used to reflect classes for network serialization - /// It will automatically generate ReplicaChunks and bind them to instances - /// when requested. It also serves as a binding registry for binding a class - /// to the ReplicaChunk that should be used to replicate it. - /////////////////////////////////////////////////////////////////////////// - class NetworkContext - : public AZ::ReflectContext - { - public: - /// @cond EXCLUDE_DOCS - class ClassBuilder; - class ClassDesc; - using ClassDescPtr = AZStd::intrusive_ptr; - using ClassBuilderPtr = AZStd::intrusive_ptr; - using ClassBindings = AZStd::unordered_map; - using ChunkBindings = AZStd::unordered_map; - using ClassInfo = ClassBuilder; ///< @deprecated Use NetworkContext::ClassBuilder - using ClassInfoPtr = ClassBuilderPtr; ///< @deprecated Use NetworkContext::ClassBuilderPtr - /// @endcond - - class IntrusiveRefCounted - { - public: - virtual ~IntrusiveRefCounted() {} - private: - // refcount - template - friend struct AZStd::IntrusivePtrCountPolicy; - mutable unsigned int m_refCount = 0; - AZ_FORCE_INLINE void add_ref() { ++m_refCount; } - AZ_FORCE_INLINE void release() - { - AZ_Assert(m_refCount > 0, "Reference count logic error, trying to remove reference when refcount is 0"); - if (--m_refCount == 0) - { - delete this; - } - } - }; - - /** - * Interface for recording classes, chunks, and datasets - * When destructed at the end of reflection, it will register/unregister the ChunkDescriptor - */ - class ClassBuilder - : public IntrusiveRefCounted - { - friend class NetworkContext; - - protected: - AZ_CLASS_ALLOCATOR(ClassBuilder, AZ::SystemAllocator, 0); - ClassBuilder(NetworkContext* context, ClassDescPtr binding); - - public: - ~ClassBuilder(); - ClassBuilderPtr operator->() { return this; } - - /// Bind a ReplicaChunk type to this class for network serialization - template > - ClassBuilderPtr Chunk(); - - /// Bind a NetBindable's Field - template - typename AZStd::enable_if::value, ClassBuilderPtr>::type - Field(const char* name, FieldType ClassType::* address); - - /// Declare an external chunk's DataSet - template - typename AZStd::enable_if::value, ClassBuilderPtr>::type - Field(const char* name, DataSetType ClassType::* address); - - /// Bind an Rpc::BindInterface for this chunk - template ::template BindInterface > - typename AZStd::enable_if::value, ClassBuilderPtr>::type - RPC(const char* name, RpcBindType ClassType::* rpc); - - /// Bind a NetBindable::Rpc for this NetBindable - template ::template Bind > - typename AZStd::enable_if::value, ClassBuilderPtr>::type - RPC(const char* name, RpcBindType ClassType::* rpc); - -#define CTOR_DATA_OVERLOAD(_getsig, _setsig) \ - template > \ - ClassBuilderPtr CtorData(const char* name, _getsig, _setsig, const MarshalerType&marshaler = MarshalerType()) \ - { \ - return CtorDataImpl(name, getter, setter, marshaler); \ - } - - /// Bind a getter/setter pair for data required during object construction - // this has to be done via overload so that the user does not have to explicitly provide - // the template arguments, they can be divined from the function call - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)() const, void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)() const, void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)() const, void (ClassType::* setter)(DataType)); -#undef CTOR_DATA_OVERLOAD - - private: - template > - ClassBuilderPtr CtorDataImpl(const char* name, GetterFunction getter, SetterFunction setter, const MarshalerType& marshaler = MarshalerType()); - - private: - ClassDescPtr m_binding; - NetworkContext* m_context; - }; - - class DescBase - : public IntrusiveRefCounted - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(DescBase, AZ::SystemAllocator, 0); - DescBase(const char* name, ptrdiff_t offset); - virtual ~DescBase() {} - - const char* GetName() const { return m_name; } - ptrdiff_t GetOffset() const { return m_offset; } - protected: - const char* m_name; ///< Field name, will be used as DataSet debug name - ptrdiff_t m_offset; ///< Offset from an instance pointer (a ReplicaChunk or the actual class instance) - }; - - class FieldDescBase - : public DescBase - { - friend class NetworkContext; - - public: - AZ_CLASS_ALLOCATOR(FieldDescBase, AZ::SystemAllocator, 0); - FieldDescBase(const char* name, ptrdiff_t offset); - virtual ~FieldDescBase() {} - - virtual void ConstructDataSet(void*) const = 0; - virtual void DestructDataSet(void*) const = 0; - virtual size_t GetDataSetSize() const = 0; - - size_t GetDataSetIndex() const { return m_dataSetIdx; } - - protected: - size_t m_dataSetIdx; - }; - - /** - * Represents a DataSet in a chunk or class - * NOTE: m_offset in this class is the offset from ReplicaChunk* -> DataSet - */ - template - class DataSetDesc - : public FieldDescBase - { - public: - AZ_CLASS_ALLOCATOR(DataSetDesc, AZ::SystemAllocator, 0); - DataSetDesc(const char* name, ptrdiff_t offset); - - void ConstructDataSet(void*) const override {} - void DestructDataSet(void*) const override {} - size_t GetDataSetSize() const override { return sizeof(DataSetType); } - }; - - /** - * Represents a field in a chunk, responsible for creating a DataSet - * that represents the field - * NOTE: m_offset in this class is the offset from NetBindable* -> NetBindable::Field - */ - template - class NetBindableFieldDesc - : public FieldDescBase - { - public: - using DataSetType = typename FieldType::DataSetType; - - public: - AZ_CLASS_ALLOCATOR(NetBindableFieldDesc, AZ::SystemAllocator, 0); - NetBindableFieldDesc(const char* name, ptrdiff_t offset); - - void ConstructDataSet(void* mem) const override { FieldType::ConstructDataSet(mem, m_name); } - void DestructDataSet(void* mem) const override { FieldType::DestructDataSet(mem); } - size_t GetDataSetSize() const override { return sizeof(DataSetType); } - }; - - class RpcDescBase - : public DescBase - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(RpcDescBase, AZ::SystemAllocator, 0); - RpcDescBase(const char* name, ptrdiff_t offset); - virtual ~RpcDescBase() {} - - virtual void ConstructRpc(void*) const {} - virtual void DestructRpc(void*) const {} - virtual size_t GetRpcSize() const { return 0; } - - size_t GetRpcIndex() const { return m_rpcIdx; } - - protected: - size_t m_rpcIdx; - }; - - template - class NetBindableRpcDesc - : public RpcDescBase - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(NetBindableRpcDesc, AZ::SystemAllocator, 0); - NetBindableRpcDesc(const char* name, ptrdiff_t offset) - : RpcDescBase(name, offset) - { - static_assert((AZStd::is_base_of::value), "NetBindableRpcDesc is intended for use only with NetBindableRpcs"); - } - - void ConstructRpc(void* mem) const override { RpcBindType::ConstructRpc(mem, m_name); } - void DestructRpc(void* mem) const override { RpcBindType::DestructRpc(mem); } - size_t GetRpcSize() const override { return sizeof(typename RpcBindType::BindInterfaceType); } - }; - - class CtorDataBase - : public IntrusiveRefCounted - { - public: - AZ_CLASS_ALLOCATOR(CtorDataBase, AZ::SystemAllocator, 0); - CtorDataBase(const char* name); - virtual ~CtorDataBase() {} - - virtual void Marshal(NetBindable* netBindable, WriteBuffer& buffer) const = 0; - virtual void Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const = 0; - virtual void Copy(ReadBuffer& src, WriteBuffer& dest) const = 0; - - protected: - const char* m_name; - }; - - template - class CtorDataDesc - : public CtorDataBase - { - using GetterFunction = AZStd::function; - using SetterFunction = AZStd::function; - public: - AZ_CLASS_ALLOCATOR(CtorDataDesc, AZ::SystemAllocator, 0); - CtorDataDesc(const char* name, GetterFunction get, SetterFunction set) - : CtorDataBase(name) - , m_get(get) - , m_set(set) - {} - - CtorDataDesc(const char* name, DataType(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)) - : CtorDataBase(name) - , m_get(AZStd::bind(getter, AZStd::placeholders::_1)) - , m_set(AZStd::bind(setter, AZStd::placeholders::_1, AZStd::placeholders::_2)) - {} - - void Marshal(NetBindable* netBindable, WriteBuffer& buffer) const override; - void Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const override; - virtual void Copy(ReadBuffer& src, WriteBuffer& dest) const override; - - GetterFunction m_get; - SetterFunction m_set; - MarshalerType m_marshaler; - }; - - struct ChunkDesc - { - public: - using Fields = AZStd::vector >; - using Rpcs = AZStd::vector >; - using Ctors = AZStd::vector >; - - const char* m_name = nullptr; ///< The name of the chunk - ReplicaChunkClassId m_chunkId; ///< The registered id of the ReplicaChunk this class will use - Fields m_fields; ///< list of data fields in the ReplicaChunk - Rpcs m_rpcs; ///< list of RPCs in the ReplicaChunk - Ctors m_ctors; ///< list of ctor callbacks to gather/apply ctor data - bool m_external = false; ///< If true, this chunk is separate from the class bound to it - }; - - /** - * Contains the chunk factory and field descriptions for a given class - */ - class ClassDesc - : public IntrusiveRefCounted - { - public: - - AZ_CLASS_ALLOCATOR(ClassDesc, AZ::SystemAllocator, 0); - ClassDesc(const char* name = nullptr, const AZ::Uuid& typeId = AZ::Uuid()); - - public: - const char* m_name; ///< The name of the class that is bound - AZ::Uuid m_typeId; ///< The type that this binding represents (null for chunks) - ChunkDesc m_chunkDesc; ///< Descriptor for the chunk for this type - - /// Functor which will register the ReplicaChunkDescriptor with the global registry - AZStd::function RegisterChunkType; - /// Functor to unregister the ReplicaChunkDescriptor (during reflection removal) - AZStd::function UnregisterChunkType; - /// Functor which will create a ReplicaChunk and bind it to the given instance - AZStd::function CreateReplicaChunk; - /// Functor which can destroy a ReplicaChunk and free its memory - AZStd::function DestroyReplicaChunk; - /// Functor which binds an instance of this class to its RPCs for local dispatch - AZStd::function BindRpcs; - }; - - AZ_CLASS_ALLOCATOR(NetworkContext, AZ::SystemAllocator, 0); - AZ_RTTI(NetworkContext, "{B1172D4A-EA1B-441D-AAE6-A9933DAECA8A}", AZ::ReflectContext); - - NetworkContext(); - virtual ~NetworkContext(); - - /// Register a class with the NetworkContext for replication - template - ClassBuilderPtr Class(); - - /// Create a replica chunk for a given class - ReplicaChunkBase* CreateReplicaChunk(const AZ::Uuid& typeId); - - /// Create a replica chunk for a given class, template version - template - ReplicaChunkBase* CreateReplicaChunk(); - - /// Destroy a replica chunk for a given class - void DestroyReplicaChunk(ReplicaChunkBase * chunk); - - /// Bind an instance and a chunk to each other - void Bind(NetBindable * instance, ReplicaChunkPtr chunk, NetworkContextBindMode mode); - - /// Returns whether or not a given type uses a reflected (automatic) ReplicaChunk - bool UsesSelfAsChunk(const AZ::Uuid & typeId) const; - - /// Returns whether or not a given type uses a custom ReplicaChunk - bool UsesExternalChunk(const AZ::Uuid & typeId) const; - - /// Return the size of the the chunk which will represent the given type - size_t GetReflectedChunkSize(const AZ::Uuid & typeId) const; - - using FieldVisitor = AZStd::function; - void EnumerateFields(const ReplicaChunkClassId&chunkId, FieldVisitor visitor) const; - void EnumerateFields(const AZ::Uuid & typeId, FieldVisitor visitor) const; - - using RpcVisitor = AZStd::function; - void EnumerateRpcs(const ReplicaChunkClassId&chunkId, RpcVisitor visitor) const; - void EnumerateRpcs(const AZ::Uuid & typeId, RpcVisitor visitor) const; - - using CtorVisitor = AZStd::function; - void EnumerateCtorData(const ReplicaChunkClassId&chunkId, CtorVisitor visitor) const; - void EnumerateCtorData(const AZ::Uuid & typeId, CtorVisitor visitor) const; - - private: - template - void InitReflectedChunkBinding(ClassDescPtr binding); - - template > - void InitExternalChunkBinding(ClassDescPtr binding); - - private: - ClassBindings m_classBindings; - ChunkBindings m_chunkBindings; - }; - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::ClassBuilderPtr NetworkContext::Class() - { - static_assert((AZStd::is_base_of::value), "Classes reflected through NetworkContext must be derived from NetBindable"); - const AZ::Uuid& typeId = AZ::AzTypeInfo::Uuid(); - ClassDescPtr binding = nullptr; - if (IsRemovingReflection()) // Just remove the entire class definition - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - binding = it->second; - m_chunkBindings.erase(binding->m_chunkDesc.m_chunkId); - m_classBindings.erase(it); - } - } - else - { - auto ret = m_classBindings.insert_key(typeId); - AZ_Assert(ret.second, "Cannot register more than one type with the same Uuid in the NetworkContext"); - binding = ret.first->second = aznew ClassDesc(AZ::AzTypeInfo::Name(), AZ::AzTypeInfo::Uuid()); - } - - return aznew ClassBuilder(this, binding); - } - - template - void NetworkContext::InitReflectedChunkBinding(ClassDescPtr binding) - { - if (!binding->RegisterChunkType) - { - binding->m_chunkDesc.m_name = ReflectedReplicaChunk::GetChunkName(); - ReplicaChunkClassId chunkClassId = ReplicaChunkClassId(binding->m_chunkDesc.m_name); - m_chunkBindings[chunkClassId] = binding; - NetworkContext* netContext = this; - - binding->RegisterChunkType = [chunkClassId, netContext]() - { - bool result = ReplicaChunkDescriptorTable::Get().RegisterChunkType, AutoChunkDescriptor >(); - ReplicaChunkDescriptor* desc = ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(chunkClassId); - ReplicaChunkDescriptorTable::Get().BeginConstructReplicaChunk(desc); - // The offset recorded in NetBindableFields is the offset in the NetBindable - // We must compute the offset of the generated DataSets here and record the - // index from the descriptor - ptrdiff_t offset = sizeof(ReflectedReplicaChunk); // data sets are right after the ReflectedReplicaChunk<> in memory - netContext->EnumerateFields(chunkClassId, - [desc, &offset](FieldDescBase* field) - { - desc->RegisterDataSet(field->m_name, offset); - field->m_dataSetIdx = desc->GetDataSetIndex(offset); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [desc, &offset](RpcDescBase* rpc) - { - desc->RegisterRPC(rpc->m_name, offset); - rpc->m_rpcIdx = desc->GetRpcIndex(offset); - offset += rpc->GetRpcSize(); - }); - AZ_Assert(offset == static_cast(ReflectedReplicaChunk::GetChunkSize()), "Overflow/underflow while registering DataSets for %s", ReflectedReplicaChunk::GetChunkName()); - ReplicaChunkDescriptorTable::Get().EndConstructReplicaChunk(); - return result; - }; - - binding->UnregisterChunkType = [chunkClassId]() - { - ReplicaChunkDescriptorTable::Get().UnregisterReplicaChunkDescriptor(chunkClassId); - }; - - binding->CreateReplicaChunk = [netContext, chunkClassId]() - { - ReflectedReplicaChunkBase* chunk = new(azmalloc(ReflectedReplicaChunk::GetChunkSize(), AZStd::alignment_of >::value, AZ::SystemAllocator, ReflectedReplicaChunk::GetChunkName()))ReflectedReplicaChunk(); - AZ::u8* dataStart = chunk->GetDataStart(); - AZ::u8* dataEnd = reinterpret_cast(chunk) + chunk->GetSize(); - ptrdiff_t offset = 0; - netContext->EnumerateFields(chunkClassId, - [&offset, dataStart, dataEnd](FieldDescBase* field) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* dataSetMem = reinterpret_cast(dataStart + offset); - field->ConstructDataSet(dataSetMem); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [&offset, dataStart, dataEnd](RpcDescBase* rpc) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* rpcMem = reinterpret_cast(dataStart + offset); - rpc->ConstructRpc(rpcMem); - offset += rpc->GetRpcSize(); - }); - AZ_Assert((dataStart + offset) == dataEnd, "Overflow/underflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - return chunk; - }; - - binding->DestroyReplicaChunk = [netContext, chunkClassId](ReplicaChunkBase* chunkBase) - { - AZ_Assert(chunkBase->GetDescriptor()->GetChunkTypeId() == chunkClassId, "Mismatched chunk type id for %s (0x%p)", ReflectedReplicaChunk::GetChunkName(), chunkBase); - ReflectedReplicaChunkBase* chunk = static_cast(chunkBase); - chunk->Unbind(); - - AZ::u8* dataStart = chunk->GetDataStart(); - AZ::u8* dataEnd = reinterpret_cast(chunk) + chunk->GetSize(); - ptrdiff_t offset = 0; - netContext->EnumerateFields(chunkClassId, - [&offset, dataStart, dataEnd](FieldDescBase* field) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in dtor while destroying %s", ReflectedReplicaChunk::GetChunkName()); - void* dataSetMem = reinterpret_cast(dataStart + offset); - field->DestructDataSet(dataSetMem); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [&offset, dataStart, dataEnd](RpcDescBase* rpc) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* rpcMem = reinterpret_cast(dataStart + offset); - rpc->DestructRpc(rpcMem); - offset += rpc->GetRpcSize(); - }); - AZ_Assert((dataStart + offset) == dataEnd, "Overflow/underflow in dtor while destroying %s", ReflectedReplicaChunk::GetChunkName()); - chunk->~ReflectedReplicaChunkBase(); - azfree(chunk, AZ::SystemAllocator, ReflectedReplicaChunk::GetChunkSize(), AZStd::alignment_of >::value); - }; - - binding->BindRpcs = [netContext, chunkClassId](NetBindable* bindable) - { - ClassType* derivedInstance = static_cast(bindable); - netContext->EnumerateRpcs(chunkClassId, - [derivedInstance](const RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - bindableRpc->Bind(derivedInstance); - }); - }; - - binding->m_chunkDesc.m_chunkId = chunkClassId; - } - } - - template - void NetworkContext::InitExternalChunkBinding(ClassDescPtr binding) - { - if (!binding->RegisterChunkType) - { - binding->m_chunkDesc.m_name = ChunkType::GetChunkName(); - ReplicaChunkClassId chunkClassId = ReplicaChunkClassId(binding->m_chunkDesc.m_name); - m_chunkBindings[chunkClassId] = binding; - const AZ::Uuid& typeId = binding->m_typeId; - NetworkContext* netContext = this; - binding->RegisterChunkType = [chunkClassId, typeId, netContext]() - { - bool result = ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - NetworkContextChunkDescriptor* desc = static_cast(ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(chunkClassId)); - desc->Bind(typeId); - netContext->EnumerateFields(chunkClassId, - [desc](FieldDescBase* field) - { - desc->RegisterDataSet(field->m_name, field->m_offset); - field->m_dataSetIdx = desc->GetDataSetIndex(field->m_offset); - }); - netContext->EnumerateRpcs(chunkClassId, - [desc](RpcDescBase* rpc) - { - desc->RegisterRPC(rpc->m_name, rpc->m_offset); - }); - return result; - }; - - binding->UnregisterChunkType = [chunkClassId]() - { - return ReplicaChunkDescriptorTable::Get().UnregisterReplicaChunkDescriptor(chunkClassId); - }; - - binding->CreateReplicaChunk = []() - { - return aznew ChunkType(); - }; - - binding->DestroyReplicaChunk = [](ReplicaChunkBase* chunk) - { - delete chunk; - }; - - binding->m_chunkDesc.m_chunkId = chunkClassId; - } - } - - template - ReplicaChunkBase* NetworkContext::CreateReplicaChunk() - { - return CreateReplicaChunk(AZ::AzTypeInfo::Uuid()); - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::DataSetDesc::DataSetDesc(const char* name, ptrdiff_t offset) - : NetworkContext::FieldDescBase(name, offset) - { - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::NetBindableFieldDesc::NetBindableFieldDesc(const char* name, ptrdiff_t offset) - : NetworkContext::FieldDescBase(name, offset) - { - } - - /////////////////////////////////////////////////////////////////////////// - template - void NetworkContext::CtorDataDesc::Marshal(NetBindable* netBindable, WriteBuffer& buffer) const - { - ClassType* instance = static_cast(netBindable); - DataType data = m_get(instance); - buffer.Write(data, m_marshaler); - } - - template - void NetworkContext::CtorDataDesc::Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const - { - ClassType* instance = static_cast(netBindable); - DataType data; - buffer.Read(data, m_marshaler); - if (instance) - { - m_set(instance, data); - } - } - - template - void NetworkContext::CtorDataDesc::Copy(ReadBuffer& src, WriteBuffer& dest) const - { - DataType data; - src.Read(data, m_marshaler); - dest.Write(data, m_marshaler); - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::ClassBuilderPtr NetworkContext::ClassBuilder::Chunk() - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "ReplicaChunks being registered with the NetworkContext must derive from ReplicaChunk"); - static_assert((AZStd::is_base_of::value), "Chunk bindings via NetworkContext must use a NetworkContextChunkDescriptor derived descriptor"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a ReplicaChunk for a class which has not been declared to the NetworkContext"); - AZ_Assert(!m_binding->m_chunkDesc.m_chunkId, "Cannot register more than one ReplicaChunk binding for a class in the NetworkContext"); - - m_context->InitExternalChunkBinding(m_binding); - m_binding->m_chunkDesc.m_external = true; - } - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::Field(const char* name, FieldType ClassType::* address) - { - if (!m_context->IsRemovingReflection()) - { - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a field for a class which has not been declared to the NetworkContext"); - AZ_Assert(!m_binding->m_chunkDesc.m_external, "Cannot register a NetBindable::Field from within an external chunk"); - - m_context->InitReflectedChunkBinding(m_binding); - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*address)); - m_binding->m_chunkDesc.m_fields.push_back(aznew NetBindableFieldDesc(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::Field(const char* name, DataSetType ClassType::* address) - { - if (!m_context->IsRemovingReflection()) - { - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a field for a class which has not been declared to the NetworkContext"); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*address)); - m_binding->m_chunkDesc.m_fields.push_back(aznew DataSetDesc(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::RPC(const char* name, RpcBindType ClassType::* rpc) - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "Cannot bind an RPC call to an object which is not a ReplicaChunkInterface"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register an RPC for a class which has not been declared to the NetworkContext"); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*rpc)); - m_binding->m_chunkDesc.m_rpcs.push_back(aznew RpcDescBase(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::RPC(const char* name, RpcBindType ClassType::* rpc) - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "Cannot bind an RPC call to an object which is not a ReplicaChunkInterface"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register an RPC for a class which has not been declared to the NetworkContext"); - - m_context->InitReflectedChunkBinding(m_binding); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*rpc)); - m_binding->m_chunkDesc.m_rpcs.push_back(aznew NetBindableRpcDesc(name, offset)); - } - - return this; - } - - template - NetworkContext::ClassBuilderPtr NetworkContext::ClassBuilder::CtorDataImpl(const char* name, GetterFunction getter, SetterFunction setter, const MarshalerType&) - { - if (!m_context->IsRemovingReflection()) - { - m_context->InitReflectedChunkBinding(m_binding); - - auto get = [getter](NetBindable* nb) -> DataType { return (*static_cast(nb).*getter)(); }; - auto set = [setter](NetBindable* nb, const DataType& data) { (*static_cast(nb).*setter)(data); }; - m_binding->m_chunkDesc.m_ctors.push_back(aznew CtorDataDesc(name, get, set)); - } - - return this; - } - - /////////////////////////////////////////////////////////////////////////// - template - const char* ReflectedReplicaChunk::GetChunkName() - { - static char name[128] = { 0 }; - if (!name[0]) - { - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), "ReflectedReplicaChunk<"); - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), AZ::AzTypeInfo::Name()); - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), ">"); - } - return name; - } - - template - size_t ReflectedReplicaChunk::GetChunkSize() - { - static size_t chunkSize = 0; - if (chunkSize == 0) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to compute chunk size"); - if (!netContext) - { - return 0; - } - chunkSize = sizeof(ReflectedReplicaChunk) + netContext->GetReflectedChunkSize(AZ::AzTypeInfo::Uuid()); - } - - return chunkSize; - } - - template - void ReflectedReplicaChunk::Bind(NetBindable* instance, NetworkContextBindMode mode) - { - SetHandler(instance); - ClassType* derivedInstance = azrtti_cast(instance); - AZ_Assert(derivedInstance, "Unable to convert NetBindable to %s", AZ::AzTypeInfo::Name()); - ReplicaChunkDescriptor* desc = GetDescriptor(); - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - netContext->EnumerateFields(desc->GetChunkTypeId(), - [this, derivedInstance, desc, mode](NetworkContext::FieldDescBase* field) - { - NetBindableFieldBase* bindableField = reinterpret_cast(reinterpret_cast(derivedInstance) + field->GetOffset()); - DataSetBase* dataSet = desc->GetDataSet(this, field->GetDataSetIndex()); - bindableField->Bind(dataSet, mode); - }); - netContext->EnumerateRpcs(desc->GetChunkTypeId(), - [this, derivedInstance, desc](NetworkContext::RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - RpcBase* rpcBase = desc->GetRpc(this, rpc->GetRpcIndex()); - bindableRpc->Bind(rpcBase); - }); - - // Transfer any stored ctor data from the buffer -> NetBindable instance - if (m_ctorBuffer.Size() > 0) - { - ReadBuffer ctorBuffer(m_ctorBuffer.GetEndianType(), m_ctorBuffer.Get(), m_ctorBuffer.Size()); - netContext->EnumerateCtorData(desc->GetChunkTypeId(), - [instance, &ctorBuffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Unmarshal(ctorBuffer, instance); - }); - } - } - - template - void ReflectedReplicaChunk::Unbind() - { - ReplicaChunkInterface* handler = GetHandler(); - if (!handler || handler == this) - { - return; - } - - NetBindable* netBindable = static_cast(handler); - ClassType* derivedInstance = azrtti_cast(netBindable); - AZ_Assert(derivedInstance, "Unable to convert NetBindable to %s. Have you forgotten to derive your component from AzFramework::NetBindable?", AZ::AzTypeInfo::Name()); - if (derivedInstance) - { - ReplicaChunkDescriptor* desc = GetDescriptor(); - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - netContext->EnumerateFields(desc->GetChunkTypeId(), - [derivedInstance](NetworkContext::FieldDescBase* field) - { - NetBindableFieldBase* bindableField = reinterpret_cast(reinterpret_cast(derivedInstance) + field->GetOffset()); - bindableField->Bind(nullptr, NetworkContextBindMode::NonAuthoritative); - }); - netContext->EnumerateRpcs(desc->GetChunkTypeId(), - [derivedInstance](NetworkContext::RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - bindableRpc->Bind(derivedInstance); - }); - } - - // We have disconnected from the handler and erased any connections from DataFields or Rpcs - SetHandler(nullptr); - } -} // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp index 838ab0b6e2..30343b1322 100644 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp @@ -26,12 +26,9 @@ #include #include -#include -#include #include -#include #include @@ -429,83 +426,60 @@ namespace AzFramework { LSV_BEGIN(lua, 1); - // calling format __index(table,key) - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua, lua_upvalueindex(1))); + AZ::ScriptContext::FromNativeContext(lua)->Error(AZ::ScriptContext::ErrorType::Warning, true, + "Property %s not found in entity table. Please push this property to your slice to avoid decrease in performance.", lua_tostring(lua, -1)); + int lookupKey = lua_gettop(lua); - bool readValue = false; - - if (netBindingTable != nullptr) + int lookupTable = lookupKey - 1; + // This is a slow function and it's made slow so we don't cache any extra data. + // This is done because this function will be called only the exported components + // and script are not in sync and we added new properties. + lua_getmetatable(lua, -2); // get the metatable which will be the top property table + int entityProperties = lua_gettop(lua); + if (lua_getmetatable(lua, -1) == 0) // get the metatable of the property which will be the original table { - AZ_Error("ScriptComponent",netBindingTable->GetScriptContext() != nullptr,"ScriptNetBindingTable is missing ScriptContext."); - AZ_Error("ScriptComponent",netBindingTable->GetScriptContext() == nullptr || netBindingTable->GetScriptContext()->NativeContext() == lua,"Trying to use a NetBindingTable in wrong lua context"); - - AZ::ScriptContext* scriptContext = netBindingTable->GetScriptContext(); - - if (scriptContext) - { - AZ::ScriptDataContext stackContext; - scriptContext->ReadStack(stackContext); - - readValue = netBindingTable->InspectTableValue(stackContext); - } + // we are looking at top level properties + lua_pushvalue(lua, -2); // copy the key + lua_rawget(lua, -2); // read the value } - - if (!readValue) + else { - AZ::ScriptContext::FromNativeContext(lua)->Error(AZ::ScriptContext::ErrorType::Warning, true, - "Property %s not found in entity table. Please push this property to your slice to avoid decrease in performance.", lua_tostring(lua, -1)); - int lookupKey = lua_gettop(lua); - - int lookupTable = lookupKey - 1; - // This is a slow function and it's made slow so we don't cache any extra data. - // This is done because this function will be called only the exported components - // and script are not in sync and we added new properties. - lua_getmetatable(lua, -2); // get the metatable which will be the top property table - int entityProperties = lua_gettop(lua); - if (lua_getmetatable(lua, -1) == 0) // get the metatable of the property which will be the original table + // we are looking into the sub table, so do a slow traversal + int scriptProperties = lua_gettop(lua); + if (!Properties__IndexFindSubtable(lua, lookupTable, entityProperties, scriptProperties)) { - // we are looking at top level properties - lua_pushvalue(lua, -2); // copy the key - lua_rawget(lua, -2); // read the value + lua_pushnil(lua); + return 1; // we did not find the table } else { - // we are looking into the sub table, so do a slow traversal - int scriptProperties = lua_gettop(lua); - if (!Properties__IndexFindSubtable(lua, lookupTable, entityProperties, scriptProperties)) - { - lua_pushnil(lua); - return 1; // we did not find the table - } - else - { - lua_pushvalue(lua, lookupKey); - lua_rawget(lua, -2); - } - } - - if (lua_istable(lua, -1)) - { - // if we are here the target table is on the top if the stack - lua_pushstring(lua, ScriptComponent::DefaultFieldName); + lua_pushvalue(lua, lookupKey); lua_rawget(lua, -2); - if (lua_isnil(lua, -1)) - { - // parent table is a group, pop the value and return the table - lua_pop(lua, 1); - } } - - // Duplicate the value, so once the storage is done its on top of the stack, and returned - lua_pushvalue(lua, -1); - - // Push key, and then move it below the value - lua_pushvalue(lua, lookupKey); - lua_insert(lua, -2); - - // Cache the value so that subsequent accesses to this property don't result in warnings - lua_rawset(lua, lookupTable); } + + if (lua_istable(lua, -1)) + { + // if we are here the target table is on the top if the stack + lua_pushstring(lua, ScriptComponent::DefaultFieldName); + lua_rawget(lua, -2); + if (lua_isnil(lua, -1)) + { + // parent table is a group, pop the value and return the table + lua_pop(lua, 1); + } + } + + // Duplicate the value, so once the storage is done its on top of the stack, and returned + lua_pushvalue(lua, -1); + + // Push key, and then move it below the value + lua_pushvalue(lua, lookupKey); + lua_insert(lua, -2); + + // Cache the value so that subsequent accesses to this property don't result in warnings + lua_rawset(lua, lookupTable); + return 1; } //========================================================================= @@ -515,30 +489,7 @@ namespace AzFramework { LSV_BEGIN_VARIABLE(lua); - // calling format __newindex(table,key,value) - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua, lua_upvalueindex(1))); - if (netBindingTable != nullptr) - { - AZ_Error("ScriptContext",netBindingTable->GetScriptContext() != nullptr,"ScriptNetBindingTable is missing ScriptContext."); - AZ_Error("ScriptContext",netBindingTable->GetScriptContext() == nullptr || netBindingTable->GetScriptContext()->NativeContext() == lua,"Trying to use a NetBindingTable in wrong lua context"); - - AZ::ScriptContext* scriptContext = netBindingTable->GetScriptContext(); - if (scriptContext) - { - AZ::ScriptDataContext stackContext; - scriptContext->ReadStack(stackContext); - - const bool assignedValue = netBindingTable->AssignTableValue(stackContext); - if (assignedValue) - { - LSV_END_VARIABLE(0); - return 0; - } - } - } - - // If we didn't assign the value above, we want - // to raw set the value to avoid coming back in here. + // We want to raw set the value to avoid coming back in here. lua_rawset(lua, 1); LSV_END_VARIABLE(-2); return 0; @@ -553,7 +504,6 @@ namespace AzFramework // [8/9/2013] //========================================================================= - const char* ScriptComponent::NetRPCFieldName = "NetRPCs"; const char* ScriptComponent::DefaultFieldName = "default"; ScriptComponent::ScriptComponent() @@ -561,7 +511,6 @@ namespace AzFramework , m_contextId(AZ::ScriptContextIds::DefaultScriptContextId) , m_script(AZ::Data::AssetLoadBehavior::PreLoad) , m_table(LUA_NOREF) - , m_netBindingTable(nullptr) { m_properties.m_name = "Properties"; } @@ -573,8 +522,6 @@ namespace AzFramework ScriptComponent::~ScriptComponent() { m_properties.Clear(); - - delete m_netBindingTable; } //========================================================================= @@ -604,11 +551,6 @@ namespace AzFramework return m_properties.GetProperty(propertyName); } - const AZ::ScriptProperty* ScriptComponent::GetNetworkedScriptProperty(const char* propertyName) const - { - return m_netBindingTable->FindScriptProperty(propertyName); - } - void ScriptComponent::Init() { // Grab the script context @@ -622,11 +564,6 @@ namespace AzFramework //========================================================================= void ScriptComponent::Activate() { - if (m_isSyncEnabled && m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - // if we have valid asset listen for script asset events, like reload if (m_script.GetId().IsValid()) { @@ -681,43 +618,6 @@ namespace AzFramework LoadScript(); } - //========================================================================= - // ScriptComponent::GetNetworkBinding - //========================================================================= - GridMate::ReplicaChunkPtr ScriptComponent::GetNetworkBinding() - { - if (m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - - return m_netBindingTable->GetNetworkBinding(); - } - - //========================================================================= - // ScriptComponent::SetNetworkBinding - //========================================================================= - void ScriptComponent::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) - { - if (m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - - m_netBindingTable->SetNetworkBinding(chunk); - } - - //========================================================================= - // ScriptComponent::UnbindFromNetwork - //========================================================================= - void ScriptComponent::UnbindFromNetwork() - { - if (m_netBindingTable) - { - m_netBindingTable->UnbindFromNetwork(); - } - } - //========================================================================= // LoadScript //========================================================================= @@ -741,11 +641,6 @@ namespace AzFramework AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Script, "Unload: %s", m_script.GetHint().c_str()); DestroyEntityTable(); - - if (m_netBindingTable) - { - m_netBindingTable->Unload(); - } } //========================================================================= @@ -798,12 +693,10 @@ namespace AzFramework // set the __index so we can read values in case we change the script // after we export the component lua_pushliteral(lua, "__index"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__Index, 1); lua_rawset(lua, -3); lua_pushliteral(lua, "__newindex"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__NewIndex, 1); lua_rawset(lua, -3); } @@ -835,8 +728,7 @@ namespace AzFramework { const char* tableName = lua_tolstring(lua, -2, nullptr); if (strncmp(tableName, "__", 2) == 0 || // skip metatables - strcmp(tableName, propertyTableName) == 0 || // Skip the Properties table - strcmp(tableName, ScriptComponent::NetRPCFieldName) == 0) // Want to skip the RPC table as well + strcmp(tableName, propertyTableName) == 0) // Skip the Properties table { break; } @@ -904,13 +796,10 @@ namespace AzFramework } lua_createtable(lua, 0, 1); // Create entity table; - int entityStackIndex = lua_gettop(lua); + [[maybe_unused]] int entityStackIndex = lua_gettop(lua); // Stack: ScriptRootTable PropertiesTable EntityTable - // Create our network binding. - CreateNetworkBindingTable(baseStackIndex, entityStackIndex); - if (basePropertyTable > -1) // if property table exists { CreatePropertyGroup(m_properties, basePropertyTable, lua_gettop(lua), basePropertyTable, true); @@ -932,11 +821,6 @@ namespace AzFramework // Keep the entity table in the registry m_table = luaL_ref(lua, LUA_REGISTRYINDEX); - if (m_netBindingTable) - { - m_netBindingTable->FinalizeNetworkTable(m_context, m_table); - } - // call OnActivate lua_pushliteral(lua, "OnActivate"); lua_rawget(lua, baseStackIndex); // ScriptTable[OnActivate] @@ -993,18 +877,6 @@ namespace AzFramework } } - //========================================================================= - // CreateNetworkBindingTable - // [6/27/2016] - //========================================================================= - void ScriptComponent::CreateNetworkBindingTable(int baseStackIndex, int entityStackIndex) - { - if (m_netBindingTable) - { - m_netBindingTable->CreateNetworkBindingTable(m_context, baseStackIndex, entityStackIndex); - } - } - //========================================================================= // CreatePropertyGroup // [3/3/2014] @@ -1028,12 +900,10 @@ namespace AzFramework // Ensure that this instance of Properties table has the proper __index and __newIndex metamethods. lua_newtable(lua); // This new table will become the Properties instance metatable. Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} lua_pushliteral(lua, "__index"); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index - lua_pushlightuserdata(lua, m_netBindingTable); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index m_netBinding lua_pushcclosure(lua, &Internal::Properties__Index, 1); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index function lua_rawset(lua, -3); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {__index=Internal::Properties__Index} lua_pushliteral(lua, "__newindex"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__NewIndex, 1); lua_rawset(lua, -3); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {__index=Internal::Properties__Index __newindex=Internal::Properties__NewIndex} lua_setmetatable(lua, -2); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {Meta{__index=Internal::Properties__Index __newindex=Internal::Properties__NewIndex} } @@ -1050,55 +920,6 @@ namespace AzFramework { AZ::ScriptProperty* prop = group.m_properties[i]; - if (m_netBindingTable != nullptr) - { - lua_pushlstring(lua, prop->m_name.c_str(), prop->m_name.length()); - lua_rawget(lua, propertyGroupTableIndex); - - // Stack: ... SomePropertyInThePropertiesTable. This may be any basic lua type (number, string, table etc) - if (lua_istable(lua, -1)) - { - bool isNetworkedProperty = false; - - AZ::ScriptDataContext stackContext; - - // If we find a table value. We want to inspect it for information. - if (m_context->ReadStack(stackContext)) - { - // check if the current property, which is a table, has a sub-table called "netSynched" - lua_pushliteral(lua, "netSynched"); // Stack: ... SomePropertyInThePropertiesTable netSynched - lua_rawget(lua, -2); // Stack: ... SomePropertyInThePropertiesTable NetSynchedSubTable/nil - if (stackContext.IsTable(-1)) - { - AZ::ScriptDataContext networkTableContext; - if (stackContext.InspectTable(-1, networkTableContext)) // Stack: ... SomePropertyInThePropertiesTable NetSynchedSubTable NetSynchedSubTable nil nil - { - // RegisterDataSet will make sure our __NewIndex function callback will be triggered whenever modifying netSynched Properties. - //isNetworkedProperty = true; - isNetworkedProperty = m_netBindingTable->RegisterDataSet(networkTableContext, prop); - } - } - - // Network binding table - lua_pop(lua, 1); // Stack: ... SomePropertyInThePropertiesTable - } - - // Pop this PropertiesTable's property - lua_pop(lua, 1); - - // If the property is networked, we don't want to copy it over into the table. - if (isNetworkedProperty) - { - continue; - } - } - else - { - // Remove the value we just pushed onto the stack - lua_pop(lua, 1); - } - } - lua_pushlstring(lua, prop->m_name.c_str(), prop->m_name.length()); if (prop->Write(*m_context)) { @@ -1157,7 +978,7 @@ namespace AzFramework return true; }; - serializeContext->Class() + serializeContext->Class() ->Version(3, converter) ->Field("ContextID", &ScriptComponent::m_contextId) ->Field("Properties", &ScriptComponent::m_properties) @@ -1174,8 +995,6 @@ namespace AzFramework AZ::ScriptProperties::Reflect(reflection); } } - - ScriptNetBindingTable::Reflect(reflection); } //========================================================================= diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h index 4d15bc527d..8294f3849c 100644 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h @@ -20,8 +20,6 @@ #include #include -#include - namespace AZ { class ScriptProperty; @@ -37,8 +35,6 @@ namespace AzToolsFramework namespace AzFramework { - class ScriptNetBindingTable; - struct ScriptCompileRequest; using WriteFunction = AZStd::function< AZ::Outcome(const ScriptCompileRequest&, AZ::IO::GenericStream& in, AZ::IO::GenericStream& out) >; @@ -92,15 +88,13 @@ namespace AzFramework class ScriptComponent : public AZ::Component , private AZ::Data::AssetBus::Handler - , public AzFramework::NetBindable { friend class AzToolsFramework::Components::ScriptEditorComponent; public: - static const char* NetRPCFieldName; static const char* DefaultFieldName; - AZ_COMPONENT(AzFramework::ScriptComponent, "{8D1BC97E-C55D-4D34-A460-E63C57CD0D4B}", NetBindable); + AZ_COMPONENT(AzFramework::ScriptComponent, "{8D1BC97E-C55D-4D34-A460-E63C57CD0D4B}", AZ::Component); /// \red ComponentDescriptor::Reflect static void Reflect(AZ::ReflectContext* reflection); @@ -116,7 +110,6 @@ namespace AzFramework // Methods used for unit tests AZ::ScriptProperty* GetScriptProperty(const char* propertyName); - const AZ::ScriptProperty* GetNetworkedScriptProperty(const char* propertyName) const; protected: ScriptComponent(const ScriptComponent&) = delete; @@ -133,13 +126,6 @@ namespace AzFramework void OnAssetReloaded(AZ::Data::Asset asset) override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // NetBindable - GridMate::ReplicaChunkPtr GetNetworkBinding() override; - void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) override; - void UnbindFromNetwork() override; - ////////////////////////////////////////////////////////////////////////// - /// Load script (unless already by other instances) and creates the script instance into the VM void LoadScript(); /// Removes the script instance and unloads the script (unless needed by other instances) @@ -152,8 +138,6 @@ namespace AzFramework void CreateEntityTable(); void DestroyEntityTable(); - void CreateNetworkBindingTable(int baseStackIndex, int entityStackIndex); - void CreatePropertyGroup(const ScriptPropertyGroup& group, int propertyGroupTableIndex, int parentIndex, int metatableIndex, bool isRoot); AZ::ScriptContext* m_context; ///< Context in which the script will be running @@ -161,7 +145,6 @@ namespace AzFramework AZ::Data::Asset m_script; ///< Reference to the script asset used for this component. int m_table; ///< Cached table index ScriptPropertyGroup m_properties; ///< List with all properties that were tweaked in the editor and should override values in the m_sourceScriptName class inside m_script. - ScriptNetBindingTable* m_netBindingTable; ///< Table that will hold our networked script values, and manage callbacks }; } // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp deleted file mode 100644 index f02e050e74..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp +++ /dev/null @@ -1,573 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "AzFramework/Script/ScriptMarshal.h" - -namespace AzFramework -{ - //////////////////////////// - // ScriptPropertyMarshaler - //////////////////////////// - - template - bool UnmarshalGenericType(AZ::DynamicSerializableField& serializableField, GridMate::ReadBuffer& rb) - { - bool valueChanged = true; - - GridMate::Marshaler serializableFieldMarshaler; - - // Store the old value, to compare with the unmarshaled value, to signal - T oldValue = (*serializableField.Get()); - - serializableFieldMarshaler.Unmarshal(serializableField,rb); - - // If our type hasn't changed, compare the values. - if (serializableField.m_typeId == T::TYPEINFO_Uuid()) - { - valueChanged = !(oldValue == (*serializableField.Get())); - } - - return valueChanged; - } - - class ScriptPropertyTableMarshalerHelper - { - public: - template - static void MarshalScriptPropertyGenericMap(const ScriptPropertyMarshaler& scriptPropertyMarshaler, GridMate::WriteBuffer& wb, const AZ::ScriptPropertyTable* scriptPropertyTable) - { - GridMate::Marshaler sizeMarshaler; - - auto mapIter = scriptPropertyTable->m_genericMapping.find(T::TYPEINFO_Uuid()); - - if (mapIter != scriptPropertyTable->m_genericMapping.end()) - { - AZ::ScriptPropertyGenericClassMapImpl* genericClassKeyMap = static_cast*>(mapIter->second); - - auto& valueMap = genericClassKeyMap->GetPairMapping(); - - // We will write out all of our keys. Since it is easier to write out nil values for the properties. - sizeMarshaler.Marshal(wb,static_cast(valueMap.size())); - - GridMate::Marshaler keyMarshaler; - - for (auto& mapPair : valueMap) - { - keyMarshaler.Marshal(wb,mapPair.first); - scriptPropertyMarshaler.Marshal(wb,mapPair.second.m_valueProperty); - } - } - else - { - sizeMarshaler.Marshal(wb,0); - } - } - - template - static bool UnmarshalScriptPropertyGenericMap(const ScriptPropertyMarshaler& scriptPropertyMarshaler, AZ::ScriptPropertyTable* scriptPropertyTable, GridMate::ReadBuffer& rb) - { - bool valueChanged = false; - - AZ::SerializeContext* useContext = nullptr; - EBUS_EVENT_RESULT(useContext, AZ::ComponentApplicationBus, GetSerializeContext); - - if (useContext) - { - const AZ::SerializeContext::ClassData* classData = useContext->FindClassData(T::TYPEINFO_Uuid()); - - if (classData && classData->m_factory) - { - auto mapIter = scriptPropertyTable->m_genericMapping.find(T::TYPEINFO_Uuid()); - - if (mapIter != scriptPropertyTable->m_genericMapping.end()) - { - // This whole thing is an in-place map update. - // to try to minimize the number of allocations. We try to re-use objects as much as possible. - // - // Two phase approach: Step one, update all of the existing properties, while keeping track of all of the used keys. - // Step two, go through and delete any unupdated keys from the mapping. - AZ::ScriptPropertyGenericClassMapImpl* genericClassKeyMap = static_cast*>(mapIter->second); - - AZStd::unordered_set newKeys; - - GridMate::Marshaler sizeMarshaler; - - AZ::u32 mapSize; - sizeMarshaler.Unmarshal(mapSize,rb); - - auto& valueMap = genericClassKeyMap->GetPairMapping(); - - GridMate::Marshaler keyMarshaler; - - for (unsigned int i=0; i < mapSize; ++i) - { - T propertyKey; - keyMarshaler.Unmarshal(propertyKey,rb); - - newKeys.insert(propertyKey); - - auto valueIter = valueMap.find(propertyKey); - - if (valueIter != valueMap.end()) - { - if (scriptPropertyMarshaler.UnmarshalToPointer(valueIter->second.m_valueProperty,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* newValueProperty = nullptr; - scriptPropertyMarshaler.UnmarshalToPointer(newValueProperty,rb); - - AZ::ScriptPropertyGenericClassMap::MapValuePair newPair; - - newPair.m_valueProperty = newValueProperty; - - T* serializableData = nullptr; - serializableData = static_cast(classData->m_factory->Create("ScriptProperty")); - (*serializableData) = propertyKey; - - AZ::ScriptPropertyGenericClass* genericPropertyClass = aznew AZ::ScriptPropertyGenericClass(); - - genericPropertyClass->Set(serializableData); - - newPair.m_keyProperty = genericPropertyClass; - - valueMap.emplace(propertyKey,newPair); - } - } - - // Delete all of the unused keyes from the map - auto valueIter = valueMap.begin(); - - while (valueIter != valueMap.end()) - { - if (newKeys.find(valueIter->first) == newKeys.end()) - { - valueChanged = true; - valueIter->second.Destroy(); - valueIter = valueMap.erase(valueIter); - } - else - { - ++valueIter; - } - } - } - } - } - - return valueChanged; - } - }; - - - - void ScriptPropertyMarshaler::Marshal(GridMate::WriteBuffer& wb, AZ::ScriptProperty*const& property) const - { - GridMate::Marshaler typeMarshaler; - GridMate::Marshaler idMarshaler; - GridMate::Marshaler nameMarshaler; - - if (property == nullptr) - { - // Write out a nil property if we have a nullptr property - nameMarshaler.Marshal(wb,""); - idMarshaler.Marshal(wb,0); - typeMarshaler.Marshal(wb,AZ::ScriptPropertyNil::RTTI_Type()); - return; - } - - // Common points: - // Always going to marshal the uuid of the type(or something similar) - // so we know what type we have on the other side. - // - // Next need to pass along the name field. - const AZ::Uuid& typeId = azrtti_typeid(property); - - nameMarshaler.Marshal(wb,property->m_name); - idMarshaler.Marshal(wb,property->m_id); - - // Method 1: - // - Allow each ScriptProperty to marshal itself. - // - Currently unavailable since the ScriptProperties live in AZCore - // and the WriteBuffer is in GridMate. - // cont.Marshal(wb); - - // Method 2: - // - Process all of our known marshallable types and use the appropriate marshaler - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler boolMarshaler; - boolMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler doubleMarshaler; - doubleMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler stringMarshaler; - stringMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - const AZ::DynamicSerializableField& serializableField = static_cast(property)->GetSerializableField(); - - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler serializableFieldMarshaler; - serializableFieldMarshaler.Marshal(wb,serializableField); - } - else if (typeId == AZ::ScriptPropertyTable::TYPEINFO_Uuid()) - { - const AZ::ScriptPropertyTable* scriptPropertyTable = static_cast(property); - - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler mapSizeMarshaler; - mapSizeMarshaler.Marshal(wb,static_cast(scriptPropertyTable->m_indexMapping.size())); - - GridMate::Marshaler indexMarshaler; - - // Currently only support integers as keys inside of the table. - for (auto& mapPair : scriptPropertyTable->m_indexMapping) - { - indexMarshaler.Marshal(wb,mapPair.first); - this->Marshal(wb,mapPair.second); - } - - mapSizeMarshaler.Marshal(wb, static_cast(scriptPropertyTable->m_keyMapping.size())); - - GridMate::Marshaler hashMarshaler; - - for (auto& mapPair : scriptPropertyTable->m_keyMapping) - { - // For hashed values. The name of the script property is the same as the hash it should be using. - // We still synchronize the Crc so we can unmarshal in place on the other side. - hashMarshaler.Marshal(wb,mapPair.first); - Marshal(wb,mapPair.second); - } - - // EntityId's - ScriptPropertyTableMarshalerHelper::MarshalScriptPropertyGenericMap((*this), wb, scriptPropertyTable); - } - else - { - typeMarshaler.Marshal(wb,AZ::ScriptPropertyNil::RTTI_Type()); - } - } - - bool ScriptPropertyMarshaler::UnmarshalToPointer(AZ::ScriptProperty*& target, GridMate::ReadBuffer& rb) const - { - bool typeChanged = false; - AZ::Uuid typeId; - AZ::u64 id; - AZStd::string name; - - GridMate::Marshaler typeMarshaler; - GridMate::Marshaler idMarshaler; - GridMate::Marshaler nameMarshaler; - - nameMarshaler.Unmarshal(name,rb); - idMarshaler.Unmarshal(id,rb); - typeMarshaler.Unmarshal(typeId,rb); - - if (target == nullptr || typeId != azrtti_typeid(target)) - { - typeChanged = true; - - AZ::ScriptProperty* actualScriptProperty = nullptr; - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyBoolean(); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyNumber(); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyString(); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyGenericClass(); - } - else if (typeId == AZ::ScriptPropertyTable::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyTable(); - } - else - { - actualScriptProperty = aznew AZ::ScriptPropertyNil(); - } - - actualScriptProperty->m_name = name; - delete target; - - target = actualScriptProperty; - } - - // Update our ID - target->m_id = id; - - // Method 1: - // - Allow each ScriptProperty to unmarshal itself - // - Currently unavailable since the ScriptProperties live in AZCore - // and the WriteBuffer is in GridMate - // actualScriptProperty->Unmarshal(rb); - // - // Method 2: - // - Process all of our known marshallable types and use the appropriate marshaler - - bool valueChanged = false; - - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - AZ::ScriptPropertyBoolean* booleanProperty = static_cast(target); - bool oldValue = booleanProperty->m_value; - - GridMate::Marshaler boolMarshaler; - boolMarshaler.Unmarshal(booleanProperty->m_value,rb); - - valueChanged = !(oldValue == booleanProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - AZ::ScriptPropertyString* stringProperty = static_cast(target); - AZStd::string oldValue = stringProperty->m_value; - - GridMate::Marshaler stringMarshaler; - stringMarshaler.Unmarshal(stringProperty->m_value,rb); - - valueChanged = !(oldValue == stringProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - AZ::ScriptPropertyNumber* numberProperty = static_cast(target); - double oldValue = numberProperty->m_value; - - GridMate::Marshaler numberMarshaler; - numberMarshaler.Unmarshal(numberProperty->m_value,rb); - - valueChanged = !(oldValue == numberProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - AZ::ScriptPropertyGenericClass* genericProperty = static_cast(target); - - AZ::DynamicSerializableField& serializableField = genericProperty->m_value; - - AZ::DynamicSerializableField oldField; - - oldField.CopyDataFrom(serializableField); - - GridMate::Marshaler serializableFieldMarshaler; - serializableFieldMarshaler.Unmarshal(serializableField,rb); - - // If our type hasn't changed, compare the values. - valueChanged = !oldField.IsEqualTo(serializableField); - } - else if (typeId == AZ::ScriptPropertyTable::RTTI_Type()) - { - AZ::ScriptPropertyTable* scriptPropertyTable = static_cast(target); - GridMate::Marshaler mapSizeMarshaler; - - // Unmarshal all of the indexes properties - { - AZ::u32 mapSize = 0; - mapSizeMarshaler.Unmarshal(mapSize, rb); - - AZStd::unordered_set newIndexes; - GridMate::Marshaler indexMarshaler; - - for (AZ::u32 i=0; i < mapSize; ++i) - { - int index = 0; - indexMarshaler.Unmarshal(index,rb); - - auto mapIter = scriptPropertyTable->m_indexMapping.find(index); - - if (mapIter != scriptPropertyTable->m_indexMapping.end()) - { - if (UnmarshalToPointer(mapIter->second,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* scriptProperty = nullptr; - UnmarshalToPointer(scriptProperty,rb); - auto insertResult = scriptPropertyTable->m_indexMapping.emplace(index,scriptProperty); - mapIter = insertResult.first; - } - - if (mapIter->second == nullptr || azrtti_istypeof(mapIter->second)) - { - valueChanged = true; - - delete mapIter->second; - scriptPropertyTable->m_indexMapping.erase(mapIter); - } - else - { - newIndexes.insert(index); - } - } - - auto mapIter = scriptPropertyTable->m_indexMapping.begin(); - - while (mapIter != scriptPropertyTable->m_indexMapping.end()) - { - if (newIndexes.find(mapIter->first) == newIndexes.end()) - { - valueChanged = true; - - delete mapIter->second; - mapIter = scriptPropertyTable->m_indexMapping.erase(mapIter); - } - else - { - ++mapIter; - } - } - } - - // Unmarshal all of the hashed values - { - AZ::u32 mapSize = 0; - mapSizeMarshaler.Unmarshal(mapSize, rb); - - AZStd::unordered_set newHashes; - GridMate::Marshaler hashMarshaler; - - for (AZ::u32 i=0; i < mapSize; ++i) - { - AZ::u32 newHash; - hashMarshaler.Unmarshal(newHash, rb); - - auto mapIter = scriptPropertyTable->m_keyMapping.find(newHash); - - if (mapIter != scriptPropertyTable->m_keyMapping.end()) - { - if (UnmarshalToPointer(mapIter->second,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* scriptProperty = nullptr; - UnmarshalToPointer(scriptProperty,rb); - auto emplaceResult = scriptPropertyTable->m_keyMapping.emplace(newHash,scriptProperty); - mapIter = emplaceResult.first; - } - - if (mapIter->second == nullptr || azrtti_istypeof(mapIter->second)) - { - valueChanged = true; - - delete mapIter->second; - scriptPropertyTable->m_keyMapping.erase(mapIter); - } - else - { - newHashes.insert(newHash); - } - } - - auto mapIter = scriptPropertyTable->m_keyMapping.begin(); - - while (mapIter != scriptPropertyTable->m_keyMapping.end()) - { - if (newHashes.find(mapIter->first) == newHashes.end()) - { - valueChanged = true; - - delete mapIter->second; - mapIter = scriptPropertyTable->m_keyMapping.erase(mapIter); - } - else - { - ++mapIter; - } - } - } - - // Unmarshal all of the generic properties - - // EntityId's - if (ScriptPropertyTableMarshalerHelper::UnmarshalScriptPropertyGenericMap((*this), scriptPropertyTable, rb)) - { - valueChanged = true; - } - } - - return typeChanged || valueChanged; - } - - //////////////////////////// - // ScriptPropertyThrottler - //////////////////////////// - - ScriptPropertyThrottler::ScriptPropertyThrottler() - : m_isDirty(true) - { - - } - - void ScriptPropertyThrottler::SignalDirty() - { - m_isDirty = true; - } - - bool ScriptPropertyThrottler::WithinThreshold(AZ::ScriptProperty* newValue) const - { - return newValue == nullptr || !m_isDirty; - } - - void ScriptPropertyThrottler::UpdateBaseline(AZ::ScriptProperty* baseline) - { - (void)baseline; - - m_isDirty = false; - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h deleted file mode 100644 index c13749d46b..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef AZFRAMEWORK_SCRIPT_SCRIPTMARSHAL_H -#define AZFRAMEWORK_SCRIPT_SCRIPTMARSHAL_H - -#include - -#include - -namespace AZ -{ - class ScriptProperty; -} - -namespace AzFramework -{ - /** - * Specalized helper marshaler for ScriptProperty class - */ - class ScriptPropertyMarshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, AZ::ScriptProperty*const& cont) const; - bool UnmarshalToPointer(AZ::ScriptProperty*& target, GridMate::ReadBuffer& rb) const; - }; - - class ScriptPropertyThrottler - { - public: - ScriptPropertyThrottler(); - - void SignalDirty(); - bool WithinThreshold(AZ::ScriptProperty* newValue) const; - void UpdateBaseline(AZ::ScriptProperty* baseline); - - private: - bool m_isDirty; - }; - - /** - * Specialized helper marshaler to help with the vector creation/destruction - */ - class ScriptRPCMarshaler - { - public: - - typedef AZStd::vector< AZ::ScriptProperty* > Container; - - ScriptRPCMarshaler() - { - } - - AZ_FORCE_INLINE void Marshal(GridMate::WriteBuffer& wb, const Container& container) const - { - AZ_Assert(container.size() < USHRT_MAX, "Container has too many elements for marshaling!"); - AZ::u16 size = static_cast(container.size()); - wb.Write(size); - for (const auto& i : container) - { - m_marshaler.Marshal(wb, i); - } - } - - AZ_FORCE_INLINE void Unmarshal(Container& container, GridMate::ReadBuffer& rb) const - { - container.clear(); - - AZ::u16 size; - rb.Read(size); - container.reserve(size); - - for (AZ::u16 i = 0; i < size; ++i) - { - AZ::ScriptProperty* readProperty = nullptr; - m_marshaler.UnmarshalToPointer(readProperty, rb); - container.insert(container.end(), readProperty); - } - } - - protected: - ScriptPropertyMarshaler m_marshaler; - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp deleted file mode 100644 index 45690eac01..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp +++ /dev/null @@ -1,1427 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include - -#include -#include - -#include - -extern "C" { -# include -# include -} - -namespace AzFramework -{ - namespace Internal - { - static int NetBinding__IsAuthoritative(lua_State* lua) - { - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua,lua_upvalueindex(1))); - - //AZ_Assert(netBindingTable != nullptr && netBindingTable->GetScriptContext(),"Missing or misconfigured ScriptNetBindingTable as upvalue in lua_cclosure"); - if (netBindingTable && netBindingTable->GetScriptContext()) - { - lua_pushboolean(lua,netBindingTable->IsMaster()); - } - else - { - // If we don't have a net binding table, or a a script context, return true - // since we likely are the master. - lua_pushboolean(lua,true); - } - - return 1; - } - - static int NetBinding__IsMaster(lua_State* lua) - { - AZ_Warning("ScriptNetBindings", false, "IsMaster deprecated for the more lexical consistent IsAuthoritative"); - return NetBinding__IsAuthoritative(lua); - } - - static int NetBinding__CallRPC(lua_State* lua) - { - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua,lua_upvalueindex(1))); - - AZ_Error("ScriptComponent", netBindingTable != nullptr,"Missing ScriptNetBindingTable as upvalue in lua_cclosure"); - AZ_Error("ScriptComponent", netBindingTable == nullptr || netBindingTable->GetScriptContext(),"Missing ScriptNetBindingTable as upvalue in lua_cclosure"); - if (netBindingTable && netBindingTable->GetScriptContext()) - { - AZ::ScriptContext* context = netBindingTable->GetScriptContext(); - - AZ::ScriptDataContext stackContext; - bool validIndex = context->ReadStack(stackContext); - - if (validIndex) - { - netBindingTable->InvokeRPC(stackContext); - } - } - - return 0; - } - } - - ////////////////////////// - // ScriptPropertyDataSet - ////////////////////////// - - // Necessary since the field doesn't make a copy, but keeps the actual literal. - // But overall :( - - const char* ScriptPropertyDataSet::GetDataSetName() - { - static size_t s_chunkIndex = 0; - static const char* s_nameArray[] = { - "DataSet1","DataSet2","DataSet3","DataSet4","DataSet5", - "DataSet6","DataSet7","DataSet8","DataSet9","DataSet10", - "DataSet11","DataSet12","DataSet13","DataSet14","DataSet15", - "DataSet16","DataSet17","DataSet18","DataSet19","DataSet20", - "DataSet21","DataSet22","DataSet23","DataSet24","DataSet25", - "DataSet26","DataSet27","DataSet28","DataSet29","DataSet30", - "DataSet31","DataSet32" - }; - - if ((s_chunkIndex >= AZ_ARRAY_SIZE(s_nameArray)) && (AZ_ARRAY_SIZE(s_nameArray) >= 0)) - { - s_chunkIndex = s_chunkIndex % AZ_ARRAY_SIZE(s_nameArray); - } - - return s_nameArray[s_chunkIndex++]; - } - - ScriptPropertyDataSet::ScriptPropertyDataSet() - : ScriptPropertyDataSetType(GetDataSetName()) - , m_reserver(nullptr) - { - } - - ScriptPropertyDataSet::~ScriptPropertyDataSet() - { - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(Get()); - - if (functionalScriptProperty) - { - functionalScriptProperty->DisableInPlaceControls(); - functionalScriptProperty->RemoveWatcher(this); - } - } - - void ScriptPropertyDataSet::Reserve(ScriptNetBindingTable::NetworkedTableValue* reserver) - { - AZ_Error("ScriptComponent",m_reserver == nullptr || reserver == m_reserver, "Trying to reserve the same DataSet for two NetworkedTableVaules."); - - if (m_reserver == nullptr) - { - m_reserver = reserver; - AZ::ScriptPropertyWatcherBus::Handler::BusConnect(this); - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(Get()); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - } - } - - void ScriptPropertyDataSet::Release(ScriptNetBindingTable::NetworkedTableValue* reserver) - { - AZ_Error("ScriptComponent",m_reserver == nullptr || m_reserver == reserver, "Incorrect NetworkedTableValue trying to release a reserver DataSet."); - if (m_reserver == reserver) - { - m_reserver = nullptr; - AZ::ScriptPropertyWatcherBus::Handler::BusDisconnect(this); - } - } - - bool ScriptPropertyDataSet::IsReserved() const - { - return m_reserver != nullptr; - } - - bool ScriptPropertyDataSet::UpdateScriptProperty(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName) - { - bool wroteValue = false; - - Modify([&](AZ::ScriptProperty*& scriptProperty) - { - wroteValue = true; - if (scriptProperty == nullptr || !scriptProperty->TryRead(scriptDataContext,-1)) - { - AZ::ScriptProperty* newPropertyType = scriptDataContext.ConstructScriptProperty(-1,propertyName.c_str()); - - delete scriptProperty; - - if (newPropertyType == nullptr) - { - scriptProperty = aznew AZ::ScriptPropertyNil(); - } - else - { - scriptProperty = newPropertyType; - } - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(newPropertyType); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - } - - m_throttler.SignalDirty(); - - return wroteValue; - }); - - return wroteValue; - } - - void ScriptPropertyDataSet::SetScriptProperty(AZ::ScriptProperty* scriptProperty) - { - Modify([&](AZ::ScriptProperty*& dataSetProperty) - { - AZ::ScriptProperty* tempProperty = dataSetProperty; - - if (scriptProperty == nullptr) - { - if (tempProperty) - { - dataSetProperty = aznew AZ::ScriptPropertyNil(tempProperty->m_name.c_str()); - } - else - { - dataSetProperty = aznew AZ::ScriptPropertyNil(); - } - } - else - { - dataSetProperty = scriptProperty; - } - - if (tempProperty) - { - delete tempProperty; - } - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(dataSetProperty); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - - m_throttler.SignalDirty(); - - return true; - }); - } - - void ScriptPropertyDataSet::OnObjectModified() - { - m_throttler.SignalDirty(); - SetDirty(); - } - - //////////////////////// - // EntityScriptContext - //////////////////////// - - ScriptNetBindingTable::EntityScriptContext::EntityScriptContext() - : m_scriptContext(nullptr) - , m_entityTableRegistryIndex(LUA_REFNIL) - { - } - - void ScriptNetBindingTable::EntityScriptContext::Unload() - { - m_scriptContext = nullptr; - m_entityTableRegistryIndex = LUA_REFNIL; - } - - bool ScriptNetBindingTable::EntityScriptContext::HasEntityTableRegistryIndex() const - { - return m_entityTableRegistryIndex != LUA_REFNIL; - } - - int ScriptNetBindingTable::EntityScriptContext::GetEntityTableRegistryIndex() const - { - return m_entityTableRegistryIndex; - } - - bool ScriptNetBindingTable::EntityScriptContext::HasScriptContext() const - { - return m_scriptContext != nullptr; - } - - AZ::ScriptContext* ScriptNetBindingTable::EntityScriptContext::GetScriptContext() const - { - return m_scriptContext; - } - - void ScriptNetBindingTable::EntityScriptContext::ConfigureContext(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex) - { - m_scriptContext = scriptContext; - m_entityTableRegistryIndex = entityTableRegistryIndex; - - AZ_Error("ScriptComponent",SanityCheckContext(),"Invalid configuration given to ScriptNetBindingTable"); - } - - bool ScriptNetBindingTable::EntityScriptContext::SanityCheckContext() const - { - bool isSane = HasScriptContext(); - - if (isSane) - { - // We want to check if our reference is actually pointing to a table - // which we will assume is our entity table - lua_State* nativeContext = m_scriptContext->NativeContext(); - - lua_rawgeti(nativeContext,LUA_REGISTRYINDEX,m_entityTableRegistryIndex); - isSane = lua_istable(nativeContext,-1); - lua_pop(nativeContext,1); - } - - return isSane; - } - - //////////////////////// - // NetworkedTableValue - //////////////////////// - - ScriptNetBindingTable::NetworkedTableValue::NetworkedTableValue(AZ::ScriptProperty* initialValue) - : m_shimmedScriptProperty(initialValue) - , m_dataSet(nullptr) - , m_forcedDataSetIndex(-1) - , m_functionReference(LUA_REFNIL) - { - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(initialValue); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - } - } - - ScriptNetBindingTable::NetworkedTableValue::~NetworkedTableValue() - { - // Always want to release our dataset if we have one when we are destroyed. - // - // We do not want to delete our proeprty thought, since we might have been copied over. - if (m_dataSet) - { - m_dataSet->Release(this); - } - } - - void ScriptNetBindingTable::NetworkedTableValue::Destroy() - { - if (m_shimmedScriptProperty) - { - delete m_shimmedScriptProperty; - m_shimmedScriptProperty = nullptr; - } - - if (m_dataSet) - { - m_dataSet->Release(this); - } - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasDataSet() const - { - return m_dataSet != nullptr; - } - - void ScriptNetBindingTable::NetworkedTableValue::RegisterDataSet(ScriptPropertyDataSet* dataSet) - { - m_dataSet = dataSet; - - if (m_dataSet) - { - if (m_shimmedScriptProperty) - { - m_dataSet->SetScriptProperty(m_shimmedScriptProperty); - m_shimmedScriptProperty = nullptr; - } - - m_dataSet->Reserve(this); - } - } - - void ScriptNetBindingTable::NetworkedTableValue::UnbindFromDataSet() - { - if (m_dataSet) - { - // Take ownership of the DataSet script property into our shimmed value - // - // If we are the master, we can take ownership and set the data set value to null - if (m_dataSet->CanSet()) - { - m_shimmedScriptProperty = m_dataSet->Get(); - m_dataSet->Set(nullptr); - } - // Otherwise, we need to clone the data in the data set since we can't modify it and we need to avoid a double deletion. - else - { - AZ::ScriptProperty* scriptProperty = m_dataSet->Get(); - m_shimmedScriptProperty = scriptProperty->Clone(); - } - - m_dataSet->Release(this); - m_dataSet = nullptr; - } - } - - ScriptPropertyDataSet* ScriptNetBindingTable::NetworkedTableValue::GetDataSet() const - { - return m_dataSet; - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasForcedDataSetIndex() const - { - return m_forcedDataSetIndex >= 1; - } - - void ScriptNetBindingTable::NetworkedTableValue::SetForcedDataSetIndex(int index) - { - m_forcedDataSetIndex = index; - } - - int ScriptNetBindingTable::NetworkedTableValue::GetForcedDataSetIndex() const - { - return m_forcedDataSetIndex; - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasCallback() const - { - return m_functionReference != LUA_REFNIL; - } - - void ScriptNetBindingTable::NetworkedTableValue::RegisterCallback(int functionReference) - { - AZ_Warning("ScriptComponent",!HasCallback() || functionReference == LUA_REFNIL,"Overriding an already registered callback for a DataSet."); - - m_functionReference = functionReference; - } - - void ScriptNetBindingTable::NetworkedTableValue::ReleaseCallback(AZ::ScriptContext& scriptContext) - { - if (HasCallback()) - { - scriptContext.ReleaseCached(m_functionReference); - m_functionReference = LUA_REFNIL; - } - } - - void ScriptNetBindingTable::NetworkedTableValue::InvokeCallback(EntityScriptContext& entityContext, const GridMate::TimeContext& timeContext) - { - (void)timeContext; - - AZ::ScriptContext* scriptContext = entityContext.GetScriptContext(); - - AZ_Warning("ScriptComponent",scriptContext,"DataSetCallback given null ScriptContext."); - AZ_Warning("ScriptComponent",entityContext.HasEntityTableRegistryIndex(),"DataSetCallback given invalid entity table reference"); - if (scriptContext && entityContext.HasEntityTableRegistryIndex()) - { - AZ::ScriptDataContext callContext; - - if (scriptContext->CallCached(m_functionReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityContext.GetEntityTableRegistryIndex()); - callContext.CallExecute(); - } - } - } - - bool ScriptNetBindingTable::NetworkedTableValue::AssignValue(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName) - { - bool assignedValue = false; - if (HasDataSet()) - { - assignedValue = GetDataSet()->UpdateScriptProperty(scriptDataContext, propertyName); - } - else - { - if (m_shimmedScriptProperty == nullptr || !m_shimmedScriptProperty->TryRead(scriptDataContext,-1)) - { - delete m_shimmedScriptProperty; - m_shimmedScriptProperty = nullptr; - m_shimmedScriptProperty = scriptDataContext.ConstructScriptProperty(-1,propertyName.c_str()); - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(m_shimmedScriptProperty); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - } - } - - assignedValue = (m_shimmedScriptProperty != nullptr); - } - - return assignedValue; - } - - bool ScriptNetBindingTable::NetworkedTableValue::InspectValue(AZ::ScriptContext* scriptContext) const - { - AZ::ScriptProperty* inspectedProperty = m_shimmedScriptProperty; - - if (HasDataSet()) - { - inspectedProperty = GetDataSet()->Get(); - } - - bool inspectedValue = false; - - if (inspectedProperty) - { - inspectedValue = inspectedProperty->Write((*scriptContext)); - } - - if (!inspectedValue) - { - inspectedValue = true; - - AZ::ScriptPropertyNil nilProperty; - nilProperty.Write((*scriptContext)); - } - - return inspectedValue; - } - - ////////////// - // RPCHelper - ////////////// - - // Maybe make this guy create the table himself? - // Encapsulate the whole binding process in here. - ScriptNetBindingTable::RPCBindingHelper::RPCBindingHelper() - : m_masterReference(LUA_REFNIL) - , m_proxyReference(LUA_REFNIL) - { - } - - ScriptNetBindingTable::RPCBindingHelper::~RPCBindingHelper() - { - } - - void ScriptNetBindingTable::RPCBindingHelper::ReleaseTableIndex(AZ::ScriptContext& scriptContext) - { - if (m_masterReference != LUA_REFNIL) - { - scriptContext.ReleaseCached(m_masterReference); - m_masterReference = LUA_REFNIL; - } - - if (m_proxyReference != LUA_REFNIL) - { - scriptContext.ReleaseCached(m_proxyReference); - m_proxyReference = LUA_REFNIL; - } - } - - bool ScriptNetBindingTable::RPCBindingHelper::IsValid() const - { - // Proxy is optional, so we only care about having the master index. - return m_masterReference != LUA_REFNIL; - } - - void ScriptNetBindingTable::RPCBindingHelper::SetMasterFunction(int masterReference) - { - AZ_Error("ScriptComponent",m_masterReference == LUA_REFNIL || masterReference == LUA_REFNIL, "Trying to rebind RPC master callback"); - - if (m_masterReference == LUA_REFNIL || masterReference == LUA_REFNIL) - { - m_masterReference = masterReference; - } - } - - bool ScriptNetBindingTable::RPCBindingHelper::InvokeMaster(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params) - { - if (!entityScriptContext.HasScriptContext()) - { - AZ_Error("ScriptComponent",false,"Invoking RPC with invalid ScriptContext"); - return false; - } - - bool allowRPC = false; - - if (m_masterReference != LUA_REFNIL) - { - AZ::ScriptDataContext callContext; - AZ::ScriptContext* scriptContext = entityScriptContext.GetScriptContext(); - - if (scriptContext->CallCached(m_masterReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityScriptContext.GetEntityTableRegistryIndex()); - - for (AZ::ScriptProperty* property : params) - { - callContext.PushArgScriptProperty(property); - } - - if (callContext.CallExecute()) - { - bool hasResult = false; - if (callContext.GetNumResults() == 1) - { - hasResult = callContext.ReadResult(0,allowRPC); - } - - AZ_Assert(hasResult,"Master RPC function needs to return a boolean value"); - (void)hasResult; - } - } - - } - - return allowRPC; - } - - void ScriptNetBindingTable::RPCBindingHelper::SetProxyFunction(int proxyReference) - { - AZ_Error("ScriptComponent",m_proxyReference == LUA_REFNIL || proxyReference == LUA_REFNIL,"Trying to rebind an RPC Proxy call."); - - if (m_proxyReference == LUA_REFNIL || proxyReference == LUA_REFNIL) - { - m_proxyReference = proxyReference; - } - } - - void ScriptNetBindingTable::RPCBindingHelper::InvokeProxy(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params) - { - if (!entityScriptContext.HasScriptContext()) - { - AZ_Error("ScriptComponent",false,"Trying to call a callback without a script context."); - return; - } - - AZ_Warning("ScriptComponent",m_proxyReference != LUA_REFNIL,"Trying to invoke an RPC on the proxy without a callback being set."); - if (m_proxyReference != LUA_REFNIL) - { - AZ::ScriptDataContext callContext; - AZ::ScriptContext* scriptContext = entityScriptContext.GetScriptContext(); - - if (scriptContext->CallCached(m_proxyReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityScriptContext.GetEntityTableRegistryIndex()); - - for (AZ::ScriptProperty* property : params) - { - callContext.PushArgScriptProperty(property); - } - - callContext.CallExecute(); - } - } - } - - ////////////////////////// - // ScriptNetBindingTable - ////////////////////////// - void ScriptNetBindingTable::Reflect(AZ::ReflectContext* reflection) - { - NetworkContext* netContext = azrtti_cast(reflection); - - if (netContext) - { - // Using old method until we update the network context to allow for array offests. - // Or find a better way to handle the script replica chunk - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(ScriptComponentReplicaChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } - - // Template specialization for the ConvertPropertyArrayToTable GenericClass support to deal with extra memory copies. - template<> - AZ::ScriptPropertyTable* ScriptNetBindingTable::ConvertPropertyArrayToTable(AZ::ScriptPropertyGenericClassArray* arrayProperty) - { - AZ::ScriptPropertyTable* scriptPropertyTable = aznew AZ::ScriptPropertyTable(arrayProperty->m_name.c_str()); - - AZ::ScriptPropertyGenericClass emptyGenericClass; - - for (unsigned int i=0; i < arrayProperty->m_values.size(); ++i) - { - // Offset by 1 to deal with lua 1 indexing. - // Table will make a clone of our object. - // - // To avoid pointlessly double copying the data. Insert the empty class. - scriptPropertyTable->SetTableValue(i+1, &emptyGenericClass); - - // Then do a find for the class back, to load up the data into the final object directly. - AZ::ScriptPropertyGenericClass* ownedClass = static_cast(scriptPropertyTable->FindTableValue(i+1)); - - const AZ::DynamicSerializableField& serializableField = arrayProperty->m_values[i]; - - ownedClass->Set(serializableField); - } - - return scriptPropertyTable; - } - - ScriptNetBindingTable::ScriptNetBindingTable() - { - } - - ScriptNetBindingTable::~ScriptNetBindingTable() - { - - } - - void ScriptNetBindingTable::Unload() - { - // Unbind our elements from our script context. - if (m_entityScriptContext.HasScriptContext()) - { - AZ::ScriptContext& scriptContext = (*m_entityScriptContext.GetScriptContext()); - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - NetworkedTableValue& tableValue = tablePair.second; - tableValue.ReleaseCallback(scriptContext); - } - - for (RPCHelperMap::value_type& rpcPair : m_rpcHelperMap) - { - RPCBindingHelper& bindingHelper = rpcPair.second; - bindingHelper.ReleaseTableIndex(scriptContext); - } - } - - // Destroy the table values, since they might contain some memory - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - tablePair.second.Destroy(); - } - - m_networkedTable.clear(); - m_rpcHelperMap.clear(); - - m_entityScriptContext.Unload(); - } - - void ScriptNetBindingTable::CreateNetworkBindingTable(AZ::ScriptContext* scriptContext, int baseTableIndex, int entityTableIndex) - { - (void)baseTableIndex; - - lua_State* nativeContext = scriptContext->NativeContext(); - - lua_pushliteral(nativeContext,"IsMaster"); - lua_pushlightuserdata(nativeContext,this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__IsMaster,1); - lua_rawset(nativeContext,entityTableIndex); - - lua_pushliteral(nativeContext,"IsAuthoritative"); - lua_pushlightuserdata(nativeContext,this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__IsAuthoritative,1); - lua_rawset(nativeContext,entityTableIndex); - - lua_pushstring(nativeContext,ScriptComponent::NetRPCFieldName); - lua_createtable(nativeContext,0,0); - - int rpcTableIndex = lua_gettop(nativeContext); - - // Read the stack - AZ::ScriptDataContext stackContext; - if (scriptContext->ReadStack(stackContext)) - { - // Inspect the element we know to be our table context - AZ::ScriptDataContext entityDataContext; - if (stackContext.IsTable(baseTableIndex) && stackContext.InspectTable(baseTableIndex,entityDataContext)) - { - // Find our RPC table inside of baseTableIndex - int tableIndex = 0; - if (entityDataContext.PushTableElement(ScriptComponent::NetRPCFieldName,&tableIndex)) - { - // If it's a table, we want to inspect it. - AZ::ScriptDataContext rpcTable; - if (entityDataContext.IsTable(tableIndex) && entityDataContext.InspectTable(tableIndex,rpcTable)) - { - // Iterate over the fields here, and register and RPC for each element inside of that table. - int fieldIndex; - int elementIndex; - const char* fieldName; - - while (rpcTable.InspectNextElement(elementIndex, fieldName, fieldIndex)) - { - if (fieldName != nullptr) - { - RegisterRPC(rpcTable,fieldName,elementIndex,rpcTableIndex); - } - } - } - } - } - } - - lua_rawset(nativeContext,entityTableIndex); - } - - void ScriptNetBindingTable::FinalizeNetworkTable(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex) - { - m_entityScriptContext.ConfigureContext(scriptContext, entityTableRegistryIndex); - - if (m_replicaChunk) - { - AssignDataSets(); - } - } - - AZ::ScriptContext* ScriptNetBindingTable::GetScriptContext() const - { - return m_entityScriptContext.GetScriptContext(); - } - - bool ScriptNetBindingTable::IsMaster() const - { - return (m_replicaChunk != nullptr) ? m_replicaChunk->IsMaster() : true; - } - - bool ScriptNetBindingTable::AssignTableValue(AZ::ScriptDataContext& stackDataContext) - { - bool wroteValue = false; - AZ_Error("ScriptComponent",stackDataContext.GetScriptContext() == m_entityScriptContext.GetScriptContext(),"Trying to use a ScriptNetBindings in the wrong context."); - - // We do not want to allow assignments on proxy replicas - // since that information will be discarded anyway. - if ((m_replicaChunk && !m_replicaChunk->IsMaster()) || (stackDataContext.GetScriptContext() != m_entityScriptContext.GetScriptContext())) - { - return false; - } - - AZStd::string key; - - if (stackDataContext.ReadValue(-2,key)) - { - NetworkedTableValue* networkedTableValue = FindTableValue(key); - - // If we don't have the value, it means we aren't trying to network it. - if (networkedTableValue) - { - if (m_replicaChunk && !networkedTableValue->HasDataSet()) - { - ScriptComponentReplicaChunk* scriptChunk = static_cast(m_replicaChunk.get()); - - scriptChunk->AssignDataSet((*networkedTableValue)); - } - - wroteValue = networkedTableValue->AssignValue(stackDataContext,key); - } - } - - return wroteValue; - } - - bool ScriptNetBindingTable::InspectTableValue(AZ::ScriptDataContext& stackContext) const - { - bool readValue = false; - AZStd::string key; - - if (stackContext.ReadValue(-1,key)) - { - AZ::ScriptContext* scriptContext = stackContext.GetScriptContext(); - - if (scriptContext) - { - const NetworkedTableValue* networkTableValue = FindTableValue(key); - - if (networkTableValue) - { - readValue = networkTableValue->InspectValue((stackContext.GetScriptContext())); - - // Default to nil if we have a network table value registered, but couldn't - // inspect it for some reason. - if (!readValue) - { - readValue = true; - static AZ::ScriptPropertyNil s_nilValue; - s_nilValue.Write((*scriptContext)); - } - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to read value into invalid ScriptContext"); - } - } - - return readValue; - } - - bool ScriptNetBindingTable::RegisterDataSet(AZ::ScriptDataContext& networkTableContext, AZ::ScriptProperty* scriptProperty) - { - if (scriptProperty == nullptr) - { - AZ_Error("ScriptComponent",false,"Trying to Create a dataset for a null script property."); - return false; - } - - AZ::Uuid typeId = azrtti_typeid(scriptProperty); - - if ( typeId == azrtti_typeid() - || typeId == azrtti_typeid()) - { - AZ_Error("ScriptComponent",false,"Using unsupported type for ScriptProperty(%s) net binding. Value will not be networked.", scriptProperty->m_name.c_str()); - return false; - } - - // If we've already got an item inside of our network table. - // We need to surpress that problem, since it may happen when we reload the script - if (m_networkedTable.find(scriptProperty->m_name) != m_networkedTable.end()) - { - return true; - } - - int elementIndex; - bool enabled = false; - bool handledProperty = false; - - if (networkTableContext.PushTableElement("Enabled",&elementIndex)) - { - // If we have the enabled field and it's not a boolean. - // Assume false. - if (networkTableContext.IsBoolean(elementIndex)) - { - // If we didn't read in the enabled value, assume it's false. - if (!networkTableContext.ReadValue(elementIndex,enabled)) - { - enabled = false; - } - } - } - else - { - // If we don't have an enabled field, assume that we want to be bound. - enabled = true; - } - - if (enabled) - { - NetworkedTableValue networkedTableValue; - - // Convert the property arrays over to a table to simplify the logic flow of detecting - // the various changes, and to more readily support what the general LUA syntax. - if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyBooleanArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyNumberArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyStringArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyGenericClassArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else - { - networkedTableValue = NetworkedTableValue(scriptProperty->Clone()); - } - - if (networkTableContext.PushTableElement("OnNewValue", &elementIndex)) - { - if (networkTableContext.IsFunction(elementIndex)) - { - networkedTableValue.RegisterCallback( networkTableContext.CacheValue(elementIndex) ); - } - } - - if (networkTableContext.PushTableElement("ForceIndex",&elementIndex)) - { - if (networkTableContext.IsNumber(elementIndex)) - { - int forcedDataSetIndex = 0; - if (networkTableContext.ReadValue(elementIndex,forcedDataSetIndex)) - { - AZ_Error("ScriptComponent",forcedDataSetIndex >= 1 && forcedDataSetIndex <= ScriptComponentReplicaChunk::k_maxScriptableDataSets,"Trying to force Property (%s) to an invalid DataSetIndex(%i).",scriptProperty->m_name.c_str(),forcedDataSetIndex); - if(forcedDataSetIndex >= 1 && forcedDataSetIndex <= ScriptComponentReplicaChunk::k_maxScriptableDataSets) - { - networkedTableValue.SetForcedDataSetIndex(forcedDataSetIndex); - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to force Property (%s) to unknown DataSetIndex. Ignoring field.", scriptProperty->m_name.c_str()); - } - } - } - - AZStd::pair insertResult = m_networkedTable.insert(NetworkedTableMap::value_type(scriptProperty->m_name,networkedTableValue)); - - // If we failed to insert the object, we need to destroy the networked table value. - // To avoid leaking memory - if (!insertResult.second) - { - networkedTableValue.Destroy(); - } - - handledProperty = true; - } - - return handledProperty; - } - - bool ScriptNetBindingTable::InvokeRPC(AZ::ScriptDataContext& stackContext) - { - lua_State* nativeContext = stackContext.GetScriptContext()->NativeContext(); - - bool invokedRPC = false; - AZStd::string rpcName; - - // Assuming this is coming from an __call metamethod - // the lua stack will look as follows - // 1 - Table - // n - Params - if (stackContext.IsTable(1)) - { - // Get the RPC name - lua_pushliteral(nativeContext,"_rpcName"); - lua_gettable(nativeContext,1); - - if (stackContext.IsString(-1)) - { - if (stackContext.ReadValue(-1,rpcName)) - { - // Pop off the key value we just read in; It's no longer necessary - lua_pop(nativeContext,1); - - RPCHelperMap::iterator rpcIter = m_rpcHelperMap.find(rpcName); - - if (rpcIter != m_rpcHelperMap.end()) - { - bool foundParams = true; - - ScriptRPCMarshaler::Container paramContainer; - - // Need to start at 2, since 1 is our table. - for (int i=2; i <= lua_gettop(nativeContext); ++i) - { - AZ::ScriptProperty* property = stackContext.ConstructScriptProperty(i,"param"); - - if (property) - { - paramContainer.push_back(property); - } - else - { - foundParams = false; - break; - } - } - - // The script marshaler will clean up the keys after it has marshalled them out. - if (foundParams) - { - invokedRPC = true; - - if (m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptReplicaChunk = static_cast(m_replicaChunk.get()); - scriptReplicaChunk->m_scriptRPC(rpcName,paramContainer); - } - else - { - rpcIter->second.InvokeMaster(m_entityScriptContext,paramContainer); - } - } - else - { - for (AZ::ScriptProperty* property : paramContainer) - { - delete property; - } - - paramContainer.clear(); - } - } - } - else - { - // We failed to read, so we need to pop the value we pushed off the stack. - lua_pop(nativeContext,1); - } - } - else - { - // Pop off the value we added to the top of the stack - lua_pop(nativeContext,1); - } - } - - return invokedRPC; - } - - void ScriptNetBindingTable::RegisterRPC(AZ::ScriptDataContext& rpcTableContext, const AZStd::string& rpc, int elementIndex, int tableStackIndex) - { - if (rpcTableContext.IsTable(elementIndex)) - { - RPCBindingHelper helper; - - AZ::ScriptDataContext rpcContext; - if (rpcTableContext.InspectTable(elementIndex,rpcContext)) - { - int functionIndex = 0; - if (rpcContext.PushTableElement("OnMaster",&functionIndex)) - { - helper.SetMasterFunction(rpcContext.CacheValue(functionIndex)); - } - else - { - AZ_Error("ScriptNetBinding", false, "Could not find OnMaster function for RPC (%s).", rpc.c_str()); - } - - if (rpcContext.PushTableElement("OnProxy",&functionIndex)) - { - helper.SetProxyFunction(rpcContext.CacheValue(functionIndex)); - } - } - else - { - AZ_Error("ScriptNetBinding", false, "Could inspect table for RPC (%s).", rpc.c_str()); - } - - if (helper.IsValid()) - { - lua_State* nativeContext = rpcTableContext.GetScriptContext()->NativeContext(); - - // Create the RPC Table inside of our entity table to allow for functions to be called on it. - // - lua_pushlstring(nativeContext,rpc.c_str(),rpc.size()); - lua_createtable(nativeContext,0,1); - - // Set up a name field inside of the table - lua_pushliteral(nativeContext,"_rpcName"); - lua_pushlstring(nativeContext,rpc.c_str(),rpc.size()); - lua_rawset(nativeContext,-3); - - // - lua_createtable(nativeContext,0,1); - lua_pushliteral(nativeContext,"__call"); - lua_pushlightuserdata(nativeContext, this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__CallRPC,1); - lua_rawset(nativeContext,-3); - - lua_setmetatable(nativeContext,-2); - // - - lua_rawset(nativeContext,tableStackIndex); - // - - m_rpcHelperMap.insert(RPCHelperMap::value_type(rpc,helper)); - } - } - } - - GridMate::ReplicaChunkPtr ScriptNetBindingTable::GetNetworkBinding() - { - m_replicaChunk = GridMate::CreateReplicaChunk(); - m_replicaChunk->SetHandler(this); - - if (m_entityScriptContext.HasScriptContext()) - { - AssignDataSets(); - } - - return m_replicaChunk; - } - - void ScriptNetBindingTable::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) - { - m_replicaChunk = chunk; - m_replicaChunk->SetHandler(this); - - if (m_entityScriptContext.HasScriptContext()) - { - AssignDataSets(); - } - } - - void ScriptNetBindingTable::UnbindFromNetwork() - { - if (m_replicaChunk) - { - m_replicaChunk->SetHandler(nullptr); - - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - tablePair.second.UnbindFromDataSet(); - } - - m_replicaChunk = nullptr; - } - } - - void ScriptNetBindingTable::OnPropertyUpdate(AZ::ScriptProperty*const& scriptProperty, const GridMate::TimeContext& tc) - { - AZ_Error("ScriptComponent",m_replicaChunk != nullptr,"DataSet callback method called without ReplicaChunk present."); - - if (scriptProperty && m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptReplicaChunk = static_cast(m_replicaChunk.get()); - - NetworkedTableValue* tableValue = FindTableValue(scriptProperty->m_name); - - if (tableValue) - { - if (!tableValue->HasDataSet()) - { - scriptReplicaChunk->AssignDataSetForProperty((*tableValue),scriptProperty); - AZ_Error("ScriptComponent",tableValue->HasDataSet(),"Unable to bind received ScriptProperty to DataSet."); - } - else - { - AZ_Error("ScriptComponent",scriptReplicaChunk->SanityCheckDataSet(scriptProperty,tableValue->GetDataSet()),"Mismatch between DataSet being chagned and mapping to dataset index."); - } - - if (tableValue->HasCallback()) - { - tableValue->InvokeCallback(m_entityScriptContext,tc); - } - } - else - { - AZ_Error("ScriptComponent",false,"Receiving update for unknown ScriptProperty."); - } - } - } - - bool ScriptNetBindingTable::OnInvokeRPC(AZStd::string functionName, AZStd::vector< AZ::ScriptProperty*> params, const GridMate::RpcContext& rpcContext) - { - (void)rpcContext; - - bool canProxyExecute = false; - AZ_Error("ScriptComponent",m_replicaChunk,"Receiving RPC callback with null ReplicaChunk."); - - RPCHelperMap::iterator rpcIter = m_rpcHelperMap.find(functionName); - - if (rpcIter != m_rpcHelperMap.end()) - { - RPCBindingHelper& rpcHelper = rpcIter->second; - - if (m_replicaChunk == nullptr || m_replicaChunk->IsMaster()) - { - canProxyExecute = rpcHelper.InvokeMaster(m_entityScriptContext,params); - } - else - { - // The canProxyExecute return value is meaningless on proxies. - rpcHelper.InvokeProxy(m_entityScriptContext,params); - } - } - - return canProxyExecute; - } - - const AZ::ScriptProperty* ScriptNetBindingTable::FindScriptProperty(const AZStd::string& name) const - { - const NetworkedTableValue* networkedTableValue = FindTableValue(name); - return networkedTableValue ? networkedTableValue->GetShimmedScriptProperty() : nullptr; - } - - void ScriptNetBindingTable::AssignDataSets() - { - if (m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptComponentChunk = static_cast(m_replicaChunk.get()); - - // Going to do this in two passes, first to do all of the forced ones, then all of the arbitrary ones. - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - if (tablePair.second.HasForcedDataSetIndex() && !tablePair.second.HasDataSet()) - { - if (!scriptComponentChunk->AssignDataSet(tablePair.second)) - { - // Remove the forced DataSet index since it was invalid. - // Second pass will assign this an arbitrary one. - tablePair.second.SetForcedDataSetIndex(-1); - } - } - } - - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - // Try to assign everything that doesn't already have a dataset. - if (!tablePair.second.HasDataSet()) - { - scriptComponentChunk->AssignDataSet(tablePair.second); - } - } - } - } - - ScriptNetBindingTable::NetworkedTableValue* ScriptNetBindingTable::FindTableValue(const AZStd::string& name) - { - NetworkedTableValue* retVal = nullptr; - NetworkedTableMap::iterator tableIter = m_networkedTable.find(name); - - if (tableIter != m_networkedTable.end()) - { - retVal = &(tableIter->second); - } - - return retVal; - } - - const ScriptNetBindingTable::NetworkedTableValue* ScriptNetBindingTable::FindTableValue(const AZStd::string& name) const - { - const NetworkedTableValue* retVal = nullptr; - NetworkedTableMap::const_iterator tableIter = m_networkedTable.find(name); - - if (tableIter != m_networkedTable.end()) - { - retVal = &(tableIter->second); - } - - return retVal; - } - - //////////////////////////////// - // ScriptComponentReplicaChunk - //////////////////////////////// - - ScriptComponentReplicaChunk::ScriptComponentReplicaChunk() - : m_scriptRPC("ScriptRPC") - , m_enabledDataSetMask(0) - { - } - - ScriptComponentReplicaChunk::~ScriptComponentReplicaChunk() - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - ScriptPropertyDataSet& dataSet = m_propertyDataSets[i]; - - dataSet.Modify([](AZ::ScriptProperty*& scriptProperty) - { - delete scriptProperty; - scriptProperty = nullptr; - return false; - }); - } - } - - bool ScriptComponentReplicaChunk::IsReplicaMigratable() - { - return true; - } - - AZ::u32 ScriptComponentReplicaChunk::CalculateDirtyDataSetMask(GridMate::MarshalContext& marshalContext) - { - if ((marshalContext.m_marshalFlags & GridMate::ReplicaMarshalFlags::ForceDirty)) - { - return m_enabledDataSetMask; - } - - return GridMate::ReplicaChunkBase::CalculateDirtyDataSetMask(marshalContext); - } - - bool ScriptComponentReplicaChunk::AssignDataSet(ScriptNetBindingTable::NetworkedTableValue& helper) - { - bool assigned = false; - - if (helper.HasForcedDataSetIndex()) - { - int testIndex = helper.GetForcedDataSetIndex() - 1; - - if (testIndex >= 0 && testIndex < k_maxScriptableDataSets) - { - ScriptPropertyDataSet* testDataSet = &m_propertyDataSets[testIndex]; - - if (!testDataSet->IsReserved()) - { - assigned = true; - helper.RegisterDataSet(testDataSet); - m_enabledDataSetMask |= (1 << testIndex); - } - else - { - AZ_Error("ScriptComponent",false,"Trying to register a networked value to a previously used DataSet."); - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to register a table value to an invalid DataSet index."); - } - } - else - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (!m_propertyDataSets[i].IsReserved()) - { - assigned = true; - helper.RegisterDataSet(&m_propertyDataSets[i]); - m_enabledDataSetMask |= (1 << i); - break; - } - } - - AZ_Error("ScriptComponent",assigned, "Trying to create more then %i datasets for a script",k_maxScriptableDataSets); - } - - return assigned; - } - - void ScriptComponentReplicaChunk::AssignDataSetForProperty(ScriptNetBindingTable::NetworkedTableValue& helper, AZ::ScriptProperty* targetProperty) - { - AZ_Error("ScriptComponent",!IsMaster(),"Binding table value to specified DataSet on Master(Master should be making that choice, not responding to a choice)."); - - if (!IsMaster()) - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (m_propertyDataSets[i].Get() == targetProperty) - { - helper.RegisterDataSet(&m_propertyDataSets[i]); - m_enabledDataSetMask |= (1 << i); - break; - } - } - } - } - - bool ScriptComponentReplicaChunk::SanityCheckDataSet(AZ::ScriptProperty* targetProperty, ScriptPropertyDataSet* assumedDataSet) - { - bool isSane = false; - - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (m_propertyDataSets[i].Get() == targetProperty) - { - isSane = &(m_propertyDataSets[i]) == assumedDataSet; - break; - } - } - - return isSane; - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h deleted file mode 100644 index eec28b71b0..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h +++ /dev/null @@ -1,320 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef AZFRAMEWORK_SCRIPT_NET_BINDINGS_H -#define AZFRAMEWORK_SCRIPT_NET_BINDINGS_H - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace AzFramework -{ - class ScriptPropertyDataSet; - class ScriptComponentReplicaChunk; - - // ScriptNetBindingTable will act as the go between for the ScriptComponent and the Replica's. - // It will also allow for holding of values in the case where you haven't been bound to a replica chunk yet and the - // script tries to interact with something that is networked. - // - // Allows for scripts to be re-used seamlessly in a offline vs online scenario(and support for going from offline to online), - // including RPCs(will alawys call the master version if offline) - class ScriptNetBindingTable - : public GridMate::ReplicaChunkInterface - { - private: - friend class ScriptComponentReplicaChunk; - friend class ScriptPropertyDataSet; - - // Helper struct to keep track of a a ScriptContext - // and the entityTableReference. Mainly used for - // calling in to functions in LUA where we want - // to push in the table reference as the first parameter - struct EntityScriptContext - { - public: - EntityScriptContext(); - - void Unload(); - - bool HasEntityTableRegistryIndex() const; - int GetEntityTableRegistryIndex() const; - - bool HasScriptContext() const; - AZ::ScriptContext* GetScriptContext() const; - - void ConfigureContext(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex); - - private: - - bool SanityCheckContext() const; - - AZ::ScriptContext* m_scriptContext; - int m_entityTableRegistryIndex; - }; - - class NetworkedTableValue; - friend NetworkedTableValue; - - typedef AZStd::unordered_map NetworkedTableMap; - - class RPCBindingHelper; - friend RPCBindingHelper; - - typedef AZStd::unordered_map RPCHelperMap; - - // Helper class that will wrap up our interactions with the actual stored value - // to hide the general use case of if we are connected to a replica or not. - // - // Additionally this will serve as a holding ground for a 'networked' - // value that doesn't have a dataset. - // - // Lastly holds onto the Callback references. - class NetworkedTableValue - { - public: - AZ_CLASS_ALLOCATOR(NetworkedTableValue, AZ::SystemAllocator, 0); - - NetworkedTableValue(AZ::ScriptProperty* initialValue = nullptr); - ~NetworkedTableValue(); - - void Destroy(); - - // Methods to register this value to a chunk - bool HasDataSet() const; - void RegisterDataSet(ScriptPropertyDataSet* dataSet); - void UnbindFromDataSet(); - ScriptPropertyDataSet* GetDataSet() const; - - // Information kept in order to force these values to use a particular dataset for debugging. - bool HasForcedDataSetIndex() const; - void SetForcedDataSetIndex(int index); - int GetForcedDataSetIndex() const; - - // Callback functions - bool HasCallback() const; - void RegisterCallback(int functionReference); - void ReleaseCallback(AZ::ScriptContext& scriptContext); - void InvokeCallback(EntityScriptContext& scriptContext, const GridMate::TimeContext& timeContext); - - bool AssignValue(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName); - bool InspectValue(AZ::ScriptContext* scriptContext) const; - - // Methods used for unit tests - const AZ::ScriptProperty* GetShimmedScriptProperty() const { return m_shimmedScriptProperty; } - private: - - // This value will be used if we have a networked property, but don't have a valid chunk yet. - // Works as a temporary store, which will be resolved once we get assigned to a DataSet - AZ::ScriptProperty* m_shimmedScriptProperty; - - // The data set we are bound to - ScriptPropertyDataSet* m_dataSet; - int m_forcedDataSetIndex; - - int m_functionReference; - }; - - // Future thoughts - // - Move the actual RPC meta table creation - // into this guy - class RPCBindingHelper - { - public: - AZ_CLASS_ALLOCATOR(RPCBindingHelper, AZ::SystemAllocator, 0); - - RPCBindingHelper(); - ~RPCBindingHelper(); - - void ReleaseTableIndex(AZ::ScriptContext& scriptContext); - - bool IsValid() const; - - void SetMasterFunction(int masterReference); - bool InvokeMaster(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params); - - void SetProxyFunction(int masterReference); - void InvokeProxy(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params); - - private: - int m_masterReference; - int m_proxyReference; - }; - - public: - AZ_CLASS_ALLOCATOR(ScriptNetBindingTable, AZ::SystemAllocator, 0); - static void Reflect(AZ::ReflectContext* reflect); - - ScriptNetBindingTable(); - ~ScriptNetBindingTable(); - - void Unload(); - - void CreateNetworkBindingTable(AZ::ScriptContext* scriptContext, int baseTableIndex, int entityTableIndex); - void FinalizeNetworkTable(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex); - - AZ::ScriptContext* GetScriptContext() const; - - bool IsMaster() const; - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // DataSet Functionality - // - // Called when the script wants to bind a function callback to when - // a value changes - // - // Might change this to just be register DataSet - bool RegisterDataSet(AZ::ScriptDataContext& stackContext, AZ::ScriptProperty* scriptProperty); - - // Called when the script wants to assign a value to the script value - bool AssignTableValue(AZ::ScriptDataContext& stackContext); - - // Called when the script wants to know the value of a script value. - bool InspectTableValue(AZ::ScriptDataContext& stackContext) const; - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - /// RPC Functionality - void RegisterRPC(AZ::ScriptDataContext& rpcTableContext, const AZStd::string& rpcName, int elementIndex, int tableStackIndex); - bool InvokeRPC(AZ::ScriptDataContext& stackContext); - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - // Netbinding Interface duplication here to be called from the ScriptComponent - GridMate::ReplicaChunkPtr GetNetworkBinding(); - void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk); - void UnbindFromNetwork(); - - void OnPropertyUpdate(AZ::ScriptProperty*const& scriptProperty, const GridMate::TimeContext& tc); - bool OnInvokeRPC(AZStd::string functionName, AZStd::vector< AZ::ScriptProperty*> properties, const GridMate::RpcContext& rpcContext); - - // Methods used for unit tests - const AZ::ScriptProperty* FindScriptProperty(const AZStd::string& name) const; - - - private: - - void RegisterMetaTableCache(); - - template - AZ::ScriptPropertyTable* ConvertPropertyArrayToTable(PropertyArrayType* arrayProperty) - { - AZ::ScriptPropertyTable* scriptPropertyTable = aznew AZ::ScriptPropertyTable(arrayProperty->m_name.c_str()); - - PropertyType propertyType; - - for (unsigned int i=0; i < arrayProperty->m_values.size(); ++i) - { - propertyType.m_value = arrayProperty->m_values[i]; - - // Offset by 1 to deal with lua 1 indexing. - // Table will make a clone of our object. - scriptPropertyTable->SetTableValue(i+1, &propertyType); - } - - return scriptPropertyTable; - } - - void AssignDataSets(); - - NetworkedTableValue* FindTableValue(const AZStd::string& name); - const NetworkedTableValue* FindTableValue(const AZStd::string& name) const; - - EntityScriptContext m_entityScriptContext; - - GridMate::ReplicaChunkPtr m_replicaChunk; - - NetworkedTableMap m_networkedTable; - RPCHelperMap m_rpcHelperMap; - }; - - // Typedeffing out the RPC and DataSet definitions. - typedef GridMate::Rpc< GridMate::RpcArg< AZStd::string >, GridMate::RpcArg< ScriptRPCMarshaler::Container, ScriptRPCMarshaler > >::BindInterface ScriptPropertyRPC; - typedef GridMate::DataSet::BindInterface ScriptPropertyDataSetType; - - class ScriptComponentReplicaChunk; - - // Specialized DataSet used by the ScriptProperties, just to add some wrapped around functionality - // and to allow me to manipulate the DataSet throttler in order to properly manage a dirty flag - class ScriptPropertyDataSet - : public ScriptPropertyDataSetType - , public AZ::ScriptPropertyWatcherBus::Handler - , public AZ::ScriptPropertyWatcher - { - private: - friend class ScriptComponentReplicaChunk; - friend class ScriptNetBindingTable::NetworkedTableValue; - - const char* GetDataSetName(); - - public: - ScriptPropertyDataSet(); - ~ScriptPropertyDataSet(); - bool IsReserved() const; - - bool UpdateScriptProperty(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName); - void SetScriptProperty(AZ::ScriptProperty* scriptProperty); - - void OnObjectModified() override; - - private: - void Reserve(ScriptNetBindingTable::NetworkedTableValue* reserver); - void Release(ScriptNetBindingTable::NetworkedTableValue* reserver); - - ScriptNetBindingTable::NetworkedTableValue* m_reserver; - }; - - // The actual ReplicaChunk that the script will use - class ScriptComponentReplicaChunk - : public GridMate::ReplicaChunkBase - { - public: - AZ_CLASS_ALLOCATOR(ScriptComponentReplicaChunk, AZ::SystemAllocator,0); - static const int k_maxScriptableDataSets = GM_MAX_DATASETS_IN_CHUNK; - - static const char* GetChunkName() { return "ScriptComponentReplicaChunk"; } - - // Might want to add some type of comment field into the various fields so this can be properly parsed - // and determined what we are actually sending. - ScriptComponentReplicaChunk(); - ~ScriptComponentReplicaChunk(); - - bool IsReplicaMigratable() override; - - AZ::u32 CalculateDirtyDataSetMask(GridMate::MarshalContext& marshalContext) override; - - // Called from the Master, will assign the table value to the DataSet specified by the helper. - bool AssignDataSet(ScriptNetBindingTable::NetworkedTableValue& helper); - - // Called from teh Proxy. Will Assign the TableValue to the DataSet that contains the target property - void AssignDataSetForProperty(ScriptNetBindingTable::NetworkedTableValue& helper, AZ::ScriptProperty* targetProperty); - - // Only called inside of an assert, checks that the DataSet that the targetProperty is in is the same as the assumedDataSet - // Used to confirm that we don't get a confusion between master/proxy about which ScriptProperty is assigned to which DataSet. - bool SanityCheckDataSet(AZ::ScriptProperty* targetProperty, ScriptPropertyDataSet* assumedDataSet); - - ScriptPropertyRPC m_scriptRPC; - - private: - AZ::u32 m_enabledDataSetMask; - ScriptPropertyDataSet m_propertyDataSets[k_maxScriptableDataSets]; - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp b/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp index e44185bd33..d3ba48d587 100644 --- a/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp @@ -177,7 +177,7 @@ namespace AzFramework Neighborhood::NeighborReplicaPtr replicaChunk = GridMate::CreateReplicaChunk(session->GetMyMember()->GetId().Compact(), m_component->m_settings->m_persistentName.c_str(), Neighborhood::NEIGHBOR_CAP_LUA_VM | Neighborhood::NEIGHBOR_CAP_LUA_DEBUGGER); replicaChunk->SetDisplayName(m_component->m_settings->m_persistentName.c_str()); replica->AttachReplicaChunk(replicaChunk); - session->GetReplicaMgr()->AddMaster(replica); + session->GetReplicaMgr()->AddPrimary(replica); } } diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake index 1b1cd49aa7..135d9d36bd 100644 --- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake +++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake @@ -161,26 +161,6 @@ set(FILES Metrics/MetricsPlainTextNameRegistration.h Network/AssetProcessorConnection.cpp Network/AssetProcessorConnection.h - Network/DynamicSerializableFieldMarshaler.h - Network/EntityIdMarshaler.h - Network/InterestManagerComponent.h - Network/InterestManagerComponent.cpp - Network/NetBindable.h - Network/NetBindable.cpp - Network/NetBindingEventsBus.h - Network/NetBindingHandlerBus.h - Network/NetBindingSystemBus.h - Network/NetBindingComponent.h - Network/NetBindingComponent.cpp - Network/NetBindingComponentChunk.h - Network/NetBindingComponentChunk.cpp - Network/NetBindingSystemImpl.h - Network/NetBindingSystemImpl.cpp - Network/NetBindingSystemComponent.h - Network/NetBindingSystemComponent.cpp - Network/NetworkContext.h - Network/NetworkContext.cpp - Network/NetSystemBus.h Network/SocketConnection.cpp Network/SocketConnection.h Logging/LogFile.cpp @@ -203,10 +183,6 @@ set(FILES Script/ScriptDebugAgentBus.h Script/ScriptDebugMsgReflection.cpp Script/ScriptDebugMsgReflection.h - Script/ScriptMarshal.h - Script/ScriptMarshal.cpp - Script/ScriptNetBindings.h - Script/ScriptNetBindings.cpp Script/ScriptRemoteDebugging.cpp Script/ScriptRemoteDebugging.h StreamingInstall/StreamingInstall.h diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index ac5f1136f5..70cad69268 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -1287,7 +1287,6 @@ namespace AzToolsFramework Field("Cached World Transform Parent", &TransformComponent::m_cachedWorldTransformParent)-> Field("Parent Activation Transform Mode", &TransformComponent::m_parentActivationTransformMode)-> Field("IsStatic", &TransformComponent::m_isStatic)-> - Field("Sync Enabled", &TransformComponent::m_netSyncEnabled)-> Field("InterpolatePosition", &TransformComponent::m_interpolatePosition)-> Field("InterpolateRotation", &TransformComponent::m_interpolateRotation)-> Version(9, &Internal::TransformComponentDataConverter); @@ -1322,21 +1321,7 @@ namespace AzToolsFramework Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)-> DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_cachedWorldTransform, "Cached World Transform", "")-> Attribute(AZ::Edit::Attributes::SliceFlags, AZ::Edit::SliceFlags::NotPushable)-> - Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)-> - - ClassElement(AZ::Edit::ClassElements::Group, "Network Sync")-> - Attribute(AZ::Edit::Attributes::AutoExpand, true)-> - - DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_netSyncEnabled, "Sync to replicas", "Sync to network replicas.")-> - DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_interpolatePosition, - "Position Interpolation", "Enable local interpolation of position.")-> - EnumAttribute(AZ::InterpolationMode::NoInterpolation, "None")-> - EnumAttribute(AZ::InterpolationMode::LinearInterpolation, "Linear")-> - - DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_interpolateRotation, - "Rotation Interpolation", "Enable local interpolation of rotation.")-> - EnumAttribute(AZ::InterpolationMode::NoInterpolation, "None")-> - EnumAttribute(AZ::InterpolationMode::LinearInterpolation, "Linear"); + Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide); ptrEdit->Class("Values", "XYZ PYR")-> DataElement(AZ::Edit::UIHandlers::Default, &EditorTransform::m_translate, "Translate", "Local Position (Relative to parent) in meters.")-> diff --git a/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp b/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp index e3b474ba5d..380739bab1 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp @@ -1486,7 +1486,7 @@ namespace GridMate // Only support a single cipher suite in OpenSSL that supports: // - // ECDHE Master key exchange using ephemeral elliptic curve diffie-hellman. + // ECDHE Key exchange using ephemeral elliptic curve diffie-hellman. // RSA Authentication (public and private key) used to sign ECDHE parameters and can be checked against a CA. // AES256 AES cipher for symmetric key encryption using a 256-bit key. // GCM Mode of operation for symmetric key encryption. diff --git a/Code/Framework/GridMate/GridMate/Carrier/StreamSecureSocketDriver.cpp b/Code/Framework/GridMate/GridMate/Carrier/StreamSecureSocketDriver.cpp index 9e59496ed1..30c2c63ed9 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/StreamSecureSocketDriver.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/StreamSecureSocketDriver.cpp @@ -97,7 +97,7 @@ namespace GridMate // Only support a single cipher suite in OpenSSL that supports: // - // ECDHE Master key exchange using ephemeral elliptic curve diffie-hellman. + // ECDHE Key exchange using ephemeral elliptic curve diffie-hellman. // RSA Authentication (public and private key) used to sign ECDHE parameters and can be checked against a CA. // AES256 AES cipher for symmetric key encryption using a 256-bit key. // GCM Mode of operation for symmetric key encryption. diff --git a/Code/Framework/GridMate/GridMate/Replica/DataSet.cpp b/Code/Framework/GridMate/GridMate/Replica/DataSet.cpp index 614c50a7e0..fb6a6fe5cd 100644 --- a/Code/Framework/GridMate/GridMate/Replica/DataSet.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/DataSet.cpp @@ -52,6 +52,6 @@ namespace GridMate bool DataSetBase::CanSet() const { - return m_replicaChunk ? m_replicaChunk->IsMaster() : true; + return m_replicaChunk ? m_replicaChunk->IsPrimary() : true; } } diff --git a/Code/Framework/GridMate/GridMate/Replica/DataSet.h b/Code/Framework/GridMate/GridMate/Replica/DataSet.h index f91a86dcec..61ff75516b 100644 --- a/Code/Framework/GridMate/GridMate/Replica/DataSet.h +++ b/Code/Framework/GridMate/GridMate/Replica/DataSet.h @@ -43,7 +43,7 @@ namespace GridMate struct DataSetDefaultTraits { /** - * \brief Should a change in DataSet value invoke a callback on a master replica chunk? + * \brief Should a change in DataSet value invoke a callback on a primary replica chunk? * * By default, DataSet::BindInterface only invokes on client/non-authoritative replica chunks. * This switch enables the callback on server/authoritative replica chunks. @@ -55,7 +55,7 @@ namespace GridMate }; /** - * \brief Turns on DataSet callbacks to be invoked on the master replica as well as client replicas. + * \brief Turns on DataSet callbacks to be invoked on the primary replica as well as client replicas. */ struct DataSetInvokeEverywhereTraits : DataSetDefaultTraits { @@ -200,7 +200,7 @@ namespace GridMate } /** - Modify the DataSet. Call this on the Master node to change the data, + Modify the DataSet. Call this on the Primary node to change the data, which will be propagated to all proxies. **/ void Set(const DataType& v) @@ -214,7 +214,7 @@ namespace GridMate } /** - Modify the DataSet. Call this on the Master node to change the data, + Modify the DataSet. Call this on the Primary node to change the data, which will be propagated to all proxies. **/ void Set(DataType&& v) @@ -228,7 +228,7 @@ namespace GridMate } /** - Modify the DataSet. Call this on the Master node to change the data, + Modify the DataSet. Call this on the Primary node to change the data, which will be propagated to all proxies. **/ template @@ -243,7 +243,7 @@ namespace GridMate } /** - Modify the DataSet directly without copying it. Call this on the Master node, + Modify the DataSet directly without copying it. Call this on the Primary node, passing in a function object that takes the value by reference, optionally modifies the data, and returns true if the data was changed. **/ diff --git a/Code/Framework/GridMate/GridMate/Replica/DeltaCompressedDataSet.h b/Code/Framework/GridMate/GridMate/Replica/DeltaCompressedDataSet.h index cc19c2336b..8d88635c07 100644 --- a/Code/Framework/GridMate/GridMate/Replica/DeltaCompressedDataSet.h +++ b/Code/Framework/GridMate/GridMate/Replica/DeltaCompressedDataSet.h @@ -159,7 +159,7 @@ namespace GridMate } /** - Modify the DataSet. Call this on the Master node to change the data, + Modify the DataSet. Call this on the Primary node to change the data, which will be propagated to all proxies. **/ void Set(const FieldType& v) @@ -201,7 +201,7 @@ namespace GridMate private: DataSet m_absolutePortion; DataSet m_relativePortion; - FieldType m_combinedValue; // the latest value on either master or proxy + FieldType m_combinedValue; // the latest value on either primary or proxy }; //----------------------------------------------------------------------------- diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/BitmaskInterestHandler.cpp b/Code/Framework/GridMate/GridMate/Replica/Interest/BitmaskInterestHandler.cpp index 1a35fd1893..75f4c8bdd2 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/BitmaskInterestHandler.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Interest/BitmaskInterestHandler.cpp @@ -366,7 +366,7 @@ namespace GridMate auto replica = Replica::CreateReplica("BitmaskInterestHandlerRules"); m_rulesReplica = CreateAndAttachReplicaChunk(replica); - m_rm->AddMaster(replica); + m_rm->AddPrimary(replica); } void BitmaskInterestHandler::OnRulesHandlerUnregistered(InterestManager* manager) diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/InterestManager.cpp b/Code/Framework/GridMate/GridMate/Replica/Interest/InterestManager.cpp index 770dcd4f1f..ff1a29a917 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/InterestManager.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Interest/InterestManager.cpp @@ -206,7 +206,7 @@ namespace GridMate return false; } - if (replica->IsMaster()) // own the replica? + if (replica->IsPrimary()) // own the replica? { return true; } diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp b/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp index 4e3c2c77a4..13a0151bc7 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp @@ -508,7 +508,7 @@ namespace GridMate auto replica = Replica::CreateReplica("ProximityInterestHandlerRules"); m_rulesReplica = CreateAndAttachReplicaChunk(replica); - m_rm->AddMaster(replica); + m_rm->AddPrimary(replica); } void ProximityInterestHandler::OnRulesHandlerUnregistered(InterestManager* manager) diff --git a/Code/Framework/GridMate/GridMate/Replica/MigrationSequence.cpp b/Code/Framework/GridMate/GridMate/Replica/MigrationSequence.cpp index 48fbfe5289..a1150a198a 100644 --- a/Code/Framework/GridMate/GridMate/Replica/MigrationSequence.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/MigrationSequence.cpp @@ -26,7 +26,7 @@ namespace GridMate m_replicaMgr = replica->GetReplicaManager(); - if (replica->IsMaster() && newOwnerId != m_replicaMgr->GetLocalPeerId()) + if (replica->IsPrimary() && newOwnerId != m_replicaMgr->GetLocalPeerId()) { m_sm.SetStateHandler(AZ_HSM_STATE_NAME(MST_TOP), AZ::HSM::StateHandler(this, &MigrationSequence::DefaultHandler), AZ::HSM::InvalidStateId, MST_MIGRATING); } @@ -312,7 +312,7 @@ namespace GridMate return true; case ME_MODIFY_NEW_OWNER: m_newOwnerId = *static_cast(event.userData); - if (m_replica->IsMaster() && m_newOwnerId != m_replicaMgr->m_self.GetId()) + if (m_replica->IsPrimary() && m_newOwnerId != m_replicaMgr->m_self.GetId()) { sm.Transition(MST_MIGRATING); } diff --git a/Code/Framework/GridMate/GridMate/Replica/RemoteProcedureCall.h b/Code/Framework/GridMate/GridMate/Replica/RemoteProcedureCall.h index 98494267ad..4256dd978b 100644 --- a/Code/Framework/GridMate/GridMate/Replica/RemoteProcedureCall.h +++ b/Code/Framework/GridMate/GridMate/Replica/RemoteProcedureCall.h @@ -370,8 +370,8 @@ namespace GridMate PeerId sourcePeerId = GetSourcePeerId(); bool shouldQueue = true; bool processed = false; - bool isMaster = m_replicaChunk->IsMaster(); - if (isMaster) + bool isPrimary = m_replicaChunk->IsPrimary(); + if (isPrimary) { // We are authoritative so execute the RPC immediately, forwarding the args along RpcRequest localRequest(this, rc.m_realTime, rc.m_realTime, rc.m_localTime); @@ -385,7 +385,7 @@ namespace GridMate if (shouldQueue) { TypeTuple* storage = aznew TypeTuple(this, RpcContext(rc.m_realTime, rc.m_realTime, rc.m_localTime, sourcePeerId), AZStd::forward(args) ...); - storage->m_authoritative = isMaster; + storage->m_authoritative = isPrimary; storage->m_processed = processed; storage->m_reliable = Traits::s_isReliable; OnRpcRequest(storage); diff --git a/Code/Framework/GridMate/GridMate/Replica/Replica.cpp b/Code/Framework/GridMate/GridMate/Replica/Replica.cpp index 483e523e05..c0a92de0d8 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Replica.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Replica.cpp @@ -106,7 +106,7 @@ namespace GridMate //----------------------------------------------------------------------------- void Replica::Destroy() { - AZ_Assert(IsMaster(), "We don't own replica 0x%x!", GetRepId()); + AZ_Assert(IsPrimary(), "We don't own replica 0x%x!", GetRepId()); if (m_manager) { m_manager->Destroy(this); @@ -327,7 +327,7 @@ namespace GridMate if (IsActive()) { - if (IsMaster()) + if (IsPrimary()) { EBUS_EVENT(Debug::ReplicaDrillerBus, OnRequestReplicaChangeOwnership, this, requestor); diff --git a/Code/Framework/GridMate/GridMate/Replica/Replica.h b/Code/Framework/GridMate/GridMate/Replica/Replica.h index fb630ac1a4..5291a7f143 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Replica.h +++ b/Code/Framework/GridMate/GridMate/Replica/Replica.h @@ -68,7 +68,7 @@ namespace GridMate Rep_ManagedAlloc = 1 << 1, Rep_CanMigrate = 1 << 2, Rep_New = 1 << 3, - Rep_Master = 1 << 4, + Rep_Primary = 1 << 4, Rep_Active = 1 << 6, Rep_ChangedOwner = 1 << 7, Rep_SuspendDownstream = 1 << 8, @@ -85,7 +85,7 @@ namespace GridMate void Destroy(); - void UpdateReplica(const ReplicaContext& rc); // Called when updating replica master from source + void UpdateReplica(const ReplicaContext& rc); // Called when updating replica primary from source void UpdateFromReplica(const ReplicaContext& rc); // Called when updating game with replica info bool AcceptChangeOwnership(PeerId requestor, const ReplicaContext& rc); // Return true to accept the transfer void OnActivate(const ReplicaContext& rc); @@ -112,8 +112,8 @@ namespace GridMate void RequestChangeOwnership(PeerId newOwner = InvalidReplicaPeerId); // If newOwner is not specified we assume it should be the local peer - bool IsMaster() const { return !IsActive() || !!(m_flags & Rep_Master); } - bool IsProxy() const { return !IsMaster(); } + bool IsPrimary() const { return !IsActive() || !!(m_flags & Rep_Primary); } + bool IsProxy() const { return !IsPrimary(); } bool IsNew() const { return !!(m_flags & Rep_New); } bool IsNewOwner() const { return !!(m_flags & Rep_ChangedOwner); } bool IsActive() const { return !!(m_flags & Rep_Active); } @@ -170,7 +170,7 @@ namespace GridMate void MarkRPCsAsRelayed(); - void SetMaster(bool isMaster) { m_flags = isMaster ? m_flags | Rep_Master : m_flags & ~Rep_Master; } + void SetPrimary(bool isPrimary) { m_flags = isPrimary ? m_flags | Rep_Primary : m_flags & ~Rep_Primary; } void SetNew() { m_flags |= Rep_New; } void SetRepId(ReplicaId id); void SetMigratable(bool migratable); diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.cpp b/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.cpp index 087f5f3273..adcff38190 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.cpp @@ -125,18 +125,18 @@ namespace GridMate return false; } //----------------------------------------------------------------------------- - bool ReplicaChunkBase::IsMaster() const + bool ReplicaChunkBase::IsPrimary() const { if (m_replica) { - return m_replica->IsMaster(); + return m_replica->IsPrimary(); } return true; } //----------------------------------------------------------------------------- bool ReplicaChunkBase::IsProxy() const { - return !IsMaster(); + return !IsPrimary(); } //----------------------------------------------------------------------------- bool ReplicaChunkBase::IsDirty(AZ::u32 marshalFlags) const @@ -398,8 +398,8 @@ namespace GridMate { if (mc.m_peer != m_replica->m_upstreamHop) { - AZ_TracePrintf("GridMate", "Received dataset updates for replica id %08x(%s) from unexpected peer.", GetReplicaId(), IsActive() && IsMaster() ? "master" : "proxy"); - if (IsMaster()) + AZ_TracePrintf("GridMate", "Received dataset updates for replica id %08x(%s) from unexpected peer.", GetReplicaId(), IsActive() && IsPrimary() ? "primary" : "proxy"); + if (IsPrimary()) { mc.m_iBuf->Skip(mc.m_iBuf->Left()); return; @@ -547,7 +547,7 @@ namespace GridMate AZ_Assert(false, "Discarding non-authoritative RPC <%s> because s_allowNonAuthoritativeRequests trait is disabled!", GetDescriptor()->GetRpcName(this, rpc)); isRpcValid = false; } - if (!rpc->IsAllowNonAuthoritativeRequestsRelay() && !IsMaster()) + if (!rpc->IsAllowNonAuthoritativeRequestsRelay() && !IsPrimary()) { AZ_Assert(false, "Discarding non-authoritative RPC <%s> because s_allowNonAuthoritativeRequestRelay trait is disabled!", GetDescriptor()->GetRpcName(this, rpc)); isRpcValid = false; @@ -639,19 +639,19 @@ namespace GridMate for (RPCQueue::iterator iRPC = m_rpcQueue.begin(); iRPC != m_rpcQueue.end(); ) { Internal::RpcRequest* request = *iRPC; - bool isMaster = IsMaster(); // need to do this check after each RPC because ownership may change + bool isPrimary = IsPrimary(); // need to do this check after each RPC because ownership may change if (!m_replica->IsActive()) // this can happen if replica was deactivated within a previous RPC call { request->m_relayed = true; } - else if (!request->m_processed && (isMaster || request->m_authoritative)) + else if (!request->m_processed && (isPrimary || request->m_authoritative)) { request->m_realTime = rc.m_realTime; request->m_localTime = rc.m_localTime; bool ret = request->m_rpc->Invoke(request); request->m_processed = true; - if (isMaster) + if (isPrimary) { if (ret) { diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.h index 7cfff0fe26..50b6bb8584 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.h @@ -45,17 +45,17 @@ namespace GridMate /** A single unit of network functionality A ReplicaChunk is a user extendable network object. One or more ReplicaChunks can be owned by a Replica, which is both a container and manager for them. A replica is owned - by a Master, and is propagated to other network nodes, who interact with is as a Proxy. + by a Primary, and is propagated to other network nodes, who interact with is as a Proxy. The data a ReplicaChunk contains should generally be related to the other data stored within it. Since multiple chunks can be attached to a Replica, unrelated data can simply be stored in other chunks on the same Replica. A ReplicaChunk has two primary ways to interact with it: DataSets and Remote Procedure Calls (RPCs). - DataSets store arbitrary data, which only the Master is able to modify. Any changes are + DataSets store arbitrary data, which only the Primary is able to modify. Any changes are propagated to the Proxy ReplicaChunks on the other nodes. RPCs are methods that can be executed on a remote node. They are first invoked on the - Master, who then decides if the invocation should be propagated to the Proxies. + Primary, who then decides if the invocation should be propagated to the Proxies. ReplicaChunks can be created by inheriting from the class and registered by calling ReplicaChunkDescriptorTable::RegisterChunkType() to create the factory required by @@ -107,7 +107,7 @@ namespace GridMate PeerId GetPeerId() const; virtual ReplicaManager* GetReplicaManager(); bool IsActive() const; - bool IsMaster() const; + bool IsPrimary() const; bool IsProxy() const; virtual void OnAttachedToReplica(Replica* replica) { (void) replica; } @@ -191,7 +191,7 @@ namespace GridMate void AddDataSetEvent(DataSetBase* dataset); // Called to enqueue a user event handler for a modified DataSet on a proxy node - void SignalDataSetChanged(const DataSetBase& dataset); // Called when the DataSet changes on the master node + void SignalDataSetChanged(const DataSetBase& dataset); // Called when the DataSet changes on the primary node void EnqueueMarshalTask(); diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaDrillerEvents.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaDrillerEvents.h index 09b454a03e..14e70a3213 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaDrillerEvents.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaDrillerEvents.h @@ -62,7 +62,7 @@ namespace GridMate //! Called when an ownership transfer request is received. virtual void OnRequestReplicaChangeOwnership(Replica* replica, PeerId requestor) { (void)replica; (void)requestor; } //! Called when a replica changes ownership, not necessarily to or from the local node. - virtual void OnReplicaChangeOwnership(Replica* replica, bool wasMaster) { (void)replica; (void)wasMaster; } + virtual void OnReplicaChangeOwnership(Replica* replica, bool wasPrimary) { (void)replica; (void)wasPrimary; } //! Called when a chunk has been created. It doesn't mean it will be added to the system. //! Object will be partially constructed at this point if you inherit from ReplicaChunk @@ -91,9 +91,9 @@ namespace GridMate //! Called when data is received for a dataset. virtual void OnReceiveDataSet(ReplicaChunkBase* chunk, AZ::u32 chunkIndex, DataSetBase* dataSet, PeerId from, PeerId to, const void* data, size_t len) { (void)chunk; (void)chunkIndex; (void)dataSet; (void)from; (void)to; (void)data; (void)len; } - //! Called when an rpc request is received. RpcRequest pointer will be null if rpc is called on master replica. + //! Called when an rpc request is received. RpcRequest pointer will be null if rpc is called on primary replica. virtual void OnRequestRpc(ReplicaChunkBase* chunk, Internal::RpcRequest* rpc) { (void)chunk; (void)rpc; } - //! Called when an rpc is invoked. RpcRequest pointer will be null if rpc is called on master replica. + //! Called when an rpc is invoked. RpcRequest pointer will be null if rpc is called on primary replica. virtual void OnInvokeRpc(ReplicaChunkBase* chunk, Internal::RpcRequest* rpc) { (void)chunk; (void)rpc; } //! Called every time an rpc is sent to a peer. virtual void OnSendRpc(ReplicaChunkBase* chunk, AZ::u32 chunkIndex, Internal::RpcRequest* rpc, PeerId from, PeerId to, const void* data, size_t len) { (void)chunk; (void)chunkIndex; (void)rpc; (void)from; (void)to; (void)data; (void)len; } diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp index 32a941ef4a..78d6f260db 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp @@ -386,7 +386,7 @@ namespace GridMate replica->SetMigratable(true); // register global session info - // this one is kind of special so don't go through AddMaster() + // this one is kind of special so don't go through AddPrimary() ReplicaContext rc(this, GetTime(), &m_self); replica->m_createTime = rc.m_realTime; replica->SetRepId(RepId_SessionInfo); @@ -405,7 +405,7 @@ namespace GridMate else { // take over ownership of the session info - AZ_Assert(!m_sessionInfo->IsMaster(), "We just became host but we were already the owner of sessionInfo!"); + AZ_Assert(!m_sessionInfo->IsPrimary(), "We just became host but we were already the owner of sessionInfo!"); AZ_Assert(m_sessionInfo->m_pHostPeer->IsOrphan(), "We can't be promoted if we are still connected to the host!"); m_sessionInfo->m_pHostPeer->Remove(m_sessionInfo->GetReplica()); m_self.Add(m_sessionInfo->GetReplica()); @@ -903,7 +903,7 @@ namespace GridMate ReplicaContext rc(this, GetTime()); for (auto& replicaObject : m_self.m_objectsTimeSort) { - if (replicaObject.m_replica->IsMaster()) + if (replicaObject.m_replica->IsPrimary()) { replicaObject.m_replica->UpdateReplica(rc); } @@ -1357,11 +1357,11 @@ namespace GridMate m_flags &= ~Rm_Processing; } //----------------------------------------------------------------------------- - void ReplicaManager::RegisterReplica(const ReplicaPtr& pReplica, bool isMaster, ReplicaContext& rc) + void ReplicaManager::RegisterReplica(const ReplicaPtr& pReplica, bool isPrimary, ReplicaContext& rc) { AZ_Assert((pReplica->m_flags & ~Replica::Rep_Traits) == 0, "This replica is not clean, flags=0x%x, rpcs=%d!", pReplica->m_flags); AZ_Assert(pReplica->GetRepId() != InvalidReplicaId, "You should set the replica ID before you register it!"); - pReplica->SetMaster(isMaster); + pReplica->SetPrimary(isPrimary); pReplica->SetNew(); auto it = m_replicas.insert(AZStd::make_pair(pReplica->GetRepId(), pReplica)); // register with lookup table (void)it; @@ -1371,21 +1371,21 @@ namespace GridMate OnReplicaChanged(pReplica); } //----------------------------------------------------------------------------- - ReplicaId ReplicaManager::AddMaster(const ReplicaPtr& pMaster) + ReplicaId ReplicaManager::AddPrimary(const ReplicaPtr& pPrimary) { AZ_Assert(IsReady(), "ReplicaManager is not ready!"); - AZ_Assert(pMaster, "Attempting to register NULL replica!"); + AZ_Assert(pPrimary, "Attempting to register NULL replica!"); ReplicaId newId = m_localIdBlocks.Alloc(); ReplicaContext rc(this, GetTime(), &m_self); - pMaster->m_createTime = rc.m_realTime; - pMaster->SetRepId(newId); - m_self.Add(pMaster.get()); - AZStd::static_pointer_cast(pMaster->m_replicaStatus)->m_ownerSeq.Set(1); - pMaster->InitReplica(this); - RegisterReplica(pMaster, true, rc); + pPrimary->m_createTime = rc.m_realTime; + pPrimary->SetRepId(newId); + m_self.Add(pPrimary.get()); + AZStd::static_pointer_cast(pPrimary->m_replicaStatus)->m_ownerSeq.Set(1); + pPrimary->InitReplica(this); + RegisterReplica(pPrimary, true, rc); - //AZ_TracePrintf("GridMate", "Peer 0x%x: Added replica master 0x%x.\n", - // GetLocalPeerId(), pMaster->GetRepId()); + //AZ_TracePrintf("GridMate", "Peer 0x%x: Added replica primary 0x%x.\n", + // GetLocalPeerId(), pPrimary->GetRepId()); return newId; } @@ -1458,9 +1458,9 @@ namespace GridMate continue; } - ReplicaPeer* source = replica->IsMaster() ? &m_self : replica->m_upstreamHop; + ReplicaPeer* source = replica->IsPrimary() ? &m_self : replica->m_upstreamHop; - if (replica->IsMaster() + if (replica->IsPrimary() || (IsSyncHost() && source->GetId() != target->GetId() && !(source->GetMode() == Mode_Peer && target->GetMode() == Mode_Peer))) { ReplicaTarget::AddReplicaTarget(target, replica.get()); @@ -1471,7 +1471,7 @@ namespace GridMate else { // Replica might've changed owner -> we need to update its targets accordingly - ReplicaPeer* source = replica->IsMaster() ? &m_self : replica->m_upstreamHop; + ReplicaPeer* source = replica->IsPrimary() ? &m_self : replica->m_upstreamHop; for (auto it = replica->m_targets.begin(); it != replica->m_targets.end(); ) { @@ -1652,14 +1652,14 @@ namespace GridMate } } //----------------------------------------------------------------------------- - void ReplicaManager::ChangeReplicaOwnership(ReplicaPtr replica, const ReplicaContext& rc, bool isMaster) + void ReplicaManager::ChangeReplicaOwnership(ReplicaPtr replica, const ReplicaContext& rc, bool isPrimary) { - bool wasMaster = replica->IsMaster(); - if (wasMaster != isMaster) // wasMaster == isMaster can happen when host's replica is moved to client, and client confirms with Cmd_NewOwner + bool wasPrimary = replica->IsPrimary(); + if (wasPrimary != isPrimary) // wasPrimary == isPrimary can happen when host's replica is moved to client, and client confirms with Cmd_NewOwner { - replica->SetMaster(isMaster); + replica->SetPrimary(isPrimary); replica->OnChangeOwnership(rc); - EBUS_EVENT(Debug::ReplicaDrillerBus, OnReplicaChangeOwnership, replica.get(), wasMaster); + EBUS_EVENT(Debug::ReplicaDrillerBus, OnReplicaChangeOwnership, replica.get(), wasPrimary); } } //----------------------------------------------------------------------------- diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h index 55b8551441..00de7e9e11 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h @@ -190,7 +190,7 @@ namespace GridMate //----------------------------------------------------------------------------- struct ReplicaMgrDesc { - // Single-master roles that replica managers can have + // Single-primary roles that replica managers can have enum Roles { Role_SyncHost = 1 << 0, @@ -421,13 +421,13 @@ namespace GridMate size_t ReleaseIdBlock(PeerId requestor); void _Unmarshal(ReadBuffer& rb, ReplicaPeer* from); - void RegisterReplica(const ReplicaPtr& pReplica, bool isMaster, ReplicaContext& rc); + void RegisterReplica(const ReplicaPtr& pReplica, bool isPrimary, ReplicaContext& rc); void UnregisterReplica(const ReplicaPtr& replica, const ReplicaContext& rc); void RemoveReplicaFromDownstream(const ReplicaPtr& replica, const ReplicaContext& rc); void MigrateReplica(ReplicaPtr replica, PeerId newOwnerId); void AnnounceReplicaMigrated(ReplicaId replicaId, PeerId newOwnerId); void OnReplicaMigrated(ReplicaPtr replica, bool isOwner, const ReplicaContext& rc); - void ChangeReplicaOwnership(ReplicaPtr replica, const ReplicaContext& rc, bool isMaster); + void ChangeReplicaOwnership(ReplicaPtr replica, const ReplicaContext& rc, bool isPrimary); void AckUpstreamSuspended(ReplicaId replicaId, PeerId sendTo, AZ::u32 requestTime); void OnAckUpstreamSuspended(ReplicaId replicaId, PeerId from, AZ::u32 requestTime); void AckDownstream(ReplicaId replicaId, PeerId sendTo, AZ::u32 requestTime); @@ -595,7 +595,7 @@ namespace GridMate * Replicas */ virtual ReplicaPtr FindReplica(ReplicaId replicaId); - ReplicaId AddMaster(const ReplicaPtr& pMaster); + ReplicaId AddPrimary(const ReplicaPtr& pPrimary); /* * Tasks diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h index 7e72dbab63..f3afb7747d 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h @@ -50,10 +50,10 @@ namespace GridMate //! Called on the originator node to request replica migration. Rpc >::BindInterface RequestOwnership; - //! Called by the master to suspend upstream requests during replica migration. + //! Called by the primary to suspend upstream requests during replica migration. Rpc, RpcArg >::BindInterface MigrationSuspendUpstream; - //! Called by the master to signal downstream flush during replica migration. + //! Called by the primary to signal downstream flush during replica migration. Rpc, RpcArg >::BindInterface MigrationRequestDownstreamAck; struct ReplicaOptions diff --git a/Code/Framework/GridMate/GridMate/Replica/SystemReplicas.cpp b/Code/Framework/GridMate/GridMate/Replica/SystemReplicas.cpp index cbaf97ad1d..944524ed2f 100644 --- a/Code/Framework/GridMate/GridMate/Replica/SystemReplicas.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/SystemReplicas.cpp @@ -84,7 +84,7 @@ namespace GridMate // on activation of this replica, create our PeerInfo replica Replica* peerReplica = Replica::CreateReplica("PeerInfo"); CreateAndAttachReplicaChunk(peerReplica); - rc.m_rm->AddMaster(peerReplica); + rc.m_rm->AddPrimary(peerReplica); } //----------------------------------------------------------------------------- void SessionInfo::OnReplicaDeactivate(const ReplicaContext& rc) @@ -132,7 +132,7 @@ namespace GridMate (void)rc; if (m_pMgr->IsSyncHost()) { - AZ_Assert(IsMaster(), "The host should always own sessionInfo!!!"); + AZ_Assert(IsPrimary(), "The host should always own sessionInfo!!!"); AZ_Assert(m_pendingPeerReports.find(peerId) == m_pendingPeerReports.end(), "We are already waiting for reports for peer 0x%8x!", peerId); vector peers; @@ -205,7 +205,7 @@ namespace GridMate //----------------------------------------------------------------------------- void PeerReplica::OnReplicaActivate(const ReplicaContext& rc) { - if (IsMaster()) + if (IsPrimary()) { m_peerId.Set(rc.m_rm->GetLocalPeerId()); } diff --git a/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaMarshalTasks.cpp b/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaMarshalTasks.cpp index e295e74556..37c0c1d8c4 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaMarshalTasks.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaMarshalTasks.cpp @@ -294,7 +294,7 @@ namespace GridMate //----------------------------------------------------------------------------- ReplicaTask::TaskStatus ReplicaMarshalZombieTask::Run(const RunContext& context) { - if (m_replica->IsMaster() || context.m_replicaManager->IsSyncHost()) + if (m_replica->IsPrimary() || context.m_replicaManager->IsSyncHost()) { m_replica->PrepareData(context.m_replicaManager->GetGridMate()->GetDefaultEndianType(), // A zombie task occurs right before replica gets removed, by design it needs to set all properties one last time. diff --git a/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaUpdateTasks.h b/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaUpdateTasks.h index 7d9d7e90fe..61e11ed56d 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaUpdateTasks.h +++ b/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaUpdateTasks.h @@ -35,7 +35,7 @@ namespace GridMate }; /** - * Task to update master & proxy replicas. + * Task to update primary & proxy replicas. * Processes RPCs and calls replicas UpdateFromReplica. Will complete immediately if no RPCs * left queued after processing, otherweise will be repeated next update tick. * Initiates replica migration if proxy owner has died. diff --git a/Code/Framework/GridMate/GridMate/Session/Session.cpp b/Code/Framework/GridMate/GridMate/Session/Session.cpp index cf9edff496..9e8aab50ec 100644 --- a/Code/Framework/GridMate/GridMate/Session/Session.cpp +++ b/Code/Framework/GridMate/GridMate/Session/Session.cpp @@ -960,7 +960,7 @@ GridSession::AddMember(GridMember* member) replica->AttachReplicaChunk(member); } - m_replicaMgr->AddMaster(replica); + m_replicaMgr->AddPrimary(replica); member->m_isHost.Set(member->IsLocal()); } @@ -1583,7 +1583,7 @@ GridSession::OnStateCreate(HSM& sm, const HSM::Event& e) // Bind session replica Replica* stateReplica = Replica::CreateReplica("SessionStateInfo"); stateReplica->AttachReplicaChunk(m_state); - m_replicaMgr->AddMaster(stateReplica); + m_replicaMgr->AddPrimary(stateReplica); // Bind member replica bool isAdded = AddMember(m_myMember); @@ -2005,7 +2005,7 @@ GridMember::OnReplicaActivate(const ReplicaContext& rc) { // if this member is me... add my state to the system. AZ_Assert(m_session->GetMyMember() == this, "The only local member should be myMember too!"); - rc.m_rm->AddMaster(m_clientState->GetReplica()); + rc.m_rm->AddPrimary(m_clientState->GetReplica()); // Both member and client state are valid! send member joined message EBUS_DBG_EVENT(Debug::SessionDrillerBus, OnMemberJoined, m_session, this); @@ -2052,7 +2052,7 @@ GridMember::OnReplicaChangeOwnership(const ReplicaContext& rc) { (void)rc; AZ_Assert(m_session->IsMigratingHost(), "This function can be called only during host migration!"); - if (IsMaster()) + if (IsPrimary()) { // Host owns the members, if I became the owner means I am the HOST! if (m_session->m_myMember == this) @@ -2084,7 +2084,7 @@ GridMember::OnKick(AZ::u8 reason, const RpcContext& rc) m_session->Leave(false); } - return true; // this is called only on the master + return true; // this is called only on the primary } return false; } @@ -2320,8 +2320,8 @@ void GridMemberStateReplica::OnReplicaDeactivate(const ReplicaContext& rc) { (void)rc; - // for master (this is our state) we always keep it. So don't do anything. - if (IsMaster()) + // for primary (this is our state) we always keep it. So don't do anything. + if (IsPrimary()) { return; } diff --git a/Code/Framework/GridMate/Tests/Interest.cpp b/Code/Framework/GridMate/Tests/Interest.cpp index b4fb9b7654..c449c92083 100644 --- a/Code/Framework/GridMate/Tests/Interest.cpp +++ b/Code/Framework/GridMate/Tests/Interest.cpp @@ -534,7 +534,7 @@ namespace GridMate auto replica = Replica::CreateReplica("ProximityInterestHandlerRules"); m_rulesReplica = CreateAndAttachReplicaChunk(replica); - m_rm->AddMaster(replica); + m_rm->AddPrimary(replica); } void ProximityInterestHandler::OnRulesHandlerUnregistered(InterestManager* manager) @@ -658,7 +658,7 @@ class Integ_InterestTest { AZ_Printf("GridMate", "InterestTestChunk::OnReplicaActivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", GetReplicaId(), - IsMaster() ? "master" : "proxy", + IsPrimary() ? "primary" : "proxy", rc.m_peer ? rc.m_peer->GetId() : 0, rc.m_rm->GetLocalPeerId()); @@ -674,7 +674,7 @@ class Integ_InterestTest { AZ_Printf("GridMate", "InterestTestChunk::OnReplicaDeactivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", GetReplicaId(), - IsMaster() ? "master" : "proxy", + IsPrimary() ? "primary" : "proxy", rc.m_peer ? rc.m_peer->GetId() : 0, rc.m_rm->GetLocalPeerId()); @@ -734,7 +734,7 @@ class Integ_InterestTest m_replica->m_data.Set(m_num); m_replica->m_bitmaskAttributeData.Set(1 << i); - m_session->GetReplicaMgr()->AddMaster(r); + m_session->GetReplicaMgr()->AddPrimary(r); } void UpdateAttribute() @@ -952,7 +952,7 @@ public: if (numUpdates == 250) { - // Checking everybody lost all replicas (except master) + // Checking everybody lost all replicas (except primary) for (int i = 0; i < k_numMachines; ++i) { for (int j = 0; j < k_numMachines; ++j) @@ -1079,11 +1079,11 @@ class LargeWorldTest void OnReplicaActivate(const ReplicaContext& rc) override { - /*if (!IsMaster())*/ + /*if (!IsPrimary())*/ /*{ AZ_Printf("GridMate", "LargeWorldTestChunk::OnReplicaActivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", GetReplicaId(), - IsMaster() ? "master" : "proxy", + IsPrimary() ? "primary" : "proxy", rc.m_peer ? rc.m_peer->GetId() : 0, rc.m_rm->GetLocalPeerId()); }*/ @@ -1214,7 +1214,7 @@ class LargeWorldTest m_replicas.push_back(replica); - m_session->GetReplicaMgr()->AddMaster(r); + m_session->GetReplicaMgr()->AddPrimary(r); } void PopulateWorld() @@ -1453,7 +1453,7 @@ public: if (numUpdates == 250) { - // Checking everybody lost all replicas (except master) + // Checking everybody lost all replicas (except primary) for (int i = 0; i < k_numMachines; ++i) { /*for (int j = 0; j < k_numMachines; ++j) diff --git a/Code/Framework/GridMate/Tests/Replica.cpp b/Code/Framework/GridMate/Tests/Replica.cpp index 4d2f8d1e3a..624ee8c7e0 100644 --- a/Code/Framework/GridMate/Tests/Replica.cpp +++ b/Code/Framework/GridMate/Tests/Replica.cpp @@ -1615,7 +1615,7 @@ public: { (void)f; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler123 requested at %u with %g on %s at %u.\n", rc.m_timestamp, f, GetReplica()->IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler123 requested at %u with %g on %s at %u.\n", rc.m_timestamp, f, GetReplica()->IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } @@ -1653,14 +1653,14 @@ public: (void)rc; if (rc.m_rm->GetUserContext(12345)) { - AZ_TracePrintf("GridMate", "Activate %s with UserData:%p\n", GetReplica()->IsMaster() ? "master" : "proxy", rc.m_rm->GetUserContext(12345)); + AZ_TracePrintf("GridMate", "Activate %s with UserData:%p\n", GetReplica()->IsPrimary() ? "primary" : "proxy", rc.m_rm->GetUserContext(12345)); } if (IsProxy()) { Bind(aznew MyObj()); } - if (IsMaster()) + if (IsPrimary()) { EBUS_EVENT(MigratableReplicaDebugMsgs::EBus, OnNewOwner, GetReplicaId(), rc.m_rm); } @@ -1679,9 +1679,9 @@ public: void OnReplicaChangeOwnership(const ReplicaContext& rc) override { (void)rc; - AZ_TracePrintf("GridMate", "Migratable replica 0x%x became %s on Peer %d\n", (int) GetReplicaId(), IsMaster() ? "master" : "proxy", (int) rc.m_rm->GetLocalPeerId()); + AZ_TracePrintf("GridMate", "Migratable replica 0x%x became %s on Peer %d\n", (int) GetReplicaId(), IsPrimary() ? "primary" : "proxy", (int) rc.m_rm->GetLocalPeerId()); - if (IsMaster()) + if (IsPrimary()) { EBUS_EVENT(MigratableReplicaDebugMsgs::EBus, OnNewOwner, GetReplicaId(), rc.m_rm); } @@ -1725,7 +1725,7 @@ protected: { (void)f; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler123 requested at %u with %g on %s at %u.\n", rc.m_timestamp, f, IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler123 requested at %u with %g on %s at %u.\n", rc.m_timestamp, f, IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } bool MyHandler2(const float& f, int p2, const RpcContext& rc) @@ -1733,7 +1733,7 @@ protected: (void)f; (void)p2; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler2 requested at %u with %g,%d on %s at %u.\n", rc.m_timestamp, f, p2, IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler2 requested at %u with %g,%d on %s at %u.\n", rc.m_timestamp, f, p2, IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } bool MyHandler3(const float& f, int p2, EBla p3, const RpcContext& rc) @@ -1742,7 +1742,7 @@ protected: (void)p2; (void)p3; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler3 requested at %u with %g,%d,%d on %s at %u.\n", rc.m_timestamp, f, p2, p3, IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler3 requested at %u with %g,%d,%d on %s at %u.\n", rc.m_timestamp, f, p2, p3, IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } bool MyHandler4(const float& f, int p2, EBla p3, const IntVectorType& p4, const RpcContext& rc) @@ -1752,13 +1752,13 @@ protected: (void)p3; (void)p4; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler4 requested at %u with %g,%d,%d,%d,%d on %s at %u.\n", rc.m_timestamp, f, p2, p3, p4[0], p4[1], IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler4 requested at %u with %g,%d,%d,%d,%d on %s at %u.\n", rc.m_timestamp, f, p2, p3, p4[0], p4[1], IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } bool MyHandlerUnreliable(const int& i, const RpcContext& rc) { (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandlerUnreliable requested at %u with %d on %s at %u.\n", rc.m_timestamp, i, IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandlerUnreliable requested at %u with %d on %s at %u.\n", rc.m_timestamp, i, IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); AZ_TEST_ASSERT(i > m_prevUnreliableValue); if ((i - m_prevUnreliableValue) > 1) { @@ -1824,7 +1824,7 @@ public: (void)rc; if (rc.m_rm->GetUserContext(12345)) { - AZ_TracePrintf("GridMate", "Activate %s with UserData:%p\n", IsMaster() ? "master" : "proxy", rc.m_rm->GetUserContext(12345)); + AZ_TracePrintf("GridMate", "Activate %s with UserData:%p\n", IsPrimary() ? "primary" : "proxy", rc.m_rm->GetUserContext(12345)); } if (IsProxy()) { @@ -1845,7 +1845,7 @@ public: void OnReplicaChangeOwnership(const ReplicaContext& rc) override { (void)rc; - AZ_TracePrintf("GridMate", "NonMigratable replica 0x%x became %s on Peer %d\n", (int) GetReplicaId(), IsMaster() ? "master" : "proxy", (int) rc.m_rm->GetLocalPeerId()); + AZ_TracePrintf("GridMate", "NonMigratable replica 0x%x became %s on Peer %d\n", (int) GetReplicaId(), IsPrimary() ? "primary" : "proxy", (int) rc.m_rm->GetLocalPeerId()); } void Bind(MyObj* pObj) @@ -1950,7 +1950,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest) // put something on s1 to get it going auto rep = Replica::CreateReplica(nullptr); s1rep1 = CreateAndAttachReplicaChunk(rep); - s1rep1id = sessions[s1].GetReplicaMgr().AddMaster(rep); + s1rep1id = sessions[s1].GetReplicaMgr().AddPrimary(rep); s1rep1->Bind(s1obj1 = aznew MyObj()); // connect s2 to s1 @@ -1993,7 +1993,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest) { auto newReplica = Replica::CreateReplica(nullptr); s2rep1 = CreateAndAttachReplicaChunk(newReplica); - s2rep1id = sessions[s2].GetReplicaMgr().AddMaster(newReplica); + s2rep1id = sessions[s2].GetReplicaMgr().AddPrimary(newReplica); s2rep1->Bind(s2obj1 = aznew MyObj()); } else @@ -2020,7 +2020,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest) { auto newReplica = Replica::CreateReplica(nullptr); s1rep2 = CreateAndAttachReplicaChunk(newReplica); - s1rep2id = sessions[s1].GetReplicaMgr().AddMaster(newReplica); + s1rep2id = sessions[s1].GetReplicaMgr().AddPrimary(newReplica); s1rep2->Bind(s1obj2 = aznew MyObj); } else @@ -2041,7 +2041,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest) { auto newReplica = Replica::CreateReplica(nullptr); s3rep1 = CreateAndAttachReplicaChunk(newReplica); - s3rep1id = sessions[s3].GetReplicaMgr().AddMaster(newReplica); + s3rep1id = sessions[s3].GetReplicaMgr().AddPrimary(newReplica); s3rep1->Bind(s3obj1 = aznew MyObj()); } else @@ -2289,13 +2289,13 @@ TEST_F(Integ_ForcedReplicaMigrationTest, ForcedReplicaMigrationTest) { auto rep = Replica::CreateReplica(nullptr); migrRep[i] = CreateAndAttachReplicaChunk(rep, aznew MyObj()); - peers[i].GetReplicaMgr().AddMaster(rep); + peers[i].GetReplicaMgr().AddPrimary(rep); AZ_TEST_ASSERT(m_replicaOwnership[migrRep[i]->GetReplicaId()] == &peers[i].GetReplicaMgr()); } { auto rep = Replica::CreateReplica(nullptr); nonMigrRep[i] = CreateAndAttachReplicaChunk(rep, aznew MyObj()); - peers[i].GetReplicaMgr().AddMaster(rep); + peers[i].GetReplicaMgr().AddPrimary(rep); } } addReplicas = false; @@ -2418,7 +2418,7 @@ public: void OnReplicaActivate(const ReplicaContext& rc) override { - if (IsMaster()) + if (IsPrimary()) { m_owner.Set(rc.m_rm->GetLocalPeerId() - 1); m_control.Set(rc.m_rm->GetLocalPeerId() - 1); @@ -2427,9 +2427,9 @@ public: void OnReplicaChangeOwnership(const ReplicaContext& rc) override { - if (IsMaster()) + if (IsPrimary()) { - AZ_TracePrintf("GridMate", "OnChangeOwnership: 0x%04x Became master on node %d\n", GetReplicaId(), rc.m_rm->GetLocalPeerId() - 1); + AZ_TracePrintf("GridMate", "OnChangeOwnership: 0x%04x Became primary on node %d\n", GetReplicaId(), rc.m_rm->GetLocalPeerId() - 1); m_owner.Set(rc.m_rm->GetLocalPeerId() - 1); } else @@ -2591,18 +2591,18 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) { auto rep = Replica::CreateReplica(nullptr); nodes[iNode].m_always = CreateAndAttachReplicaChunk(rep); - nodes[iNode].m_session.GetReplicaMgr().AddMaster(rep); + nodes[iNode].m_session.GetReplicaMgr().AddPrimary(rep); } { auto rep = Replica::CreateReplica(nullptr); nodes[iNode].m_never = CreateAndAttachReplicaChunk(rep); - nodes[iNode].m_session.GetReplicaMgr().AddMaster(rep); + nodes[iNode].m_session.GetReplicaMgr().AddPrimary(rep); } { auto rep = Replica::CreateReplica(nullptr); nodes[iNode].m_sometimes = CreateAndAttachReplicaChunk(rep); nodes[iNode].m_sometimes->m_acceptMigrationRequests = iNode == Peer1 || iNode == Client1; - nodes[iNode].m_session.GetReplicaMgr().AddMaster(rep); + nodes[iNode].m_session.GetReplicaMgr().AddPrimary(rep); } } } @@ -2675,7 +2675,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Client1].m_always->m_accepted == 1); AZ_TEST_ASSERT(nodes[Client1].m_always->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Client1].m_always->m_owner.Get() == Client2); - AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId())->IsPrimary()); // C1 -> C2 -> Host (2nd migration) ReplicaPtr aHonC1 = nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId()); @@ -2737,7 +2737,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Peer1].m_always->m_accepted == 1); AZ_TEST_ASSERT(nodes[Peer1].m_always->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Peer1].m_always->m_owner.Get() == Peer2); - AZ_TEST_ASSERT(nodes[Peer2].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer2].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer1].m_always->m_control.Get() == Peer2); // P2 -> Host -> C2 (both at same time, with C2 arriving second) @@ -2750,7 +2750,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(aP2onH->m_accepted == 1); AZ_TEST_ASSERT(aP2onH->GetReplica()->IsProxy()); AZ_TEST_ASSERT(aP2onH->m_owner.Get() == Client2); - AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Peer2].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Peer2].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer2].m_always->m_control.Get() == Client2); // Host -> C1 @@ -2758,7 +2758,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Host].m_always->m_accepted == 1); AZ_TEST_ASSERT(nodes[Host].m_always->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Host].m_always->m_owner.Get() == Client1); - AZ_TEST_ASSERT(nodes[Client1].m_session.GetReplicaMgr().FindReplica(nodes[Host].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Client1].m_session.GetReplicaMgr().FindReplica(nodes[Host].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Host].m_always->m_control.Get() == Client1); // C1 -> C2 -> Host (2nd migration) @@ -2771,7 +2771,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(aC1onC2->m_accepted == 1); AZ_TEST_ASSERT(aC1onC2->GetReplica()->IsProxy()); AZ_TEST_ASSERT(aC1onC2->m_owner.Get() == Host); - AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Client1].m_always->m_control.Get() == Host); // C2 -> P1 @@ -2779,13 +2779,13 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Client2].m_always->m_accepted == 1); AZ_TEST_ASSERT(nodes[Client2].m_always->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Client2].m_always->m_owner.Get() == Peer1); - AZ_TEST_ASSERT(nodes[Peer1].m_session.GetReplicaMgr().FindReplica(nodes[Client2].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer1].m_session.GetReplicaMgr().FindReplica(nodes[Client2].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Client2].m_always->m_control.Get() == Peer1); // P1 -> C1 (Forbidden) AZ_TEST_ASSERT(nodes[Peer1].m_never->m_requests == 0); AZ_TEST_ASSERT(nodes[Peer1].m_never->m_accepted == 0); - AZ_TEST_ASSERT(nodes[Peer1].m_never->GetReplica()->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer1].m_never->GetReplica()->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer1].m_never->m_owner.Get() == Peer1); AZ_TEST_ASSERT(nodes[Client1].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_never->GetReplicaId())->IsProxy()); AZ_TEST_ASSERT(nodes[Peer1].m_never->m_control.Get() == Peer1); @@ -2793,7 +2793,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) // C2 -> P2 (Forbidden) AZ_TEST_ASSERT(nodes[Client2].m_never->m_requests == 0); AZ_TEST_ASSERT(nodes[Client2].m_never->m_accepted == 0); - AZ_TEST_ASSERT(nodes[Client2].m_never->GetReplica()->IsMaster()); + AZ_TEST_ASSERT(nodes[Client2].m_never->GetReplica()->IsPrimary()); AZ_TEST_ASSERT(nodes[Client2].m_never->m_owner.Get() == Client2); AZ_TEST_ASSERT(nodes[Peer2].m_session.GetReplicaMgr().FindReplica(nodes[Client2].m_never->GetReplicaId())->IsProxy()); AZ_TEST_ASSERT(nodes[Client2].m_never->m_control.Get() == Client2); @@ -2803,7 +2803,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Peer1].m_sometimes->m_accepted == 1); AZ_TEST_ASSERT(nodes[Peer1].m_sometimes->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Peer1].m_sometimes->m_owner.Get() == Host); - AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_sometimes->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_sometimes->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer1].m_sometimes->m_control.Get() == Host); // C1 -> P1 @@ -2811,13 +2811,13 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Client1].m_sometimes->m_accepted == 1); AZ_TEST_ASSERT(nodes[Client1].m_sometimes->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Client1].m_sometimes->m_owner.Get() == Peer1); - AZ_TEST_ASSERT(nodes[Peer1].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_sometimes->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer1].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_sometimes->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Client1].m_sometimes->m_control.Get() == Peer1); // P2 -> C2 (Forbidden) AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->m_requests == 1); AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->m_accepted == 0); - AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->GetReplica()->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->GetReplica()->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->m_owner.Get() == Peer2); AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Peer2].m_never->GetReplicaId())->IsProxy()); AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->m_control.Get() == Peer2); @@ -2825,7 +2825,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) // C2 -> Host (Forbidden) AZ_TEST_ASSERT(nodes[Client2].m_sometimes->m_requests == 1); AZ_TEST_ASSERT(nodes[Client2].m_sometimes->m_accepted == 0); - AZ_TEST_ASSERT(nodes[Client2].m_sometimes->GetReplica()->IsMaster()); + AZ_TEST_ASSERT(nodes[Client2].m_sometimes->GetReplica()->IsPrimary()); AZ_TEST_ASSERT(nodes[Client2].m_sometimes->m_owner.Get() == Client2); AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Client2].m_never->GetReplicaId())->IsProxy()); AZ_TEST_ASSERT(nodes[Client2].m_sometimes->m_control.Get() == Client2); @@ -2946,12 +2946,12 @@ TEST_F(Integ_PeerRejoinTest, PeerRejoinTest) { auto rep = Replica::CreateReplica(nullptr); migrRep[i] = CreateAndAttachReplicaChunk(rep, aznew MyObj()); - peers[i].GetReplicaMgr().AddMaster(rep); + peers[i].GetReplicaMgr().AddPrimary(rep); } { auto rep = Replica::CreateReplica(nullptr); nonMigrRep[i] = CreateAndAttachReplicaChunk(rep, aznew MyObj()); - peers[i].GetReplicaMgr().AddMaster(rep); + peers[i].GetReplicaMgr().AddPrimary(rep); } } addReplicas = false; @@ -3099,7 +3099,7 @@ public: { // make sure the requestor is set to s1 AZ_TEST_ASSERT(rpcContext.m_sourcePeer == s1 + 1); - if (IsMaster()) + if (IsPrimary()) { m_nAuthoritativeOnlyRpcCallsFromS1.Modify([](int& value) { ++value; return true; }); } @@ -3114,7 +3114,7 @@ public: { // make sure the requestor is set to s2 AZ_TEST_ASSERT(rpcContext.m_sourcePeer == s2 + 1); - if (IsMaster()) + if (IsPrimary()) { m_nAuthoritativeOnlyRpcCallsFromS2.Modify([](int& value) { ++value; return true; }); } @@ -3129,7 +3129,7 @@ public: { // make sure the requestor is set to s3 AZ_TEST_ASSERT(rpcContext.m_sourcePeer == s3 + 1); - if (IsMaster()) + if (IsPrimary()) { m_nAuthoritativeOnlyRpcCallsFromS3.Modify([](int& value) { ++value; return true; }); } @@ -3168,7 +3168,7 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) ReplicaChunkDescriptorTable::Get().RegisterChunkType(); MPSession sessions[nSessions]; - ReplicaPtr masters[nSessions]; + ReplicaPtr primarys[nSessions]; // initialize transport int basePort = 4427; @@ -3202,10 +3202,10 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) for (int i = 0; i < nSessions; ++i) { AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().IsReady()); - masters[i] = Replica::CreateReplica("ReplicationSecurityOptionsTest::TestReplica"); + primarys[i] = Replica::CreateReplica("ReplicationSecurityOptionsTest::TestReplica"); TestChunkPtr chunk = CreateReplicaChunk(); - masters[i]->AttachReplicaChunk(chunk); - sessions[i].GetReplicaMgr().AddMaster(masters[i]); + primarys[i]->AttachReplicaChunk(chunk); + sessions[i].GetReplicaMgr().AddPrimary(primarys[i]); } } @@ -3214,9 +3214,9 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) AZ_TEST_START_TRACE_SUPPRESSION; for (int i = 0; i < nSessions; ++i) { - sessions[s1].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS1(); - sessions[s2].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS2(); - sessions[s3].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS3(); + sessions[s1].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS1(); + sessions[s2].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS2(); + sessions[s3].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS3(); } } @@ -3227,36 +3227,36 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) AZ_TEST_STOP_TRACE_SUPPRESSION(2); // All chunks should have received the call from the host - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); // the host chunk should have received calls from both clients - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 1); - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 1); // the chunk on s2 should receive its own call but not from s3 - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 1); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 0); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 0); // the chunk on s3 should receive its own call but not from s2 - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 0); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 0); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 1); // all datasets should have propagated properly for (int i = 0; i < nSessions; ++i) { - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); } } @@ -3265,9 +3265,9 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) AZ_TEST_START_TRACE_SUPPRESSION; for (int i = 0; i < nSessions; ++i) { - sessions[s1].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS1(); - sessions[s2].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS2(); - sessions[s3].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS3(); + sessions[s1].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS1(); + sessions[s2].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS2(); + sessions[s3].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS3(); } } @@ -3278,40 +3278,40 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) AZ_TEST_STOP_TRACE_SUPPRESSION(6); // Each chunk should have received their own AuthoritativeOnlyRpc once. - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 1); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 1); // Calls from other nodes should have been discarded. - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 0); - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 0); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 0); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 0); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 0); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 0); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 0); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 0); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 0); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 0); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 0); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 0); // Calls should have successfully propagated to the other 2 proxies - AZ_TEST_ASSERT(sessions[s1].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS2 == 1); - AZ_TEST_ASSERT(sessions[s1].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS3 == 1); - AZ_TEST_ASSERT(sessions[s2].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(sessions[s2].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS3 == 1); - AZ_TEST_ASSERT(sessions[s3].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(sessions[s3].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(sessions[s1].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(sessions[s1].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(sessions[s2].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(sessions[s2].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(sessions[s3].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(sessions[s3].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS2 == 1); // all datasets should have propagated properly for (int i = 0; i < nSessions; ++i) { - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); } } @@ -3594,7 +3594,7 @@ public: auto rep = Replica::CreateReplica(nullptr); auto chunk = CreateAndAttachReplicaChunk(rep); replicas.push_back(AZStd::make_pair(rep, chunk)); - session.GetReplicaMgr().AddMaster(rep); + session.GetReplicaMgr().AddPrimary(rep); } } @@ -3730,7 +3730,7 @@ public: { auto rep = Replica::CreateReplica(nullptr); chunks[i] = CreateAndAttachReplicaChunk(rep); - sessions[sHost].GetReplicaMgr().AddMaster(rep); + sessions[sHost].GetReplicaMgr().AddPrimary(rep); } // connect to host diff --git a/Code/Framework/GridMate/Tests/ReplicaBehavior.cpp b/Code/Framework/GridMate/Tests/ReplicaBehavior.cpp index 3f9db2ba0e..c3dac305db 100644 --- a/Code/Framework/GridMate/Tests/ReplicaBehavior.cpp +++ b/Code/Framework/GridMate/Tests/ReplicaBehavior.cpp @@ -687,7 +687,7 @@ namespace ReplicaBehavior { AZ_TEST_ASSERT(chunk->Data1.IsDefaultValue()); AZ_TEST_ASSERT(chunk->Data2.IsDefaultValue()); - m_replicaIdDefault = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaIdDefault = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } } @@ -725,7 +725,7 @@ namespace ReplicaBehavior { AZ_TEST_ASSERT(!chunk->Data1.IsDefaultValue()); AZ_TEST_ASSERT(!chunk->Data2.IsDefaultValue()); - m_replicaIdModified = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaIdModified = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } break; } @@ -816,7 +816,7 @@ namespace ReplicaBehavior { LargeChunkWithDefaults* chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_ReplicaDefaultDataSetDriller() @@ -923,13 +923,13 @@ namespace ReplicaBehavior { ChunkWithBools* chunk1 = CreateAndAttachReplicaChunk(replica1); AZ_TEST_ASSERT(chunk1); - m_replicaBoolsId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica1); + m_replicaBoolsId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica1); ReplicaPtr replica2 = Replica::CreateReplica(nullptr); ChunkWithShortInts* chunk2 = CreateAndAttachReplicaChunk(replica2); AZ_TEST_ASSERT(chunk2); - m_replicaU8Id = m_sessions[sHost].GetReplicaMgr().AddMaster(replica2); + m_replicaU8Id = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica2); } ~Integ_Replica_ComparePackingBoolsVsU8() @@ -1058,7 +1058,7 @@ namespace ReplicaBehavior { auto chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary() @@ -1155,7 +1155,7 @@ namespace ReplicaBehavior { auto chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty() @@ -1249,7 +1249,7 @@ namespace ReplicaBehavior { ForcingDirtyTestChunk* chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_CheckReplicaIsntSentWithNoChanges() @@ -1360,7 +1360,7 @@ namespace ReplicaBehavior { auto chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_CheckEntityScriptReplicaIsntSentWithNoChanges() diff --git a/Code/Framework/GridMate/Tests/ReplicaMedium.cpp b/Code/Framework/GridMate/Tests/ReplicaMedium.cpp index 7c04c26487..fbdf4ee493 100644 --- a/Code/Framework/GridMate/Tests/ReplicaMedium.cpp +++ b/Code/Framework/GridMate/Tests/ReplicaMedium.cpp @@ -73,12 +73,12 @@ public: static const char* GetChunkName() { return "RPCChunk"; } RPCChunk() - : m_fromMasterBroadcast(0) - , m_fromMasterNotBroadcast(0) + : m_fromPrimaryBroadcast(0) + , m_fromPrimaryNotBroadcast(0) , m_fromProxyBroadcast(0) , m_fromProxyNotBroadcast(0) - , FromMasterBroadcast("FromMasterBroadcast") - , FromMasterNotBroadcast("FromMasterNotBroadcast") + , FromPrimaryBroadcast("FromPrimaryBroadcast") + , FromPrimaryNotBroadcast("FromPrimaryNotBroadcast") , FromProxyBroadcast("FromProxyBroadcast") , FromProxyNotBroadcast("FromProxyNotBroadcast") , BroadcastInt("BroadcastInt") @@ -86,30 +86,30 @@ public: bool IsReplicaMigratable() override { return false; } - bool FromMasterBroadcastFn(const RpcContext&) + bool FromPrimaryBroadcastFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed FromMasterBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - m_fromMasterBroadcast++; + AZ_TracePrintf("GridMate", "Executed FromPrimaryBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + m_fromPrimaryBroadcast++; return true; } - bool FromMasterNotBroadcastFn(const RpcContext&) + bool FromPrimaryNotBroadcastFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed FromMasterNotBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - m_fromMasterNotBroadcast++; + AZ_TracePrintf("GridMate", "Executed FromPrimaryNotBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + m_fromPrimaryNotBroadcast++; return false; } bool FromProxyBroadcastFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed FromProxyBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed FromProxyBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); m_fromProxyBroadcast++; return true; } bool FromProxyNotBroadcastFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed FromProxyNotBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed FromProxyNotBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); m_fromProxyNotBroadcast++; return false; } @@ -120,14 +120,14 @@ public: return true; } - int m_fromMasterBroadcast; - int m_fromMasterNotBroadcast; + int m_fromPrimaryBroadcast; + int m_fromPrimaryNotBroadcast; int m_fromProxyBroadcast; int m_fromProxyNotBroadcast; AZStd::vector m_sentData; - Rpc<>::BindInterface FromMasterBroadcast; - Rpc<>::BindInterface FromMasterNotBroadcast; + Rpc<>::BindInterface FromPrimaryBroadcast; + Rpc<>::BindInterface FromPrimaryNotBroadcast; Rpc<>::BindInterface FromProxyBroadcast; Rpc<>::BindInterface FromProxyNotBroadcast; Rpc >::BindInterface BroadcastInt; @@ -158,21 +158,21 @@ public: bool Zero(const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[0]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[0]; (void) list; return true; } bool One(AZ::u32 t1, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[1]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[1]; list.push_back(t1); return true; } bool Two(AZ::u32 t1, AZ::u32 t2, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[2]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[2]; list.push_back(t1); list.push_back(t2); return true; @@ -180,7 +180,7 @@ public: bool Three(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[3]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[3]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -189,7 +189,7 @@ public: bool Four(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[4]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[4]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -199,7 +199,7 @@ public: bool Five(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[5]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[5]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -210,7 +210,7 @@ public: bool Six(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, AZ::u32 t6, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[6]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[6]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -222,7 +222,7 @@ public: bool Seven(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, AZ::u32 t6, AZ::u32 t7, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[7]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[7]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -235,7 +235,7 @@ public: bool Eight(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, AZ::u32 t6, AZ::u32 t7, AZ::u32 t8, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[8]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[8]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -249,7 +249,7 @@ public: bool Nine(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, AZ::u32 t6, AZ::u32 t7, AZ::u32 t8, AZ::u32 t9, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[9]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[9]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -890,7 +890,7 @@ public: // put something on s1 to get it going auto replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } RPCChunk::Ptr m_chunk; @@ -905,11 +905,11 @@ TEST_F(Integ_ReplicaChunkRPCExec, ReplicaChunkRPCExec) switch (tick) { case 10: - m_chunk->FromMasterBroadcast(); + m_chunk->FromPrimaryBroadcast(); break; case 20: - m_chunk->FromMasterNotBroadcast(); + m_chunk->FromPrimaryNotBroadcast(); break; case 30: @@ -932,13 +932,13 @@ TEST_F(Integ_ReplicaChunkRPCExec, ReplicaChunkRPCExec) auto s2proxy = m_sessions[s2].GetReplicaMgr().FindReplica(m_replicaId)->FindReplicaChunk(); auto s3proxy = m_sessions[s3].GetReplicaMgr().FindReplica(m_replicaId)->FindReplicaChunk(); - AZ_TEST_ASSERT(s1host->m_fromMasterBroadcast == 1); - AZ_TEST_ASSERT(s2proxy->m_fromMasterBroadcast == 1); - AZ_TEST_ASSERT(s3proxy->m_fromMasterBroadcast == 1); + AZ_TEST_ASSERT(s1host->m_fromPrimaryBroadcast == 1); + AZ_TEST_ASSERT(s2proxy->m_fromPrimaryBroadcast == 1); + AZ_TEST_ASSERT(s3proxy->m_fromPrimaryBroadcast == 1); - AZ_TEST_ASSERT(s1host->m_fromMasterNotBroadcast == 1); - AZ_TEST_ASSERT(s2proxy->m_fromMasterNotBroadcast == 0); - AZ_TEST_ASSERT(s3proxy->m_fromMasterNotBroadcast == 0); + AZ_TEST_ASSERT(s1host->m_fromPrimaryNotBroadcast == 1); + AZ_TEST_ASSERT(s2proxy->m_fromPrimaryNotBroadcast == 0); + AZ_TEST_ASSERT(s3proxy->m_fromPrimaryNotBroadcast == 0); AZ_TEST_ASSERT(s1host->m_fromProxyBroadcast == 1); AZ_TEST_ASSERT(s2proxy->m_fromProxyBroadcast == 1); @@ -965,12 +965,12 @@ public: GM_CLASS_ALLOCATOR(DestroyRPCChunk); DestroyRPCChunk() - : DestroyFromMaster("DestroyFromMaster") + : DestroyFromPrimary("DestroyFromPrimary") , DestroyFromProxy("DestroyFromProxy") , BeforeDestroyFromProxy("BeforeDestroyFromProxy") , AfterDestroyFromProxy("AfterDestroyFromProxy") - , BeforeDestroyFromMaster("BeforeDestroyFromMaster") - , AfterDestroyFromMaster("AfterDestroyFromMaster") + , BeforeDestroyFromPrimary("BeforeDestroyFromPrimary") + , AfterDestroyFromPrimary("AfterDestroyFromPrimary") { } @@ -979,11 +979,11 @@ public: bool IsReplicaMigratable() override { return false; } - bool DestroyFromMasterFn(const RpcContext&) + bool DestroyFromPrimaryFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed DestroyFromMaster %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - ++s_destroyFromMasterCalls; - if (GetReplica()->IsMaster()) + AZ_TracePrintf("GridMate", "Executed DestroyFromPrimary %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + ++s_destroyFromPrimaryCalls; + if (GetReplica()->IsPrimary()) { GetReplica()->Destroy(); } @@ -992,9 +992,9 @@ public: bool DestroyFromProxyFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed DestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed DestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); ++s_destroyFromProxyCalls; - if (GetReplica()->IsMaster()) + if (GetReplica()->IsPrimary()) { GetReplica()->Destroy(); } @@ -1003,53 +1003,53 @@ public: bool BeforeDestroyFromProxyFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed BeforeDestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed BeforeDestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); ++s_beforeDestroyFromProxyCalls; return true; } bool AfterDestroyFromProxyFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed AfterDestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed AfterDestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); ++s_afterDestroyFromProxyCalls; return true; } - bool BeforeDestroyFromMasterFn(const RpcContext&) + bool BeforeDestroyFromPrimaryFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed BeforeDestroyFromMaster %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - ++s_beforeDestroyFromMasterCalls; + AZ_TracePrintf("GridMate", "Executed BeforeDestroyFromPrimary %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + ++s_beforeDestroyFromPrimaryCalls; return true; } - bool AfterDestroyFromMasterFn(const RpcContext&) + bool AfterDestroyFromPrimaryFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed AfterDestroyFromMaster %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - ++s_afterDestroyFromMasterCalls; + AZ_TracePrintf("GridMate", "Executed AfterDestroyFromPrimary %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + ++s_afterDestroyFromPrimaryCalls; return true; } - Rpc<>::BindInterface DestroyFromMaster; + Rpc<>::BindInterface DestroyFromPrimary; Rpc<>::BindInterface DestroyFromProxy; Rpc<>::BindInterface BeforeDestroyFromProxy; Rpc<>::BindInterface AfterDestroyFromProxy; - Rpc<>::BindInterface BeforeDestroyFromMaster; - Rpc<>::BindInterface AfterDestroyFromMaster; + Rpc<>::BindInterface BeforeDestroyFromPrimary; + Rpc<>::BindInterface AfterDestroyFromPrimary; - static int s_destroyFromMasterCalls; - static int s_beforeDestroyFromMasterCalls; - static int s_afterDestroyFromMasterCalls; + static int s_destroyFromPrimaryCalls; + static int s_beforeDestroyFromPrimaryCalls; + static int s_afterDestroyFromPrimaryCalls; static int s_destroyFromProxyCalls; static int s_beforeDestroyFromProxyCalls; static int s_afterDestroyFromProxyCalls; }; int DestroyRPCChunk::s_destroyFromProxyCalls = 0; -int DestroyRPCChunk::s_destroyFromMasterCalls = 0; +int DestroyRPCChunk::s_destroyFromPrimaryCalls = 0; int DestroyRPCChunk::s_beforeDestroyFromProxyCalls = 0; int DestroyRPCChunk::s_afterDestroyFromProxyCalls = 0; -int DestroyRPCChunk::s_beforeDestroyFromMasterCalls = 0; -int DestroyRPCChunk::s_afterDestroyFromMasterCalls = 0; +int DestroyRPCChunk::s_beforeDestroyFromPrimaryCalls = 0; +int DestroyRPCChunk::s_afterDestroyFromPrimaryCalls = 0; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -1077,7 +1077,7 @@ public: { auto replica = Replica::CreateReplica(nullptr); CreateAndAttachReplicaChunk(replica); - m_repId[i] = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_repId[i] = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } } @@ -1092,12 +1092,12 @@ TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC) { case 10: { - // calling destroy on master - auto master = m_sessions[sHost].GetReplicaMgr().FindReplica(m_repId[0]); - auto masterChunk = master->FindReplicaChunk(); - masterChunk->BeforeDestroyFromMaster(); - masterChunk->DestroyFromMaster(); - masterChunk->AfterDestroyFromMaster(); + // calling destroy on primary + auto primary = m_sessions[sHost].GetReplicaMgr().FindReplica(m_repId[0]); + auto primaryChunk = primary->FindReplicaChunk(); + primaryChunk->BeforeDestroyFromPrimary(); + primaryChunk->DestroyFromPrimary(); + primaryChunk->AfterDestroyFromPrimary(); // calling destroy on proxy auto proxy = m_sessions[s2].GetReplicaMgr().FindReplica(m_repId[1]); @@ -1113,15 +1113,15 @@ TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC) { // checking if before destroy RPC was called on every peer AZ_TEST_ASSERT(DestroyRPCChunk::s_beforeDestroyFromProxyCalls == nSessions); - AZ_TEST_ASSERT(DestroyRPCChunk::s_beforeDestroyFromMasterCalls == nSessions); + AZ_TEST_ASSERT(DestroyRPCChunk::s_beforeDestroyFromPrimaryCalls == nSessions); // checking if destroy itself was called on every peer AZ_TEST_ASSERT(DestroyRPCChunk::s_destroyFromProxyCalls == nSessions); - AZ_TEST_ASSERT(DestroyRPCChunk::s_destroyFromMasterCalls == nSessions); + AZ_TEST_ASSERT(DestroyRPCChunk::s_destroyFromPrimaryCalls == nSessions); // checking if after destroy RPC was never called AZ_TEST_ASSERT(DestroyRPCChunk::s_afterDestroyFromProxyCalls == 0); // RPCs that arrive via the network after deactivation should be dropped. - AZ_TEST_ASSERT(DestroyRPCChunk::s_afterDestroyFromMasterCalls == 1); // RPCs explicitly called on an inactive replica should still be executed. + AZ_TEST_ASSERT(DestroyRPCChunk::s_afterDestroyFromPrimaryCalls == 1); // RPCs explicitly called on an inactive replica should still be executed. return TestStatus::Completed; } @@ -1157,7 +1157,7 @@ public: { // put something on s1 to get it going m_replica = Replica::CreateReplica(nullptr); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -1232,7 +1232,7 @@ public: // put something on s1 to get it going m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -1286,7 +1286,7 @@ public: // put something on s1 to get it going m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -1391,7 +1391,7 @@ public: { // put something on s1 to get it going m_replica = Replica::CreateReplica(nullptr); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } @@ -1453,7 +1453,7 @@ public: { ReplicaPtr replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); AZ_TEST_ASSERT(m_chunk->m_attaches == 1); AZ_TEST_ASSERT(m_chunk->m_activates == 1); @@ -1531,7 +1531,7 @@ public: auto chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); } - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); auto numChunks = replica->GetNumChunks(); AZ_TEST_ASSERT(numChunks == GM_MAX_CHUNKS_PER_REPLICA); @@ -1594,7 +1594,7 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); AZ_TEST_ASSERT(m_chunk->m_attaches == 1); AZ_TEST_ASSERT(m_chunk->m_activates == 1); @@ -1820,16 +1820,16 @@ public: ++m_numRequestChangeOwnership; } - void OnReplicaChangeOwnership(Replica* replica, bool wasMaster) override + void OnReplicaChangeOwnership(Replica* replica, bool wasPrimary) override { AZ_TEST_ASSERT(replica); switch (m_numChangedOwnership) { case 0: // host loses ownership - AZ_TEST_ASSERT(replica->IsProxy() && wasMaster == true); + AZ_TEST_ASSERT(replica->IsProxy() && wasPrimary == true); break; case 1: // peer acquires ownership - AZ_TEST_ASSERT(replica->IsMaster() && wasMaster == false); + AZ_TEST_ASSERT(replica->IsPrimary() && wasPrimary == false); break; default: AZ_TEST_ASSERT(0); @@ -2008,7 +2008,7 @@ public: ReplicaPtr replica = Replica::CreateReplica(nullptr); CreateAndAttachReplicaChunk(replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_ReplicaDriller() @@ -2038,7 +2038,7 @@ TEST_F(Integ_ReplicaDriller, ReplicaDriller) { auto rep = m_sessions[s2].GetReplicaMgr().FindReplica(m_replicaId); AZ_TEST_ASSERT(rep); - AZ_TEST_ASSERT(rep->IsMaster()); + AZ_TEST_ASSERT(rep->IsPrimary()); rep->Destroy(); break; } @@ -2110,7 +2110,7 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } @@ -2172,16 +2172,16 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); - m_masterHandler.reset(aznew CustomHandler()); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); + m_primaryHandler.reset(aznew CustomHandler()); m_proxyHandler.reset(aznew CustomHandler()); - m_chunk->SetHandler(m_masterHandler.get()); + m_chunk->SetHandler(m_primaryHandler.get()); } ReplicaPtr m_replica; ReplicaId m_replicaId; CustomHandlerChunk::Ptr m_chunk; - AZStd::scoped_ptr m_masterHandler; + AZStd::scoped_ptr m_primaryHandler; AZStd::scoped_ptr m_proxyHandler; }; @@ -2262,7 +2262,7 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -2338,7 +2338,7 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -2488,7 +2488,7 @@ public: m_chunks[i] = CreateAndAttachReplicaChunk(replica); m_chunks[i]->m_value.Set(i + 1); // setting dataset values to 1..kNumReplicas m_chunks[i]->SetPriority(k_replicaPriorityNormal + static_cast(i)); // the later created - the higher priorities, so should be sent in reverse order - m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } } @@ -2594,7 +2594,7 @@ public: ReplicaPtr replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(replica); - m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } SuspendUpdatesChunk::Ptr m_chunk = nullptr; @@ -2684,9 +2684,9 @@ public: void OnReplicaActivate(const GridMate::ReplicaContext&) override { - if (IsMaster()) + if (IsPrimary()) { - nMasterActivations++; + nPrimaryActivations++; } else { @@ -2694,11 +2694,11 @@ public: } } - static int nMasterActivations; + static int nPrimaryActivations; static int nProxyActivations; }; }; -int Integ_BasicHostChunkDescriptorTest::HostChunk::nMasterActivations = 0; +int Integ_BasicHostChunkDescriptorTest::HostChunk::nPrimaryActivations = 0; int Integ_BasicHostChunkDescriptorTest::HostChunk::nProxyActivations = 0; TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest) @@ -2744,25 +2744,25 @@ TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest) { hostReplica = Replica::CreateReplica("HostReplica"); hostReplica->AttachReplicaChunk(CreateReplicaChunk()); - nodes[Host].GetReplicaMgr().AddMaster(hostReplica); + nodes[Host].GetReplicaMgr().AddPrimary(hostReplica); } if (tick == 300) { - AZ_TEST_ASSERT(HostChunk::nMasterActivations == 1); + AZ_TEST_ASSERT(HostChunk::nPrimaryActivations == 1); AZ_TEST_ASSERT(HostChunk::nProxyActivations == 1); AZ_TEST_ASSERT(nodes[Client].GetReplicaMgr().FindReplica(hostReplica->GetRepId())->FindReplicaChunk()); AZ_TEST_START_TRACE_SUPPRESSION; clientReplica = Replica::CreateReplica("ClientReplica"); clientReplica->AttachReplicaChunk(CreateReplicaChunk()); - nodes[Client].GetReplicaMgr().AddMaster(clientReplica); + nodes[Client].GetReplicaMgr().AddPrimary(clientReplica); } if (tick == 400) { AZ_TEST_STOP_TRACE_SUPPRESSION(1); - AZ_TEST_ASSERT(HostChunk::nMasterActivations == 2); + AZ_TEST_ASSERT(HostChunk::nPrimaryActivations == 2); AZ_TEST_ASSERT(HostChunk::nProxyActivations == 1); AZ_TEST_ASSERT(!nodes[Host].GetReplicaMgr().FindReplica(clientReplica->GetRepId())->FindReplicaChunk()); } @@ -2792,10 +2792,10 @@ TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest) } /* - * Create and immedietly destroy master replica + * Create and immedietly destroy primary replica * Test that it does not result in any network sync */ -class Integ_CreateDestroyMaster +class Integ_CreateDestroyPrimary : public Integ_SimpleTest , public Debug::ReplicaDrillerBus::Handler { @@ -2831,7 +2831,7 @@ public: } }; -TEST_F(Integ_CreateDestroyMaster, CreateDestroyMaster) +TEST_F(Integ_CreateDestroyPrimary, CreateDestroyPrimary) { RunTickLoop([this](int tick)-> TestStatus { @@ -2843,7 +2843,7 @@ TEST_F(Integ_CreateDestroyMaster, CreateDestroyMaster) ConnectDriller(); auto replica = Replica::CreateReplica(nullptr); CreateAndAttachReplicaChunk(replica); - m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); // Destroying replica right away replica->Destroy(); @@ -2894,7 +2894,7 @@ public: LargeChunkWithDefaultsMedium* chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~ReplicaACKfeedbackTestFixture() diff --git a/Code/Framework/GridMate/Tests/ReplicaSmall.cpp b/Code/Framework/GridMate/Tests/ReplicaSmall.cpp index c2cd8845da..f1d78d5a18 100644 --- a/Code/Framework/GridMate/Tests/ReplicaSmall.cpp +++ b/Code/Framework/GridMate/Tests/ReplicaSmall.cpp @@ -234,7 +234,7 @@ public: /** * OfflineModeTest verifies that replica chunks are usable without -* an active session, and basically behave as masters. +* an active session, and basically behave as primarys. */ class OfflineModeTest : public UnitTest::GridMateMPTestFixture @@ -297,7 +297,7 @@ public: AZ_TEST_ASSERT(OfflineChunk::s_nInstances == 1); ReplicaChunkPtr chunkPtr = offlineChunk; chunkPtr->Init(ReplicaChunkClassId(OfflineChunk::GetChunkName())); - AZ_TEST_ASSERT(chunkPtr->IsMaster()); + AZ_TEST_ASSERT(chunkPtr->IsPrimary()); AZ_TEST_ASSERT(!chunkPtr->IsProxy()); offlineChunk->m_data1.Set(5); AZ_TEST_ASSERT(offlineChunk->m_data1.Get() == 5); @@ -315,7 +315,7 @@ public: return true; }); AZ_TEST_ASSERT(offlineChunk->m_data2.Get() == 10); - AZ_TEST_ASSERT(offlineChunk->m_nCallsDataSetChangeCB == 0); // DataSet change CB doesn't get called on master. + AZ_TEST_ASSERT(offlineChunk->m_nCallsDataSetChangeCB == 0); // DataSet change CB doesn't get called on primary. offlineChunk->CallRpc(); AZ_TEST_ASSERT(offlineChunk->m_nCallsRpcHandlerCB == 1); @@ -325,11 +325,11 @@ public: AZ_TEST_ASSERT(strcmp(offlineReplica->GetDebugName(), replicaName) == 0); offlineReplica->AttachReplicaChunk(chunkPtr); - AZ_TEST_ASSERT(chunkPtr->IsMaster()); + AZ_TEST_ASSERT(chunkPtr->IsPrimary()); AZ_TEST_ASSERT(!chunkPtr->IsProxy()); offlineReplica->DetachReplicaChunk(chunkPtr); - AZ_TEST_ASSERT(chunkPtr->IsMaster()); + AZ_TEST_ASSERT(chunkPtr->IsPrimary()); AZ_TEST_ASSERT(!chunkPtr->IsProxy()); AZ_TEST_ASSERT(OfflineChunk::s_nInstances == 1); @@ -462,7 +462,7 @@ public: ReplicaPeer peer(&rm); AZ_TracePrintf("GridMate", "\n"); - Replica* replica = Replica::CreateReplica("TestMasterReplica"); + Replica* replica = Replica::CreateReplica("TestPrimaryReplica"); ReplicaChunkDescriptorTable::Get().RegisterChunkType(); AZStd::unique_ptr chunk(CreateReplicaChunk()); diff --git a/Code/Framework/Tests/GridMocks.h b/Code/Framework/Tests/GridMocks.h deleted file mode 100644 index 08426bf5a6..0000000000 --- a/Code/Framework/Tests/GridMocks.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include - -namespace UnitTest -{ - class MockSession - : public GridMate::GridSession - { - public: - MockSession(GridMate::SessionService* service) - : GridSession(service) - { - } - - void SetReplicaManager(GridMate::ReplicaManager* replicaManager) - { - m_replicaMgr = replicaManager; - } - - MOCK_METHOD4(CreateRemoteMember, GridMate::GridMember*(const GridMate::string&, GridMate::ReadBuffer&, GridMate::RemotePeerMode, GridMate::ConnectionID)); - MOCK_METHOD1(OnSessionParamChanged, void(const GridMate::GridSessionParam&)); - MOCK_METHOD1(OnSessionParamRemoved, void(const GridMate::string&)); - }; - - class MockSessionService - : public GridMate::SessionService - { - public: - MockSessionService() - : SessionService(GridMate::SessionServiceDesc()) - { - } - - ~MockSessionService() - { - m_activeSearches.clear(); - m_gridMate = nullptr; - } - - MOCK_CONST_METHOD0(IsReady, bool()); - }; -} diff --git a/Code/Framework/Tests/InterestManagerComponentTests.cpp b/Code/Framework/Tests/InterestManagerComponentTests.cpp deleted file mode 100644 index f321609785..0000000000 --- a/Code/Framework/Tests/InterestManagerComponentTests.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "GridMocks.h" - -#include -#include -#include - -#include -#include -#include - -namespace UnitTest -{ - using testing::_; - - class MockInterestManagerEvents - : public AzFramework::InterestManagerEventsBus::Handler - { - public: - MockInterestManagerEvents() - { - BusConnect(); - } - - virtual ~MockInterestManagerEvents() - { - BusDisconnect(); - } - - MOCK_METHOD1(OnInterestManagerActivate, void(GridMate::InterestManager* im)); - MOCK_METHOD1(OnInterestManagerDeactivate, void(GridMate::InterestManager* im)); - }; - - class InterestManagerComponentFixture - : public AllocatorsFixture - { - public: - InterestManagerComponentFixture() - : AllocatorsFixture() - { - - } - - ~InterestManagerComponentFixture() - { - - } - - void SetUp() override - { - AZ::AzSock::Startup(); - - AllocatorsFixture::SetUp(); - AZ::AllocatorInstance::Create(); - m_gridMate = GridMate::GridMateCreate(GridMate::GridMateDesc()); - m_carrier = GridMate::DefaultCarrier::Create(GridMate::CarrierDesc(), m_gridMate); - - m_sessionService = AZStd::make_unique(); - m_gridSession = AZStd::make_unique(m_sessionService.get()); - - m_replicaManagerDesc.m_carrier = m_carrier; - m_replicaManagerDesc.m_myPeerId = AZ::Crc32(testing::UnitTest::GetInstance()->current_test_info()->test_case_name()); - m_replicaManagerDesc.m_roles = GridMate::ReplicaMgrDesc::Role_SyncHost; - m_replicaManager = AZStd::make_unique(); - m_replicaManager->Init(m_replicaManagerDesc); - - m_gridSession->SetReplicaManager(m_replicaManager.get()); - } - - void TearDown() override - { - m_gridSession = nullptr; - m_sessionService = nullptr; - - m_replicaManager->Shutdown(); - m_replicaManager = nullptr; - - m_carrier->Shutdown(); - delete m_carrier; - GridMate::GridMateDestroy(m_gridMate); - AZ::AllocatorInstance::Destroy(); - AllocatorsFixture::TearDown(); - - AZ::AzSock::Cleanup(); - } - - AZStd::unique_ptr m_sessionService; - AZStd::unique_ptr m_gridSession; - - GridMate::IGridMate* m_gridMate; - GridMate::Carrier* m_carrier; - - GridMate::ReplicaMgrDesc m_replicaManagerDesc; - AZStd::unique_ptr m_replicaManager; - }; - - TEST_F(InterestManagerComponentFixture, TestNetworkSessionDeactivate) - { - // Using StrictMock here will ensure that the test fails if any of the events fire (as no EXPECT_CALL has been set). - testing::StrictMock interestManagerEvents; - AzFramework::InterestManagerComponent interestManagerComponent; - - // This will connect the component to the NetBindingSystemEventsBus - interestManagerComponent.Activate(); - - // Ensure that the interest manager component handles receiving OnNetworkSessionDeactivated for a session that was never activated. - // This can happen in the event of a client failing to connect to a host. - AzFramework::NetBindingSystemEventsBus::Broadcast( - &AzFramework::NetBindingSystemEvents::OnNetworkSessionDeactivated, m_gridSession.get()); - - interestManagerComponent.Deactivate(); - } - - TEST_F(InterestManagerComponentFixture, TestNetworkSessionActivateAndDeactivate) - { - // Using StrictMock here will ensure that the test fails if any of the events fire (as no EXPECT_CALL has been set). - testing::StrictMock interestManagerEvents; - AzFramework::InterestManagerComponent interestManagerComponent; - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - - // This will connect the component to the NetBindingSystemEventsBus - interestManagerComponent.Activate(); - - // Golden path test that the interest manager component behaves as expected under normal conditions - // (receiving OnNetworkSessionActivated followed by OnNetworkSessionDeactivated). - testing::Expectation activationEvent = EXPECT_CALL(interestManagerEvents, OnInterestManagerActivate(_)) - .Times(1); - AzFramework::NetBindingSystemEventsBus::Broadcast( - &AzFramework::NetBindingSystemEvents::OnNetworkSessionActivated, m_gridSession.get()); - - EXPECT_CALL(interestManagerEvents, OnInterestManagerDeactivate(_)) - .Times(1) - .After(activationEvent); - AzFramework::NetBindingSystemEventsBus::Broadcast( - &AzFramework::NetBindingSystemEvents::OnNetworkSessionDeactivated, m_gridSession.get()); - - interestManagerComponent.Deactivate(); - } -} diff --git a/Code/Framework/Tests/NetBinding.cpp b/Code/Framework/Tests/NetBinding.cpp deleted file mode 100644 index cf2455be0f..0000000000 --- a/Code/Framework/Tests/NetBinding.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace UnitTest -{ -#if 0 - using namespace AZ; - - /** - */ - class NetBindingTestComponent - : public AZ::Component - , public AzFramework::NetBindable - { - friend class NetBindingComponentChunk; - - public: - AZ_COMPONENT(NetBindingTestComponent, "{DE5CF1C0-B4B6-4BB0-86FE-936B400871E0}", AzFramework::NetBindable); - - protected: - class NetChunk - : public GridMate::ReplicaChunk - { - public: - AZ_CLASS_ALLOCATOR(NetChunk, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingTestComponent::NetChunk"; } - - bool IsReplicaMigratable() override { return false; } - }; - - /////////////////////////////////////////////////////////////////////// - // NetBindable - GridMate::ReplicaChunkPtr GetNetworkBinding() override - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::GetNetworkBinding()\n"); - m_chunk = GridMate::CreateReplicaChunk(); - AZ_Assert(m_chunk, "Failed to create NetBindingTestComponent::NetChunk!"); - return m_chunk; - } - - void SetNetworkBinding(GridMate::ReplicaChunkPtr binding) override - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::SetNetworkBinding()\n"); - AZ_TEST_ASSERT(binding); - AZ_TEST_ASSERT(binding->GetDescriptor()->GetChunkTypeId() == GridMate::ReplicaChunkClassId(NetChunk::GetChunkName())); - m_chunk = AZStd::static_pointer_cast(binding); - } - - void UnbindFromNetwork() override - { - if (m_chunk) - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::UnbindFromNetwork()\n"); - m_chunk = nullptr; - } - } - /////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////// - // AZ::Component - static void Reflect(AZ::ReflectContext* reflection) - { - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - if (serializeContext) - { - serializeContext->Class() - ; - } - - // We also need to register the chunk type, and this would be a good time to do so. - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - - void Activate() override - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::Activate()\n"); - } - - void Deactivate() override - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::Deactivate()\n"); - UnbindFromNetwork(); - } - /////////////////////////////////////////////////////////////////////// - - AZStd::intrusive_ptr m_chunk; - }; - - /** - * Fakes the behavior of NetBindingSystemContextData on the host side - */ - class FakeNetBindingContextChunk - : public GridMate::ReplicaChunk - { - public: - AZ_CLASS_ALLOCATOR(FakeNetBindingContextChunk, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingSystemContextData"; } // We are pretending to be a NetBindingSystemContextData - - FakeNetBindingContextChunk() - : m_bindingContextSequence("BindingContextSequence", AzFramework::UnspecifiedNetBindingContextSequence) - { - } - - bool IsReplicaMigratable() override { return true; } - - GridMate::DataSet m_bindingContextSequence; - }; - - /* - * NetBindingSystemComponentLifecycleTest - */ - class NetBindingSystemComponentLifecycleTest - : public GridMate::SessionEventBus::Handler - , public AzFramework::NetBindingHandlerBus::Handler - { - public: - void OnSessionCreated(GridMate::GridSession* session) override - { - if (session == m_session) - { - if (session->IsHost()) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionActivated, session); - } - } - } - - void OnSessionJoined(GridMate::GridSession* session) override - { - if (session == m_session) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionActivated, session); - } - } - - void OnSessionDelete(GridMate::GridSession* session) - { - if (session == m_session) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionDeactivated, session); - m_session = nullptr; - } - } - - void BindToNetwork(GridMate::ReplicaPtr bindTo) override - { - // Verify that BindToNetwork() is not called more than once - AZ_TEST_ASSERT(!m_receivedBindEvent); - m_receivedBindEvent = true; - - // Test that now we should be binding to the network - bool shouldBindToNetwork = false; - EBUS_EVENT_RESULT(shouldBindToNetwork, AzFramework::NetBindingSystemBus, ShouldBindToNetwork); - AZ_TEST_ASSERT(shouldBindToNetwork); - - // Verify that the context sequence is no longer unspecified - AzFramework::NetBindingContextSequence contextSequence = AzFramework::UnspecifiedNetBindingContextSequence; - EBUS_EVENT_RESULT(contextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence != AzFramework::UnspecifiedNetBindingContextSequence); - } - - void UnbindFromNetwork() override - { - // Verify that UnbindFromNetwork() is not called more than once - AZ_TEST_ASSERT(!m_receivedUnbindEvent); - m_receivedUnbindEvent = true; - } - - void run() - { - // Setup - AZ::ComponentApplication app; - AZ::ComponentApplication::Descriptor appDesc; - appDesc.m_recordsMode = AZ::Debug::AllocationRecords::RECORD_FULL; - AZ::Entity* systemEntity = app.Create(appDesc); - - app.RegisterComponentDescriptor(AzFramework::NetBindingSystemComponent::CreateDescriptor()); - app.RegisterComponentDescriptor(AzFramework::GameEntityContextComponent::CreateDescriptor()); - - systemEntity->Init(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->Activate(); - AzFramework::NetBindingHandlerBus::Handler::BusConnect(); - - GridMate::GridMateDesc gridMateDesc; - GridMate::IGridMate* gridMate = GridMate::GridMateCreate(gridMateDesc); - GridMate::GridMateAllocatorMP::Descriptor allocDesc; - allocDesc.m_stackRecordLevels = 15; - allocDesc.m_custom = &AZ::AllocatorInstance::Get(); - AZ::AllocatorInstance::Create(allocDesc); - if (AZ::AllocatorInstance::Get().GetRecords()) - { - AZ::AllocatorInstance::Get().GetRecords()->SetMode(AZ::Debug::AllocationRecords::RECORD_FULL); - } - GridMate::StartGridMateService(gridMate, GridMate::SessionServiceDesc()); - GridMate::SessionEventBus::Handler::BusConnect(gridMate); - - // Test offline behavior - { - bool shouldBindToNetwork = true; - EBUS_EVENT_RESULT(shouldBindToNetwork, AzFramework::NetBindingSystemBus, ShouldBindToNetwork); - AZ_TEST_ASSERT(!shouldBindToNetwork); - - AzFramework::NetBindingContextSequence offlineContextSequence = 0xBADF00D; - EBUS_EVENT_RESULT(offlineContextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(offlineContextSequence == AzFramework::UnspecifiedNetBindingContextSequence); - } - - // Test host-side behavior - { - m_receivedBindEvent = m_receivedUnbindEvent = false; - - // Host a session - GridMate::CarrierDesc carrierDesc; - carrierDesc.m_enableDisconnectDetection = true; - GridMate::LANSessionParams sessionParams; - sessionParams.m_numPublicSlots = 10; - sessionParams.m_flags = 0; - sessionParams.m_port = HOST_PORT; - sessionParams.m_params[sessionParams.m_numParams].m_id = "filter"; - sessionParams.m_params[sessionParams.m_numParams].m_value = GridMate::Utils::GetMachineAddress(); - sessionParams.m_numParams++; - m_session = gridMate->GetMultiplayerService()->HostSession(&sessionParams, carrierDesc); - - int nFrame = 0; - while (m_session) - { - if (nFrame == 10) - { - // Verify that BindToNetwork() has been called - AZ_TEST_ASSERT(m_receivedBindEvent); - - // Verify that we have a valid context sequence - AzFramework::NetBindingContextSequence contextSequence1 = AzFramework::UnspecifiedNetBindingContextSequence; - EBUS_EVENT_RESULT(contextSequence1, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence1 != AzFramework::UnspecifiedNetBindingContextSequence); - - EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext); - - // Verify that the context sequence was incremented - AzFramework::NetBindingContextSequence contextSequence2 = contextSequence1; - EBUS_EVENT_RESULT(contextSequence2, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence2 != AzFramework::UnspecifiedNetBindingContextSequence); - AZ_TEST_ASSERT(contextSequence2 > contextSequence1); - - m_session->Leave(false); - } - - app.Tick(); - gridMate->Update(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - nFrame++; - } - - // Verify that we should no longer bind to the network - bool shouldBindToNetwork = true; - EBUS_EVENT_RESULT(shouldBindToNetwork, AzFramework::NetBindingSystemBus, ShouldBindToNetwork); - AZ_TEST_ASSERT(!shouldBindToNetwork); - - // Verify that the context sequence was reset to unspecified - AzFramework::NetBindingContextSequence offlineContextSequence = 0xBADF00D; - EBUS_EVENT_RESULT(offlineContextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(offlineContextSequence == AzFramework::UnspecifiedNetBindingContextSequence); - } - - // Test nonhost-side behavior by faking the behavior on the host side and then joining the host session. - { - m_receivedBindEvent = m_receivedUnbindEvent = false; - - // Host a session - GridMate::CarrierDesc carrierDesc; - carrierDesc.m_enableDisconnectDetection = true; - GridMate::LANSessionParams sessionParams; - sessionParams.m_numPublicSlots = 10; - sessionParams.m_flags = 0; - sessionParams.m_port = HOST_PORT; - sessionParams.m_params[sessionParams.m_numParams].m_id = "filter"; - sessionParams.m_params[sessionParams.m_numParams].m_value = GridMate::Utils::GetMachineAddress(); - sessionParams.m_numParams++; - GridMate::GridSession* hostSession = gridMate->GetMultiplayerService()->HostSession(&sessionParams, carrierDesc); - - // Add the fake context replica on the host and set the context sequence to 1 - GridMate::ReplicaPtr replica = GridMate::Replica::CreateReplica("Potato"); - FakeNetBindingContextChunk* contextChunk = GridMate::CreateReplicaChunk(); - replica->AttachReplicaChunk(contextChunk); - while (!hostSession->IsReady()) - { - gridMate->Update(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - } - hostSession->GetReplicaMgr()->AddMaster(replica); - contextChunk->m_bindingContextSequence.Set(1); - - int nFrame = 0; - while (m_session) - { - if (nFrame == 10) - { - // Join the hosted session - GridMate::SessionIdInfo sessionInfo; - sessionInfo.m_sessionId = hostSession->GetId(); - m_session = gridMate->GetMultiplayerService()->JoinSession(&sessionInfo, GridMate::JoinParams(), carrierDesc); - } - - if (nFrame == 20) - { - // Verify that BindToNetwork() has been called - AZ_TEST_ASSERT(m_receivedBindEvent); - - // Verify that we have a valid context sequence - AzFramework::NetBindingContextSequence contextSequence = AzFramework::UnspecifiedNetBindingContextSequence; - EBUS_EVENT_RESULT(contextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence == contextChunk->m_bindingContextSequence.Get()); - - // Simulate a context switch on the host - contextChunk->m_bindingContextSequence.Set(contextChunk->m_bindingContextSequence.Get() + 1); - } - - if (nFrame == 30) - { - // Verify that the context sequence was incremented - AzFramework::NetBindingContextSequence contextSequence = AzFramework::UnspecifiedNetBindingContextSequence; - EBUS_EVENT_RESULT(contextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence == contextChunk->m_bindingContextSequence.Get()); - - hostSession->Leave(false); - } - - app.Tick(); - gridMate->Update(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - nFrame++; - } - - // Verify that we should no longer bind to the network - bool shouldBindToNetwork = true; - EBUS_EVENT_RESULT(shouldBindToNetwork, AzFramework::NetBindingSystemBus, ShouldBindToNetwork); - AZ_TEST_ASSERT(!shouldBindToNetwork); - - // Verify that the context sequence was reset to unspecified - AzFramework::NetBindingContextSequence offlineContextSequence = 0xBADF00D; - EBUS_EVENT_RESULT(offlineContextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(offlineContextSequence == AzFramework::UnspecifiedNetBindingContextSequence); - } - - // Clean up - GridMate::SessionEventBus::Handler::BusDisconnect(); - GridMate::GridMateDestroy(gridMate); - AZ::AllocatorInstance::Destroy(); - AzFramework::NetBindingHandlerBus::Handler::BusDisconnect(); - app.Destroy(); - } - - static const int HOST_PORT = 5000; - - GridMate::GridSession* m_session; - bool m_receivedBindEvent; - bool m_receivedUnbindEvent; - }; - - /* - * NetBindingFeatureTest (requires two instances) - */ - class NetBindingFeatureTest - : public GridMate::SessionEventBus::Handler - { - public: - void OnSessionCreated(GridMate::GridSession* session) override - { - if (session == m_session) - { - if (session->IsHost()) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionActivated, session); - } - } - } - - void OnSessionJoined(GridMate::GridSession* session) override - { - if (session == m_session) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionActivated, session); - } - } - - void OnSessionDelete(GridMate::GridSession* session) - { - if (session == m_session) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionDeactivated, session); - m_session = nullptr; - } - } - - void OnGridSearchComplete(GridMate::GridSearch* results) override - { - if (results == m_search) - { - GridMate::CarrierDesc carrierDesc; - carrierDesc.m_enableDisconnectDetection = true; - - // Create an entity before we get in the session - AZ_TracePrintf("NetBinding", "Spawning master entity...\n"); - AZ::Entity* newEntity = nullptr; - newEntity = aznew Entity; - newEntity->CreateComponent(); - newEntity->CreateComponent(); - newEntity->Init(); - newEntity->Activate(); - m_entities.push_back(newEntity); - - if (results->GetNumResults() == 0) - { - // Host a session instead - GridMate::LANSessionParams sessionParams; - sessionParams.m_numPublicSlots = 10; - sessionParams.m_flags = 0; - sessionParams.m_port = HOST_PORT; - sessionParams.m_params[sessionParams.m_numParams].m_id = "filter"; - sessionParams.m_params[sessionParams.m_numParams].m_value = GridMate::Utils::GetMachineAddress(); - sessionParams.m_numParams++; - m_session = m_gridMate->GetMultiplayerService()->HostSession(&sessionParams, carrierDesc); - - m_search->Release(); - } - else - { - // Join the session - GridMate::JoinParams joinParams; - m_session = m_gridMate->GetMultiplayerService()->JoinSession(results->GetResult(0), joinParams, carrierDesc); - } - m_search = nullptr; - } - } - - void OnMemberJoined(GridMate::GridSession* session, GridMate::GridMember* member) override - { - if (session == m_session) - { - if (session->IsHost()) - { - if (member != session->GetMyMember()) - { - // Spawn an entity after session creation - AZ_TracePrintf("NetBinding", "Spawning master entity...\n"); - AZ::Entity* newEntity = nullptr; - EBUS_EVENT_RESULT(newEntity, AzFramework::GameEntityContextRequestBus, CreateGameEntity, "ReplicatedEntity2"); - newEntity->CreateComponent(); - newEntity->CreateComponent(); - newEntity->Init(); - newEntity->Activate(); - m_entities.push_back(newEntity); - } - } - } - } - - void run() - { - m_gridMate = nullptr; - m_session = nullptr; - - AZ::ComponentApplication app; - AZ::ComponentApplication::Descriptor appDesc; - AZ::Entity* systemEntity = app.Create(appDesc); - - app.RegisterComponentDescriptor(AzFramework::NetBindingSystemComponent::CreateDescriptor()); - app.RegisterComponentDescriptor(AzFramework::NetBindingComponent::CreateDescriptor()); - app.RegisterComponentDescriptor(NetBindingTestComponent::CreateDescriptor()); - app.RegisterComponentDescriptor(AzFramework::GameEntityContextComponent::CreateDescriptor()); - - systemEntity->Init(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->Activate(); - - GridMate::GridMateDesc gridMateDesc; - m_gridMate = GridMate::GridMateCreate(gridMateDesc); - - GridMate::GridMateAllocatorMP::Descriptor allocDesc; - allocDesc.m_custom = &AZ::AllocatorInstance::Get(); - AZ::AllocatorInstance::Create(allocDesc); - - GridMate::StartGridMateService(m_gridMate, GridMate::SessionServiceDesc()); - - GridMate::SessionEventBus::Handler::BusConnect(m_gridMate); - - // Search for an existing session - // If a session is not found, we will host a session from within the search callback. - { - GridMate::LANSearchParams searchParams; - searchParams.m_serverPort = HOST_PORT; - searchParams.m_params[searchParams.m_numParams].m_id = "filter"; - searchParams.m_params[searchParams.m_numParams].m_value = GridMate::Utils::GetMachineAddress(); - searchParams.m_params[searchParams.m_numParams].m_op = GridMate::GridSessionSearchOperators::SSO_OPERATOR_EQUAL; - searchParams.m_numParams++; - m_search = m_gridMate->GetMultiplayerService()->StartGridSearch(&searchParams); - - while (m_search) - { - m_gridMate->Update(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - } - } - - // Tick for a while - //static int nTicks = 100; - for (int i = 0; m_session; ++i) - { - if (m_session->IsHost()) - { - if (i > 4000 && m_session->GetNumberOfMembers() == 1) - { - m_session->Leave(false); - } - } - - m_gridMate->Update(); - app.Tick(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - } - - GridMate::SessionEventBus::Handler::BusDisconnect(); - - GridMate::GridMateDestroy(m_gridMate); - - AZ::AllocatorInstance::Destroy(); - - for (AZ::Entity* entity : m_entities) - { - AzFramework::EntityContextId contextId = AzFramework::EntityContextId::CreateNull(); - EBUS_EVENT_ID_RESULT(contextId, entity->GetId(), AzFramework::EntityIdContextQueryBus, GetOwningContextId); - if (contextId.IsNull()) - { - delete entity; - } - else - { - EBUS_EVENT(AzFramework::GameEntityContextRequestBus, DestroyGameEntity, entity); - } - } - - app.Destroy(); - } - - static const int HOST_PORT = 6000; - - GridMate::IGridMate* m_gridMate; - GridMate::GridSession* m_session; - GridMate::GridSearch* m_search; - AZStd::fixed_vector m_entities; - }; -#endif -} - -AZ_TEST_SUITE(NetBinding) -//AZ_TEST(UnitTest::NetBindingSystemComponentLifecycleTest) -//AZ_TEST(UnitTest::NetBindingFeatureTest) -AZ_TEST_SUITE_END diff --git a/Code/Framework/Tests/NetBindingMocks.h b/Code/Framework/Tests/NetBindingMocks.h deleted file mode 100644 index 3973fe670d..0000000000 --- a/Code/Framework/Tests/NetBindingMocks.h +++ /dev/null @@ -1,335 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#ifndef AZCORE_UNITTEST_NETBINDINGMOCKS_H -#define AZCORE_UNITTEST_NETBINDINGMOCKS_H - -#include -#include -#include -#include -#include -#include -#include - -namespace UnitTest -{ - class MockGameEntityContext - : public AzFramework::GameEntityContextRequestBus::Handler - , public AzFramework::SliceGameEntityOwnershipServiceRequestBus::Handler - { - public: - MockGameEntityContext() - { - AzFramework::GameEntityContextRequestBus::Handler::BusConnect(); - AzFramework::SliceGameEntityOwnershipServiceRequestBus::Handler::BusConnect(); - } - - ~MockGameEntityContext() - { - AzFramework::SliceGameEntityOwnershipServiceRequestBus::Handler::BusDisconnect(); - AzFramework::GameEntityContextRequestBus::Handler::BusDisconnect(); - } - - MOCK_METHOD3(InstantiateDynamicSlice, AzFramework::SliceInstantiationTicket(const AZ::Data::Asset&, const AZ::Transform&, const AZ::IdUtils::Remapper::IdMapper&)); - MOCK_METHOD0(GetGameEntityContextId, AzFramework::EntityContextId()); - MOCK_METHOD0(GetGameEntityContextInstance, AzFramework::EntityContext*()); - MOCK_METHOD1(CreateGameEntity, AZ::Entity*(const char*)); - MOCK_METHOD1(AddGameEntity, void (AZ::Entity*)); - MOCK_METHOD1(DestroyGameEntity, void (const AZ::EntityId&)); - MOCK_METHOD1(DestroyGameEntityAndDescendants, void (const AZ::EntityId&)); - MOCK_METHOD1(ActivateGameEntity, void (const AZ::EntityId&)); - MOCK_METHOD1(DeactivateGameEntity, void (const AZ::EntityId&)); - MOCK_METHOD1(DestroyDynamicSliceByEntity, bool (const AZ::EntityId&)); - MOCK_METHOD2(LoadFromStream, bool (AZ::IO::GenericStream&, bool)); - MOCK_METHOD0(ResetGameContext, void ()); - MOCK_METHOD1(GetEntityName, AZStd::string (const AZ::EntityId&)); - MOCK_METHOD1(DestroySliceByEntity, bool(const AZ::EntityId&)); - MOCK_METHOD1(CreateGameEntityForBehaviorContext, AzFramework::BehaviorEntity (const char *)); - MOCK_METHOD1(CancelDynamicSliceInstantiation, void (const AzFramework::SliceInstantiationTicket &)); - }; - - class MockNetBindingSystemContextData - : public AzFramework::NetBindingSystemContextData - { - public: - AZ_CLASS_ALLOCATOR(MockNetBindingSystemContextData, AZ::SystemAllocator, 0); - - static const char* GetChunkName() - { - return "MockNetBindingSystemContextData"; - } - - MOCK_METHOD1(OnAttachedToReplica, void (GridMate::Replica*)); - MOCK_METHOD1(OnDetachedFromReplica, void (GridMate::Replica*)); - MOCK_METHOD1(UpdateChunk, void (const GridMate::ReplicaContext&)); - MOCK_METHOD1(UpdateFromChunk, void (const GridMate::ReplicaContext&)); - MOCK_METHOD2(AcceptChangeOwnership, bool (GridMate::PeerId, const GridMate::ReplicaContext&)); - MOCK_METHOD1(OnReplicaChangeOwnership, void (const GridMate::ReplicaContext&)); - MOCK_METHOD0(IsUpdateFromReplicaEnabled, bool ()); - MOCK_CONST_METHOD1(ShouldSendToPeer, bool (GridMate::ReplicaPeer*)); - MOCK_METHOD1(CalculateDirtyDataSetMask, AZ::u32 (GridMate::MarshalContext&)); - MOCK_METHOD1(OnDataSetChanged, void (const GridMate::DataSetBase&)); - MOCK_METHOD2(Marshal, void (GridMate::MarshalContext&, AZ::u32)); - MOCK_METHOD2(Unmarshal, void (GridMate::UnmarshalContext&, AZ::u32)); - MOCK_METHOD0(IsReplicaMigratable, bool ()); - MOCK_METHOD0(IsBroadcast, bool ()); - MOCK_METHOD1(OnReplicaActivate, void (const GridMate::ReplicaContext&)); - MOCK_METHOD1(OnReplicaDeactivate, void (const GridMate::ReplicaContext&)); - - /** - * \brief Helper method for GoogleMock to call NetBindingSystemContextData::OnReplicaActivate - */ - void Base_OnReplicaActivate(const GridMate::ReplicaContext& rc) - { - NetBindingSystemContextData::OnReplicaActivate(rc); - } - - MOCK_METHOD0(GetReplicaManager, GridMate::ReplicaManager* ()); - MOCK_METHOD0(ShouldBindToNetwork, bool ()); - }; - - class MockReplicaManager - : public GridMate::ReplicaManager - { - public: - MOCK_METHOD2(OnIncomingConnection, void (GridMate::Carrier*, GridMate::ConnectionID)); - MOCK_METHOD3(OnFailedToConnect, void (GridMate::Carrier*, GridMate::ConnectionID, GridMate::CarrierDisconnectReason)); - MOCK_METHOD3(OnDriverError, void (GridMate::Carrier*, GridMate::ConnectionID, const GridMate::DriverError&)); - MOCK_METHOD3(OnSecurityError, void (GridMate::Carrier*, GridMate::ConnectionID, const GridMate::SecurityError&)); - MOCK_METHOD1(Destroy, bool (GridMate::Replica*)); - MOCK_METHOD2(GetReplicaContext, void (const GridMate::Replica*, GridMate::ReplicaContext&)); - MOCK_METHOD2(OnConnectionEstablished, void (GridMate::Carrier*, GridMate::ConnectionID)); - MOCK_METHOD3(OnDisconnect, void (GridMate::Carrier*, GridMate::ConnectionID, GridMate::CarrierDisconnectReason)); - MOCK_METHOD3(OnRateChange, void (GridMate::Carrier*, GridMate::ConnectionID, AZ::u32)); - MOCK_METHOD1(FindReplica, GridMate::ReplicaPtr (GridMate::ReplicaId)); - }; - - class MockAssetHandler - : public AZ::Data::AssetHandler - { - public: - AZ_CLASS_ALLOCATOR(MockAssetHandler, AZ::SystemAllocator, 0) - - MOCK_METHOD2(CreateAsset, AZ::Data::AssetPtr (const AZ::Data::AssetId&, const AZ::Data::AssetType&)); - MOCK_METHOD3(LoadAssetData, AZ::Data::AssetHandler::LoadResult ( - const AZ::Data::Asset&, - AZStd::shared_ptr, - const AZ::Data::AssetFilterCB&)); - MOCK_METHOD2(SaveAssetData, bool (const AZ::Data::Asset&, AZ::IO::GenericStream*)); - MOCK_METHOD3(InitAsset, void (const AZ::Data::Asset&, bool, bool)); - MOCK_METHOD1(DestroyAsset, void (AZ::Data::AssetPtr)); - MOCK_METHOD1(GetHandledAssetTypes, void (AZStd::vector&)); - MOCK_CONST_METHOD1(CanHandleAsset, bool (const AZ::Data::AssetId&)); - }; - - class MockAsset - : public AZ::DynamicSliceAsset - { - public: - AZ_RTTI(MockAsset, "{78ABC204-452E-4621-A552-F04D3ABF1690}", DynamicSliceAsset); - - MockAsset(const AZ::Data::AssetId& assetId = AZ::Data::AssetId()) - : DynamicSliceAsset(assetId) - { - } - - ~MockAsset() = default; - }; - - class MockSliceReference - : public AZ::SliceComponent::SliceReference - { - public: - using SliceReference::SliceReference; - - MOCK_METHOD1(CreateInstance, AZ::SliceComponent::SliceInstance*(const AZ::IdUtils::Remapper::IdMapper&)); - MOCK_METHOD2(CloneInstance, AZ::SliceComponent::SliceInstance*(AZ::SliceComponent::SliceInstance*, AZ::SliceComponent::EntityIdToEntityIdMap&)); - MOCK_METHOD1(FindInstance, AZ::SliceComponent::SliceInstance*(const AZ::SliceComponent::SliceInstanceId&)); - MOCK_METHOD1(RemoveInstance, bool(AZ::SliceComponent::SliceInstance*)); - MOCK_METHOD3(RemoveEntity, bool(AZ::EntityId, bool, AZ::SliceComponent::SliceInstance*)); - MOCK_CONST_METHOD0(GetInstances, const AZ::SliceComponent::SliceReference::SliceInstances&()); - MOCK_CONST_METHOD0(GetSliceAsset, const AZ::Data::Asset& ()); - MOCK_CONST_METHOD0(GetSliceComponent, AZ::SliceComponent*()); - MOCK_CONST_METHOD0(IsInstantiated, bool ()); - MOCK_CONST_METHOD3(GetInstanceEntityAncestry, bool(const AZ::EntityId&, AZ::SliceComponent::EntityAncestorList&, AZ::u32)); - MOCK_METHOD0(ComputeDataPatch, void()); - }; - - class MockSliceInstance - : public AZ::SliceComponent::SliceInstance - { - public: - using SliceInstance::SliceInstance; - - void SetMockInstantiatedContainer(AZ::SliceComponent::InstantiatedContainer* newContainer) - { - m_instantiated = newContainer; - - for (AZ::Entity* entity : m_instantiated->m_entities) - { - m_entityIdToBaseCache.insert(AZStd::make_pair(entity->GetId(), entity->GetId())); - } - - for (AZ::Entity* entity : m_instantiated->m_entities) - { - m_baseToNewEntityIdMap.insert(AZStd::make_pair(entity->GetId(), entity->GetId())); - } - } - - MOCK_CONST_METHOD0(GetInstantiated, const AZ::SliceComponent::InstantiatedContainer*()); - MOCK_CONST_METHOD0(GetDataPatch, const AZ::DataPatch&()); - MOCK_CONST_METHOD0(GetDataFlags, const AZ::SliceComponent::DataFlagsPerEntity&()); - MOCK_METHOD0(GetDataFlags, AZ::SliceComponent::DataFlagsPerEntity&()); - MOCK_CONST_METHOD0(GetEntityIdMap, const AZ::SliceComponent::EntityIdToEntityIdMap& ()); - MOCK_CONST_METHOD0(GetEntityIdToBaseMap, const AZ::SliceComponent::EntityIdToEntityIdMap& ()); - MOCK_CONST_METHOD0(GetId, const AZ::SliceComponent::SliceInstanceId& ()); - MOCK_CONST_METHOD0(GetMetadataEntity, AZ::Entity* ()); - }; - - class MockEntity - : public AZ::Entity - { - public: - ~MockEntity() override {} - - MOCK_METHOD0(Init, void ()); - MOCK_METHOD0(Activate, void ()); - MOCK_METHOD0(Deactivate, void ()); - - /** - * \brief Helper method for GoogleMock to call base class method - */ - void Base_Init() - { - Entity::Init(); - } - - /** - * \brief Helper method for GoogleMock to mark an entity as activated - */ - void Base_Activate() - { - m_state = State::Active; - } - - /** - * \brief Helper method for GoogleMock to mark an entity as deactivated - */ - void Base_Deactivate() - { - m_state = State::Init; - } - }; - - class MockComponentApplication - : public AZ::ComponentApplicationBus::Handler - { - public: - MockComponentApplication() - { - AZ::ComponentApplicationBus::Handler::BusConnect(); - AZ::Interface::Register(this); - } - ~MockComponentApplication() - { - AZ::Interface::Unregister(this); - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - } - - AZStd::vector m_mockEntities; - - bool AddEntity(AZ::Entity* entity) override - { - const auto it = AZStd::find(m_mockEntities.begin(), m_mockEntities.end(), entity); - if (it == m_mockEntities.end()) - { - m_mockEntities.push_back(entity); - return true; - } - - return false; - } - - AZ::Entity* FindEntity(const AZ::EntityId& id) override - { - const auto it = AZStd::find_if(m_mockEntities.begin(), m_mockEntities.end(), [id](AZ::Entity* entity) - { - return entity->GetId() == id; - }); - - if (it != m_mockEntities.end()) - { - return *it; - } - return nullptr; - } - - MOCK_METHOD0(Destroy, void ()); - MOCK_METHOD1(RegisterComponentDescriptor, void (const AZ::ComponentDescriptor*)); - MOCK_METHOD1(UnregisterComponentDescriptor, void (const AZ::ComponentDescriptor*)); - MOCK_METHOD1(RegisterEntityAddedEventHandler, void(AZ::EntityAddedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityRemovedEventHandler, void(AZ::EntityRemovedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityActivatedEventHandler, void(AZ::EntityActivatedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityDeactivatedEventHandler, void(AZ::EntityDeactivatedEvent::Handler&)); - MOCK_METHOD1(SignalEntityActivated, void(AZ::Entity*)); - MOCK_METHOD1(SignalEntityDeactivated, void(AZ::Entity*)); - MOCK_METHOD1(RemoveEntity, bool (AZ::Entity*)); - MOCK_METHOD1(DeleteEntity, bool (const AZ::EntityId&)); - MOCK_METHOD1(GetEntityName, AZStd::string (const AZ::EntityId&)); - MOCK_METHOD1(EnumerateEntities, void (const ComponentApplicationRequests::EntityCallback&)); - MOCK_METHOD0(GetApplication, AZ::ComponentApplication* ()); - MOCK_METHOD0(GetSerializeContext, AZ::SerializeContext* ()); - MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ()); - MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ()); - MOCK_CONST_METHOD0(GetAppRoot, const char* ()); - MOCK_CONST_METHOD0(GetEngineRoot, const char* ()); - MOCK_CONST_METHOD0(GetExecutableFolder, const char* ()); - MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ()); - MOCK_METHOD0(GetTickDeltaTime, float ()); - MOCK_METHOD0(GetTimeAtCurrentTick, AZ::ScriptTimePoint ()); - MOCK_METHOD1(Tick, void (float)); - MOCK_METHOD0(TickSystem, void ()); - MOCK_CONST_METHOD0(GetRequiredSystemComponents, AZ::ComponentTypeList ()); - MOCK_METHOD1(ResolveModulePath, void (AZ::OSString&)); - MOCK_METHOD0(RegisterCoreComponents, void ()); - MOCK_METHOD1(Reflect, void (AZ::ReflectContext*)); - MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&)); - }; - - class MockBindingComponent - : public AZ::Component - , public AzFramework::NetBindingHandlerBus::Handler - { - public: - AZ_COMPONENT(MockBindingComponent, "{8393809A-3256-4865-97A9-1CCA43073B4A}", NetBindingHandlerInterface); - - static void Reflect(AZ::ReflectContext*) {} - - MOCK_METHOD0(Init, void ()); - MOCK_METHOD0(Activate, void ()); - MOCK_METHOD0(Deactivate, void ()); - MOCK_METHOD1(ReadInConfig, bool (const AZ::ComponentConfig*)); - MOCK_CONST_METHOD1(WriteOutConfig, bool (AZ::ComponentConfig*)); - MOCK_METHOD1(BindToNetwork, void (GridMate::ReplicaPtr)); - MOCK_METHOD0(UnbindFromNetwork, void ()); - MOCK_METHOD0(IsEntityBoundToNetwork, bool ()); - MOCK_METHOD0(IsEntityAuthoritative, bool ()); - MOCK_METHOD0(MarkAsLevelSliceEntity, void ()); - MOCK_METHOD1(SetSliceInstanceId, void (const AZ::SliceComponent::SliceInstanceId&)); - MOCK_METHOD1(SetReplicaPriority, void (GridMate::ReplicaPriority)); - MOCK_METHOD1(RequestEntityChangeOwnership, void (GridMate::PeerId)); - MOCK_CONST_METHOD0(GetReplicaPriority, GridMate::ReplicaPriority ()); - }; -} - -#endif // AZCORE_UNITTEST_NETBINDINGMOCKS_H diff --git a/Code/Framework/Tests/NetBindingSystemImplTest.cpp b/Code/Framework/Tests/NetBindingSystemImplTest.cpp deleted file mode 100644 index 790ef1cd72..0000000000 --- a/Code/Framework/Tests/NetBindingSystemImplTest.cpp +++ /dev/null @@ -1,605 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include "NetBindingMocks.h" -#include -#include -#include -#include - -namespace UnitTest -{ - using namespace AZ; - using namespace AzFramework; - using namespace GridMate; - - class NetBindingWithSlicesTest - : public ScopedAllocatorSetupFixture - { - public: - const NetBindingContextSequence k_fakeContextSeq = 1; - const AZ::SliceComponent::SliceInstanceId k_fakeSliceInstanceId = Uuid::CreateRandom(); - const AZ::SliceComponent::SliceInstanceId k_fakeSliceInstanceId_Another = Uuid::CreateRandom(); - - SliceInstantiationTicket m_sliceTicket = SliceInstantiationTicket(EntityContextId::CreateName("Test"), 1); - const Data::AssetId k_fakeAssetId = Data::AssetId(Uuid::CreateRandom(), 0); - - const EntityId k_fakeEntityId_One = EntityId(9001); - const ReplicaId k_repId_One = 1001; - const EntityId k_fakeEntityId_Two = EntityId(9002); - const ReplicaId k_repId_Two = 1002; - - AZStd::unique_ptr m_netBindingImpl; - AZStd::unique_ptr m_componentApplication; - AZStd::unique_ptr m_applicationContext; - - AZStd::unique_ptr m_gameEntityMock; - AZStd::unique_ptr m_replicaManagerMock; - ReplicaPtr m_replicaMock; - - ComponentDescriptor* m_netBindingSystemComponentDescriptor = nullptr; - - AZStd::intrusive_ptr m_contextChunkMock; - - MockAssetHandler* m_myAssetHandlerAndCatalog = nullptr; // owned by AssetManager - AZStd::unique_ptr m_fakeAsset; - - const float k_wayOverSliceTimeout = NetBindingSystemImpl::s_sliceBindingTimeout.count() * 2.f; - const float k_smallStep = 0.1f; - - void SetUpFakeAssetManager() - { - using namespace testing; - - const Data::AssetManager::Descriptor desc; - Data::AssetManager::Create(desc); - - m_myAssetHandlerAndCatalog = aznew NiceMock; - - ON_CALL(*m_myAssetHandlerAndCatalog, CreateAsset(_, _)) - .WillByDefault(Invoke([this](const Data::AssetId&, const Data::AssetType&) -> Data::AssetPtr - { - m_fakeAsset = AZStd::make_unique>(k_fakeAssetId); - return m_fakeAsset.get(); - })); - - ON_CALL(*m_myAssetHandlerAndCatalog, DestroyAsset(_)) - .WillByDefault(Invoke([this](const Data::AssetPtr asset) - { - EXPECT_EQ(asset, m_fakeAsset.get()); - m_fakeAsset.reset(); - })); - - Data::AssetManager::Instance().RegisterHandler(m_myAssetHandlerAndCatalog, AzTypeInfo::Uuid()); - Data::AssetManager::Instance().RegisterHandler(m_myAssetHandlerAndCatalog, AzTypeInfo::Uuid()); - } - - void SetUp() override - { - using namespace testing; - - m_applicationContext.reset(aznew SerializeContext()); - - AllocatorInstance::Create(); - AllocatorInstance::Create(); - - DefaultValue::Set(m_sliceTicket); - - m_gameEntityMock = AZStd::make_unique>(); - m_componentApplication = AZStd::make_unique>(); - - ON_CALL(*m_componentApplication, GetSerializeContext()) - .WillByDefault(Invoke([this]() - { - return m_applicationContext.get(); - })); - - ON_CALL(*m_gameEntityMock, GetGameEntityContextId()) - .WillByDefault(Return(EntityContextId::CreateRandom())); - - m_netBindingSystemComponentDescriptor = NetBindingSystemComponent::CreateDescriptor(); - - ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - m_contextChunkMock.reset(CreateReplicaChunk>()); - - ON_CALL(*m_contextChunkMock, ShouldBindToNetwork()) - .WillByDefault(Return(true)); - - m_replicaManagerMock = AZStd::make_unique>(); - - ON_CALL(*m_contextChunkMock, GetReplicaManager()) - .WillByDefault(Invoke([this]() - { - return m_replicaManagerMock.get(); - })); - - m_replicaMock = Replica::CreateReplica("unittest"); - - ON_CALL(*m_replicaManagerMock, FindReplica(_)) - .WillByDefault(Invoke([this](ReplicaId id) -> ReplicaPtr - { - AZ_UNUSED(id); - return m_replicaMock; - })); - - ON_CALL(*m_contextChunkMock, OnReplicaActivate(_)) - .WillByDefault(Invoke(m_contextChunkMock.get(), &MockNetBindingSystemContextData::Base_OnReplicaActivate)); - - m_netBindingImpl = AZStd::make_unique(); - m_netBindingImpl->Init(); - - m_contextChunkMock->OnReplicaActivate(ReplicaContext(nullptr, TimeContext())); - - SetUpFakeAssetManager(); - } - - void TearDown() override - { - Data::AssetManager::Destroy(); - - m_replicaMock.reset(); - m_replicaManagerMock.reset(); - m_contextChunkMock.reset(); - - m_fakeAsset.reset(); - m_netBindingImpl->Shutdown(); - m_netBindingImpl.reset(); - - ReplicaChunkDescriptorTable::Get().UnregisterReplicaChunkDescriptor(ReplicaChunkClassId(MockNetBindingSystemContextData::GetChunkName())); - - m_netBindingSystemComponentDescriptor->ReleaseDescriptor(); - - m_componentApplication.reset(); - m_gameEntityMock.reset(); - - AllocatorInstance::Destroy(); - AllocatorInstance::Destroy(); - - m_applicationContext.reset(); - } - }; - - TEST_F(NetBindingWithSlicesTest, SameSliceInstanceId_InstantiateDynamicSlice_CallOnce) - { - using namespace testing; - - EXPECT_CALL(*m_gameEntityMock, InstantiateDynamicSlice(_, _, _)) - .Times(1); - EXPECT_CALL(*m_gameEntityMock, CancelDynamicSliceInstantiation(_)) - .Times(1); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - // this should kick off NetBindingSystemImpl::ProcessBindRequests - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } - - TEST_F(NetBindingWithSlicesTest, DifferentSliceInstanceId_InstantiateDynamicSlice_CalledTwice) - { - using namespace testing; - - EXPECT_CALL(*m_gameEntityMock, InstantiateDynamicSlice(_, _, _)) - .Times(2); - EXPECT_CALL(*m_gameEntityMock, CancelDynamicSliceInstantiation(_)) - .Times(2); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId_Another; // different slice entity - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - // this should kick off NetBindingSystemImpl::ProcessBindRequests - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } - - TEST_F(NetBindingWithSlicesTest, AssetManagerDestroyed_InstantiateDynamicSlice_NotCalled) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - Data::AssetManager::Destroy(); - - // this should kick off NetBindingSystemImpl::ProcessBindRequests, but InstantiateDynamicSlice will not be called - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } - - class ExtendedBindingWithSlicesTest - : public NetBindingWithSlicesTest - { - public: - void SetUp() override - { - NetBindingWithSlicesTest::SetUp(); - } - - void TearDown() override - { - using namespace testing; - - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_One)) - .Times(AtMost(1)); - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(AtMost(1)); - - NetBindingWithSlicesTest::TearDown(); - } - - class InstantiateMockSlice - { - public: - explicit InstantiateMockSlice(ExtendedBindingWithSlicesTest* parent) - { - using namespace testing; - - m_mockSliceRef = AZStd::make_unique(); - m_mockSliceInstance = AZStd::make_unique(); - - // container owns the entities and will delete them - auto mockContainer = AZStd::make_unique(); - - auto binding1 = AZStd::make_unique>(); - mockContainer->m_entities.push_back(CreateMockEntity(parent->k_fakeEntityId_One, binding1.release())); - - auto binding2 = AZStd::make_unique>(); - mockContainer->m_entities.push_back(CreateMockEntity(parent->k_fakeEntityId_Two, binding2.release())); - - m_mockSliceInstance->SetMockInstantiatedContainer(mockContainer.release()); - - SliceComponent::SliceInstanceAddress sliceInstanceAddress(m_mockSliceRef.get(), m_mockSliceInstance.get()); - - // This will pass our mock slice to NetBindingSystem - EBUS_EVENT_ID(parent->m_sliceTicket, SliceInstantiationResultBus, OnSlicePreInstantiate, parent->k_fakeAssetId, sliceInstanceAddress); - EBUS_EVENT_ID(parent->m_sliceTicket, SliceInstantiationResultBus, OnSliceInstantiated, parent->k_fakeAssetId, sliceInstanceAddress); - } - - Entity* CreateMockEntity(const EntityId& id, Component* optional = nullptr) - { - using namespace testing; - - auto mock = AZStd::make_unique>(); - mock->SetId(EntityId(id)); - if (optional) - { - mock->AddComponent(optional); // entity owns the component - } - ON_CALL(*mock, Init()) - .WillByDefault(Invoke(mock.get(), &MockEntity::Base_Init)); - mock->Init(); - - ON_CALL(*mock, Activate()) - .WillByDefault(Invoke(mock.get(), &MockEntity::Base_Activate)); - - ON_CALL(*mock, Deactivate()) - .WillByDefault(Invoke(mock.get(), &MockEntity::Base_Deactivate)); - - return mock.release(); - } - - AZStd::unique_ptr m_mockSliceRef; - AZStd::unique_ptr m_mockSliceInstance; - }; - - AZStd::unique_ptr m_slice; - - void CreateMockSlice() - { - m_slice = AZStd::make_unique(this); - } - }; - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_EntitiesThatWerentBounded_StayDeactivated) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - CreateMockSlice(); - - MockEntity* mock1 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_One)); - EXPECT_CALL(*mock1, Activate()). - Times(1); - - MockEntity* mock2 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_Two)); - EXPECT_CALL(*mock2, Activate()). - Times(0); - - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(0); - - // Now it should time out the slice handler and the second entity should remain deactivated since we didn't give binding request for it - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - - } - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_SpawnSecondEntity_AfterLongDelay_InSameSlicenInstance) - { - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(0); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - CreateMockSlice(); - - MockEntity* mock2 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_Two)); - EXPECT_CALL(*mock2, Activate()). - Times(0); - - // This should not trigger removal of the second entity yet - auto halfTimeoutInSeconds = AZStd::chrono::seconds(NetBindingSystemImpl::s_sliceBindingTimeout).count() * 10.f; - EBUS_EVENT(AZ::TickBus, OnTick, halfTimeoutInSeconds, AZ::ScriptTimePoint()); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - EXPECT_CALL(*mock2, Activate()). - Times(1); - - // This should give net binding system time to bind the second entity - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - // Let the slice timeout, this should lead to no destruction since both entities ought to have been bound by now - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - } - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_DespawnLastEntity_DespawnWholeSliceAfterTimeout) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - CreateMockSlice(); - - MockEntity* mock1 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_One)); - EXPECT_CALL(*mock1, Activate()). - Times(1); - - // This should not trigger removal of the second entity yet - auto halfTimeoutInSeconds = AZStd::chrono::seconds(NetBindingSystemImpl::s_sliceBindingTimeout).count() * 10.f; - EBUS_EVENT(AZ::TickBus, OnTick, halfTimeoutInSeconds, AZ::ScriptTimePoint()); - - EXPECT_CALL(*mock1, Deactivate()). - Times(1); - EBUS_EVENT(NetBindingSystemBus, UnbindGameEntity, k_fakeEntityId_One, k_fakeSliceInstanceId); - - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_One)) - .Times(1); - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(1); - - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - } - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_DespawnLastEntityBeforeSliceInstantiation_DespawnWholeSlice) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - EBUS_EVENT(NetBindingSystemBus, UnbindGameEntity, k_fakeEntityId_One, k_fakeSliceInstanceId); - - CreateMockSlice(); - - MockEntity* mock1 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_One)); - EXPECT_CALL(*mock1, Activate()). - Times(0); - - auto halfTimeoutInSeconds = AZStd::chrono::seconds(NetBindingSystemImpl::s_sliceBindingTimeout).count() * 10.f; - EBUS_EVENT(AZ::TickBus, OnTick, halfTimeoutInSeconds, AZ::ScriptTimePoint()); - - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - } - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_ReuseEntity) - { - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(0); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - CreateMockSlice(); - - MockEntity* mock2 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_Two)); - EXPECT_CALL(*mock2, Activate()). - Times(1); - - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - - EXPECT_CALL(*mock2, Deactivate()). - Times(1); - - // some time later the second entity goes away and comes back - EBUS_EVENT(NetBindingSystemBus, UnbindGameEntity, k_fakeEntityId_Two, k_fakeSliceInstanceId); - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - // The same entity should be activated for the second time - EXPECT_CALL(*mock2, Activate()). - Times(1); // Note, Google Mock treats each expect_call separately and satisfies them separately. That's why it's 1 here, despite being a second call. - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } - - TEST_F(ExtendedBindingWithSlicesTest, SliceFailedToSpawn) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - EBUS_EVENT_ID(m_sliceTicket, SliceInstantiationResultBus, OnSliceInstantiationFailed, k_fakeAssetId); - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - EXPECT_TRUE(m_componentApplication->FindEntity(k_fakeEntityId_One) == nullptr); - } - - TEST_F(ExtendedBindingWithSlicesTest, SliceSpawned_AfterTimeout) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - - CreateMockSlice(); - - MockEntity* mock1 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_One)); - EXPECT_CALL(*mock1, Activate()). - Times(1); - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } -} diff --git a/Code/Framework/Tests/NetworkContext.cpp b/Code/Framework/Tests/NetworkContext.cpp deleted file mode 100644 index 5af9ca70d8..0000000000 --- a/Code/Framework/Tests/NetworkContext.cpp +++ /dev/null @@ -1,801 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace UnitTest -{ - using namespace AZ; - using namespace AzFramework; - - class TestComponentExternalChunk - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponentExternalChunk, "{73BB3B15-7C4D-4BD5-9568-F3B2DCBC7725}", AZ::Component); - - static void Reflect(ReflectContext* context); - - void Init() override - { - NetBindable::NetInit(); - } - - void Activate() override {} - void Deactivate() override {} - - bool SetPos(float x, float y, const RpcContext&) - { - m_x = x; - m_y = y; - return true; - } - - void OnFloatChanged(const float&, const TimeContext&) - { - m_floatChanged = true; - } - - bool m_floatChanged = false; - private: - float m_x = 0, m_y = 0; - }; - - class TestComponentReplicaChunk - : public ReplicaChunkBase - , public ReplicaChunkInterface - { - public: - GM_CLASS_ALLOCATOR(TestComponentReplicaChunk); - static const char* GetChunkName() { return "TestComponentReplicaChunk"; } - bool IsReplicaMigratable() override { return true; } - - public: - TestComponentReplicaChunk() - : m_int("m_int", 42) - , m_float("m_float", 96.4f) - , SetInt("SetInt") - , SetPos("SetPos") - { - } - - bool SetIntImpl(int newValue, const RpcContext&) - { - m_int.Set(newValue); - return true; - } - - DataSet m_int; - DataSet::BindInterface m_float; - GridMate::Rpc > >::BindInterface SetInt; - GridMate::Rpc, GridMate::RpcArg >::BindInterface SetPos; - }; - - void TestComponentExternalChunk::Reflect(ReflectContext* context) - { - NetworkContext* netContext = azrtti_cast(context); - if (netContext) - { - netContext->Class() - ->Chunk() - ->Field("m_int", &TestComponentReplicaChunk::m_int) - ->Field("m_float", &TestComponentReplicaChunk::m_float) - ->RPC("SetInt", &TestComponentReplicaChunk::SetInt) - ->RPC("SetPos", &TestComponentReplicaChunk::SetPos); - } - } - - class TestComponentAutoChunk - : public AZ::Component - , public NetBindable - { - public: - enum TestEnum - { - TEST_Value0 = 0, - TEST_Value1 = 1, - TEST_Value255 = 255 - }; - - AZ_COMPONENT(TestComponentAutoChunk, "{003FD1BC-8456-43D5-9879-1B3804327A4F}", AZ::Component); - - static void Reflect(ReflectContext* context) - { - NetworkContext* netContext = azrtti_cast(context); - if (netContext) - { - netContext->Class() - ->Field("m_int", &TestComponentAutoChunk::m_int) - ->Field("m_float", &TestComponentAutoChunk::m_float) - ->Field("m_enum", &TestComponentAutoChunk::m_enum) - ->RPC("SetInt", &TestComponentAutoChunk::SetInt) - ->CtorData("CtorInt", &TestComponentAutoChunk::GetCtorInt, &TestComponentAutoChunk::SetCtorInt) - ->CtorData("CtorVec", &TestComponentAutoChunk::GetCtorVec, &TestComponentAutoChunk::SetCtorVec); - } - SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("m_int", &TestComponentAutoChunk::m_int) - ->Field("m_float", &TestComponentAutoChunk::m_float) - ->Field("m_enum", &TestComponentAutoChunk::m_enum) - ->Field("ctorInt", &TestComponentAutoChunk::m_ctorInt) - ->Field("ctorVec", &TestComponentAutoChunk::m_ctorVec); - } - } - - void Init() override - { - NetBindable::NetInit(); - } - - void Activate() override {} - void Deactivate() override {} - - void SetNetworkBinding(ReplicaChunkPtr chunk) override {} - void UnbindFromNetwork() override {} - - bool SetIntImpl(int val, const RpcContext&) - { - m_int = val; - return true; - } - - void OnFloatChanged(const float&, const TimeContext&) - { - } - - int GetCtorInt() const { return m_ctorInt; } - void SetCtorInt(const int& ctorInt) { m_ctorInt = ctorInt; } - - AZStd::vector& GetCtorVec() { return m_ctorVec; } - void SetCtorVec(const AZStd::vector& vec) { m_ctorVec = vec; } - - int m_ctorInt; - AZStd::vector m_ctorVec; - Field m_int; - BoundField m_float; - Field > m_enum; - Rpc::Binder SetInt; - }; - - class NetContextReflectionTest - : public AllocatorsTestFixture - { - public: - void SetUp() override - { - AllocatorsTestFixture::SetUp(); - - AZ::AllocatorInstance::Create(); - } - - void TearDown() override - { - AZ::AllocatorInstance::Destroy(); - - AllocatorsTestFixture::TearDown(); - } - - void run() - { - AzFramework::Application app; - AzFramework::Application::Descriptor appDesc; - appDesc.m_recordingMode = Debug::AllocationRecords::RECORD_NO_RECORDS; - appDesc.m_allocationRecords = false; - appDesc.m_enableDrilling = false; - - app.Start(appDesc); - - // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is - // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash - // in the unit tests. - AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - - AzFramework::NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_TEST_ASSERT(netContext); - - AZ::ComponentDescriptor* descTestComponentExternalChunk = TestComponentExternalChunk::CreateDescriptor(); - app.RegisterComponentDescriptor(descTestComponentExternalChunk); - - AZ::ComponentDescriptor* descTestComponentAutoChunk = TestComponentAutoChunk::CreateDescriptor(); - app.RegisterComponentDescriptor(descTestComponentAutoChunk); - - AZ::Entity* testEntity = aznew AZ::Entity("TestEntity"); - testEntity->Init(); - testEntity->CreateComponent(); - testEntity->CreateComponent(); - testEntity->Activate(); - - // test field binding/auto reflection/creation - { - TestComponentAutoChunk* testComponent = testEntity->FindComponent(); - AZ_TEST_ASSERT(testComponent); - - testComponent->SetInt(2048); // should happen locally - AZ_TEST_ASSERT(testComponent->m_int == 2048); - - ReplicaChunkPtr chunk = testComponent->GetNetworkBinding(); - AZ_TEST_ASSERT(chunk); - - GridMate::ReplicaChunkDescriptor* desc = chunk->GetDescriptor(); - AZ_TEST_ASSERT(desc); - - testComponent->m_ctorInt = 8192; - for (int n = 0; n < 16; ++n) - { - testComponent->m_ctorVec.push_back(n); - } - - GridMate::WriteBufferDynamic wb(GridMate::EndianType::IgnoreEndian); - desc->MarshalCtorData(chunk.get(), wb); - - { - // Create a chunk from the recorded ctor data, ensure that it stores - // the ctor data in preparation for copying it to the instance - GridMate::TimeContext tc; - GridMate::ReplicaContext rc(nullptr, tc); - GridMate::ReadBuffer rb(wb.GetEndianType(), wb.Get(), wb.Size()); - GridMate::UnmarshalContext ctx(rc); - ctx.m_hasCtorData = true; - ctx.m_iBuf = &rb; - ReplicaChunkPtr chunk2 = desc->CreateFromStream(ctx); - AZ_TEST_ASSERT(chunk2); // ensure a new chunk was created - ReflectedReplicaChunkBase* refChunk = static_cast(chunk2.get()); - AZ_TEST_ASSERT(refChunk->m_ctorBuffer.Size() == sizeof(int) + sizeof(AZ::u16) + (sizeof(int) * testComponent->m_ctorVec.size())); - } - - { - // discard a ctor data stream and ensure that the stream is emptied - GridMate::TimeContext tc; - GridMate::ReplicaContext rc(nullptr, tc); - GridMate::ReadBuffer rb(wb.GetEndianType(), wb.Get(), wb.Size()); - GridMate::UnmarshalContext ctx(rc); - ctx.m_hasCtorData = true; - ctx.m_iBuf = &rb; - desc->DiscardCtorStream(ctx); - AZ_TEST_ASSERT(rb.IsEmptyIgnoreTrailingBits()); // should have discarded the whole stream - } - - { - // Make another chunk and bind it to a new component and make sure the ctor data matches - AZ::Entity* testEntity2 = aznew AZ::Entity("TestEntity2"); - testEntity2->Init(); - testEntity2->CreateComponent(); - testEntity2->Activate(); - - GridMate::TimeContext tc; - GridMate::ReplicaContext rc(nullptr, tc); - GridMate::ReadBuffer rb(wb.GetEndianType(), wb.Get(), wb.Size()); - GridMate::UnmarshalContext ctx(rc); - ctx.m_hasCtorData = true; - ctx.m_iBuf = &rb; - ReplicaChunkPtr chunk2 = desc->CreateFromStream(ctx); - - TestComponentAutoChunk* testComponent2 = testEntity2->FindComponent(); - netContext->Bind(testComponent2, chunk2, NetworkContextBindMode::NonAuthoritative); - // Ensure values match after ctor data is applied - AZ_TEST_ASSERT(testComponent2->m_ctorInt == testComponent->m_ctorInt); - AZ_TEST_ASSERT(testComponent2->m_ctorVec == testComponent->m_ctorVec); - } - - testComponent->SetInt(4096); - AZ_TEST_ASSERT(testComponent->m_int == 4096); - - testComponent->m_int = 42; // now it should change - AZ_TEST_ASSERT(testComponent->m_int == 42); - testComponent->m_enum = TestComponentAutoChunk::TEST_Value1; - - chunk.reset(); // should cause netContext->DestroyReplicaChunk() - } - - // test chunk binding/creation - { - TestComponentExternalChunk* testComponent = testEntity->FindComponent(); - AZ_TEST_ASSERT(testComponent); - - ReplicaChunkPtr chunk = testComponent->GetNetworkBinding(); - AZ_TEST_ASSERT(chunk); - - TestComponentReplicaChunk* testChunk = static_cast(chunk.get()); - - // for now, this will throw a warning, but will at least attempt the dispatch - testChunk->SetPos(42.0f, 96.0f); - - AZ_TEST_ASSERT(testComponent->m_floatChanged == false); - testChunk->m_float.Set(1024.0f); - // I would like to test that the notify fired, but without a Replica, cant :( - - testComponent->UnbindFromNetwork(); - chunk.reset(); ///// CRASHES FROM HERE - } - - // test serialization of NetBindable::Fields - { - TestComponentAutoChunk* testComponent = testEntity->FindComponent(); - AZStd::vector buffer; - AZ::IO::ByteContainerStream > saveStream(&buffer); - bool saved = AZ::Utils::SaveObjectToStream(saveStream, AZ::DataStream::ST_XML, testComponent); - AZ_TEST_ASSERT(saved); - AZ::IO::ByteContainerStream > loadStream(&buffer); - TestComponentAutoChunk* testCopy = AZ::Utils::LoadObjectFromStream(loadStream); - AZ_TEST_ASSERT(testCopy); - delete testCopy; - } - - testEntity->Deactivate(); - delete testEntity; - - descTestComponentExternalChunk->ReleaseDescriptor(); - descTestComponentAutoChunk->ReleaseDescriptor(); - - app.Stop(); - } - }; - - TEST_F(NetContextReflectionTest, Test) - { - run(); - } - - template - class NetContextFixture - : public ::testing::Test - { - public: - NetContextFixture() = default; - ~NetContextFixture() = default; - - void SetUp() override - { - AZ::AllocatorInstance::Create(); - - m_app = AZStd::make_unique(); - m_app->Start(AzFramework::Application::Descriptor()); - - // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is - // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash - // in the unit tests. - AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - - AzFramework::NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_TEST_ASSERT(netContext); - - m_descTestComponentAutoChunk = ComponentType::CreateDescriptor(); - m_app->RegisterComponentDescriptor(m_descTestComponentAutoChunk); - - m_entity = AZStd::make_unique("TestEntity"); - m_entity->Init(); - m_entity->CreateComponent(); - m_entity->Activate(); - } - - void TearDown() override - { - m_descTestComponentAutoChunk->ReleaseDescriptor(); - - m_entity->Deactivate(); - m_entity.reset(); - - m_app->Stop(); - m_app.reset(); - - AZ::AllocatorInstance::Destroy(); - } - - void RunTest() - { - const ComponentType* testComponent = m_entity->FindComponent(); - AZStd::vector buffer; - AZ::IO::ByteContainerStream > saveStream(&buffer); - const bool saved = AZ::Utils::SaveObjectToStream(saveStream, AZ::DataStream::ST_XML, testComponent); - AZ_TEST_ASSERT(saved); - AZ::IO::ByteContainerStream > loadStream(&buffer); - const AZStd::unique_ptr testCopy(AZ::Utils::LoadObjectFromStream(loadStream)); - AZ_TEST_ASSERT(testCopy); - } - - AZStd::unique_ptr m_app; - AZStd::unique_ptr m_entity; - AZ::ComponentDescriptor* m_descTestComponentAutoChunk = nullptr; - }; - - class TestComponent_EmptyNetContext - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponent_EmptyNetContext, "{B1E2E2DD-DA70-4D59-A185-AF9A5CCF1574}", AZ::Component, NetBindable); - - static void Reflect(ReflectContext* context) - { - if (SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1); - } - if (NetworkContext* netContext = azrtti_cast(context)) - { - netContext->Class(); - } - } - - void Activate() override {} - void Deactivate() override {} - }; - - using NetContextEmpty = NetContextFixture; - TEST_F(NetContextEmpty, SerializationTests) - { - RunTest(); - } - - template - class TestComponent_OneField - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponent_OneField, "{A7BCDBEF-3D4F-4D04-A6FA-DF48D4B66ABE}", AZ::Component, NetBindable); - - using ThisComponentType = TestComponent_OneField; - - static void Reflect(ReflectContext* context) - { - if (SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Field("Field", &TestComponent_OneField::m_field) - ->Version(1); - } - if (NetworkContext* netContext = azrtti_cast(context)) - { - netContext->Class() - ->Field("Field", &TestComponent_OneField::m_field); - } - } - - void Activate() override {} - void Deactivate() override {} - - Field m_field; - }; - - TYPED_TEST_CASE_P(NetContextFixture); - - TYPED_TEST_P(NetContextFixture, SerializationTests) - { - this->RunTest(); - } - - REGISTER_TYPED_TEST_CASE_P(NetContextFixture, SerializationTests); - - /* - * Testing the basic common types. - */ - using CommonTypes = ::testing::Types< - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField - >; - - INSTANTIATE_TYPED_TEST_CASE_P(NetContextCommonSerialization, NetContextFixture, CommonTypes); - - /* - * And some less common types. - */ - using LessCommonTypes = ::testing::Types< - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField>, - TestComponent_OneField - >; - - INSTANTIATE_TYPED_TEST_CASE_P(NetContextLessCommonSerialization, NetContextFixture, LessCommonTypes); - - /* - * Next up are marshal and unmarshal tests. - */ - - template - class NetContextMarshalFixture - : public UnitTest::AllocatorsTestFixture - { - public: - NetContextMarshalFixture() = default; - ~NetContextMarshalFixture() = default; - - void SetUp() override - { - UnitTest::AllocatorsTestFixture::SetUp(); - - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - m_app = AZStd::make_unique(); - m_app->Start(AzFramework::Application::Descriptor()); - - // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is - // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash - // in the unit tests. - AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - - AzFramework::NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_TEST_ASSERT(netContext); - - m_descTestComponentAutoChunk = ComponentType::CreateDescriptor(); - m_app->RegisterComponentDescriptor(m_descTestComponentAutoChunk); - - m_entityFrom = AZStd::make_unique("TestEntityFrom"); - m_entityFrom->Init(); - m_componentFrom = m_entityFrom->CreateComponent(); - m_entityFrom->Activate(); - - m_entityTo = AZStd::make_unique("TestEntityTo"); - m_entityTo->Init(); - m_componentTo = m_entityTo->CreateComponent(); - m_entityTo->Activate(); - } - - void MarshalUnMarshal() - { - AzFramework::NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_TEST_ASSERT(netContext); - - ComponentType* testComponent = m_entityFrom->FindComponent(); - AZ_TEST_ASSERT(testComponent); - ReplicaChunkPtr chunk = testComponent->GetNetworkBinding(); - AZ_TEST_ASSERT(chunk); - - m_outReplica = AZStd::make_unique("ReplicaTo"); - { - m_outManager = AZStd::make_unique(); - m_outPeer = AZStd::make_unique(m_outManager.get()); - - GridMate::WriteBufferDynamic wb(GridMate::EndianType::IgnoreEndian); - { - GridMate::TimeContext tc; - const GridMate::ReplicaContext rc(nullptr, tc); - GridMate::MarshalContext mc(GridMate::ReplicaMarshalFlags::FullSync, &wb, nullptr, rc); - mc.m_peer = m_outPeer.get(); - mc.m_rm = m_outManager.get(); - chunk->Debug_PrepareData(wb.GetEndianType(), GridMate::ReplicaMarshalFlags::FullSync); - chunk->Debug_Marshal(mc, 0); - } - - // and now unmarshal into the other entity - { - GridMate::TimeContext tc; - const GridMate::ReplicaContext rc(nullptr, tc); - GridMate::ReadBuffer rb(wb.GetEndianType(), wb.Get(), wb.Size()); - GridMate::UnmarshalContext ctx(rc); - ctx.m_hasCtorData = false; - ctx.m_iBuf = &rb; - ctx.m_peer = m_outPeer.get(); - ctx.m_rm = m_outManager.get(); - m_outReplicaChunk = chunk->GetDescriptor()->CreateFromStream(ctx); - - m_outReplicaChunk->Debug_AttachedToReplica(m_outReplica.get()); - ctx.m_peer->Debug_Add(m_outReplica.get()); - m_outReplicaChunk->Debug_Unmarshal(ctx, 0); - /* - * Note the order: unmarshal first to populate the chunk with data, then apply it to a component. - * The expectation is that the valid will apply to NetBindable::Field without being overwritten. - */ - m_componentTo->SetNetworkBinding(m_outReplicaChunk); - - // the main test body can now test for the equality - } - } - } - - void TearDown() override - { - m_outReplicaChunk.reset(); - m_outManager.reset(); - m_outPeer.reset(); - m_outReplica.release(); // Replica is held by as an intrusive pointer in @m_outPeer and is destroyed there. - - if (m_entityFrom) - { - m_entityFrom->Deactivate(); - m_entityFrom.reset(); - } - - if (m_entityTo) - { - m_entityTo->Deactivate(); - m_entityTo.reset(); - } - - m_descTestComponentAutoChunk->ReleaseDescriptor(); - - m_app->Stop(); - m_app.reset(); - - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - - UnitTest::AllocatorsTestFixture::TearDown(); - } - - AZStd::unique_ptr m_app; - AZStd::unique_ptr m_entityFrom; - AZStd::unique_ptr m_entityTo; - - ComponentType* m_componentFrom = nullptr; - ComponentType* m_componentTo = nullptr; - - AZ::ComponentDescriptor* m_descTestComponentAutoChunk = nullptr; - - GridMate::ReplicaChunkPtr m_outReplicaChunk; - AZStd::unique_ptr m_outReplica; - AZStd::unique_ptr m_outManager; - AZStd::unique_ptr m_outPeer; - }; - - using NetContextVector3 = NetContextMarshalFixture>; - TEST_F(NetContextVector3, SerializationTests) - { - const Vector3 value = AZ::Vector3::CreateAxisZ( 1.f ); - - m_componentFrom->m_field = value; - MarshalUnMarshal(); - - AZ_TEST_ASSERT(m_componentTo->m_field.Get() == value); - } - - /* - * Now the same test but with NetBindable::BoundField<> - */ - - template - class TestComponent_OneBoundField - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponent_OneBoundField, "{2B283821-41DF-46BB-BE8E-66EF7301B62A}", AZ::Component, NetBindable); - - using ThisComponentType = TestComponent_OneBoundField; - - static void Reflect(ReflectContext* context) - { - if (SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Field("Field", &ThisComponentType::m_boundField) - ->Version(1); - } - if (NetworkContext* netContext = azrtti_cast(context)) - { - netContext->Class() - ->Field("Field", &ThisComponentType::m_boundField); - } - } - - void Activate() override {} - void Deactivate() override {} - - void OnBoundFieldChanged( const FieldType&, const GridMate::TimeContext& ) {} - - BoundField m_boundField; - }; - - using NetContextBoundVector2 = NetContextMarshalFixture>; - TEST_F(NetContextBoundVector2, SerializationTests) - { - const Vector2 value = AZ::Vector2::CreateAxisX( 4.f ); - - m_componentFrom->m_boundField = value; - MarshalUnMarshal(); - - AZ_TEST_ASSERT(m_componentTo->m_boundField.Get() == value); - } - - TEST_F(NetContextBoundVector2, Delete_Authoritative_Entity) - { - using ThisComponentType = TestComponent_OneBoundField; - - AzFramework::NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_TEST_ASSERT(netContext); - ThisComponentType* testComponent = m_entityFrom->FindComponent(); - AZ_TEST_ASSERT(testComponent); - ReplicaChunkPtr chunk = testComponent->GetNetworkBinding(); - - // Testing early deletion of an entity on the server. - m_entityFrom->Deactivate(); - m_entityFrom.reset(); - - // This test passes if it doesn't crash on cleanup. - chunk.reset(); - } - - template - class TestComponent_OneBoundField_ServerCallback - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponent_OneBoundField_ServerCallback, "{74F5B232-0544-45CA-B207-9846052ED1AD}", AZ::Component, NetBindable); - - using ThisComponentType = TestComponent_OneBoundField_ServerCallback; - - static void Reflect(ReflectContext* context) - { - if (SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Field("Field", &ThisComponentType::m_boundField) - ->Version(1); - } - if (NetworkContext* netContext = azrtti_cast(context)) - { - netContext->Class() - ->Field("Field", &ThisComponentType::m_boundField); - } - } - - void Activate() override {} - void Deactivate() override {} - - void OnBoundFieldChanged( const FieldType&, const GridMate::TimeContext& ) - { - ++m_callbacksInvokeCount; - } - - AZ::u8 m_callbacksInvokeCount = 0; - - BoundField m_boundField; - }; - - using NetContextBoundVector2WithCallbackCount = NetContextMarshalFixture>; - TEST_F(NetContextBoundVector2WithCallbackCount, BoundField_Invoke_OnServer_Test) - { - MarshalUnMarshal(); - - m_componentFrom->m_callbacksInvokeCount = 0; // resetting the count - - const Vector2 value = AZ::Vector2::CreateAxisX( 4.f ); - m_componentFrom->m_boundField = value; - - AZ_TEST_ASSERT(m_componentFrom->m_callbacksInvokeCount == 1); - } -} diff --git a/Code/Framework/Tests/NetworkMarshal.cpp b/Code/Framework/Tests/NetworkMarshal.cpp deleted file mode 100644 index e9c8b336f6..0000000000 --- a/Code/Framework/Tests/NetworkMarshal.cpp +++ /dev/null @@ -1,552 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "TestTypes.h" - -#include -#include -#include -#include - -#include - -namespace UnitTest -{ - template - class MarshalerTester - : public AllocatorsFixture - { - public: - MarshalerTester() - : m_writeBuffer(GridMate::EndianType::BigEndian) - , m_readBuffer(GridMate::EndianType::BigEndian) - { - } - - void SetUp() override - { - AllocatorsFixture::SetUp(); - m_random.SetSeed(AZStd::chrono::milliseconds().count()); - } - - void PopulateReadBuffer() - { - m_readBuffer = GridMate::ReadBuffer(m_writeBuffer.GetEndianType(), m_writeBuffer.Get(), m_writeBuffer.Size()); - } - - AZ::SimpleLcgRandom m_random; - - GridMate::Marshaler m_marshaler; - GridMate::WriteBufferStatic<> m_writeBuffer; - GridMate::ReadBuffer m_readBuffer; - }; - - // EntityIdMarshalerTest - typedef MarshalerTester EntityIdMarshalerTest; - - TEST_F(EntityIdMarshalerTest, SingleMarshalUnmarshalTest_EquivalentEmptyValue) - { - AZ::EntityId initialId; - m_marshaler.Marshal(m_writeBuffer, initialId); - - PopulateReadBuffer(); - - AZ::EntityId receivedId; - m_marshaler.Unmarshal(receivedId, m_readBuffer); - - EXPECT_EQ(initialId,receivedId); - EXPECT_FALSE(receivedId.IsValid()); - } - - TEST_F(EntityIdMarshalerTest, SingleMarshalUnmarshalTest_EquivalentRandomValue) - { - AZ::EntityId initialId = AZ::EntityId(m_random.GetRandom()); - m_marshaler.Marshal(m_writeBuffer, initialId); - - PopulateReadBuffer(); - - AZ::EntityId receivedId; - m_marshaler.Unmarshal(receivedId, m_readBuffer); - - EXPECT_EQ(initialId,receivedId); - } - - TEST_F(EntityIdMarshalerTest, MultipleMarshalUnmarshalTest_EquivalentEmptyRandomEmptyRandomValueChain) - { - AZ::EntityId sentId1_empty; - AZ::EntityId sentId2_random = AZ::EntityId(m_random.GetRandom()); - AZ::EntityId sentId3_empty; - AZ::EntityId sentId4_random = AZ::EntityId(m_random.GetRandom()); - - m_marshaler.Marshal(m_writeBuffer, sentId1_empty); - m_marshaler.Marshal(m_writeBuffer, sentId2_random); - m_marshaler.Marshal(m_writeBuffer, sentId3_empty); - m_marshaler.Marshal(m_writeBuffer, sentId4_random); - - PopulateReadBuffer(); - - AZ::EntityId receivedId1_empty; - AZ::EntityId receivedId2_random; - AZ::EntityId receivedId3_empty; - AZ::EntityId receivedId4_random; - - m_marshaler.Unmarshal(receivedId1_empty, m_readBuffer); - m_marshaler.Unmarshal(receivedId2_random, m_readBuffer); - m_marshaler.Unmarshal(receivedId3_empty, m_readBuffer); - m_marshaler.Unmarshal(receivedId4_random, m_readBuffer); - - EXPECT_EQ(sentId1_empty, receivedId1_empty); - EXPECT_EQ(sentId2_random, receivedId2_random); - EXPECT_EQ(sentId3_empty, receivedId3_empty); - EXPECT_EQ(sentId4_random, receivedId4_random); - } - - // AZ::DynamicSerializableFieldMarshaler - class FooSerializable - { - public: - AZ_RTTI(FooSerializable, "{A60F0B2B-6085-4FF1-BD17-A0B0143BB03D}"); - AZ_CLASS_ALLOCATOR(FooSerializable, AZ::SystemAllocator,0); - - static void Reflect(AZ::SerializeContext& serializeContext) - { - serializeContext.Class() - ->Version(1) - ->Field("IntValue", &FooSerializable::m_intValue) - ->Field("FloatValue", &FooSerializable::m_floatValue) - ; - } - - FooSerializable() - : m_intValue(0) - , m_floatValue(0.0f) - { - } - - bool operator==(const FooSerializable& other) const - { - return m_intValue == other.m_intValue && AZ::IsClose(m_floatValue, other.m_floatValue,0.0001f); - } - - AZ::u32 m_intValue; - float m_floatValue; - }; - - class BarSerializable - { - public: - AZ_RTTI(BarSerializable, "{2389C23F-D247-420B-A385-71AB8455CD2E}"); - AZ_CLASS_ALLOCATOR(BarSerializable, AZ::SystemAllocator,0); - - static void Reflect(AZ::SerializeContext& serializeContext) - { - serializeContext.Class() - ->Version(1) - ->Field("LongValue", &BarSerializable::m_longValue) - ->Field("DoubleValue", &BarSerializable::m_doubleValue) - ; - } - - BarSerializable() - : m_longValue(0) - , m_doubleValue(0.0) - { - } - - bool operator==(const BarSerializable& other) const - { - return m_longValue == other.m_longValue && AZ::IsClose(m_doubleValue,other.m_doubleValue,0.0001); - } - - long m_longValue; - double m_doubleValue; - }; - - class ComplexSerializable - { - public: - AZ_RTTI(ComplexSerializable,"{055CB45C-702C-499F-8221-E9ABB21CF1D4}"); - AZ_CLASS_ALLOCATOR(ComplexSerializable, AZ::SystemAllocator,0); - - static void Reflect(AZ::SerializeContext& serializeContext) - { - serializeContext.Class() - ->Version(1) - ->Field("FooSerializable",&ComplexSerializable::m_fooField) - ->Field("BarSerializable",&ComplexSerializable::m_barField) - ; - } - - bool operator==(const ComplexSerializable& other) const - { - return m_fooField == other.m_fooField && m_barField == other.m_barField; - } - - FooSerializable m_fooField; - BarSerializable m_barField; - }; - - class DynamicSerializableFieldMarshalerTest - : public MarshalerTester - , public AZ::ComponentApplicationBus::Handler - { - public: - DynamicSerializableFieldMarshalerTest() - : MarshalerTester() - { - } - - void SetUp() override - { - MarshalerTester::SetUp(); - - FooSerializable::Reflect(m_serializeContext); - BarSerializable::Reflect(m_serializeContext); - ComplexSerializable::Reflect(m_serializeContext); - - // Create the Marshaler with access to our custom serialize context. - m_marshaler = GridMate::Marshaler(&m_serializeContext); - - AZ::ComponentApplicationBus::Handler::BusConnect(); - } - - void TearDown() override - { - MarshalerTester::TearDown(); - - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - } - - FooSerializable* GenerateFooSerializable() - { - FooSerializable* field = new FooSerializable(); - - RandomizeFooSerializable((*field)); - - return field; - } - - void RandomizeFooSerializable(FooSerializable& serializable) - { - serializable.m_intValue = m_random.GetRandom(); - serializable.m_floatValue = m_random.GetRandomFloat(); - } - - BarSerializable* GenerateBarSerializable() - { - BarSerializable* field = new BarSerializable(); - - return field; - } - - void RandomizeBarSerializable(BarSerializable& serializable) - { - serializable.m_longValue = static_cast(m_random.GetRandom()); - serializable.m_doubleValue = static_cast(m_random.GetRandomFloat()); - } - - ComplexSerializable* GenerateComplexSerializable() - { - ComplexSerializable* complexField = new ComplexSerializable(); - - RandomizeFooSerializable(complexField->m_fooField); - RandomizeBarSerializable(complexField->m_barField); - - return complexField; - } - - // Used Component Application Methods - AZ::SerializeContext* GetSerializeContext() { return &m_serializeContext; } - - // Unused ComponentApplication methods - void RegisterComponentDescriptor(const AZ::ComponentDescriptor* descriptor) override { (void)descriptor; AZ_Assert(false,"Unsupported method in Unit Test"); } - void UnregisterComponentDescriptor(const AZ::ComponentDescriptor* descriptor) override { (void)descriptor; AZ_Assert(false,"Unsupported method in Unit Test"); } - - AZ::ComponentApplication* GetApplication() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - bool AddEntity(AZ::Entity* entity) override { (void)entity; AZ_Assert(false,"Unsupported method in Unit Test"); return false; } - bool RemoveEntity(AZ::Entity* entity) override { (void)entity; AZ_Assert(false,"Unsupported method in Unit Test"); return false; } - bool DeleteEntity(const AZ::EntityId& id) override { (void)id; AZ_Assert(false,"Unsupported method in Unit Test"); return false; } - AZ::Entity* FindEntity(const AZ::EntityId& id) override { (void)id; AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - void EnumerateEntities(const EntityCallback& callback) override { (void)callback; AZ_Assert(false,"Unsupported method in Unit Test"); } - AZ::BehaviorContext* GetBehaviorContext() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - const char* GetAppRoot() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - const char* GetExecutableFolder() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - AZ::Debug::DrillerManager* GetDrillerManager() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - void ReloadModule(const char* moduleFullPath) override { (void)moduleFullPath; AZ_Assert(false,"Unsupported method in Unit Test"); } - - AZ::SerializeContext m_serializeContext; - }; - - TEST_F(DynamicSerializableFieldMarshalerTest, SingleMarshalUnmarshalTest_EquivalentEmptyValue) - { - AZ::DynamicSerializableField sentField; - m_marshaler.Marshal(m_writeBuffer, sentField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField; - m_marshaler.Unmarshal(receivedField,m_readBuffer); - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, SingleMarshalUnmarshalTest_EquivalentFooValue) - { - AZ::DynamicSerializableField sentField; - - FooSerializable* fooSerializable = GenerateFooSerializable(); - sentField.Set(fooSerializable); - - m_marshaler.Marshal(m_writeBuffer, sentField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField; - m_marshaler.Unmarshal(receivedField,m_readBuffer); - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - - sentField.DestroyData(&m_serializeContext); - receivedField.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, SingleMarshalUnmarshalTest_EquivalentBarValue) - { - AZ::DynamicSerializableField sentField; - - BarSerializable* barSerializable = GenerateBarSerializable(); - sentField.Set(barSerializable); - - m_marshaler.Marshal(m_writeBuffer, sentField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField; - m_marshaler.Unmarshal(receivedField,m_readBuffer); - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - - sentField.DestroyData(&m_serializeContext); - receivedField.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, SingleMarshalUnmarshalTest_EquivalentComplexValue) - { - AZ::DynamicSerializableField sentField; - - ComplexSerializable* complexSerializable = GenerateComplexSerializable(); - sentField.Set(complexSerializable); - - m_marshaler.Marshal(m_writeBuffer, sentField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField; - m_marshaler.Unmarshal(receivedField,m_readBuffer); - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - - sentField.DestroyData(&m_serializeContext); - receivedField.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, MultipleMarshalUnmarshalTest_EmptyEmptyChainEquivalentValue) - { - AZ::DynamicSerializableField sentField1; - AZ::DynamicSerializableField sentField2; - - m_marshaler.Marshal(m_writeBuffer, sentField1); - m_marshaler.Marshal(m_writeBuffer, sentField2); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField1; - AZ::DynamicSerializableField receivedField2; - - m_marshaler.Unmarshal(receivedField1,m_readBuffer); - m_marshaler.Unmarshal(receivedField2,m_readBuffer); - - EXPECT_TRUE(sentField1.IsEqualTo(receivedField1, &m_serializeContext)); - EXPECT_TRUE(sentField2.IsEqualTo(receivedField2, &m_serializeContext)); - - sentField1.DestroyData(&m_serializeContext); - sentField2.DestroyData(&m_serializeContext); - receivedField1.DestroyData(&m_serializeContext); - receivedField2.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, MultipleMarshalUnmarshalTest_FooBarComplexChainEquivalentValue) - { - AZ::DynamicSerializableField sentField1; - FooSerializable* fooSerializable = GenerateFooSerializable(); - sentField1.Set(fooSerializable); - - AZ::DynamicSerializableField sentField2; - BarSerializable* barSerializable = GenerateBarSerializable(); - sentField2.Set(barSerializable); - - AZ::DynamicSerializableField sentField3; - ComplexSerializable* complexSerializable = GenerateComplexSerializable(); - sentField3.Set(complexSerializable); - - m_marshaler.Marshal(m_writeBuffer, sentField1); - m_marshaler.Marshal(m_writeBuffer, sentField2); - m_marshaler.Marshal(m_writeBuffer, sentField3); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField1; - AZ::DynamicSerializableField receivedField2; - AZ::DynamicSerializableField receivedField3; - - m_marshaler.Unmarshal(receivedField1, m_readBuffer); - m_marshaler.Unmarshal(receivedField2, m_readBuffer); - m_marshaler.Unmarshal(receivedField3, m_readBuffer); - - EXPECT_TRUE(sentField1.IsEqualTo(receivedField1, &m_serializeContext)); - EXPECT_TRUE(sentField2.IsEqualTo(receivedField2, &m_serializeContext)); - EXPECT_TRUE(sentField3.IsEqualTo(receivedField3, &m_serializeContext)); - - sentField1.DestroyData(&m_serializeContext); - sentField2.DestroyData(&m_serializeContext); - sentField3.DestroyData(&m_serializeContext); - - receivedField1.DestroyData(&m_serializeContext); - receivedField2.DestroyData(&m_serializeContext); - receivedField3.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, MultipleMarshalUnmarshalTest_EmptyFooEmptyBarEmptyComplexChainEquivalentValue) - { - AZ::DynamicSerializableField emptyField; - - AZ::DynamicSerializableField sentField1; - FooSerializable* fooSerializable = GenerateFooSerializable(); - sentField1.Set(fooSerializable); - - AZ::DynamicSerializableField sentField2; - BarSerializable* barSerializable = GenerateBarSerializable(); - sentField2.Set(barSerializable); - - AZ::DynamicSerializableField sentField3; - ComplexSerializable* complexSerializable = GenerateComplexSerializable(); - sentField3.Set(complexSerializable); - - m_marshaler.Marshal(m_writeBuffer, emptyField); - m_marshaler.Marshal(m_writeBuffer, sentField1); - m_marshaler.Marshal(m_writeBuffer, emptyField); - m_marshaler.Marshal(m_writeBuffer, sentField2); - m_marshaler.Marshal(m_writeBuffer, emptyField); - m_marshaler.Marshal(m_writeBuffer, sentField3); - m_marshaler.Marshal(m_writeBuffer, emptyField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedEmptyField1; - AZ::DynamicSerializableField receivedField1; - AZ::DynamicSerializableField receivedEmptyField2; - AZ::DynamicSerializableField receivedField2; - AZ::DynamicSerializableField receivedEmptyField3; - AZ::DynamicSerializableField receivedField3; - AZ::DynamicSerializableField receivedEmptyField4; - - m_marshaler.Unmarshal(receivedEmptyField1, m_readBuffer); - m_marshaler.Unmarshal(receivedField1, m_readBuffer); - m_marshaler.Unmarshal(receivedEmptyField2, m_readBuffer); - m_marshaler.Unmarshal(receivedField2, m_readBuffer); - m_marshaler.Unmarshal(receivedEmptyField3, m_readBuffer); - m_marshaler.Unmarshal(receivedField3, m_readBuffer); - m_marshaler.Unmarshal(receivedEmptyField4, m_readBuffer); - - EXPECT_TRUE(emptyField.IsEqualTo(receivedEmptyField1, &m_serializeContext)); - EXPECT_TRUE(sentField1.IsEqualTo(receivedField1, &m_serializeContext)); - EXPECT_TRUE(emptyField.IsEqualTo(receivedEmptyField2, &m_serializeContext)); - EXPECT_TRUE(sentField2.IsEqualTo(receivedField2, &m_serializeContext)); - EXPECT_TRUE(emptyField.IsEqualTo(receivedEmptyField3, &m_serializeContext)); - EXPECT_TRUE(sentField3.IsEqualTo(receivedField3, &m_serializeContext)); - EXPECT_TRUE(emptyField.IsEqualTo(receivedEmptyField4, &m_serializeContext)); - - emptyField.DestroyData(&m_serializeContext); - sentField1.DestroyData(&m_serializeContext); - sentField2.DestroyData(&m_serializeContext); - sentField3.DestroyData(&m_serializeContext); - - receivedEmptyField1.DestroyData(&m_serializeContext); - receivedField1.DestroyData(&m_serializeContext); - receivedEmptyField2.DestroyData(&m_serializeContext); - receivedField2.DestroyData(&m_serializeContext); - receivedEmptyField3.DestroyData(&m_serializeContext); - receivedField3.DestroyData(&m_serializeContext); - receivedEmptyField4.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, MultipleMarshalUnmarshalTest_RandomChainEquivalentValue) - { - // Need to watch out for the size of the WriteBuffer. It's about ~2048 bytes, at worst case here, I'll write ~100 Bytes to the field per test object) - // So I need to keep this ~20 elements. - int numValues = 5 + m_random.GetRandom()%10; - AZStd::vector< AZ::DynamicSerializableField > sentValues; - AZStd::vector< AZ::DynamicSerializableField > receivedValues; - - sentValues.resize(numValues); - receivedValues.resize(numValues); - - for (auto& currentField : sentValues) - { - int value = m_random.GetRandom() % 4; - switch (value) - { - case 0: - { - currentField.Set(GenerateFooSerializable()); - } - break; - case 1: - { - currentField.Set(GenerateBarSerializable()); - } - break; - case 2: - { - currentField.Set(GenerateComplexSerializable()); - } - break; - case 3: - default: - // Empty field - break; - } - } - - for (auto& currentField : sentValues) - { - m_marshaler.Marshal(m_writeBuffer,currentField); - } - - PopulateReadBuffer(); - - for (auto& currentField : receivedValues) - { - m_marshaler.Unmarshal(currentField,m_readBuffer); - } - - for (unsigned int i=0; i < sentValues.size(); ++i) - { - AZ::DynamicSerializableField& sentField = sentValues[i]; - AZ::DynamicSerializableField& receivedField = receivedValues[i]; - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - - sentField.DestroyData(&m_serializeContext); - receivedField.DestroyData(&m_serializeContext); - } - } -} diff --git a/Code/Framework/Tests/Script/ScriptComponentTests.cpp b/Code/Framework/Tests/Script/ScriptComponentTests.cpp index a463192dd0..54c0d1dfa3 100644 --- a/Code/Framework/Tests/Script/ScriptComponentTests.cpp +++ b/Code/Framework/Tests/Script/ScriptComponentTests.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include "EntityTestbed.h" @@ -63,8 +62,6 @@ namespace UnitTest EBUS_EVENT_RESULT(m_behaviorContext, AZ::ComponentApplicationBus, GetBehaviorContext); EBUS_EVENT_RESULT(m_serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - NetBindable::Reflect(m_serializeContext); - AzToolsFramework::Components::ScriptEditorComponent::CreateDescriptor(); // descriptor is deleted by app AzToolsFramework::Components::ScriptEditorComponent::Reflect(m_serializeContext); @@ -228,63 +225,4 @@ namespace UnitTest EXPECT_NE(scriptComponent->GetScriptProperty("myNum"), nullptr); } - - TEST_F(ScriptComponentTest, UpdateNetSynchedProperty) - { - // Make sure altering a netsynched property in script only affects the single entity instance - const AZStd::string script = "local test = {\ - Properties = {\ - myNetSynchedNum = { default = 41, netSynched ={} },\ - doUpdate = { default = false },\ - },\ - }\ - function test:OnActivate()\ - self.tickBusHandler = TickBus.Connect(self, self.entityId)\ - end\ - function test:OnDeactivate()\ - self.tickBusHandler:Disconnect()\ - end\ - function test:OnTick(deltaTime, timePoint)\ - if self.Properties.doUpdate then\ - self.Properties.myNetSynchedNum = self.Properties.myNetSynchedNum+1\ - end\ - end\ - return test"; - - - const Data::Asset scriptAsset = CreateAndLoadScriptAsset(script); - Entity entity1, entity2; - ScriptComponent* scriptComponentInstance1 = BuildGameEntity(scriptAsset, entity1); - ScriptComponent* scriptComponentInstance2 = BuildGameEntity(scriptAsset, entity2); - - // Change the value of entity1's doUpdate to true. - // This way entity1's myNetSynchedNum should be incremented during OnTick - auto* doUpdateScriptProperty = azrtti_cast(scriptComponentInstance1->GetScriptProperty("doUpdate")); - ASSERT_NE(doUpdateScriptProperty, nullptr); - doUpdateScriptProperty->m_value = true; - - entity1.Init(); - entity2.Init(); - entity1.Activate(); - entity2.Activate(); - - // Tick in order to call OnTick in our lua script. - m_app.Tick(); - m_app.TickSystem(); - - // Ensure Entity1's myNetSynchedNum updated, but not Entity2 - auto* netSynchedProperty1 = scriptComponentInstance1->GetNetworkedScriptProperty("myNetSynchedNum"); - auto* netSynchedProperty2 = scriptComponentInstance2->GetNetworkedScriptProperty("myNetSynchedNum"); - ASSERT_NE(netSynchedProperty1, nullptr); - ASSERT_NE(netSynchedProperty2, nullptr); - - auto* num1 = azrtti_cast(netSynchedProperty1); - auto* num2 = azrtti_cast(netSynchedProperty2); - - ASSERT_NE(num1, nullptr); - ASSERT_NE(num2, nullptr); - - EXPECT_EQ(num1->m_value, 42); - EXPECT_EQ(num2->m_value, 41); - } } // namespace UnitTest diff --git a/Code/Framework/Tests/TransformComponent.cpp b/Code/Framework/Tests/TransformComponent.cpp index de172dc051..c2615f2a30 100644 --- a/Code/Framework/Tests/TransformComponent.cpp +++ b/Code/Framework/Tests/TransformComponent.cpp @@ -955,37 +955,6 @@ namespace UnitTest const char* m_objectStreamBuffer = nullptr; }; - class TransformComponentConvertFromV2 - : public TransformComponentVersionConverter - { - public: - TransformComponentConvertFromV2() - { - m_objectStreamBuffer = - R"DELIMITER( - - - - - - - - - - - - - - -)DELIMITER"; - } - }; - - TEST_F(TransformComponentConvertFromV2, IsStatic_False) - { - EXPECT_FALSE(m_transformInterface->IsStaticTransform()); - } - /////////////////////////////////////////////////////////////////////////// // TransformConfig diff --git a/Code/Framework/Tests/frameworktests_files.cmake b/Code/Framework/Tests/frameworktests_files.cmake index cf02b007b4..07990dc8fa 100644 --- a/Code/Framework/Tests/frameworktests_files.cmake +++ b/Code/Framework/Tests/frameworktests_files.cmake @@ -26,8 +26,6 @@ set(FILES GenAppDescriptors.cpp GenericComponentWrapperTest.cpp InstanceDataHierarchy.cpp - NetBinding.cpp - NetworkContext.cpp OctreePerformanceTests.cpp OctreeTests.cpp Slices.cpp @@ -35,12 +33,8 @@ set(FILES Script/ScriptEntityTests.cpp AssetCatalog.cpp AssetProcessorConnection.cpp - NetBindingSystemImplTest.cpp - NetBindingMocks.h NativeWindow.cpp TransformComponent.cpp - GridMocks.h - InterestManagerComponentTests.cpp SQLiteConnectionTests.cpp ProcessLaunchParseTests.cpp Application.cpp From ab8738b7c398364d2f797da7c872132fcaa99edd Mon Sep 17 00:00:00 2001 From: Eric Phister <52085794+amzn-phist@users.noreply.github.com> Date: Tue, 11 May 2021 15:16:32 -0500 Subject: [PATCH 123/225] Updating to support Wwise SDK 2021.1.1.X (#686) * Code updates for Wwise 2021.1.X support. * [WIP] CMake updates for Wwise 2021.1.X support. * Updates FindWwise.cmake to search for a Wwise install or let user set it as cache variable. * Makes Wwise SDK optional, and the AudioEngineWwise Gem will revert to a 'stub' build if no SDK found. * Adding a .gitignore for Wwise project files. * Updates a .wcmdline file for integration into Wwise projects. * Updates the cmake messaging regarding Wwise SDK and smooths out some of configuration scenarios. * Updates the Wwise project for AutomatedTesting to ver 2021.1.1.7601 and rebuilds banks. --- AutomatedTesting/sounds/.gitignore | 8 + AutomatedTesting/sounds/wwise/Init.bnk | 4 +- AutomatedTesting/sounds/wwise/Init.txt | 1 - AutomatedTesting/sounds/wwise/PluginInfo.xml | 9 +- .../sounds/wwise/SoundbanksInfo.xml | 26 +- AutomatedTesting/sounds/wwise/test_bank1.bnk | 4 +- AutomatedTesting/sounds/wwise/test_bank1.txt | 4 +- AutomatedTesting/sounds/wwise/test_bank2.bnk | 4 +- .../sounds/wwise/test_bank3.bankdeps | 4 +- AutomatedTesting/sounds/wwise/test_bank3.bnk | 4 +- AutomatedTesting/sounds/wwise/test_bank3.txt | 2 +- AutomatedTesting/sounds/wwise/test_bank4.bnk | 2 +- AutomatedTesting/sounds/wwise/test_bank4.txt | 2 +- AutomatedTesting/sounds/wwise/test_bank5.bnk | 4 +- AutomatedTesting/sounds/wwise/test_bank5.txt | 2 +- AutomatedTesting/sounds/wwise/test_bank6.bnk | 4 +- .../sounds/wwise/test_bank7.bankdeps | 4 +- AutomatedTesting/sounds/wwise/test_bank7.bnk | 4 +- AutomatedTesting/sounds/wwise/test_bank7.txt | 4 +- .../Default Work Unit.wwu | 10 +- .../Attenuations/Default Work Unit.wwu | 2 +- .../Audio Devices/Default Work Unit.wwu | 3 +- .../wwise_project/AutomatedTesting.wproj | 13491 ++++++++++++++++ .../Default Work Unit.wwu | 2 +- .../Conversion Settings/Default Work Unit.wwu | 2 +- .../Factory Conversion Settings.wwu | 2 +- .../Dynamic Dialogue/Default Work Unit.wwu | 2 +- .../Effects/Default Work Unit.wwu | 2 +- .../wwise_project/Effects/Factory Effects.wwu | 2 +- .../wwise_project/Effects/Factory Reflect.wwu | 8 +- .../Events/Default Work Unit.wwu | 2 +- .../Game Parameters/Default Work Unit.wwu | 2 +- .../Game Parameters/Factory Motion.wwu | 2 +- .../Factory SoundSeed Air Game Syncs.wwu | 2 +- .../Default Work Unit.wwu | 2 +- .../Default Work Unit.wwu | 6 +- .../Metadata/Default Work Unit.wwu | 6 + .../Mixing Sessions/Default Work Unit.wwu | 2 +- .../Modulators/Default Work Unit.wwu | 2 +- .../Presets/Default Work Unit.wwu | 2 +- .../wwise_project/Presets/Factory Reflect.wwu | 3 +- .../Presets/Factory Spatial Audio.wwu | 3 +- .../Queries/Default Work Unit.wwu | 2 +- .../wwise_project/Queries/Factory Queries.wwu | 2 +- .../SoundBanks/Default Work Unit.wwu | 2 +- .../Default Work Unit.wwu | 2 +- .../States/Default Work Unit.wwu | 2 +- .../Switches/Default Work Unit.wwu | 2 +- .../Triggers/Default Work Unit.wwu | 2 +- .../Virtual Acoustics/Default Work Unit.wwu | 2 +- .../Factory Reflect Acoustic Textures.wwu | 2 +- Gems/AudioEngineWwise/Code/CMakeLists.txt | 22 +- .../Code/Platform/Android/PAL_android.cmake | 2 +- .../Code/Platform/Linux/PAL_linux.cmake | 2 +- .../Code/Platform/Mac/PAL_mac.cmake | 2 +- .../Windows/AudioSystemImpl_wwise_Windows.cpp | 2 - .../Code/Platform/Windows/PAL_windows.cmake | 2 +- .../Code/Platform/iOS/PAL_ios.cmake | 2 +- .../Source/Engine/AudioSystemImpl_wwise.cpp | 18 +- .../Code/Source/Engine/Common_wwise.h | 5 +- ...copy_output_and_generate_metadata.wcmdline | 4 +- cmake/3rdParty/FindWwise.cmake | 93 +- .../Platform/Android/Wwise_android.cmake | 3 - .../Platform/Windows/Wwise_windows.cmake | 7 +- 64 files changed, 13696 insertions(+), 142 deletions(-) create mode 100644 AutomatedTesting/sounds/.gitignore create mode 100644 AutomatedTesting/sounds/wwise_project/AutomatedTesting.wproj create mode 100644 AutomatedTesting/sounds/wwise_project/Metadata/Default Work Unit.wwu diff --git a/AutomatedTesting/sounds/.gitignore b/AutomatedTesting/sounds/.gitignore new file mode 100644 index 0000000000..80c66daa1c --- /dev/null +++ b/AutomatedTesting/sounds/.gitignore @@ -0,0 +1,8 @@ +.backup/ +.cache/ +*.log +*.akd +*.dat +*.prof +*.validationcache +*.wsettings \ No newline at end of file diff --git a/AutomatedTesting/sounds/wwise/Init.bnk b/AutomatedTesting/sounds/wwise/Init.bnk index 530a7e007f..292288ff26 100644 --- a/AutomatedTesting/sounds/wwise/Init.bnk +++ b/AutomatedTesting/sounds/wwise/Init.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:803ddb37eb27cba666f9320c2f5905219193e1a069d1144a64df92fab0e31878 -size 1243 +oid sha256:c9e6a4ef3d2f33f31827ce2bba2ed8bad87324f3fe86f79389ef2956b304a924 +size 1180 diff --git a/AutomatedTesting/sounds/wwise/Init.txt b/AutomatedTesting/sounds/wwise/Init.txt index 038359ac1a..4b989c4017 100644 --- a/AutomatedTesting/sounds/wwise/Init.txt +++ b/AutomatedTesting/sounds/wwise/Init.txt @@ -21,5 +21,4 @@ Audio Bus ID Name Wwise Object Path Notes Audio Devices ID Name Type Notes 2317455096 No_Output No Output 3859886410 System System - 4230635974 Default_Motion_Device Wwise Motion diff --git a/AutomatedTesting/sounds/wwise/PluginInfo.xml b/AutomatedTesting/sounds/wwise/PluginInfo.xml index 61e689f373..19f3fe9c1b 100644 --- a/AutomatedTesting/sounds/wwise/PluginInfo.xml +++ b/AutomatedTesting/sounds/wwise/PluginInfo.xml @@ -1,9 +1,8 @@ - + - - - - + + + diff --git a/AutomatedTesting/sounds/wwise/SoundbanksInfo.xml b/AutomatedTesting/sounds/wwise/SoundbanksInfo.xml index 22ae71f4dc..d7bfecaa53 100644 --- a/AutomatedTesting/sounds/wwise/SoundbanksInfo.xml +++ b/AutomatedTesting/sounds/wwise/SoundbanksInfo.xml @@ -1,11 +1,11 @@ - + - Q:\audio\dev\AutomatedTesting\sounds\wwise_project\ - Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\ - Q:\audio\dev\AutomatedTesting\sounds\wwise\ + D:\code\o3de\AutomatedTesting\sounds\wwise_project\ + D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\ + D:\code\o3de\AutomatedTesting\sounds\wwise\ - Q:\audio\dev\AutomatedTesting\sounds\wwise_project\GeneratedSoundBanks\Windows + D:\code\o3de\AutomatedTesting\sounds\wwise_project\GeneratedSoundBanks\Windows @@ -28,7 +28,7 @@ - + \SoundBanks\Default Work Unit\test_bank2 test_bank2 test_bank2.bnk @@ -37,7 +37,7 @@ - + \SoundBanks\Default Work Unit\test_bank3 test_bank3 test_bank3.bnk @@ -60,7 +60,7 @@ - + \SoundBanks\Default Work Unit\test_bank1 test_bank1 test_bank1.bnk @@ -83,7 +83,7 @@ - + \SoundBanks\Default Work Unit\test_bank6 test_bank6 test_bank6.bnk @@ -102,7 +102,7 @@ - + \SoundBanks\Default Work Unit\test_bank7 test_bank7 test_bank7.bnk @@ -125,7 +125,7 @@ - + \SoundBanks\Default Work Unit\test_bank4 test_bank4 test_bank4.bnk @@ -136,7 +136,7 @@ - + \SoundBanks\Default Work Unit\test_bank5 test_bank5 test_bank5.bnk @@ -169,7 +169,7 @@ - + Init Init Init.bnk diff --git a/AutomatedTesting/sounds/wwise/test_bank1.bnk b/AutomatedTesting/sounds/wwise/test_bank1.bnk index 9e8f50a98a..bd0e1e66cb 100644 --- a/AutomatedTesting/sounds/wwise/test_bank1.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank1.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94ea13931c13592deba669bd4920328ff96f17e6f8fce280d03f00251a96327a -size 94122 +oid sha256:3db299d7d823b649ff20a7ffc986dccfce1fa3189f178491e2712d6c00b317af +size 94126 diff --git a/AutomatedTesting/sounds/wwise/test_bank1.txt b/AutomatedTesting/sounds/wwise/test_bank1.txt index a0c6e13621..5ec2e4b96b 100644 --- a/AutomatedTesting/sounds/wwise/test_bank1.txt +++ b/AutomatedTesting/sounds/wwise/test_bank1.txt @@ -3,8 +3,8 @@ Event ID Name Wwise Object Path Notes 865645077 test_event_1_bank1_embedded_target \Default Work Unit\test_event_1_bank1_embedded_target In Memory Audio ID Name Audio source file Wwise Object Path Notes Data Size - 23965881 test_sfx_1_bank1_embedded Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZ_sfx_NME_wpn_plasma_pistol_fire_impact004_56D34C19.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_1_bank1_embedded 93864 + 23965881 test_sfx_1_bank1_embedded D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZ_sfx_NME_wpn_plasma_pistol_fire_impact004_56D34C19.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_1_bank1_embedded 93864 Streamed Audio ID Name Audio source file Generated audio file Wwise Object Path Notes - 499820003 test_sfx_2_bank1_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\env_door_scanner_scan_success_56D34C19.wem 499820003.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_2_bank1_streamed + 499820003 test_sfx_2_bank1_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\env_door_scanner_scan_success_56D34C19.wem 499820003.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_2_bank1_streamed diff --git a/AutomatedTesting/sounds/wwise/test_bank2.bnk b/AutomatedTesting/sounds/wwise/test_bank2.bnk index 2e31c359bf..ee96554646 100644 --- a/AutomatedTesting/sounds/wwise/test_bank2.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank2.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad73fd0981e47fe3313eff51d2841ea5fd522a99103684d696849e7353277ea9 -size 430 +oid sha256:1bdaed4dc5cc514a8a3ddfaf990f59061514af7962a7a112eb677ad5c45fcb85 +size 434 diff --git a/AutomatedTesting/sounds/wwise/test_bank3.bankdeps b/AutomatedTesting/sounds/wwise/test_bank3.bankdeps index 606dbdbac8..51a952d463 100644 --- a/AutomatedTesting/sounds/wwise/test_bank3.bankdeps +++ b/AutomatedTesting/sounds/wwise/test_bank3.bankdeps @@ -2,9 +2,9 @@ "version": "1.0", "bankName": "test_bank3.bnk", "dependencies": [ - "196049145.wem", + "test_bank4.bnk", "Init.bnk", - "test_bank4.bnk" + "196049145.wem" ], "includedEvents": [ "test_event_5_bank3_embedded_target_bank4", diff --git a/AutomatedTesting/sounds/wwise/test_bank3.bnk b/AutomatedTesting/sounds/wwise/test_bank3.bnk index 32e6161e6c..6b83836c18 100644 --- a/AutomatedTesting/sounds/wwise/test_bank3.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank3.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:33eabaa646e9567017946bee05b1b5a835e91862f63145ebe5a2fbdd9c9f5a49 -size 226 +oid sha256:57c75cf8745b31071a788a20d8de5a60cedbfb8a6155eae1a461b8c6501e5479 +size 230 diff --git a/AutomatedTesting/sounds/wwise/test_bank3.txt b/AutomatedTesting/sounds/wwise/test_bank3.txt index ca6efc6e02..9a843afad7 100644 --- a/AutomatedTesting/sounds/wwise/test_bank3.txt +++ b/AutomatedTesting/sounds/wwise/test_bank3.txt @@ -3,5 +3,5 @@ Event ID Name Wwise Object Path Notes 645979556 test_event_6_bank3_streamed_target_bank4 \Default Work Unit\test_event_6_bank3_streamed_target_bank4 Event that lives in test_bank3. This event targets only one media, which is streamed from test_bank4. Streamed Audio ID Name Audio source file Generated audio file Wwise Object Path Notes - 196049145 test_sfx_6_bank4_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZ_sfx_NME_wpn_plasma_pistol_fire003_56D34C19.wem 196049145.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_6_bank4_streamed + 196049145 test_sfx_6_bank4_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZ_sfx_NME_wpn_plasma_pistol_fire003_56D34C19.wem 196049145.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_6_bank4_streamed diff --git a/AutomatedTesting/sounds/wwise/test_bank4.bnk b/AutomatedTesting/sounds/wwise/test_bank4.bnk index e169744d84..5f5883d559 100644 --- a/AutomatedTesting/sounds/wwise/test_bank4.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank4.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79d308f3c50fece383fd82fd0060e26558e6a2e78a4ecd5d8afe24907489a88f +oid sha256:3a635f7d1ccb256caed90d18ca566cd0fa56d49b491af7c88c0b5da55a3ef4fe size 142234 diff --git a/AutomatedTesting/sounds/wwise/test_bank4.txt b/AutomatedTesting/sounds/wwise/test_bank4.txt index 770cb7f171..7649b0eed5 100644 --- a/AutomatedTesting/sounds/wwise/test_bank4.txt +++ b/AutomatedTesting/sounds/wwise/test_bank4.txt @@ -1,3 +1,3 @@ In Memory Audio ID Name Audio source file Wwise Object Path Notes Data Size - 666825490 test_sfx_5_bank4_embedded Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZN_sfx_env_commsarray_apllyupdate_end_56D34C19.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_5_bank4_embedded 142170 + 666825490 test_sfx_5_bank4_embedded D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZN_sfx_env_commsarray_apllyupdate_end_56D34C19.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_5_bank4_embedded 142170 diff --git a/AutomatedTesting/sounds/wwise/test_bank5.bnk b/AutomatedTesting/sounds/wwise/test_bank5.bnk index b4e629d9a7..168c7c1a4d 100644 --- a/AutomatedTesting/sounds/wwise/test_bank5.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank5.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80c02f30d439ffcfb479e4a82b0269fe4f479c50019028e51f0fa6e3fea0bfdd -size 290 +oid sha256:fa329eeb83184e88b7ab26fbff2479a98232210bcd130801041b20ccb3bcf16e +size 294 diff --git a/AutomatedTesting/sounds/wwise/test_bank5.txt b/AutomatedTesting/sounds/wwise/test_bank5.txt index 0f66c57f8e..3d560cf9f5 100644 --- a/AutomatedTesting/sounds/wwise/test_bank5.txt +++ b/AutomatedTesting/sounds/wwise/test_bank5.txt @@ -5,5 +5,5 @@ Event ID Name Wwise Object Path Notes 3546419658 test_event_7_bank5_referenced_event_bank1_embedded \Default Work Unit\test_event_7_bank5_referenced_event_bank1_embedded Streamed Audio ID Name Audio source file Generated audio file Wwise Object Path Notes - 499820003 test_sfx_2_bank1_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\env_door_scanner_scan_success_56D34C19.wem 499820003.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_2_bank1_streamed + 499820003 test_sfx_2_bank1_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\env_door_scanner_scan_success_56D34C19.wem 499820003.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_2_bank1_streamed diff --git a/AutomatedTesting/sounds/wwise/test_bank6.bnk b/AutomatedTesting/sounds/wwise/test_bank6.bnk index 18ee92b51d..4c942037f0 100644 --- a/AutomatedTesting/sounds/wwise/test_bank6.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank6.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07d132d54b2c747e2409a56c05a4adca0dfa4407b791ffaa6bb14531f92f89aa -size 494 +oid sha256:80d3014fcfd3a8ff37219515f0c9d67a2a674094002538ac6741702dca07c14d +size 498 diff --git a/AutomatedTesting/sounds/wwise/test_bank7.bankdeps b/AutomatedTesting/sounds/wwise/test_bank7.bankdeps index 02be60a544..56cf29c619 100644 --- a/AutomatedTesting/sounds/wwise/test_bank7.bankdeps +++ b/AutomatedTesting/sounds/wwise/test_bank7.bankdeps @@ -2,9 +2,9 @@ "version": "1.0", "bankName": "test_bank7.bnk", "dependencies": [ + "656567798.wem", "601903616.wem", - "Init.bnk", - "656567798.wem" + "Init.bnk" ], "includedEvents": [ "test_event_11_bank7_streamed_target", diff --git a/AutomatedTesting/sounds/wwise/test_bank7.bnk b/AutomatedTesting/sounds/wwise/test_bank7.bnk index abc398d1f1..c01346fd58 100644 --- a/AutomatedTesting/sounds/wwise/test_bank7.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank7.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:990538a33c72e79d63cab0c191b4e0f199688b923bb6bdcc8888aab375e7d11d -size 226 +oid sha256:0de33094b9792d7f9ff8042e16b153dd76729e9010d6713e1824d2229c653042 +size 230 diff --git a/AutomatedTesting/sounds/wwise/test_bank7.txt b/AutomatedTesting/sounds/wwise/test_bank7.txt index 033c2ea5b9..3bf2da686b 100644 --- a/AutomatedTesting/sounds/wwise/test_bank7.txt +++ b/AutomatedTesting/sounds/wwise/test_bank7.txt @@ -3,6 +3,6 @@ Event ID Name Wwise Object Path Notes 2110064689 test_event_11_bank7_streamed_target \Default Work Unit\test_event_11_bank7_streamed_target Streamed Audio ID Name Audio source file Generated audio file Wwise Object Path Notes - 601903616 test_sfx_8_bank7_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\gun_blaster_no_trigger_shot_1_56D34C19.wem 601903616.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_8_bank7_streamed - 656567798 test_sfx_7_bank7_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\impact_bot_hits_metalelement_56D34C19.wem 656567798.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_7_bank7_streamed + 601903616 test_sfx_8_bank7_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\gun_blaster_no_trigger_shot_1_56D34C19.wem 601903616.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_8_bank7_streamed + 656567798 test_sfx_7_bank7_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\impact_bot_hits_metalelement_56D34C19.wem 656567798.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_7_bank7_streamed diff --git a/AutomatedTesting/sounds/wwise_project/Actor-Mixer Hierarchy/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Actor-Mixer Hierarchy/Default Work Unit.wwu index 8cc6eeecc2..33ac513281 100644 --- a/AutomatedTesting/sounds/wwise_project/Actor-Mixer Hierarchy/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Actor-Mixer Hierarchy/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + @@ -21,6 +21,7 @@ + @@ -50,6 +51,7 @@ + @@ -72,6 +74,7 @@ + @@ -101,6 +104,7 @@ + @@ -130,6 +134,7 @@ + @@ -159,6 +164,7 @@ + @@ -187,6 +193,7 @@ SFX + @@ -215,6 +222,7 @@ SFX + diff --git a/AutomatedTesting/sounds/wwise_project/Attenuations/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Attenuations/Default Work Unit.wwu index 9034f07366..955c7d9e4a 100644 --- a/AutomatedTesting/sounds/wwise_project/Attenuations/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Attenuations/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Audio Devices/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Audio Devices/Default Work Unit.wwu index 472e9b12d1..f56682b0bf 100644 --- a/AutomatedTesting/sounds/wwise_project/Audio Devices/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Audio Devices/Default Work Unit.wwu @@ -1,11 +1,10 @@ - + - diff --git a/AutomatedTesting/sounds/wwise_project/AutomatedTesting.wproj b/AutomatedTesting/sounds/wwise_project/AutomatedTesting.wproj new file mode 100644 index 0000000000..1aead159ad --- /dev/null +++ b/AutomatedTesting/sounds/wwise_project/AutomatedTesting.wproj @@ -0,0 +1,13491 @@ + + + + + + + + + + + + + + + + + + + + + + GeneratedSoundBanks\Windows + + + + + 256 + + + + + + ..\wwise\ + + + + + Copy Streamed Files and Generate Dependency Info + + + + + "$(CopyStreamedFilesExePath)" -info "$(InfoFilePath)" -outputpath "$(SoundBankPath)" -banks "$(SoundBankListAsTextFile)" -languages "$(LanguageList)" +"$(WwiseProjectPath)\..\..\..\python\python.cmd" "$(WwiseProjectPath)\..\..\..\Gems\AudioEngineWwise\Tools\WwiseAuthoringScripts\bank_info_parser.py" "$(InfoFilePath)" "$(SoundBankPath)" + + + + + + + + + + + + + + + -80 + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 8 + + + + + 0 + + + + + -1 + + + + + -1 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + -1 + + + + + -1 + + + + + 0 + + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + False + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 2 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + + + + + 1 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + 10000 + + + + + 1 + + + + + 400 + + + + + 1 + + + + + 1 + + + + + 0.5 + + + + + 0 + + + + + -96 + + + + + 0 + + + + + True + + + + + False + + + + + 0 + + + + + 0 + + + + + 16 + + + + + -96 + + + + + 0 + + + + + 48000 + + + + + 0 + + + + + + + + + 16 + + + + + False + + + + + 1 + + + + + 75 + + + + + + + + + False + + + + + 512 + + + + + -50 + + + + + -30 + + + + + -40 + + + + + 0 + + + + + 24024 + + + + + 0 + + + + + 8 + + + + + English(US) + + + + + 0 + + + + + 0 + + + + + False + + + + + + + + + + + + + + + 1 + + + + + True + + + + + False + + + + + False + + + + + True + + + + + 256 + + + + + + + + + + 50 + + + + + 100 + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + True + + + + + True + + + + + True + + + + + True + + + + + -80 + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 64 + + + + + 1.5 + + + + + 2 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + 64 + + + + + 64 + + + + + 4 + + + + + 0 + + + + + 0.1 + + + + + 4 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 20 + + + + + 10000 + + + + + 0.2 + + + + + True + + + + + 80 + + + + + 0.2 + + + + + False + + + + + 200 + + + + + 0.25 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 4 + + + + + 4 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 0 + + + + + 100 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 10 + + + + + 1 + + + + + 200 + + + + + 0 + + + + + 0 + + + + + 10 + + + + + 1 + + + + + 200 + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 40 + + + + + 0 + + + + + 1000 + + + + + 160 + + + + + 0 + + + + + 0.5 + + + + + 0.2 + + + + + 0 + + + + + 0.5 + + + + + 0.2 + + + + + 0 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0.2 + + + + + 0 + + + + + 0.2 + + + + + 0.2 + + + + + 3000 + + + + + 0.2 + + + + + 0 + + + + + 6 + + + + + 15000 + + + + + 0 + + + + + 1000 + + + + + 20000 + + + + + 0 + + + + + 0.5 + + + + + 0.2 + + + + + 0 + + + + + 0.5 + + + + + 0.2 + + + + + 0 + + + + + 1 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + 1 + + + + + False + + + + + + + + + 1 + + + + + 0 + + + + + True + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + False + + + + + 3 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 1 + + + + + False + + + + + 2 + + + + + True + + + + + False + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 50 + + + + + False + + + + + -10 + + + + + True + + + + + 1 + + + + + 1 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 1 + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + True + + + + + 5000 + + + + + 10000 + + + + + False + + + + + + + + + False + + + + + 0 + + + + + 3 + + + + + 9 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 0 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + + + + + 1000 + + + + + 5000 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 96 + + + + + -100 + + + + + -100 + + + + + -100 + + + + + False + + + + + False + + + + + + + + + False + + + + + 0 + + + + + 35 + + + + + 0 + + + + + True + + + + + 0 + + + + + 1 + + + + + 1 + + + + + True + + + + + + + + + 0 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 3 + + + + + 9 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + False + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + False + + + + + False + + + + + + + + + 64 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 100 + + + + + 0 + + + + + True + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 100 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + -96 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 100 + + + + + 0 + + + + + False + + + + + 0 + + + + + 50 + + + + + 50 + + + + + 50 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + 4000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 1 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 120 + + + + + 4 + + + + + 4 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 100 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 100 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 1 + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + 0 + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + True + + + + + False + + + + + False + + + + + True + + + + + True + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + + -1 + + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 1 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 120 + + + + + 4 + + + + + 4 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 1 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 120 + + + + + 4 + + + + + 4 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 1 + + + + + 1 + + + + + False + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 50 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 7 + + + + + + + + + + False + + + + + 1 + + + + + + + + + + False + + + + + True + + + + + True + + + + + True + + + + + True + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + + + + + 4 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + -6 + + + + + 0 + + + + + 90 + + + + + 0 + + + + + 245 + + + + + False + + + + + True + + + + + False + + + + + 100 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + False + + + + + 100 + + + + + + + + + True + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + False + + + + + + + + + + + + + + + False + + + + + False + + + + + True + + + + + False + + + + + False + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + True + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + True + + + + + + + + + 0 + + + + + False + + + + + + + + + + + + + + + + + + True + + + + + 4 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + + + + + 0 + + + + + False + + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 8 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 100 + + + + + 0 + + + + + True + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + False + + + + + + + + + 0 + + + + + 50 + + + + + 0.2 + + + + + False + + + + + 0.2 + + + + + 0.5 + + + + + True + + + + + 100 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + False + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + + + + + + 1 + + + + + False + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + + + + + + 1 + + + + + False + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + + + + + 0 + + + + + True + + + + + 1 + + + + + 1 + + + + + False + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 4 + + + + + 1 + + + + + 440 + + + + + -12 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 1 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 4 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + -12 + + + + + 1 + + + + + False + + + + + 0 + + + + + -12 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + False + + + + + 10 + + + + + 0 + + + + + + + + + 0 + + + + + 4 + + + + + 6 + + + + + 5 + + + + + 100 + + + + + 1000 + + + + + 12000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + True + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 1 + + + + + 1 + + + + + 1 + + + + + + + + + 0 + + + + + 0.5 + + + + + 15 + + + + + True + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 25 + + + + + + + + + 0.1 + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 1.5 + + + + + 0.1 + + + + + 0 + + + + + + + + + 0.1 + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 3 + + + + + 0.01 + + + + + -40 + + + + + + + + + True + + + + + 0 + + + + + True + + + + + 0.01 + + + + + 0 + + + + + False + + + + + True + + + + + 10 + + + + + 0.1 + + + + + 0 + + + + + + + + + 100 + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + 1 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + True + + + + + 40 + + + + + 0 + + + + + 0 + + + + + 18000 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + True + + + + + 10 + + + + + 0 + + + + + 100 + + + + + -40 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + True + + + + + 40 + + + + + 18000 + + + + + -96 + + + + + -20 + + + + + 20 + + + + + 0 + + + + + 0 + + + + + False + + + + + True + + + + + 100 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 13.62 + + + + + 26.09 + + + + + 26.55 + + + + + 26.91 + + + + + 28.04 + + + + + 29.09 + + + + + 29.9 + + + + + 30.86 + + + + + 15.66 + + + + + 17.52 + + + + + 19.02 + + + + + 20.83 + + + + + 22.6 + + + + + 24.05 + + + + + 24.78 + + + + + 25.6 + + + + + -96.3 + + + + + 2 + + + + + True + + + + + 8 + + + + + False + + + + + 0 + + + + + True + + + + + 4 + + + + + -35 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + 0 + + + + + True + + + + + 100 + + + + + 0 + + + + + False + + + + + -96.3 + + + + + + + + + 0 + + + + + 0 + + + + + 40 + + + + + 1.2 + + + + + 80 + + + + + 50 + + + + + 8 + + + + + 2 + + + + + 100 + + + + + 15 + + + + + 5 + + + + + 66 + + + + + -96.3 + + + + + 0 + + + + + -20 + + + + + 23 + + + + + True + + + + + False + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 3 + + + + + 1 + + + + + 1 + + + + + 1000 + + + + + 0 + + + + + 3 + + + + + 1 + + + + + 2 + + + + + 10000 + + + + + 0 + + + + + 3 + + + + + 1 + + + + + 0 + + + + + 2.25 + + + + + True + + + + + 0 + + + + + -96.3 + + + + + -96.3 + + + + + False + + + + + 25 + + + + + 8 + + + + + 0 + + + + + -20 + + + + + 100 + + + + + 50 + + + + + 100 + + + + + 0.8 + + + + + 0.1 + + + + + 0 + + + + + 180 + + + + + + + + + 1 + + + + + 0 + + + + + False + + + + + 0 + + + + + 1 + + + + + 0 + + + + + False + + + + + 0 + + + + + 10 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0.5 + + + + + False + + + + + 0 + + + + + 10 + + + + + 5 + + + + + 1 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0.25 + + + + + False + + + + + 0 + + + + + 0.5 + + + + + + + + + 1 + + + + + 1 + + + + + True + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 10 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + 10 + + + + + 0.5 + + + + + 0 + + + + + 1 + + + + + + + + + 440 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 10 + + + + + + + + + False + + + + + 440 + + + + + 0 + + + + + 10 + + + + + 1 + + + + + + + + + 0 + + + + + 5 + + + + + 1 + + + + + True + + + + + 0 + + + + + 1 + + + + + True + + + + + 50 + + + + + 1 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + 100 + + + + + + + + + 0 + + + + + 50 + + + + + 50 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 100 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + -96.3 + + + + + 0 + + + + + 0 + + + + + False + + + + + 4 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 0 + + + + + -75 + + + + + False + + + + + False + + + + + 6 + + + + + 0 + + + + + 0 + + + + + True + + + + + 100 + + + + + True + + + + + 0 + + + + + -96.3 + + + + + 0 + + + + + -60 + + + + + -96.3 + + + + + False + + + + + 0 + + + + + 0 + + + + + 1024 + + + + + 48000 + + + + + 48000 + + + + + 48000 + + + + + 180 + + + + + 0 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + -48 + + + + + False + + + + + 0.1 + + + + + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + 100 + + + + + 0 + + + + + 2048 + + + + + + + + + 0 + + + + + True + + + + + 100 + + + + + 1 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + True + + + + + True + + + + + + + + + 1 + + + + + False + + + + + Recorder.wav + + + + + -3 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + + + + + + True + + + + + -96.3 + + + + + False + + + + + -3 + + + + + -3 + + + + + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + -100 + + + + + True + + + + + -12 + + + + + 0.1 + + + + + -12 + + + + + 0 + + + + + False + + + + + -12 + + + + + 0.1 + + + + + -12 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 50 + + + + + -96 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + 0 + + + + + False + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + False + + + + + True + + + + + True + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1024 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + -96 + + + + + 0 + + + + + 0 + + + + + False + + + + + -6 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + False + + + + + -6 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + + + + + False + + + + + False + + + + + + + + + 1 + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 250 + + + + + 100 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + -96 + + + + + 3 + + + + + True + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0.5 + + + + + 0 + + + + + 2400 + + + + + 345 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 1 + + + + + + + + + False + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 32 + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + False + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 100 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 10 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 20000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0.707 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 256 + + + + + False + + + + + 100 + + + + + 100 + + + + + 100 + + + + + 100 + + + + + 1000 + + + + + 1000 + + + + + 1000 + + + + + 1000 + + + + + 20000 + + + + + 20000 + + + + + 20000 + + + + + 20000 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 5 + + + + + 5 + + + + + 9 + + + + + 9 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 16641 + + + + + 0 + + + + + 0 + + + + + False + + + + + 10 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 60 + + + + + 1 + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + 0 + + + + + True + + + + + False + + + + + 0.01 + + + + + True + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0.1 + + + + + 0 + + + + + 0.01 + + + + + True + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0.1 + + + + + 0 + + + + + 0.01 + + + + + True + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0.1 + + + + + 0 + + + + + 0.01 + + + + + True + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0.1 + + + + + 0 + + + + + 150 + + + + + 1000 + + + + + 6000 + + + + + 0 + + + + + False + + + + + 0 + + + + + 4 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + 5 + + + + + 100 + + + + + 0 + + + + + 1 + + + + + True + + + + + 3 + + + + + 200 + + + + + 0 + + + + + 1 + + + + + True + + + + + 3 + + + + + 500 + + + + + 0 + + + + + 1 + + + + + True + + + + + 4 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 3 + + + + + 3000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 3 + + + + + 6000 + + + + + 0 + + + + + 1 + + + + + 4 + + + + + + + + + -12 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + -12 + + + + + 1 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 6 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + + + + + + 0 + + + + + 0 + + + + + + + + + 0.6 + + + + + 0.6 + + + + + 0.5 + + + + + 0.3 + + + + + 0.05 + + + + + 0.25 + + + + + 0.02 + + + + + 1.5 + + + + + 0.2 + + + + + 0.3 + + + + + True + + + + + 0.2 + + + + + 8 + + + + + 0.2 + + + + + 12 + + + + + + + + + 20 + + + + + 0.7 + + + + + 100 + + + + + 0.1 + + + + + 1 + + + + + 1 + + + + + True + + + + + 1 + + + + + 0 + + + + + 3 + + + + + 1 + + + + + + + + + 2 + + + + + 0.7 + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 0.9 + + + + + 0.1 + + + + + 3 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 2 + + + + + False + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + 0 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + 1.4 + + + + + -6 + + + + + True + + + + + 0 + + + + + 0 + + + + + False + + + + + True + + + + + 0.5 + + + + + 10000 + + + + + -6 + + + + + 7 + + + + + 1 + + + + + 1 + + + + + 7.25 + + + + + 2.75 + + + + + 3.25 + + + + + 4.25 + + + + + 4.75 + + + + + 3.75 + + + + + + + + + 100 + + + + + 50 + + + + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + -200 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + 100 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + 100 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + -200 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + 100 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + 100 + 37 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AutomatedTesting/sounds/wwise_project/Control Surface Sessions/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Control Surface Sessions/Default Work Unit.wwu index 1f7d254b46..4e13dee554 100644 --- a/AutomatedTesting/sounds/wwise_project/Control Surface Sessions/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Control Surface Sessions/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Conversion Settings/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Conversion Settings/Default Work Unit.wwu index ac7c83d1db..236f5765db 100644 --- a/AutomatedTesting/sounds/wwise_project/Conversion Settings/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Conversion Settings/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Conversion Settings/Factory Conversion Settings.wwu b/AutomatedTesting/sounds/wwise_project/Conversion Settings/Factory Conversion Settings.wwu index 9a94d81c32..7873f5135a 100644 --- a/AutomatedTesting/sounds/wwise_project/Conversion Settings/Factory Conversion Settings.wwu +++ b/AutomatedTesting/sounds/wwise_project/Conversion Settings/Factory Conversion Settings.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Dynamic Dialogue/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Dynamic Dialogue/Default Work Unit.wwu index e6e033e251..5411c7d503 100644 --- a/AutomatedTesting/sounds/wwise_project/Dynamic Dialogue/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Dynamic Dialogue/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Effects/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Effects/Default Work Unit.wwu index f938135d6b..ca63005f4b 100644 --- a/AutomatedTesting/sounds/wwise_project/Effects/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Effects/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Effects/Factory Effects.wwu b/AutomatedTesting/sounds/wwise_project/Effects/Factory Effects.wwu index ac716afb97..5a545f5e61 100644 --- a/AutomatedTesting/sounds/wwise_project/Effects/Factory Effects.wwu +++ b/AutomatedTesting/sounds/wwise_project/Effects/Factory Effects.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Effects/Factory Reflect.wwu b/AutomatedTesting/sounds/wwise_project/Effects/Factory Reflect.wwu index f2269dd2dc..2c0ebb6b67 100644 --- a/AutomatedTesting/sounds/wwise_project/Effects/Factory Reflect.wwu +++ b/AutomatedTesting/sounds/wwise_project/Effects/Factory Reflect.wwu @@ -1,10 +1,9 @@ - + - - + @@ -185,8 +184,7 @@ - - + diff --git a/AutomatedTesting/sounds/wwise_project/Events/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Events/Default Work Unit.wwu index c65c8adca1..73c2e8f028 100644 --- a/AutomatedTesting/sounds/wwise_project/Events/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Events/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Game Parameters/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Game Parameters/Default Work Unit.wwu index e373885f46..a939ebe124 100644 --- a/AutomatedTesting/sounds/wwise_project/Game Parameters/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Game Parameters/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory Motion.wwu b/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory Motion.wwu index b06d283012..3989d74308 100644 --- a/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory Motion.wwu +++ b/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory Motion.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory SoundSeed Air Game Syncs.wwu b/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory SoundSeed Air Game Syncs.wwu index 049dacb51e..efe69cb1a8 100644 --- a/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory SoundSeed Air Game Syncs.wwu +++ b/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory SoundSeed Air Game Syncs.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Interactive Music Hierarchy/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Interactive Music Hierarchy/Default Work Unit.wwu index 1086c4511f..e8f4d23bb6 100644 --- a/AutomatedTesting/sounds/wwise_project/Interactive Music Hierarchy/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Interactive Music Hierarchy/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Master-Mixer Hierarchy/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Master-Mixer Hierarchy/Default Work Unit.wwu index a627ce106e..b6c14df7af 100644 --- a/AutomatedTesting/sounds/wwise_project/Master-Mixer Hierarchy/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Master-Mixer Hierarchy/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + @@ -9,13 +9,15 @@ + - + + diff --git a/AutomatedTesting/sounds/wwise_project/Metadata/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Metadata/Default Work Unit.wwu new file mode 100644 index 0000000000..0317c70b7c --- /dev/null +++ b/AutomatedTesting/sounds/wwise_project/Metadata/Default Work Unit.wwu @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/sounds/wwise_project/Mixing Sessions/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Mixing Sessions/Default Work Unit.wwu index 8c62ef9009..c24440febd 100644 --- a/AutomatedTesting/sounds/wwise_project/Mixing Sessions/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Mixing Sessions/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Modulators/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Modulators/Default Work Unit.wwu index 062f9f80df..dc16200be3 100644 --- a/AutomatedTesting/sounds/wwise_project/Modulators/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Modulators/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Presets/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Presets/Default Work Unit.wwu index 2bed1c6613..07f7565980 100644 --- a/AutomatedTesting/sounds/wwise_project/Presets/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Presets/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Presets/Factory Reflect.wwu b/AutomatedTesting/sounds/wwise_project/Presets/Factory Reflect.wwu index 53f828f459..8138f5bcdd 100644 --- a/AutomatedTesting/sounds/wwise_project/Presets/Factory Reflect.wwu +++ b/AutomatedTesting/sounds/wwise_project/Presets/Factory Reflect.wwu @@ -1,5 +1,5 @@ - + @@ -19,6 +19,7 @@ + diff --git a/AutomatedTesting/sounds/wwise_project/Presets/Factory Spatial Audio.wwu b/AutomatedTesting/sounds/wwise_project/Presets/Factory Spatial Audio.wwu index 5b96bd3b29..d73cf8d8c3 100644 --- a/AutomatedTesting/sounds/wwise_project/Presets/Factory Spatial Audio.wwu +++ b/AutomatedTesting/sounds/wwise_project/Presets/Factory Spatial Audio.wwu @@ -1,5 +1,5 @@ - + @@ -17,6 +17,7 @@ + diff --git a/AutomatedTesting/sounds/wwise_project/Queries/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Queries/Default Work Unit.wwu index f4e9f99aa4..ff80573330 100644 --- a/AutomatedTesting/sounds/wwise_project/Queries/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Queries/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Queries/Factory Queries.wwu b/AutomatedTesting/sounds/wwise_project/Queries/Factory Queries.wwu index 527315de63..813983d789 100644 --- a/AutomatedTesting/sounds/wwise_project/Queries/Factory Queries.wwu +++ b/AutomatedTesting/sounds/wwise_project/Queries/Factory Queries.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/SoundBanks/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/SoundBanks/Default Work Unit.wwu index da8fa90010..c12261ab5b 100644 --- a/AutomatedTesting/sounds/wwise_project/SoundBanks/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/SoundBanks/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu index d6b8329537..379bf37da9 100644 --- a/AutomatedTesting/sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/States/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/States/Default Work Unit.wwu index f27a0d0310..b06937baa9 100644 --- a/AutomatedTesting/sounds/wwise_project/States/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/States/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Switches/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Switches/Default Work Unit.wwu index 49c00bc378..37fb0b424c 100644 --- a/AutomatedTesting/sounds/wwise_project/Switches/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Switches/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Triggers/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Triggers/Default Work Unit.wwu index 3b2e2634df..bb2a827d79 100644 --- a/AutomatedTesting/sounds/wwise_project/Triggers/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Triggers/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Default Work Unit.wwu index 29c26cbbab..d10d9475dc 100644 --- a/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Factory Reflect Acoustic Textures.wwu b/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Factory Reflect Acoustic Textures.wwu index 864f6ba959..ca4a1ae8f2 100644 --- a/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Factory Reflect Acoustic Textures.wwu +++ b/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Factory Reflect Acoustic Textures.wwu @@ -1,5 +1,5 @@ - + diff --git a/Gems/AudioEngineWwise/Code/CMakeLists.txt b/Gems/AudioEngineWwise/Code/CMakeLists.txt index dfd9ae6e24..5ea6a6d461 100644 --- a/Gems/AudioEngineWwise/Code/CMakeLists.txt +++ b/Gems/AudioEngineWwise/Code/CMakeLists.txt @@ -18,10 +18,15 @@ set(AUDIOENGINEWWISE_COMPILEDEFINITIONS $,WWISE_RELEASE,ENABLE_AUDIO_LOGGING> ) +find_package(Wwise MODULE) +if (NOT Wwise_FOUND) + message(STATUS "** Update the LY_WWISE_INSTALL_PATH cache variable if you intend to use Wwise.") +endif() + ################################################################################ # Server / Unsupported ################################################################################ -if (PAL_TRAIT_BUILD_SERVER_SUPPORTED OR PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB) +if (PAL_TRAIT_BUILD_SERVER_SUPPORTED OR PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB OR NOT Wwise_FOUND) # Stub gem for server and unsupported platforms. Audio Engine Wwise is client only ly_add_target( NAME AudioEngineWwise.Stub ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} @@ -34,11 +39,17 @@ if (PAL_TRAIT_BUILD_SERVER_SUPPORTED OR PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB) ) endif() -if (PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB) - add_library(Gem::AudioEngineWwise ALIAS AudioEngineWwise.Stub) #setup an alias so the stub will be used if something references AudioEngineWwise +if (PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB OR NOT Wwise_FOUND) + # setup aliases so stubs will be used if something references AudioEngineWwise(.Editor) + add_library(Gem::AudioEngineWwise ALIAS AudioEngineWwise.Stub) + add_library(Gem::AudioEngineWwise.Editor ALIAS AudioEngineWwise.Stub) return() endif() + +################################################################################ +# Runtime / Game +################################################################################ ly_add_target( NAME AudioEngineWwise.Static STATIC NAMESPACE Gem @@ -165,7 +176,7 @@ if (PAL_TRAIT_BUILD_TESTS_SUPPORTED) TARGETS ${testTargets} FILES - ${CMAKE_CURRENT_SOURCE_DIR}/Tests/Sounds//wwise/soundbanks/init.bnk + ${CMAKE_CURRENT_SOURCE_DIR}/Tests/Sounds/wwise/soundbanks/init.bnk OUTPUT_SUBDIRECTORY Test.Assets/Gems/AudioEngineWwise/sounds/wwise/soundbanks ) @@ -173,7 +184,7 @@ if (PAL_TRAIT_BUILD_TESTS_SUPPORTED) endif() ################################################################################ -# Editor +# Tools / Editor ################################################################################ if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_target( @@ -199,7 +210,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_target( NAME AudioEngineWwise.Editor GEM_MODULE - NAMESPACE Gem FILES_CMAKE audioenginewwise_editor_shared_files.cmake diff --git a/Gems/AudioEngineWwise/Code/Platform/Android/PAL_android.cmake b/Gems/AudioEngineWwise/Code/Platform/Android/PAL_android.cmake index 69420d8aca..9600a0a2cb 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Android/PAL_android.cmake +++ b/Gems/AudioEngineWwise/Code/Platform/Android/PAL_android.cmake @@ -9,4 +9,4 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB TRUE) +set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB FALSE) diff --git a/Gems/AudioEngineWwise/Code/Platform/Linux/PAL_linux.cmake b/Gems/AudioEngineWwise/Code/Platform/Linux/PAL_linux.cmake index 69420d8aca..9600a0a2cb 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Linux/PAL_linux.cmake +++ b/Gems/AudioEngineWwise/Code/Platform/Linux/PAL_linux.cmake @@ -9,4 +9,4 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB TRUE) +set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB FALSE) diff --git a/Gems/AudioEngineWwise/Code/Platform/Mac/PAL_mac.cmake b/Gems/AudioEngineWwise/Code/Platform/Mac/PAL_mac.cmake index 69420d8aca..9600a0a2cb 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Mac/PAL_mac.cmake +++ b/Gems/AudioEngineWwise/Code/Platform/Mac/PAL_mac.cmake @@ -9,4 +9,4 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB TRUE) +set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB FALSE) diff --git a/Gems/AudioEngineWwise/Code/Platform/Windows/AudioSystemImpl_wwise_Windows.cpp b/Gems/AudioEngineWwise/Code/Platform/Windows/AudioSystemImpl_wwise_Windows.cpp index b6ae569e30..2cf8acba9c 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Windows/AudioSystemImpl_wwise_Windows.cpp +++ b/Gems/AudioEngineWwise/Code/Platform/Windows/AudioSystemImpl_wwise_Windows.cpp @@ -25,8 +25,6 @@ namespace Audio void SetupAkSoundEngine(AkPlatformInitSettings& platformInitSettings) { - // Turn off XAudio2 output type due to rare startup crashes. Prefers WASAPI or DirectSound. - platformInitSettings.eAudioAPI = static_cast(platformInitSettings.eAudioAPI & ~AkAPI_XAudio2); platformInitSettings.threadBankManager.dwAffinityMask = 0; platformInitSettings.threadLEngine.dwAffinityMask = 0; platformInitSettings.threadMonitor.dwAffinityMask = 0; diff --git a/Gems/AudioEngineWwise/Code/Platform/Windows/PAL_windows.cmake b/Gems/AudioEngineWwise/Code/Platform/Windows/PAL_windows.cmake index 69420d8aca..9600a0a2cb 100644 --- a/Gems/AudioEngineWwise/Code/Platform/Windows/PAL_windows.cmake +++ b/Gems/AudioEngineWwise/Code/Platform/Windows/PAL_windows.cmake @@ -9,4 +9,4 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB TRUE) +set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB FALSE) diff --git a/Gems/AudioEngineWwise/Code/Platform/iOS/PAL_ios.cmake b/Gems/AudioEngineWwise/Code/Platform/iOS/PAL_ios.cmake index 69420d8aca..9600a0a2cb 100644 --- a/Gems/AudioEngineWwise/Code/Platform/iOS/PAL_ios.cmake +++ b/Gems/AudioEngineWwise/Code/Platform/iOS/PAL_ios.cmake @@ -9,4 +9,4 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB TRUE) +set(PAL_TRAIT_AUDIO_ENGINE_WWISE_USE_STUB FALSE) diff --git a/Gems/AudioEngineWwise/Code/Source/Engine/AudioSystemImpl_wwise.cpp b/Gems/AudioEngineWwise/Code/Source/Engine/AudioSystemImpl_wwise.cpp index 2e11c7a810..6fb21964a3 100644 --- a/Gems/AudioEngineWwise/Code/Source/Engine/AudioSystemImpl_wwise.cpp +++ b/Gems/AudioEngineWwise/Code/Source/Engine/AudioSystemImpl_wwise.cpp @@ -66,12 +66,18 @@ namespace Audio { void* Malloc(AkMemPoolId memId, size_t size) { - return AZ::AllocatorInstance::Get().Allocate(size, 0, 0, MemoryManagerCategories[memId & AkMemID_MASK]); + size_t memCategory = memId & AkMemID_MASK; + AZ_Assert(memCategory < AkMemID_NUM, "Wwise::MemHooks::Malloc - Bad AkMemPoolId passed: %zu", memCategory); + return AZ::AllocatorInstance::Get().Allocate(size, 0, 0, + (memCategory < AkMemID_NUM) ? MemoryManagerCategories[memCategory] : nullptr); } void* Malign(AkMemPoolId memId, size_t size, AkUInt32 alignment) { - return AZ::AllocatorInstance::Get().Allocate(size, alignment, 0, MemoryManagerCategories[memId & AkMemID_MASK]); + size_t memCategory = memId & AkMemID_MASK; + AZ_Assert(memCategory < AkMemID_NUM, "WWise::MemHooks::Malign - Bad AkMemPoolId passed: %zu", memCategory); + return AZ::AllocatorInstance::Get().Allocate(size, alignment, 0, + (memCategory < AkMemID_NUM) ? MemoryManagerCategories[memCategory] : nullptr); } void* Realloc([[maybe_unused]] AkMemPoolId memId, void* address, size_t size) @@ -79,12 +85,12 @@ namespace Audio return AZ::AllocatorInstance::Get().ReAllocate(address, size, 0); } - void Free([[maybe_unused]] AkMemPoolId memId, void* address) + void* ReallocAligned([[maybe_unused]] AkMemPoolId memId, void* address, size_t size, AkUInt32 alignment) { - AZ::AllocatorInstance::Get().DeAllocate(address); + return AZ::AllocatorInstance::Get().ReAllocate(address, size, alignment); } - void Falign([[maybe_unused]] AkMemPoolId memId, void* address) + void Free([[maybe_unused]] AkMemPoolId memId, void* address) { AZ::AllocatorInstance::Get().DeAllocate(address); } @@ -427,8 +433,8 @@ namespace Audio akMemSettings.pfMalloc = Wwise::MemHooks::Malloc; akMemSettings.pfMalign = Wwise::MemHooks::Malign; akMemSettings.pfRealloc = Wwise::MemHooks::Realloc; + akMemSettings.pfReallocAligned = Wwise::MemHooks::ReallocAligned; akMemSettings.pfFree = Wwise::MemHooks::Free; - akMemSettings.pfFalign = Wwise::MemHooks::Falign; akMemSettings.pfTotalReservedMemorySize = Wwise::MemHooks::TotalReservedMemorySize; akMemSettings.pfSizeOfMemory = Wwise::MemHooks::SizeOfMemory; akMemSettings.uMemAllocationSizeLimit = Wwise::Cvars::s_PrimaryMemorySize << 10; diff --git a/Gems/AudioEngineWwise/Code/Source/Engine/Common_wwise.h b/Gems/AudioEngineWwise/Code/Source/Engine/Common_wwise.h index 2e806a80e9..25e6a22d84 100644 --- a/Gems/AudioEngineWwise/Code/Source/Engine/Common_wwise.h +++ b/Gems/AudioEngineWwise/Code/Source/Engine/Common_wwise.h @@ -91,8 +91,9 @@ namespace Audio // See AkMemoryMgr.h inline static const char* MemoryManagerCategories[] { - "Object", "Event", "Structure", "Media", "GameObject", "Processing", "ProcessingPlugin", "Streaming", "StreamingIO", "SpatialAudio", - "SpatialAudioGeometry", "SpatialAudioPaths", "GameSim", "MonitorQueue", "Profiler", "FilePackage", "SoundEngine" + "Object", "Event", "Structure", "Media", "GameObject", "Processing", "ProcessingPlugin", "Streaming", "StreamingIO", + "SpatialAudio", "SpatialAudioGeometry", "SpatialAudioPaths", "GameSim", "MonitorQueue", "Profiler", "FilePackage", + "SoundEngine", "Integration" }; static_assert(AZ_ARRAY_SIZE(MemoryManagerCategories) == AkMemID_NUM, diff --git a/Gems/AudioEngineWwise/Tools/WwiseAuthoringScripts/ly_copy_output_and_generate_metadata.wcmdline b/Gems/AudioEngineWwise/Tools/WwiseAuthoringScripts/ly_copy_output_and_generate_metadata.wcmdline index 5d2394fae2..3cc868384b 100644 --- a/Gems/AudioEngineWwise/Tools/WwiseAuthoringScripts/ly_copy_output_and_generate_metadata.wcmdline +++ b/Gems/AudioEngineWwise/Tools/WwiseAuthoringScripts/ly_copy_output_and_generate_metadata.wcmdline @@ -1,3 +1,3 @@ -"$(WwiseExePath)\CopyStreamedFiles.exe" -info "$(InfoFilePath)" -outputpath "$(SoundBankPath)" -banks "$(SoundBankListAsTextFile)" -languages "$(LanguageList)" -"$(WwiseProjectPath)\..\..\..\python.cmd" "$(WwiseProjectPath)\..\..\..\Gems\AudioEngineWwise\Tools\WwiseAuthoringScripts\bank_info_parser.py" "$(InfoFilePath)" "$(SoundBankPath)" +"$(CopyStreamedFilesExePath)" -info "$(InfoFilePath)" -outputpath "$(SoundBankPath)" -banks "$(SoundBankListAsTextFile)" -languages "$(LanguageList)" +"$(WwiseProjectPath)\..\..\..\python\python.cmd" "$(WwiseProjectPath)\..\..\..\Gems\AudioEngineWwise\Tools\WwiseAuthoringScripts\bank_info_parser.py" "$(InfoFilePath)" "$(SoundBankPath)" diff --git a/cmake/3rdParty/FindWwise.cmake b/cmake/3rdParty/FindWwise.cmake index 27b78695f2..9b46c24d75 100644 --- a/cmake/3rdParty/FindWwise.cmake +++ b/cmake/3rdParty/FindWwise.cmake @@ -9,6 +9,59 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# The current supported version of Wwise +set(WWISE_VERSION 2021.1.1.7601) + +# Wwise Install Path +# Initialize to the default 3rdParty path +set(LY_WWISE_INSTALL_PATH "" CACHE PATH "Path to Wwise version ${WWISE_VERSION} installation.") + +function(is_valid_sdk sdk_path is_valid) + set(${is_valid} FALSE PARENT_SCOPE) + if(EXISTS ${sdk_path}) + set(sdk_version_file ${sdk_path}/SDK/include/AK/AkWwiseSDKVersion.h) + if(EXISTS ${sdk_version_file}) + string(FIND ${sdk_path} ${WWISE_VERSION} index) + if(NOT index EQUAL -1) + set(${is_valid} TRUE PARENT_SCOPE) + else() + # The install path doesn't contain the WWISE_VERSION string. + # The path could still be correct, but it would require parsing the AkWwiseSDKVersion.h to verify. + endif() + endif() + endif() +endfunction() + +# Paths that will be checked, in order: +# - CMake cache variable +# - WWISEROOT Environment Variable +# - Standard 3rdParty path +set(WWISE_SDK_PATHS + "${LY_WWISE_INSTALL_PATH}" + "$ENV{WWISEROOT}" + "${LY_3RDPARTY_PATH}/Wwise/${WWISE_VERSION}" +) + +set(found_sdk FALSE) +foreach(test_path ${WWISE_SDK_PATHS}) + is_valid_sdk(${test_path} found_sdk) + if(found_sdk) + # Update the Wwise Install Path cache variable + set(LY_WWISE_INSTALL_PATH "${test_path}" CACHE PATH "Path to Wwise version ${WWISE_VERSION} installation." FORCE) + break() + endif() +endforeach() + +if(NOT found_sdk) + # If we don't find a path that appears to be a valid Wwise install, we can bail here. + # No 3rdParty::Wwise target will exist, so that can be checked elsewhere. + message(STATUS "Wwise SDK version ${WWISE_VERSION} was not found.") + return() +else() + message(STATUS "Using Wwise SDK at ${LY_WWISE_INSTALL_PATH}") +endif() + + set(WWISE_COMMON_LIB_NAMES # Core AK AkMemoryMgr @@ -55,44 +108,26 @@ set(WWISE_NON_RELEASE_LIB_NAMES CommunicationCentral ) -# Additional Libraries -# These can be added/enabled to the linker depending on what your Wwise project uses. -# In addition to uncommenting the libraries here, be sure to add the appropriate plugin factory -# header includes to PluginRegistration_wwise.h. - set(WWISE_ADDITIONAL_LIB_NAMES -# Common - #AkConvolutionReverbFX - #AkReflectFX - #AkRouterMixerFX - #ResonanceAudioFX - #MasteringSuiteFX - #AkSoundSeedImpactFX - #AkSoundSeedGrainSource - #AkSoundSeedWindSource - #AkSoundSeedWooshSource - #AuroHeadphoneFX - #CrankcaseAudioREVModelPlayerSource - #McDSPFutzBoxFX - #McDSPLimiterFX - -# iZotope - #iZHybridReverbFX - #iZTrashBoxModelerFX - #iZTrashDelayFX - #iZTrashDistortionFX - #iZTrashDynamicsFX - #iZTrashFiltersFX - #iZTrashMultibandDistortionFX + # Additional Libraries ) set(WWISE_COMPILE_DEFINITIONS $,AK_OPTIMIZED,> ) + +# The default install path might look different than the standard 3rdParty format (${LY_3RDPARTY_PATH}//). +# Use these to get the parent path and folder name before adding the external 3p target. +get_filename_component(WWISE_3P_ROOT ${LY_WWISE_INSTALL_PATH} DIRECTORY) +get_filename_component(WWISE_FOLDER ${LY_WWISE_INSTALL_PATH} NAME) + ly_add_external_target( NAME Wwise - VERSION 2019.2.8.7432 + VERSION "${WWISE_FOLDER}" + 3RDPARTY_ROOT_DIRECTORY "${WWISE_3P_ROOT}" INCLUDE_DIRECTORIES SDK/include COMPILE_DEFINITIONS ${WWISE_COMPILE_DEFINITIONS} ) + +set(Wwise_FOUND TRUE) diff --git a/cmake/3rdParty/Platform/Android/Wwise_android.cmake b/cmake/3rdParty/Platform/Android/Wwise_android.cmake index 5d7713511b..d204688489 100644 --- a/cmake/3rdParty/Platform/Android/Wwise_android.cmake +++ b/cmake/3rdParty/Platform/Android/Wwise_android.cmake @@ -10,9 +10,6 @@ # set(WWISE_ANDROID_LIB_NAMES - AkMotionGeneratorSource - AkMotionSink - AkMotionSourceSource zip ) diff --git a/cmake/3rdParty/Platform/Windows/Wwise_windows.cmake b/cmake/3rdParty/Platform/Windows/Wwise_windows.cmake index 37141f7e6d..09b9478ac0 100644 --- a/cmake/3rdParty/Platform/Windows/Wwise_windows.cmake +++ b/cmake/3rdParty/Platform/Windows/Wwise_windows.cmake @@ -10,16 +10,11 @@ # set(WWISE_WINDOWS_LIB_NAMES - ASIOSourceSink AkAutobahn - AkMotionGeneratorSource - AkMotionSink - AkMotionSourceSource - MSSpatialSink SFLib ) -set(WWISE_VS_VER "vc150") # use the version of Wwise built with MSVC2017, or toolset 141 +set(WWISE_VS_VER "vc160") set(WWISE_LIB_PATH ${BASE_PATH}/SDK/x64_${WWISE_VS_VER}/$,Debug,$,Profile,Release>>/lib) From 21dfcfed74ed657656c2d67ccda70a871b6bfd24 Mon Sep 17 00:00:00 2001 From: mbalfour Date: Tue, 11 May 2021 15:26:07 -0500 Subject: [PATCH 124/225] Fix bug where setting autoLoad to false for one gem will prevent every gem after it from loading as well. --- Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp index daf5b5efd2..b2fe4417d3 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp @@ -1304,7 +1304,7 @@ namespace AZ // Add all auto loadable non-asset gems to the list of gem modules to load if (!moduleLoadData.m_autoLoad) { - break; + continue; } for (AZ::OSString& dynamicLibraryPath : moduleLoadData.m_dynamicLibraryPaths) { From fe24f37a705738160a657bd22b4fe5c011e0f01e Mon Sep 17 00:00:00 2001 From: Aristo7 <5432499+Aristo7@users.noreply.github.com> Date: Tue, 11 May 2021 15:34:31 -0500 Subject: [PATCH 125/225] Fixing up null.builder loading issue --- Gems/Atom/RHI/Null/Code/CMakeLists.txt | 2 +- Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Gems/Atom/RHI/Null/Code/CMakeLists.txt b/Gems/Atom/RHI/Null/Code/CMakeLists.txt index 1b88e72648..be1c5d22aa 100644 --- a/Gems/Atom/RHI/Null/Code/CMakeLists.txt +++ b/Gems/Atom/RHI/Null/Code/CMakeLists.txt @@ -89,7 +89,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ) ly_add_target( - NAME Atom_RHI_Null.Builders MODULE + NAME Atom_RHI_Null.Builders GEM_MODULE NAMESPACE Gem FILES_CMAKE atom_rhi_null_builders_shared_files.cmake diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt index 06b4e2a7fe..33873e0dfa 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt @@ -104,14 +104,5 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) Gem::ImguiAtom Gem::AtomFont Gem::AtomToolsFramework.Editor - - # Testing jenkins issue - Gem::Atom_RHI_Vulkan.Private - Gem::Atom_RHI_Vulkan.Builders - Gem::Atom_RHI_DX12.Private - Gem::Atom_RHI_DX12.Builders - Gem::Atom_RHI_Null.Private - Gem::Atom_RHI_Null.Builders - Gem::Atom_RHI_Metal.Builders ) endif() From 5440d0926d432e8d59ea3a44a890c25a776783ea Mon Sep 17 00:00:00 2001 From: karlberg Date: Tue, 11 May 2021 13:42:44 -0700 Subject: [PATCH 126/225] Fixing some dependencies in script canvas and emfx --- .../Components/AnimGraphNetSyncComponent.cpp | 448 ------------------ .../Components/AnimGraphNetSyncComponent.h | 153 ------ .../Components/AnimGraphNetSyncTypes.h | 285 ----------- .../Integration/System/AnimationModule.cpp | 3 - .../Code/emotionfx_shared_files.cmake | 3 - .../Execution/RuntimeComponent.cpp | 4 - .../ScriptCanvas/Execution/RuntimeComponent.h | 9 +- .../Variable/GraphVariableMarshal.cpp | 245 ---------- .../Variable/GraphVariableMarshal.h | 86 ---- .../Variable/GraphVariableNetBindings.cpp | 181 ------- .../Variable/GraphVariableNetBindings.h | 101 ---- .../Code/scriptcanvasgem_common_files.cmake | 4 - 12 files changed, 1 insertion(+), 1521 deletions(-) delete mode 100644 Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.cpp delete mode 100644 Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.h delete mode 100644 Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncTypes.h delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.h delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.h diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.cpp deleted file mode 100644 index 904f500018..0000000000 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.cpp +++ /dev/null @@ -1,448 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "EMotionFX_precompiled.h" -#include -#include -#include -#include -#include -#include - -namespace EMotionFX -{ - namespace Integration - { - namespace Network - { - /** - * \brief This is a GridMate chunk that replicates Anim Graph parameters. - * It's challenge is to replicate any of the supported parameter types where - * the types are only known at runtime. To solve that, many datasets are created - * with helper macros to avoid code duplication (@PARAM_DATASET and @PARAM_DATASET_NAME). - * - * For maximum compression, one should build a custom component that specifies the anim graph parameters by hand, for example: - * - * DataSet m_param0; - * - * or if using delta compression feature of GridMate: - * - * DeltaCompressedDataSet m_param1; - * - * Active nodes (@m_activeNodes) change infrequently. - * - * Warning: @m_motionNodes motion nodes often do change frequently as their motion play time ticks down. - * Care must be applied when aiming for the network budget of a project. - */ - class AnimGraphNetSyncComponent::Chunk : public GridMate::ReplicaChunkBase - { - public: - GM_CLASS_ALLOCATOR(Chunk); - - Chunk() : m_activeNodes("Active Nodes", NodeIndexContainer{}), m_motionNodes("Motion Nodes", MotionNodePlaytimeContainer{}) {} - - static const char* GetChunkName() { return "AnimGraphNetSyncComponent::Chunk"; } - bool IsReplicaMigratable() override { return true; } - - using AnimDataSetType = GridMate::DataSet; - - template - using AnimDataSet = AnimDataSetType::BindInterface; - - // A helper macro that creates a variable like this one: - // AnimDataSet<&AnimGraphNetSyncComponent::OnAnimParameterChanged<0>> m_parameter0 = { "Param 0" }; - #define PARAM_DATASET( N ) AnimDataSet<&AnimGraphNetSyncComponent::OnAnimParameterChanged< N >> m_parameter##N = { "Param " #N } - - PARAM_DATASET(0); - PARAM_DATASET(1); - PARAM_DATASET(2); - PARAM_DATASET(3); - PARAM_DATASET(4); - PARAM_DATASET(5); - PARAM_DATASET(6); - PARAM_DATASET(7); - PARAM_DATASET(8); - PARAM_DATASET(9); - - /* - * Note: GridMate by default supports up to 32 DataSets per ReplicaChunk: @GM_MAX_DATASETS_IN_CHUNK. - * That means that a component can sync up to 32 separate network fields. One can vary the number of supported number - * of parameters by simply creating new entries of @PARAM_DATASET above and @PARAM_DATASET_NAME below. - */ - - // A collection of datasets that are used to synchronize anim graph parameters. - AZStd::array m_parameters = { { // clang pre-6.0 requires double "{{" here but doesn't perform compile length verification :( - &m_parameter0, - &m_parameter1, - &m_parameter2, - &m_parameter3, - &m_parameter4, - &m_parameter5, - &m_parameter6, - &m_parameter7, - &m_parameter8, - &m_parameter9, - } }; - - GridMate::DataSet:: - BindInterface m_activeNodes; - GridMate::DataSet:: - BindInterface m_motionNodes; - }; - - void AnimGraphNetSyncComponent::Reflect(AZ::ReflectContext* context) - { - GridMate::ReplicaChunkDescriptorTable& descTable = GridMate::ReplicaChunkDescriptorTable::Get(); - if (!descTable.FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(Chunk::GetChunkName()))) - { - descTable.RegisterChunkType(); - } - - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field( "Sync parameters", &AnimGraphNetSyncComponent::m_syncParameters ) - ->Field( "Sync active nodes", &AnimGraphNetSyncComponent::m_syncActiveNodes ) - ->Field( "Sync motion nodes", &AnimGraphNetSyncComponent::m_syncMotionNodes ) - ; - - AZ::EditContext* editContent = serializeContext->GetEditContext(); - if (editContent) - { - editContent->Class("Anim Graph Net Sync", - "Replicates anim graph parameters over the network using GridMate") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->Attribute(AZ::Edit::Attributes::Category, "Networking") - ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/AnimGraphNetSync.svg") - ->DataElement( AZ::Edit::UIHandlers::Default, &AnimGraphNetSyncComponent::m_syncParameters, "Sync parameters", - "Synchronize parameters of the anim graph on the entity" ) - ->DataElement( AZ::Edit::UIHandlers::Default, &AnimGraphNetSyncComponent::m_syncActiveNodes, "Sync active nodes", - "Synchronize active nodes in the anim graph on the entity" ) - ->DataElement( AZ::Edit::UIHandlers::Default, &AnimGraphNetSyncComponent::m_syncMotionNodes, "Sync motion nodes", - "Synchronize motion nodes in the anim graph on the entity. Warning: this may take a significant amount of network bandwidth" ) - ; - } - } - } - - void AnimGraphNetSyncComponent::Activate() - { - AnimGraphComponentNotificationBus::Handler::BusConnect(GetEntityId()); - - if (m_syncMotionNodes || m_syncActiveNodes) // if there is anything synchronize over the network - { - const bool isAuthoritative = AzFramework::NetQuery::IsEntityAuthoritative(GetEntityId()); - if (isAuthoritative) - { - // Only the server (or authoritative entity) needs to watch the nodes values. - AZ::TickBus::Handler::BusConnect(); - } - - // We need to get anim graph instance. It will be either available to us now or later via a notification bus. See @OnAnimGraphInstanceCreated - AnimGraphComponentRequestBus::EventResult(m_instance, GetEntityId(), &AnimGraphComponentRequestBus::Events::GetAnimGraphInstance); - if (m_instance) - { - if (!m_instance->GetSnapshot()) - { - m_instance->CreateSnapshot(isAuthoritative); - } - } - } - } - - void AnimGraphNetSyncComponent::Deactivate() - { - AnimGraphComponentNotificationBus::Handler::BusDisconnect(); - AZ::TickBus::Handler::BusDisconnect(); - } - - void AnimGraphNetSyncComponent::SetParameterOnClient(const AnimParameter& value, AZ::u8 index) - { - switch (value.m_type) - { - case AnimParameter::Type::Unsupported: - break; - case AnimParameter::Type::Float: - AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterFloat, index, value.m_value.f); - break; - case AnimParameter::Type::Bool: - AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterBool, index, value.m_value.b); - break; - case AnimParameter::Type::Vector2: - AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterVector2, index, value.m_value.v2); - break; - case AnimParameter::Type::Vector3: - AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterVector3, index, value.m_value.v3); - break; - case AnimParameter::Type::Quaternion: - AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterRotation, index, value.m_value.q); - break; - default: - AZ_Assert(false, "Unsupported type"); - break; - } - } - - template - void AnimGraphNetSyncComponent::OnAnimParameterChanged(const AnimParameter& value, const GridMate::TimeContext&) - { - SetParameterOnClient(value, Index); - } - - template - void AnimGraphNetSyncComponent::SetParameterOnServer(AZ::u8 parameterIndex, const FieldType& newValue) - { - if (m_syncParameters) - { - if (Chunk* chunk = GetChunk()) - { - if (parameterIndex < chunk->m_parameters.size()) - { - AnimParameter param; - param.m_type = AnimParameterType; - - static_assert(sizeof(FieldType) <= sizeof(param.m_value), "The largest value param.m_value can store is a Quaternion"); - // This is to simplify writing a value into a union. - // Ideally, one would use std::variant (C++17) instead of a union. - memcpy(¶m.m_value, &newValue, sizeof(FieldType)); - - chunk->m_parameters[parameterIndex]->Set(param); - } - else - { - AZ_Warning("EMotionFX", false, "AnimGraphNetSyncComponent does not support synchronizing more than %u parameters", chunk->m_parameters.size()); - } - } - } - } - - void AnimGraphNetSyncComponent::OnAnimGraphFloatParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - float beforeValue, - float afterValue) - { - AZ_UNUSED(beforeValue); - SetParameterOnServer(static_cast(parameterIndex), afterValue); - } - - void AnimGraphNetSyncComponent::OnAnimGraphBoolParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - bool beforeValue, - bool afterValue) - { - AZ_UNUSED(beforeValue); - SetParameterOnServer(static_cast(parameterIndex), afterValue); - } - - void AnimGraphNetSyncComponent::OnAnimGraphStringParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const char* beforeValue, - const char* afterValue) - { - AZ_UNUSED(parameterIndex); - AZ_UNUSED(beforeValue); - AZ_UNUSED(afterValue); - AZ_Warning("EMotionFX", false, "AnimGraphNetSync component does not supported synchronizing string parameters, please consider refactoring your anim graph to replace strings with integers or enum values."); - } - - void AnimGraphNetSyncComponent::OnAnimGraphVector2ParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const AZ::Vector2& beforeValue, - const AZ::Vector2& afterValue) - { - AZ_UNUSED(beforeValue); - SetParameterOnServer(static_cast(parameterIndex), afterValue); - } - - void AnimGraphNetSyncComponent::OnAnimGraphVector3ParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const AZ::Vector3& beforeValue, - const AZ::Vector3& afterValue) - { - AZ_UNUSED(beforeValue); - SetParameterOnServer(static_cast(parameterIndex), afterValue); - } - - void AnimGraphNetSyncComponent::OnAnimGraphRotationParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const AZ::Quaternion& beforeValue, - const AZ::Quaternion& afterValue) - { - AZ_UNUSED(beforeValue); - SetParameterOnServer(static_cast(parameterIndex), afterValue); - } - - void AnimGraphNetSyncComponent::OnActiveNodesChanged(const NodeIndexContainer& activeNodes, const GridMate::TimeContext& tc) - { - AZ_UNUSED(tc); - // Client receiving values - if (m_instance) - { - if (const AZStd::shared_ptr snapshot = m_instance->GetSnapshot()) - { - snapshot->SetActiveNodes(activeNodes); - } - } - } - - void AnimGraphNetSyncComponent::OnMotionNodesChanged(const MotionNodePlaytimeContainer& motionNodes, const GridMate::TimeContext& tc) - { - AZ_UNUSED(tc); - // Client receiving values - if (m_instance) - { - if (const AZStd::shared_ptr snapshot = m_instance->GetSnapshot()) - { - snapshot->SetMotionNodePlaytimes(motionNodes); - } - } - } - - bool AnimGraphNetSyncComponent::IsDifferent(const MotionNodePlaytimeContainer& oldList, const MotionNodePlaytimeContainer& newList) const - { - if (oldList.size() != newList.size()) - { - return true; - } - - AZStd::size_t i = 0; - for (auto& value : oldList) - { - if (value.first != newList[i].first || value.second != newList[i].second) - { - return true; - } - - ++i; - } - - return false; - } - - bool AnimGraphNetSyncComponent::IsDifferent(const NodeIndexContainer& oldList, const NodeIndexContainer& newList) const - { - if (oldList.size() != newList.size()) - { - return true; - } - - AZStd::size_t i = 0; - for (AZ::u32 value : oldList) - { - if (value != newList[i]) - { - return true; - } - - ++i; - } - - return false; - } - - void AnimGraphNetSyncComponent::OnTick(float deltaTime, AZ::ScriptTimePoint time) - { - AZ_UNUSED(deltaTime); - AZ_UNUSED(time); - - if (!GetChunk()) - { - return; // network is not ready yet - } - - if (m_instance) - { - if (const AZStd::shared_ptr snapshot = m_instance->GetSnapshot()) - { - if (m_syncActiveNodes) - { - const NodeIndexContainer& activeNodes = snapshot->GetActiveNodes(); - const NodeIndexContainer& currentValue = GetChunk()->m_activeNodes.Get(); - if (IsDifferent(currentValue, activeNodes)) - { - GetChunk()->m_activeNodes.Set(activeNodes); // Server sending the values - } - } - - if (m_syncMotionNodes) - { - const MotionNodePlaytimeContainer& playTimes = snapshot->GetMotionNodePlaytimes(); - const MotionNodePlaytimeContainer& currentTimes = GetChunk()->m_motionNodes.Get(); - if (IsDifferent(currentTimes, playTimes)) - { - GetChunk()->m_motionNodes.Set(playTimes); // Server sending the values - } - } - } - } - } - - void AnimGraphNetSyncComponent::OnAnimGraphInstanceCreated(EMotionFX::AnimGraphInstance* instance) - { - m_instance = instance; - if (m_instance) - { - const bool isAuthoritative = AzFramework::NetQuery::IsEntityAuthoritative(GetEntityId()); - if (!m_instance->GetSnapshot()) - { - m_instance->CreateSnapshot(isAuthoritative); - } - } - } - - void AnimGraphNetSyncComponent::OnAnimGraphInstanceDestroyed(EMotionFX::AnimGraphInstance*) - { - m_instance = nullptr; - } - - AnimGraphNetSyncComponent::Chunk* AnimGraphNetSyncComponent::GetChunk() const - { - return static_cast(m_chunk.get()); - } - - GridMate::ReplicaChunkPtr AnimGraphNetSyncComponent::GetNetworkBinding() - { - m_chunk = GridMate::CreateReplicaChunk(); - AZ_Assert(m_chunk, "Failed to create a chunk"); - - if (m_instance) - { - if (!m_instance->GetSnapshot()) - { - m_instance->CreateSnapshot(true /* authoritative */); - } - } - - return m_chunk; - } - - void AnimGraphNetSyncComponent::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) - { - m_chunk = chunk; - m_chunk->SetHandler(this); - } - - void AnimGraphNetSyncComponent::UnbindFromNetwork() - { - AZ_Assert(m_chunk, "There wasn't any chunk present"); - if (m_chunk) - { - m_chunk->SetHandler(nullptr); - m_chunk = nullptr; - } - } - } - } // namespace Integration -} // namespace EMotionFXAnimation diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.h b/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.h deleted file mode 100644 index b6cfc2c795..0000000000 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace EMotionFX -{ - namespace Integration - { - namespace Network - { - /** - * \brief Generic solution for synchronizing parameters of Anim Graph component. - * Synchronization is done over GridMate. - * - * Note that this is not the most optimal synchronization but it does - * work for just about all Anim Graphs. - * - * Disclaimer: string parameters are not supported! Because one should not synchronize - * strings over the network. They ought to be converted to enum/int values beforehand. - */ - class AnimGraphNetSyncComponent - : public AZ::Component - , public AzFramework::NetBindable - , public AnimGraphComponentNotificationBus::Handler - , public AZ::TickBus::Handler - { - public: - AZ_COMPONENT(AnimGraphNetSyncComponent, "{2F9428C1-0F07-4667-B052-40D9BC473AD3}", NetBindable); - - static void Reflect(AZ::ReflectContext* context); - - // AZ::Component interface implementation - void Activate() override; - void Deactivate() override; - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("EMotionFXAnimGraphNetSyncService", 0x42e6f127)); - } - - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("EMotionFXAnimGraphNetSyncService", 0x42e6f127)); - } - - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.push_back(AZ_CRC("EMotionFXAnimGraphService", 0x9ec3c819)); - required.push_back(AZ_CRC("ReplicaChunkService", 0xf86b88a8)); - } - - protected: - // NetBindable interface implementation - GridMate::ReplicaChunkPtr GetNetworkBinding() override; - void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) override; - void UnbindFromNetwork() override; - - // AnimGraphComponentNotificationBus interface implementation - void OnAnimGraphFloatParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - float beforeValue, - float afterValue) override; - void OnAnimGraphBoolParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - bool beforeValue, - bool afterValue) override; - void OnAnimGraphStringParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const char* beforeValue, - const char* afterValue) override; - void OnAnimGraphVector2ParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const AZ::Vector2& beforeValue, - const AZ::Vector2& afterValue) override; - void OnAnimGraphVector3ParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const AZ::Vector3& beforeValue, - const AZ::Vector3& afterValue) override; - void OnAnimGraphRotationParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const AZ::Quaternion& beforeValue, - const AZ::Quaternion& afterValue) override; - - // TickBus - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; - - // AnimGraphComponentNotificationBus - void OnAnimGraphInstanceCreated(EMotionFX::AnimGraphInstance* instance) override; - void OnAnimGraphInstanceDestroyed(EMotionFX::AnimGraphInstance* instance) override; - - private: - class Chunk; - GridMate::ReplicaChunkPtr m_chunk; - Chunk* GetChunk() const; - - // DataSet callback, it's a template to avoid duplicating similar callbacks - template - void OnAnimParameterChanged(const AnimParameter& value, const GridMate::TimeContext& tc); - - // Helper on a client side - void SetParameterOnClient(const AnimParameter& value, AZ::u8 index); - - // Helper on the server side to avoid duplicating very similar callbacks - template - void SetParameterOnServer(AZ::u8 parameterIndex, const FieldType& newValue); - - /** - * \brief Optionally turn on or off replicating parameters of an anim graph on the same entity as this component. - */ - bool m_syncParameters = true; - - /** - * \brief Optionally turn on or off replicating active nodes of an anim graph on the same entity as this component. - */ - bool m_syncActiveNodes = false; - /** - * \brief Optionally turn on or off replicating motion playtime nodes of an anim graph on the same entity as this component. - * - * It's off by default because these nodes are very frequently changing and would result in a high network bandwidth use. - */ - bool m_syncMotionNodes = false; - - // GridMate DataSet callback on clients - void OnActiveNodesChanged(const NodeIndexContainer& activeNodes, const GridMate::TimeContext& tc); - // GridMate DataSet callback on clients - void OnMotionNodesChanged(const MotionNodePlaytimeContainer& motionNodes, const GridMate::TimeContext& tc); - - // Helper comparison method to avoid sending the same data - bool IsDifferent(const NodeIndexContainer& oldList, const NodeIndexContainer& newList) const; - // Helper comparison method to avoid sending the same data - bool IsDifferent(const MotionNodePlaytimeContainer& oldList, const MotionNodePlaytimeContainer& newList) const; - - EMotionFX::AnimGraphInstance* m_instance = nullptr; - }; - } - } // namespace Integration -} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncTypes.h b/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncTypes.h deleted file mode 100644 index 9194dc1b65..0000000000 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncTypes.h +++ /dev/null @@ -1,285 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -namespace EMotionFX -{ - namespace Integration - { - namespace Network - { - /** - * \brief A general storage for an anim graph parameter. - */ - class AnimParameter - { - public: - /** - * \brief String type is not supported because one should not be syncing strings over the network. - */ - enum class Type : AZ::u8 - { - Unsupported, - Float, - Bool, - Vector2, - Vector3, - Quaternion, - }; - - /** - * \brief A storage for all possible supported types in @AnimGraphNetSyncComponent - */ - union Value - { - Value() - { - q = AZ::Quaternion::CreateZero(); - } - - float f; - bool b = false; - AZ::Vector2 v2; - AZ::Vector3 v3; - AZ::Quaternion q; - }; - - AnimParameter() : m_type(Type::Unsupported) {} - - Type m_type; - Value m_value; - - AnimParameter(const AnimParameter& other) - { - m_type = other.m_type; - CopyValue(other); - } - - AnimParameter& operator=(const AnimParameter& other) - { - m_type = other.m_type; - CopyValue(other); - - return *this; - } - - friend bool operator==(const AnimParameter& lhs, const AnimParameter& rhs) - { - if (lhs.m_type != rhs.m_type) - { - return false; - } - - switch (lhs.m_type) - { - case Type::Float: - return lhs.m_value.f == rhs.m_value.f; - case Type::Bool: - return lhs.m_value.b == rhs.m_value.b; - case Type::Vector2: - return lhs.m_value.v2 == rhs.m_value.v2; - case Type::Vector3: - return lhs.m_value.v3 == rhs.m_value.v3; - case Type::Quaternion: - return lhs.m_value.q == rhs.m_value.q; - default: - return true; - } - } - - private: - void CopyValue(const AnimParameter& other) - { - switch (m_type) - { - case Type::Float: - m_value.f = other.m_value.f; - break; - case Type::Bool: - m_value.b = other.m_value.b; - break; - case Type::Vector2: - m_value.v2 = other.m_value.v2; - break; - case Type::Vector3: - m_value.v3 = other.m_value.v3; - break; - case Type::Quaternion: - m_value.q = other.m_value.q; - break; - default: - break; - } - } - }; - - /** - * \brief Custom GridMate throttler. See GridMate:: @BasicThrottle - */ - class AnimParameterThrottler - { - public: - bool WithinThreshold(const AnimParameter& newValue) const - { - return m_baseline == newValue; - } - - void UpdateBaseline(const AnimParameter& baseline) - { - m_baseline = baseline; - } - - private: - AnimParameter m_baseline; - }; - - /** - * \brief A custom GridMate marshaler. - * 1 byte is spend on the type. And a variable number of bytes afterwards for the value. - */ - class AnimParameterMarshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, const AnimParameter& parameter) - { - wb.Write(AZ::u8(parameter.m_type)); - - switch (parameter.m_type) - { - case AnimParameter::Type::Float: - wb.Write(parameter.m_value.f); - break; - case AnimParameter::Type::Bool: - wb.Write(parameter.m_value.b); - break; - case AnimParameter::Type::Vector2: - wb.Write(parameter.m_value.v2); - break; - case AnimParameter::Type::Vector3: - wb.Write(parameter.m_value.v3); - break; - case AnimParameter::Type::Quaternion: - wb.Write(parameter.m_value.q); - break; - default: - // other types are not supported - break; - } - } - - void Unmarshal(AnimParameter& parameter, GridMate::ReadBuffer& rb) - { - AZ::u8 type; - rb.Read(type); - parameter.m_type = static_cast(type); - - switch (parameter.m_type) - { - case AnimParameter::Type::Float: - rb.Read(parameter.m_value.f); - break; - case AnimParameter::Type::Bool: - rb.Read(parameter.m_value.b); - break; - case AnimParameter::Type::Vector2: - rb.Read(parameter.m_value.v2); - break; - case AnimParameter::Type::Vector3: - rb.Read(parameter.m_value.v3); - break; - case AnimParameter::Type::Quaternion: - rb.Read(parameter.m_value.q); - break; - default: - // other types are not supported - break; - } - } - }; - - /** - * \brief Custom marshaler for Animation node index that is used by Activate Nodes list - */ - struct NodeIndexContainerMarshaler - { - void Marshal(GridMate::WriteBuffer& wb, const NodeIndexContainer& source) const - { - GridMate::VlqU64Marshaler m64; - GridMate::VlqU32Marshaler m32; - - m64.Marshal(wb, source.size()); // 1 byte most of the time (if the size is less than 127) - for (AZ::u32 item : source) - { - m32.Marshal(wb, item); // 1 byte most of the time (if the value is less than 127) - } - } - - void Unmarshal(NodeIndexContainer& target, GridMate::ReadBuffer& rb) const - { - target.clear(); - GridMate::VlqU64Marshaler m64; - GridMate::VlqU32Marshaler m32; - - AZ::u64 arraySize; - m64.Unmarshal(arraySize, rb); - target.resize(arraySize); - - for (AZ::u64 i = 0; i < arraySize; ++i) - { - m32.Unmarshal(target[i], rb); - } - } - }; - - /** - * \brief Custom marshaler for Animation motion node information that is used by motion node playtime list - */ - struct MotionNodePlaytimeContainerMarshaler - { - void Marshal(GridMate::WriteBuffer& wb, const MotionNodePlaytimeContainer& source) const - { - GridMate::VlqU64Marshaler m64; - GridMate::VlqU32Marshaler m32; - - m64.Marshal(wb, source.size()); - for (const AZStd::pair& item : source) - { - m32.Marshal(wb, item.first); // average of 1 byte - wb.Write(item.second); // 4 bytes - } - } - - void Unmarshal(MotionNodePlaytimeContainer& target, GridMate::ReadBuffer& rb) const - { - target.clear(); - GridMate::VlqU64Marshaler m64; - GridMate::VlqU32Marshaler m32; - - AZ::u64 arraySize; - m64.Unmarshal(arraySize, rb); - target.resize(arraySize); - - for (AZ::u64 i = 0; i < arraySize; ++i) - { - m32.Unmarshal(target[i].first, rb); - rb.Read(target[i].second); - } - } - }; - } - } // namespace Integration -} // namespace EMotionFXAnimation diff --git a/Gems/EMotionFX/Code/Source/Integration/System/AnimationModule.cpp b/Gems/EMotionFX/Code/Source/Integration/System/AnimationModule.cpp index 4d7db16133..e5561697fd 100644 --- a/Gems/EMotionFX/Code/Source/Integration/System/AnimationModule.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/System/AnimationModule.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -74,8 +73,6 @@ namespace EMotionFX AnimGraphComponent::CreateDescriptor(), SimpleMotionComponent::CreateDescriptor(), SimpleLODComponent::CreateDescriptor(), - - Network::AnimGraphNetSyncComponent::CreateDescriptor(), #if defined(EMOTIONFXANIMATION_EDITOR) // Pipeline components diff --git a/Gems/EMotionFX/Code/emotionfx_shared_files.cmake b/Gems/EMotionFX/Code/emotionfx_shared_files.cmake index 0c7e4ef0e7..88c6525f91 100644 --- a/Gems/EMotionFX/Code/emotionfx_shared_files.cmake +++ b/Gems/EMotionFX/Code/emotionfx_shared_files.cmake @@ -31,9 +31,6 @@ set(FILES Source/Integration/Components/ActorComponent.cpp Source/Integration/Components/AnimAudioComponent.h Source/Integration/Components/AnimAudioComponent.cpp - Source/Integration/Components/AnimGraphNetSyncComponent.h - Source/Integration/Components/AnimGraphNetSyncTypes.h - Source/Integration/Components/AnimGraphNetSyncComponent.cpp Source/Integration/Components/AnimGraphComponent.h Source/Integration/Components/AnimGraphComponent.cpp Source/Integration/Components/SimpleMotionComponent.h diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp index ba1d34fea0..d5745cf3cc 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp @@ -19,11 +19,9 @@ #include #include #include -#include #include #include #include -#include #if !defined(_RELEASE) && !defined(PERFORMANCE_BUILD) #define SCRIPT_CANVAS_RUNTIME_ASSET_CHECK @@ -163,8 +161,6 @@ namespace ScriptCanvas ->Field("m_variableOverrides", &RuntimeComponent::m_variableOverrides) ; } - - GraphVariableNetBindingTable::Reflect(context); } void RuntimeComponent::SetVariableOverrides(const VariableData& overrideData) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h index ef90155e41..81f46d27b9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h @@ -15,8 +15,6 @@ #include #include -#include - #include #include #include @@ -41,11 +39,10 @@ namespace ScriptCanvas //! This component should only be used at runtime class RuntimeComponent : public AZ::Component - , public AzFramework::NetBindable , public AZ::EntityBus::Handler { public: - AZ_COMPONENT(RuntimeComponent, "{95BFD916-E832-4956-837D-525DE8384282}", NetBindable); + AZ_COMPONENT(RuntimeComponent, "{95BFD916-E832-4956-837D-525DE8384282}", AZ::Component); static void Reflect(AZ::ReflectContext* context); @@ -67,8 +64,6 @@ namespace ScriptCanvas const VariableData& GetVariableOverrides() const; - void SetNetworkBinding(GridMate::ReplicaChunkPtr) {} - void SetVariableOverrides(const VariableData& overrideData); protected: @@ -103,8 +98,6 @@ namespace ScriptCanvas void StopExecution(); - void UnbindFromNetwork(void) {} - private: AZ::Data::Asset m_runtimeAsset; ExecutionStatePtr m_executionState; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp deleted file mode 100644 index 8d8db1d876..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ScriptCanvas -{ - void DatumMarshaler::SetNetBindingTable(GraphVariableNetBindingTable* netBindingTable) - { - m_graphVariableNetBindingTable = netBindingTable; - } - - void DatumMarshaler::Marshal(GridMate::WriteBuffer& wb, const Datum* const & property) const - { - if (!property) - { - return; - } - - GridMate::Marshaler typeMarshaler; - const Data::eType& datumType = property->GetType().GetType(); - typeMarshaler.Marshal(wb, datumType); - - VariableId assetVariableId; - AZStd::unordered_map>& variableIdMap = m_graphVariableNetBindingTable->GetVariableIdMap(); - - for (AZStd::pair>& pair : variableIdMap) - { - AZStd::pair& variableIndexPair = pair.second; - - if (variableIndexPair.first->GetDatum() == property) - { - assetVariableId = m_graphVariableNetBindingTable->FindAssetVariableIdByRuntimeVariableId(pair.first); - break; - } - } - - if (!assetVariableId.IsValid()) - { - return; - } - - GridMate::Marshaler uuidMarshaler; - uuidMarshaler.Marshal(wb, assetVariableId.GetDatumId()); - - AZStd::string uuidString = assetVariableId.m_id.ToString(); - - switch (datumType) - { - case Data::eType::AABB: - MarshalType(wb, property); - break; - - case Data::eType::Boolean: - MarshalType(wb, property); - break; - - case Data::eType::Color: - MarshalType(wb, property); - break; - - case Data::eType::CRC: - MarshalType(wb, property); - break; - - case Data::eType::EntityID: - MarshalType(wb, property); - break; - - case Data::eType::Matrix3x3: - MarshalType(wb, property); - break; - - case Data::eType::Matrix4x4: - MarshalType(wb, property); - break; - - case Data::eType::NamedEntityID: - MarshalType(wb, property); - break; - - case Data::eType::Number: - MarshalType(wb, property); - break; - - case Data::eType::OBB: - MarshalType(wb, property); - break; - - case Data::eType::Plane: - MarshalType(wb, property); - break; - - case Data::eType::Quaternion: - MarshalType(wb, property); - break; - - case Data::eType::String: - MarshalType(wb, property); - break; - - case Data::eType::Transform: - MarshalType(wb, property); - break; - - case Data::eType::Vector2: - MarshalType(wb, property); - break; - - case Data::eType::Vector3: - MarshalType(wb, property); - break; - - case Data::eType::Vector4: - MarshalType(wb, property); - break; - - default: - AZ_Warning("ScriptCanvasNetworking", false, "Marshal unsupported data type"); - break; - } - } - - bool DatumMarshaler::UnmarshalToPointer(const Datum*& target, GridMate::ReadBuffer& rb) - { - // :SCTODO: for some reason, this UnmarshalToPointer can get called before SetNetworkBinding is called - // (which is where we set m_graphVariableNetBindingTable). So we check for nullptr here just in case. - if (!m_graphVariableNetBindingTable) - { - return false; - } - - ScriptCanvas::Data::eType datumType = Data::eType::Invalid; - GridMate::Marshaler typeMarshaler; - typeMarshaler.Unmarshal(datumType, rb); - - AZ::Uuid uuid; - GridMate::Marshaler uuidMarshaler; - uuidMarshaler.Unmarshal(uuid, rb); - - VariableId runtimeVariableId = m_graphVariableNetBindingTable->FindRuntimeVariableIdByAssetVariableId(VariableId(uuid)); - - if (!runtimeVariableId.IsValid()) - { - return false; - } - - AZStd::string uuidString = runtimeVariableId.m_id.ToString(); - - AZStd::unordered_map>& m_variableIdMap = m_graphVariableNetBindingTable->GetVariableIdMap(); - AZStd::pair& variableIndexPair = m_variableIdMap[runtimeVariableId]; - GraphVariable* graphVariable = variableIndexPair.first; - - switch (datumType) - { - case Data::eType::AABB: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Boolean: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Color: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::CRC: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::EntityID: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Matrix3x3: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Matrix4x4: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::NamedEntityID: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Number: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::OBB: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Plane: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Quaternion: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::String: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Transform: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Vector2: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Vector3: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Vector4: - return UnmarshalType(target, rb, graphVariable); - - default: - AZ_Warning("ScriptCanvasNetworking", false, "Unmarshal unsupported data type"); - break; - } - - return false; - } - - void DatumThrottler::SignalDirty() - { - m_isDirty = true; - } - - bool DatumThrottler::WithinThreshold(const Datum* newValue) const - { - return (newValue == nullptr || !m_isDirty); - } - - void DatumThrottler::UpdateBaseline([[maybe_unused]] const Datum* baseline) - { - m_isDirty = false; - } -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.h deleted file mode 100644 index 5fd8c3fa0d..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include -#include -#include -#include - -namespace ScriptCanvas -{ - class GraphVariableNetBindingTable; - - class DatumMarshaler - { - public: - void SetNetBindingTable(GraphVariableNetBindingTable* netBindingTable); - void Marshal(GridMate::WriteBuffer& wb, const Datum* const & cont) const; - bool UnmarshalToPointer(const Datum*& target, GridMate::ReadBuffer& rb); - - private: - template - void MarshalType(GridMate::WriteBuffer& wb, const Datum* const & property) const - { - GridMate::Marshaler marshaler; - const T* value = property->GetAs(); - marshaler.Marshal(wb, *value); - } - - template - bool UnmarshalType(const Datum*& target, GridMate::ReadBuffer& rb, GraphVariable* graphVariable) - { - bool valueChanged = false; - ModifiableDatumView datumView; - - if (graphVariable) - { - graphVariable->ConfigureDatumView(datumView); - - if (datumView.IsValid()) - { - GridMate::Marshaler marshaler; - T value; - - marshaler.Unmarshal(value, rb); - datumView.SetAs(value); - target = graphVariable->GetDatum(); - valueChanged = true; - } - } - - return valueChanged; - } - - private: - //! The network binding table is needed to determine which Datum to update - //! when unmarshaling data. - // :SCTODO: synced Datums should be tracked via ID - //! and that ID should be used to lookup Datums (right now we can assume - //! which Datum should be updated, since only one Datum is supported). - GraphVariableNetBindingTable* m_graphVariableNetBindingTable = nullptr; - }; - - //! Simple throttler that simple operates via dirty flag. - class DatumThrottler - { - public: - DatumThrottler() = default; - - void SignalDirty(); - bool WithinThreshold(const Datum* newValue) const; - void UpdateBaseline(const Datum* baseline); - - private: - bool m_isDirty = false; - }; -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp deleted file mode 100644 index e30cb95255..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include - -namespace ScriptCanvas -{ - const char* DatumDataSet::GetDataSetName() - { - static size_t s_chunkIndex = 0; - static const char* s_nameArray[] = { - "DataSet1","DataSet2","DataSet3","DataSet4","DataSet5", - "DataSet6","DataSet7","DataSet8","DataSet9","DataSet10", - "DataSet11","DataSet12","DataSet13","DataSet14","DataSet15", - "DataSet16","DataSet17","DataSet18","DataSet19","DataSet20", - "DataSet21","DataSet22","DataSet23","DataSet24","DataSet25", - "DataSet26","DataSet27","DataSet28","DataSet29","DataSet30", - "DataSet31","DataSet32" - }; - - if (s_chunkIndex > AZ_ARRAY_SIZE(s_nameArray) && AZ_ARRAY_SIZE(s_nameArray) >= 0) - { - s_chunkIndex = s_chunkIndex % AZ_ARRAY_SIZE(s_nameArray); - } - - return s_nameArray[s_chunkIndex++]; - } - - DatumDataSet::DatumDataSet() - : DatumDataSetType(DatumDataSet::GetDataSetName()) - { - } - - ////////////////////////// - // GraphVariableReplicaChunk - ////////////////////////// - - const char* GraphVariableReplicaChunk::GetChunkName() - { - return "GraphVariableReplicaChunk"; - } - - bool GraphVariableReplicaChunk::IsReplicaMigratable() - { - return true; - } - - ////////////////////////// - // GraphVariableNetBindingTable - ////////////////////////// - - void GraphVariableNetBindingTable::Reflect([[maybe_unused]] AZ::ReflectContext* reflect) - { - GridMate::ReplicaChunkDescriptorTable& descriptorTable = GridMate::ReplicaChunkDescriptorTable::Get(); - AZ::Crc32 hash = GridMate::ReplicaChunkClassId(GraphVariableReplicaChunk::GetChunkName()); - - if (!descriptorTable.FindReplicaChunkDescriptor(hash)) - { - descriptorTable.RegisterChunkType(); - } - } - - GridMate::ReplicaChunkPtr GraphVariableNetBindingTable::GetNetworkBinding() - { - if (!m_replicaChunk) - { - m_replicaChunk = GridMate::CreateReplicaChunk(); - m_replicaChunk->SetHandler(this); - SetGraphNetBindingTable(); - } - - return m_replicaChunk; - } - - void GraphVariableNetBindingTable::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) - { - m_replicaChunk = chunk; - m_replicaChunk->SetHandler(this); - SetGraphNetBindingTable(); - } - - void GraphVariableNetBindingTable::UnbindFromNetwork() - { - if (m_replicaChunk) - { - m_replicaChunk->SetHandler(nullptr); - m_replicaChunk = nullptr; - } - } - - void GraphVariableNetBindingTable::OnPropertyUpdate([[maybe_unused]] const Datum* const & scriptProperty, [[maybe_unused]] const GridMate::TimeContext& tc) - { - } - - void GraphVariableNetBindingTable::AddDatum(GraphVariable* variable) - { - size_t index = m_variableIdMap.size(); - - m_variableIdMap[variable->GetVariableId()] = AZStd::make_pair(variable, static_cast(index)); - } - - void GraphVariableNetBindingTable::OnDatumChanged(GraphVariable& variable) - { - if (m_replicaChunk && m_replicaChunk->IsMaster()) - { - GraphVariableReplicaChunk* graphVarChunk = static_cast(m_replicaChunk.get()); - auto iter = m_variableIdMap.find(variable.GetVariableId()); - - if (iter == m_variableIdMap.end()) - { - AZ_TracePrintf("ScriptCanvasNetworking", "GraphVariableNetBindingTable::OnDatumChanged: variable not found"); - return; - } - - const AZStd::pair& pair = iter->second; - DatumDataSet& datumDataSet = graphVarChunk->m_properties[pair.second]; - datumDataSet.GetThrottler().SignalDirty(); - datumDataSet.Set(variable.GetDatum()); - } - } - - void GraphVariableNetBindingTable::SetVariableMappings(const AZStd::unordered_map& assetToRuntimeVariableMap, const AZStd::unordered_map& runtimeToAssetVariableMap) - { - m_assetToRuntimeVariableMap = assetToRuntimeVariableMap; - m_runtimeToAssetVariableMap = runtimeToAssetVariableMap; - } - - VariableId GraphVariableNetBindingTable::FindAssetVariableIdByRuntimeVariableId(VariableId runtimeVariableId) - { - auto iter = m_runtimeToAssetVariableMap.find(runtimeVariableId); - - if (iter != m_runtimeToAssetVariableMap.end()) - { - return iter->second; - } - - return VariableId(); - } - - VariableId GraphVariableNetBindingTable::FindRuntimeVariableIdByAssetVariableId(VariableId assetVariableId) - { - auto iter = m_assetToRuntimeVariableMap.find(assetVariableId); - - if (iter != m_assetToRuntimeVariableMap.end()) - { - return iter->second; - } - - return VariableId(); - } - - AZStd::unordered_map>& GraphVariableNetBindingTable::GetVariableIdMap() - { - return m_variableIdMap; - } - - void GraphVariableNetBindingTable::SetGraphNetBindingTable() - { - GraphVariableReplicaChunk* graphVariableChunk = static_cast(m_replicaChunk.get()); - - for (DatumDataSet& dataSet : graphVariableChunk->m_properties) - { - dataSet.GetMarshaler().SetNetBindingTable(this); - } - } -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.h deleted file mode 100644 index d0f945523d..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include -#include -#include -#include -#include - -namespace ScriptCanvas -{ - class GraphVariable; - class GraphVariableReplicaChunk; - - //! Core functionality for managing replicated Datums in a script canvas and the - //! corresponding GridMate callbacks and data structs (DataSets). - class GraphVariableNetBindingTable - : public GridMate::ReplicaChunkInterface - { - public: - AZ_CLASS_ALLOCATOR(GraphVariableNetBindingTable, AZ::SystemAllocator, 0); - - static void Reflect(AZ::ReflectContext* reflect); - - GraphVariableNetBindingTable() = default; - ~GraphVariableNetBindingTable() = default; - - GridMate::ReplicaChunkPtr GetNetworkBinding(); - void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk); - void UnbindFromNetwork(); - - //! Gets called when the given Datum object is updated with a new value - //! that was received over the network. - void OnPropertyUpdate(const Datum* const & scriptProperty, const GridMate::TimeContext& tc); - - //! Adds the given Datum to the list of "synced datums" for this instance. - void AddDatum(GraphVariable* variable); - - //! Called when local data changes for a Datum whose values should be replicated - //! over the network. - void OnDatumChanged(GraphVariable& variable); - - void SetVariableMappings(const AZStd::unordered_map& assetToRuntimeVariableMap, const AZStd::unordered_map& runtimeToAssetVariableMap); - VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeVariableId); - VariableId FindRuntimeVariableIdByAssetVariableId(VariableId assetVariableId); - AZStd::unordered_map>& GetVariableIdMap(); - - private: - void SetGraphNetBindingTable(); - - private: - AZStd::unordered_map m_assetToRuntimeVariableMap; - AZStd::unordered_map m_runtimeToAssetVariableMap; - - //! Replica chunk used for GridMate networking binding. See GraphVariableReplicaChunk. - GridMate::ReplicaChunkPtr m_replicaChunk; - - //! Contains pointers to all replicated variables contained within the runtime component - //! of the canvas this net binding is associated with. - AZStd::unordered_map> m_variableIdMap; - }; - - typedef GridMate::DataSet::BindInterface DatumDataSetType; - - class DatumDataSet - : public DatumDataSetType - { - public: - DatumDataSet(); - ~DatumDataSet() = default; - - private: - const char* GetDataSetName(); - }; - - class GraphVariableReplicaChunk - : public GridMate::ReplicaChunkBase - { - public: - AZ_CLASS_ALLOCATOR(GraphVariableReplicaChunk, AZ::SystemAllocator, 0); - - static const char* GetChunkName(); - - GraphVariableReplicaChunk() = default; - ~GraphVariableReplicaChunk() = default; - - bool IsReplicaMigratable() override; - - DatumDataSet m_properties[GM_MAX_DATASETS_IN_CHUNK]; - }; -} diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 871d8d4c5d..84391021df 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -597,10 +597,6 @@ set(FILES Include/ScriptCanvas/Variable/GraphVariable.cpp Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp - Include/ScriptCanvas/Variable/GraphVariableNetBindings.h - Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp - Include/ScriptCanvas/Variable/GraphVariableMarshal.h - Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp Include/ScriptCanvas/Variable/VariableCore.h Include/ScriptCanvas/Variable/VariableCore.cpp Include/ScriptCanvas/Variable/VariableData.h From b5e87d3601d6fadf2a7f92531d317463efbb0cec Mon Sep 17 00:00:00 2001 From: mbalfour Date: Tue, 11 May 2021 16:13:04 -0500 Subject: [PATCH 127/225] Change SerializeContextTools into a ToolsApplication so that it can correctly read in slice data: - Uses ToolsApplication instead of ComponentApplication so that built-in Editor components are recognized and read in correctly - Starts up all the DynamicModules immediately so that the System Components are activated, which registers asset handlers and allows asset references to serialize in correctly - Adds a -specialization command-line flag to specify which project specialization to use (editor, game, etc) - Removes the filter to ignore unknown classes since they should all now be "known" - Adds a few gem autoload flags and a null thumbnail service so that Qt and Python systems can be skipped, as they aren't needed for the data conversions and would bring additional overhead and complications --- .../SerializeContextTools/Application.cpp | 43 ++++++++++++++++--- .../Tools/SerializeContextTools/Application.h | 5 ++- .../SerializeContextTools/CMakeLists.txt | 2 + .../Tools/SerializeContextTools/Utilities.cpp | 1 - Code/Tools/SerializeContextTools/main.cpp | 7 +-- .../gem_autoload.serializecontexttools.setreg | 15 +++++++ 6 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 Registry/gem_autoload.serializecontexttools.setreg diff --git a/Code/Tools/SerializeContextTools/Application.cpp b/Code/Tools/SerializeContextTools/Application.cpp index 2ab9847aa6..72e68ebb1e 100644 --- a/Code/Tools/SerializeContextTools/Application.cpp +++ b/Code/Tools/SerializeContextTools/Application.cpp @@ -16,12 +16,23 @@ #include #include +#include + namespace AZ { + // SerializeContextTools is a full ToolsApplication that will load a project's Gem DLLs and initialize the system components. + // This level of initialization is required to get all the serialization contexts and asset handlers registered, so that when + // data transformations take place, none of the data is dropped due to not being recognized. + // However, as a simplification, anything requiring Python or Qt is skipped during initialization: + // - The gem_autoload.serializecontexttools.setreg file disables autoload for QtForPython, EditorPythonBindings, and PythonAssetBuilder + // - The system component initialization below uses ThumbnailerNullComponent so that other components relying on a ThumbnailService + // can still be started up, but the thumbnail service itself won't do anything. The real ThumbnailerComponent uses Qt, which is why + // it isn't used. + namespace SerializeContextTools { Application::Application(int argc, char** argv) - : AZ::ComponentApplication(argc, argv) + : AzToolsFramework::ToolsApplication(&argc, &argv) { AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath(); if (projectPath.empty()) @@ -51,14 +62,25 @@ namespace AZ else { AZ::SettingsRegistryInterface::Specializations projectSpecializations{ projectName }; - AZ::IO::PathView configFilenameStem = m_configFilePath.Stem(); - if (AZ::StringFunc::Equal(configFilenameStem.Native(), "Editor")) + + // If a project specialization has been passed in via the command line, use it. + if (m_commandLine.HasSwitch("specialization")) { - projectSpecializations.Append("editor"); + AZStd::string specialization = m_commandLine.GetSwitchValue("specialization", 0); + projectSpecializations.Append(specialization); } - else if (AZ::StringFunc::Equal(configFilenameStem.Native(), "Game")) + // Otherwise, if a config file was passed in, auto-set the specialization based on the config file name. + else { - projectSpecializations.Append(projectName + "_GameLauncher"); + AZ::IO::PathView configFilenameStem = m_configFilePath.Stem(); + if (AZ::StringFunc::Equal(configFilenameStem.Native(), "Editor")) + { + projectSpecializations.Append("editor"); + } + else if (AZ::StringFunc::Equal(configFilenameStem.Native(), "Game")) + { + projectSpecializations.Append(projectName + "_GameLauncher"); + } } // Used the project specializations to merge the build dependencies *.setreg files @@ -78,5 +100,14 @@ namespace AZ AZ::ComponentApplication::SetSettingsRegistrySpecializations(specializations); specializations.Append("serializecontexttools"); } + + AZ::ComponentTypeList Application::GetRequiredSystemComponents() const + { + // Use all of the default system components, but also add in the ThumbnailerNullComponent so that components requiring + // a ThumbnailService can still be started up. + AZ::ComponentTypeList components = AzToolsFramework::ToolsApplication::GetRequiredSystemComponents(); + components.emplace_back(azrtti_typeid()); + return components; + } } // namespace SerializeContextTools } // namespace AZ diff --git a/Code/Tools/SerializeContextTools/Application.h b/Code/Tools/SerializeContextTools/Application.h index 63bc1892ed..b1b818e27d 100644 --- a/Code/Tools/SerializeContextTools/Application.h +++ b/Code/Tools/SerializeContextTools/Application.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace AZ @@ -20,13 +20,14 @@ namespace AZ namespace SerializeContextTools { class Application final - : public AZ::ComponentApplication + : public AzToolsFramework::ToolsApplication { public: Application(int argc, char** argv); ~Application() override = default; const char* GetConfigFilePath() const; + AZ::ComponentTypeList GetRequiredSystemComponents() const override; protected: void SetSettingsRegistrySpecializations(AZ::SettingsRegistryInterface::Specializations& specializations) override; diff --git a/Code/Tools/SerializeContextTools/CMakeLists.txt b/Code/Tools/SerializeContextTools/CMakeLists.txt index 1a993de53c..e73fd014ab 100644 --- a/Code/Tools/SerializeContextTools/CMakeLists.txt +++ b/Code/Tools/SerializeContextTools/CMakeLists.txt @@ -29,4 +29,6 @@ ly_add_target( BUILD_DEPENDENCIES PRIVATE AZ::AzCore + AZ::AzFramework + AZ::AzToolsFramework ) diff --git a/Code/Tools/SerializeContextTools/Utilities.cpp b/Code/Tools/SerializeContextTools/Utilities.cpp index 127f833f6b..1c50466443 100644 --- a/Code/Tools/SerializeContextTools/Utilities.cpp +++ b/Code/Tools/SerializeContextTools/Utilities.cpp @@ -236,7 +236,6 @@ namespace AZ::SerializeContextTools AZ::IO::MemoryStream stream(data.data(), fileLength); ObjectStream::FilterDescriptor filter; - filter.m_flags = ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES; // Never load dependencies. That's another file that would need to be processed // separately from this one. filter.m_assetCB = AZ::Data::AssetFilterNoAssetLoading; diff --git a/Code/Tools/SerializeContextTools/main.cpp b/Code/Tools/SerializeContextTools/main.cpp index ee505c9cc0..4bff597d81 100644 --- a/Code/Tools/SerializeContextTools/main.cpp +++ b/Code/Tools/SerializeContextTools/main.cpp @@ -23,6 +23,7 @@ void PrintHelp() AZ_Printf("Help", "Serialize Context Tool\n"); AZ_Printf("Help", " [-config] *\n"); AZ_Printf("Help", " [opt] -config=: optional path to application's config file. Default is 'config/editor.xml'.\n"); + AZ_Printf("Help", " [opt] -specialization=: optional Registry project specialization, such as 'editor' or 'game'. Default is none. \n"); AZ_Printf("Help", "\n"); AZ_Printf("Help", " 'help': Print this help\n"); AZ_Printf("Help", " example: 'help'\n"); @@ -81,11 +82,7 @@ int main(int argc, char** argv) bool result = false; Application application(argc, argv); AZ::ComponentApplication::StartupParameters startupParameters; - startupParameters.m_loadDynamicModules = false; - application.Create({}, startupParameters); - // Load the DynamicModules after the Application starts to prevent Gem System Components - // from activating - application.LoadDynamicModules(); + application.Start({}, startupParameters); const AZ::CommandLine* commandLine = application.GetAzCommandLine(); if (commandLine->GetNumMiscValues() < 1) diff --git a/Registry/gem_autoload.serializecontexttools.setreg b/Registry/gem_autoload.serializecontexttools.setreg new file mode 100644 index 0000000000..1f4a8931c5 --- /dev/null +++ b/Registry/gem_autoload.serializecontexttools.setreg @@ -0,0 +1,15 @@ +{ + "Amazon": { + "Gems": { + "QtForPython.Editor": { + "AutoLoad": false + }, + "EditorPythonBindings.Editor": { + "AutoLoad": false + }, + "PythonAssetBuilder.Editor": { + "AutoLoad": false + } + } + } +} From 318f97a717bf367a7a96827e3891f3dbeacd5230 Mon Sep 17 00:00:00 2001 From: karlberg Date: Tue, 11 May 2021 14:28:10 -0700 Subject: [PATCH 128/225] build fix for removed gridmate headers --- .../ViewportSelection/EditorTransformComponentSelection.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index 9388f3f5f0..c6450d03c7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -13,6 +13,9 @@ #include "EditorTransformComponentSelection.h" #include +#include +#include +#include #include #include #include From b92a1884a806a6df681ec95954a9a4e03688561c Mon Sep 17 00:00:00 2001 From: Aristo7 <5432499+Aristo7@users.noreply.github.com> Date: Tue, 11 May 2021 18:08:59 -0400 Subject: [PATCH 129/225] Addex dx12/metal builders to linux --- .../Code/Source/Platform/Linux/additional_linux_tool_deps.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake index 8fb58f5e56..942a694205 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake @@ -12,4 +12,6 @@ set(LY_RUNTIME_DEPENDENCIES Gem::Atom_RHI_Vulkan.Private Gem::Atom_RHI_Vulkan.Builders + Gem::Atom_RHI_DX12.Builders + Gem::Atom_RHI_Metal.Builders ) From 3169b3477d18572832e348527d30a766b9d43bcb Mon Sep 17 00:00:00 2001 From: karlberg Date: Tue, 11 May 2021 15:15:35 -0700 Subject: [PATCH 130/225] Adding missing files to azframework_files.cmake and fixing include errors due to network removal --- Code/Framework/AzFramework/AzFramework/Physics/WindBus.h | 1 + Code/Framework/AzFramework/AzFramework/azframework_files.cmake | 1 + .../Source/Components/ClothComponentMesh/ClothComponentMesh.h | 1 + 3 files changed, 3 insertions(+) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h b/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h index 60da2c3607..f96af2bcf9 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h @@ -13,6 +13,7 @@ #include #include +#include #include namespace Physics diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake index 135d9d36bd..48b0202a5b 100644 --- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake +++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake @@ -255,6 +255,7 @@ set(FILES Physics/ClassConverters.cpp Physics/ClassConverters.h Physics/MaterialBus.h + Physics/WindBus.h Process/ProcessCommunicator.cpp Process/ProcessCommunicator.h Process/ProcessWatcher.cpp diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.h b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.h index 4374b67e32..a1fb6d5572 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.h +++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.h @@ -14,6 +14,7 @@ #include #include +#include #include From 7f5962d1ba4f2f81da1d002f9adc1a44f6f799d7 Mon Sep 17 00:00:00 2001 From: sharmajs-amzn <82233357+sharmajs-amzn@users.noreply.github.com> Date: Tue, 11 May 2021 15:23:43 -0700 Subject: [PATCH 131/225] disable AssetJobsFloodTest.ContainerCoreTest_BasicDependencyManagement_Success test (#703) --- .../Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp index 78e2288a4c..d6122b81f1 100644 --- a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp +++ b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp @@ -1042,11 +1042,7 @@ namespace UnitTest -#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS TEST_F(AssetJobsFloodTest, DISABLED_ContainerCoreTest_BasicDependencyManagement_Success) -#else - TEST_F(AssetJobsFloodTest, ContainerCoreTest_BasicDependencyManagement_Success) -#endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS { m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect(); // Setup has already created/destroyed assets From 93ef3acb504ca8b978e12b414d09cc5c835c4ac3 Mon Sep 17 00:00:00 2001 From: Aristo7 <5432499+Aristo7@users.noreply.github.com> Date: Tue, 11 May 2021 18:43:09 -0400 Subject: [PATCH 132/225] Removing non-tool modules from tools runtime deps --- .../Source/Platform/Linux/additional_linux_tool_deps.cmake | 1 - .../Code/Source/Platform/Mac/additional_mac_tool_deps.cmake | 3 --- .../Platform/Windows/additional_windows_tool_deps.cmake | 4 ---- 3 files changed, 8 deletions(-) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake index 942a694205..908417b1f8 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake @@ -10,7 +10,6 @@ # set(LY_RUNTIME_DEPENDENCIES - Gem::Atom_RHI_Vulkan.Private Gem::Atom_RHI_Vulkan.Builders Gem::Atom_RHI_DX12.Builders Gem::Atom_RHI_Metal.Builders diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake index 0b601adf8d..445a416a68 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake @@ -10,10 +10,7 @@ # set(LY_RUNTIME_DEPENDENCIES - Gem::Atom_RHI_Metal.Private Gem::Atom_RHI_Metal.Builders Gem::Atom_RHI_Vulkan.Builders Gem::Atom_RHI_DX12.Builders - Gem::Atom_RHI_Null.Private - Gem::Atom_RHI_Null.Builders ) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake index e30a9737ac..908417b1f8 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake @@ -10,11 +10,7 @@ # set(LY_RUNTIME_DEPENDENCIES - Gem::Atom_RHI_Vulkan.Private Gem::Atom_RHI_Vulkan.Builders - Gem::Atom_RHI_DX12.Private Gem::Atom_RHI_DX12.Builders - Gem::Atom_RHI_Null.Private - Gem::Atom_RHI_Null.Builders Gem::Atom_RHI_Metal.Builders ) From b2a92b1950ab010a09d3631a7cb2bf29d83e49fa Mon Sep 17 00:00:00 2001 From: karlberg Date: Tue, 11 May 2021 16:00:15 -0700 Subject: [PATCH 133/225] Removing test that required netbinding on the AzFramework TransformComponent --- .../Code/Tests/Builders/LevelBuilderTest.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Gems/LmbrCentral/Code/Tests/Builders/LevelBuilderTest.cpp b/Gems/LmbrCentral/Code/Tests/Builders/LevelBuilderTest.cpp index 58e7e9e093..47d24f09f4 100644 --- a/Gems/LmbrCentral/Code/Tests/Builders/LevelBuilderTest.cpp +++ b/Gems/LmbrCentral/Code/Tests/Builders/LevelBuilderTest.cpp @@ -309,22 +309,6 @@ TEST_F(LevelBuilderTest, DynamicSlice_NoAssetReferences_HasNoProductDependencies ASSERT_EQ(productPathDependencies.size(), 0); } -TEST_F(LevelBuilderTest, DynamicSlice_HasAssetReference_HasCorrectProductDependency) -{ - LevelBuilderWorker worker; - AZStd::vector productDependencies; - ProductPathDependencySet productPathDependencies; - - AZStd::string filePath(GetTestFileAliasedPath("levelSlice_oneAssetRef.entities_xml")); - ASSERT_TRUE(AZ::IO::FileIOBase::GetInstance()->Exists(filePath.c_str())); - - worker.PopulateLevelSliceDependenciesHelper(filePath, productDependencies, productPathDependencies); - ASSERT_EQ(productPathDependencies.size(), 0); - ASSERT_EQ(productDependencies.size(), 1); - ASSERT_EQ(productDependencies[0].m_dependencyId.m_guid, AZ::Uuid("A8970A25-5043-5519-A927-F180E7D6E8C1")); - ASSERT_EQ(productDependencies[0].m_dependencyId.m_subId, 1); -} - void BuildSliceWithSimpleAssetReference(const AZStd::vector& filePaths, AZStd::vector& productDependencies, ProductPathDependencySet& productPathDependencies) { auto* assetComponent = aznew MockSimpleAssetRefComponent; From a2a315a6cd4d2e6bf4d9ade57e753c4e8b34528d Mon Sep 17 00:00:00 2001 From: catdo Date: Tue, 11 May 2021 16:29:26 -0700 Subject: [PATCH 134/225] Fixed all nits and took out the general module and its usage --- .../Gem/PythonTests/CMakeLists.txt | 5 +- .../PrefabLevel_OpensLevelWithEntities.py | 62 +++++++++---------- ...{TestSuite_Active.py => TestSuite_Main.py} | 18 +++--- .../Gem/PythonTests/prefab/__init__.py | 2 +- 4 files changed, 39 insertions(+), 48 deletions(-) rename AutomatedTesting/Gem/PythonTests/prefab/{TestSuite_Active.py => TestSuite_Main.py} (61%) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index e4b68b6120..86bcb967ab 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -129,11 +129,10 @@ endif() NAME AutomatedTesting::PrefabTests TEST_SUITE main TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/prefab/TestSuite_Active.py - TIMEOUT 3600 + PATH ${CMAKE_CURRENT_LIST_DIR}/prefab/TestSuite_Main.py + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets ) diff --git a/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py index 45f44474e1..ca59bbc2f8 100644 --- a/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py +++ b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py @@ -9,22 +9,19 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """ - # fmt:off -class Tests (): +class Tests(): find_empty_entity = ("Entity: 'EmptyEntity' found", "Entity: 'EmptyEntity' *not* found in level") - empty_entity_pos = ( - "'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position") + empty_entity_pos = ("'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position") find_pxentity = ("Entity: 'EntityWithPxCollider' found", "Entity: 'EntityWithPxCollider' *not* found in level") - pxentity_component = ( - "Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' has *not* a Physx Collider") + pxentity_component = ("Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' has *not* a Physx Collider") # fmt:on -def PrefabLevel_OpensLevelWithEntities (): +def PrefabLevel_OpensLevelWithEntities(): """ Opens the level that contains 2 entities, "EmptyEntity" and "EntityWithPxCollider". - This test makes sure that both entities exist after openning the level and that: + This test makes sure that both entities exist after opening the level and that: - EmptyEntity is at Position: (10, 20, 30) - EntityWithPxCollider has a PhysXCollider component """ @@ -37,42 +34,41 @@ def PrefabLevel_OpensLevelWithEntities (): import editor_python_test_tools.hydra_editor_utils as hydra - import azlmbr.legacy.general as general - import azlmbr.bus + import azlmbr.entity as entity + import azlmbr.bus as bus from azlmbr.math import Vector3 - EXPECTED_EMPTY_ENTITY_POS = Vector3 (10.00, 20.0, 30.0) + EXPECTED_EMPTY_ENTITY_POS = Vector3(10.00, 20.0, 30.0) - helper.init_idle () - helper.open_level ("prefab", "PrefabLevel_OpensLevelWithEntities") + helper.init_idle() + helper.open_level("prefab", "PrefabLevel_OpensLevelWithEntities") - class EmptyEntity (): - value = None + def find_entity(entity_name): + searchFilter = entity.SearchFilter() + searchFilter.names = [entity_name] + entityIds = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter) + if entityIds[0].IsValid(): + return entityIds[0] + return None - def find_empty_entity (): - EmptyEntity.value = general.find_editor_entity ("EmptyEntity") - return EmptyEntity.value.IsValid () + helper.wait_for_condition(lambda: find_entity("EmptyEntity").IsValid(), 5.0) + empty_entity_id = find_entity("EmptyEntity") + Report.result(Tests.find_empty_entity, empty_entity_id.IsValid()) - helper.wait_for_condition (find_empty_entity, 5.0) - Report.result (Tests.find_empty_entity, EmptyEntity.value.IsValid ()) - - empty_entity_pos = azlmbr.components.TransformBus (azlmbr.bus.Event, "GetWorldTranslation", EmptyEntity.value) - is_at_position = empty_entity_pos.IsClose (EXPECTED_EMPTY_ENTITY_POS) - Report.result (Tests.empty_entity_pos, is_at_position) + empty_entity_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", empty_entity_id) + is_at_position = empty_entity_pos.IsClose(EXPECTED_EMPTY_ENTITY_POS) + Report.result(Tests.empty_entity_pos, is_at_position) if not is_at_position: - Report.info (f'Expected position: {EXPECTED_EMPTY_ENTITY_POS.ToString ()}, actual position: {empty_entity_pos.ToString ()}') + Report.info(f'Expected position: {EXPECTED_EMPTY_ENTITY_POS.ToString()}, actual position: {empty_entity_pos.ToString()}') - pxentity = general.find_editor_entity ("EntityWithPxCollider") - Report.result (Tests.find_pxentity, pxentity.IsValid ()) - - pxcollider_id = hydra.get_component_type_id ("PhysX Collider") - hasComponent = azlmbr.editor.EditorComponentAPIBus (azlmbr.bus.Broadcast, 'HasComponentOfType', pxentity, - pxcollider_id) - Report.result (Tests.pxentity_component, hasComponent) + pxentity = find_entity("EntityWithPxCollider") + Report.result(Tests.find_pxentity, pxentity.IsValid()) + pxcollider_id = hydra.get_component_type_id("PhysX Collider") + hasComponent = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'HasComponentOfType', pxentity, pxcollider_id) + Report.result(Tests.pxentity_component, hasComponent) if __name__ == "__main__": from editor_python_test_tools.utils import Report Report.start_test (PrefabLevel_OpensLevelWithEntities) - PrefabLevel_OpensLevelWithEntities () \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py similarity index 61% rename from AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Active.py rename to AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py index 3cd0a0d43d..51c78a99e2 100644 --- a/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py @@ -22,18 +22,14 @@ sys.path.append (os.path.dirname (os.path.abspath (__file__)) + '/../automatedte from base import TestAutomationBase - @pytest.mark.SUITE_main -@pytest.mark.parametrize ("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize ("project", ["AutomatedTesting"]) -class TestAutomation (TestAutomationBase): +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomation(TestAutomationBase): - def _run_prefab_test (self, request, workspace, editor, test_module): - self._run_test (request, workspace, editor, test_module, - ["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]) + def _run_prefab_test(self, request, workspace, editor, test_module): + self._run_test(request, workspace, editor, test_module, ["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]) - def test_PrefabLevel_OpensLevelWithEntities (self, request, workspace, editor, launcher_platform): + def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform): from . import PrefabLevel_OpensLevelWithEntities as test_module - - - self._run_prefab_test (request, workspace, editor, test_module) \ No newline at end of file + self._run_prefab_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/prefab/__init__.py b/AutomatedTesting/Gem/PythonTests/prefab/__init__.py index 6ed3dc4bda..79f8fa4422 100644 --- a/AutomatedTesting/Gem/PythonTests/prefab/__init__.py +++ b/AutomatedTesting/Gem/PythonTests/prefab/__init__.py @@ -7,4 +7,4 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -""" \ No newline at end of file +""" From 35500981ebcee1c344b995b4f281963dbfe3c69f Mon Sep 17 00:00:00 2001 From: karlberg Date: Tue, 11 May 2021 16:36:44 -0700 Subject: [PATCH 135/225] More removal fixes --- .../Components/TransformComponent.cpp | 2 ++ .../Code/Tests/Builders/LevelBuilderTest.cpp | 16 ++++++++++++++++ Gems/PhysX/Code/Tests/PhysXTestCommon.h | 1 + 3 files changed, 19 insertions(+) diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp index 284df15eb9..3c05887a89 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp @@ -878,6 +878,8 @@ namespace AzFramework AZ::SerializeContext* serializeContext = azrtti_cast(reflection); if (serializeContext) { + serializeContext->ClassDeprecate("NetBindable", "{80206665-D429-4703-B42E-94434F82F381}"); + serializeContext->Class() ->Version(4, &TransformComponentVersionConverter) ->Field("Parent", &TransformComponent::m_parentId) diff --git a/Gems/LmbrCentral/Code/Tests/Builders/LevelBuilderTest.cpp b/Gems/LmbrCentral/Code/Tests/Builders/LevelBuilderTest.cpp index 47d24f09f4..58e7e9e093 100644 --- a/Gems/LmbrCentral/Code/Tests/Builders/LevelBuilderTest.cpp +++ b/Gems/LmbrCentral/Code/Tests/Builders/LevelBuilderTest.cpp @@ -309,6 +309,22 @@ TEST_F(LevelBuilderTest, DynamicSlice_NoAssetReferences_HasNoProductDependencies ASSERT_EQ(productPathDependencies.size(), 0); } +TEST_F(LevelBuilderTest, DynamicSlice_HasAssetReference_HasCorrectProductDependency) +{ + LevelBuilderWorker worker; + AZStd::vector productDependencies; + ProductPathDependencySet productPathDependencies; + + AZStd::string filePath(GetTestFileAliasedPath("levelSlice_oneAssetRef.entities_xml")); + ASSERT_TRUE(AZ::IO::FileIOBase::GetInstance()->Exists(filePath.c_str())); + + worker.PopulateLevelSliceDependenciesHelper(filePath, productDependencies, productPathDependencies); + ASSERT_EQ(productPathDependencies.size(), 0); + ASSERT_EQ(productDependencies.size(), 1); + ASSERT_EQ(productDependencies[0].m_dependencyId.m_guid, AZ::Uuid("A8970A25-5043-5519-A927-F180E7D6E8C1")); + ASSERT_EQ(productDependencies[0].m_dependencyId.m_subId, 1); +} + void BuildSliceWithSimpleAssetReference(const AZStd::vector& filePaths, AZStd::vector& productDependencies, ProductPathDependencySet& productPathDependencies) { auto* assetComponent = aznew MockSimpleAssetRefComponent; diff --git a/Gems/PhysX/Code/Tests/PhysXTestCommon.h b/Gems/PhysX/Code/Tests/PhysXTestCommon.h index c4d08953eb..d130cccf9f 100644 --- a/Gems/PhysX/Code/Tests/PhysXTestCommon.h +++ b/Gems/PhysX/Code/Tests/PhysXTestCommon.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include From cdca18ca2590ddd46217398a3d63c5a5ffac7328 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Tue, 11 May 2021 18:26:05 -0700 Subject: [PATCH 136/225] Use a smart viewport context pointer in AtomFont to avoid a crash --- .../Code/Include/AtomLyIntegration/AtomFont/FFont.h | 4 ++-- Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h index 83273633be..84d53a5446 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h +++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h @@ -237,7 +237,7 @@ namespace AZ void Prepare(const char* str, bool updateTexture, const AtomFont::GlyphSize& glyphSize = AtomFont::defaultGlyphSize); void DrawStringUInternal( const RHI::Viewport& viewport, - RPI::ViewportContext* viewportContext, + RPI::ViewportContextPtr viewportContext, float x, float y, float z, @@ -291,7 +291,7 @@ namespace AZ TextDrawContext m_ctx; AZ::Vector2 m_position; AZ::Vector2 m_size; - AZ::RPI::ViewportContext* m_viewportContext; + AZ::RPI::ViewportContextPtr m_viewportContext; const AZ::RHI::Viewport* m_viewport; }; DrawParameters ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize); diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp index 48d24f0473..faeed52fb0 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp @@ -280,7 +280,7 @@ void AZ::FFont::DrawString(float x, float y, const char* str, const bool asciiMu return; } - DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext().get(), x, y, 1.0f, str, asciiMultiLine, ctx); + DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext(), x, y, 1.0f, str, asciiMultiLine, ctx); } void AZ::FFont::DrawString(float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx) @@ -290,12 +290,12 @@ void AZ::FFont::DrawString(float x, float y, float z, const char* str, const boo return; } - DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext().get(), x, y, z, str, asciiMultiLine, ctx); + DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext(), x, y, z, str, asciiMultiLine, ctx); } void AZ::FFont::DrawStringUInternal( const RHI::Viewport& viewport, - RPI::ViewportContext* viewportContext, + RPI::ViewportContextPtr viewportContext, float x, float y, float z, @@ -1686,7 +1686,7 @@ AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::Te //Code mostly duplicated from CRenderer::Draw2dTextWithDepth float posX = params.m_position.GetX(); float posY = params.m_position.GetY(); - internalParams.m_viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId).get(); + internalParams.m_viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId); const AZ::RHI::Viewport& viewport = internalParams.m_viewportContext->GetWindowContext()->GetViewport(); internalParams.m_viewport = &viewport; if (params.m_virtual800x600ScreenSize) From 6fcd5c7817a3a78172c8f98058056be710a52eb6 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Tue, 11 May 2021 18:27:47 -0700 Subject: [PATCH 137/225] Restore Viewport debug text Adds the AtomViewportDisplayInfo Gem which renders debug text to the default viewport context depending on the value of r_DisplayInfo. The gem is flagged as a dependency of AtomBridge, so all Atom projects will consume it by default. --- .../AtomBridge/Code/CMakeLists.txt | 4 + .../AtomViewportDisplayInfo/CMakeLists.txt | 12 + .../Code/CMakeLists.txt | 50 +++ ...AtomViewportDisplayInfoSystemComponent.cpp | 289 ++++++++++++++++++ .../AtomViewportDisplayInfoSystemComponent.h | 79 +++++ .../Code/Source/Module.cpp | 51 ++++ .../Code/Source/Tests/test_Main.cpp | 20 ++ .../Code/atomviewportdisplayinfo_files.cmake | 16 + .../atomviewportdisplayinfo_test_files.cmake | 14 + .../AtomViewportDisplayInfo/gem.json | 32 ++ Gems/AtomLyIntegration/CMakeLists.txt | 1 + 11 files changed, 568 insertions(+) create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/CMakeLists.txt create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Module.cpp create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Tests/test_Main.cpp create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_files.cmake create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_test_files.cmake create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt index b684e445b3..885f0d1a25 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt @@ -29,6 +29,8 @@ ly_add_target( Gem::Atom_RPI.Public Gem::Atom_Bootstrap.Headers Legacy::CryCommon + RUNTIME_DEPENDENCIES + Gem::AtomViewportDisplayInfo ) ly_add_target( @@ -68,5 +70,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AssetBuilderSDK Gem::Atom_Utils.Static Gem::Atom_AtomBridge.Static + RUNTIME_DEPENDENCIES + Gem::AtomViewportDisplayInfo ) endif() diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/CMakeLists.txt b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/CMakeLists.txt new file mode 100644 index 0000000000..20a680bce9 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +add_subdirectory(Code) diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt new file mode 100644 index 0000000000..395cc22d47 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt @@ -0,0 +1,50 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +ly_add_target( + NAME AtomViewportDisplayInfo GEM_MODULE + NAMESPACE Gem + FILES_CMAKE + atomviewportdisplayinfo_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Source + BUILD_DEPENDENCIES + PRIVATE + AZ::AzCore + AZ::AtomCore + Legacy::CryCommon + Gem::Atom_RHI.Reflect + Gem::Atom_RPI.Public +) + +################################################################################ +# Tests +################################################################################ +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) + ly_add_target( + NAME AtomViewportDisplayInfo.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE Gem + FILES_CMAKE + atomviewportdisplayinfo_test_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Include + Tests + BUILD_DEPENDENCIES + PRIVATE + AZ::AzTest + ) + ly_add_googletest( + NAME Gem::AtomViewportDisplayInfo.Tests + ) +endif() + diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp new file mode 100644 index 0000000000..394923071e --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp @@ -0,0 +1,289 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include "AtomViewportDisplayInfoSystemComponent.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +AZ_CVAR(float, r_fpsInterval, 1.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, + "The time period over which to calculate the framerate for r_displayInfo"); + +namespace AZ::Render +{ + static constexpr int DisplayInfoLevelNone = 0; + static constexpr int DisplayInfoLevelNormal = 1; + static constexpr int DisplayInfoLevelFull = 2; + static constexpr int DisplayInfoLevelCompact = 3; + + void AtomViewportDisplayInfoSystemComponent::Reflect(AZ::ReflectContext* context) + { + if (AZ::SerializeContext* serialize = azrtti_cast(context)) + { + serialize->Class() + ->Version(0) + ; + + if (AZ::EditContext* ec = serialize->GetEditContext()) + { + ec->Class("Viewport Display Info", "Manages debug viewport information through r_DisplayInfo") + ->ClassElement(Edit::ClassElements::EditorData, "") + ->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) + ->Attribute(Edit::Attributes::AutoExpand, true) + ; + } + } + } + + void AtomViewportDisplayInfoSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC("ViewportDisplayInfoService")); + } + + void AtomViewportDisplayInfoSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC("ViewportDisplayInfoService")); + } + + void AtomViewportDisplayInfoSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) + { + required.push_back(AZ_CRC("RPISystem", 0xf2add773)); + } + + void AtomViewportDisplayInfoSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent) + { + } + + void AtomViewportDisplayInfoSystemComponent::Activate() + { + AZ::Name apiName = AZ::RHI::Factory::Get().GetName(); + if (!apiName.IsEmpty()) + { + m_rendererDescription = AZStd::string::format("Atom using %s RHI", apiName.GetCStr()); + } + + CrySystemEventBus::Handler::BusConnect(); + AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect( + AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContextName()); + } + + void AtomViewportDisplayInfoSystemComponent::Deactivate() + { + AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect(); + CrySystemEventBus::Handler::BusDisconnect(); + } + + AZ::RPI::ViewportContextPtr AtomViewportDisplayInfoSystemComponent::GetViewportContext() const + { + return AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContext(); + } + + void AtomViewportDisplayInfoSystemComponent::DrawLine(AZStd::string_view line, AZ::Color color) + { + m_drawParams.m_color = color; + AzFramework::FontDrawInterface* fontDrawInterface = + AZ::Interface::Get()->GetDefaultFontDrawInterface(); + AZ::Vector2 textSize = fontDrawInterface->GetTextSize(m_drawParams, line); + fontDrawInterface->DrawScreenAlignedText2d(m_drawParams, line); + m_drawParams.m_position.SetY(m_drawParams.m_position.GetY() + textSize.GetY() + m_lineSpacing); + } + + void AtomViewportDisplayInfoSystemComponent::OnRenderTick() + { + AzFramework::FontDrawInterface* fontDrawInterface = + AZ::Interface::Get()->GetDefaultFontDrawInterface(); + AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext(); + + if (!fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene()) + { + return; + } + + m_fpsInterval = AZStd::chrono::seconds(r_fpsInterval); + + UpdateFramerate(); + + if (!m_displayInfoCVar) + { + return; + } + int displayLevel = m_displayInfoCVar->GetIVal(); + if (displayLevel == DisplayInfoLevelNone) + { + return; + } + + m_drawParams.m_drawViewportId = viewportContext->GetId(); + auto viewportSize = viewportContext->GetViewportSize(); + m_drawParams.m_position = AZ::Vector3(viewportSize.m_width, 0.f, 1.f); + m_drawParams.m_color = AZ::Colors::White; + m_drawParams.m_scale = AZ::Vector2(0.7f); + m_drawParams.m_hAlign = AzFramework::TextHorizontalAlignment::Right; + m_drawParams.m_monospace = false; + m_drawParams.m_depthTest = false; + m_drawParams.m_virtual800x600ScreenSize = true; + m_drawParams.m_scaleWithWindow = false; + m_drawParams.m_multiline = true; + m_drawParams.m_lineSpacing = 0.5f; + + // Calculate line spacing based on the font's actual line height + const float lineHeight = fontDrawInterface->GetTextSize(m_drawParams, " ").GetY(); + m_lineSpacing = lineHeight * m_drawParams.m_lineSpacing; + + DrawRendererInfo(); + if (displayLevel != DisplayInfoLevelCompact) + { + DrawCameraInfo(); + DrawMemoryInfo(); + } + DrawFramerate(); + } + + void AtomViewportDisplayInfoSystemComponent::OnCrySystemInitialized(ISystem& system, [[maybe_unused]]const SSystemInitParams& initParams) + { + m_displayInfoCVar = system.GetGlobalEnvironment()->pConsole->GetCVar("r_DisplayInfo"); + } + + void AtomViewportDisplayInfoSystemComponent::OnCrySystemShutdown([[maybe_unused]]ISystem& system) + { + m_displayInfoCVar = nullptr; + } + + void AtomViewportDisplayInfoSystemComponent::DrawRendererInfo() + { + DrawLine(m_rendererDescription, AZ::Colors::Yellow); + } + + void AtomViewportDisplayInfoSystemComponent::DrawCameraInfo() + { + AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext(); + AZ::RPI::ViewPtr currentView = viewportContext->GetDefaultView(); + if (currentView == nullptr) + { + return; + } + + auto viewportSize = viewportContext->GetViewportSize(); + AzFramework::CameraState cameraState; + AzFramework::SetCameraClippingVolumeFromPerspectiveFovMatrixRH(cameraState, currentView->GetViewToClipMatrix()); + const AZ::Transform transform = currentView->GetCameraTransform(); + const AZ::Vector3 translation = transform.GetTranslation(); + const AZ::Vector3 rotation = transform.GetEulerDegrees(); + DrawLine(AZStd::string::format( + "CamPos=%.2f %.2f %.2f Angl=%3.0f %3.0f %4.0f ZN=%.2f ZF=%.0f", + translation.GetX(), translation.GetY(), translation.GetZ(), + rotation.GetX(), rotation.GetY(), rotation.GetZ(), + cameraState.m_nearClip, cameraState.m_farClip + )); + } + + void AtomViewportDisplayInfoSystemComponent::DrawMemoryInfo() + { + static IMemoryManager::SProcessMemInfo processMemInfo; + + // Throttle memory usage updates to avoid potentially expensive memory usage API calls every tick. + constexpr AZStd::chrono::duration memoryUpdateInterval = AZStd::chrono::seconds(0.5); + AZStd::chrono::time_point currentTime = m_fpsHistory.back().Get(); + if (m_lastMemoryUpdate.has_value()) + { + if (currentTime - m_lastMemoryUpdate.value() > memoryUpdateInterval) + { + if (auto memoryManager = GetISystem()->GetIMemoryManager()) + { + memoryManager->GetProcessMemInfo(processMemInfo); + } + } + } + m_lastMemoryUpdate = currentTime; + + + int peakUsageMB = aznumeric_cast(processMemInfo.PeakPagefileUsage >> 20); + int currentUsageMB = aznumeric_cast(processMemInfo.PagefileUsage >> 20); + DrawLine(AZStd::string::format("Mem=%d Peak=%d", currentUsageMB, peakUsageMB)); + } + + void AtomViewportDisplayInfoSystemComponent::UpdateFramerate() + { + if (!m_tickRequests) + { + m_tickRequests = AZ::TickRequestBus::FindFirstHandler(); + } + if (!m_tickRequests) + { + return; + } + + AZ::ScriptTimePoint currentTime = m_tickRequests->GetTimeAtCurrentTick(); + // Only keep as much sampling data is is required by our FPS history. + while (!m_fpsHistory.empty() && (currentTime.Get() - m_fpsHistory.front().Get() > m_fpsInterval)) + { + m_fpsHistory.pop_front(); + } + m_fpsHistory.push_back(currentTime); + } + + void AtomViewportDisplayInfoSystemComponent::DrawFramerate() + { + AZStd::chrono::duration actualInterval = AZStd::chrono::seconds(0); + AZStd::optional lastTime; + AZStd::optional minFPS; + AZStd::optional maxFPS; + for (const AZ::ScriptTimePoint& time : m_fpsHistory) + { + if (lastTime.has_value()) + { + AZStd::chrono::duration deltaTime = time.Get() - lastTime.value().Get(); + if (deltaTime.count() == 0.0) + { + continue; + } + double fps = AZStd::chrono::seconds(1) / deltaTime; + if (!minFPS.has_value()) + { + minFPS = fps; + maxFPS = fps; + } + else + { + minFPS = AZStd::min(minFPS.value(), fps); + maxFPS = AZStd::max(maxFPS.value(), fps); + } + actualInterval += deltaTime; + } + lastTime = time; + } + + const double averageFPS = aznumeric_cast(m_fpsHistory.size()) / actualInterval.count(); + const double frameIntervalSeconds = m_fpsInterval.count(); + + DrawLine( + AZStd::string::format( + "FPS %.1f [%.0f..%.0f], frame avg over %.1fs", + averageFPS, + minFPS.value_or(0.0), + maxFPS.value_or(0.0), + frameIntervalSeconds), + AZ::Colors::Yellow); + } +} // namespace AZ::Render diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h new file mode 100644 index 0000000000..5cb6ed3308 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h @@ -0,0 +1,79 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +struct ICVar; + +namespace AZ +{ + class TickRequests; + + namespace Render + { + class AtomViewportDisplayInfoSystemComponent + : public AZ::Component + , public AZ::RPI::ViewportContextNotificationBus::Handler + , public CrySystemEventBus::Handler + { + public: + AZ_COMPONENT(AtomViewportDisplayInfoSystemComponent, "{AC32F173-E7E2-4943-8E6C-7C3091978221}"); + + static void Reflect(AZ::ReflectContext* context); + + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); + + protected: + // AZ::Component overrides... + void Activate() override; + void Deactivate() override; + + // AZ::RPI::ViewportContextNotificationBus::Handler overrides... + void OnRenderTick() override; + + // CrySystemEventBus::Handler overrides... + void OnCrySystemInitialized(ISystem& system, const SSystemInitParams& initParams) override; + void OnCrySystemShutdown(ISystem& system) override; + + private: + AZ::RPI::ViewportContextPtr GetViewportContext() const; + void DrawLine(AZStd::string_view line, AZ::Color color = AZ::Colors::White); + + void UpdateFramerate(); + + void DrawRendererInfo(); + void DrawCameraInfo(); + void DrawMemoryInfo(); + void DrawFramerate(); + + AZStd::string m_rendererDescription; + AzFramework::TextDrawParameters m_drawParams; + float m_lineSpacing; + AZStd::chrono::duration m_fpsInterval = AZStd::chrono::seconds(1); + AZStd::deque m_fpsHistory; + AZStd::optional m_lastMemoryUpdate; + AZ::TickRequests* m_tickRequests = nullptr; + ICVar* m_displayInfoCVar = nullptr; + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Module.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Module.cpp new file mode 100644 index 0000000000..f67e1bd1f5 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Module.cpp @@ -0,0 +1,51 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include + +#include "AtomViewportDisplayInfoSystemComponent.h" + +namespace AZ +{ + namespace Render + { + class AtomViewportDisplayInfoModule + : public AZ::Module + { + public: + AZ_RTTI(AtomViewportDisplayInfoModule, "{B10C0E55-03A1-4A46-AE3E-D3615AEAA659}", AZ::Module); + AZ_CLASS_ALLOCATOR(AtomViewportDisplayInfoModule, AZ::SystemAllocator, 0); + + AtomViewportDisplayInfoModule() + : AZ::Module() + { + m_descriptors.insert(m_descriptors.end(), { + AtomViewportDisplayInfoSystemComponent::CreateDescriptor(), + }); + } + + AZ::ComponentTypeList GetRequiredSystemComponents() const override + { + return AZ::ComponentTypeList{ + azrtti_typeid(), + }; + } + }; + } // namespace Render +} // namespace AZ + +// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM +// The first parameter should be GemName_GemIdLower +// The second should be the fully qualified name of the class above +AZ_DECLARE_MODULE_CLASS(Gem_AtomViewportDisplayInfo, AZ::Render::AtomViewportDisplayInfoModule) diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Tests/test_Main.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Tests/test_Main.cpp new file mode 100644 index 0000000000..b533221bbe --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Tests/test_Main.cpp @@ -0,0 +1,20 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include + +AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); + +TEST(AtomViewportDisplayInfoSanityTest, Sanity) +{ + EXPECT_EQ(1, 1); +} diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_files.cmake b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_files.cmake new file mode 100644 index 0000000000..561971453b --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_files.cmake @@ -0,0 +1,16 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(FILES + Source/AtomViewportDisplayInfoSystemComponent.cpp + Source/AtomViewportDisplayInfoSystemComponent.h + Source/Module.cpp +) diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_test_files.cmake b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_test_files.cmake new file mode 100644 index 0000000000..0bc1ee3a50 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_test_files.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(FILES + Source/Tests/test_Main.cpp +) diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json new file mode 100644 index 0000000000..a54dc188a7 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json @@ -0,0 +1,32 @@ +{ + "gem_name": "AtomLyIntegration_AtomViewportDisplayInfo", + "Dependencies": [ + { + "Uuid": "a218db9eb2114477b46600fea4441a6c", + "VersionConstraints": [ + "~>0.1.0" + ], + "_comment": "Atom RPI" + }, + { + "Uuid": "c7ff89ad6e8b4b45b2fadef2bcf12d6e", + "VersionConstraints": [ + "~>0.1.0" + ], + "_comment": "Atom_Bootstrap" + } + ], + "GemFormatVersion": 4, + "Uuid": "7c255c884bae4046b0640abe3c88cc4c", + "Name": "AtomLyIntegration_AtomViewportDisplayInfo", + "DisplayName": "Atom.AtomViewportDisplayInfo", + "Version": "0.1.0", + "Summary": "Provides a diagnostic viewport overlay for the default O3DE Atom viewport.", + "Tags": ["Atom"], + "IconPath": "preview.png", + "Modules": [ + { + "Type": "GameModule" + } + ] +} diff --git a/Gems/AtomLyIntegration/CMakeLists.txt b/Gems/AtomLyIntegration/CMakeLists.txt index 57bb860a9e..35022e643b 100644 --- a/Gems/AtomLyIntegration/CMakeLists.txt +++ b/Gems/AtomLyIntegration/CMakeLists.txt @@ -16,3 +16,4 @@ add_subdirectory(EMotionFXAtom) add_subdirectory(AtomFont) add_subdirectory(TechnicalArt) add_subdirectory(AtomBridge) +add_subdirectory(AtomViewportDisplayInfo) From bf62687b37de60d3b5196dad620d1365c021cf2e Mon Sep 17 00:00:00 2001 From: Steve Pham <82231385+spham-amzn@users.noreply.github.com> Date: Tue, 11 May 2021 18:58:26 -0700 Subject: [PATCH 138/225] Update android installation script to install gradle 7.0 --- .../build/build_node/Platform/Windows/install_android.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build/build_node/Platform/Windows/install_android.ps1 b/scripts/build/build_node/Platform/Windows/install_android.ps1 index 30e651cc3a..2fde5fcb8c 100644 --- a/scripts/build/build_node/Platform/Windows/install_android.ps1 +++ b/scripts/build/build_node/Platform/Windows/install_android.ps1 @@ -28,8 +28,8 @@ Start-Process -FilePath $sdkmanager -ArgumentList $build_tools -NoNewWindow -Wai Write-Host "Installing Gradle and Ninja" Import-Module C:\ProgramData\chocolatey\helpers\chocolateyInstaller.psm1 #Grade needs a custom installer due to being hardcoded to C:\Programdata in Chocolatey $packageName = 'gradle' -$version = '5.6.4' -$checksum = 'ABC10BCEDB58806E8654210F96031DB541BCD2D6FC3161E81CB0572D6A15E821' +$version = '7.0' +$checksum = '81003F83B0056D20EEDF48CDDD4F52A9813163D4BA185BCF8ABD34B8EEEA4CBD' $url = "https://services.gradle.org/distributions/gradle-$version-all.zip" $installDir = "C:\Gradle" @@ -38,6 +38,6 @@ Install-ChocolateyZipPackage $packageName $url $installDir -Checksum $checksum - $gradle_home = Join-Path $installDir "$packageName-$version" $gradle_bat = Join-Path $gradle_home 'bin/gradle.bat' -Install-ChocolateyEnvironmentVariable "GRADLE_HOME" $gradle_home 'Machine' +Install-ChocolateyEnvironmentVariable "GRADLE_BUILD_HOME" $gradle_home 'Machine' choco install -y ninja --version=1.10.0 --package-parameters="/installDir:C:\Ninja" \ No newline at end of file From 7342e62680a8a651df4bd935f9c44ddb11239e8d Mon Sep 17 00:00:00 2001 From: mnaumov Date: Tue, 11 May 2021 19:33:46 -0700 Subject: [PATCH 139/225] Hiding "Open Material" when material asset is assigned --- .../Code/Source/Material/EditorMaterialComponentSlot.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp index 9d63f4a4a9..7ebf25454d 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp @@ -269,7 +269,8 @@ namespace AZ QAction* action = nullptr; - menu.addAction("Open Material Editor", [this]() { EditorMaterialSystemComponentRequestBus::Broadcast(&EditorMaterialSystemComponentRequestBus::Events::OpenInMaterialEditor, ""); }); + action = menu.addAction("Open Material Editor...", [this]() { EditorMaterialSystemComponentRequestBus::Broadcast(&EditorMaterialSystemComponentRequestBus::Events::OpenInMaterialEditor, ""); }); + action->setVisible(!m_materialAsset.GetId().IsValid()); action = menu.addAction("Clear", [this]() { Clear(); }); action->setEnabled(m_materialAsset.GetId().IsValid() || !m_propertyOverrides.empty() || !m_matModUvOverrides.empty()); From d98a69199402e0e781748a7f021cf39af7d77254 Mon Sep 17 00:00:00 2001 From: abrmich Date: Tue, 11 May 2021 10:19:30 -0700 Subject: [PATCH 140/225] UI Editor Viewport fixes --- .../Editor/Icons/Viewport}/Anchor_Left.tif | 0 .../Editor/Icons/Viewport}/Anchor_TopLeft.tif | 0 .../Editor/Icons/Viewport}/Anchor_Whole.tif | 0 .../Icons/Viewport}/Border_Selected.tif | 0 .../Icons/Viewport}/Border_Unselected.tif | 0 .../Icons/Viewport}/Canvas_Background.tif | 0 .../Viewport/Canvas_Background.tif.assetinfo | 69 ++++++++++++++ .../Editor/Icons/Viewport}/DottedLine.tif | 0 .../Assets/Editor/Icons/Viewport}/Pivot.tif | 0 .../Transform_Gizmo_Center_Square.tif | 0 .../Viewport}/Transform_Gizmo_Circle.tif | 0 .../Transform_Gizmo_Line_Square_X.tif | 0 .../Transform_Gizmo_Line_Square_Y.tif | 0 .../Transform_Gizmo_Line_Triangle_X.tif | 0 .../Transform_Gizmo_Line_Triangle_Y.tif | 0 Gems/LyShine/Code/Editor/EditorWindow.cpp | 1 - Gems/LyShine/Code/Editor/QtHelpers.cpp | 16 ++++ Gems/LyShine/Code/Editor/QtHelpers.h | 4 + Gems/LyShine/Code/Editor/ViewportAnchor.cpp | 8 +- .../Code/Editor/ViewportCanvasBackground.cpp | 2 +- Gems/LyShine/Code/Editor/ViewportHelpers.h | 1 - .../LyShine/Code/Editor/ViewportHighlight.cpp | 4 +- Gems/LyShine/Code/Editor/ViewportIcon.cpp | 12 ++- Gems/LyShine/Code/Editor/ViewportIcon.h | 15 ++++ .../Code/Editor/ViewportInteraction.cpp | 23 ++--- Gems/LyShine/Code/Editor/ViewportPivot.cpp | 2 +- Gems/LyShine/Code/Editor/ViewportWidget.cpp | 89 +++++++++++-------- Gems/LyShine/Code/Editor/ViewportWidget.h | 5 +- Gems/LyShine/Code/Include/LyShine/Draw2d.h | 19 ++-- Gems/LyShine/Code/Source/Draw2d.cpp | 23 +++-- 30 files changed, 213 insertions(+), 80 deletions(-) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Anchor_Left.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Anchor_TopLeft.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Anchor_Whole.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Border_Selected.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Border_Unselected.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Canvas_Background.tif (100%) create mode 100644 Gems/LyShine/Assets/Editor/Icons/Viewport/Canvas_Background.tif.assetinfo rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/DottedLine.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Pivot.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Transform_Gizmo_Center_Square.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Transform_Gizmo_Circle.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Transform_Gizmo_Line_Square_X.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Transform_Gizmo_Line_Square_Y.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Transform_Gizmo_Line_Triangle_X.tif (100%) rename {Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons => Gems/LyShine/Assets/Editor/Icons/Viewport}/Transform_Gizmo_Line_Triangle_Y.tif (100%) diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Left.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Anchor_Left.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Left.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Anchor_Left.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_TopLeft.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Anchor_TopLeft.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_TopLeft.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Anchor_TopLeft.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Whole.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Anchor_Whole.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Whole.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Anchor_Whole.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Selected.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Border_Selected.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Selected.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Border_Selected.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Unselected.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Border_Unselected.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Unselected.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Border_Unselected.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Canvas_Background.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Canvas_Background.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Canvas_Background.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Canvas_Background.tif diff --git a/Gems/LyShine/Assets/Editor/Icons/Viewport/Canvas_Background.tif.assetinfo b/Gems/LyShine/Assets/Editor/Icons/Viewport/Canvas_Background.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShine/Assets/Editor/Icons/Viewport/Canvas_Background.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/DottedLine.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/DottedLine.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/DottedLine.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/DottedLine.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Pivot.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Pivot.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Pivot.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Pivot.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Center_Square.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Center_Square.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Center_Square.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Center_Square.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Circle.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Circle.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Circle.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Circle.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_X.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Line_Square_X.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_X.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Line_Square_X.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_Y.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Line_Square_Y.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_Y.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Line_Square_Y.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_X.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Line_Triangle_X.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_X.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Line_Triangle_X.tif diff --git a/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_Y.tif b/Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Line_Triangle_Y.tif similarity index 100% rename from Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_Y.tif rename to Gems/LyShine/Assets/Editor/Icons/Viewport/Transform_Gizmo_Line_Triangle_Y.tif diff --git a/Gems/LyShine/Code/Editor/EditorWindow.cpp b/Gems/LyShine/Code/Editor/EditorWindow.cpp index 4641b02a13..e3810dcbee 100644 --- a/Gems/LyShine/Code/Editor/EditorWindow.cpp +++ b/Gems/LyShine/Code/Editor/EditorWindow.cpp @@ -1451,7 +1451,6 @@ void EditorWindow::OnEditorNotifyEvent(EEditorNotifyEvent ev) { // change skin RefreshEditorMenu(); - m_viewport->UpdateViewportBackground(); break; } case eNotify_OnUpdateViewports: diff --git a/Gems/LyShine/Code/Editor/QtHelpers.cpp b/Gems/LyShine/Code/Editor/QtHelpers.cpp index 9691c2a618..16a5d42327 100644 --- a/Gems/LyShine/Code/Editor/QtHelpers.cpp +++ b/Gems/LyShine/Code/Editor/QtHelpers.cpp @@ -13,6 +13,8 @@ #include "EditorCommon.h" +#include + namespace QtHelpers { AZ::Vector2 QPointFToVector2(const QPointF& point) @@ -34,4 +36,18 @@ namespace QtHelpers return inWidget; } + float GetHighDpiScaleFactor(const QWidget& widget) + { + float dpiScale = QHighDpiScaling::factor(widget.windowHandle()->screen()); + return dpiScale; + } + + QSize GetDpiScaledViewportSize(const QWidget& widget) + { + float dpiScale = GetHighDpiScaleFactor(widget); + float width = ceilf(widget.size().width() * dpiScale); + float height = ceilf(widget.size().height() * dpiScale); + return QSize(width, height); + } + } // namespace QtHelpers diff --git a/Gems/LyShine/Code/Editor/QtHelpers.h b/Gems/LyShine/Code/Editor/QtHelpers.h index f55ffc767e..7af68432d3 100644 --- a/Gems/LyShine/Code/Editor/QtHelpers.h +++ b/Gems/LyShine/Code/Editor/QtHelpers.h @@ -21,4 +21,8 @@ namespace QtHelpers bool IsGlobalPosInWidget(const QWidget* widget, const QPoint& pos); + float GetHighDpiScaleFactor(const QWidget& widget); + + QSize GetDpiScaledViewportSize(const QWidget& widget); + } // namespace QtHelpers diff --git a/Gems/LyShine/Code/Editor/ViewportAnchor.cpp b/Gems/LyShine/Code/Editor/ViewportAnchor.cpp index d61066f4d9..f46a62586d 100644 --- a/Gems/LyShine/Code/Editor/ViewportAnchor.cpp +++ b/Gems/LyShine/Code/Editor/ViewportAnchor.cpp @@ -14,10 +14,10 @@ #include "EditorCommon.h" ViewportAnchor::ViewportAnchor() - : m_anchorWhole(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Anchor_Whole.tif")) - , m_anchorLeft(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Anchor_Left.tif")) - , m_anchorLeftTop(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Anchor_TopLeft.tif")) - , m_dottedLine(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/DottedLine.tif")) + : m_anchorWhole(new ViewportIcon("Editor/Icons/Viewport/Anchor_Whole.tif")) + , m_anchorLeft(new ViewportIcon("Editor/Icons/Viewport/Anchor_Left.tif")) + , m_anchorLeftTop(new ViewportIcon("Editor/Icons/Viewport/Anchor_TopLeft.tif")) + , m_dottedLine(new ViewportIcon("Editor/Icons/Viewport/DottedLine.tif")) { } diff --git a/Gems/LyShine/Code/Editor/ViewportCanvasBackground.cpp b/Gems/LyShine/Code/Editor/ViewportCanvasBackground.cpp index ccc35de305..344e3af9cb 100644 --- a/Gems/LyShine/Code/Editor/ViewportCanvasBackground.cpp +++ b/Gems/LyShine/Code/Editor/ViewportCanvasBackground.cpp @@ -15,7 +15,7 @@ #include "EditorCommon.h" ViewportCanvasBackground::ViewportCanvasBackground() - : m_canvasBackground(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Canvas_Background.tif")) + : m_canvasBackground(new ViewportIcon("Editor/Icons/Viewport/Canvas_Background.tif")) { } diff --git a/Gems/LyShine/Code/Editor/ViewportHelpers.h b/Gems/LyShine/Code/Editor/ViewportHelpers.h index 9a1aadead5..7cb64d01c7 100644 --- a/Gems/LyShine/Code/Editor/ViewportHelpers.h +++ b/Gems/LyShine/Code/Editor/ViewportHelpers.h @@ -17,7 +17,6 @@ namespace ViewportHelpers { //------------------------------------------------------------------------------- - const AZ::Color backgroundColorLight(0.85f, 0.85f, 0.85f, 1.0f); const AZ::Color backgroundColorDark(0.133f, 0.137f, 0.149f, 1.0f); // #222236, RGBA: 34, 35, 38, 255 const AZ::Color selectedColor(1.000f, 1.000f, 1.000f, 1.0f); // #FFFFFF, RGBA: 255, 255, 255, 255 const AZ::Color unselectedColor(0.800f, 0.800f, 0.800f, 0.500f); // #CCCCCC, RGBA: 204, 204, 204, 128 diff --git a/Gems/LyShine/Code/Editor/ViewportHighlight.cpp b/Gems/LyShine/Code/Editor/ViewportHighlight.cpp index c050d55049..e6699615c6 100644 --- a/Gems/LyShine/Code/Editor/ViewportHighlight.cpp +++ b/Gems/LyShine/Code/Editor/ViewportHighlight.cpp @@ -14,8 +14,8 @@ #include "EditorCommon.h" ViewportHighlight::ViewportHighlight() - : m_highlightIconSelected(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Border_Selected.tif")) - , m_highlightIconUnselected(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Border_Unselected.tif")) + : m_highlightIconSelected(new ViewportIcon("Editor/Icons/Viewport/Border_Selected.tif")) + , m_highlightIconUnselected(new ViewportIcon("Editor/Icons/Viewport/Border_Unselected.tif")) { } diff --git a/Gems/LyShine/Code/Editor/ViewportIcon.cpp b/Gems/LyShine/Code/Editor/ViewportIcon.cpp index 81ed5dbcb5..b1866efb00 100644 --- a/Gems/LyShine/Code/Editor/ViewportIcon.cpp +++ b/Gems/LyShine/Code/Editor/ViewportIcon.cpp @@ -17,6 +17,8 @@ #include #include +float ViewportIcon::m_dpiScaleFactor = 1.0f; + ViewportIcon::ViewportIcon(const char* textureFilename) { m_image = CDraw2d::LoadTexture(textureFilename); @@ -31,7 +33,12 @@ AZ::Vector2 ViewportIcon::GetTextureSize() const if (m_image) { AZ::RHI::Size size = m_image->GetDescriptor().m_size; - return AZ::Vector2(size.m_width, size.m_height); + AZ::Vector2 scaledSize(size.m_width, size.m_height); + if (m_applyDpiScaleFactorToSize) + { + scaledSize *= m_dpiScaleFactor; + } + return scaledSize; } return AZ::Vector2(0.0f, 0.0f); @@ -380,5 +387,6 @@ void ViewportIcon::DrawElementRectOutline(Draw2dHelper& draw2d, AZ::EntityId ent rightVec.NormalizeSafe(); downVec.NormalizeSafe(); - draw2d.DrawRectOutlineTextured(m_image, points, rightVec, downVec, color); + uint32_t lineThickness = aznumeric_cast(GetTextureSize().GetY()); + draw2d.DrawRectOutlineTextured(m_image, points, rightVec, downVec, color, lineThickness); } diff --git a/Gems/LyShine/Code/Editor/ViewportIcon.h b/Gems/LyShine/Code/Editor/ViewportIcon.h index 85fd2fe068..b61d0715b6 100644 --- a/Gems/LyShine/Code/Editor/ViewportIcon.h +++ b/Gems/LyShine/Code/Editor/ViewportIcon.h @@ -49,6 +49,21 @@ public: // width of the border (but the texture can have alpha at edges to make it thinner). void DrawElementRectOutline(Draw2dHelper& draw2d, AZ::EntityId entityId, AZ::Color color); + // Set whether to apply high resolution dpi scaling to the icon size + void SetApplyDpiScaleFactorToSize(bool apply) { m_applyDpiScaleFactorToSize = apply; } + + // Get whether to apply high resolution dpi scaling to the icon size + bool GetApplyDpiScaleFactorToSize() { return m_applyDpiScaleFactorToSize; } + + // Set scale factor + static void SetDpiScaleFactor(float scale) { m_dpiScaleFactor = scale; } + + // Get scale factor + static float GetDpiScaleFactor() { return m_dpiScaleFactor; } + private: AZ::Data::Instance m_image; + bool m_applyDpiScaleFactorToSize = true; + + static float m_dpiScaleFactor; }; diff --git a/Gems/LyShine/Code/Editor/ViewportInteraction.cpp b/Gems/LyShine/Code/Editor/ViewportInteraction.cpp index 60b7f4f35b..c846bbb8c3 100644 --- a/Gems/LyShine/Code/Editor/ViewportInteraction.cpp +++ b/Gems/LyShine/Code/Editor/ViewportInteraction.cpp @@ -167,8 +167,8 @@ ViewportInteraction::ViewportInteraction(EditorWindow* editorWindow) : QObject() , m_editorWindow(editorWindow) , m_activeElementId() - , m_anchorWhole(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Anchor_Whole.tif")) - , m_pivotIcon(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Pivot.tif")) + , m_anchorWhole(new ViewportIcon("Editor/Icons/Viewport/Anchor_Whole.tif")) + , m_pivotIcon(new ViewportIcon("Editor/Icons/Viewport/Pivot.tif")) , m_interactionMode(PersistentGetInteractionMode()) , m_interactionType(InteractionType::NONE) , m_coordinateSystem(PersistentGetCoordinateSystem()) @@ -186,13 +186,13 @@ ViewportInteraction::ViewportInteraction(EditorWindow* editorWindow) , m_startAnchors(UiTransform2dInterface::Anchors()) , m_grabbedAnchors(ViewportHelpers::SelectedAnchors()) , m_grabbedGizmoParts(ViewportHelpers::GizmoParts()) - , m_lineTriangleX(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_X.tif")) - , m_lineTriangleY(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_Y.tif")) - , m_circle(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Circle.tif")) - , m_lineSquareX(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_X.tif")) - , m_lineSquareY(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_Y.tif")) - , m_centerSquare(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Center_Square.tif")) - , m_dottedLine(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/DottedLine.tif")) + , m_lineTriangleX(new ViewportIcon("Editor/Icons/Viewport/Transform_Gizmo_Line_Triangle_X.tif")) + , m_lineTriangleY(new ViewportIcon("Editor/Icons/Viewport/Transform_Gizmo_Line_Triangle_Y.tif")) + , m_circle(new ViewportIcon("Editor/Icons/Viewport/Transform_Gizmo_Circle.tif")) + , m_lineSquareX(new ViewportIcon("Editor/Icons/Viewport/Transform_Gizmo_Line_Square_X.tif")) + , m_lineSquareY(new ViewportIcon("Editor/Icons/Viewport/Transform_Gizmo_Line_Square_Y.tif")) + , m_centerSquare(new ViewportIcon("Editor/Icons/Viewport/Transform_Gizmo_Center_Square.tif")) + , m_dottedLine(new ViewportIcon("Editor/Icons/Viewport/DottedLine.tif")) , m_dragInteraction(nullptr) , m_expanderWatcher(new ViewportInteractionExpanderWatcher(this)) { @@ -908,8 +908,9 @@ void ViewportInteraction::GetScaleToFitTransformProps(const AZ::Vector2* newCanv EBUS_EVENT_ID_RESULT(canvasSize, m_editorWindow->GetCanvas(), UiCanvasBus, GetCanvasSize); } - const int viewportWidth = m_editorWindow->GetViewport()->size().width(); - const int viewportHeight = m_editorWindow->GetViewport()->size().height(); + QSize viewportSize = QtHelpers::GetDpiScaledViewportSize(*m_editorWindow->GetViewport()); + const int viewportWidth = viewportSize.width(); + const int viewportHeight = viewportSize.height(); // We pad the edges of the viewport to allow the user to easily see the borders of // the canvas edges, which is especially helpful if there are anchors sitting on diff --git a/Gems/LyShine/Code/Editor/ViewportPivot.cpp b/Gems/LyShine/Code/Editor/ViewportPivot.cpp index 694cf91515..c264f7093d 100644 --- a/Gems/LyShine/Code/Editor/ViewportPivot.cpp +++ b/Gems/LyShine/Code/Editor/ViewportPivot.cpp @@ -15,7 +15,7 @@ #include "ViewportPivot.h" ViewportPivot::ViewportPivot() - : m_pivot(new ViewportIcon("Plugins/UiCanvasEditor/CanvasIcons/Pivot.tif")) + : m_pivot(new ViewportIcon("Editor/Icons/Viewport/Pivot.tif")) { } diff --git a/Gems/LyShine/Code/Editor/ViewportWidget.cpp b/Gems/LyShine/Code/Editor/ViewportWidget.cpp index 89c5a0bb50..f9464f17c7 100644 --- a/Gems/LyShine/Code/Editor/ViewportWidget.cpp +++ b/Gems/LyShine/Code/Editor/ViewportWidget.cpp @@ -38,6 +38,7 @@ #include #include +#include #define UICANVASEDITOR_SETTINGS_VIEWPORTWIDGET_DRAW_ELEMENT_BORDERS_KEY "ViewportWidget::m_drawElementBordersFlags" #define UICANVASEDITOR_SETTINGS_VIEWPORTWIDGET_DRAW_ELEMENT_BORDERS_DEFAULT ( ViewportWidget::DrawElementBorders_Unselected ) @@ -220,8 +221,6 @@ ViewportWidget::ViewportWidget(EditorWindow* parent) { setAcceptDrops(true); - UpdateViewportBackground(); - InitUiRenderer(); SetupShortcuts(); @@ -299,19 +298,6 @@ void ViewportWidget::ToggleDrawElementBorders(uint32 flags) SetDrawElementBordersFlags(m_drawElementBordersFlags); } -void ViewportWidget::UpdateViewportBackground() -{ - const QColor backgroundColor(ViewportHelpers::backgroundColorDark.GetR8(), - ViewportHelpers::backgroundColorDark.GetG8(), - ViewportHelpers::backgroundColorDark.GetB8(), - ViewportHelpers::backgroundColorDark.GetA8()); - - QPalette pal(palette()); - pal.setColor(QPalette::Window, backgroundColor); - setPalette(pal); - setAutoFillBackground(true); -} - void ViewportWidget::ActiveCanvasChanged() { bool canvasLoaded = m_editorWindow->GetCanvas().IsValid(); @@ -519,6 +505,9 @@ void ViewportWidget::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoin gEnv->pRenderer->SetSrgbWrite(true); #endif + const float dpiScale = QtHelpers::GetHighDpiScaleFactor(*this); + ViewportIcon::SetDpiScaleFactor(dpiScale); + // Set up to render a frame to this viewport's window GetViewportContext()->RenderTick(); @@ -554,7 +543,9 @@ void ViewportWidget::RefreshTick() void ViewportWidget::mousePressEvent(QMouseEvent* ev) { UiEditorMode editorMode = m_editorWindow->GetEditorMode(); - QMouseEvent scaledEvent(ev->type(), WidgetToViewport(ev->localPos()), ev->button(), ev->buttons(), ev->modifiers()); + + QPointF scaledPosition = WidgetToViewport(ev->localPos()); + QMouseEvent scaledEvent(ev->type(), scaledPosition, ev->button(), ev->buttons(), ev->modifiers()); if (editorMode == UiEditorMode::Edit) { // in Edit mode just send input to ViewportInteraction @@ -569,8 +560,7 @@ void ViewportWidget::mousePressEvent(QMouseEvent* ev) if (ev->button() == Qt::LeftButton) { // Send event to this canvas - QPointF scaledPos = WidgetToViewport(ev->localPos()); - const AZ::Vector2 viewportPosition(aznumeric_cast(scaledPos.x()), aznumeric_cast(scaledPos.y())); + const AZ::Vector2 viewportPosition(aznumeric_cast(scaledPosition.x()), aznumeric_cast(scaledPosition.y())); const AzFramework::InputChannel::Snapshot inputSnapshot(AzFramework::InputDeviceMouse::Button::Left, AzFramework::InputDeviceMouse::Id, AzFramework::InputChannel::State::Began); @@ -588,7 +578,9 @@ void ViewportWidget::mousePressEvent(QMouseEvent* ev) void ViewportWidget::mouseMoveEvent(QMouseEvent* ev) { UiEditorMode editorMode = m_editorWindow->GetEditorMode(); - QMouseEvent scaledEvent(ev->type(), WidgetToViewport(ev->localPos()), ev->button(), ev->buttons(), ev->modifiers()); + + QPointF scaledPosition = WidgetToViewport(ev->localPos()); + QMouseEvent scaledEvent(ev->type(), scaledPosition, ev->button(), ev->buttons(), ev->modifiers()); if (editorMode == UiEditorMode::Edit) { @@ -596,7 +588,8 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent* ev) m_viewportInteraction->MouseMoveEvent(&scaledEvent, m_editorWindow->GetHierarchy()->selectedItems()); - SetRulerCursorPositions(ev->globalPos()); + QPointF screenPosition = WidgetToViewport(ev->screenPos()); + SetRulerCursorPositions(screenPosition.toPoint()); } else // if (editorMode == UiEditorMode::Preview) { @@ -604,8 +597,7 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent* ev) AZ::EntityId canvasEntityId = m_editorWindow->GetPreviewModeCanvas(); if (canvasEntityId.IsValid()) { - QPointF scaledPos = WidgetToViewport(ev->localPos()); - const AZ::Vector2 viewportPosition(aznumeric_cast(scaledPos.x()), aznumeric_cast(scaledPos.y())); + const AZ::Vector2 viewportPosition(aznumeric_cast(scaledPosition.x()), aznumeric_cast(scaledPosition.y())); const AzFramework::InputChannelId& channelId = (ev->buttons() & Qt::LeftButton) ? AzFramework::InputDeviceMouse::Button::Left : AzFramework::InputDeviceMouse::SystemCursorPosition; @@ -625,7 +617,9 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent* ev) void ViewportWidget::mouseReleaseEvent(QMouseEvent* ev) { UiEditorMode editorMode = m_editorWindow->GetEditorMode(); - QMouseEvent scaledEvent(ev->type(), WidgetToViewport(ev->localPos()), ev->button(), ev->buttons(), ev->modifiers()); + + QPointF scaledPosition = WidgetToViewport(ev->localPos()); + QMouseEvent scaledEvent(ev->type(), scaledPosition, ev->button(), ev->buttons(), ev->modifiers()); if (editorMode == UiEditorMode::Edit) { // in Edit mode just send input to ViewportInteraction @@ -641,8 +635,7 @@ void ViewportWidget::mouseReleaseEvent(QMouseEvent* ev) if (ev->button() == Qt::LeftButton) { // Send event to this canvas - QPointF scaledPos = WidgetToViewport(ev->localPos()); - const AZ::Vector2 viewportPosition(aznumeric_cast(scaledPos.x()), aznumeric_cast(scaledPos.y())); + const AZ::Vector2 viewportPosition(aznumeric_cast(scaledPosition.x()), aznumeric_cast(scaledPosition.y())); const AzFramework::InputChannel::Snapshot inputSnapshot(AzFramework::InputDeviceMouse::Button::Left, AzFramework::InputDeviceMouse::Id, AzFramework::InputChannel::State::Ended); @@ -726,7 +719,7 @@ bool ViewportWidget::event(QEvent* ev) } } - bool result = QWidget::event(ev); + bool result = RenderViewportWidget::event(ev); return result; } @@ -931,14 +924,16 @@ void ViewportWidget::RenderEditMode(float deltaTime) EBUS_EVENT_ID_RESULT(canvasSize, canvasEntityId, UiCanvasBus, GetCanvasSize); m_draw2d->SetSortKey(backgroundKey); + + // Render a rectangle covering the entire editor viewport area + RenderViewportBackground(); + + // Render a checkerboard background covering the canvas area which represents transparency m_viewportBackground->Draw(draw2d, canvasSize, m_viewportInteraction->GetCanvasToViewportScale(), m_viewportInteraction->GetCanvasToViewportTranslation()); - AZ::Vector2 viewportSize(aznumeric_cast(size().width()), aznumeric_cast(size().height())); - viewportSize *= QHighDpiScaling::factor(windowHandle()->screen()); - #ifdef LYSHINE_ATOM_TODO // clear the stencil buffer before rendering each canvas - required for masking // NOTE: the FRT_CLEAR_IMMEDIATE is required since we will not be setting the render target @@ -953,6 +948,8 @@ void ViewportWidget::RenderEditMode(float deltaTime) EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, deltaTime, false); // Render this canvas + QSize scaledViewportSize = QtHelpers::GetDpiScaledViewportSize(*this); + AZ::Vector2 viewportSize(scaledViewportSize.width(), scaledViewportSize.height()); EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, RenderCanvasInEditorViewport, false, viewportSize); m_draw2d->SetSortKey(topLayerKey); @@ -1050,6 +1047,9 @@ void ViewportWidget::RenderEditMode(float deltaTime) void ViewportWidget::RenderPreviewMode(float deltaTime) { + // sort keys for different layers + static const int64_t backgroundKey = -0x1000; + AZ::EntityId canvasEntityId = m_editorWindow->GetPreviewModeCanvas(); if (m_fontTextureHasChanged) @@ -1072,10 +1072,10 @@ void ViewportWidget::RenderPreviewMode(float deltaTime) if (canvasEntityId.IsValid()) { - // Get the canvas size - AZ::Vector2 viewportSize(aznumeric_cast(size().width()), aznumeric_cast(size().height())); - viewportSize *= QHighDpiScaling::factor(windowHandle()->screen()); + QSize scaledViewportSize = QtHelpers::GetDpiScaledViewportSize(*this); + AZ::Vector2 viewportSize(scaledViewportSize.width(), scaledViewportSize.height()); + // Get the canvas size AZ::Vector2 canvasSize = m_editorWindow->GetPreviewCanvasSize(); if (canvasSize.GetX() == 0.0f && canvasSize.GetY() == 0.0f) { @@ -1139,7 +1139,7 @@ void ViewportWidget::RenderPreviewMode(float deltaTime) canvasToViewportMatrix.SetTranslation(translation); EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetCanvasToViewportMatrix, canvasToViewportMatrix); -#ifdef LYSHINE_ATOM_TODO +#ifdef LYSHINE_ATOM_TODO // mask support with Atom // clear the stencil buffer before rendering each canvas - required for masking // NOTE: the FRT_CLEAR_IMMEDIATE is required since we will not be setting the render target // We also clear the color to a mid grey so that we can see the bounds of the canvas @@ -1147,16 +1147,18 @@ void ViewportWidget::RenderPreviewMode(float deltaTime) gEnv->pRenderer->ClearTargetsImmediately(FRT_CLEAR, viewportBackgroundColor); #endif -#ifdef LYSHINE_ATOM_TODO + m_draw2d->SetSortKey(backgroundKey); + + RenderViewportBackground(); + // Render a black rectangle covering the canvas area. This allows the canvas bounds to be visible when the canvas size is // not exactly the same as the viewport size AZ::Vector2 topLeftInViewportSpace = CanvasHelpers::GetViewportPoint(canvasEntityId, AZ::Vector2(0.0f, 0.0f)); AZ::Vector2 bottomRightInViewportSpace = CanvasHelpers::GetViewportPoint(canvasEntityId, canvasSize); AZ::Vector2 sizeInViewportSpace = bottomRightInViewportSpace - topLeftInViewportSpace; - Draw2dHelper draw2d(m_draw2d.get()) - int texId = gEnv->pRenderer->GetBlackTextureId(); - draw2d.DrawImage(texId, topLeftInViewportSpace, sizeInViewportSpace); -#endif + Draw2dHelper draw2d(m_draw2d.get()); + auto image = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::Black); + draw2d.DrawImage(image, topLeftInViewportSpace, sizeInViewportSpace); // Render this canvas // NOTE: the displayBounds param is always false. If we wanted a debug option to display the bounds @@ -1166,6 +1168,17 @@ void ViewportWidget::RenderPreviewMode(float deltaTime) } } +void ViewportWidget::RenderViewportBackground() +{ + QSize viewportSize = QtHelpers::GetDpiScaledViewportSize(*this); + AZ::Color backgroundColor = ViewportHelpers::backgroundColorDark; + const AZ::Data::Instance& image = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White); + + Draw2dHelper draw2d(m_draw2d.get()); + draw2d.SetImageColor(backgroundColor.GetAsVector3()); + draw2d.DrawImage(image, AZ::Vector2(0.0f, 0.0f), AZ::Vector2(viewportSize.width(), viewportSize.height())); +} + void ViewportWidget::SetupShortcuts() { // Actions with shortcuts are created instead of direct shortcuts because the shortcut dispatcher only looks for matching actions diff --git a/Gems/LyShine/Code/Editor/ViewportWidget.h b/Gems/LyShine/Code/Editor/ViewportWidget.h index 4d15f3dea4..77f07d7f6e 100644 --- a/Gems/LyShine/Code/Editor/ViewportWidget.h +++ b/Gems/LyShine/Code/Editor/ViewportWidget.h @@ -54,8 +54,6 @@ public: // member functions bool IsDrawingElementBorders(uint32 flags) const; void ToggleDrawElementBorders(uint32 flags); - void UpdateViewportBackground(); - void ActiveCanvasChanged(); void EntityContextChanged(); @@ -154,6 +152,9 @@ private: // member functions //! Render the viewport when in preview mode void RenderPreviewMode(float deltaTime); + //! Fill the entire viewport area with a background color + void RenderViewportBackground(); + //! Create shortcuts for manipulating the viewport void SetupShortcuts(); diff --git a/Gems/LyShine/Code/Include/LyShine/Draw2d.h b/Gems/LyShine/Code/Include/LyShine/Draw2d.h index df61542e25..8270461e73 100644 --- a/Gems/LyShine/Code/Include/LyShine/Draw2d.h +++ b/Gems/LyShine/Code/Include/LyShine/Draw2d.h @@ -131,16 +131,18 @@ public: // member functions //! Draw a rectangular outline with a texture // - //! \param image The texture to be used for drawing the outline - //! \param points The rect's vertices (top left, top right, bottom right, bottom left) - //! \param rightVec Right vector. Specified because the rect's width/height could be 0 - //! \param downVec Down vector. Specified because the rect's width/height could be 0 - //! \param color The color of the outline + //! \param image The texture to be used for drawing the outline + //! \param points The rect's vertices (top left, top right, bottom right, bottom left) + //! \param rightVec Right vector. Specified because the rect's width/height could be 0 + //! \param downVec Down vector. Specified because the rect's width/height could be 0 + //! \param color The color of the outline + //! \param lineThickness The thickness in pixels of the outline. If 0, it will be based on image height void DrawRectOutlineTextured(AZ::Data::Instance image, UiTransformInterface::RectPoints points, AZ::Vector2 rightVec, AZ::Vector2 downVec, - AZ::Color color); + AZ::Color color, + uint32_t lineThickness = 0); //! Get the width and height (in pixels) that would be used to draw the given text string. // @@ -439,11 +441,12 @@ public: // member functions UiTransformInterface::RectPoints points, AZ::Vector2 rightVec, AZ::Vector2 downVec, - AZ::Color color) + AZ::Color color, + uint32_t lineThickness = 0) { if (m_draw2d) { - m_draw2d->DrawRectOutlineTextured(image, points, rightVec, downVec, color); + m_draw2d->DrawRectOutlineTextured(image, points, rightVec, downVec, color, lineThickness); } } diff --git a/Gems/LyShine/Code/Source/Draw2d.cpp b/Gems/LyShine/Code/Source/Draw2d.cpp index 308761ff4e..1a639ea299 100644 --- a/Gems/LyShine/Code/Source/Draw2d.cpp +++ b/Gems/LyShine/Code/Source/Draw2d.cpp @@ -309,7 +309,8 @@ void CDraw2d::DrawRectOutlineTextured(AZ::Data::Instance image, UiTransformInterface::RectPoints points, AZ::Vector2 rightVec, AZ::Vector2 downVec, - AZ::Color color) + AZ::Color color, + uint32_t lineThickness) { // since the rect can be transformed we have to add the offsets by multiplying them // by unit vectors parallel with the edges of the rect. However, the rect could be @@ -325,18 +326,22 @@ void CDraw2d::DrawRectOutlineTextured(AZ::Data::Instance image, float rectWidth = widthVec.GetLength(); float rectHeight = heightVec.GetLength(); - // the outline thickness will be based on the texture height - float textureHeight = image ? aznumeric_cast(image->GetDescriptor().m_size.m_height) : 0.0f; - if (textureHeight <= 0.0f) + if (lineThickness == 0 && image) { - AZ_Assert(false, "Attempting to draw a textured rect outline with an image of zero height."); - return; // avoiding possible divide by zero later + lineThickness = image->GetDescriptor().m_size.m_height; + } + + if (lineThickness == 0) + { + AZ_Assert(false, "Attempting to draw a rect outline with of zero thickness."); + return; } // the outline is centered on the element rect so half the outline is outside // the rect and half is inside the rect - float outerOffset = -textureHeight * 0.5f; - float innerOffset = textureHeight * 0.5f; + float offset = aznumeric_cast(lineThickness); + float outerOffset = -offset * 0.5f; + float innerOffset = offset * 0.5f; float outerV = 0.0f; float innerV = 1.0f; @@ -348,7 +353,7 @@ void CDraw2d::DrawRectOutlineTextured(AZ::Data::Instance image, { float oldInnerOffset = innerOffset; innerOffset = minDimension * 0.5f; - // note oldInnerOffset can't be zero because of early return if textureHeight is zero + // note oldInnerOffset can't be zero because of early return if lineThickness is zero innerV = 0.5f + 0.5f * innerOffset / oldInnerOffset; } From 0867764e5b732074a67985c4d758fab1a53910db Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 11 May 2021 22:46:21 -0700 Subject: [PATCH 141/225] Updating Autocomponent behavior context property methods to give warnings if a Get/Set fails and how users might go about fixing the issue --- .../Source/AutoGen/AutoComponent_Source.jinja | 49 ++++++++++++------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 423aa57706..576978f75c 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -666,36 +666,46 @@ enum class NetworkProperties {% if (Property.attrib['IsPublic'] | booleanTrue == true) and (Property.attrib['GenerateEventBindings'] | booleanTrue == true) %} ->Method("Get{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id) -> {{ Property.attrib['Type'] }} { - AZ::Entity* entity; - AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id); - - if (entity) + AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); + if (!entity) { - if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>()) - { - return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}(); - } + AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + return {{ Property.attrib['Type'] }}(); } - return {{ Property.attrib['Type'] }}(); + {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>(); + if (!networkComponent) + { + AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str()) + return {{ Property.attrib['Type'] }}(); + } + + return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}(); }) ->Method("Set{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id, const {{ Property.attrib['Type'] }}& {{ LowerFirst(Property.attrib['Name']) }}) -> void { - AZ::Entity* entity; - AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id); - - if (entity) + AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); + if (!entity) { + AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + return; + } + + {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>(); + if (!networkComponent) + { + AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} method failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str()) return; } - if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>()) + {{ ClassName }}Controller* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController()); + if (!controller) { - if (auto* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController())) - { - controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }}); - } + AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} method failed. Entity '%s' (id: %s) {{ ClassName }} is missing the network controller. Network controllers only spawn when some form of write access is available; for example, when you're server authoritatively controlling this entity, or you're a client predictively writing to your player entity. Please check your network context before attempting to set {{ UpperFirst(Property.attrib['Name']) }}.", entity->GetName().c_str(), id.ToString().c_str()) + return; } + + controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }}); }) {% endif %} {% endcall -%} @@ -1183,7 +1193,8 @@ namespace {{ Component.attrib['Namespace'] }} void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToBehaviorContext(AZ::ReflectContext* context) { - if (auto* behaviorContext = azrtti_cast(context)) + AZ::BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) { behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}") {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}} From 905bdf9627f5c6226624d3343fb2c45f0d707440 Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Mon, 3 May 2021 16:32:18 -0700 Subject: [PATCH 142/225] Fix sprite asset selection in property editor (#384) * Fix sprite asset selection in property editor * Linux compile fix * More fixes for the custom Sprite property handler * PR feedback to use existing constant image extension --- .../Code/Editor/PropertyHandlerSprite.cpp | 26 +++- Gems/LyShine/Code/Source/Sprite.cpp | 125 +++++++++++------- Gems/LyShine/Code/Source/Sprite.h | 8 ++ Gems/LyShine/Code/Source/UiImageComponent.cpp | 3 +- 4 files changed, 106 insertions(+), 56 deletions(-) diff --git a/Gems/LyShine/Code/Editor/PropertyHandlerSprite.cpp b/Gems/LyShine/Code/Editor/PropertyHandlerSprite.cpp index 20721d4624..9263210088 100644 --- a/Gems/LyShine/Code/Editor/PropertyHandlerSprite.cpp +++ b/Gems/LyShine/Code/Editor/PropertyHandlerSprite.cpp @@ -11,6 +11,7 @@ */ #include "UiCanvasEditor_precompiled.h" #include "EditorCommon.h" +#include "Sprite.h" #include "PropertyHandlerSprite.h" @@ -31,6 +32,8 @@ #include +#include + #include #include @@ -44,6 +47,7 @@ PropertySpriteCtrl::PropertySpriteCtrl(QWidget* parent) [ this ]([[maybe_unused]] AZ::Data::AssetId newAssetID) { EBUS_EVENT(AzToolsFramework::PropertyEditorGUIMessages::Bus, RequestWrite, this); + AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::Bus::Handler::OnEditingFinished, m_propertyAssetCtrl); }); setAcceptDrops(true); @@ -150,7 +154,9 @@ void PropertyHandlerSprite::WriteGUIValuesIntoProperty(size_t index, PropertySpr AZStd::string assetPath; EBUS_EVENT_RESULT(assetPath, AZ::Data::AssetCatalogRequestBus, GetAssetPathById, GUI->GetPropertyAssetCtrl()->GetCurrentAssetID()); - instance.SetAssetPath(assetPath.c_str()); + // Convert streaming image's product path to relative source path to assign to the SimpleAssetReference + AZStd::string sourcePath = CSprite::GetImageSourcePathFromProductPath(assetPath); + instance.SetAssetPath(sourcePath.c_str()); } bool PropertyHandlerSprite::ReadValuesIntoGUI(size_t index, PropertySpriteCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) @@ -162,12 +168,26 @@ bool PropertyHandlerSprite::ReadValuesIntoGUI(size_t index, PropertySpriteCtrl* ctrl->blockSignals(true); { - ctrl->SetCurrentAssetType(instance.GetAssetType()); + // Set the asset type for the PropertyAssetCtrl. + // Use the hardcoded streaming image asset type instead of the passed in instance's asset type + // since the passed in type is the legacy SimpleAssetReference, and the asset picker + // does not associate this type with streaming images + AZ::Data::AssetType assetType = AZ::AzTypeInfo::Uuid(); + ctrl->SetCurrentAssetType(assetType); AZ::Data::AssetId assetId; if (!instance.GetAssetPath().empty()) { - EBUS_EVENT_RESULT(assetId, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, instance.GetAssetPath().c_str(), instance.GetAssetType(), false); + // Get the image path from the SimpleAssetReference and fix it up since CSprite still + // allows user specified paths that have the .sprite extension or the deprecated .dds extension + AZStd::string sourcePath = CSprite::GetImageSourcePathFromProductPath(instance.GetAssetPath()); + AZStd::string fixedUpSourcePath; + CSprite::FixUpSourceImagePathFromUserDefinedPath(sourcePath, fixedUpSourcePath); + + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + assetId, &AZ::Data::AssetCatalogRequestBus::Events::GenerateAssetIdTEMP, + fixedUpSourcePath.c_str()); + assetId.m_subId = AZ::RPI::StreamingImageAsset::GetImageAssetSubId(); } ctrl->SetSelectedAssetID(assetId); } diff --git a/Gems/LyShine/Code/Source/Sprite.cpp b/Gems/LyShine/Code/Source/Sprite.cpp index c574a16c0c..26e4056a41 100644 --- a/Gems/LyShine/Code/Source/Sprite.cpp +++ b/Gems/LyShine/Code/Source/Sprite.cpp @@ -26,6 +26,7 @@ namespace { const char* const spriteExtension = "sprite"; + const char* const streamingImageExtension = "streamingimage"; // Increment this when the Sprite Serialize(TSerialize) function // changes to be incompatible with previous data @@ -37,7 +38,7 @@ namespace }; const int numAllowedSpriteTextureExtensions = AZ_ARRAY_SIZE(allowedSpriteTextureExtensions); - bool IsValidSpriteTextureExtension(const AZStd::string& extension) + bool IsValidImageExtension(const AZStd::string& extension) { for (int i = 0; i < numAllowedSpriteTextureExtensions; ++i) { @@ -50,6 +51,13 @@ namespace return false; } + bool IsImageProductPath(const AZStd::string& pathname) + { + AZStd::string extension; + AzFramework::StringFunc::Path::GetExtension(pathname.c_str(), extension, false); + return (extension.compare(streamingImageExtension) == 0); + } + // Check if a file exists. This does not go through the AssetCatalog so that it can identify files that exist but aren't processed yet, // and so that it will work before the AssetCatalog has loaded bool CheckIfFileExists(const AZStd::string& sourceRelativePath, const AZStd::string& cacheRelativePath) @@ -88,61 +96,49 @@ namespace return fileExists; } - bool ReplaceSpriteExtensionWithTextureExtension(const AZStd::string& spritePath, AZStd::string& texturePath) + bool GetSourceAssetPaths(const AZStd::string& pathname, AZStd::string& spritePath, AZStd::string& texturePath) { - for (int i = 0; i < numAllowedSpriteTextureExtensions; ++i) + // Remove product extension from the texture path if it exists + AZStd::string sourcePathname(pathname); + if (IsImageProductPath(pathname)) { - AZStd::string sourceRelativePath(spritePath); - AzFramework::StringFunc::Path::ReplaceExtension(sourceRelativePath, allowedSpriteTextureExtensions[i]); - AZStd::string cacheRelativePath = sourceRelativePath + ".streamingimage"; - - bool textureExists = CheckIfFileExists(sourceRelativePath, cacheRelativePath); - if (textureExists) - { - texturePath = sourceRelativePath; - return true; - } + sourcePathname = CSprite::GetImageSourcePathFromProductPath(pathname); } - return false; - } - - bool GetAssetPaths(const AZStd::string& pathname, AZStd::string& spritePath, AZStd::string& texturePath) - { - // the input string could be in any form. So make it normalized + // the input string could be in any form. So make it normalized (forward slashes and lower case) // NOTE: it should not be a full path at this point. If called from the UI editor it will // have been transformed to a game path. If being called with a hard coded path it should be a // game path already - it is not good for code to be using full paths. - AZStd::string assetPath(pathname); - EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePath, assetPath); + EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePath, sourcePathname); // check the extension and work out the pathname of the sprite file and the texture file // currently it works if the input path is either a sprite file or a texture file AZStd::string extension; - AzFramework::StringFunc::Path::GetExtension(assetPath.c_str(), extension, false); + AzFramework::StringFunc::Path::GetExtension(sourcePathname.c_str(), extension, false); if (extension.compare(spriteExtension) == 0) { - spritePath = assetPath; + // The .sprite file has been specified + spritePath = sourcePathname; // look for a texture file with the same name - if (!ReplaceSpriteExtensionWithTextureExtension(spritePath, texturePath)) + if (!CSprite::FixUpSourceImagePathFromUserDefinedPath(spritePath, texturePath)) { gEnv->pSystem->Warning(VALIDATOR_MODULE_SHINE, VALIDATOR_WARNING, VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE, - assetPath.c_str(), "No texture file found for sprite: %s, no sprite will be used", assetPath.c_str()); + spritePath.c_str(), "No texture file found for sprite: %s, no sprite will be used", spritePath.c_str()); return false; } } - else if (IsValidSpriteTextureExtension(extension)) + else if (IsValidImageExtension(extension)) { - texturePath = assetPath; - spritePath = assetPath; + texturePath = sourcePathname; + spritePath = sourcePathname; AzFramework::StringFunc::Path::ReplaceExtension(spritePath, spriteExtension); } else { gEnv->pSystem->Warning(VALIDATOR_MODULE_SHINE, VALIDATOR_WARNING, VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE, - assetPath.c_str(), "Invalid file extension for sprite: %s, no sprite will be used", assetPath.c_str()); + pathname.c_str(), "Invalid file extension for sprite: %s, no sprite will be used", pathname.c_str()); return false; } @@ -665,7 +661,7 @@ CSprite* CSprite::LoadSprite(const string& pathname) { AZStd::string spritePath; AZStd::string texturePath; - bool validAssetPaths = GetAssetPaths(pathname.c_str(), spritePath, texturePath); + bool validAssetPaths = GetSourceAssetPaths(pathname.c_str(), spritePath, texturePath); if (!validAssetPaths) { @@ -760,7 +756,7 @@ bool CSprite::DoesSpriteTextureAssetExist(const AZStd::string& pathname) { AZStd::string spritePath; AZStd::string texturePath; - bool validAssetPaths = GetAssetPaths(pathname, spritePath, texturePath); + bool validAssetPaths = GetSourceAssetPaths(pathname.c_str(), spritePath, texturePath); if (!validAssetPaths) { @@ -785,8 +781,7 @@ bool CSprite::DoesSpriteTextureAssetExist(const AZStd::string& pathname) } // Check if the texture asset exists - AZStd::string cacheRelativePath = texturePath + ".streamingimage"; - bool textureExists = CheckIfFileExists(texturePath, cacheRelativePath); + bool textureExists = CheckIfFileExists(spritePath, texturePath); return textureExists; } @@ -806,6 +801,48 @@ void CSprite::ReplaceSprite(ISprite** baseSprite, ISprite* newSprite) } } +//////////////////////////////////////////////////////////////////////////////////////////////////// +bool CSprite::FixUpSourceImagePathFromUserDefinedPath(const AZStd::string& userDefinedPath, AZStd::string& sourceImagePath) +{ + static const char* textureExtensions[] = { "png", "tif", "tiff", "tga", "jpg", "jpeg", "bmp", "gif" }; + + AZStd::string sourceRelativePath(userDefinedPath); + AZStd::string cacheRelativePath = AZStd::string::format("%s.%s", sourceRelativePath.c_str(), streamingImageExtension); + bool textureExists = CheckIfFileExists(sourceRelativePath, cacheRelativePath); + + if (textureExists) + { + sourceImagePath = userDefinedPath; + return true; + } + + AZStd::string curSourceImagePath(userDefinedPath); + for (const char* extensionReplacement : textureExtensions) + { + AzFramework::StringFunc::Path::ReplaceExtension(curSourceImagePath, extensionReplacement); + cacheRelativePath = AZStd::string::format("%s.%s", curSourceImagePath.c_str(), streamingImageExtension); + textureExists = CheckIfFileExists(curSourceImagePath, cacheRelativePath); + + if (textureExists) + { + sourceImagePath = curSourceImagePath; + return true; + } + } + + return false; +} + +AZStd::string CSprite::GetImageSourcePathFromProductPath(const AZStd::string& productPathname) +{ + AZStd::string sourcePathname(productPathname); + if (IsImageProductPath(sourcePathname)) + { + AzFramework::StringFunc::Path::StripExtension(sourcePathname); + } + return sourcePathname; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// bool CSprite::LoadTexture(const string& texturePathname, const string& pathname, ITexture*& texture) { @@ -850,7 +887,7 @@ void CSprite::ReleaseTexture(ITexture*& texture) bool CSprite::LoadImage(const AZStd::string& nameTex, AZ::Data::Instance& image) { AZStd::string sourceRelativePath(nameTex); - AZStd::string cacheRelativePath = sourceRelativePath + ".streamingimage"; + AZStd::string cacheRelativePath = AZStd::string::format("%s.%s", sourceRelativePath.c_str(), streamingImageExtension); bool textureExists = CheckIfFileExists(sourceRelativePath, cacheRelativePath); if (!textureExists) @@ -859,27 +896,13 @@ bool CSprite::LoadImage(const AZStd::string& nameTex, AZ::Data::InstanceAttribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshEntireTree", 0xefbc823c)); editInfo->DataElement("Sprite", &UiImageComponent::m_spritePathname, "Sprite path", "The sprite path. Can be overridden by another component such as an interactable.") ->Attribute(AZ::Edit::Attributes::Visibility, &UiImageComponent::IsSpriteTypeAsset) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &UiImageComponent::OnEditorSpritePathnameChange) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshEntireTree", 0xefbc823c)); + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &UiImageComponent::OnEditorSpritePathnameChange); editInfo->DataElement(AZ::Edit::UIHandlers::ComboBox, &UiImageComponent::m_spriteSheetCellIndex, "Index", "Sprite-sheet index. Defines which cell in a sprite-sheet is displayed.") ->Attribute(AZ::Edit::Attributes::Visibility, &UiImageComponent::IsSpriteTypeSpriteSheet) ->Attribute(AZ::Edit::Attributes::ChangeNotify, &UiImageComponent::OnIndexChange) From 3219c787ac66bf19dea7040581a27e2a80fa2d77 Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Thu, 6 May 2021 13:27:46 -0700 Subject: [PATCH 143/225] UI cursor Atom conversion (#607) --- Gems/LyShine/Code/CMakeLists.txt | 1 + Gems/LyShine/Code/Source/LyShine.cpp | 69 ++++++++++++++++++---------- Gems/LyShine/Code/Source/LyShine.h | 12 ++++- 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt index 9c46a61236..732bd1cfd4 100644 --- a/Gems/LyShine/Code/CMakeLists.txt +++ b/Gems/LyShine/Code/CMakeLists.txt @@ -93,6 +93,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) PUBLIC Gem::Atom_RPI.Public Gem::Atom_Utils.Static + Gem::Atom_Bootstrap.Headers ) ly_add_target( diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp index bc6a27dac4..679cae3421 100644 --- a/Gems/LyShine/Code/Source/LyShine.cpp +++ b/Gems/LyShine/Code/Source/LyShine.cpp @@ -137,7 +137,6 @@ CLyShine::CLyShine(ISystem* system) , m_draw2d(new CDraw2d) , m_uiRenderer(new UiRenderer) , m_uiCanvasManager(new UiCanvasManager) - , m_uiCursorTexture(nullptr) , m_uiCursorVisibleCounter(0) { // Reflect the Deprecated Lua buses using the behavior context. @@ -170,6 +169,7 @@ CLyShine::CLyShine(ISystem* system) AzFramework::InputTextEventListener::Connect(); UiCursorBus::Handler::BusConnect(); AZ::TickBus::Handler::BusConnect(); + AZ::Render::Bootstrap::NotificationBus::Handler::BusConnect(); // These are internal Amazon components, so register them so that we can send back their names to our metrics collection // IF YOU ARE A THIRDPARTY WRITING A GEM, DO NOT REGISTER YOUR COMPONENTS WITH EditorMetricsComponentRegistrationBus @@ -248,17 +248,12 @@ CLyShine::~CLyShine() AZ::TickBus::Handler::BusDisconnect(); AzFramework::InputTextEventListener::Disconnect(); AzFramework::InputChannelEventListener::Disconnect(); + AZ::Render::Bootstrap::NotificationBus::Handler::BusDisconnect(); UiCanvasComponent::Shutdown(); // must be done after UiCanvasComponent::Shutdown CSprite::Shutdown(); - - if (m_uiCursorTexture) - { - m_uiCursorTexture->Release(); - m_uiCursorTexture = nullptr; - } } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -443,6 +438,9 @@ void CLyShine::Render() // Render all the canvases loaded in game m_uiCanvasManager->RenderLoadedCanvases(); + // Set sort key for draw2d layer to ensure it renders in front of the canvases + static const int64_t topLayerKey = 0x1000000; + m_draw2d->SetSortKey(topLayerKey); m_draw2d->RenderDeferredPrimitives(); // Don't render the UI cursor when in edit mode. For example during UI Preview mode a script could turn on the @@ -558,18 +556,20 @@ bool CLyShine::IsUiCursorVisible() //////////////////////////////////////////////////////////////////////////////////////////////////// void CLyShine::SetUiCursor(const char* cursorImagePath) { - if (m_uiCursorTexture) - { - m_uiCursorTexture->Release(); - m_uiCursorTexture = nullptr; - } + m_uiCursorTexture.reset(); + m_cursorImagePathToLoad.clear(); - if (cursorImagePath && *cursorImagePath && gEnv && gEnv->pRenderer) + if (cursorImagePath && *cursorImagePath) { - m_uiCursorTexture = gEnv->pRenderer->EF_LoadTexture(cursorImagePath, FT_DONT_RELEASE | FT_DONT_STREAM); - if (m_uiCursorTexture) + m_cursorImagePathToLoad = cursorImagePath; + // The cursor image can only be loaded after the RPI has been initialized. + // Note: this check could be avoided if LyShineSystemComponent included the RPISystem + // as a required service. However, LyShineSystempComponent is currently activated for + // tools as well as game and RPIService is not available with all tools such as AP. An + // enhancement would be to break LyShineSystemComponent into a game only component + if (m_uiRenderer->IsReady()) { - m_uiCursorTexture->SetClamp(true); + LoadUiCursor(); } } } @@ -581,8 +581,11 @@ AZ::Vector2 CLyShine::GetUiCursorPosition() AzFramework::InputSystemCursorRequestBus::EventResult(systemCursorPositionNormalized, AzFramework::InputDeviceMouse::Id, &AzFramework::InputSystemCursorRequests::GetSystemCursorPositionNormalized); - return AZ::Vector2(systemCursorPositionNormalized.GetX() * static_cast(gEnv->pRenderer->GetOverlayWidth()), - systemCursorPositionNormalized.GetY() * static_cast(gEnv->pRenderer->GetOverlayHeight())); + + AZ::Vector2 viewportSize = m_uiRenderer->GetViewportSize(); + + return AZ::Vector2(systemCursorPositionNormalized.GetX() * viewportSize.GetX(), + systemCursorPositionNormalized.GetY() * viewportSize.GetY()); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -642,6 +645,7 @@ bool CLyShine::OnInputTextEventFiltered(const AZStd::string& textUTF8) return result; } +//////////////////////////////////////////////////////////////////////////////////////////////////// void CLyShine::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) { // Update the loaded UI canvases @@ -651,15 +655,33 @@ void CLyShine::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time Render(); } +//////////////////////////////////////////////////////////////////////////////////////////////////// int CLyShine::GetTickOrder() { return AZ::TICK_UI; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CLyShine::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstrapScene) +{ + // Load cursor if its path was set before RPI was initialized + LoadUiCursor(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CLyShine::LoadUiCursor() +{ + if (!m_cursorImagePathToLoad.empty()) + { + m_uiCursorTexture = CDraw2d::LoadTexture(m_cursorImagePathToLoad); // LYSHINE_ATOM_TODO - add clamp option to draw2d and set cursor to clamp + m_cursorImagePathToLoad.clear(); + } +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void CLyShine::RenderUiCursor() { - if (!gEnv || !gEnv->pRenderer || !m_uiCursorTexture || !IsUiCursorVisible()) + if (!m_uiCursorTexture || !IsUiCursorVisible()) { return; } @@ -671,13 +693,10 @@ void CLyShine::RenderUiCursor() } const AZ::Vector2 position = GetUiCursorPosition(); - const AZ::Vector2 dimensions(static_cast(m_uiCursorTexture->GetWidth()), static_cast(m_uiCursorTexture->GetHeight())); + AZ::RHI::Size cursorSize = m_uiCursorTexture->GetDescriptor().m_size; + const AZ::Vector2 dimensions(aznumeric_cast(cursorSize.m_width), aznumeric_cast(cursorSize.m_height)); -#ifdef LYSHINE_ATOM_TODO // Convert cursor to Atom image - m_draw2d->BeginDraw2d(); - m_draw2d->DrawImage(m_uiCursorTexture->GetTextureID(), position, dimensions); - m_draw2d->EndDraw2d(); -#endif + m_draw2d->DrawImage(m_uiCursorTexture, position, dimensions); } #ifndef _RELEASE diff --git a/Gems/LyShine/Code/Source/LyShine.h b/Gems/LyShine/Code/Source/LyShine.h index 943f5fa537..4c46b0db19 100644 --- a/Gems/LyShine/Code/Source/LyShine.h +++ b/Gems/LyShine/Code/Source/LyShine.h @@ -19,6 +19,9 @@ #include #include +#include +#include + #if !defined(_RELEASE) #define LYSHINE_INTERNAL_UNIT_TEST #endif @@ -41,6 +44,7 @@ class CLyShine , public AzFramework::InputChannelEventListener , public AzFramework::InputTextEventListener , public AZ::TickBus::Handler + , protected AZ::Render::Bootstrap::NotificationBus::Handler { public: @@ -111,6 +115,10 @@ public: int GetTickOrder() override; // ~TickEvents + // AZ::Render::Bootstrap::NotificationBus + void OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) override; + // ~AZ::Render::Bootstrap::NotificationBus + // Get the UIRenderer for the game (which is owned by CLyShine). This is not exposed outside the gem. UiRenderer* GetUiRenderer(); @@ -128,6 +136,7 @@ private: // member functions AZ_DISABLE_COPY_MOVE(CLyShine); + void LoadUiCursor(); void RenderUiCursor(); private: // static member functions @@ -146,7 +155,8 @@ private: // data std::unique_ptr m_uiCanvasManager; - ITexture* m_uiCursorTexture; + AZStd::string m_cursorImagePathToLoad; + AZ::Data::Instance m_uiCursorTexture; int m_uiCursorVisibleCounter; bool m_updatingLoadedCanvases = false; // guard against nested updates From d9cb61575e5c9afbc1d4f3f10cea3202e85db6b3 Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Fri, 7 May 2021 11:25:57 -0700 Subject: [PATCH 144/225] Fix up particle emitter to work with Atom (#626) * Fix up particle emitter component to work with Atom * PR feedback and disable render target tests until supported --- Code/CryEngine/CryCommon/LyShine/ISprite.h | 6 -- Gems/LyShine/Code/Source/Sprite.cpp | 84 +++---------------- Gems/LyShine/Code/Source/Sprite.h | 7 +- Gems/LyShine/Code/Source/UiImageComponent.cpp | 38 +++++---- .../Code/Source/UiImageSequenceComponent.cpp | 19 ++++- .../Source/UiParticleEmitterComponent.cpp | 27 ++++-- Gems/LyShine/Code/Tests/SpriteTest.cpp | 2 + .../Code/Source/UiCustomImageComponent.cpp | 4 +- 8 files changed, 76 insertions(+), 111 deletions(-) diff --git a/Code/CryEngine/CryCommon/LyShine/ISprite.h b/Code/CryEngine/CryCommon/LyShine/ISprite.h index d2e9a6e039..b9adda6901 100644 --- a/Code/CryEngine/CryCommon/LyShine/ISprite.h +++ b/Code/CryEngine/CryCommon/LyShine/ISprite.h @@ -16,9 +16,6 @@ #include #include -// forward declarations -class ITexture; - //////////////////////////////////////////////////////////////////////////////////////////////////// //! A sprite is a texture with extra information about how it behaves for 2D drawing //! Currently a sprite exists on disk as a side car file next to the texture file. @@ -80,9 +77,6 @@ public: // member functions //! Set the borders of a given cell within the sprite-sheet. virtual void SetCellBorders(int cellIndex, Borders borders) = 0; - //! Get the texture for this sprite - virtual ITexture* GetTexture() = 0; - //! Serialize this object for save/load virtual void Serialize(TSerialize ser) = 0; diff --git a/Gems/LyShine/Code/Source/Sprite.cpp b/Gems/LyShine/Code/Source/Sprite.cpp index 26e4056a41..7abbba4ea2 100644 --- a/Gems/LyShine/Code/Source/Sprite.cpp +++ b/Gems/LyShine/Code/Source/Sprite.cpp @@ -11,7 +11,6 @@ */ #include "LyShine_precompiled.h" #include "Sprite.h" -#include #include #include #include @@ -193,8 +192,7 @@ AZStd::string CSprite::s_emptyString; //////////////////////////////////////////////////////////////////////////////////////////////////// CSprite::CSprite() - : m_texture(nullptr) - , m_numSpriteSheetCellTags(0) + : m_numSpriteSheetCellTags(0) , m_atlas(nullptr) { AddRef(); @@ -204,8 +202,6 @@ CSprite::CSprite() //////////////////////////////////////////////////////////////////////////////////////////////////// CSprite::~CSprite() { - ReleaseTexture(m_texture); - s_loadedSprites->erase(m_pathname); TextureAtlasNamespace::TextureAtlasNotificationBus::Handler::BusDisconnect(); } @@ -250,26 +246,17 @@ void CSprite::SetCellBorders(int cellIndex, Borders borders) } //////////////////////////////////////////////////////////////////////////////////////////////////// -ITexture* CSprite::GetTexture() +AZ::Data::Instance CSprite::GetImage() { // Prioritize usage of an atlas +#ifdef LYSHINE_ATOM_TODO // texture atlas conversion to use Atom if (m_atlas) { return m_atlas->GetTexture(); } +#endif - if (!m_texture && !m_pathname.empty()) - { - // the render target texture may not have existed when the sprite was created - m_texture = gEnv->pRenderer->EF_GetTextureByName(m_pathname.c_str()); - if (m_texture) - { - // increase the reference count to this texture so it doesn't get removed while - // we are using it - m_texture->AddRef(); - } - } - return m_texture; + return m_image; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -377,31 +364,21 @@ bool CSprite::AreCellBordersZeroWidth(int cellIndex) const //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Vector2 CSprite::GetSize() { -#ifdef LYSHINE_ATOM_TODO // Convert texture atlases to use Atom - ITexture* texture = GetTexture(); - if (texture) + AZ::Data::Instance image = GetImage(); + if (image) { if (m_atlas) { return AZ::Vector2(static_cast(m_atlasCoordinates.GetWidth()), static_cast(m_atlasCoordinates.GetHeight())); } - return AZ::Vector2(static_cast(texture->GetWidth()), static_cast(texture->GetHeight())); - } - else - { - return AZ::Vector2(0.0f, 0.0f); - } -#else - if (m_image) - { - AZ::RHI::Size size = m_image->GetRHIImage()->GetDescriptor().m_size; + + AZ::RHI::Size size = image->GetRHIImage()->GetDescriptor().m_size; return AZ::Vector2(size.m_width, size.m_height); } else { return AZ::Vector2(0.0f, 0.0f); } -#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -734,6 +711,7 @@ CSprite* CSprite::CreateSprite(const string& renderTargetName) // create Sprite object CSprite* sprite = new CSprite; +#ifdef LYSHINE_ATOM_TODO // render target converstion to use ATom // the render target texture may not exist yet in which case we will need to load it later sprite->m_texture = gEnv->pRenderer->EF_GetTextureByName(renderTargetName.c_str()); if (sprite->m_texture) @@ -742,6 +720,7 @@ CSprite* CSprite::CreateSprite(const string& renderTargetName) // while we are using it sprite->m_texture->AddRef(); } +#endif sprite->m_pathname = renderTargetName; sprite->m_texturePathname.clear(); @@ -833,6 +812,7 @@ bool CSprite::FixUpSourceImagePathFromUserDefinedPath(const AZStd::string& userD return false; } +//////////////////////////////////////////////////////////////////////////////////////////////////// AZStd::string CSprite::GetImageSourcePathFromProductPath(const AZStd::string& productPathname) { AZStd::string sourcePathname(productPathname); @@ -843,46 +823,6 @@ AZStd::string CSprite::GetImageSourcePathFromProductPath(const AZStd::string& pr return sourcePathname; } -//////////////////////////////////////////////////////////////////////////////////////////////////// -bool CSprite::LoadTexture(const string& texturePathname, const string& pathname, ITexture*& texture) -{ - uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM); - texture = gEnv->pRenderer->EF_LoadTexture(texturePathname.c_str(), loadTextureFlags); - - if (!texture || !texture->IsTextureLoaded()) - { - gEnv->pSystem->Warning( - VALIDATOR_MODULE_SHINE, - VALIDATOR_WARNING, - VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE, - texturePathname.c_str(), - "No texture file found for sprite: %s, no sprite will be used. " - "NOTE: File must be in current project or a gem.", - pathname.c_str()); - texture = nullptr; - return false; - } - texture->SetFilter(FILTER_LINEAR); - return true; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CSprite::ReleaseTexture(ITexture*& texture) -{ - if (texture) - { - // In order to avoid the texture being deleted while there are still commands on the render - // thread command queue that use it, we queue a command to delete the texture onto the - // command queue. - auto pInfo = AZStd::make_unique(); - pInfo->eClassName = eRCN_Texture; - pInfo->pResource = texture; - gEnv->pRenderer->ReleaseResourceAsync(AZStd::move(pInfo)); - texture = nullptr; - } -} - //////////////////////////////////////////////////////////////////////////////////////////////////// bool CSprite::LoadImage(const AZStd::string& nameTex, AZ::Data::Instance& image) { diff --git a/Gems/LyShine/Code/Source/Sprite.h b/Gems/LyShine/Code/Source/Sprite.h index b3037bf242..026646013e 100644 --- a/Gems/LyShine/Code/Source/Sprite.h +++ b/Gems/LyShine/Code/Source/Sprite.h @@ -41,7 +41,6 @@ public: // member functions Borders GetBorders() const override; void SetBorders(Borders borders) override; void SetCellBorders(int cellIndex, Borders borders) override; - ITexture* GetTexture() override; void Serialize(TSerialize ser) override; bool SaveToXml(const string& pathname) override; bool AreBordersZeroWidth() const override; @@ -71,7 +70,7 @@ public: // member functions // ~TextureAtlasNotifications - AZ::Data::Instance GetImage() { return m_image; } + AZ::Data::Instance GetImage(); public: // static member functions @@ -93,9 +92,6 @@ public: // static member functions static AZStd::string GetImageSourcePathFromProductPath(const AZStd::string& productPathname); private: - static bool LoadTexture(const string& texturePathname, const string& pathname, ITexture*& texture); - static void ReleaseTexture(ITexture*& texture); - static bool LoadImage(const AZStd::string& nameTex, AZ::Data::Instance& image); static void ReleaseImage(AZ::Data::Instance& image); @@ -120,7 +116,6 @@ private: // data string m_pathname; string m_texturePathname; Borders m_borders; - ITexture* m_texture; AZ::Data::Instance m_image; int m_numSpriteSheetCellTags; //!< Number of Cell child-tags in sprite XML; unfortunately needed to help with serialization. diff --git a/Gems/LyShine/Code/Source/UiImageComponent.cpp b/Gems/LyShine/Code/Source/UiImageComponent.cpp index c2294b8a93..9cf923a460 100644 --- a/Gems/LyShine/Code/Source/UiImageComponent.cpp +++ b/Gems/LyShine/Code/Source/UiImageComponent.cpp @@ -34,9 +34,8 @@ #include #include "UiSerialize.h" -#include "Sprite.h" #include "UiLayoutHelpers.h" - +#include "Sprite.h" #include "RenderGraph.h" namespace @@ -281,6 +280,20 @@ namespace 14, 15, 21, 21, 20, 14, // center quad }; + AZ::Data::Instance GetSpriteImage(ISprite* sprite) + { + AZ::Data::Instance image; + if (sprite) + { + CSprite* cSprite = dynamic_cast(sprite); // LYSHINE_ATOM_TODO - find a different solution from downcasting + if (cSprite) + { + image = cSprite->GetImage(); + } + } + + return image; + } } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -471,20 +484,12 @@ void UiImageComponent::Render(LyShine::IRenderGraph* renderGraph) renderGraph->AddPrimitive(&m_cachedPrimitive, texture, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, m_blendMode); #else - AZ::Data::Instance image; - if (sprite) - { - CSprite* cSprite = static_cast(sprite); // LYSHINE_ATOM_TODO - find a different solution from downcasting - if (cSprite) - { - image = cSprite->GetImage(); - } - } + AZ::Data::Instance image = GetSpriteImage(sprite); bool isClampTextureMode = m_imageType == ImageType::Tiled ? false : true; bool isTextureSRGB = IsSpriteTypeRenderTarget() && m_isRenderTargetSRGB; bool isTexturePremultipliedAlpha = false; // we are not rendering from a render target with alpha in it - LyShine::RenderGraph* lyRenderGraph = static_cast(renderGraph); // LYSHINE_ATOM_TODO - find a different solution from downcasting + LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph); // LYSHINE_ATOM_TODO - find a different solution from downcasting if (lyRenderGraph) { lyRenderGraph->AddPrimitiveAtom(&m_cachedPrimitive, image, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, m_blendMode); @@ -880,8 +885,7 @@ float UiImageComponent::GetTargetWidth(float /*maxWidth*/) { float targetWidth = 0.0f; - ITexture* texture = (m_sprite) ? m_sprite->GetTexture() : nullptr; - if (texture) + if (m_sprite) { switch (m_imageType) { @@ -915,8 +919,7 @@ float UiImageComponent::GetTargetHeight(float /*maxHeight*/) { float targetHeight = 0.0f; - ITexture* texture = (m_sprite) ? m_sprite->GetTexture() : nullptr; - if (texture) + if (m_sprite) { switch (m_imageType) { @@ -2363,7 +2366,8 @@ void UiImageComponent::SnapOffsetsToFixedImage() } // if the image has no texture it will not use Fixed rendering so do nothing - if (!m_sprite || !m_sprite->GetTexture()) + AZ::Data::Instance image = GetSpriteImage(m_sprite); + if (!image) { return; } diff --git a/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp b/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp index e6cbef8386..df77a003ae 100644 --- a/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp +++ b/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp @@ -12,6 +12,9 @@ #include "LyShine_precompiled.h" #include "UiImageSequenceComponent.h" +#include "Sprite.h" +#include "RenderGraph.h" + #include #include #include @@ -100,7 +103,7 @@ void UiImageSequenceComponent::Render(LyShine::IRenderGraph* renderGraph) return; } - ISprite* sprite = m_spriteList[m_sequenceIndex]; + CSprite* sprite = dynamic_cast(m_spriteList[m_sequenceIndex]); // get fade value (tracked by UiRenderer) and compute the desired alpha for the image float fade = renderGraph->GetAlphaFade(); @@ -158,15 +161,23 @@ void UiImageSequenceComponent::Render(LyShine::IRenderGraph* renderGraph) } } - ITexture* texture = (sprite) ? sprite->GetTexture() : nullptr; + AZ::Data::Instance image; + if (sprite) + { + image = sprite->GetImage(); + } bool isClampTextureMode = false; bool isTextureSRGB = false; bool isTexturePremultipliedAlpha = false; LyShine::BlendMode blendMode = LyShine::BlendMode::Normal; // Add the quad to the render graph - renderGraph->AddPrimitive(&m_cachedPrimitive, texture, - isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode); + LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph); + if (lyRenderGraph) + { + lyRenderGraph->AddPrimitiveAtom(&m_cachedPrimitive, image, + isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode); + } } } diff --git a/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp b/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp index e54f61fbfa..3c9a871847 100644 --- a/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp +++ b/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp @@ -13,6 +13,8 @@ #include "UiParticleEmitterComponent.h" #include "EditorPropertyTypes.h" +#include "Sprite.h" +#include "RenderGraph.h" #include #include @@ -21,7 +23,6 @@ #include #include -#include #include #include @@ -764,6 +765,12 @@ void UiParticleEmitterComponent::InGamePostActivate() //////////////////////////////////////////////////////////////////////////////////////////////////// void UiParticleEmitterComponent::Render(LyShine::IRenderGraph* renderGraph) { + AZ::u32 particlesToRender = AZ::GetMin(m_particleContainer.size(), m_particleBufferSize); + if (particlesToRender == 0) + { + return; + } + AZ::Matrix4x4 transform = AZ::Matrix4x4::CreateIdentity(); AZ::Vector2 emitterOffset = AZ::Vector2::CreateZero(); @@ -781,9 +788,15 @@ void UiParticleEmitterComponent::Render(LyShine::IRenderGraph* renderGraph) EBUS_EVENT_ID_RESULT(transform, canvasID, UiCanvasBus, GetCanvasToViewportMatrix); } - AZ::u32 particlesToRender = AZ::GetMin(m_particleContainer.size(), m_particleBufferSize); - - ITexture* texture = (m_sprite) ? m_sprite->GetTexture() : nullptr; + AZ::Data::Instance image; + if (m_sprite) + { + CSprite* sprite = dynamic_cast(m_sprite); + if (sprite) + { + image = sprite->GetImage(); + } + } bool isClampTextureMode = true; bool isTextureSRGB = false; @@ -836,7 +849,11 @@ void UiParticleEmitterComponent::Render(LyShine::IRenderGraph* renderGraph) m_cachedPrimitive.m_numVertices = totalVerticesInserted; m_cachedPrimitive.m_numIndices = totalParticlesInserted * indicesPerParticle; - renderGraph->AddPrimitive(&m_cachedPrimitive, texture, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, m_blendMode); + LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph); + if (lyRenderGraph) + { + lyRenderGraph->AddPrimitiveAtom(&m_cachedPrimitive, image, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, m_blendMode); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/LyShine/Code/Tests/SpriteTest.cpp b/Gems/LyShine/Code/Tests/SpriteTest.cpp index 1d45a6113c..29ef1eb7f2 100644 --- a/Gems/LyShine/Code/Tests/SpriteTest.cpp +++ b/Gems/LyShine/Code/Tests/SpriteTest.cpp @@ -68,6 +68,7 @@ namespace UnitTest AZStd::unique_ptr m_data; }; +#ifdef LYSHINE_ATOM_TODO // [LYN-3359] - render target support using Atom TEST_F(LyShineSpriteTest, Sprite_CanAcquireRenderTarget) { // initialize to create the static sprite cache @@ -130,6 +131,7 @@ namespace UnitTest CSprite::Shutdown(); delete mockTexture; } +#endif } //namespace UnitTest AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); diff --git a/Gems/LyShineExamples/Code/Source/UiCustomImageComponent.cpp b/Gems/LyShineExamples/Code/Source/UiCustomImageComponent.cpp index 1bd2bd10be..b2055f2a0c 100644 --- a/Gems/LyShineExamples/Code/Source/UiCustomImageComponent.cpp +++ b/Gems/LyShineExamples/Code/Source/UiCustomImageComponent.cpp @@ -78,8 +78,9 @@ namespace LyShineExamples } //////////////////////////////////////////////////////////////////////////////////////////////////// - void UiCustomImageComponent::Render(LyShine::IRenderGraph* renderGraph) + void UiCustomImageComponent::Render([[maybe_unused]] LyShine::IRenderGraph* renderGraph) { +#ifdef LYSHINE_ATOM_TODO // [LYN-3635] convert to use Atom // get fade value (tracked by UiRenderer) and compute the desired alpha for the image float fade = renderGraph->GetAlphaFade(); float desiredAlpha = m_overrideAlpha * fade; @@ -126,6 +127,7 @@ namespace LyShineExamples bool isTexturePremultipliedAlpha = false; // we are not rendering from a render target with alpha in it LyShine::BlendMode blendMode = LyShine::BlendMode::Normal; renderGraph->AddPrimitive(&m_cachedPrimitive, texture, m_clamp, isTextureSRGB, isTexturePremultipliedAlpha, blendMode); +#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// From 2558801a247498bb0ed05b7ebaf26d9ccd98a7f0 Mon Sep 17 00:00:00 2001 From: jjjoness <82226755+jjjoness@users.noreply.github.com> Date: Wed, 12 May 2021 08:58:16 +0100 Subject: [PATCH 145/225] Commit before merging main --- Code/Sandbox/Editor/MainWindow.cpp | 4 ++-- Code/Sandbox/Editor/ToolbarManager.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index 5abb780bac..5538df1424 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -1064,8 +1064,8 @@ void MainWindow::InitActions() .SetApplyHoverEffect() .SetCheckable(true) .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdatePlayGame); - am->AddAction(ID_TOOLBAR_WIDGET_PLAYCONSOLE_LABEL, tr("Play Console")) - .SetText(tr("Play Console")); + am->AddAction(ID_TOOLBAR_WIDGET_PLAYCONSOLE_LABEL, tr("Play Controls")) + .SetText(tr("Play Controls")); am->AddAction(ID_SWITCH_PHYSICS, tr("Simulate")) .SetShortcut(tr("Ctrl+P")) .SetToolTip(tr("Simulate (Ctrl+P)")) diff --git a/Code/Sandbox/Editor/ToolbarManager.cpp b/Code/Sandbox/Editor/ToolbarManager.cpp index bbb3ef6790..76fbe92fa8 100644 --- a/Code/Sandbox/Editor/ToolbarManager.cpp +++ b/Code/Sandbox/Editor/ToolbarManager.cpp @@ -613,7 +613,7 @@ AmazonToolbar ToolbarManager::GetObjectToolbar() const AmazonToolbar ToolbarManager::GetPlayConsoleToolbar() const { - AmazonToolbar t = AmazonToolbar("PlayConsole", QObject::tr("Play Console")); + AmazonToolbar t = AmazonToolbar("PlayConsole", QObject::tr("Play Controls")); t.SetMainToolbar(true); t.AddAction(ID_TOOLBAR_WIDGET_SPACER_RIGHT, ORIGINAL_TOOLBAR_VERSION); From f9fb61cc5df598f799d8b44d854fa6b1ea91b1ef Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Wed, 12 May 2021 09:40:37 +0100 Subject: [PATCH 146/225] Fix issue with viewport interaction ordering and viewport matrix changed handler (#695) * fix for ctrl+mouse-wheel to cycle transform modes in the viewport * ensure correct callback function is invoked * remove redundant check in CameraInput --- .../AzFramework/Viewport/CameraInput.cpp | 5 - .../Editor/ViewportManipulatorController.cpp | 354 ++++++++++-------- .../Editor/ViewportManipulatorController.h | 2 +- .../Source/RPI.Public/ViewportContext.cpp | 3 +- 4 files changed, 191 insertions(+), 173 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index 4c95865938..8669b58911 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -407,11 +407,6 @@ namespace AzFramework { if (input->m_state == InputChannel::State::Began) { - if (input->m_state == InputChannel::State::Updated) - { - return; - } - m_translation |= translationFromKey(input->m_channelId); if (m_translation != TranslationType::Nil) { diff --git a/Code/Sandbox/Editor/ViewportManipulatorController.cpp b/Code/Sandbox/Editor/ViewportManipulatorController.cpp index 0bf2bbc412..248d2ba52c 100644 --- a/Code/Sandbox/Editor/ViewportManipulatorController.cpp +++ b/Code/Sandbox/Editor/ViewportManipulatorController.cpp @@ -21,206 +21,228 @@ #include -static const auto ManipulatorPriority = AzFramework::ViewportControllerPriority::High; -static const auto InteractionPriority = AzFramework::ViewportControllerPriority::Low; +static const auto ManipulatorPriority = AzFramework::ViewportControllerPriority::Highest; +static const auto InteractionPriority = AzFramework::ViewportControllerPriority::High; namespace SandboxEditor { - -ViewportManipulatorControllerInstance::ViewportManipulatorControllerInstance(AzFramework::ViewportId viewport, ViewportManipulatorController* controller) - : AzFramework::MultiViewportControllerInstanceInterface(viewport, controller) -{ -} - -AzToolsFramework::ViewportInteraction::MouseButton ViewportManipulatorControllerInstance::GetMouseButton( - const AzFramework::InputChannel& inputChannel) -{ - using AzToolsFramework::ViewportInteraction::MouseButton; - using InputButton = AzFramework::InputDeviceMouse::Button; - const auto& id = inputChannel.GetInputChannelId(); - if (id == InputButton::Left) + ViewportManipulatorControllerInstance::ViewportManipulatorControllerInstance( + AzFramework::ViewportId viewport, ViewportManipulatorController* controller) + : AzFramework::MultiViewportControllerInstanceInterface(viewport, controller) { - return MouseButton::Left; - } - if (id == InputButton::Middle) - { - return MouseButton::Middle; - } - if (id == InputButton::Right) - { - return MouseButton::Right; - } - return MouseButton::None; -} - -bool ViewportManipulatorControllerInstance::IsMouseMove(const AzFramework::InputChannel& inputChannel) -{ - return inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::SystemCursorPosition; -} - -AzToolsFramework::ViewportInteraction::KeyboardModifier ViewportManipulatorControllerInstance::GetKeyboardModifier( - const AzFramework::InputChannel& inputChannel) -{ - using AzToolsFramework::ViewportInteraction::KeyboardModifier; - using Key = AzFramework::InputDeviceKeyboard::Key; - const auto& id = inputChannel.GetInputChannelId(); - if (id == Key::ModifierAltL || id == Key::ModifierAltR) - { - return KeyboardModifier::Alt; - } - if (id == Key::ModifierCtrlL || id == Key::ModifierCtrlR) - { - return KeyboardModifier::Ctrl; - } - if (id == Key::ModifierShiftL || id == Key::ModifierShiftR) - { - return KeyboardModifier::Shift; - } - return KeyboardModifier::None; -} - -bool ViewportManipulatorControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) -{ - // We only care about manipulator and viewport interaction events - if (event.m_priority != ManipulatorPriority && event.m_priority != InteractionPriority) - { - return false; } - using InteractionBus = AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus; - using namespace AzToolsFramework::ViewportInteraction; - using AzFramework::InputChannel; - - bool interactionHandled = false; - AZStd::optional overrideButton; - AZStd::optional eventType; - - // Because we receive events multiple times at separate priorities for manipulator events and - // viewport interaction events, we want to avoid updating our "last tick state" until we're on our last event, - // which currently is the low priority Interaction processor. - const bool finishedProcessingEvents = event.m_priority == InteractionPriority; - - if (IsMouseMove(event.m_inputChannel)) + AzToolsFramework::ViewportInteraction::MouseButton ViewportManipulatorControllerInstance::GetMouseButton( + const AzFramework::InputChannel& inputChannel) { - // Cache the ray trace results when doing manipulator interaction checks, no need to recalculate after - if (event.m_priority == ManipulatorPriority) + using AzToolsFramework::ViewportInteraction::MouseButton; + using InputButton = AzFramework::InputDeviceMouse::Button; + const auto& id = inputChannel.GetInputChannelId(); + if (id == InputButton::Left) { - AzFramework::ScreenPoint screenPosition = AzFramework::ScreenPoint(0, 0); - ViewportMouseCursorRequestBus::EventResult( - screenPosition, GetViewportId(), &ViewportMouseCursorRequestBus::Events::ViewportCursorScreenPosition); - - m_state.m_mousePick.m_screenCoordinates = screenPosition; - AZStd::optional ray; - ViewportInteractionRequestBus::EventResult( - ray, GetViewportId(), &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPosition); - - if (ray.has_value()) - { - m_state.m_mousePick.m_rayOrigin = ray.value().origin; - m_state.m_mousePick.m_rayDirection = ray.value().direction; - } + return MouseButton::Left; } - eventType = MouseEvent::Move; - } - else if (auto mouseButton = GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None) - { - const AZ::u32 mouseButtonValue = static_cast(mouseButton); - overrideButton = mouseButton; - if (event.m_inputChannel.GetState() == InputChannel::State::Began) + if (id == InputButton::Middle) { - m_state.m_mouseButtons.m_mouseButtons |= mouseButtonValue; - if (IsDoubleClick(mouseButton)) + return MouseButton::Middle; + } + if (id == InputButton::Right) + { + return MouseButton::Right; + } + return MouseButton::None; + } + + bool ViewportManipulatorControllerInstance::IsMouseMove(const AzFramework::InputChannel& inputChannel) + { + return inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::SystemCursorPosition; + } + + AzToolsFramework::ViewportInteraction::KeyboardModifier ViewportManipulatorControllerInstance::GetKeyboardModifier( + const AzFramework::InputChannel& inputChannel) + { + using AzToolsFramework::ViewportInteraction::KeyboardModifier; + using Key = AzFramework::InputDeviceKeyboard::Key; + const auto& id = inputChannel.GetInputChannelId(); + if (id == Key::ModifierAltL || id == Key::ModifierAltR) + { + return KeyboardModifier::Alt; + } + if (id == Key::ModifierCtrlL || id == Key::ModifierCtrlR) + { + return KeyboardModifier::Ctrl; + } + if (id == Key::ModifierShiftL || id == Key::ModifierShiftR) + { + return KeyboardModifier::Shift; + } + return KeyboardModifier::None; + } + + bool ViewportManipulatorControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) + { + // We only care about manipulator and viewport interaction events + if (event.m_priority != ManipulatorPriority && event.m_priority != InteractionPriority) + { + return false; + } + + using InteractionBus = AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus; + using namespace AzToolsFramework::ViewportInteraction; + using AzFramework::InputChannel; + + bool interactionHandled = false; + float wheelDelta = 0.0f; + AZStd::optional overrideButton; + AZStd::optional eventType; + + // Because we receive events multiple times at separate priorities for manipulator events and + // viewport interaction events, we want to avoid updating our "last tick state" until we're on our last event, + // which currently is the low priority Interaction processor. + const bool finishedProcessingEvents = event.m_priority == InteractionPriority; + + const auto state = event.m_inputChannel.GetState(); + if (IsMouseMove(event.m_inputChannel)) + { + // Cache the ray trace results when doing manipulator interaction checks, no need to recalculate after + if (event.m_priority == ManipulatorPriority) { - // Only remove the double click flag once we're done processing both Manipulator and Interaction events - if (event.m_priority == InteractionPriority) + AzFramework::ScreenPoint screenPosition = AzFramework::ScreenPoint(0, 0); + ViewportMouseCursorRequestBus::EventResult( + screenPosition, GetViewportId(), &ViewportMouseCursorRequestBus::Events::ViewportCursorScreenPosition); + + m_mouseInteraction.m_mousePick.m_screenCoordinates = screenPosition; + AZStd::optional ray; + ViewportInteractionRequestBus::EventResult( + ray, GetViewportId(), &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPosition); + + if (ray.has_value()) { - m_pendingDoubleClicks.erase(mouseButton); + m_mouseInteraction.m_mousePick.m_rayOrigin = ray.value().origin; + m_mouseInteraction.m_mousePick.m_rayDirection = ray.value().direction; } - eventType = MouseEvent::DoubleClick; } - else + eventType = MouseEvent::Move; + } + else if (auto mouseButton = GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None) + { + const AZ::u32 mouseButtonValue = static_cast(mouseButton); + overrideButton = mouseButton; + if (state == InputChannel::State::Began) { - // Only insert the double click timing once we're done processing events, to avoid a false IsDoubleClick positive - if (finishedProcessingEvents) + m_mouseInteraction.m_mouseButtons.m_mouseButtons |= mouseButtonValue; + if (IsDoubleClick(mouseButton)) { - m_pendingDoubleClicks[mouseButton] = m_curTime; + // Only remove the double click flag once we're done processing both Manipulator and Interaction events + if (event.m_priority == InteractionPriority) + { + m_pendingDoubleClicks.erase(mouseButton); + } + eventType = MouseEvent::DoubleClick; + } + else + { + // Only insert the double click timing once we're done processing events, to avoid a false IsDoubleClick positive + if (finishedProcessingEvents) + { + m_pendingDoubleClicks[mouseButton] = m_curTime; + } + eventType = MouseEvent::Down; } - eventType = MouseEvent::Down; } - } - else if (event.m_inputChannel.GetState() == InputChannel::State::Ended) - { - // If we've actually logged a mouse down event, forward a mouse up event. - // This prevents corner cases like the context menu thinking it should be opened even though no one clicked in this viewport, - // due to RenderViewportWidget ensuring all controllers get InputChannel::State::Ended events. - if (m_state.m_mouseButtons.m_mouseButtons & mouseButtonValue) + else if (state == InputChannel::State::Ended) { - // Erase the button from our state if we're done processing events. - if (event.m_priority == InteractionPriority) + // If we've actually logged a mouse down event, forward a mouse up event. + // This prevents corner cases like the context menu thinking it should be opened even though no one clicked in this viewport, + // due to RenderViewportWidget ensuring all controllers get InputChannel::State::Ended events. + if (m_mouseInteraction.m_mouseButtons.m_mouseButtons & mouseButtonValue) { - m_state.m_mouseButtons.m_mouseButtons &= ~mouseButtonValue; + // Erase the button from our state if we're done processing events. + if (event.m_priority == InteractionPriority) + { + m_mouseInteraction.m_mouseButtons.m_mouseButtons &= ~mouseButtonValue; + } + eventType = MouseEvent::Up; } - eventType = MouseEvent::Up; } } - } - else if (auto keyboardModifier = GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None) - { - if (event.m_inputChannel.GetState() == InputChannel::State::Began || event.m_inputChannel.GetState() == InputChannel::State::Updated) + else if (auto keyboardModifier = GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None) { - m_state.m_keyboardModifiers.m_keyModifiers |= static_cast(keyboardModifier); + if (state == InputChannel::State::Began || state == InputChannel::State::Updated) + { + m_mouseInteraction.m_keyboardModifiers.m_keyModifiers |= static_cast(keyboardModifier); + } + else if (state == InputChannel::State::Ended) + { + m_mouseInteraction.m_keyboardModifiers.m_keyModifiers &= ~static_cast(keyboardModifier); + } } - else if (event.m_inputChannel.GetState() == InputChannel::State::Ended) + else if (event.m_inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::Movement::Z) { - m_state.m_keyboardModifiers.m_keyModifiers &= ~static_cast(keyboardModifier); + if (state == InputChannel::State::Began || state == InputChannel::State::Updated) + { + eventType = MouseEvent::Wheel; + wheelDelta = event.m_inputChannel.GetValue(); + } } - } - if (eventType) - { - MouseInteraction mouseInteraction = m_state; - if (overrideButton) + if (eventType) { - mouseInteraction.m_mouseButtons.m_mouseButtons = static_cast(overrideButton.value()); + MouseInteraction mouseInteraction = m_mouseInteraction; + if (overrideButton) + { + mouseInteraction.m_mouseButtons.m_mouseButtons = static_cast(overrideButton.value()); + } + + mouseInteraction.m_interactionId.m_viewportId = GetViewportId(); + + // Depending on priority, we dispatch to either the manipulator or viewport interaction event + const auto& targetInteractionEvent = event.m_priority == ManipulatorPriority + ? &InteractionBus::Events::InternalHandleMouseManipulatorInteraction + : &InteractionBus::Events::InternalHandleMouseViewportInteraction; + + const auto mouseInteractionEvent = [mouseInteraction, event = eventType.value(), wheelDelta] { + switch (event) + { + case MouseEvent::Up: + case MouseEvent::Down: + case MouseEvent::Move: + case MouseEvent::DoubleClick: + return MouseInteractionEvent(AZStd::move(mouseInteraction), event); + case MouseEvent::Wheel: + return MouseInteractionEvent(AZStd::move(mouseInteraction), wheelDelta); + } + + AZ_Assert(false, "Unhandled MouseEvent"); + return MouseInteractionEvent(MouseInteraction{}, MouseEvent::Up); + }(); + + InteractionBus::EventResult( + interactionHandled, AzToolsFramework::GetEntityContextId(), targetInteractionEvent, mouseInteractionEvent); } - mouseInteraction.m_interactionId.m_viewportId = GetViewportId(); - // Depending on priority, we dispatch to either the manipulator or viewport interaction event - const auto& targetInteractionEvent = - event.m_priority == ManipulatorPriority - ? &InteractionBus::Events::InternalHandleMouseManipulatorInteraction - : &InteractionBus::Events::InternalHandleMouseViewportInteraction; - - InteractionBus::EventResult( - interactionHandled, - AzToolsFramework::GetEntityContextId(), - targetInteractionEvent, - MouseInteractionEvent(AZStd::move(mouseInteraction), eventType.value())); + return interactionHandled; } - return interactionHandled; -} - -void ViewportManipulatorControllerInstance::ResetInputChannels() -{ - m_pendingDoubleClicks.clear(); - m_state = AzToolsFramework::ViewportInteraction::MouseInteraction(); -} - -void ViewportManipulatorControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) -{ - m_curTime = event.m_time; -} - -bool ViewportManipulatorControllerInstance::IsDoubleClick(AzToolsFramework::ViewportInteraction::MouseButton button) const -{ - auto clickIt = m_pendingDoubleClicks.find(button); - if (clickIt == m_pendingDoubleClicks.end()) + void ViewportManipulatorControllerInstance::ResetInputChannels() { - return false; + m_pendingDoubleClicks.clear(); + m_mouseInteraction = AzToolsFramework::ViewportInteraction::MouseInteraction(); } - const double doubleClickThresholdMilliseconds = qApp->doubleClickInterval(); - return (m_curTime.GetMilliseconds() - clickIt->second.GetMilliseconds()) < doubleClickThresholdMilliseconds; -} + void ViewportManipulatorControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) + { + m_curTime = event.m_time; + } + + bool ViewportManipulatorControllerInstance::IsDoubleClick(AzToolsFramework::ViewportInteraction::MouseButton button) const + { + auto clickIt = m_pendingDoubleClicks.find(button); + if (clickIt == m_pendingDoubleClicks.end()) + { + return false; + } + const double doubleClickThresholdMilliseconds = qApp->doubleClickInterval(); + return (m_curTime.GetMilliseconds() - clickIt->second.GetMilliseconds()) < doubleClickThresholdMilliseconds; + } } //namespace SandboxEditor diff --git a/Code/Sandbox/Editor/ViewportManipulatorController.h b/Code/Sandbox/Editor/ViewportManipulatorController.h index d5540229c4..6d4ab4d1ba 100644 --- a/Code/Sandbox/Editor/ViewportManipulatorController.h +++ b/Code/Sandbox/Editor/ViewportManipulatorController.h @@ -39,7 +39,7 @@ namespace SandboxEditor static bool IsMouseMove(const AzFramework::InputChannel& inputChannel); static AzToolsFramework::ViewportInteraction::KeyboardModifier GetKeyboardModifier(const AzFramework::InputChannel& inputChannel); - AzToolsFramework::ViewportInteraction::MouseInteraction m_state; + AzToolsFramework::ViewportInteraction::MouseInteraction m_mouseInteraction; AZStd::unordered_map m_pendingDoubleClicks; AZ::ScriptTimePoint m_curTime; }; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp index cc25fb39ba..0dae5ac2d0 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp @@ -40,9 +40,10 @@ namespace AZ { m_projectionMatrixChangedEvent.Signal(matrix); }); + m_onViewMatrixChangedHandler = ViewportContext::MatrixChangedEvent::Handler([this](const AZ::Matrix4x4& matrix) { - m_projectionMatrixChangedEvent.Signal(matrix); + m_viewMatrixChangedEvent.Signal(matrix); }); SetRenderScene(renderScene); From 552ebea1350898594de79471e6b683bf51bfbbf1 Mon Sep 17 00:00:00 2001 From: jjjoness <82226755+jjjoness@users.noreply.github.com> Date: Wed, 12 May 2021 11:40:36 +0100 Subject: [PATCH 147/225] Added Simulate button --- .../img/UI20/toolbar/Simulate_Physics.svg | 24 +++++++++++++++++++ .../AzQtComponents/Components/resources.qrc | 1 + Code/Sandbox/Editor/MainWindow.cpp | 3 +++ Code/Sandbox/Editor/ToolbarManager.cpp | 2 ++ 4 files changed, 30 insertions(+) create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Simulate_Physics.svg diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Simulate_Physics.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Simulate_Physics.svg new file mode 100644 index 0000000000..0839be31b1 --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Simulate_Physics.svg @@ -0,0 +1,24 @@ + + + Icon / Toolbar / Play Console / Simulate Physics + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc index 1e8ddb43e0..b995874a41 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc @@ -372,6 +372,7 @@ img/UI20/toolbar/Select.svg img/UI20/toolbar/select_object.svg img/UI20/toolbar/Select_terrain.svg + img/UI20/toolbar/Simulate_Physics.svg img/UI20/toolbar/Simulate_Physics_on_selected_objects.svg img/UI20/toolbar/Terrain.svg img/UI20/toolbar/Terrain_Texture.svg diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index c02b64f8b7..b6aece28e3 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -1023,10 +1023,13 @@ void MainWindow::InitActions() am->AddAction(ID_TOOLBAR_WIDGET_PLAYCONSOLE_LABEL, tr("Play Controls")) .SetText(tr("Play Controls")); am->AddAction(ID_SWITCH_PHYSICS, tr("Simulate")) + .SetIcon(QIcon(":/stylesheet/img/UI20/toolbar/Simulate_Physics.svg")) .SetShortcut(tr("Ctrl+P")) .SetToolTip(tr("Simulate (Ctrl+P)")) .SetCheckable(true) .SetStatusTip(tr("Enable processing of Physics and AI.")) + .SetApplyHoverEffect() + .SetCheckable(true) .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnSwitchPhysicsUpdate); am->AddAction(ID_GAME_SYNCPLAYER, tr("Move Player and Camera Separately")).SetCheckable(true) .SetStatusTip(tr("Move Player and Camera Separately")) diff --git a/Code/Sandbox/Editor/ToolbarManager.cpp b/Code/Sandbox/Editor/ToolbarManager.cpp index 7d7ac5112b..391eabae33 100644 --- a/Code/Sandbox/Editor/ToolbarManager.cpp +++ b/Code/Sandbox/Editor/ToolbarManager.cpp @@ -616,6 +616,8 @@ AmazonToolbar ToolbarManager::GetPlayConsoleToolbar() const t.AddAction(ID_TOOLBAR_SEPARATOR, ORIGINAL_TOOLBAR_VERSION); t.AddAction(ID_TOOLBAR_WIDGET_PLAYCONSOLE_LABEL, ORIGINAL_TOOLBAR_VERSION); t.AddAction(ID_VIEW_SWITCHTOGAME, TOOLBARS_WITH_PLAY_GAME); + t.AddAction(ID_TOOLBAR_SEPARATOR, ORIGINAL_TOOLBAR_VERSION); + t.AddAction(ID_SWITCH_PHYSICS, TOOLBARS_WITH_PLAY_GAME); return t; } From ae9b36c135ac17d1e3a22e626084b4a4e359717e Mon Sep 17 00:00:00 2001 From: mbalfour Date: Wed, 12 May 2021 08:56:49 -0500 Subject: [PATCH 148/225] PR feedback - now allows for multiple specializations on the command-line, and changed the switch name to "specializations" to reflect that. --- Code/Tools/SerializeContextTools/Application.cpp | 8 +++++--- Code/Tools/SerializeContextTools/main.cpp | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Code/Tools/SerializeContextTools/Application.cpp b/Code/Tools/SerializeContextTools/Application.cpp index 72e68ebb1e..da0cca5ca6 100644 --- a/Code/Tools/SerializeContextTools/Application.cpp +++ b/Code/Tools/SerializeContextTools/Application.cpp @@ -64,10 +64,12 @@ namespace AZ AZ::SettingsRegistryInterface::Specializations projectSpecializations{ projectName }; // If a project specialization has been passed in via the command line, use it. - if (m_commandLine.HasSwitch("specialization")) + if (size_t specializationCount = m_commandLine.GetNumSwitchValues("specializations"); specializationCount > 0) { - AZStd::string specialization = m_commandLine.GetSwitchValue("specialization", 0); - projectSpecializations.Append(specialization); + for (size_t specializationIndex = 0; specializationIndex < specializationCount; ++specializationIndex) + { + projectSpecializations.Append(m_commandLine.GetSwitchValue("specializations", specializationIndex)); + } } // Otherwise, if a config file was passed in, auto-set the specialization based on the config file name. else diff --git a/Code/Tools/SerializeContextTools/main.cpp b/Code/Tools/SerializeContextTools/main.cpp index 4bff597d81..fb2dc442ed 100644 --- a/Code/Tools/SerializeContextTools/main.cpp +++ b/Code/Tools/SerializeContextTools/main.cpp @@ -23,7 +23,8 @@ void PrintHelp() AZ_Printf("Help", "Serialize Context Tool\n"); AZ_Printf("Help", " [-config] *\n"); AZ_Printf("Help", " [opt] -config=: optional path to application's config file. Default is 'config/editor.xml'.\n"); - AZ_Printf("Help", " [opt] -specialization=: optional Registry project specialization, such as 'editor' or 'game'. Default is none. \n"); + AZ_Printf("Help", " [opt] -specializations=: -separated list of optional Registry project\n"); + AZ_Printf("Help", " specializations, such as 'editor' or 'game' or 'editor;test'. Default is none. \n"); AZ_Printf("Help", "\n"); AZ_Printf("Help", " 'help': Print this help\n"); AZ_Printf("Help", " example: 'help'\n"); From 7cec2d8b076445ea8e2c965cc4a20bd424d74b50 Mon Sep 17 00:00:00 2001 From: bosnichd Date: Wed, 12 May 2021 08:30:15 -0600 Subject: [PATCH 149/225] Remove more unused things from CryCommon and CrySystem. (#709) Lots of unrelated removals, I basically tried to remove everything exposed via gEnv that isn't used anymore, and following the threads found a few other things to remove also. --- .../Engine/Config/engine_core.thread_config | 402 --- .../Config/engine_sandbox.thread_config | 128 - Code/CryEngine/CryCommon/CMakeLists.txt | 35 - Code/CryEngine/CryCommon/CryAssert_Android.h | 2 +- Code/CryEngine/CryCommon/CryAssert_Linux.h | 2 +- Code/CryEngine/CryCommon/CryAssert_Mac.h | 2 +- Code/CryEngine/CryCommon/CryAssert_iOS.h | 2 +- Code/CryEngine/CryCommon/CryAssert_impl.h | 2 +- Code/CryEngine/CryCommon/CrySystemBus.h | 6 - Code/CryEngine/CryCommon/CryThread.h | 3 - Code/CryEngine/CryCommon/CryThreadImpl.h | 19 - .../CryCommon/CryThreadImpl_windows.h | 2 - Code/CryEngine/CryCommon/CryThread_windows.h | 14 - .../CryCommon/EngineSettingsBackend.cpp | 34 - .../CryCommon/EngineSettingsBackend.h | 65 - .../CryCommon/EngineSettingsBackendApple.cpp | 486 --- .../CryCommon/EngineSettingsBackendApple.h | 51 - .../CryCommon/EngineSettingsBackendWin32.cpp | 431 --- .../CryCommon/EngineSettingsBackendWin32.h | 53 - .../CryCommon/EngineSettingsManager.cpp | 479 --- .../CryCommon/EngineSettingsManager.h | 89 - Code/CryEngine/CryCommon/IFlares.h | 228 -- Code/CryEngine/CryCommon/IMaterialEffects.h | 504 --- .../CryCommon/INotificationNetwork.h | 147 - Code/CryEngine/CryCommon/IRenderer.h | 28 +- .../CryCommon/IResourceCompilerHelper.cpp | 378 --- .../CryCommon/IResourceCompilerHelper.h | 167 - Code/CryEngine/CryCommon/IShader.h | 42 +- Code/CryEngine/CryCommon/ISoftCodeMgr.h | 276 -- Code/CryEngine/CryCommon/IStreamEngine.h | 1 - Code/CryEngine/CryCommon/ISystem.h | 327 +- Code/CryEngine/CryCommon/ISystemScheduler.h | 63 - Code/CryEngine/CryCommon/IThreadManager.h | 111 - Code/CryEngine/CryCommon/IThreadTask.h | 166 - .../CryEngine/CryCommon/Mocks/IRendererMock.h | 2 - Code/CryEngine/CryCommon/Mocks/ISystemMock.h | 44 - .../crycommon_enginesettings_mac_files.cmake | 15 - ...ycommon_enginesettings_windows_files.cmake | 15 - Code/CryEngine/CryCommon/ProfileLog.h | 70 - Code/CryEngine/CryCommon/ProjectDefines.h | 33 - .../CryCommon/ResourceCompilerHelper.cpp | 639 ---- .../CryCommon/ResourceCompilerHelper.h | 46 - .../CryCommon/SettingsManagerHelpers.cpp | 325 -- .../CryCommon/SettingsManagerHelpers.h | 491 --- .../crycommon_enginesettings_files.cmake | 27 - .../CryEngine/CryCommon/crycommon_files.cmake | 10 - Code/CryEngine/CryCommon/physinterface.h | 1 - Code/CryEngine/CryCommon/platform_impl.cpp | 3 +- Code/CryEngine/CrySystem/AutoDetectSpec.cpp | 4 +- Code/CryEngine/CrySystem/CMakeLists.txt | 2 - Code/CryEngine/CrySystem/ConsoleBatchFile.cpp | 17 - .../CrySystem/CrySystem_precompiled.h | 1 - .../CrySystem/CryThreadUtil_pthread.h | 259 -- .../CrySystem/CryThreadUtil_win32_thread.h | 432 --- Code/CryEngine/CrySystem/DebugCallStack.cpp | 926 ------ Code/CryEngine/CrySystem/DebugCallStack.h | 95 - Code/CryEngine/CrySystem/DllMain.cpp | 36 - Code/CryEngine/CrySystem/IDebugCallStack.cpp | 278 -- Code/CryEngine/CrySystem/IDebugCallStack.h | 90 - .../CrySystem/IThreadConfigManager.h | 59 - .../CrySystem/LevelSystem/LevelSystem.cpp | 17 - .../LevelSystem/SpawnableLevelSystem.cpp | 4 - Code/CryEngine/CrySystem/Log.cpp | 10 +- .../CrySystem/NotificationNetwork.cpp | 1345 -------- .../CryEngine/CrySystem/NotificationNetwork.h | 293 -- Code/CryEngine/CrySystem/ProfileLogSystem.cpp | 134 - Code/CryEngine/CrySystem/ProfileLogSystem.h | 74 - Code/CryEngine/CrySystem/ResourceManager.cpp | 11 +- .../CrySystem/SoftCode/SoftCodeMgr.cpp | 787 ----- .../CrySystem/SoftCode/SoftCodeMgr.h | 111 - Code/CryEngine/CrySystem/System.cpp | 562 ---- Code/CryEngine/CrySystem/System.h | 95 - Code/CryEngine/CrySystem/SystemInit.cpp | 164 +- Code/CryEngine/CrySystem/SystemRender.cpp | 48 - Code/CryEngine/CrySystem/SystemScheduler.cpp | 211 -- Code/CryEngine/CrySystem/SystemScheduler.h | 63 - Code/CryEngine/CrySystem/SystemThreading.cpp | 697 ---- Code/CryEngine/CrySystem/SystemWin32.cpp | 15 - .../CrySystem/ThreadConfigManager.cpp | 577 ---- .../CryEngine/CrySystem/ThreadConfigManager.h | 137 - Code/CryEngine/CrySystem/ThreadInfo.cpp | 123 - Code/CryEngine/CrySystem/ThreadInfo.h | 43 - Code/CryEngine/CrySystem/ThreadTask.cpp | 1046 ------ Code/CryEngine/CrySystem/ThreadTask.h | 181 - .../CrySystem/UnitTests/CryMathTests.cpp | 46 - .../CrySystem/UnitTests/CryPakUnitTests.cpp | 141 - Code/CryEngine/CrySystem/UnixConsole.cpp | 6 - Code/CryEngine/CrySystem/XConsole.cpp | 200 -- Code/CryEngine/CrySystem/XML/xml.cpp | 2 - .../CryEngine/CrySystem/crysystem_files.cmake | 21 - .../CrySystem/crysystem_test_files.cmake | 2 - .../AssetBrowser/AssetBrowserComponent.cpp | 2 - Code/LauncherUnified/Launcher.cpp | 5 - .../Editor/BackgroundScheduleManager.cpp | 629 ---- .../Editor/BackgroundScheduleManager.h | 117 - Code/Sandbox/Editor/BackgroundTaskManager.cpp | 410 --- Code/Sandbox/Editor/BackgroundTaskManager.h | 161 - Code/Sandbox/Editor/CMakeLists.txt | 1 - Code/Sandbox/Editor/CryEdit.cpp | 10 - Code/Sandbox/Editor/GameEngine.cpp | 21 - Code/Sandbox/Editor/IEditor.h | 2 - Code/Sandbox/Editor/IEditorImpl.cpp | 14 - Code/Sandbox/Editor/IEditorImpl.h | 17 - .../Include/IBackgroundScheduleManager.h | 207 -- .../Editor/Include/IBackgroundTaskManager.h | 230 -- Code/Sandbox/Editor/LevelInfo.cpp | 4 - Code/Sandbox/Editor/Lib/Tests/IEditorMock.h | 2 - Code/Sandbox/Editor/MainStatusBarItems.h | 1 - Code/Sandbox/Editor/MainWindow.cpp | 7 - Code/Sandbox/Editor/Objects/EntityObject.h | 1 - Code/Sandbox/Editor/UsedResources.cpp | 35 - Code/Sandbox/Editor/UsedResources.h | 2 - Code/Sandbox/Editor/editor_lib_files.cmake | 6 - .../SandboxIntegration.cpp | 25 - .../SandboxIntegration.h | 5 - .../CloudCanvasPythonWorkerInterface.h | 53 - .../MaglevControlPanelPlugin_stub.cpp | 31 - .../CryCommonTools/Export/AnimationData.cpp | 297 -- .../CryCommonTools/Export/AnimationData.h | 211 -- .../CryCommonTools/Export/CBAHelpers.cpp | 57 - Code/Tools/CryCommonTools/Export/CBAHelpers.h | 27 - .../Export/ColladaExportWriter.cpp | 556 ---- .../Export/ColladaExportWriter.h | 29 - .../CryCommonTools/Export/ColladaWriter.cpp | 2918 ----------------- .../CryCommonTools/Export/ColladaWriter.h | 32 - .../CryCommonTools/Export/ExportFileType.cpp | 66 - .../CryCommonTools/Export/ExportFileType.h | 42 - .../CryCommonTools/Export/ExportHelpers.h | 83 - .../Export/ExportSourceDecoratorBase.cpp | 130 - .../Export/ExportSourceDecoratorBase.h | 54 - .../Export/ExportStatusWindow.cpp | 215 -- .../Export/ExportStatusWindow.h | 67 - .../CryCommonTools/Export/GeometryData.cpp | 82 - .../CryCommonTools/Export/GeometryData.h | 102 - .../Export/GeometryExportSourceAdapter.cpp | 54 - .../Export/GeometryExportSourceAdapter.h | 36 - .../Export/GeometryFileData.cpp | 59 - .../CryCommonTools/Export/GeometryFileData.h | 52 - .../Export/GeometryMaterialData.cpp | 36 - .../Export/GeometryMaterialData.h | 35 - Code/Tools/CryCommonTools/Export/HelperData.h | 41 - .../CryCommonTools/Export/IAnimationData.h | 96 - .../CryCommonTools/Export/IExportContext.h | 55 - .../CryCommonTools/Export/IExportSource.h | 98 - .../CryCommonTools/Export/IExportWriter.h | 28 - .../CryCommonTools/Export/IGeometryData.h | 35 - .../CryCommonTools/Export/IGeometryFileData.h | 54 - .../Export/IGeometryMaterialData.h | 27 - .../CryCommonTools/Export/IMaterialData.h | 33 - Code/Tools/CryCommonTools/Export/IModelData.h | 36 - Code/Tools/CryCommonTools/Export/IMorphData.h | 29 - .../CryCommonTools/Export/ISkeletonData.h | 56 - .../CryCommonTools/Export/ISkinningData.h | 26 - .../CryCommonTools/Export/MaterialData.cpp | 69 - .../CryCommonTools/Export/MaterialData.h | 56 - .../CryCommonTools/Export/MaterialHelpers.cpp | 107 - .../CryCommonTools/Export/MaterialHelpers.h | 39 - Code/Tools/CryCommonTools/Export/MaxHelpers.h | 138 - .../Export/MaxUserPropertyHelpers.cpp | 99 - .../Export/MaxUserPropertyHelpers.h | 32 - Code/Tools/CryCommonTools/Export/MeshUtils.h | 914 ------ .../Tools/CryCommonTools/Export/ModelData.cpp | 118 - Code/Tools/CryCommonTools/Export/ModelData.h | 63 - .../Tools/CryCommonTools/Export/MorphData.cpp | 55 - Code/Tools/CryCommonTools/Export/MorphData.h | 52 - .../SingleAnimationExportSourceAdapter.cpp | 86 - .../SingleAnimationExportSourceAdapter.h | 45 - .../CryCommonTools/Export/SkeletonData.cpp | 309 -- .../CryCommonTools/Export/SkeletonData.h | 116 - .../CryCommonTools/Export/SkinningData.cpp | 45 - .../CryCommonTools/Export/SkinningData.h | 46 - .../CryCommonTools/Export/TransformHelpers.h | 119 - Code/Tools/CryCommonTools/UI/EULADialog.cpp | 132 - Code/Tools/CryCommonTools/UI/EULADialog.h | 55 - Code/Tools/CryCommonTools/UI/EditControl.cpp | 48 - Code/Tools/CryCommonTools/UI/EditControl.h | 36 - Code/Tools/CryCommonTools/UI/FrameWindow.cpp | 116 - Code/Tools/CryCommonTools/UI/FrameWindow.h | 44 - Code/Tools/CryCommonTools/UI/IUIComponent.h | 28 - Code/Tools/CryCommonTools/UI/Layout.cpp | 233 -- Code/Tools/CryCommonTools/UI/Layout.h | 61 - Code/Tools/CryCommonTools/UI/ListView.cpp | 96 - Code/Tools/CryCommonTools/UI/ListView.h | 42 - Code/Tools/CryCommonTools/UI/LogWindow.cpp | 158 - Code/Tools/CryCommonTools/UI/LogWindow.h | 71 - Code/Tools/CryCommonTools/UI/ProgressBar.cpp | 65 - Code/Tools/CryCommonTools/UI/ProgressBar.h | 39 - Code/Tools/CryCommonTools/UI/PushButton.cpp | 64 - Code/Tools/CryCommonTools/UI/PushButton.h | 78 - Code/Tools/CryCommonTools/UI/Spacer.cpp | 43 - Code/Tools/CryCommonTools/UI/Spacer.h | 40 - Code/Tools/CryCommonTools/UI/TaskList.cpp | 148 - Code/Tools/CryCommonTools/UI/TaskList.h | 48 - Code/Tools/CryCommonTools/UI/ToggleButton.cpp | 65 - Code/Tools/CryCommonTools/UI/ToggleButton.h | 78 - Code/Tools/CryCommonTools/UI/Win32GUI.cpp | 390 --- Code/Tools/CryCommonTools/UI/Win32GUI.h | 216 -- .../Code/Editor/PropertyHandlerSprite.cpp | 2 - 198 files changed, 29 insertions(+), 28558 deletions(-) delete mode 100644 Assets/Engine/Config/engine_core.thread_config delete mode 100644 Assets/Engine/Config/engine_sandbox.thread_config delete mode 100644 Code/CryEngine/CryCommon/EngineSettingsBackend.cpp delete mode 100644 Code/CryEngine/CryCommon/EngineSettingsBackend.h delete mode 100644 Code/CryEngine/CryCommon/EngineSettingsBackendApple.cpp delete mode 100644 Code/CryEngine/CryCommon/EngineSettingsBackendApple.h delete mode 100644 Code/CryEngine/CryCommon/EngineSettingsBackendWin32.cpp delete mode 100644 Code/CryEngine/CryCommon/EngineSettingsBackendWin32.h delete mode 100644 Code/CryEngine/CryCommon/EngineSettingsManager.cpp delete mode 100644 Code/CryEngine/CryCommon/EngineSettingsManager.h delete mode 100644 Code/CryEngine/CryCommon/IFlares.h delete mode 100644 Code/CryEngine/CryCommon/IMaterialEffects.h delete mode 100644 Code/CryEngine/CryCommon/INotificationNetwork.h delete mode 100644 Code/CryEngine/CryCommon/IResourceCompilerHelper.cpp delete mode 100644 Code/CryEngine/CryCommon/IResourceCompilerHelper.h delete mode 100644 Code/CryEngine/CryCommon/ISoftCodeMgr.h delete mode 100644 Code/CryEngine/CryCommon/ISystemScheduler.h delete mode 100644 Code/CryEngine/CryCommon/IThreadManager.h delete mode 100644 Code/CryEngine/CryCommon/IThreadTask.h delete mode 100644 Code/CryEngine/CryCommon/Platform/Mac/crycommon_enginesettings_mac_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Windows/crycommon_enginesettings_windows_files.cmake delete mode 100644 Code/CryEngine/CryCommon/ProfileLog.h delete mode 100644 Code/CryEngine/CryCommon/ResourceCompilerHelper.cpp delete mode 100644 Code/CryEngine/CryCommon/ResourceCompilerHelper.h delete mode 100644 Code/CryEngine/CryCommon/SettingsManagerHelpers.cpp delete mode 100644 Code/CryEngine/CryCommon/SettingsManagerHelpers.h delete mode 100644 Code/CryEngine/CryCommon/crycommon_enginesettings_files.cmake delete mode 100644 Code/CryEngine/CrySystem/CryThreadUtil_pthread.h delete mode 100644 Code/CryEngine/CrySystem/CryThreadUtil_win32_thread.h delete mode 100644 Code/CryEngine/CrySystem/DebugCallStack.cpp delete mode 100644 Code/CryEngine/CrySystem/DebugCallStack.h delete mode 100644 Code/CryEngine/CrySystem/IDebugCallStack.cpp delete mode 100644 Code/CryEngine/CrySystem/IDebugCallStack.h delete mode 100644 Code/CryEngine/CrySystem/IThreadConfigManager.h delete mode 100644 Code/CryEngine/CrySystem/NotificationNetwork.cpp delete mode 100644 Code/CryEngine/CrySystem/NotificationNetwork.h delete mode 100644 Code/CryEngine/CrySystem/ProfileLogSystem.cpp delete mode 100644 Code/CryEngine/CrySystem/ProfileLogSystem.h delete mode 100644 Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.cpp delete mode 100644 Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.h delete mode 100644 Code/CryEngine/CrySystem/SystemScheduler.cpp delete mode 100644 Code/CryEngine/CrySystem/SystemScheduler.h delete mode 100644 Code/CryEngine/CrySystem/SystemThreading.cpp delete mode 100644 Code/CryEngine/CrySystem/ThreadConfigManager.cpp delete mode 100644 Code/CryEngine/CrySystem/ThreadConfigManager.h delete mode 100644 Code/CryEngine/CrySystem/ThreadInfo.cpp delete mode 100644 Code/CryEngine/CrySystem/ThreadInfo.h delete mode 100644 Code/CryEngine/CrySystem/ThreadTask.cpp delete mode 100644 Code/CryEngine/CrySystem/ThreadTask.h delete mode 100644 Code/CryEngine/CrySystem/UnitTests/CryMathTests.cpp delete mode 100644 Code/CryEngine/CrySystem/UnitTests/CryPakUnitTests.cpp delete mode 100644 Code/Sandbox/Editor/BackgroundScheduleManager.cpp delete mode 100644 Code/Sandbox/Editor/BackgroundScheduleManager.h delete mode 100644 Code/Sandbox/Editor/BackgroundTaskManager.cpp delete mode 100644 Code/Sandbox/Editor/BackgroundTaskManager.h delete mode 100644 Code/Sandbox/Editor/Include/IBackgroundScheduleManager.h delete mode 100644 Code/Sandbox/Editor/Include/IBackgroundTaskManager.h delete mode 100644 Code/Sandbox/Plugins/MaglevControlPanel/CloudCanvasPythonWorkerInterface.h delete mode 100644 Code/Sandbox/Plugins/MaglevControlPanel/MaglevControlPanelPlugin_stub.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/AnimationData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/AnimationData.h delete mode 100644 Code/Tools/CryCommonTools/Export/CBAHelpers.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/CBAHelpers.h delete mode 100644 Code/Tools/CryCommonTools/Export/ColladaExportWriter.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/ColladaExportWriter.h delete mode 100644 Code/Tools/CryCommonTools/Export/ColladaWriter.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/ColladaWriter.h delete mode 100644 Code/Tools/CryCommonTools/Export/ExportFileType.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/ExportFileType.h delete mode 100644 Code/Tools/CryCommonTools/Export/ExportHelpers.h delete mode 100644 Code/Tools/CryCommonTools/Export/ExportSourceDecoratorBase.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/ExportSourceDecoratorBase.h delete mode 100644 Code/Tools/CryCommonTools/Export/ExportStatusWindow.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/ExportStatusWindow.h delete mode 100644 Code/Tools/CryCommonTools/Export/GeometryData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/GeometryData.h delete mode 100644 Code/Tools/CryCommonTools/Export/GeometryExportSourceAdapter.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/GeometryExportSourceAdapter.h delete mode 100644 Code/Tools/CryCommonTools/Export/GeometryFileData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/GeometryFileData.h delete mode 100644 Code/Tools/CryCommonTools/Export/GeometryMaterialData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/GeometryMaterialData.h delete mode 100644 Code/Tools/CryCommonTools/Export/HelperData.h delete mode 100644 Code/Tools/CryCommonTools/Export/IAnimationData.h delete mode 100644 Code/Tools/CryCommonTools/Export/IExportContext.h delete mode 100644 Code/Tools/CryCommonTools/Export/IExportSource.h delete mode 100644 Code/Tools/CryCommonTools/Export/IExportWriter.h delete mode 100644 Code/Tools/CryCommonTools/Export/IGeometryData.h delete mode 100644 Code/Tools/CryCommonTools/Export/IGeometryFileData.h delete mode 100644 Code/Tools/CryCommonTools/Export/IGeometryMaterialData.h delete mode 100644 Code/Tools/CryCommonTools/Export/IMaterialData.h delete mode 100644 Code/Tools/CryCommonTools/Export/IModelData.h delete mode 100644 Code/Tools/CryCommonTools/Export/IMorphData.h delete mode 100644 Code/Tools/CryCommonTools/Export/ISkeletonData.h delete mode 100644 Code/Tools/CryCommonTools/Export/ISkinningData.h delete mode 100644 Code/Tools/CryCommonTools/Export/MaterialData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/MaterialData.h delete mode 100644 Code/Tools/CryCommonTools/Export/MaterialHelpers.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/MaterialHelpers.h delete mode 100644 Code/Tools/CryCommonTools/Export/MaxHelpers.h delete mode 100644 Code/Tools/CryCommonTools/Export/MaxUserPropertyHelpers.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/MaxUserPropertyHelpers.h delete mode 100644 Code/Tools/CryCommonTools/Export/MeshUtils.h delete mode 100644 Code/Tools/CryCommonTools/Export/ModelData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/ModelData.h delete mode 100644 Code/Tools/CryCommonTools/Export/MorphData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/MorphData.h delete mode 100644 Code/Tools/CryCommonTools/Export/SingleAnimationExportSourceAdapter.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/SingleAnimationExportSourceAdapter.h delete mode 100644 Code/Tools/CryCommonTools/Export/SkeletonData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/SkeletonData.h delete mode 100644 Code/Tools/CryCommonTools/Export/SkinningData.cpp delete mode 100644 Code/Tools/CryCommonTools/Export/SkinningData.h delete mode 100644 Code/Tools/CryCommonTools/Export/TransformHelpers.h delete mode 100644 Code/Tools/CryCommonTools/UI/EULADialog.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/EULADialog.h delete mode 100644 Code/Tools/CryCommonTools/UI/EditControl.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/EditControl.h delete mode 100644 Code/Tools/CryCommonTools/UI/FrameWindow.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/FrameWindow.h delete mode 100644 Code/Tools/CryCommonTools/UI/IUIComponent.h delete mode 100644 Code/Tools/CryCommonTools/UI/Layout.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/Layout.h delete mode 100644 Code/Tools/CryCommonTools/UI/ListView.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/ListView.h delete mode 100644 Code/Tools/CryCommonTools/UI/LogWindow.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/LogWindow.h delete mode 100644 Code/Tools/CryCommonTools/UI/ProgressBar.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/ProgressBar.h delete mode 100644 Code/Tools/CryCommonTools/UI/PushButton.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/PushButton.h delete mode 100644 Code/Tools/CryCommonTools/UI/Spacer.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/Spacer.h delete mode 100644 Code/Tools/CryCommonTools/UI/TaskList.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/TaskList.h delete mode 100644 Code/Tools/CryCommonTools/UI/ToggleButton.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/ToggleButton.h delete mode 100644 Code/Tools/CryCommonTools/UI/Win32GUI.cpp delete mode 100644 Code/Tools/CryCommonTools/UI/Win32GUI.h diff --git a/Assets/Engine/Config/engine_core.thread_config b/Assets/Engine/Config/engine_core.thread_config deleted file mode 100644 index f9183d9174..0000000000 --- a/Assets/Engine/Config/engine_core.thread_config +++ /dev/null @@ -1,402 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Assets/Engine/Config/engine_sandbox.thread_config b/Assets/Engine/Config/engine_sandbox.thread_config deleted file mode 100644 index 7c0dc00b71..0000000000 --- a/Assets/Engine/Config/engine_sandbox.thread_config +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Code/CryEngine/CryCommon/CMakeLists.txt b/Code/CryEngine/CryCommon/CMakeLists.txt index 4725489358..5105ff1a5b 100644 --- a/Code/CryEngine/CryCommon/CMakeLists.txt +++ b/Code/CryEngine/CryCommon/CMakeLists.txt @@ -32,41 +32,6 @@ ly_add_target( AZ::AzFramework ) -ly_add_target( - NAME CryCommon.EngineSettings.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - crycommon_enginesettings_files.cmake - ${pal_dir}/crycommon_enginesettings_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - ${pal_dir} - BUILD_DEPENDENCIES - PUBLIC - AZ::AzCore - AZ::AzFramework -) - -ly_add_target( - NAME CryCommon.EngineSettings.RC.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - crycommon_enginesettings_files.cmake - ${pal_dir}/crycommon_enginesettings_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - ${pal_dir} - COMPILE_DEFINITIONS - PRIVATE - RESOURCE_COMPILER - BUILD_DEPENDENCIES - PUBLIC - AZ::AzCore - AZ::AzFramework -) - if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_add_target( diff --git a/Code/CryEngine/CryCommon/CryAssert_Android.h b/Code/CryEngine/CryCommon/CryAssert_Android.h index 68f716ec28..6e60df1bb1 100644 --- a/Code/CryEngine/CryCommon/CryAssert_Android.h +++ b/Code/CryEngine/CryCommon/CryAssert_Android.h @@ -31,7 +31,7 @@ void CryAssertTrace(const char* szFormat, ...) return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (szFormat == NULL) { diff --git a/Code/CryEngine/CryCommon/CryAssert_Linux.h b/Code/CryEngine/CryCommon/CryAssert_Linux.h index 7c52f78366..f0acdd79db 100644 --- a/Code/CryEngine/CryCommon/CryAssert_Linux.h +++ b/Code/CryEngine/CryCommon/CryAssert_Linux.h @@ -34,7 +34,7 @@ void CryAssertTrace(const char* szFormat, ...) return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (szFormat == NULL) { diff --git a/Code/CryEngine/CryCommon/CryAssert_Mac.h b/Code/CryEngine/CryCommon/CryAssert_Mac.h index 9502605fea..f7f74c3b58 100644 --- a/Code/CryEngine/CryCommon/CryAssert_Mac.h +++ b/Code/CryEngine/CryCommon/CryAssert_Mac.h @@ -30,7 +30,7 @@ void CryAssertTrace(const char* szFormat, ...) return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (szFormat == NULL) { diff --git a/Code/CryEngine/CryCommon/CryAssert_iOS.h b/Code/CryEngine/CryCommon/CryAssert_iOS.h index ad668fb131..2cb08befff 100644 --- a/Code/CryEngine/CryCommon/CryAssert_iOS.h +++ b/Code/CryEngine/CryCommon/CryAssert_iOS.h @@ -31,7 +31,7 @@ void CryAssertTrace(const char* szFormat, ...) return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (szFormat == NULL) { diff --git a/Code/CryEngine/CryCommon/CryAssert_impl.h b/Code/CryEngine/CryCommon/CryAssert_impl.h index ed55162f1a..edbbb2f0c4 100644 --- a/Code/CryEngine/CryCommon/CryAssert_impl.h +++ b/Code/CryEngine/CryCommon/CryAssert_impl.h @@ -305,7 +305,7 @@ void CryAssertTrace(const char* _pszFormat, ...) { return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (NULL == _pszFormat) { diff --git a/Code/CryEngine/CryCommon/CrySystemBus.h b/Code/CryEngine/CryCommon/CrySystemBus.h index f183de0fa9..def1ce4688 100644 --- a/Code/CryEngine/CryCommon/CrySystemBus.h +++ b/Code/CryEngine/CryCommon/CrySystemBus.h @@ -49,12 +49,6 @@ public: //! ISystem has shut down. virtual void OnCrySystemPostShutdown() {} - //! Engine pre physics update. - virtual void OnCrySystemPrePhysicsUpdate() {} - - //! Engine post physics update. - virtual void OnCrySystemPostPhysicsUpdate() {} - //! Sent when a new level is being created. virtual void OnCryEditorBeginCreate() {} diff --git a/Code/CryEngine/CryCommon/CryThread.h b/Code/CryEngine/CryCommon/CryThread.h index f1e97b2199..9aa7bce128 100644 --- a/Code/CryEngine/CryCommon/CryThread.h +++ b/Code/CryEngine/CryCommon/CryThread.h @@ -37,9 +37,6 @@ enum CryLockType #define CRYLOCK_HAVE_FASTLOCK 1 -void CryThreadSetName(threadID nThreadId, const char* sThreadName); -const char* CryThreadGetName(threadID nThreadId); - ///////////////////////////////////////////////////////////////////////////// // // Primitive locks and conditions. diff --git a/Code/CryEngine/CryCommon/CryThreadImpl.h b/Code/CryEngine/CryCommon/CryThreadImpl.h index b151b3da8a..da9be86dd5 100644 --- a/Code/CryEngine/CryCommon/CryThreadImpl.h +++ b/Code/CryEngine/CryCommon/CryThreadImpl.h @@ -31,22 +31,3 @@ #else // Put other platform specific includes here! #endif - -#include - -void CryThreadSetName(threadID dwThreadId, const char* sThreadName) -{ - if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIThreadTaskManager()) - { - gEnv->pSystem->GetIThreadTaskManager()->SetThreadName(dwThreadId, sThreadName); - } -} - -const char* CryThreadGetName(threadID dwThreadId) -{ - if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIThreadTaskManager()) - { - return gEnv->pSystem->GetIThreadTaskManager()->GetThreadName(dwThreadId); - } - return ""; -} diff --git a/Code/CryEngine/CryCommon/CryThreadImpl_windows.h b/Code/CryEngine/CryCommon/CryThreadImpl_windows.h index 6f37edeea1..3ff28a81be 100644 --- a/Code/CryEngine/CryCommon/CryThreadImpl_windows.h +++ b/Code/CryEngine/CryCommon/CryThreadImpl_windows.h @@ -13,8 +13,6 @@ #pragma once -//#include - #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif diff --git a/Code/CryEngine/CryCommon/CryThread_windows.h b/Code/CryEngine/CryCommon/CryThread_windows.h index 1d9ea6dc31..b70260c7ac 100644 --- a/Code/CryEngine/CryCommon/CryThread_windows.h +++ b/Code/CryEngine/CryCommon/CryThread_windows.h @@ -249,10 +249,6 @@ public: void SetName(const char* Name) { m_name = Name; - if (m_threadId) - { - CryThreadSetName(m_threadId, m_name); - } } const char* GetName() { return m_name; } @@ -289,11 +285,6 @@ private: self->m_bIsStarted = true; self->m_bIsRunning = true; - if (!self->m_name.empty()) - { - CryThreadSetName(-1, self->m_name); - } - self->m_Runnable->Run(); self->m_bIsRunning = false; self->m_bCreatedThread = false; @@ -311,11 +302,6 @@ private: self->m_bIsStarted = true; self->m_bIsRunning = true; - if (!self->m_name.empty()) - { - CryThreadSetName(-1, self->m_name); - } - self->Run(); self->m_bIsRunning = false; self->m_bCreatedThread = false; diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackend.cpp b/Code/CryEngine/CryCommon/EngineSettingsBackend.cpp deleted file mode 100644 index caf7e03f31..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackend.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ - - -#include "EngineSettingsBackend.h" - -#ifdef CRY_ENABLE_RC_HELPER - -CEngineSettingsBackend::CEngineSettingsBackend(CEngineSettingsManager* parent, const wchar_t* moduleName) - : m_parent(parent) - , m_moduleName() -{ - if (moduleName != nullptr) - { - m_moduleName = moduleName; - } -} - -CEngineSettingsBackend::~CEngineSettingsBackend() -{ - -} - -#endif // CRY_ENABLE_RC_HELPER - diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackend.h b/Code/CryEngine/CryCommon/EngineSettingsBackend.h deleted file mode 100644 index fce16517ec..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackend.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ -#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H -#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H -#pragma once - -#include "ProjectDefines.h" - -#ifdef CRY_ENABLE_RC_HELPER - -#include "SettingsManagerHelpers.h" - -#include - -class CEngineSettingsManager; - -class CEngineSettingsBackend -{ -public: - CEngineSettingsBackend(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL); - virtual ~CEngineSettingsBackend(); - - virtual std::wstring GetModuleFilePath() const = 0; - - virtual bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) = 0; - virtual bool GetModuleSpecificIntEntry(const char* key, int& value) = 0; - virtual bool GetModuleSpecificBoolEntry(const char* key, bool& value) = 0; - - virtual bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) = 0; - virtual bool SetModuleSpecificIntEntry(const char* key, const int& value) = 0; - virtual bool SetModuleSpecificBoolEntry(const char* key, const bool& value) = 0; - - virtual bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) = 0; - - virtual void LoadEngineSettingsFromRegistry() = 0; - virtual bool StoreEngineSettingsToRegistry() = 0; - -protected: - CEngineSettingsManager* parent() const - { - return m_parent; - } - - const std::wstring& moduleName() const - { - return m_moduleName; - } - -private: - std::wstring m_moduleName; - CEngineSettingsManager* m_parent; -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackendApple.cpp b/Code/CryEngine/CryCommon/EngineSettingsBackendApple.cpp deleted file mode 100644 index 06f8d532d3..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackendApple.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ - -#include "EngineSettingsBackendApple.h" - -#ifdef CRY_ENABLE_RC_HELPER - -#include "AzCore/PlatformDef.h" - -#if AZ_TRAIT_OS_PLATFORM_APPLE - -#include "EngineSettingsManager.h" -#include "SettingsManagerHelpers.h" - -#include "platform.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace SettingsManagerHelpers; - -static const char gDefaultRegistryLocation[] = "/EngineSettings.reg"; - -#define REG_SOFTWARE L"Software\\" -#define REG_COMPANY_NAME L"Amazon\\" -#define REG_PRODUCT_NAME L"Lumberyard\\" -#define REG_SETTING L"Settings\\" -#define REG_BASE_SETTING_KEY REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME REG_SETTING - -////////////////////////////////////////////////////////////////////////// -class SimpleRegistry -{ - typedef std::map< std::wstring, std::wstring > WStringMap; - std::map< std::wstring, WStringMap * > m_modules; - -public: - SimpleRegistry(); - ~SimpleRegistry(); - - void setBoolValue(const std::wstring& module, const std::wstring& key, bool value); - void setIntValue(const std::wstring& module, const std::wstring& key, int value); - void setStrValue(const std::wstring& module, const std::wstring& key, const std::wstring& value); - - bool getBoolValue(const std::wstring& module, const std::wstring& key, bool& value); - bool getIntValue(const std::wstring& module, const std::wstring& key, int& value); - bool getStrValue(const std::wstring& module, const std::wstring& key, std::wstring& value); - - bool loadFromFile(const char* fileName); - bool saveToFile(const char* fileName); - -protected: - void clear(); - -private: - static const wchar_t gSimpleMagic[]; - static const size_t gMetaCharCount; -}; - -const wchar_t SimpleRegistry::gSimpleMagic[] = L"FR0"; -const size_t SimpleRegistry::gMetaCharCount = sizeof(size_t) / sizeof(wchar_t); - -SimpleRegistry::SimpleRegistry() -{ -} - -SimpleRegistry::~SimpleRegistry() -{ - clear(); -} - -void SimpleRegistry::setBoolValue(const std::wstring& module, const std::wstring& key, bool value) -{ - return setStrValue(module, key, value ? L"true" : L"false"); -} - -void SimpleRegistry::setIntValue(const std::wstring& module, const std::wstring& key, int value) -{ - return setStrValue(module, key, std::to_wstring(value)); -} - -void SimpleRegistry::setStrValue(const std::wstring& module, const std::wstring& key, const std::wstring& value) -{ - WStringMap *map = nullptr; - - auto i = m_modules.find(module); - - if (i == m_modules.end()) - { - map = new WStringMap; - m_modules.emplace(module, map); - } - else - { - map = i->second; - } - - assert(map); - - (*map)[key] = value; -} - -bool SimpleRegistry::getBoolValue(const std::wstring& module, const std::wstring& key, bool& value) -{ - std::wstring str; - - if (!getStrValue(module, key, str)) - { - return false; - } - - value = (0 == str.compare(L"true")); - - return true; -} - -bool SimpleRegistry::getIntValue(const std::wstring& module, const std::wstring& key, int& value) -{ - std::wstring str; - - if (!getStrValue(module, key, str)) - { - return false; - } - - value = std::stoi(str); - - return true; -} - -bool SimpleRegistry::getStrValue(const std::wstring& module, const std::wstring& key, std::wstring& value) -{ - WStringMap *map = nullptr; - - auto mi = m_modules.find(module); - if (mi == m_modules.end()) - { - return false; - } - - map = mi->second; - assert(map); - - auto ki = map->find(key); - if (ki == map->end()) - { - return false; - } - - value = ki->second; - - return true; -} - -bool SimpleRegistry::loadFromFile(const char* fileName) -{ - clear(); - - std::wifstream file(fileName, std::ios_base::in|std::ios_base::binary); - file.imbue(std::locale(file.getloc(), new std::codecvt_utf16)); - if (!file.is_open()) - { - AZ_Warning("EngineSettings", false, "Failed to open registry settings file: %s", fileName); - return false; - } - - std::wstring module; - std::wstring key; - std::wstring value; - - wchar_t buffer[512]; - size_t size; - wchar_t meta[gMetaCharCount]; - - /* magic number */ - if(!file.read(buffer, sizeof(gSimpleMagic) / sizeof(wchar_t)) || - wcsncmp(gSimpleMagic, buffer, sizeof(gSimpleMagic) / sizeof(wchar_t)) != 0) - { - file.close(); - AZ_Warning("EngineSettings", false, "Failed to load registry settings from file: %s", fileName); - return false; - } - - while (file.good()) - { - file.read(meta, gMetaCharCount); - if (!file.good()) - { - break; - } - - memcpy(&size, meta, sizeof(size)); - file.read(buffer, size); - buffer[file.gcount()] = L'\0'; - module = buffer; - - file.read(meta, gMetaCharCount); - memcpy(&size, meta, sizeof(size)); - file.read(buffer, size); - buffer[file.gcount()] = L'\0'; - key = buffer; - - file.read(meta, gMetaCharCount); - memcpy(&size, meta, sizeof(size)); - file.read(buffer, size); - buffer[file.gcount()] = L'\0'; - value = buffer; - - setStrValue(module, key, value); - } - - file.close(); - - return true; -} - -bool SimpleRegistry::saveToFile(const char* fileName) -{ - std::wofstream file(fileName, std::ios_base::out|std::ios_base::trunc|std::ios_base::binary); - file.imbue(std::locale(file.getloc(), new std::codecvt_utf16)); - if (!file.is_open()) - { - return false; - } - - std::wstring module; - - size_t size; - wchar_t meta[gMetaCharCount]; - - /* magic number */ - file.write(gSimpleMagic, sizeof(gSimpleMagic) / sizeof(wchar_t)); - - for (auto j : m_modules) - { - module = j.first; - - for (auto i : *j.second) - { - size = module.size(); - memcpy(meta, &size, sizeof(meta)); - file.write(meta, gMetaCharCount); - file.write(module.c_str(), size); - - size = i.first.size(); - memcpy(meta, &size, sizeof(meta)); - file.write(meta, gMetaCharCount); - file.write(i.first.c_str(), size); - - size = i.second.size(); - memcpy(meta, &size, sizeof(meta)); - file.write(meta, gMetaCharCount); - file.write(i.second.c_str(), size); - } - } - - file.close(); - - return true; -} - -void SimpleRegistry::clear() -{ - for (auto pair : m_modules) - { - delete pair.second; - } - - m_modules.clear(); -} -////////////////////////////////////////////////////////////////////////// - -CEngineSettingsBackendApple::CEngineSettingsBackendApple(CEngineSettingsManager* parent, const wchar_t* moduleName) - : CEngineSettingsBackend(parent, moduleName) - , m_registry(new SimpleRegistry) - , m_registryFilePath() -{ - std::string rootValue = gEnv->pFileIO->GetAlias("@root@"); - if (rootValue.empty()) - { - AZ_Warning("EngineSettings", false, "Could not get engine root."); - return; - } - - rootValue.append(gDefaultRegistryLocation); - m_registryFilePath = rootValue; -} - -CEngineSettingsBackendApple::~CEngineSettingsBackendApple() -{ - delete m_registry, m_registry = nullptr; -} - -std::wstring CEngineSettingsBackendApple::GetModuleFilePath() const -{ - std::string path; - - std::wstring_convert> converter; - std::string module = converter.to_bytes(moduleName()); - - void* handle = ::dlopen(module.c_str(), RTLD_LAZY); - if (handle) - { - const int c = _dyld_image_count(); - for (int i = 0; i < c; ++i) - { - const char* image = _dyld_get_image_name(i); - const void* altHandle = dlopen(image, RTLD_LAZY); - if (handle == altHandle) - { - char absImage[PATH_MAX]; - realpath(image, absImage); - char *ext = rindex(absImage, '.'); - if (ext) - { - *ext = '\0'; - } - path.append(absImage); - path.append(".ini"); - break; - } - } - } - - return converter.from_bytes(path); -} - -bool CEngineSettingsBackendApple::GetModuleSpecificStringEntryUtf16(const char* key, CWCharBuffer wbuffer) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - std::wstring str; - if (!m_registry->getStrValue(moduleName(), wkey, str)) - { - return false; - } - - std::wcscpy(wbuffer.getPtr(), str.c_str()); - - return true; -} - -bool CEngineSettingsBackendApple::GetModuleSpecificIntEntry(const char* key, int& value) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - return m_registry->getIntValue(moduleName(), wkey, value); -} - -bool CEngineSettingsBackendApple::GetModuleSpecificBoolEntry(const char* key, bool& value) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - return m_registry->getBoolValue(moduleName(), wkey, value); -} - -bool CEngineSettingsBackendApple::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - m_registry->setStrValue(moduleName(), wkey, str); - - return true; -} - -bool CEngineSettingsBackendApple::SetModuleSpecificIntEntry(const char* key, const int& value) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - m_registry->setIntValue(moduleName(), wkey, value); - - return true; -} - -bool CEngineSettingsBackendApple::SetModuleSpecificBoolEntry(const char* key, const bool& value) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - m_registry->setBoolValue(moduleName(), wkey, value); - - return true; -} - -bool CEngineSettingsBackendApple::GetInstalledBuildRootPathUtf16(const int index, CWCharBuffer name, CWCharBuffer path) -{ - return false; -} - -bool CEngineSettingsBackendApple::StoreEngineSettingsToRegistry() -{ - bool bRet = true; - wchar_t buffer[1024]; - - // ResourceCompiler Specific - if (parent()->GetValueByRef("RC_ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_ShowWindow", b); - } - - if (parent()->GetValueByRef("RC_HideCustom", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_HideCustom", b); - } - - if (parent()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - m_registry->setStrValue(REG_BASE_SETTING_KEY, L"RC_Parameters", buffer); - } - - if (parent()->GetValueByRef("RC_EnableSourceControl", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_EnableSourceControl", b); - } - - bRet &= m_registry->saveToFile(m_registryFilePath.c_str()); - return bRet; -} - -void CEngineSettingsBackendApple::LoadEngineSettingsFromRegistry() -{ - if (!m_registry->loadFromFile(m_registryFilePath.c_str())) - { - return; - } - - std::wstring wStrResult; - bool bResult; - - if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"RootPath", wStrResult)) - { - parent()->SetKey("ENG_RootPath", wStrResult.c_str()); - } - - // Engine Specific - if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"ENG_RootPath", wStrResult)) - { - parent()->SetKey("ENG_RootPath", wStrResult.c_str()); - } - - // ResourceCompiler Specific - if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_ShowWindow", bResult)) - { - parent()->SetKey("RC_ShowWindow", bResult); - } - if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_HideCustom", bResult)) - { - parent()->SetKey("RC_HideCustom", bResult); - } - if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"RC_Parameters", wStrResult)) - { - parent()->SetKey("RC_Parameters", wStrResult.c_str()); - } - if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_EnableSourceControl", bResult)) - { - parent()->SetKey("RC_EnableSourceControl", bResult); - } -} - -#endif // AZ_TRAIT_OS_PLATFORM_APPLE -#endif // CRY_ENABLE_RC_HELPER - diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackendApple.h b/Code/CryEngine/CryCommon/EngineSettingsBackendApple.h deleted file mode 100644 index efc5a12bed..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackendApple.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ -#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H -#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H -#pragma once - -#include "EngineSettingsBackend.h" - -#ifdef CRY_ENABLE_RC_HELPER - -class CEngineSettingsManager; -class SimpleRegistry; - -class CEngineSettingsBackendApple : public CEngineSettingsBackend -{ -public: - CEngineSettingsBackendApple(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL); - ~CEngineSettingsBackendApple(); - - std::wstring GetModuleFilePath() const override; - - bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) override; - bool GetModuleSpecificIntEntry(const char* key, int& value) override; - bool GetModuleSpecificBoolEntry(const char* key, bool& value) override; - - bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) override; - bool SetModuleSpecificIntEntry(const char* key, const int& value) override; - bool SetModuleSpecificBoolEntry(const char* key, const bool& value) override; - - bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) override; - - void LoadEngineSettingsFromRegistry() override; - bool StoreEngineSettingsToRegistry() override; - -private: - SimpleRegistry *m_registry; - std::string m_registryFilePath; -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.cpp b/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.cpp deleted file mode 100644 index c2e9a67d57..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ - - -#include "EngineSettingsBackendWin32.h" - -#ifdef CRY_ENABLE_RC_HELPER - -#include "AzCore/PlatformDef.h" - -#ifdef AZ_PLATFORM_WINDOWS - -#include "EngineSettingsManager.h" - -#include "platform.h" -#include - -#define REG_SOFTWARE L"Software\\" -#define REG_COMPANY_NAME L"Amazon\\" -#define REG_PRODUCT_NAME L"Open 3D Engine\\" -#define REG_SETTING L"Settings\\" -#define REG_BASE_SETTING_KEY REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME REG_SETTING - -EXTERN_C IMAGE_DOS_HEADER __ImageBase; - -using namespace SettingsManagerHelpers; - -static bool g_bWindowQuit; -static CEngineSettingsManager* g_pThis = 0; -static const unsigned int IDC_hEditRootPath = 100; -static const unsigned int IDC_hBtnBrowse = 101; - -namespace -{ - class RegKey - { - public: - RegKey(const wchar_t* key, bool writeable); - ~RegKey(); - void* pKey; - }; - - RegKey::RegKey(const wchar_t* key, bool writeable) - { - HKEY hKey; - LONG result; - if (writeable) - { - result = RegCreateKeyExW(HKEY_CURRENT_USER, key, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); - } - else - { - result = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey); - } - pKey = hKey; - } - - RegKey::~RegKey() - { - RegCloseKey((HKEY)pKey); - } -} - -CEngineSettingsBackendWin32::CEngineSettingsBackendWin32(CEngineSettingsManager* parent, const wchar_t* moduleName) - : CEngineSettingsBackend(parent, moduleName) -{ -} - -std::wstring CEngineSettingsBackendWin32::GetModuleFilePath() const -{ - wchar_t szFilename[_MAX_PATH]; - GetModuleFileNameW((HINSTANCE)&__ImageBase, szFilename, _MAX_PATH); - wchar_t drive[_MAX_DRIVE]; - wchar_t dir[_MAX_DIR]; - wchar_t fname[_MAX_FNAME]; - wchar_t ext[1] = L""; - _wsplitpath_s(szFilename, drive, dir, fname, ext); - _wmakepath_s(szFilename, drive, dir, fname, L"ini"); - return szFilename; -} - -bool CEngineSettingsBackendWin32::GetModuleSpecificStringEntryUtf16(const char* key, CWCharBuffer wbuffer) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), false); - if (!superKey.pKey) - { - wbuffer[0] = 0; - return false; - } - if (!GetRegValue(superKey.pKey, key, wbuffer)) - { - wbuffer[0] = 0; - return false; - } - - return true; -} - -bool CEngineSettingsBackendWin32::GetModuleSpecificIntEntry(const char* key, int& value) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), false); - if (!superKey.pKey) - { - return false; - } - if (!GetRegValue(superKey.pKey, key, value)) - { - value = 0; - return false; - } - - return true; -} - -bool CEngineSettingsBackendWin32::GetModuleSpecificBoolEntry(const char* key, bool& value) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), false); - if (!superKey.pKey) - { - return false; - } - if (!GetRegValue(superKey.pKey, key, value)) - { - value = false; - return false; - } - - return true; -} - -bool CEngineSettingsBackendWin32::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), true); - if (superKey.pKey) - { - return SetRegValue(superKey.pKey, key, str); - } - return false; -} - -bool CEngineSettingsBackendWin32::SetModuleSpecificIntEntry(const char* key, const int& value) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), true); - if (superKey.pKey) - { - return SetRegValue(superKey.pKey, key, value); - } - return false; -} - -bool CEngineSettingsBackendWin32::SetModuleSpecificBoolEntry(const char* key, const bool& value) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), true); - if (superKey.pKey) - { - return SetRegValue(superKey.pKey, key, value); - } - return false; -} - -bool CEngineSettingsBackendWin32::GetInstalledBuildRootPathUtf16(const int index, CWCharBuffer name, CWCharBuffer path) -{ - RegKey key(REG_BASE_SETTING_KEY L"O3DEExport\\ProjectBuilds", false); - if (key.pKey) - { - DWORD type; - DWORD nameSizeInBytes = DWORD(name.getSizeInBytes()); - DWORD pathSizeInBytes = DWORD(path.getSizeInBytes()); - LONG result = RegEnumValueW((HKEY)key.pKey, index, name.getPtr(), &nameSizeInBytes, NULL, &type, (BYTE*)path.getPtr(), &pathSizeInBytes); - if (result == ERROR_SUCCESS) - { - return true; - } - } - return false; -} - -bool CEngineSettingsBackendWin32::StoreEngineSettingsToRegistry() -{ - // make sure the path in registry exists - { - RegKey key0(REG_SOFTWARE REG_COMPANY_NAME, true); - if (!key0.pKey) - { - RegKey software(REG_SOFTWARE, true); - HKEY hKey; - RegCreateKeyW((HKEY)software.pKey, REG_COMPANY_NAME, &hKey); - if (!hKey) - { - return false; - } - } - - RegKey key1(REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME, true); - if (!key1.pKey) - { - RegKey softwareCompany(REG_SOFTWARE REG_COMPANY_NAME, true); - HKEY hKey; - RegCreateKeyW((HKEY)softwareCompany.pKey, REG_COMPANY_NAME, &hKey); - if (!hKey) - { - return false; - } - } - - RegKey key2(REG_BASE_SETTING_KEY, true); - if (!key2.pKey) - { - RegKey softwareCompanyProduct(REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME, true); - HKEY hKey; - RegCreateKeyW((HKEY)key2.pKey, REG_SETTING, &hKey); - if (!hKey) - { - return false; - } - } - } - - bool bRet = true; - - RegKey key(REG_BASE_SETTING_KEY, true); - if (!key.pKey) - { - bRet = false; - } - else - { - wchar_t buffer[1024]; - - // ResourceCompiler Specific - - if (parent()->GetValueByRef("RC_ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - SetRegValue(key.pKey, "RC_ShowWindow", b); - } - - if (parent()->GetValueByRef("RC_HideCustom", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - SetRegValue(key.pKey, "RC_HideCustom", b); - } - - if (parent()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - SetRegValue(key.pKey, "RC_Parameters", buffer); - } - - if (parent()->GetValueByRef("RC_EnableSourceControl", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - SetRegValue(key.pKey, "RC_EnableSourceControl", b); - } - } - - return bRet; -} - -void CEngineSettingsBackendWin32::LoadEngineSettingsFromRegistry() -{ - wchar_t buffer[1024]; - - bool bResult; - - // Engine Specific (Deprecated value) - RegKey key(REG_BASE_SETTING_KEY, false); - if (key.pKey) - { - if (GetRegValue(key.pKey, "RootPath", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - parent()->SetKey("ENG_RootPath", buffer); - } - - // Engine Specific - if (GetRegValue(key.pKey, "ENG_RootPath", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - parent()->SetKey("ENG_RootPath", buffer); - } - - // ResourceCompiler Specific - if (GetRegValue(key.pKey, "RC_ShowWindow", bResult)) - { - parent()->SetKey("RC_ShowWindow", bResult); - } - if (GetRegValue(key.pKey, "RC_HideCustom", bResult)) - { - parent()->SetKey("RC_HideCustom", bResult); - } - if (GetRegValue(key.pKey, "RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - parent()->SetKey("RC_Parameters", buffer); - } - if (GetRegValue(key.pKey, "RC_EnableSourceControl", bResult)) - { - parent()->SetKey("RC_EnableSourceControl", bResult); - } - } -} - -bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, const wchar_t* value) -{ - CFixedString name; - name.appendAscii(valueName); - - size_t const sizeInBytes = (wcslen(value) + 1) * sizeof(value[0]); - return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_SZ, (BYTE*)value, DWORD(sizeInBytes))); -} - -bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, bool value) -{ - CFixedString name; - name.appendAscii(valueName); - - DWORD dwVal = value; - return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_DWORD, (BYTE*)&dwVal, sizeof(dwVal))); -} - -bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, int value) -{ - CFixedString name; - name.appendAscii(valueName); - - DWORD dwVal = value; - return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_DWORD, (BYTE*)&dwVal, sizeof(dwVal))); -} - -bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, CWCharBuffer wbuffer) -{ - if (wbuffer.getSizeInElements() <= 0) - { - return false; - } - - CFixedString name; - name.appendAscii(valueName); - - DWORD type; - DWORD sizeInBytes = DWORD(wbuffer.getSizeInBytes()); - if (ERROR_SUCCESS != RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)wbuffer.getPtr(), &sizeInBytes)) - { - wbuffer[0] = 0; - return false; - } - - const size_t sizeInElements = sizeInBytes / sizeof(wbuffer[0]); - if (sizeInElements > wbuffer.getSizeInElements()) // paranoid check - { - wbuffer[0] = 0; - return false; - } - - // According to MSDN documentation for RegQueryValueEx(), strings returned by the function - // are not zero-terminated sometimes, so we need to terminate them by ourselves. - if (wbuffer[sizeInElements - 1] != 0) - { - if (sizeInElements >= wbuffer.getSizeInElements()) - { - // No space left to put terminating zero character - wbuffer[0] = 0; - return false; - } - wbuffer[sizeInElements] = 0; - } - - return true; -} - -bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, bool& value) -{ - CFixedString name; - name.appendAscii(valueName); - - // Open the appropriate registry key - DWORD type, dwVal = 0, size = sizeof(dwVal); - bool res = (ERROR_SUCCESS == RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)&dwVal, &size)); - if (res) - { - value = (dwVal != 0); - } - else - { - wchar_t buffer[100]; - res = GetRegValue(key, valueName, CWCharBuffer(buffer, sizeof(buffer))); - if (res) - { - value = (wcscmp(buffer, L"true") == 0); - } - } - return res; -} - -bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, int& value) -{ - CFixedString name; - name.appendAscii(valueName); - - // Open the appropriate registry key - DWORD type, dwVal = 0, size = sizeof(dwVal); - - bool res = (ERROR_SUCCESS == RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)&dwVal, &size)); - if (res) - { - value = dwVal; - } - - return res; -} - -#endif // AZ_PLATFORM_WINDOWS -#endif // CRY_ENABLE_RC_HELPER diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.h b/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.h deleted file mode 100644 index 47b4772ede..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ -#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H -#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H -#pragma once - -#include "EngineSettingsBackend.h" - -#ifdef CRY_ENABLE_RC_HELPER - -class CEngineSettingsManager; - -class CEngineSettingsBackendWin32 : public CEngineSettingsBackend -{ -public: - CEngineSettingsBackendWin32(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL); - - std::wstring GetModuleFilePath() const override; - - bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) override; - bool GetModuleSpecificIntEntry(const char* key, int& value) override; - bool GetModuleSpecificBoolEntry(const char* key, bool& value) override; - - bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) override; - bool SetModuleSpecificIntEntry(const char* key, const int& value) override; - bool SetModuleSpecificBoolEntry(const char* key, const bool& value) override; - - bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) override; - - void LoadEngineSettingsFromRegistry() override; - bool StoreEngineSettingsToRegistry() override; - -protected: - bool SetRegValue(void* key, const char* valueName, const wchar_t* value); - bool SetRegValue(void* key, const char* valueName, bool value); - bool SetRegValue(void* key, const char* valueName, int value); - bool GetRegValue(void* key, const char* valueName, SettingsManagerHelpers::CWCharBuffer wbuffer); - bool GetRegValue(void* key, const char* valueName, bool& value); - bool GetRegValue(void* key, const char* valueName, int& value); -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H diff --git a/Code/CryEngine/CryCommon/EngineSettingsManager.cpp b/Code/CryEngine/CryCommon/EngineSettingsManager.cpp deleted file mode 100644 index 13ad568217..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsManager.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include "ProjectDefines.h" -#include "EngineSettingsManager.h" - -#if defined(CRY_ENABLE_RC_HELPER) - -#include // assert() -#include "EngineSettingsBackend.h" - -#include "AzCore/PlatformDef.h" -#include "platform.h" - -#if defined(AZ_PLATFORM_WINDOWS) -#include "EngineSettingsBackendWin32.h" -#include -#elif AZ_TRAIT_OS_PLATFORM_APPLE -#include "EngineSettingsBackendApple.h" -#endif - - -#include -#include - -#define INFOTEXT L"Please specify the directory of your CryENGINE installation (RootPath):" - - -using namespace SettingsManagerHelpers; - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -CEngineSettingsManager::CEngineSettingsManager(const wchar_t* moduleName, const wchar_t* iniFileName) - : m_hWndParent(0) - , m_backend(NULL) -{ - m_sModuleName.clear(); - -#if defined(AZ_PLATFORM_WINDOWS) - m_backend = new CEngineSettingsBackendWin32(this, moduleName); -#elif AZ_TRAIT_OS_PLATFORM_APPLE - m_backend = new CEngineSettingsBackendApple(this, moduleName); -#endif - assert(m_backend); - - // std initialization - RestoreDefaults(); - - // try to load content from INI file - if (moduleName != NULL) - { - m_sModuleName = moduleName; - - if (iniFileName == NULL) - { - // find INI filename located in module path - m_sModuleFileName = m_backend->GetModuleFilePath().c_str(); - } - else - { - m_sModuleFileName = iniFileName; - } - - if (LoadValuesFromConfigFile(m_sModuleFileName.c_str())) - { - m_bGetDataFromBackend = false; - return; - } - } - - m_bGetDataFromBackend = true; - - // load basic content from registry - LoadEngineSettingsFromRegistry(); -} - -////////////////////////////////////////////////////////////////////////// -CEngineSettingsManager::~CEngineSettingsManager() -{ - delete m_backend, m_backend = NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::RestoreDefaults() -{ - // Engine - SetKey("ENG_RootPath", L""); - - // RC - SetKey("RC_ShowWindow", false); - SetKey("RC_HideCustom", false); - SetKey("RC_Parameters", L""); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) -{ - if (wbuffer.getSizeInElements() <= 0) - { - return false; - } - - if (!m_bGetDataFromBackend) - { - if (!HasKey(key)) - { - wbuffer[0] = 0; - return false; - } - if (!GetValueByRef(key, wbuffer)) - { - wbuffer[0] = 0; - return false; - } - } - else - { - assert(m_backend); - return m_backend->GetModuleSpecificStringEntryUtf16(key, wbuffer); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetModuleSpecificStringEntryUtf8(const char* key, SettingsManagerHelpers::CCharBuffer buffer) -{ - if (buffer.getSizeInElements() <= 0) - { - return false; - } - - wchar_t wBuffer[1024]; - - if (!GetModuleSpecificStringEntryUtf16(key, SettingsManagerHelpers::CWCharBuffer(wBuffer, sizeof(wBuffer)))) - { - buffer[0] = 0; - return false; - } - - SettingsManagerHelpers::ConvertUtf16ToUtf8(wBuffer, buffer); - - return true; -} - - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetModuleSpecificIntEntry(const char* key, int& value) -{ - value = 0; - - if (!m_bGetDataFromBackend) - { - if (!HasKey(key)) - { - return false; - } - if (!GetValueByRef(key, value)) - { - return false; - } - } - else - { - assert(m_backend); - return m_backend->GetModuleSpecificIntEntry(key, value); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetModuleSpecificBoolEntry(const char* key, bool& value) -{ - value = false; - - if (!m_bGetDataFromBackend) - { - if (!HasKey(key)) - { - return false; - } - if (!GetValueByRef(key, value)) - { - return false; - } - } - else - { - assert(m_backend); - return m_backend->GetModuleSpecificBoolEntry(key, value); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) -{ - SetKey(key, str); - if (!m_bGetDataFromBackend) - { - return StoreData(); - } - - assert(m_backend); - return m_backend->SetModuleSpecificStringEntryUtf16(key, str); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::SetModuleSpecificIntEntry(const char* key, const int& value) -{ - SetKey(key, value); - if (!m_bGetDataFromBackend) - { - return StoreData(); - } - - assert(m_backend); - return m_backend->SetModuleSpecificIntEntry(key, value); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::SetModuleSpecificBoolEntry(const char* key, const bool& value) -{ - SetKey(key, value); - if (!m_bGetDataFromBackend) - { - return StoreData(); - } - - assert(m_backend); - return m_backend->SetModuleSpecificBoolEntry(key, value); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::SetModuleSpecificStringEntryUtf8(const char* key, const char* str) -{ - wchar_t wbuffer[512]; - SettingsManagerHelpers::ConvertUtf8ToUtf16(str, SettingsManagerHelpers::CWCharBuffer(wbuffer, sizeof(wbuffer))); - - return SetModuleSpecificStringEntryUtf16(key, wbuffer); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::HasKey(const char* key) -{ - return m_keyValueArray.find(key) != 0; -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::SetKey(const char* key, const wchar_t* value) -{ - m_keyValueArray.set(key, value); -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::SetKey(const char* key, bool value) -{ - m_keyValueArray.set(key, (value ? L"true" : L"false")); -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::SetKey(const char* key, int value) -{ - m_keyValueArray.set(key, std::to_wstring(value).c_str()); -} - -bool CEngineSettingsManager::GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) -{ - assert(m_backend); - return m_backend->GetInstalledBuildRootPathUtf16(index, name, path); -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::SetParentDialog(size_t window) -{ - m_hWndParent = window; -} - - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::StoreData() -{ - if (m_bGetDataFromBackend) - { - bool res = StoreEngineSettingsToRegistry(); - - if (!res) - { -#ifdef AZ_PLATFORM_WINDOWS - MessageBoxA(reinterpret_cast(m_hWndParent), "Could not store data to registry.", "Error", MB_OK | MB_ICONERROR); -#endif - } - return res; - } - - // store data to INI file - - FILE* file; -#ifdef AZ_PLATFORM_WINDOWS - _wfopen_s(&file, m_sModuleFileName.c_str(), L"wb"); -#else - char fname[MAX_PATH]; - memset(fname, 0, MAX_PATH); - wcstombs(fname, m_sModuleFileName.c_str(), MAX_PATH); - file = fopen(fname, "wb"); -#endif - if (file == NULL) - { - return false; - } - - char buffer[2048]; - - for (size_t i = 0; i < m_keyValueArray.size(); ++i) - { - const SKeyValue& kv = m_keyValueArray[i]; - - fprintf_s(file, kv.key.c_str()); - fprintf_s(file, " = "); - - if (kv.value.length() > 0) - { - SettingsManagerHelpers::ConvertUtf16ToUtf8(kv.value.c_str(), SettingsManagerHelpers::CCharBuffer(buffer, sizeof(buffer))); - fprintf_s(file, "%s", buffer); - } - - fprintf_s(file, "\r\n"); - } - - fclose(file); - - return true; -} - - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::LoadValuesFromConfigFile(const wchar_t* szFileName) -{ - m_keyValueArray.clear(); - - // read file to memory - - FILE* file; -#ifdef AZ_PLATFORM_WINDOWS - _wfopen_s(&file, szFileName, L"rb"); -#else - char fname[MAX_PATH]; - memset(fname, 0, MAX_PATH); - wcstombs(fname, szFileName, MAX_PATH); - file = fopen(fname, "rb"); -#endif - if (file == NULL) - { - return false; - } - - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - char* data = new char[size + 1]; - fread_s(data, size, 1, size, file); - fclose(file); - - wchar_t wBuffer[1024]; - - // parse file for root path - - int start = 0, end = 0; - while (end < size) - { - while (end < size && data[end] != '\n') - { - end++; - } - - memcpy(data, &data[start], end - start); - data[end - start] = 0; - start = end = end + 1; - - CFixedString line(data); - size_t equalsOfs; - for (equalsOfs = 0; equalsOfs < line.length(); ++equalsOfs) - { - if (line[equalsOfs] == '=') - { - break; - } - } - if (equalsOfs < line.length()) - { - CFixedString key; - CFixedString value; - - key.appendAscii(line.c_str(), equalsOfs); - key.trim(); - - SettingsManagerHelpers::ConvertUtf8ToUtf16(line.c_str() + equalsOfs + 1, SettingsManagerHelpers::CWCharBuffer(wBuffer, sizeof(wBuffer))); - value.append(wBuffer); - value.trim(); - - m_keyValueArray.set(key.c_str(), value.c_str()); - } - } - delete[] data; - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::StoreEngineSettingsToRegistry() -{ - assert(m_backend); - return m_backend->StoreEngineSettingsToRegistry(); -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::LoadEngineSettingsFromRegistry() -{ - assert(m_backend); - m_backend->LoadEngineSettingsFromRegistry(); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetValueByRef(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) const -{ - if (wbuffer.getSizeInElements() <= 0) - { - return false; - } - - const SKeyValue* p = m_keyValueArray.find(key); - if (!p || (p->value.length() + 1) > wbuffer.getSizeInElements()) - { - wbuffer[0] = 0; - return false; - } - azwcscpy(wbuffer.getPtr(), wbuffer.getSizeInElements(), p->value.c_str()); - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetValueByRef(const char* key, bool& value) const -{ - wchar_t buffer[100]; - if (!GetValueByRef(key, SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - return false; - } - value = (wcscmp(buffer, L"true") == 0); - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetValueByRef(const char* key, int& value) const -{ - wchar_t buffer[100]; - if (!GetValueByRef(key, SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - return false; - } - value = wcstol(buffer, 0, 10); - return true; -} - -#endif //(CRY_ENABLE_RC_HELPER) diff --git a/Code/CryEngine/CryCommon/EngineSettingsManager.h b/Code/CryEngine/CryCommon/EngineSettingsManager.h deleted file mode 100644 index 95216b3bf3..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsManager.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H -#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H -#pragma once - -#include "ProjectDefines.h" - -#if defined(CRY_ENABLE_RC_HELPER) - -#include "SettingsManagerHelpers.h" - -class CEngineSettingsBackend; - -////////////////////////////////////////////////////////////////////////// -// Manages storage and loading of all information for tools and CryENGINE, by either registry or an INI file. -// Information can be read and set by key-to-value functions. -// Specific information can be set by a dialog application called by this class. -// If the engine root path is not found, a fall-back dialog is opened. -class CEngineSettingsManager -{ -public: - // prepares CEngineSettingsManager to get requested information either from registry or an INI file, - // if existent as a file with name an directory equal to the module, or from registry. - CEngineSettingsManager(const wchar_t* moduleName = NULL, const wchar_t* iniFileName = NULL); - ~CEngineSettingsManager(); - - void RestoreDefaults(); - - // stores/loads user specific information for modules to/from registry or INI file - bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer); - bool GetModuleSpecificStringEntryUtf8(const char* key, SettingsManagerHelpers::CCharBuffer buffer); - bool GetModuleSpecificIntEntry(const char* key, int& value); - bool GetModuleSpecificBoolEntry(const char* key, bool& value); - - bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str); - bool SetModuleSpecificStringEntryUtf8(const char* key, const char* str); - bool SetModuleSpecificIntEntry(const char* key, const int& value); - bool SetModuleSpecificBoolEntry(const char* key, const bool& value); - - bool GetValueByRef(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) const; - bool GetValueByRef(const char* key, bool& value) const; - bool GetValueByRef(const char* key, int& value) const; - - void SetKey(const char* key, const wchar_t* value); - void SetKey(const char* key, bool value); - void SetKey(const char* key, int value); - - bool StoreData(); - - bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path); - - void SetParentDialog(size_t window); - -private: - bool HasKey(const char* key); - - void LoadEngineSettingsFromRegistry(); - bool StoreEngineSettingsToRegistry(); - - // parses a file and stores all flags in a private key-value-map - bool LoadValuesFromConfigFile(const wchar_t* szFileName); - -private: - CEngineSettingsBackend *m_backend; - - SettingsManagerHelpers::CFixedString m_sModuleName; // name to store key-value pairs of modules in (registry) or to identify INI file - SettingsManagerHelpers::CFixedString m_sModuleFileName; // used in case of data being loaded from INI file - bool m_bGetDataFromBackend; - SettingsManagerHelpers::CKeyValueArray<30> m_keyValueArray; - - void* m_hBtnBrowse; - size_t m_hWndParent; -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H diff --git a/Code/CryEngine/CryCommon/IFlares.h b/Code/CryEngine/CryCommon/IFlares.h deleted file mode 100644 index d1626a83d9..0000000000 --- a/Code/CryEngine/CryCommon/IFlares.h +++ /dev/null @@ -1,228 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IFLARES_H -#define CRYINCLUDE_CRYCOMMON_IFLARES_H -#pragma once - -#include // <> required for Interfuscator -#include // <> required for Interfuscator -#include "smartptr.h" - -struct IShader; -class CCamera; - -class __MFPA -{ -}; -class __MFPB -{ -}; -#define MFP_SIZE_ENFORCE : public __MFPA, public __MFPB - -enum EFlareType -{ - eFT__Base__, - eFT_Root, - eFT_Group, - eFT_Ghost, - eFT_MultiGhosts, - eFT_Glow, - eFT_ChromaticRing, - eFT_IrisShafts, - eFT_CameraOrbs, - eFT_ImageSpaceShafts, - eFT_Streaks, - eFT_Reference, - eFT_Proxy, - eFT_Max -}; - -#define FLARE_LIBS_PATH "libs/flares/" -#define FLARE_EXPORT_FILE "LensFlareList.xml" -#define FLARE_EXPORT_FILE_VERSION "1" - -struct FlareInfo -{ - EFlareType type; - const char* name; -#if defined(FLARES_SUPPORT_EDITING) - const char* imagename; -#endif -}; - -#if defined(FLARES_SUPPORT_EDITING) -# define ADD_FLARE_INFO(type, name, imagename) {type, name, imagename} -#else -# define ADD_FLARE_INFO(type, name, imagename) {type, name} -#endif - -class FlareInfoArray -{ -public: - struct Props - { - const FlareInfo* p; - size_t size; - }; - - static const Props Get() - { - static const FlareInfo flareInfoArray[] = - { - ADD_FLARE_INFO(eFT__Base__, "__Base__", NULL), - ADD_FLARE_INFO(eFT_Root, "Root", NULL), - ADD_FLARE_INFO(eFT_Group, "Group", NULL), - ADD_FLARE_INFO(eFT_Ghost, "Ghost", "EngineAssets/Textures/flares/icons/ghost.dds"), - ADD_FLARE_INFO(eFT_MultiGhosts, "Multi Ghost", "EngineAssets/Textures/flares/icons/multi_ghost.dds"), - ADD_FLARE_INFO(eFT_Glow, "Glow", "EngineAssets/Textures/flares/icons/glow.dds"), - ADD_FLARE_INFO(eFT_ChromaticRing, "ChromaticRing", "EngineAssets/Textures/flares/icons/ring.dds"), - ADD_FLARE_INFO(eFT_IrisShafts, "IrisShafts", "EngineAssets/Textures/flares/icons/iris_shafts.dds"), - ADD_FLARE_INFO(eFT_CameraOrbs, "CameraOrbs", "EngineAssets/Textures/flares/icons/orbs.dds"), - ADD_FLARE_INFO(eFT_ImageSpaceShafts, "Vol Shafts", "EngineAssets/Textures/flares/icons/vol_shafts.dds"), - ADD_FLARE_INFO(eFT_Streaks, "Streaks", "EngineAssets/Textures/flares/icons/iris_shafts.dds") - }; - - Props ret; - ret.p = flareInfoArray; - ret.size = sizeof(flareInfoArray) / sizeof(flareInfoArray[0]); - return ret; - } - -private: - FlareInfoArray(); - ~FlareInfoArray(); -}; - -struct SLensFlareRenderParam -{ - SLensFlareRenderParam() - : pCamera(NULL) - , pShader(NULL) - { - } - ~SLensFlareRenderParam(){} - bool IsValid() const - { - return pCamera && pShader; - } - CCamera* pCamera; - IShader* pShader; -}; - -class ISoftOcclusionQuery -{ -public: - // - virtual ~ISoftOcclusionQuery() {} - - virtual void AddRef() = 0; - virtual void Release() = 0; - // -}; - -class IOpticsElementBase MFP_SIZE_ENFORCE -{ -public: - - IOpticsElementBase() - : m_nRefCount(0) - { - } - void AddRef() - { - CryInterlockedIncrement(&m_nRefCount); - } - void Release() - { - if (CryInterlockedDecrement(&m_nRefCount) <= 0) - { - delete this; - } - } - - // - virtual EFlareType GetType() = 0; - virtual bool IsGroup() const = 0; - virtual string GetName() const = 0; - virtual void SetName(const char* ch_name) = 0; - virtual void Load(IXmlNode* pNode) = 0; - - virtual IOpticsElementBase* GetParent() const = 0; - virtual ~IOpticsElementBase() { - } - - virtual bool IsEnabled() const = 0; - - virtual void AddElement(IOpticsElementBase* pElement) = 0; - virtual void InsertElement(int nPos, IOpticsElementBase* pElement) = 0; - virtual void Remove(int i) = 0; - virtual void RemoveAll() = 0; - virtual int GetElementCount() const = 0; - virtual IOpticsElementBase* GetElementAt(int i) const = 0; - - virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; - virtual void Invalidate() = 0; - - virtual void Render(SLensFlareRenderParam* pParam, const Vec3& vPos) = 0; - - virtual void SetOpticsReference([[maybe_unused]] IOpticsElementBase* pReference) {} - virtual IOpticsElementBase* GetOpticsReference() const { return NULL; } - // - -#if defined(FLARES_SUPPORT_EDITING) - virtual AZStd::vector GetEditorParamGroups() = 0; -#endif - - ///Basic Setters/////////////////////////////////////////////////////////////// - virtual void SetEnabled(bool enabled) { (void)enabled; } - virtual void SetSize(float size) { (void)size; } - virtual void SetPerspectiveFactor(float perspectiveFactor) { (void)perspectiveFactor; } - virtual void SetDistanceFadingFactor(float distanceFadingFactor) { (void)distanceFadingFactor; } - virtual void SetBrightness(float brightness) { (void)brightness; } - virtual void SetColor(ColorF color) { (void)color; } - virtual void SetMovement(Vec2 movement) { (void)movement; } - virtual void SetTransform(const Matrix33& xform) { (void)xform; } - virtual void SetOccBokehEnabled(bool occBokehEnabled) { (void)occBokehEnabled; } - virtual void SetOrbitAngle(float orbitAngle) { (void)orbitAngle; } - virtual void SetSensorSizeFactor(float sizeFactor) { (void)sizeFactor; } - virtual void SetSensorBrightnessFactor(float brightnessFactor) { (void)brightnessFactor; } - virtual void SetAutoRotation(bool autoRotation) { (void)autoRotation; } - virtual void SetAspectRatioCorrection(bool aspectRatioCorrection) { (void)aspectRatioCorrection; } - //////////////////////////////////////////////////////////////////////////////// - -private: - - volatile int m_nRefCount; -}; - -class IOpticsManager -{ -public: - // - virtual ~IOpticsManager(){} - virtual void Reset() = 0; - virtual IOpticsElementBase* Create(EFlareType type) const = 0; - virtual bool Load(const char* fullFlareName, int& nOutIndex, bool forceReload = false) = 0; - virtual bool Load(XmlNodeRef& rootNode, int& nOutIndex) = 0; - virtual IOpticsElementBase* GetOptics(int nIndex) = 0; - virtual bool AddOptics(IOpticsElementBase* pOptics, const char* name, int& nOutNewIndex, bool allowReplace = false) = 0; - virtual bool Rename(const char* fullFlareName, const char* newFullFlareName) = 0; - virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; - virtual void Invalidate() = 0; - // -}; - -typedef _smart_ptr IOpticsElementBasePtr; - -#endif // CRYINCLUDE_CRYCOMMON_IFLARES_H diff --git a/Code/CryEngine/CryCommon/IMaterialEffects.h b/Code/CryEngine/CryCommon/IMaterialEffects.h deleted file mode 100644 index 73e03a1d80..0000000000 --- a/Code/CryEngine/CryCommon/IMaterialEffects.h +++ /dev/null @@ -1,504 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Material Effects System - - -#ifndef CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H -#define CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H -#pragma once - -#if !defined(_RELEASE) - #define MATERIAL_EFFECTS_DEBUG -#endif - - -#include "CryFixedArray.h" - -struct IRenderNode; -struct ISurfaceType; - -////////////////////////////////////////////////////////////////////////// -enum EMFXPlayFlags -{ - eMFXPF_Disable_Delay = BIT(0), - eMFXPF_Audio = BIT(1), - eMFXPF_Decal = BIT(2), - eMFXPF_Particles = BIT(3), - eMFXPF_Deprecated0 = BIT(4), // formerly eMFXPF_Flowgraph - eMFXPF_ForceFeedback = BIT(5), - eMFXPF_All = (eMFXPF_Audio | eMFXPF_Decal | eMFXPF_Particles | eMFXPF_Deprecated0 | eMFXPF_ForceFeedback), -}; - -#define MFX_INVALID_ANGLE (gf_PI2 + 1) - -////////////////////////////////////////////////////////////////////////// -struct SMFXAudioEffectRtpc -{ - SMFXAudioEffectRtpc() - { - rtpcName = ""; - rtpcValue = 0.0f; - } - const char* rtpcName; - float rtpcValue; -}; - -////////////////////////////////////////////////////////////////////////// -struct SMFXRunTimeEffectParams -{ - static const int MAX_AUDIO_RTPCS = 4; - - SMFXRunTimeEffectParams() - : playSoundFP(false) - , playflags(eMFXPF_All) - , fLastTime(0.0f) - , srcSurfaceId(0) - , trgSurfaceId(0) - , srcRenderNode(0) - , trgRenderNode(0) - , partID(0) - , pos(ZERO) - , decalPos(ZERO) - , normal(0.0f, 0.0f, 1.0f) - , angle(MFX_INVALID_ANGLE) - , scale(1.0f) - , audioComponentOffset(ZERO) - , numAudioRtpcs(0) - , fDecalPlacementTestMaxSize(1000.f) - { - dir[0].Set(0.0f, 0.0f, -1.0f); - dir[1].Set(0.0f, 0.0f, 1.0f); - } - - bool AddAudioRtpc(const char* name, float val) - { - if (numAudioRtpcs < MAX_AUDIO_RTPCS) - { - audioRtpcs[numAudioRtpcs].rtpcName = name; - audioRtpcs[numAudioRtpcs].rtpcValue = val; - ++numAudioRtpcs; - return true; - } - return false; - } - - void ResetAudioRtpcs() - { - numAudioRtpcs = 0; - } - -public: - uint16 playSoundFP; // Sets 1p/3p audio switch - uint16 playflags; // See EMFXPlayFlags - float fLastTime; // Last time this effect was played - float fDecalPlacementTestMaxSize; - - int srcSurfaceId; - int trgSurfaceId; - IRenderNode* srcRenderNode; - IRenderNode* trgRenderNode; - int partID; - - Vec3 pos; - Vec3 decalPos; - Vec3 dir[2]; - Vec3 normal; - float angle; - float scale; - - // audio related - Vec3 audioComponentOffset; // in case of audio component, uses this offset - - SMFXAudioEffectRtpc audioRtpcs[MAX_AUDIO_RTPCS]; - uint32 numAudioRtpcs; -}; - -struct SMFXBreakageParams -{ - enum EBreakageRequestFlags - { - eBRF_Matrix = BIT(0), - eBRF_HitPos = BIT(1), - eBRF_HitImpulse = BIT(2), - eBRF_Velocity = BIT(3), - eBRF_ExplosionImpulse = BIT(4), - eBRF_Mass = BIT(5), - eBFR_Entity = BIT(6), - }; - - SMFXBreakageParams() - : m_flags(0) - , m_worldTM(IDENTITY) - , m_vHitPos(ZERO) - , m_vHitImpulse(IDENTITY) - , m_vVelocity(ZERO) - , m_fExplosionImpulse(1.0f) - , m_fMass(0.0f) - { - } - - - // Matrix - void SetMatrix(const Matrix34& worldTM) - { - m_worldTM = worldTM; - SetFlag(eBRF_Matrix); - } - - const Matrix34& GetMatrix() const - { - return m_worldTM; - } - - // HitPos - void SetHitPos(const Vec3& vHitPos) - { - m_vHitPos = vHitPos; - SetFlag(eBRF_HitPos); - } - - const Vec3& GetHitPos() const - { - return m_vHitPos; - } - - // HitImpulse - void SetHitImpulse(const Vec3& vHitImpulse) - { - m_vHitImpulse = vHitImpulse; - SetFlag(eBRF_HitImpulse); - } - - const Vec3& GetHitImpulse() const - { - return m_vHitImpulse; - } - - // Velocity - void SetVelocity(const Vec3& vVelocity) - { - m_vVelocity = vVelocity; - SetFlag(eBRF_Velocity); - } - - const Vec3& GetVelocity() const - { - return m_vVelocity; - } - - // Explosion Impulse - void SetExplosionImpulse(float fExplosionImpulse) - { - m_fExplosionImpulse = fExplosionImpulse; - SetFlag(eBRF_ExplosionImpulse); - } - - float GetExplosionImpulse() const - { - return m_fExplosionImpulse; - } - - // Mass - void SetMass(float fMass) - { - m_fMass = fMass; - SetFlag(eBRF_Mass); - } - - float GetMass() const - { - return m_fMass; - } - - // Checking for flags - bool CheckFlag(EBreakageRequestFlags flag) const - { - return (m_flags & flag) != 0; - } - -protected: - void SetFlag(EBreakageRequestFlags flag) - { - m_flags |= flag; - } - - void ClearFlag(EBreakageRequestFlags flag) - { - m_flags &= ~flag; - } - - uint32 m_flags; - Matrix34 m_worldTM; - Vec3 m_vHitPos; - Vec3 m_vHitImpulse; - Vec3 m_vVelocity; - float m_fExplosionImpulse; - float m_fMass; -}; - -class IMFXParticleParams -{ -public: - IMFXParticleParams() - : name(NULL) - , userdata(NULL) - , scale(1.0f) - { - } - - const char* name; - const char* userdata; - float scale; -}; - -class SMFXParticleListNode -{ -public: - static SMFXParticleListNode* Create(); - void Destroy(); - static void FreePool(); - - IMFXParticleParams m_particleParams; - SMFXParticleListNode* pNext; - -private: - SMFXParticleListNode() - { - pNext = NULL; - } - ~SMFXParticleListNode() {} -}; - -class IMFXAudioParams -{ - const static uint MAX_SWITCH_DATA_ELEMENTS = 4; - -public: - - struct SSwitchData - { - SSwitchData() - : switchName(NULL) - , switchStateName(NULL) - { - } - - const char* switchName; - const char* switchStateName; - }; - - IMFXAudioParams() - : triggerName(NULL) - { - } - const char* triggerName; - - CryFixedArray triggerSwitches; -}; - -class SMFXAudioListNode -{ -public: - static SMFXAudioListNode* Create(); - void Destroy(); - static void FreePool(); - - IMFXAudioParams m_audioParams; - SMFXAudioListNode* pNext; - -private: - SMFXAudioListNode() - : pNext(NULL) - { - } - - ~SMFXAudioListNode() - { - } -}; - -class IMFXDecalParams -{ -public: - IMFXDecalParams() - { - filename = 0; - material = 0; - minscale = 1.f; - maxscale = 1.f; - rotation = -1.f; - lifetime = 10.0f; - assemble = false; - forceedge = false; - } - const char* filename; - const char* material; - float minscale; - float maxscale; - float rotation; - float lifetime; - bool assemble; - bool forceedge; -}; - -class SMFXDecalListNode -{ -public: - static SMFXDecalListNode* Create(); - void Destroy(); - static void FreePool(); - - IMFXDecalParams m_decalParams; - SMFXDecalListNode* pNext; - -private: - SMFXDecalListNode() - { - pNext = 0; - } - ~SMFXDecalListNode() {} -}; - -class IMFXForceFeedbackParams -{ -public: - IMFXForceFeedbackParams() - : forceFeedbackEventName (NULL) - , intensityFallOffMinDistanceSqr(0.0f) - , intensityFallOffMaxDistanceSqr(0.0f) - { - } - - const char* forceFeedbackEventName; - float intensityFallOffMinDistanceSqr; - float intensityFallOffMaxDistanceSqr; -}; - -class SMFXForceFeedbackListNode -{ -public: - static SMFXForceFeedbackListNode* Create(); - void Destroy(); - static void FreePool(); - - IMFXForceFeedbackParams m_forceFeedbackParams; - SMFXForceFeedbackListNode* pNext; - -private: - SMFXForceFeedbackListNode() - : pNext(NULL) - { - } - ~SMFXForceFeedbackListNode() {} -}; - -struct SMFXResourceList; -typedef _smart_ptr SMFXResourceListPtr; - -struct SMFXResourceList -{ -public: - SMFXParticleListNode* m_particleList; - SMFXAudioListNode* m_audioList; - SMFXDecalListNode* m_decalList; - SMFXForceFeedbackListNode* m_forceFeedbackList; - - void AddRef() { ++m_refs; } - void Release() - { - if (--m_refs <= 0) - { - Destroy(); - } - } - - static SMFXResourceListPtr Create(); - static void FreePool(); - -private: - int m_refs; - - virtual void Destroy(); - - SMFXResourceList() - : m_refs(0) - { - m_particleList = 0; - m_audioList = 0; - m_decalList = 0; - m_forceFeedbackList = 0; - } - virtual ~SMFXResourceList() - { - while (m_particleList != 0) - { - SMFXParticleListNode* next = m_particleList->pNext; - m_particleList->Destroy(); - m_particleList = next; - } - while (m_audioList != 0) - { - SMFXAudioListNode* next = m_audioList->pNext; - m_audioList->Destroy(); - m_audioList = next; - } - while (m_decalList != 0) - { - SMFXDecalListNode* next = m_decalList->pNext; - m_decalList->Destroy(); - m_decalList = next; - } - while (m_forceFeedbackList != 0) - { - SMFXForceFeedbackListNode* next = m_forceFeedbackList->pNext; - m_forceFeedbackList->Destroy(); - m_forceFeedbackList = next; - } - } -}; - -typedef uint16 TMFXEffectId; -static const TMFXEffectId InvalidEffectId = 0; - -struct SMFXCustomParamValue -{ - float fValue; -}; - -////////////////////////////////////////////////////////////////////////// -struct IMaterialEffects -{ - // - virtual ~IMaterialEffects(){} - virtual void LoadFXLibraries() = 0; - virtual void Reset(bool bCleanup) = 0; - virtual void ClearDelayedEffects() = 0; - virtual TMFXEffectId GetEffectIdByName(const char* libName, const char* effectName) = 0; - virtual TMFXEffectId GetEffectId(int surfaceIndex1, int surfaceIndex2) = 0; - virtual TMFXEffectId GetEffectId(const char* customName, int surfaceIndex2) = 0; - virtual SMFXResourceListPtr GetResources(TMFXEffectId effectId) const = 0; - virtual void PreLoadAssets() = 0; - virtual bool ExecuteEffect(TMFXEffectId effectId, SMFXRunTimeEffectParams& runtimeParams) = 0; - virtual int GetDefaultSurfaceIndex() = 0; - virtual int GetDefaultCanopyIndex() = 0; - - virtual bool PlayBreakageEffect(ISurfaceType* pSurfaceType, const char* breakageType, const SMFXBreakageParams& mfxBreakageParams) = 0; - - virtual void SetCustomParameter(TMFXEffectId effectId, const char* customParameter, const SMFXCustomParamValue& customParameterValue) = 0; - - virtual void CompleteInit() = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H diff --git a/Code/CryEngine/CryCommon/INotificationNetwork.h b/Code/CryEngine/CryCommon/INotificationNetwork.h deleted file mode 100644 index 9ad44b24ab..0000000000 --- a/Code/CryEngine/CryCommon/INotificationNetwork.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H -#define CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H -#pragma once - - -// Constants - -#define NN_CHANNEL_NAME_LENGTH_MAX 16 - -struct INotificationNetworkClient; - -// User Interfaces - -struct INotificationNetworkListener -{ - // - virtual ~INotificationNetworkListener(){} - // Called upon receiving data from the Channel the Listener is binded to. - virtual void OnNotificationNetworkReceive(const void* pBuffer, size_t length) = 0; - // -}; - -struct INotificationNetworkConnectionCallback -{ - // - virtual ~INotificationNetworkConnectionCallback(){} - virtual void OnConnect(INotificationNetworkClient* pClient, bool bSucceeded) = 0; - virtual void OnDisconnected(INotificationNetworkClient* pClient) = 0; - // -}; - -// Interfaces - -struct INotificationNetworkClient -{ - // - virtual ~INotificationNetworkClient(){} - virtual void Release() = 0; - - // Binds a Listener to the given Notification Channel. - // Each Listener can be binded only to one Channel, calling the method - // again with an already added Listener and a different Channel will rebind it. - // The Channel name cannot exceed NN_CHANNEL_NAME_LENGTH_MAX chars. - virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener) = 0; - - // If it exist, removes the given Listener form the Notification Network. - virtual bool ListenerRemove(INotificationNetworkListener* pListener) = 0; - - // Sends arbitrary data to the Notification Network the Client is connected to. - virtual bool Send(const char* channelName, const void* pBuffer, size_t length) = 0; - - // Checks if the current client is connected. - // Returns true if it is connected, false otherwise. - virtual bool IsConnected() = 0; - - // Checks if the connection attempt failed. - // Returns true if it failed to connect by any reason (such as timeout). - virtual bool IsFailedToConnect() const = 0; - - // Start the connection request for this particular client. - // Parameters: - // address - Is the host name or ipv4 (for now) address string to which - // we want to connect. - // port - Is the TCP port to which we want to connect. - // Remarks: Port 9432 is being used by the live preview already. - virtual bool Connect(const char* address, uint16 port) = 0; - - // Tries to register a callback listener object. - // A callback listener object will receive events from the client element, - // such as connection result information. - // Parameters: - // - pConnectionCallback - Is a pointer to an object implementing interface - // INotificationNetworkConnectionCallback which will be called when - // the events happen, such as connection, disconnection and failed attempt - // to connect. - // Return Value: - // - It will return true if registered the callback object successfully. - // - It will return false when there the callback object is already - // registered. - virtual bool RegisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) = 0; - - // Tries to unregister a callback listener object. - // A callback listener object will receive events from the client element, - // such as connection result information. - // Parameters: - // - pConnectionCallback - Is a pointer to an object implementing interface - // INotificationNetworkConnectionCallback which will be called when - // the events happen, such as connection, disconnection and failed attempt - // to connect and that we want to unregister. - // Return Value: - // - It will return true if unregistered the callback object successfully. - // - It will return false when no object matching the one requested is found - // int the object. - virtual bool UnregisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) = 0; - // -}; - -struct INotificationNetwork -{ - // - virtual ~INotificationNetwork(){} - - virtual void Release() = 0; - - // Creates a disconnected client. - virtual INotificationNetworkClient* CreateClient() = 0; - - // Attempts to connect to the Notification Network at the given address, - // returns a Client interface if communication is possible. - virtual INotificationNetworkClient* Connect(const char* address, uint16 port) = 0; - - // Returns the Connection count of the given Channel. If NULL is passed - // instead of a valid Channel name the total count of all Connections is - // returned. - virtual size_t GetConnectionCount(const char* channelName = NULL) = 0; - - // Has to be called from the main thread to process received notifications. - virtual void Update() = 0; - - // Binds a Listener to the given Notification Channel. - // Each Listener can be binded only to one Channel, calling the method - // again with an already added Listener and a different Channel will rebind it. - // The Channel name cannot exceed NN_CHANNEL_NAME_LENGTH_MAX chars. - virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener) = 0; - - // If it exist, removes the given Listener form the Notification Network. - virtual bool ListenerRemove(INotificationNetworkListener* pListener) = 0; - - // Sends arbitrary data to all the Connections listening to the given Channel. - virtual uint32 Send(const char* channel, const void* pBuffer, size_t length) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H diff --git a/Code/CryEngine/CryCommon/IRenderer.h b/Code/CryEngine/CryCommon/IRenderer.h index 94f8772e71..bb8f8fa572 100644 --- a/Code/CryEngine/CryCommon/IRenderer.h +++ b/Code/CryEngine/CryCommon/IRenderer.h @@ -16,12 +16,12 @@ #include "Cry_Geo.h" #include "Cry_Camera.h" #include "ITexture.h" -#include // <> required for Interfuscator +#include // <> required for Interfuscator +#include // <> required for Interfuscator +#include "smartptr.h" #include #include -#include "IResourceCompilerHelper.h" // for IResourceCompilerHelper::ERcCallResult - // forward declarations struct SRenderingPassInfo; struct SRTStack; @@ -95,7 +95,6 @@ struct IFFont; struct IFFont_RenderProxy; struct STextDrawContext; struct IRenderMesh; -class IOpticsManager; struct ShadowFrustumMGPUCache; struct IAsyncTextureCompileListener; struct IClipVolume; @@ -955,25 +954,6 @@ protected: virtual ~ITextureStreamListener() {} }; -#if defined(CRY_ENABLE_RC_HELPER) -//////////////////////////////////////////////////////////////////////////// -// Listener for asynchronous texture compilation. -// Connects the listener to the task-queue of pending compilation requests. -enum ERcExitCode; -struct IAsyncTextureCompileListener -{ -public: - virtual void OnCompilationStarted(const char* source, const char* target, int nPending) = 0; - virtual void OnCompilationFinished(const char* source, const char* target, IResourceCompilerHelper::ERcCallResult nReturnCode) = 0; - - virtual void OnCompilationQueueTriggered(int nPending) = 0; - virtual void OnCompilationQueueDepleted() = 0; - -protected: - virtual ~IAsyncTextureCompileListener() {} -}; -#endif - enum eDolbyVisionMode { eDVM_Disabled, @@ -1869,8 +1849,6 @@ struct IRenderer virtual SDepthTexture* CreateDepthSurface(int nWidth, int nHeight, bool shaderResourceView = false) = 0; virtual void DestroyDepthSurface(SDepthTexture* pDepthSurf) = 0; - virtual IOpticsElementBase* CreateOptics(EFlareType type) const = 0; - // Note: // Used for pausing timer related stuff. // Example: diff --git a/Code/CryEngine/CryCommon/IResourceCompilerHelper.cpp b/Code/CryEngine/CryCommon/IResourceCompilerHelper.cpp deleted file mode 100644 index 380c94e4c7..0000000000 --- a/Code/CryEngine/CryCommon/IResourceCompilerHelper.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "IResourceCompilerHelper.h" - -#include -// DO NOT USE AZSTD. - -#include // std string used here. -#include -#include - -// the following block is for _mkdir on windows and mkdir on other platforms. -#if defined(_WIN32) -# include -#else -# include -# include -#endif - -namespace RCPathUtil -{ - const char* GetExt(const char* filepath) - { - const char* str = filepath; - size_t len = strlen(filepath); - for (const char* p = str + len - 1; p >= str; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - // we've reached a path separator - it means there's no extension in this name - return ""; - case '.': - // there's an extension in this file name - return p + 1; - } - } - return ""; - } - - const char* GetFile(const char* filepath) - { - const size_t len = strlen(filepath); - for (const char* p = filepath + len - 1; p >= filepath; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - return p + 1; - } - } - return filepath; - } - - - //! Replace extension for given file. - std::string RemoveExtension(const char* filepath) - { - std::string filepathstr = filepath; - const char* str = filepathstr.c_str(); - for (const char* p = str + filepathstr.length() - 1; p >= str; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - // we've reached a path separator - it means there's no extension in this name - return filepathstr; - case '.': - // there's an extension in this file name - filepathstr.erase(p - str); - return filepathstr; - } - } - // it seems the file name is a pure name, without path or extension - return filepathstr; - } - - std::string ReplaceExtension(const char* filepath, const char* ext) - { - std::string str = filepath; - if (ext != 0) - { - str = RemoveExtension(str.c_str()); - if (ext[0] != 0 && ext[0] != '.') - { - str += "."; - } - str += ext; - } - return str; - } - - std::string GetPath(const char* filepath) - { - std::string filepathstr = filepath; - const char* str = filepathstr.c_str(); - for (const char* p = str + filepathstr.length() - 1; p >= str; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - // we've reached a path separator - it means there's no extension in this name - return filepathstr.substr(0, p - str); - } - } - // it seems the file name is a pure name, without path - return ""; - } - - - ////////////////////////////////////////////////////////////////////////// - bool IsRelativePath(const char* p) - { - if (!p || !p[0]) - { - return true; - } - return p[0] != '/' && p[0] != '\\' && !strchr(p, ':'); - } -} - -const char* IResourceCompilerHelper::SourceImageFormatExts[NUM_SOURCE_IMAGE_TYPE] = { "tif", "bmp", "gif", "jpg", "jpeg", "jpe", "tga", "png" }; -const char* IResourceCompilerHelper::SourceImageFormatExtsWithDot[NUM_SOURCE_IMAGE_TYPE] = { ".tif", ".bmp", ".gif", ".jpg", ".jpeg", ".jpe", ".tga", ".png" }; -const char* IResourceCompilerHelper::EngineImageFormatExts[NUM_ENGINE_IMAGE_TYPE] = { "dds" }; -const char* IResourceCompilerHelper::EngineImageFormatExtsWithDot[NUM_ENGINE_IMAGE_TYPE] = { ".dds" }; - - -IResourceCompilerHelper::ERcCallResult IResourceCompilerHelper::ConvertResourceCompilerExitCodeToResultCode(int exitCode) -{ - switch (exitCode) - { - case eRcExitCode_Success: - case eRcExitCode_UserFixing: - return eRcCallResult_success; - - case eRcExitCode_Error: - return eRcCallResult_error; - - case eRcExitCode_FatalError: - return eRcCallResult_error; - case eRcExitCode_Crash: - return eRcCallResult_crash; - } - return eRcCallResult_error; -} - - -////////////////////////////////////////////////////////////////////////// -const char* IResourceCompilerHelper::GetCallResultDescription(IResourceCompilerHelper::ERcCallResult result) -{ - switch (result) - { - case eRcCallResult_success: - return "Success."; - case eRcCallResult_notFound: - return "ResourceCompiler executable was not found."; - case eRcCallResult_error: - return "ResourceCompiler exited with an error."; - case eRcCallResult_crash: - return "ResourceCompiler crashed! Please report this. Include source asset and this log in the report."; - default: - return "Unexpected failure in ResultCompilerHelper."; - } -} - -// Arguments: -// szFilePath - could be source or destination filename -void IResourceCompilerHelper::GetOutputFilename(const char* szFilePath, char* buffer, size_t bufferSizeInBytes) -{ - if (IResourceCompilerHelper::IsSourceImageFormatSupported(szFilePath)) - { - std::string newString = RCPathUtil::ReplaceExtension(szFilePath, "dds"); - azstrncpy(buffer, bufferSizeInBytes, newString.c_str(), bufferSizeInBytes - 1); - return; - } - - azstrncpy(buffer, bufferSizeInBytes, szFilePath, bufferSizeInBytes - 1); -} - -IResourceCompilerHelper::ERcCallResult IResourceCompilerHelper::InvokeResourceCompiler(const char* szSrcFilePath, const char* szDstFilePath, const bool bUserDialog) -{ - - const char* szDstFileName = RCPathUtil::GetFile(szDstFilePath); - std::string pathOnly = RCPathUtil::GetPath(szDstFilePath); - const int maxStringSize = 512; - char szRemoteCmdLine[maxStringSize] = { 0 }; - char szFullPathToSourceFile[maxStringSize] = { 0 }; - - if (RCPathUtil::IsRelativePath(szSrcFilePath)) - { - azstrcat(szFullPathToSourceFile, maxStringSize, "#ENGINEROOT#"); - azstrcat(szFullPathToSourceFile, maxStringSize, "\\"); - } - azstrcat(szFullPathToSourceFile, maxStringSize, szSrcFilePath); - - azstrcat(szRemoteCmdLine, maxStringSize, " /targetroot=\""); - azstrcat(szRemoteCmdLine, maxStringSize, pathOnly.c_str()); - azstrcat(szRemoteCmdLine, maxStringSize, "\""); - - azstrcat(szRemoteCmdLine, maxStringSize, " /overwritefilename=\""); - azstrcat(szRemoteCmdLine, maxStringSize, szDstFileName); - azstrcat(szRemoteCmdLine, maxStringSize, "\""); - - return CallResourceCompiler(szFullPathToSourceFile, szRemoteCmdLine, nullptr, true, false, !bUserDialog); -} - -unsigned int IResourceCompilerHelper::GetNumSourceImageFormats() -{ - return NUM_SOURCE_IMAGE_TYPE; -} - -const char* IResourceCompilerHelper::GetSourceImageFormat(unsigned int index, bool bWithDot) -{ - if (index >= GetNumSourceImageFormats()) - { - return nullptr; - } - - if (bWithDot) - { - return SourceImageFormatExtsWithDot[index]; - } - else - { - return SourceImageFormatExts[index]; - } -} - -unsigned int IResourceCompilerHelper::GetNumEngineImageFormats() -{ - return NUM_ENGINE_IMAGE_TYPE; -} - -const char* IResourceCompilerHelper::GetEngineImageFormat(unsigned int index, bool bWithDot) -{ - if (index >= GetNumEngineImageFormats()) - { - return nullptr; - } - - if (bWithDot) - { - return EngineImageFormatExtsWithDot[index]; - } - else - { - return EngineImageFormatExts[index]; - } -} - -bool IResourceCompilerHelper::IsSourceImageFormatSupported(const char* szFileNameOrExtension) -{ - if (!szFileNameOrExtension) // if this hits, might want to check the call site - { - return false; - } - - //check the string length - size_t len = strlen(szFileNameOrExtension); - if (len < 3)//no point in going on if the smallest valid ext is 3 characters - { - return false; - } - - //find the ext by starting at the last character and moving backward to first he first '.' - const char* szExtension = nullptr; - size_t cur = len - 1; - while (cur && !szExtension) - { - if (szFileNameOrExtension[cur] == '.') - { - szExtension = &szFileNameOrExtension[cur]; - } - cur--; - } - if (len - cur < 3)//no point in going on if the smallest valid ext is 3 characters - { - return false; - } - - //if we didn't find a '.' it could still be valid, they may not have - //passed it in. i.e. "dds" instead of ".dds" which is still valid - if (!szExtension) - { - //with no '.' the largest ext is currently 4 characters - //no point in going on if it is larger - if (len > 4) - { - return false; - } - - szExtension = szFileNameOrExtension; - } - - //loop over all the valid exts and see if it is one of them - for (unsigned int i = 0; i < GetNumSourceImageFormats(); ++i) - { - if (!azstricmp(szExtension, GetSourceImageFormat(i, szExtension[0] == '.'))) - { - return true; - } - } - - return false; -} - -bool IResourceCompilerHelper::IsGameImageFormatSupported(const char* szFileNameOrExtension) -{ - if (!szFileNameOrExtension) // if this hits, might want to check the call site - { - return false; - } - - //check the string length - size_t len = strlen(szFileNameOrExtension); - if (len < 3)//no point in going on if the smallest valid ext is 3 characters - { - return false; - } - - //find the ext by starting at the last character and moving backward to first he first '.' - const char* szExtension = nullptr; - size_t cur = len - 1; - while (cur && !szExtension) - { - if (szFileNameOrExtension[cur] == '.') - { - szExtension = &szFileNameOrExtension[cur]; - } - cur--; - } - if (len - cur < 3)//no point in going on if the smallest valid ext is 3 characters - { - return false; - } - - //if we didn't find a '.' it could still be valid, they may not have - //passed it in. i.e. "dds" instead of ".dds" which is still valid - if (!szExtension) - { - //with no '.' the largest ext is currently 4 characters - //no point in going on if it is larger - if (len > 4) - { - return false; - } - - szExtension = szFileNameOrExtension; - } - - //loop over all the valid exts and see if it is one of them - for (unsigned int i = 0; i < GetNumEngineImageFormats(); ++i) - { - if (!azstricmp(szExtension, GetEngineImageFormat(i, szExtension[0] == '.'))) - { - return true; - } - } - - return false; -} diff --git a/Code/CryEngine/CryCommon/IResourceCompilerHelper.h b/Code/CryEngine/CryCommon/IResourceCompilerHelper.h deleted file mode 100644 index 52f05b0c84..0000000000 --- a/Code/CryEngine/CryCommon/IResourceCompilerHelper.h +++ /dev/null @@ -1,167 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H -#define CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H - -#pragma once - -// DO NOT USE AZSTD - -#include - -// IResourceCompilerHelper exists to define an interface that allows -// remote or local compilation of resources through the "resource Compiler" executable -// in most tools it will be implemented as a local execution. However, in the engine -// it will be substituted for a remote RC invocation through the Asset Processor if -// that system is enabled (via con var and define) - -// DO NOT USE CRYSTRING or CRY ALLOCATORS HERE. This is used in maya plugins, that kind of thing. -// the following path utils are special versions of these functions which take pains -// to not use crystring. -// the functions in this interface must be cross platform. -namespace RCPathUtil -{ - // given a full path, return the extension (it will be a pointer into the existing string) - const char* GetExt(const char* filepath); - - // given a full path, return the file only (it will be a pointer into the existing string) - const char* GetFile(const char* filepath); - - // given a filepath, get only the path. - std::string GetPath(const char* filepath); - std::string ReplaceExtension(const char* filepath, const char* ext); - bool IsRelativePath(const char* p); -} - -class IResourceCompilerListener; - -enum ERcExitCode -{ - eRcExitCode_Success = 0, // must be 0 - eRcExitCode_Error = 1, - eRcExitCode_FatalError = 100, - eRcExitCode_Crash = 101, - eRcExitCode_UserFixing = 200, - eRcExitCode_Pending = 666, -}; - -/// A pure virtual interface to the RC Helper system -/// the RC helper system allows you to make requests to a remote process in order to process -/// an asset for you. -class IResourceCompilerHelper -{ -public: - virtual ~IResourceCompilerHelper() {} - - // defines the result of a call via this API to the RC system - enum ERcCallResult - { - eRcCallResult_success, // everything is OK - eRcCallResult_notFound, // the RC executable is not found - eRcCallResult_error, // the RC executable returned an error - eRcCallResult_crash, // the RC executable did not finish - }; - - // - // Arguments: - // szFileName null terminated ABSOLUTE file path or 0 can be used to test for rc.exe existence - // relative path needs to be relative to rc_plugins directory - // szAdditionalSettings - 0 or e.g. "/refresh" or "/refresh /xyz=56" - // - // this is a SYNCHRONOUS, BLOCKING call and will return once the process is complete - virtual ERcCallResult CallResourceCompiler( - const char* szFileName = 0, - const char* szAdditionalSettings = 0, - IResourceCompilerListener* listener = 0, - bool bMayShowWindow = true, - bool bSilent = false, - bool bNoUserDialog = false, - const wchar_t* szWorkingDirectory = 0, - const wchar_t* szRootPath = 0) = 0; - - // InvokeResourceCompiler - a utility that calls the above CallResourceCompiler function - // but generates appropriate settings so you don't have to specify each option. - // This is a BLOCKING call - // the srcFile can be relative to the project root or an absolute path - // the dstFilePath MUST be relative to the same folder as the Src File path - // this will output dstFilePath in the same folder as srcFile. - virtual ERcCallResult InvokeResourceCompiler(const char* szSrcFilePath, const char* szDstFilePath, const bool bUserDialog); - - // --------------------- utility functions --------------------------------- - - // given a RC.EXE process exit code like 101, convert it to the above ERcCallResult - ERcCallResult ConvertResourceCompilerExitCodeToResultCode(int exitCode); - - // given a ERcCallResult, convert it to a simple english string for debugging. - static const char* GetCallResultDescription(ERcCallResult result); - - // given a filename such as "blah.tif" convert it to the appropriate output name "blah.dds" for example - static void GetOutputFilename(const char* szFilePath, char* buffer, size_t bufferSizeInBytes); - - ////////////////////////////////////////////////////////////////////////// - - enum SourceImageTypes - { - SOURCE_IMAGE_TYPE_TIF, - SOURCE_IMAGE_TYPE_BMP, - SOURCE_IMAGE_TYPE_GIF, - SOURCE_IMAGE_TYPE_JPG, - SOURCE_IMAGE_TYPE_JPEG, - SOURCE_IMAGE_TYPE_JPE, - SOURCE_IMAGE_TYPE_TGA, - SOURCE_IMAGE_TYPE_PNG, - NUM_SOURCE_IMAGE_TYPE - }; - - enum EngineImageTypes - { - ENGINE_IMAGE_TYPE_DDS, - NUM_ENGINE_IMAGE_TYPE - }; - -private: - static const char* SourceImageFormatExts[NUM_SOURCE_IMAGE_TYPE]; - static const char* SourceImageFormatExtsWithDot[NUM_SOURCE_IMAGE_TYPE]; - static const char* EngineImageFormatExts[NUM_ENGINE_IMAGE_TYPE]; - static const char* EngineImageFormatExtsWithDot[NUM_ENGINE_IMAGE_TYPE]; - -public: - static unsigned int GetNumSourceImageFormats(); - static const char* GetSourceImageFormat(unsigned int index, bool bWithDot); - - static unsigned int GetNumEngineImageFormats(); - static const char* GetEngineImageFormat(unsigned int index, bool bWithDot); - - static bool IsSourceImageFormatSupported(const char* szExtension); - static bool IsGameImageFormatSupported(const char* szExtension); -}; - -//////////////////////////////////////////////////////////////////////////// -// Listener for synchronous resource-compilation. -// Connects the listener to the output of the RC process. -class IResourceCompilerListener -{ -public: - // FbxImportDialog relies on this enum being in the order from most verbose to least verbose - enum MessageSeverity - { - MessageSeverity_Debug = 0, - MessageSeverity_Info, - MessageSeverity_Warning, - MessageSeverity_Error - }; - - virtual void OnRCMessage(MessageSeverity /*severity*/, const char* /*text*/) {} - virtual ~IResourceCompilerListener() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H diff --git a/Code/CryEngine/CryCommon/IShader.h b/Code/CryEngine/CryCommon/IShader.h index a87144a8c2..5f5209992e 100644 --- a/Code/CryEngine/CryCommon/IShader.h +++ b/Code/CryEngine/CryCommon/IShader.h @@ -24,7 +24,9 @@ #endif #include "smartptr.h" -#include // <> required for Interfuscator +#include // <> required for Interfuscator +#include // <> required for Interfuscator +#include "smartptr.h" #include "VertexFormats.h" #include #include @@ -2828,7 +2830,6 @@ struct SRenderLight m_ObjMatrix.SetIdentity(); m_BaseObjMatrix.SetIdentity(); m_sName = ""; - m_pSoftOccQuery = NULL; m_pLightAnim = NULL; m_fAreaWidth = 1; m_fAreaHeight = 1; @@ -2884,11 +2885,6 @@ struct SRenderLight return m_pLightImage ? m_pLightImage : NULL; } - IOpticsElementBase* GetLensOpticsElement() const - { - return m_pLensOpticsElement; - } - void SetOpticsParams(const SOpticsInstanceParameters& params) { m_opticsParams = params; @@ -2899,24 +2895,6 @@ struct SRenderLight return m_opticsParams; } - void SetLensOpticsElement(IOpticsElementBase* pOptics) - { - if (m_pLensOpticsElement == pOptics) - { - return; - } - if (pOptics && pOptics->GetType() != eFT_Root) - { - return; - } - SAFE_RELEASE(m_pLensOpticsElement); - m_pLensOpticsElement = pOptics; - if (m_pLensOpticsElement) - { - m_pLensOpticsElement->AddRef(); - } - } - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { /*LATER*/} void AcquireResources() @@ -2937,14 +2915,6 @@ struct SRenderLight { m_pSpecularCubemap->AddRef(); } - if (m_pLensOpticsElement) - { - m_pLensOpticsElement->AddRef(); - } - if (m_pSoftOccQuery) - { - m_pSoftOccQuery->AddRef(); - } if (m_pLightAnim) { m_pLightAnim->AddRef(); @@ -2961,8 +2931,6 @@ struct SRenderLight SAFE_RELEASE(m_pLightImage); SAFE_RELEASE(m_pDiffuseCubemap); SAFE_RELEASE(m_pSpecularCubemap); - SAFE_RELEASE(m_pLensOpticsElement); - SAFE_RELEASE(m_pSoftOccQuery); SAFE_RELEASE(m_pLightAnim); SAFE_RELEASE(m_pLightAttenMap); } @@ -3046,8 +3014,6 @@ struct SRenderLight const char* m_sName; // Optional name of the light source. SShaderItem m_Shader; // Shader item CRenderObject* m_pObject[MAX_RECURSION_LEVELS]; // Object for light coronas and light flares. - IOpticsElementBase* m_pLensOpticsElement; // Optics element for this shader instance - ISoftOcclusionQuery* m_pSoftOccQuery; ILightAnimWrapper* m_pLightAnim; Matrix34 m_BaseObjMatrix; @@ -3146,9 +3112,7 @@ public: m_fShadowSlopeBias = dl.m_fShadowSlopeBias; m_fShadowResolutionScale = dl.m_fShadowResolutionScale; m_fHDRDynamic = dl.m_fHDRDynamic; - m_pLensOpticsElement = dl.m_pLensOpticsElement; m_LensOpticsFrustumAngle = dl.m_LensOpticsFrustumAngle; - m_pSoftOccQuery = dl.m_pSoftOccQuery; m_fLightFrustumAngle = dl.m_fLightFrustumAngle; m_fProjectorNearPlane = dl.m_fProjectorNearPlane; m_Flags = dl.m_Flags; diff --git a/Code/CryEngine/CryCommon/ISoftCodeMgr.h b/Code/CryEngine/CryCommon/ISoftCodeMgr.h deleted file mode 100644 index b3cef7e1f0..0000000000 --- a/Code/CryEngine/CryCommon/ISoftCodeMgr.h +++ /dev/null @@ -1,276 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to manage SoftCode module loading and patching - - -#ifndef CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H -#define CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H -#pragma once - - -// Provides the generic interface for exchanging member values between SoftCode modules, -struct IExchangeValue -{ - // - virtual ~IExchangeValue() {} - - // Allocates a new IExchangeValue with the underlying type - virtual IExchangeValue* Clone() const = 0; - // Returns the size of the underlying type (to check compatibility) - virtual size_t GetSizeOf() const = 0; - // -}; - -template -struct ExchangeValue - : public IExchangeValue -{ - ExchangeValue(T& value) - : m_value(value) - {} - - virtual IExchangeValue* Clone() const { return new ExchangeValue(*this); } - virtual size_t GetSizeOf() const { return sizeof(m_value); } - - T m_value; -}; - -template -struct ExchangeArray - : public IExchangeValue -{ - ExchangeArray(T* pArr) - { - for (size_t i = 0; i < S; ++i) - { - m_array[i] = pArr[i]; - } - } - - virtual IExchangeValue* Clone() const { return new ExchangeArray(*this); } - virtual size_t GetSizeOf() const { return sizeof(m_array); } - - T m_array[S]; -}; - -/* - This is a non-intrusive support function for types where default construction does no initialization. - SoftCoding relies on default construction to initialize object state correctly. - For most types this works as expected but for some types (typically things like vectors or matrices) - default initialization would be too costly and is therefore not implemented. - This function allows a specialized implementation to be used for such types that will perform - initialization on the newly constructed instance. For example: - - inline void DefaultInitialize(Matrix34& matrix) - { - matrix.SetIdentity(); - } -*/ -template -void DefaultInitialize(T& t) -{ - t = T(); -} - -// Vector support -template -struct Vec2_tpl; -template -struct Vec3_tpl; -template -void DefaultInitialize(Vec2_tpl& vec) { vec.zero(); } -template -void DefaultInitialize(Vec3_tpl& vec) { vec.zero(); } - -// Matrix support -template -struct Matrix33_tpl; -template -struct Matrix34_tpl; -template -struct Matrix44_tpl; - -template -void DefaultInitialize(Matrix33_tpl& matrix) { matrix.SetIdentity(); } -template -void DefaultInitialize(Matrix34_tpl& matrix) { matrix.SetIdentity(); } -template -void DefaultInitialize(Matrix44_tpl& matrix) { matrix.SetIdentity(); } - -// Quat support -template -struct Quat_tpl; -template -void DefaultInitialize(Quat_tpl& quat) { quat.SetIdentity(); } - -// Interface for performing an exchange of instance data -struct IExchanger -{ - // - virtual ~IExchanger() {} - - // True if data is being read from instance members - virtual bool IsLoading() const = 0; - - virtual size_t InstanceCount() const = 0; - - virtual bool BeginInstance(void* pInstance) = 0; - virtual bool SetValue(const char* name, IExchangeValue& value) = 0; - virtual IExchangeValue* GetValue(const char* name, void* pTarget, size_t targetSize) = 0; - // - - template - void Visit(const char* name, T& instance); - - template - void Visit(const char* name, T (&arr)[S]); -}; - -template -void IExchanger::Visit(const char* name, T& value) -{ - if (IsLoading()) - { - IExchangeValue* pValue = GetValue(name, &value, sizeof(value)); - if (pValue) - { - ExchangeValue* pTypedValue = static_cast*>(pValue); - value = pTypedValue->m_value; - } - } - else // Saving - { - // If this member is stored - if (SetValue(name, ExchangeValue(value))) - { - // Set the original value to the default state (to allow safe destruction) - DefaultInitialize(value); - } - } -} - -template -void IExchanger::Visit(const char* name, T (&arr)[S]) -{ - if (IsLoading()) - { - IExchangeValue* pValue = GetValue(name, &arr, sizeof(arr)); - if (pValue) - { - ExchangeArray* pTypedArray = static_cast*>(pValue); - // TODO: Accommodate array resizing? Complex however... - for (size_t i = 0; i < S; ++i) - { - arr[i] = pTypedArray->m_array[i]; - } - } - } - else // Saving - { - // If this member is stored - if (SetValue(name, ExchangeArray(arr))) - { - T defaultValue; - DefaultInitialize(defaultValue); - - // Set the original value to the default value (to allow safe destruction) - for (size_t i = 0; i < S; ++i) - { - arr[i] = defaultValue; - } - } - } -} - -struct InstanceTracker; - -struct ITypeRegistrar -{ - // - virtual ~ITypeRegistrar() {} - - virtual const char* GetName() const = 0; - - // Creates an instance of the type - virtual void* CreateInstance() = 0; - // - -#ifdef SOFTCODE_ENABLED - // How many active instances exist of this type? - virtual size_t InstanceCount() const = 0; - // Used to remove a tracked instance from the Registrar - virtual void RemoveInstance(InstanceTracker* pTracker) = 0; - // Exchanges the instance state with the given exchanger data set - virtual bool ExchangeInstances(IExchanger& exchanger) = 0; - // Destroys all tracked instances of this type - virtual bool DestroyInstances() = 0; - // Returns true if pInstance is of this type (linear search) - virtual bool HasInstance(void* pInstance) const = 0; -#endif -}; - -struct ITypeLibrary -{ - // - virtual ~ITypeLibrary() {} - - virtual const char* GetName() = 0; - virtual void* CreateInstanceVoid(const char* typeName) = 0; - // - -#ifdef SOFTCODE_ENABLED - virtual void SetOverride(ITypeLibrary* pOverrideLib) = 0; - - // Fills in the supplied type list if large enough, and sets count to number of types - virtual size_t GetTypes(ITypeRegistrar** ppRegistrar, size_t& count) const = 0; -#endif -}; - -struct ISoftCodeListener -{ - // - virtual ~ISoftCodeListener() {} - - // Called when an instance is replaced to allow managing systems to fixup pointers - virtual void InstanceReplaced(void* pOldInstance, void* pNewInstance) = 0; - // -}; - -/// Interface for ... -struct ISoftCodeMgr -{ - // - virtual ~ISoftCodeMgr() {} - - // Used to register built-in libraries on first use - virtual void RegisterLibrary(ITypeLibrary* pLib) = 0; - - // Loads any new SoftCode modules - virtual void LoadNewModules() = 0; - - virtual void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName) = 0; - virtual void RemoveListener(const char* libraryName, ISoftCodeListener* pListener) = 0; - - // To be called regularly to poll for library updates - virtual void PollForNewModules() = 0; - - // Stops thread execution until a new SoftCode instance is available - virtual void* WaitForUpdate(void* pInstance) = 0; - - /// Frees this instance from memory - //virtual void Release() = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H diff --git a/Code/CryEngine/CryCommon/IStreamEngine.h b/Code/CryEngine/CryCommon/IStreamEngine.h index f325eec389..0536e1f486 100644 --- a/Code/CryEngine/CryCommon/IStreamEngine.h +++ b/Code/CryEngine/CryCommon/IStreamEngine.h @@ -34,7 +34,6 @@ #include #include "smartptr.h" -#include // <> required for Interfuscator #include "CryThread.h" #include "IStreamEngineDefs.h" diff --git a/Code/CryEngine/CryCommon/ISystem.h b/Code/CryEngine/CryCommon/ISystem.h index 86c2b57464..4c6bd73b61 100644 --- a/Code/CryEngine/CryCommon/ISystem.h +++ b/Code/CryEngine/CryCommon/ISystem.h @@ -49,19 +49,15 @@ #include // <> required for Interfuscator #include "CryVersion.h" #include "smartptr.h" -#include // <> required for Interfuscator #include // shared_ptr #include struct ISystem; struct ILog; -struct IProfileLogSystem; namespace AZ::IO { struct IArchive; } -struct IKeyboard; -struct IMouse; struct IConsole; struct IRemoteConsole; struct IRenderer; @@ -79,29 +75,21 @@ struct SFileVersion; struct INameTable; struct ILevelSystem; struct IViewSystem; -struct IMaterialEffects; -class IOpticsManager; class ICrySizer; class IXMLBinarySerializer; struct IReadWriteXMLSink; -struct IThreadTaskManager; struct IResourceManager; struct ITextModeConsole; struct IAVI_Reader; class CPNoise3; -struct IVisualLog; struct ILocalizationManager; -struct ISoftCodeMgr; struct IZLibCompressor; struct IZLibDecompressor; struct ILZ4Decompressor; class IZStdDecompressor; struct IOutputPrintSink; -struct IThreadManager; struct IWindowMessageHandler; struct IImageHandler; -class IResourceCompilerHelper; -class ILmbrAWS; namespace AZ { @@ -111,12 +99,6 @@ namespace AZ } } -class IResourceCompilerHelper; - -namespace Serialization { - struct IArchiveHost; -} - typedef void* WIN_HWND; class CCamera; @@ -124,39 +106,13 @@ struct CLoadingTimeProfiler; class ICmdLine; -struct INotificationNetwork; class ILyShine; -namespace JobManager { - struct IJobManager; -} - -#define PROC_MENU 1 -#define PROC_3DENGINE 2 - -// Summary: -// IDs for script userdata typing. -// Remarks: -// Maybe they should be moved into the game.dll . -//##@{ -#define USER_DATA_SOUND 1 -#define USER_DATA_TEXTURE 2 -#define USER_DATA_OBJECT 3 -#define USER_DATA_LIGHT 4 -#define USER_DATA_BONEHANDLER 5 -#define USER_DATA_POINTER 6 -//##@} - enum ESystemUpdateFlags { - ESYSUPDATE_IGNORE_PHYSICS = 0x0002, // Summary: // Special update mode for editor. - ESYSUPDATE_EDITOR = 0x0004, - ESYSUPDATE_MULTIPLAYER = 0x0008, - ESYSUPDATE_EDITOR_AI_PHYSICS = 0x0010, - ESYSUPDATE_EDITOR_ONLY = 0x0020, - ESYSUPDATE_UPDATE_VIEW_ONLY = 0x0040 + ESYSUPDATE_EDITOR = 0x0004 }; // Description: @@ -189,29 +145,6 @@ enum ESystemConfigPlatform END_CONFIG_PLATFORM_ENUM, // MUST BE LAST VALUE. USED FOR ERROR CHECKING. }; -enum ESubsystem -{ - ESubsys_3DEngine = 0, - ESubsys_AI = 1, - ESubsys_Physics = 2, - ESubsys_Renderer = 3, - ESubsys_Script = 4 -}; - -// Summary: -// Collates cycles taken per update. -struct sUpdateTimes -{ - uint32 PhysYields; - uint64 SysUpdateTime; - uint64 PhysStepTime; - uint64 RenderTime; - //extended yimes info - uint64 physWaitTime; - uint64 streamingWaitTime; - uint64 animationWaitTime; -}; - enum ESystemGlobalState { ESYSTEM_GLOBAL_STATE_UNKNOWN, @@ -568,33 +501,6 @@ struct IErrorObserver // }; -enum ESystemProtectedFunctions -{ - eProtectedFunc_Save = 0, - eProtectedFunc_Load = 1, - eProtectedFuncsLast = 10, -}; - -struct SCvarsDefault -{ - SCvarsDefault() - { - sz_r_DriverDef = NULL; - } - - const char* sz_r_DriverDef; -}; - -#if defined(CVARS_WHITELIST) -struct ICVarsWhitelist -{ - // - virtual ~ICVarsWhitelist() {}; - virtual bool IsWhiteListed(const string& command, bool silent) = 0; - // -}; -#endif // defined(CVARS_WHITELIST) - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION ISYSTEM_H_SECTION_3 #include AZ_RESTRICTED_FILE(ISystem_h) @@ -616,9 +522,6 @@ struct SSystemInitParams { void* hInstance; // void* hWnd; // - void* hWndForInputSystem; // the HWND for the input devices, distinct from the hWnd, which the rendering system overrides anyways - - bool remoteResourceCompiler; ILog* pLog; // You can specify your own ILog to be used by System. ILogCallback* pLogCallback; // You can specify your own ILogCallback to be added on log creation (used by Editor). @@ -633,33 +536,14 @@ struct SSystemInitParams bool bPreview; // When running in Preview mode (Minimal initialization). bool bTestMode; // When running in Automated testing mode. bool bDedicatedServer; // When running a dedicated server. - bool bExecuteCommandLine; // can be switched of to suppress the feature or do it later during the initialization. - bool bSkipFont; // Don't load CryFont.dll bool bSkipConsole; // Don't create console - bool bSkipNetwork; // Don't create Network - bool bSkipWebsocketServer; // Don't create the WebSocket server - bool bMinimal; // Don't load banks - bool bTesting; // CryUnit - bool bNoRandom; //use fixed generator init/seed bool bUnattendedMode; // When running as part of a build on build-machines: Prevent popping up of any dialog bool bSkipMovie; // Don't load movie - bool bSkipAnimation; // Don't load animation bool bToolMode; // System is running inside a tool. Will not create USER directory or anything else that the game needs to do - bool bSkipPhysics; // Don't initialize CryPhysics. - ISystem* pSystem; // Pointer to existing ISystem interface, it will be reused if not NULL. - typedef void* (*ProtectedFunction)(void* param1, void* param2); - ProtectedFunction pProtectedFunctions[eProtectedFuncsLast]; // Protected functions. - - SCvarsDefault* pCvarsDefault; // to override the default value of some cvar - -#if defined(CVARS_WHITELIST) - ICVarsWhitelist* pCVarsWhitelist; // CVars whitelist callback -#endif // defined(CVARS_WHITELIST) - SharedEnvironmentInstance* pSharedEnvironment; // Summary: @@ -668,16 +552,10 @@ struct SSystemInitParams { hInstance = NULL; hWnd = NULL; - hWndForInputSystem = NULL; - - remoteResourceCompiler = false; pLog = NULL; pLogCallback = NULL; pUserCallback = NULL; -#if defined(CVARS_WHITELIST) - pCVarsWhitelist = NULL; -#endif // defined(CVARS_WHITELIST) sLogFileName = NULL; autoBackupLogs = true; pValidator = NULL; @@ -688,32 +566,13 @@ struct SSystemInitParams bPreview = false; bTestMode = false; bDedicatedServer = false; - bExecuteCommandLine = true; - bExecuteCommandLine = true; - bSkipFont = false; bSkipConsole = false; - bSkipNetwork = false; -#if defined(WIN32) || defined(WIN64) - // create websocket server by default. bear in mind that USE_HTTP_WEBSOCKETS is not defined in release. - bSkipWebsocketServer = false; -#else - // CTCPStreamSocket only seems to fully support Win32 and 64 - bSkipWebsocketServer = true; -#endif - bMinimal = false; - bTesting = false; - bNoRandom = false; bUnattendedMode = false; bSkipMovie = false; - bSkipAnimation = false; bToolMode = false; - bSkipPhysics = false; pSystem = NULL; - memset(pProtectedFunctions, 0, sizeof(pProtectedFunctions)); - pCvarsDefault = NULL; - pSharedEnvironment = nullptr; } }; @@ -782,8 +641,6 @@ struct SSystemGlobalEnvironment { AZ::IO::IArchive* pCryPak; AZ::IO::FileIOBase* pFileIO; - IProfileLogSystem* pProfileLogSystem; - IOpticsManager* pOpticsManager; ITimer* pTimer; ICryFont* pCryFont; ::IConsole* pConsole; @@ -791,81 +648,27 @@ struct SSystemGlobalEnvironment ILog* pLog; IMovieSystem* pMovieSystem; INameTable* pNameTable; - IVisualLog* pVisualLog; IRenderer* pRenderer; - IMaterialEffects* pMaterialEffects; - ISoftCodeMgr* pSoftCodeMgr; ILyShine* pLyShine; - IResourceCompilerHelper* pResourceCompilerHelper; SharedEnvironmentInstance* pSharedEnvironment; - IThreadManager* pThreadManager; #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION ISYSTEM_H_SECTION_4 #include AZ_RESTRICTED_FILE(ISystem_h) #endif - ISystemScheduler* pSystemScheduler; - threadID mMainThreadId; //The main thread ID is used in multiple systems so should be stored globally - ////////////////////////////////////////////////////////////////////////// - uint32 nMainFrameID; - - ////////////////////////////////////////////////////////////////////////// - const char* szCmdLine; // Startup command line. - - ////////////////////////////////////////////////////////////////////////// - // Generic debug string which can be easily updated by any system and output by the debug handler - enum - { - MAX_DEBUG_STRING_LENGTH = 128 - }; - char szDebugStatus[MAX_DEBUG_STRING_LENGTH]; - - ////////////////////////////////////////////////////////////////////////// - // Used to tell if this is a server/multiplayer instance - bool bServer; - bool bMultiplayer; - bool bHostMigrating; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Indicate Editor status. - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // Used by CRY_ASSERT bool bIgnoreAllAsserts; bool bNoAssertDialog; - bool bTesting; ////////////////////////////////////////////////////////////////////////// - bool bNoRandomSeed; - - SPlatformInfo pi; - - // Protected functions. - SSystemInitParams::ProtectedFunction pProtectedFunctions[eProtectedFuncsLast]; // Protected functions. - - ////////////////////////////////////////////////////////////////////////// - // Flag to able to print out of memory conditon - bool bIsOutOfMemory; - bool bIsOutOfVideoMemory; - bool bToolMode; int retCode = 0; - ILINE const bool IsClient() const - { -#if defined(CONSOLE) - return true; -#else - return bClient; -#endif - } - ILINE const bool IsDedicated() const { #if defined(CONSOLE) @@ -895,11 +698,6 @@ struct SSystemGlobalEnvironment { bDedicated = isDedicated; } - - ILINE void SetIsClient(bool isClient) - { - bClient = isClient; - } #endif //this way the compiler can strip out code for consoles @@ -939,26 +737,6 @@ struct SSystemGlobalEnvironment #endif } - ILINE const bool IsFMVPlaying() const - { - return m_isFMVPlaying; - } - - ILINE void SetFMVIsPlaying(const bool isPlaying) - { - m_isFMVPlaying = isPlaying; - } - - ILINE const bool IsCutscenePlaying() const - { - return m_isCutscenePlaying; - } - - ILINE void SetCutsceneIsPlaying(const bool isPlaying) - { - m_isCutscenePlaying = isPlaying; - } - ILINE bool IsInToolMode() const { return bToolMode; @@ -969,35 +747,17 @@ struct SSystemGlobalEnvironment bToolMode = bNewToolMode; } - ILINE void SetDynamicMergedMeshGenerationEnabled(bool mmgenEnable) - { - m_bDynamicMergedMeshGenerationEnabled = mmgenEnable; - } - - ILINE const bool IsDynamicMergedMeshGenerationEnabled() const - { - return m_bDynamicMergedMeshGenerationEnabled; - } - #if !defined(CONSOLE) private: - bool bClient; bool bEditor; // Engine is running under editor. bool bEditorGameMode; // Engine is in editor game mode. bool bEditorSimulationMode; // Engine is in editor simulation mode. bool bDedicated; // Engine is in dedicated #endif - bool m_isFMVPlaying; - bool m_isCutscenePlaying; - bool m_bDynamicMergedMeshGenerationEnabled; - public: SSystemGlobalEnvironment() - : pSystemScheduler(nullptr) - , szCmdLine("") - , bToolMode(false) - , m_bDynamicMergedMeshGenerationEnabled(false) + : bToolMode(false) { }; }; @@ -1035,37 +795,11 @@ struct IProfilingSystem // Initialize and dispatch all engine's subsystems. struct ISystem { - struct ILoadingProgressListener - { - // - virtual ~ILoadingProgressListener() {} - virtual void OnLoadingProgress(int steps) = 0; - // - }; - -#ifndef _RELEASE - enum LevelLoadOrigin - { - eLLO_Unknown, - eLLO_NewLevel, - eLLO_Level2Level, - eLLO_Resumed, - eLLO_MapCmd, - }; - - struct ICheckpointData - { - int m_totalLoads; - LevelLoadOrigin m_loadOrigin; - }; -#endif - // virtual ~ISystem() {} // Summary: // Releases ISystem. virtual void Release() = 0; - virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const = 0; // will return NULL if no whitelisting // Summary: // Returns pointer to the global environment structure. @@ -1094,9 +828,6 @@ struct ISystem virtual void DoWorkDuringOcclusionChecks() = 0; virtual bool NeedDoWorkDuringOcclusionChecks() = 0; - //! Update screen and call some important tick functions during loading. - virtual void SynchronousLoadingTick(const char* pFunc, int line) = 0; - // Summary: // Returns the current used memory. virtual uint32 GetUsedMemory() = 0; @@ -1170,7 +901,6 @@ struct ISystem virtual IZLibDecompressor* GetIZLibDecompressor() = 0; virtual ILZ4Decompressor* GetLZ4Decompressor() = 0; virtual IZStdDecompressor* GetZStdDecompressor() = 0; - virtual INotificationNetwork* GetINotificationNetwork() = 0; virtual IViewSystem* GetIViewSystem() = 0; virtual ILevelSystem* GetILevelSystem() = 0; virtual INameTable* GetINameTable() = 0; @@ -1187,24 +917,10 @@ struct ISystem // Returns: // Can be NULL, because it only exists when running through the editor, not in pure game mode. virtual IResourceManager* GetIResourceManager() = 0; - virtual IThreadTaskManager* GetIThreadTaskManager() = 0; virtual IProfilingSystem* GetIProfilingSystem() = 0; virtual ISystemEventDispatcher* GetISystemEventDispatcher() = 0; - virtual IVisualLog* GetIVisualLog() = 0; virtual ITimer* GetITimer() = 0; - virtual IThreadManager* GetIThreadManager() = 0; - - virtual void SetLoadingProgressListener(ILoadingProgressListener* pListener) = 0; - virtual ISystem::ILoadingProgressListener* GetLoadingProgressListener() const = 0; - - // Summary: - // Game is created after System init, so has to be set explicitly. - virtual void SetIMaterialEffects(IMaterialEffects* pMaterialEffects) = 0; - virtual void SetIOpticsManager(IOpticsManager* pOpticsManager) = 0; - virtual void SetIVisualLog(IVisualLog* pVisualLog) = 0; - - //virtual const char *GetGamePath()=0; virtual void DebugStats(bool checkpoint, bool leaks) = 0; virtual void DumpWinHeaps() = 0; @@ -1219,7 +935,6 @@ struct ISystem virtual bool WasInDevMode() const = 0; virtual bool IsDevMode() const = 0; virtual bool IsMODValid(const char* szMODName) const = 0; - virtual bool IsMinimalMode() const = 0; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -1334,12 +1049,6 @@ struct ISystem // Detects and set optimal spec. virtual void AutoDetectSpec(bool detectResolution) = 0; - // Summary: - // Thread management for subsystems - // Return Value: - // Non-0 if the state was indeed changed, 0 if already in that state. - virtual int SetThreadState(ESubsystem subsys, bool bActive) = 0; - // Summary: // Query if system is now paused. // Pause flag is set when calling system update with pause mode. @@ -1406,14 +1115,6 @@ struct ISystem // Get log index of the currently running Open 3D Engine application. (0 = first instance, 1 = second instance, etc) virtual int GetApplicationLogInstance(const char* logFilePath) = 0; - // Summary: - // Retrieves the current stats for systems to update the respective time taken - virtual sUpdateTimes& GetCurrentUpdateTimeStats() = 0; - - // Summary: - // Retrieves the array of update times and the number of entries - virtual const sUpdateTimes* GetUpdateTimeStats(uint32&, uint32&) = 0; - // Summary: // Clear all currently logged and drawn on screen error messages virtual void ClearErrorMessages() = 0; @@ -1458,17 +1159,6 @@ struct ISystem virtual void AsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync) = 0; // - -#if defined(CVARS_WHITELIST) - virtual ICVarsWhitelist* GetCVarsWhiteList() const = 0; -#endif // defined(CVARS_WHITELIST) - -#ifndef _RELEASE - virtual void GetCheckpointData(ICheckpointData& data) = 0; - virtual void IncreaseCheckpointLoadCount() = 0; - virtual void SetLoadOrigin(LevelLoadOrigin origin) = 0; -#endif - #if !defined(_RELEASE) virtual bool IsSavingResourceList() const = 0; #endif @@ -1513,11 +1203,6 @@ struct ISystem using CrySystemNotificationBus = AZ::EBus; }; -//JAT - this is a very important function for the dedicated server - it lets us run >1000 players per piece of server hardware -//JAT - this saves us lots of money on the dedicated server hardware -#define SYNCHRONOUS_LOADING_TICK() do { if (gEnv && gEnv->pSystem) {gEnv->pSystem->SynchronousLoadingTick(__FUNC__, __LINE__); } \ -} while (0) - #if defined(USE_DISK_PROFILER) struct DiskOperationInfo @@ -1594,7 +1279,7 @@ typedef ISystem* (*PFNCREATESYSTEMINTERFACE)(SSystemInitParams& initParams); ////////////////////////////////////////////////////////////////////////// // Global environment variable. ////////////////////////////////////////////////////////////////////////// -extern SC_API SSystemGlobalEnvironment* gEnv; +extern SSystemGlobalEnvironment* gEnv; // Summary: @@ -1613,11 +1298,6 @@ inline ISystem* GetISystem() } return systemInterface; }; - -inline ISystemScheduler* GetISystemScheduler(void) -{ - return gEnv->pSystemScheduler; -}; ////////////////////////////////////////////////////////////////////////// // Description: @@ -1640,7 +1320,6 @@ void* GetDetachEnvironmentSymbol(); extern bool g_bProfilerEnabled; -extern int g_iTraceAllocations; // Summary: // Interface of the DLL. diff --git a/Code/CryEngine/CryCommon/ISystemScheduler.h b/Code/CryEngine/CryCommon/ISystemScheduler.h deleted file mode 100644 index 9280eb2ea6..0000000000 --- a/Code/CryEngine/CryCommon/ISystemScheduler.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H -#define CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H -#pragma once - -#if defined(__cplusplus) -#define SLICE_AND_SLEEP() do { if (GetISystemScheduler()) { GetISystemScheduler()->SliceAndSleep(__FUNC__, __LINE__); } \ -} while (0) -#define SLICE_SCOPE_DEFINE() CSliceLoadingMonitor sliceScope -#else -extern void SliceAndSleep(const char* pFunc, int line); -#define SLICE_AND_SLEEP() SliceAndSleep(__FILE__, __LINE__) -#endif - -struct ISystemScheduler -{ - virtual ~ISystemScheduler(){} - - // - // Map load slicing functionality support - virtual void SliceAndSleep(const char* sliceName, int line) = 0; - virtual void SliceLoadingBegin() = 0; - virtual void SliceLoadingEnd() = 0; - - virtual void SchedulingSleepIfNeeded(void) = 0; - // -}; - -ISystemScheduler* GetISystemScheduler(void); - -class CSliceLoadingMonitor -{ -public: - CSliceLoadingMonitor() - { - if (GetISystemScheduler()) - { - GetISystemScheduler()->SliceLoadingBegin(); - } - } - - ~CSliceLoadingMonitor() - { - if (GetISystemScheduler()) - { - GetISystemScheduler()->SliceLoadingEnd(); - } - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H diff --git a/Code/CryEngine/CryCommon/IThreadManager.h b/Code/CryEngine/CryCommon/IThreadManager.h deleted file mode 100644 index 448e3eec16..0000000000 --- a/Code/CryEngine/CryCommon/IThreadManager.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -class IThreadConfigManager; - -enum EJoinMode -{ - eJM_TryJoin, - eJM_Join, -}; - -class IThread -{ -public: - // - virtual ~IThread() - { - } - - //! Entry functions for code executed on thread. - virtual void ThreadEntry() = 0; - // -}; - -enum EFPE_Severity -{ - eFPE_None, //!< No Floating Point Exceptions. - eFPE_Basic, //!< Invalid operation, Div by 0. - eFPE_All, //!< Invalid operation, Div by 0, Denormalized operand, Overflow, Underflow, Inexact. - eFPE_LastEntry -}; - -//temp disable CRY DX12 -//#define SCOPED_ENABLE_FLOAT_EXCEPTIONS(eFPESeverity) CScopedFloatingPointException scopedSetFloatExceptionMask(eFPESeverity) -//#define SCOPED_DISABLE_FLOAT_EXCEPTIONS() CScopedFloatingPointException scopedSetFloatExceptionMask(eFPE_None) - -struct IThreadManager -{ -public: - // - virtual ~IThreadManager() - { - } - - //! Get thread config manager. - virtual IThreadConfigManager* GetThreadConfigManager() = 0; - - //! Spawn a new thread and apply thread config settings at thread beginning. - virtual bool SpawnThread(IThread* pThread, const char* sThreadName, ...) = 0; - - //! Wait on another thread to exit (Blocking). - //! Use eJM_TryJoin if you cannot be sure that the target thread is awake. - //! \retval true if target thread has not been started yet or has already exited. - //! \retval false if target thread is still running and therefore not in a state to exit. - virtual bool JoinThread(IThread* pThreadTask, EJoinMode joinStatus) = 0; - - //! Register 3rd party thread with the thread manager. - //! Applies thread config for thread if found. - //! \param pThreadHandle If NULL, the current thread handle will be used. - virtual bool RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...) = 0; - - //! Unregister 3rd party thread with the thread manager. - virtual bool UnRegisterThirdPartyThread(const char* sThreadName, ...) = 0; - - //! Get Thread Name. - //! Returns "" if thread not found. - virtual const char* GetThreadName(threadID nThreadId) = 0; - - //! Get ThreadID. - virtual threadID GetThreadId(const char* sThreadName, ...) = 0; - - //! Execute function for each other thread but this one. - typedef void (* ThreadModifFunction)(threadID nThreadId, void* pData); - virtual void ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData = 0) = 0; - - virtual void EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId = 0) = 0; - virtual void EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity) = 0; - - virtual uint GetFloatingPointExceptionMask() = 0; - virtual void SetFloatingPointExceptionMask(uint nMask) = 0; - // -}; -/*TEMP DISABLE CRY DX12 -class CScopedFloatingPointException -{ -public: - CScopedFloatingPointException(EFPE_Severity eFPESeverity) - { - oldMask = gEnv->pThreadManager->GetFloatingPointExceptionMask(); - gEnv->pThreadManager->EnableFloatExceptions(eFPESeverity); - } - ~CScopedFloatingPointException() - { - gEnv->pThreadManager->SetFloatingPointExceptionMask(oldMask); - } -private: - uint oldMask; -}; -*/ diff --git a/Code/CryEngine/CryCommon/IThreadTask.h b/Code/CryEngine/CryCommon/IThreadTask.h deleted file mode 100644 index d4a565fcff..0000000000 --- a/Code/CryEngine/CryCommon/IThreadTask.h +++ /dev/null @@ -1,166 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "BitFiddling.h" - -#ifndef CRYINCLUDE_CRYCOMMON_ITHREADTASK_H -#define CRYINCLUDE_CRYCOMMON_ITHREADTASK_H -#pragma once - -#include - -// forward declarations -struct SThreadTaskInfo; - -enum EThreadTaskFlags -{ - THREAD_TASK_BLOCKING = BIT(0), // Blocking tasks will be allocated on their own thread. - THREAD_TASK_ASSIGN_TO_POOL = BIT(1), // Task can be assigned to any thread in the group of threads -}; - -class IThreadTask_Thread -{ -public: - // - virtual ~IThreadTask_Thread() {}; - virtual void AddTask(SThreadTaskInfo* pTaskInfo) = 0; - virtual void RemoveTask(SThreadTaskInfo* pTaskInfo) = 0; - virtual void RemoveAllTasks() = 0; - virtual void SingleUpdate() = 0; - // -}; - -typedef int ThreadPoolHandle; - -struct SThreadTaskParams -{ - uint32 nFlags; // Task flags. @see ETaskFlags - union - { - int nPreferedThread; // Preferred Thread index (0,1,2,3...) - ThreadPoolHandle nThreadsGroupId; // Id of group of threads(useful only if THREAD_TASK_ASSIGN_TO_POOL is set) - }; - int16 nPriorityOff; // If THREAD_TASK_BLOCKING, this will adjust the priority of the thread - int16 nStackSizeKB; // If THREAD_TASK_BLOCKING, this will adjust the stack size of the thread - const char* name; // Name for this task (thread for the blocking task will be named using this string) - - SThreadTaskParams() - : nFlags(0) - , nPreferedThread(-1) - , nPriorityOff(0) - , name("") - , nStackSizeKB(SIMPLE_THREAD_STACK_SIZE_KB) {} -}; - -////////////////////////////////////////////////////////////////////////// -// Tasks must implement this interface. -////////////////////////////////////////////////////////////////////////// -struct IThreadTask -{ - // - // The function to be called on every update for non bocking tasks. - // Or will be called only once for the blocking threads. - virtual void OnUpdate() = 0; - - // Called to indicate that this task must quit. - // Warning! can be called from different thread then OnUpdate call. - virtual void Stop() = 0; - - // Returns task info - virtual struct SThreadTaskInfo* GetTaskInfo() = 0; - - virtual ~IThreadTask() {} - // -}; - -struct SThreadTaskInfo - : public CMultiThreadRefCount -{ - IThreadTask_Thread* m_pThread; - IThreadTask* m_pTask; - SThreadTaskParams m_params; - - SThreadTaskInfo() - : m_pThread(NULL) - , m_pTask(NULL) { m_params.nFlags = 0; m_params.nPreferedThread = -1; } -}; - -// Might be changed to uint64 etc in the future -typedef uint32 ThreadPoolAffinityMask; -#define INVALID_AFFINITY 0 - -////////////////////////////////////////////////////////////////////////// -// Description of thread pool to create -////////////////////////////////////////////////////////////////////////// -struct ThreadPoolDesc -{ - ThreadPoolAffinityMask AffinityMask; // number of bits means number of threads. affinity overlapping is prohibited - string sPoolName; - int32 nThreadPriority; - int32 nThreadStackSizeKB; - - ThreadPoolDesc() - : AffinityMask(INVALID_AFFINITY) - , sPoolName("UnnamedPool") - , nThreadPriority(-1) - , nThreadStackSizeKB(-1) { } - - ILINE bool CreateThread(ThreadPoolAffinityMask affinityMask) - { - if (this->AffinityMask & affinityMask) - { - return false; - } - - this->AffinityMask |= affinityMask; - return true; - } - - ILINE uint32 GetThreadCount() const - { - return CountBits(AffinityMask); - } -}; - -////////////////////////////////////////////////////////////////////////// -// Task manager. -////////////////////////////////////////////////////////////////////////// -struct IThreadTaskManager -{ - // - virtual ~IThreadTaskManager(){} - // Register new task to the manager. - virtual void RegisterTask(IThreadTask* pTask, const SThreadTaskParams& options) = 0; - virtual void UnregisterTask(IThreadTask* pTask) = 0; - - // Limit number of threads to this amount. - virtual void SetMaxThreadCount(int nMaxThreads) = 0; - - // Create a pool of threads - virtual ThreadPoolHandle CreateThreadsPool(const ThreadPoolDesc& desc) = 0; - virtual const bool DestroyThreadsPool(const ThreadPoolHandle& handle) = 0; - virtual const bool GetThreadsPoolDesc(const ThreadPoolHandle handle, ThreadPoolDesc* pDesc) const = 0; - virtual const bool SetThreadsPoolAffinity(const ThreadPoolHandle handle, const ThreadPoolAffinityMask AffinityMask) = 0; - - virtual void SetThreadName(threadID dwThreadId, const char* sThreadName) = 0; - virtual const char* GetThreadName(threadID dwThreadId) = 0; - - // Return thread handle by thread name - virtual threadID GetThreadByName(const char* sThreadName) = 0; - - // if bMark=true the calling thread will dump its stack during crashes - virtual void MarkThisThreadForDebugging(const char* name, bool bDump) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ITHREADTASK_H diff --git a/Code/CryEngine/CryCommon/Mocks/IRendererMock.h b/Code/CryEngine/CryCommon/Mocks/IRendererMock.h index 7b0b7b76a2..74d072c48c 100644 --- a/Code/CryEngine/CryCommon/Mocks/IRendererMock.h +++ b/Code/CryEngine/CryCommon/Mocks/IRendererMock.h @@ -585,8 +585,6 @@ public: SDepthTexture * (int, int, bool)); MOCK_METHOD1(DestroyDepthSurface, void(SDepthTexture * pDepthSurf)); - MOCK_CONST_METHOD1(CreateOptics, - IOpticsElementBase * (EFlareType type)); MOCK_METHOD1(PauseTimer, void(bool bPause)); MOCK_METHOD0(CreateShaderPublicParams, diff --git a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h index 1e28937764..cfe150c1df 100644 --- a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h +++ b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h @@ -23,8 +23,6 @@ class SystemMock public: MOCK_METHOD0(Release, void()); - MOCK_CONST_METHOD0(GetCVarsWhiteListConfigSink, - ILoadConfigurationEntrySink * ()); MOCK_METHOD0(GetGlobalEnvironment, SSystemGlobalEnvironment * ()); MOCK_METHOD2(UpdatePreTickBus, @@ -37,8 +35,6 @@ public: void()); MOCK_METHOD0(NeedDoWorkDuringOcclusionChecks, bool()); - MOCK_METHOD2(SynchronousLoadingTick, - void(const char* pFunc, int line)); MOCK_METHOD0(RenderStatistics, void()); MOCK_METHOD0(GetUsedMemory, @@ -84,8 +80,6 @@ public: ILZ4Decompressor * ()); MOCK_METHOD0(GetZStdDecompressor, IZStdDecompressor * ()); - MOCK_METHOD0(GetINotificationNetwork, - INotificationNetwork * ()); MOCK_METHOD0(GetIViewSystem, IViewSystem * ()); MOCK_METHOD0(GetILevelSystem, @@ -116,28 +110,12 @@ public: IRemoteConsole * ()); MOCK_METHOD0(GetIResourceManager, IResourceManager * ()); - MOCK_METHOD0(GetIThreadTaskManager, - IThreadTaskManager * ()); MOCK_METHOD0(GetIProfilingSystem, IProfilingSystem * ()); MOCK_METHOD0(GetISystemEventDispatcher, ISystemEventDispatcher * ()); - MOCK_METHOD0(GetIVisualLog, - IVisualLog * ()); MOCK_METHOD0(GetITimer, ITimer * ()); - MOCK_METHOD0(GetIThreadManager, - IThreadManager * ()); - MOCK_METHOD1(SetLoadingProgressListener, - void(ILoadingProgressListener * pListener)); - MOCK_CONST_METHOD0(GetLoadingProgressListener, - ISystem::ILoadingProgressListener * ()); - MOCK_METHOD1(SetIMaterialEffects, - void(IMaterialEffects * pMaterialEffects)); - MOCK_METHOD1(SetIOpticsManager, - void(IOpticsManager * pOpticsManager)); - MOCK_METHOD1(SetIVisualLog, - void(IVisualLog * pVisualLog)); MOCK_METHOD2(DebugStats, void(bool checkpoint, bool leaks)); MOCK_METHOD0(DumpWinHeaps, @@ -154,8 +132,6 @@ public: bool()); MOCK_CONST_METHOD1(IsMODValid, bool(const char* szMODName)); - MOCK_CONST_METHOD0(IsMinimalMode, - bool()); MOCK_METHOD3(CreateXmlNode, XmlNodeRef(const char*, bool, bool)); MOCK_METHOD4(LoadXmlFromBuffer, @@ -209,8 +185,6 @@ public: void(ESystemConfigPlatform platform)); MOCK_METHOD1(AutoDetectSpec, void(bool detectResolution)); - MOCK_METHOD2(SetThreadState, - int(ESubsystem subsys, bool bActive)); MOCK_CONST_METHOD0(IsPaused, bool()); MOCK_METHOD0(GetLocalizationManager, @@ -239,10 +213,6 @@ public: int()); MOCK_METHOD1(GetApplicationLogInstance, int(const char* logFilePath)); - MOCK_METHOD0(GetCurrentUpdateTimeStats, - sUpdateTimes & ()); - MOCK_METHOD2(GetUpdateTimeStats, - const sUpdateTimes * (uint32 &, uint32 &)); MOCK_METHOD0(ClearErrorMessages, void()); MOCK_METHOD2(debug_GetCallStack, @@ -260,20 +230,6 @@ public: MOCK_METHOD5(AsyncMemcpy, void(void* dst, const void* src, size_t size, int nFlags, volatile int* sync)); -#if defined(CVARS_WHITELIST) - MOCK_CONST_METHOD0(GetCVarsWhiteList, - ICVarsWhitelist * ()); -#endif - -#ifndef _RELEASE - MOCK_METHOD1(GetCheckpointData, - void(ICheckpointData & data)); - MOCK_METHOD0(IncreaseCheckpointLoadCount, - void()); - MOCK_METHOD1(SetLoadOrigin, - void(LevelLoadOrigin origin)); -#endif - #if !defined(_RELEASE) MOCK_CONST_METHOD0(IsSavingResourceList, bool()); diff --git a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_enginesettings_mac_files.cmake b/Code/CryEngine/CryCommon/Platform/Mac/crycommon_enginesettings_mac_files.cmake deleted file mode 100644 index f862be24f6..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_enginesettings_mac_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../EngineSettingsBackendApple.cpp - ../../EngineSettingsBackendApple.h -) diff --git a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_enginesettings_windows_files.cmake b/Code/CryEngine/CryCommon/Platform/Windows/crycommon_enginesettings_windows_files.cmake deleted file mode 100644 index db9fd5b464..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_enginesettings_windows_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../EngineSettingsBackendWin32.cpp - ../../EngineSettingsBackendWin32.h -) diff --git a/Code/CryEngine/CryCommon/ProfileLog.h b/Code/CryEngine/CryCommon/ProfileLog.h deleted file mode 100644 index fbde619166..0000000000 --- a/Code/CryEngine/CryCommon/ProfileLog.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_PROFILELOG_H -#define CRYINCLUDE_CRYCOMMON_PROFILELOG_H -#pragma once - - -#include // <> required for Interfuscator -#include // <> required for Interfuscator - -struct ILogElement -{ - virtual ~ILogElement(){} - virtual ILogElement* Log (const char* name, const char* message) = 0; - virtual ILogElement* SetTime (float time) = 0; - virtual void Flush (stack_string& indent) = 0; -}; - -struct IProfileLogSystem -{ - virtual ~IProfileLogSystem(){} - virtual ILogElement* Log (const char* name, const char* msg) = 0; - virtual void SetTime (ILogElement* pElement, float time) = 0; - virtual void Release () = 0; -}; - -struct SHierProfileLogItem -{ - SHierProfileLogItem(const char* name, const char* msg, int inbDoLog) - : m_pLogElement(NULL) - , m_bDoLog(inbDoLog) - { - if (m_bDoLog) - { - m_pLogElement = gEnv->pProfileLogSystem->Log(name, msg); - m_startTime = gEnv->pTimer->GetAsyncTime(); - } - } - ~SHierProfileLogItem() - { - if (m_bDoLog) - { - CTimeValue endTime = gEnv->pTimer->GetAsyncTime(); - gEnv->pProfileLogSystem->SetTime(m_pLogElement, (endTime - m_startTime).GetMilliSeconds()); - } - } - -private: - int m_bDoLog; - CTimeValue m_startTime; - ILogElement* m_pLogElement; -}; - -#define HPROFILE_BEGIN(msg1, msg2, doLog) { SHierProfileLogItem __hier_profile_uniq_var_in_this_scope__(msg1, msg2, doLog); -#define HPROFILE_END() } - -#define HPROFILE(msg1, msg2, doLog) SHierProfileLogItem __hier_profile_uniq_var_in_this_scope__(msg1, msg2, doLog); - -#endif // CRYINCLUDE_CRYCOMMON_PROFILELOG_H diff --git a/Code/CryEngine/CryCommon/ProjectDefines.h b/Code/CryEngine/CryCommon/ProjectDefines.h index f82861d6e0..67ae58a324 100644 --- a/Code/CryEngine/CryCommon/ProjectDefines.h +++ b/Code/CryEngine/CryCommon/ProjectDefines.h @@ -78,9 +78,6 @@ typedef uint32 vtx_idx; #if defined(WIN32) || defined(WIN64) || LOG_CONST_CVAR_ACCESS #define RELEASE_LOGGING -//#if defined(_RELEASE) -//#define CVARS_WHITELIST -//#endif // defined(_RELEASE) #endif #if defined(_RELEASE) && !defined(RELEASE_LOGGING) @@ -181,32 +178,6 @@ typedef uint32 vtx_idx; #define SHADER_REFLECT_TEXTURE_SLOTS 0 #endif -#if (defined(WIN32) || defined(WIN64) || defined(AZ_PLATFORM_MAC)) && (!defined(AZ_MONOLITHIC_BUILD) || defined(RESOURCE_COMPILER)) -#define CRY_ENABLE_RC_HELPER 1 -#endif - -#if !defined(_RELEASE) && PROJECTDEFINES_H_TRAIT_ENABLE_SOFTCODE_SYSTEM - #define SOFTCODE_SYSTEM_ENABLED -#endif - -// Is SoftCoding enabled for this module? Usually set by the SoftCode AddIn in conjunction with a SoftCode.props file. -#ifdef SOFTCODE_ENABLED - -// Is this current compilation unit part of a SOFTCODE build? - #ifdef SOFTCODE -// Import any SC functions from the host module - #define SC_API __declspec(dllimport) - #else -// Export any SC functions from the host module - #define SC_API __declspec(dllexport) - #endif - -#else // SoftCode disabled - - #define SC_API - -#endif - // these enable and disable certain net features to give compatibility between PCs and consoles / profile and performance builds #define PC_CONSOLE_NET_COMPATIBLE 0 #define PROFILE_PERFORMANCE_NET_COMPATIBLE 0 @@ -292,10 +263,6 @@ typedef uint32 vtx_idx; # define ENABLE_LOADING_PROFILER // requires AZ_PROFILE_TELEMETRY to also be defined #endif -#if defined(SOFTCODE_ENABLED) - #error "SoftCode currently relies on CryMemoryManager being enabled. Either build without SoftCode support, or enable CryMemoryManager." -#endif - #if PROJECTDEFINES_H_TRAIT_USE_GPU_PARTICLES && !defined(NULL_RENDERER) #define GPU_PARTICLES 1 #else diff --git a/Code/CryEngine/CryCommon/ResourceCompilerHelper.cpp b/Code/CryEngine/CryCommon/ResourceCompilerHelper.cpp deleted file mode 100644 index 33373f7460..0000000000 --- a/Code/CryEngine/CryCommon/ResourceCompilerHelper.cpp +++ /dev/null @@ -1,639 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include "ProjectDefines.h" - -#if defined(CRY_ENABLE_RC_HELPER) - -#include "ResourceCompilerHelper.h" -#include "EngineSettingsManager.h" - -// When complining CryTiffPlugin the mayaAssert.h is included that defined -// Assert as _Assert. This wreaks havoc with AZ_Assert since under the covers -// it calls AzCore::Debug::Trace::Assert, which gets transformed bo -// Trace::_Assert, which does not exist. Gotta love macros. Undefine Assert -// before we include semaphore so that it can compile correctly -#if defined(Assert) -#undef Assert -#endif - -#include -#include -#include -#include -#include - -#if defined(AZ_PLATFORM_WINDOWS) -#include -#include // ShellExecuteW() -#endif - -#if AZ_TRAIT_OS_PLATFORM_APPLE -#include "AppleSpecific.h" -#include -#else -#undef RC_EXECUTABLE -#define RC_EXECUTABLE "rc.exe" -#endif - -#include -#include // lawsonn - we use std::string internally -#include - -namespace -{ - class LineStreamBuffer - { - public: - template - LineStreamBuffer(T* object, void (T::* method)(const char* line)) - : m_charCount(0) - , m_bTruncated(false) - { - m_target = new Target(object, method); - } - - ~LineStreamBuffer() - { - Flush(); - delete m_target; - } - - void HandleText(const char* text, int length) - { - const char* pos = text; - while (pos - text < length) - { - const char* start = pos; - - while (pos - text < length && *pos != '\n' && *pos != '\r') - { - ++pos; - } - - size_t n = pos - start; - if (m_charCount + n > kMaxCharCount) - { - n = kMaxCharCount - m_charCount; - m_bTruncated = true; - } - memcpy(&m_buffer[m_charCount], start, n); - m_charCount += n; - - if (pos - text < length) - { - Flush(); - while (pos - text < length && (*pos == '\n' || *pos == '\r')) - { - ++pos; - } - } - } - } - - void Flush() - { - if (m_charCount > 0) - { - m_buffer[m_charCount] = 0; - m_target->Call(m_buffer); - m_charCount = 0; - } - } - - bool IsTruncated() const - { - return m_bTruncated; - } - - private: - struct ITarget - { - virtual ~ITarget() {} - virtual void Call(const char* line) = 0; - }; - template - struct Target - : public ITarget - { - public: - Target(T* object, void (T::* method)(const char* line)) - : object(object) - , method(method) {} - virtual void Call(const char* line) - { - (object->*method)(line); - } - private: - T* object; - void (T::* method)(const char* line); - }; - - ITarget* m_target; - size_t m_charCount; - static const size_t kMaxCharCount = 2047; - char m_buffer[kMaxCharCount + 1]; - bool m_bTruncated; - }; - -#if !defined(AZ_PLATFORM_WINDOWS) - void MessageBoxW(int, const wchar_t* header, const wchar_t* message, unsigned long) - { -#if AZ_TRAIT_OS_PLATFORM_APPLE - CFStringEncoding encoding = (CFByteOrderLittleEndian == CFByteOrderGetCurrent()) ? - kCFStringEncodingUTF32LE : kCFStringEncodingUTF32BE; - CFStringRef header_ref = CFStringCreateWithBytes(nullptr, reinterpret_cast(header), wcslen(header) * sizeof(wchar_t), encoding, false); - CFStringRef message_ref = CFStringCreateWithBytes(nullptr, reinterpret_cast(message), wcslen(message) * sizeof(wchar_t), encoding, false); - - CFOptionFlags result; //result code from the message box - - CFUserNotificationDisplayAlert(0, kCFUserNotificationStopAlertLevel, 0, 0, 0, header_ref, message_ref, 0, 0, 0, &result); - - CFRelease(header_ref); - CFRelease(message_ref); -#endif - } -#endif -} - -namespace -{ - class RcLock - { - public: - RcLock() - : m_cs(0u, 1u) - { - m_cs.release(); - } - ~RcLock() - { - } - - void Lock() - { - m_cs.acquire(); - } - void Unlock() - { - m_cs.release(); - } - - private: - AZStd::semaphore m_cs; - }; - - - template - class RcAutoLock - { - public: - RcAutoLock(LockClass& lock) - : m_lock(lock) - { - m_lock.Lock(); - } - ~RcAutoLock() - { - m_lock.Unlock(); - } - - private: - RcAutoLock(); - RcAutoLock(const RcAutoLock&); - RcAutoLock& operator =(const RcAutoLock&); - - private: - LockClass& m_lock; - }; - - - HANDLE s_rcProcessHandle = 0; - RcLock s_rcProcessHandleLock; -} - -////////////////////////////////////////////////////////////////////////// -static void ShowMessageBoxRcNotFound([[maybe_unused]] const wchar_t* const szCmdLine, [[maybe_unused]] const wchar_t* const szDir) -{ - SettingsManagerHelpers::CFixedString tmp; - - tmp.append(L"The resource compiler (RC.EXE) was not found."); - MessageBoxW(0, tmp.c_str(), L"Error", MB_ICONERROR | MB_OK); -} - - -////////////////////////////////////////////////////////////////////////// -namespace -{ - class ResourceCompilerLineHandler - { - public: - ResourceCompilerLineHandler(IResourceCompilerListener* listener) - : m_listener(listener) - { - } - - void HandleLine(const char* line) - { - if (!m_listener || !line) - { - return; - } - - // check the first three characters to see if it's a warning or error. - bool bHasPrefix; - IResourceCompilerListener::MessageSeverity severity; - if ((line[0] == 'E') && (line[1] == ':') && (line[2] == ' ')) - { - bHasPrefix = true; - severity = IResourceCompilerListener::MessageSeverity_Error; - line += 3; // skip the prefix - } - else if ((line[0] == 'W') && (line[1] == ':') && (line[2] == ' ')) - { - bHasPrefix = true; - severity = IResourceCompilerListener::MessageSeverity_Warning; - line += 3; // skip the prefix - } - else if ((line[0] == ' ') && (line[1] == ' ') && (line[2] == ' ')) - { - bHasPrefix = true; - severity = IResourceCompilerListener::MessageSeverity_Info; - line += 3; // skip the prefix - } - else - { - bHasPrefix = false; - severity = IResourceCompilerListener::MessageSeverity_Info; - } - - if (bHasPrefix) - { - // skip thread info "%d>", if present - { - const char* p = line; - while (*p == ' ') - { - ++p; - } - if (isdigit(*p)) - { - while (isdigit(*p)) - { - ++p; - } - if (*p == '>') - { - line = p + 1; - } - } - } - - // skip time info "%d:%d", if present - { - const char* p = line; - while (*p == ' ') - { - ++p; - } - if (isdigit(*p)) - { - while (isdigit(*p)) - { - ++p; - } - if (*p == ':') - { - ++p; - if (isdigit(*p)) - { - while (isdigit(*p)) - { - ++p; - } - while (*p == ' ') - { - ++p; - } - line = p; - } - } - } - } - } - - m_listener->OnRCMessage(severity, line); - } - - private: - IResourceCompilerListener* m_listener; - }; - - // we now support macros like #ENGINEROOT# in the string: - void replaceAllInStringInPlace(std::string& inOut, const char* findValue, const char* replaceValue) - { - if (!findValue) - { - return; - } - - if (!replaceValue) - { - return; - } - - std::string::size_type pos = std::string::npos; - std::string::size_type replaceLen = strlen(findValue); - - while ((pos = inOut.find(findValue)) != std::string::npos) - { - inOut.replace(pos, replaceLen, replaceValue); - } - } - - // given a string that contains macros (like #ENGINEROOT#), eliminate the macros and replace them with the real data. - // note that in the 'remote' implementation, these macros are sent to the remote RC. It can then expand them for its own environment - // but in a local RC, these macros are expanded by the local environment. - void expandMacros(const char* inputString, char* outputString, std::size_t bufferSize) - { - if (!inputString) - { - return; - } - - if (!outputString) - { - return; - } - - AZStd::string_view rootFolder; - AZ::ComponentApplicationBus::BroadcastResult(rootFolder, &AZ::ComponentApplicationRequests::GetAppRoot); - - std::string finalString(inputString); - const AZStd::string rootFolderStr = rootFolder.data(); - replaceAllInStringInPlace(finalString, "#ENGINEROOT#", rootFolderStr.c_str()); - // put additional replacements here. - - azstrcpy(outputString, bufferSize, finalString.c_str()); - } -} - -////////////////////////////////////////////////////////////////////////// -IResourceCompilerHelper::ERcCallResult CResourceCompilerHelper::CallResourceCompiler( - const char* szFileName, - const char* szAdditionalSettings, - IResourceCompilerListener* listener, - bool bMayShowWindow, - bool bSilent, - bool bNoUserDialog, - const wchar_t* szWorkingDirectory, - [[maybe_unused]] const wchar_t* szRootPath) -{ -#if defined(AZ_PLATFORM_WINDOWS) - HANDLE hChildStdOutRd = INVALID_HANDLE_VALUE, hChildStdOutWr = INVALID_HANDLE_VALUE; - HANDLE hChildStdInRd = INVALID_HANDLE_VALUE, hChildStdInWr = INVALID_HANDLE_VALUE; - PROCESS_INFORMATION pi; -#else - FILE* hChildStdOutRd; -#endif - - { - RcAutoLock lock(s_rcProcessHandleLock); - - // make command for execution - SettingsManagerHelpers::CFixedString wRemoteCmdLine; - - - if (!szAdditionalSettings) - { - szAdditionalSettings = ""; - } - - // expand the additioanl settings. - char szActualFileName[512] = {0}; - char szActualAdditionalSettings[512] = {0}; - - expandMacros(szFileName, szActualFileName, 512); - expandMacros(szAdditionalSettings, szActualAdditionalSettings, 512); - - CSettingsManagerTools smTools = CSettingsManagerTools(); // moved this line to after macro expansion to avoid multiple of these existing at once. - - AZStd::string_view exeFolderName; - AZ::ComponentApplicationBus::BroadcastResult(exeFolderName, &AZ::ComponentApplicationRequests::GetExecutableFolder); - - wchar_t szRegSettingsBuffer[1024]; - smTools.GetEngineSettingsManager()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(szRegSettingsBuffer, sizeof(szRegSettingsBuffer))); - bool enableSourceControl = true; - smTools.GetEngineSettingsManager()->GetValueByRef("RC_EnableSourceControl", enableSourceControl); - - wRemoteCmdLine.appendAscii("\""); - wRemoteCmdLine.appendAscii(exeFolderName.data(), exeFolderName.size()); - wRemoteCmdLine.appendAscii("/"); - wRemoteCmdLine.appendAscii(RC_EXECUTABLE); - wRemoteCmdLine.appendAscii("\""); - - if (!enableSourceControl) - { - wRemoteCmdLine.appendAscii(" -nosourcecontrol "); - } - - if (!szFileName) - { - wRemoteCmdLine.appendAscii(" -userdialog=0 "); - wRemoteCmdLine.appendAscii(szActualAdditionalSettings); - wRemoteCmdLine.appendAscii(" "); - wRemoteCmdLine.append(szRegSettingsBuffer); - } - else - { - wRemoteCmdLine.appendAscii(" \""); - wRemoteCmdLine.appendAscii(szActualFileName); - wRemoteCmdLine.appendAscii("\""); - wRemoteCmdLine.appendAscii(bNoUserDialog ? " -userdialog=0 " : " -userdialog=1 "); - wRemoteCmdLine.appendAscii(szActualAdditionalSettings); - wRemoteCmdLine.appendAscii(" "); - wRemoteCmdLine.append(szRegSettingsBuffer); - } - - // Create a pipe to read the stdout of the RC. - SECURITY_ATTRIBUTES saAttr; - if (listener) - { -#if defined(AZ_PLATFORM_WINDOWS) - ZeroMemory(&saAttr, sizeof(saAttr)); - saAttr.bInheritHandle = TRUE; - saAttr.lpSecurityDescriptor = 0; - CreatePipe(&hChildStdOutRd, &hChildStdOutWr, &saAttr, 0); - SetHandleInformation(hChildStdOutRd, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN - CreatePipe(&hChildStdInRd, &hChildStdInWr, &saAttr, 0); - SetHandleInformation(hChildStdInWr, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN -#endif - } - -#if defined(AZ_PLATFORM_WINDOWS) - STARTUPINFOW si; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - si.dwX = 100; - si.dwY = 100; - if (listener) - { - si.hStdError = hChildStdOutWr; - si.hStdOutput = hChildStdOutWr; - si.hStdInput = hChildStdInRd; - si.dwFlags = STARTF_USEPOSITION | STARTF_USESTDHANDLES; - } - else - { - si.dwFlags = STARTF_USEPOSITION; - } - - ZeroMemory(&pi, sizeof(pi)); -#endif - - bool bShowWindow; - if (bMayShowWindow) - { - wchar_t buffer[20]; - smTools.GetEngineSettingsManager()->GetValueByRef("ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))); - bShowWindow = (wcscmp(buffer, L"true") == 0); - } - else - { - bShowWindow = false; - } - -#if defined(AZ_PLATFORM_WINDOWS) - const wchar_t* szStartingDirectory = szWorkingDirectory; - if (!szStartingDirectory) - { - char currentDirectory[MAX_PATH]; - AZ::Utils::GetExecutableDirectory(currentDirectory, MAX_PATH); - SettingsManagerHelpers::CFixedString wCurrentDirectory; - wCurrentDirectory.appendAscii(currentDirectory); - szStartingDirectory = wCurrentDirectory.c_str(); - } - - - if (!CreateProcessW( - NULL, // No module name (use command line). - const_cast(wRemoteCmdLine.c_str()), // Command line. - NULL, // Process handle not inheritable. - NULL, // Thread handle not inheritable. - TRUE, // Set handle inheritance to TRUE. - bShowWindow ? 0 : CREATE_NO_WINDOW, // creation flags. - NULL, // Use parent's environment block. - szStartingDirectory, // Set starting directory. - &si, // Pointer to STARTUPINFO structure. - &pi)) // Pointer to PROCESS_INFORMATION structure. - { - // The following code block is commented out instead of being deleted - // because it's good to have at hand for a debugging session. - #if 0 - const size_t charsInMessageBuffer = 32768; // msdn about FormatMessage(): "The output buffer cannot be larger than 64K bytes." - wchar_t szMessageBuffer[charsInMessageBuffer] = L""; - FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, szMessageBuffer, charsInMessageBuffer, NULL); - GetCurrentDirectoryW(charsInMessageBuffer, szMessageBuffer); - #endif - - if (!bSilent) - { - ShowMessageBoxRcNotFound(wRemoteCmdLine.c_str(), szStartingDirectory); - } - - return eRcCallResult_notFound; - } - - s_rcProcessHandle = pi.hProcess; -#else - int fd = open(".", O_RDONLY); - char remoteCmdLineUtf8[MAX_PATH * 8]; - char workingDirectory[MAX_PATH * 8]; - ConvertUtf16ToUtf8(wRemoteCmdLine.c_str(), SettingsManagerHelpers::CCharBuffer(remoteCmdLineUtf8, MAX_PATH * 8)); - if (szWorkingDirectory) - { - ConvertUtf16ToUtf8(szWorkingDirectory, SettingsManagerHelpers::CCharBuffer(workingDirectory, MAX_PATH * 8)); - chdir(workingDirectory); - } - hChildStdOutRd = popen(remoteCmdLineUtf8, "r"); - fchdir(fd); - if (hChildStdOutRd == nullptr) - { - if (!bSilent) - { - ShowMessageBoxRcNotFound(wRemoteCmdLine.c_str(), szWorkingDirectory); - } - return eRcCallResult_notFound; - } -#endif - } - - bool bFailedToReadOutput = false; - - if (listener) - { -#if defined(AZ_PLATFORM_WINDOWS) - // Close the pipe that writes to the child process, since we don't actually have any input for it. - CloseHandle(hChildStdInWr); - - // Read all the output from the child process. - CloseHandle(hChildStdOutWr); -#endif - ResourceCompilerLineHandler lineHandler(listener); - LineStreamBuffer lineBuffer(&lineHandler, &ResourceCompilerLineHandler::HandleLine); - for (;; ) - { - char buffer[2048]; - DWORD bytesRead; -#if defined(AZ_PLATFORM_WINDOWS) - if (!ReadFile(hChildStdOutRd, buffer, sizeof(buffer), &bytesRead, NULL) || (bytesRead == 0)) -#else - if (fgets(buffer, sizeof(buffer), hChildStdOutRd) == nullptr || (bytesRead = strlen(buffer) == 0)) -#endif - { - break; - } - lineBuffer.HandleText(buffer, bytesRead); - } - - bFailedToReadOutput = lineBuffer.IsTruncated(); - } - -#if defined(AZ_PLATFORM_WINDOWS) - // Wait until child process exits. - WaitForSingleObject(pi.hProcess, INFINITE); -#else - DWORD exitCode = pclose(hChildStdOutRd); -#endif - -#if defined(AZ_PLATFORM_WINDOWS) - RcAutoLock lock(s_rcProcessHandleLock); - s_rcProcessHandle = 0; - - DWORD exitCode = eRcExitCode_Error; - if (bFailedToReadOutput || GetExitCodeProcess(pi.hProcess, &exitCode) == 0) - { - exitCode = eRcExitCode_Error; - } - - // Close process and thread handles. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); -#endif - - return ConvertResourceCompilerExitCodeToResultCode(exitCode); -} - - -#endif //(CRY_ENABLE_RC_HELPER) diff --git a/Code/CryEngine/CryCommon/ResourceCompilerHelper.h b/Code/CryEngine/CryCommon/ResourceCompilerHelper.h deleted file mode 100644 index 913d72f642..0000000000 --- a/Code/CryEngine/CryCommon/ResourceCompilerHelper.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H -#define CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H - -#pragma once - -#if defined(CRY_ENABLE_RC_HELPER) - -#include "IResourceCompilerHelper.h" - -////////////////////////////////////////////////////////////////////////// -// Provides settings and functions to make calls to RC. -// calls RC locally. only works on windows, does not exist on other platforms -// note: You shouldn't be calling this directly -// instead, you should be calling it via the IResourceCompilerHelper interface. -// since it may be replaced with a custom RC for your platform or a remote invocation -class CResourceCompilerHelper - : public IResourceCompilerHelper -{ -public: - virtual ERcCallResult CallResourceCompiler( - const char* szFileName = 0, - const char* szAdditionalSettings = 0, - IResourceCompilerListener* listener = 0, - bool bMayShowWindow = true, - bool bSilent = false, - bool bNoUserDialog = false, - const wchar_t* szWorkingDirectory = 0, - const wchar_t* szRootPath = 0) override; -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H diff --git a/Code/CryEngine/CryCommon/SettingsManagerHelpers.cpp b/Code/CryEngine/CryCommon/SettingsManagerHelpers.cpp deleted file mode 100644 index 9746b00574..0000000000 --- a/Code/CryEngine/CryCommon/SettingsManagerHelpers.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "ProjectDefines.h" - -#if defined(CRY_ENABLE_RC_HELPER) - -#include "SettingsManagerHelpers.h" -#include "EngineSettingsManager.h" - -#include -#include -#include - -#include -#include - -#if defined(AZ_PLATFORM_WINDOWS) -#include -#include //ShellExecuteW() -#pragma comment(lib, "Shell32.lib") -#endif -#if AZ_TRAIT_OS_PLATFORM_APPLE -#include "AppleSpecific.h" -#endif - -bool SettingsManagerHelpers::Utf16ContainsAsciiOnly(const wchar_t* wstr) -{ - while (*wstr) - { - if (*wstr > 127 || *wstr < 0) - { - return false; - } - ++wstr; - } - return true; -} - - -void SettingsManagerHelpers::ConvertUtf16ToUtf8(const wchar_t* src, CCharBuffer dst) -{ - if (dst.getSizeInElements() <= 0) - { - return; - } - - if (src[0] == 0) - { - dst[0] = 0; - } - else - { - const std::codecvt& utf8Utf16Facet = std::use_facet>(std::locale()); - std::mbstate_t mb{}; - const wchar_t* from_next; - char* to_next; - std::codecvt_base::result result = utf8Utf16Facet.out(mb, src, src + wcslen(src), from_next, dst.getPtr(), dst.getPtr() + dst.getSizeInElements(), to_next); - if (result != std::codecvt_base::ok) - { - dst[0] = 0; - } - else - { - to_next = 0; - } - } -} - - -void SettingsManagerHelpers::ConvertUtf8ToUtf16(const char* src, CWCharBuffer dst) -{ - if (dst.getSizeInElements() <= 0) - { - return; - } - - if (src[0] == 0) - { - dst[0] = 0; - } - else - { - const std::codecvt& utf8Utf16Facet = std::use_facet>(std::locale()); - std::mbstate_t mb{}; - const char* from_next; - wchar_t* to_next; - std::codecvt_base::result result = utf8Utf16Facet.in(mb, src, src + strlen(src), from_next, dst.getPtr(), dst.getPtr() + dst.getSizeInElements(), to_next); - if (result != std::codecvt_base::ok) - { - dst[0] = 0; - } - else - { - to_next = 0; - } - } -} - - -void SettingsManagerHelpers::GetAsciiFilename(const wchar_t* wfilename, CCharBuffer buffer) -{ - if (buffer.getSizeInElements() <= 0) - { - return; - } - - if (wfilename[0] == 0) - { - buffer[0] = 0; - return; - } - - if (Utf16ContainsAsciiOnly(wfilename)) - { - ConvertUtf16ToUtf8(wfilename, buffer); - return; - } - -#if defined(AZ_PLATFORM_WINDOWS) - // The path is non-ASCII unicode, so let's resort to short filenames (they are always ASCII-only, I hope) - wchar_t shortW[MAX_PATH]; - const int bufferCharCount = sizeof(shortW) / sizeof(shortW[0]); - const int charCount = GetShortPathNameW(wfilename, shortW, bufferCharCount); - if (charCount <= 0 || charCount >= bufferCharCount) - { - buffer[0] = 0; - return; - } - - shortW[charCount] = 0; - if (!Utf16ContainsAsciiOnly(shortW)) - { - buffer[0] = 0; - return; - } - - ConvertUtf16ToUtf8(shortW, buffer); -#else - buffer[0] = 0; -#endif -} - - -////////////////////////////////////////////////////////////////////////// -CSettingsManagerTools::CSettingsManagerTools(const wchar_t* szModuleName) -{ - m_pSettingsManager = new CEngineSettingsManager(szModuleName); -} - -////////////////////////////////////////////////////////////////////////// -CSettingsManagerTools::~CSettingsManagerTools() -{ - delete m_pSettingsManager; -} - -////////////////////////////////////////////////////////////////////////// -bool CSettingsManagerTools::GetInstalledBuildPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) -{ - return m_pSettingsManager->GetInstalledBuildRootPathUtf16(index, name, path); -} - - -bool CSettingsManagerTools::GetInstalledBuildPathAscii(const int index, SettingsManagerHelpers::CCharBuffer name, SettingsManagerHelpers::CCharBuffer path) -{ - wchar_t wName[MAX_PATH]; - wchar_t wPath[MAX_PATH]; - if (GetInstalledBuildPathUtf16(index, SettingsManagerHelpers::CWCharBuffer(wName, sizeof(wName)), SettingsManagerHelpers::CWCharBuffer(wPath, sizeof(wPath)))) - { - SettingsManagerHelpers::GetAsciiFilename(wName, name); - SettingsManagerHelpers::GetAsciiFilename(wPath, path); - return true; - } - return false; -} - - - -////////////////////////////////////////////////////////////////////////// -static bool FileExists(const wchar_t* filename) -{ -#if defined(AZ_PLATFORM_WINDOWS) - const DWORD dwAttrib = GetFileAttributesW(filename); - return dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY); -#else - char utf8Filename[MAX_PATH]; - SettingsManagerHelpers::ConvertUtf16ToUtf8(filename, SettingsManagerHelpers::CCharBuffer(utf8Filename, sizeof(utf8Filename))); - struct stat buffer; - return (stat(utf8Filename, &buffer) == 0); -#endif -} - - -////////////////////////////////////////////////////////////////////////// -void CSettingsManagerTools::GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer wbuffer) -{ - if (wbuffer.getSizeInElements() <= 0) - { - return; - } - - AZStd::string_view exePath; - AZ::ComponentApplicationBus::BroadcastResult(exePath, &AZ::ComponentApplicationRequests::GetExecutableFolder); - - SettingsManagerHelpers::CFixedString editorExe; - editorExe = wbuffer.getPtr(); - editorExe.appendAscii(exePath.data(), exePath.size()); - - if (editorExe.length() <= 0) - { - wbuffer[0] = 0; - return; - } - - bool bFound = false; - if (Is64bitWindows()) - { - const size_t len = editorExe.length(); - editorExe.appendAscii("/Editor.exe"); - bFound = FileExists(editorExe.c_str()); - if (!bFound) - { - editorExe.setLength(len); - } - } - - const size_t sizeToCopy = (editorExe.length() + 1) * sizeof(wbuffer[0]); - if (!bFound || sizeToCopy > wbuffer.getSizeInBytes()) - { - wbuffer[0] = 0; - } - else - { - memcpy(wbuffer.getPtr(), editorExe.c_str(), sizeToCopy); - } -} - - -////////////////////////////////////////////////////////////////////////// -bool CSettingsManagerTools::CallEditor(void** pEditorWindow, [[maybe_unused]] void* hParent, const char* pWindowName, const char* pFlag) -{ -#if !defined(AZ_PLATFORM_WINDOWS) - AZ_Assert(false, "CSettingsManagerTools::CallEditor is not supported on this platform!"); - return false; -#else - HWND window = ::FindWindowA(NULL, pWindowName); - if (window) - { - *pEditorWindow = window; - return true; - } - else - { - *pEditorWindow = 0; - - wchar_t buffer[512] = { L'\0' }; - GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))); - - SettingsManagerHelpers::CFixedString wFlags; - SettingsManagerHelpers::ConvertUtf8ToUtf16(pFlag, wFlags.getBuffer()); - wFlags.setLength(wcslen(wFlags.c_str())); - - if (buffer[0] != '\0') - { - INT_PTR hIns = (INT_PTR)ShellExecuteW(NULL, L"open", buffer, wFlags.c_str(), NULL, SW_SHOWNORMAL); - if (hIns > 32) - { - return true; - } - else - { - MessageBoxA(0, "Editor.exe was not found.\n\nPlease verify CryENGINE root path.", "Error", MB_ICONERROR | MB_OK); - } - } - } - - return false; -#endif -} - -////////////////////////////////////////////////////////////////////////// -// Modified version of -// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139(v=vs.85).aspx -bool CSettingsManagerTools::Is64bitWindows() -{ -#if defined(_WIN64) - // 64-bit programs run only on 64-bit Windows - return true; -#elif !defined(AZ_PLATFORM_WINDOWS) - return false; -#else - // 32-bit programs run on both 32-bit and 64-bit Windows - static bool bWin64 = false; - static bool bOnce = true; - if (bOnce) - { - typedef BOOL (WINAPI * LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); - LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process"); - if (fnIsWow64Process != NULL) - { - BOOL itIsWow64Process = FALSE; - if (fnIsWow64Process(GetCurrentProcess(), &itIsWow64Process)) - { - bWin64 = (itIsWow64Process == TRUE); - } - } - bOnce = false; - } - return bWin64; -#endif -} - -#endif // #if defined(CRY_ENABLE_RC_HELPER) - -// eof diff --git a/Code/CryEngine/CryCommon/SettingsManagerHelpers.h b/Code/CryEngine/CryCommon/SettingsManagerHelpers.h deleted file mode 100644 index e05d2b97aa..0000000000 --- a/Code/CryEngine/CryCommon/SettingsManagerHelpers.h +++ /dev/null @@ -1,491 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H -#define CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H -#pragma once - -#include "ProjectDefines.h" -#include // memcpy -#include // std::min - - -namespace SettingsManagerHelpers -{ - namespace Utils - { - inline size_t strlen(const char* p) - { - return p ? ::strlen(p) : 0; - } - - inline size_t strcmp(const char* p0, const char* p1) - { - return ::strcmp(p0, p1); - } - - - inline size_t strlen(const wchar_t* p) - { - return p ? ::wcslen(p) : 0; - } - - inline size_t strcmp(const wchar_t* p0, const wchar_t* p1) - { - return ::wcscmp(p0, p1); - } - } - - // The function copies characters from src to dst one by one until any of - // the following conditions is met: - // 1) the end of the destination buffer (minus one character) is reached - // 2) the end of the source buffer is reached - // 3) zero character is found in the source buffer - // - // When any of 1), 2), 3) happens, the function writes the terminating zero - // character to the destination buffer and return. - // - // The function guarantees writing the terminating zero character to the - // destination buffer (if the buffer can fit at least one character). - // - // The function returns false when a null pointer is passed or when - // clamping happened (i.e. when the end of the destination buffer is - // reached but the source has some characters left). - inline bool strcpy_with_clamp(char* const dst, size_t const dst_size_in_bytes, const char* const src, size_t const src_size_in_bytes = (size_t)-1) - { - if (!dst || dst_size_in_bytes < sizeof(char)) - { - return false; - } - - if (!src || src_size_in_bytes < sizeof(char)) - { - dst[0] = 0; - return src != 0; // we return true for non-null src without characters - } - - const size_t src_n = src_size_in_bytes; - const size_t n = (std::min)(dst_size_in_bytes - 1, src_n); - - for (size_t i = 0; i < n; ++i) - { - dst[i] = src[i]; - if (!src[i]) - { - return true; - } - } - - dst[n] = 0; - return n >= src_n || src[n] == 0; - } - - - template - class CBuffer - { - public: - typedef T element_type; - - private: - element_type* m_ptr; - size_t m_sizeInBytes; - - public: - CBuffer(element_type* ptr, size_t sizeInBytes) - : m_ptr(ptr) - , m_sizeInBytes(ptr ? sizeInBytes : 0) - { - } - - const element_type* getPtr() const - { - return m_ptr; - } - - element_type* getPtr() - { - return m_ptr; - } - - size_t getSizeInElements() const - { - return m_sizeInBytes / sizeof(element_type); - } - - size_t getSizeInBytes() const - { - return m_sizeInBytes; - } - - const element_type& operator[](size_t pos) const - { - return m_ptr[pos]; - } - - element_type& operator[](size_t pos) - { - return m_ptr[pos]; - } - }; - - typedef CBuffer CCharBuffer; - typedef CBuffer CWCharBuffer; - - - template - class CFixedString - { - public: - typedef T char_type; - static const size_t npos = ~size_t(0); - private: - size_t m_count; // # chars (not counting trailing zero) - char_type m_buffer[CAPACITY + 1]; // '+ 1' is for trailing zero - - public: - CFixedString() - { - clear(); - } - - CFixedString(const char_type* p) - { - set(p); - } - - CFixedString& operator=(const char_type* p) - { - set(p); - return *this; - } - - CFixedString& operator=(const CFixedString& s) - { - if (&s != this) - { - set(s.m_buffer, s.m_count); - } - return *this; - } - - CBuffer getBuffer() - { - return CBuffer(m_buffer, (CAPACITY + 1) * sizeof(char_type)); - } - - char_type operator[](const size_t i) const - { - return m_buffer[i]; - } - - const char_type* c_str() const - { - return &m_buffer[0]; - } - - const size_t length() const - { - return m_count; - } - - void clear() - { - m_count = 0; - m_buffer[m_count] = 0; - } - - void setLength(size_t n) - { - m_count = (n <= CAPACITY) ? n : CAPACITY; - m_buffer[m_count] = 0; - } - - char_type* ptr() - { - return &m_buffer[0]; - } - - CFixedString substr(size_t pos = 0, size_t n = npos) const - { - CFixedString s; - if (pos < m_count && n > 0) - { - if (n > m_count || pos + n > m_count) - { - n = m_count - pos; - } - s.set(&m_buffer[pos], n); - } - return s; - } - - void set(const char_type* p, size_t n) - { - if (p == 0 || n <= 0) - { - m_count = 0; - } - else - { - m_count = (n > CAPACITY) ? CAPACITY : n; - // memmove() is used because p may point to m_buffer - memmove(m_buffer, p, m_count * sizeof(*p)); - } - m_buffer[m_count] = 0; - } - - void set(const char_type* p) - { - if (p && p[0]) - { - set(p, Utils::strlen(p)); - } - else - { - clear(); - } - } - - void append(const char_type* p, size_t n) - { - if (p && n > 0) - { - if (n > CAPACITY || m_count + n > CAPACITY) - { - // assert(0); - n = CAPACITY - m_count; - } - if (n > 0) - { - memcpy(&m_buffer[m_count], p, n * sizeof(*p)); - m_count += n; - m_buffer[m_count] = 0; - } - } - } - - void append(const char_type* p) - { - if (p && p[0]) - { - append(p, Utils::strlen(p)); - } - } - - void appendAscii(const char* p, size_t n) - { - if (p && n > 0) - { - if (n > CAPACITY || m_count + n > CAPACITY) - { - // assert(0); - n = CAPACITY - m_count; - } - if (n > 0) - { - for (size_t i = 0; i < n; ++i) - { - m_buffer[m_count + i] = p[i]; - } - m_count += n; - m_buffer[m_count] = 0; - } - } - } - - void appendAscii(const char* p) - { - if (p && p[0]) - { - appendAscii(p, Utils::strlen(p)); - } - } - - bool equals(const char_type* p) const - { - return (p == 0 || p[0] == 0) - ? (m_count == 0) - : (Utils::strcmp(m_buffer, p) == 0); - } - - void trim() - { - size_t begin = 0; - while (begin < m_count && (m_buffer[begin] == ' ' || m_buffer[begin] == '\r' || m_buffer[begin] == '\t' || m_buffer[begin] == '\n')) - { - ++begin; - } - - if (begin >= m_count) - { - clear(); - return; - } - - size_t end = m_count - 1; - while (end > begin && (m_buffer[begin] == ' ' || m_buffer[begin] == '\r' || m_buffer[begin] == '\t' || m_buffer[begin] == '\n')) - { - --end; - } - - m_count = end + 1; - m_buffer[m_count] = 0; - - if (begin > 0) - { - set(&m_buffer[begin], m_count - begin); - } - } - }; - - - struct SKeyValue - { - CFixedString key; - CFixedString value; - }; - - - template - class CKeyValueArray - { - private: - size_t count; - SKeyValue data[CAPACITY]; - - public: - CKeyValueArray() - : count(0) - { - } - - size_t size() const - { - return count; - } - - const SKeyValue& operator[](size_t i) const - { - return data[i]; - } - - void clear() - { - count = 0; - } - - const SKeyValue* find(const char* key) const - { - for (size_t i = 0; i < count; ++i) - { - if (data[i].key.equals(key)) - { - return &data[i]; - } - } - return 0; - } - - SKeyValue* find(const char* key) - { - for (size_t i = 0; i < count; ++i) - { - if (data[i].key.equals(key)) - { - return &data[i]; - } - } - return 0; - } - - SKeyValue* set(const char* key, const wchar_t* value) - { - SKeyValue* p = find(key); - if (!p) - { - if (count >= CAPACITY) - { - return 0; - } - p = &data[count++]; - p->key = key; - } - p->value = value; - return p; - } - }; - - -#if defined(CRY_ENABLE_RC_HELPER) - - bool Utf16ContainsAsciiOnly(const wchar_t* wstr); - - void ConvertUtf16ToUtf8(const wchar_t* src, CCharBuffer dst); - - void ConvertUtf8ToUtf16(const char* src, CWCharBuffer dst); - - template - void AddPathSeparator(CFixedString& wstr) - { - if (wstr.length() <= 0) - { - return; - } - - if (wstr[wstr.length() - 1] == L'/' || wstr[wstr.length() - 1] == L'\\') - { - return; - } - - wstr.appendAscii("/"); - } - - void GetAsciiFilename(const wchar_t* wfilename, CCharBuffer buffer); - -#endif // #if defined(CRY_ENABLE_RC_HELPER) -} // namespace SettingsManagerHelpers - - -#if defined(CRY_ENABLE_RC_HELPER) - -////////////////////////////////////////////////////////////////////////// -// Provides settings and functions to make calls to RC. -class CEngineSettingsManager; -class CSettingsManagerTools -{ -public: - CSettingsManagerTools(const wchar_t* szModuleName = 0); - ~CSettingsManagerTools(); - -private: - CEngineSettingsManager* m_pSettingsManager; - -public: - CEngineSettingsManager* GetEngineSettingsManager() - { - return m_pSettingsManager; - } - - bool GetInstalledBuildPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path); - bool GetInstalledBuildPathAscii(const int index, SettingsManagerHelpers::CCharBuffer name, SettingsManagerHelpers::CCharBuffer path); - - void GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer wbuffer); - bool CallEditor(void** pEditorWindow, void* hParent, const char* pWndName, const char* pFlag); - - static bool Is64bitWindows(); -}; - -#endif // #if defined(CRY_ENABLE_RC_HELPER) - -#endif // CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H diff --git a/Code/CryEngine/CryCommon/crycommon_enginesettings_files.cmake b/Code/CryEngine/CryCommon/crycommon_enginesettings_files.cmake deleted file mode 100644 index 0fbd223d21..0000000000 --- a/Code/CryEngine/CryCommon/crycommon_enginesettings_files.cmake +++ /dev/null @@ -1,27 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ProjectDefines.h - SettingsManagerHelpers.cpp - SettingsManagerHelpers.h - EngineSettingsManager.cpp - EngineSettingsManager.h - EngineSettingsBackend.cpp - EngineSettingsBackend.h - ResourceCompilerHelper.cpp - ResourceCompilerHelper.h -) - -# Remove files that cause #define collisions on Mac due to multiple inclusions of 'AppleSpecific.h' and include orders -set(SKIP_UNITY_BUILD_INCLUSION_FILES - SettingsManagerHelpers.cpp -) diff --git a/Code/CryEngine/CryCommon/crycommon_files.cmake b/Code/CryEngine/CryCommon/crycommon_files.cmake index ca95802fd9..77b51825f1 100644 --- a/Code/CryEngine/CryCommon/crycommon_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_files.cmake @@ -22,7 +22,6 @@ set(FILES IConsole.h IEntityRenderState.h IEntityRenderState_info.cpp - IFlares.h IFont.h IFunctorBase.h IFuncVariable.h @@ -40,12 +39,10 @@ set(FILES ILog.h ILZ4Decompressor.h IMaterial.h - IMaterialEffects.h IMemory.h IMeshBaking.h IMiniLog.h IMovieSystem.h - INotificationNetwork.h IPhysics.h IPhysicsDebugRenderer.h IPostEffectGroup.h @@ -55,12 +52,10 @@ set(FILES IRenderer.h IRenderMesh.h IResourceCollector.h - IResourceCompilerHelper.h IResourceManager.h ISerialize.h IShader.h IShader_info.h - ISoftCodeMgr.h ISplines.h IStatObj.h StatObjBus.h @@ -69,11 +64,8 @@ set(FILES IStreamEngineDefs.h ISurfaceType.h ISystem.h - ISystemScheduler.h ITextModeConsole.h ITexture.h - IThreadManager.h - IThreadTask.h ITimer.h IValidator.h IVideoRenderer.h @@ -108,7 +100,6 @@ set(FILES MaterialUtils.h MTPseudoRandom.cpp CryTypeInfo.cpp - IResourceCompilerHelper.cpp BaseTypes.h CompileTimeAssert.h CryThreadSafeWorkerContainer.h @@ -170,7 +161,6 @@ set(FILES PoolAllocator.h primitives.h primitives_info.h - ProfileLog.h ProjectDefines.h Range.h RenderContextConfig.h diff --git a/Code/CryEngine/CryCommon/physinterface.h b/Code/CryEngine/CryCommon/physinterface.h index 036f7e29ab..dd787d48b7 100644 --- a/Code/CryEngine/CryCommon/physinterface.h +++ b/Code/CryEngine/CryCommon/physinterface.h @@ -3244,7 +3244,6 @@ struct PhysicsVars int nBodiesLargeGroup; int bBreakOnValidation; int bLogActiveObjects; - int bMultiplayer; int bProfileEntities; int bProfileFunx; int bProfileGroups; diff --git a/Code/CryEngine/CryCommon/platform_impl.cpp b/Code/CryEngine/CryCommon/platform_impl.cpp index 142f07e5e7..885ea2984d 100644 --- a/Code/CryEngine/CryCommon/platform_impl.cpp +++ b/Code/CryEngine/CryCommon/platform_impl.cpp @@ -33,7 +33,7 @@ #define PLATFORM_IMPL_H_SECTION_VIRTUAL_ALLOCATORS 7 #endif -SC_API struct SSystemGlobalEnvironment* gEnv = nullptr; +struct SSystemGlobalEnvironment* gEnv = nullptr; // Traits #if defined(AZ_RESTRICTED_PLATFORM) @@ -147,7 +147,6 @@ void* GetDetachEnvironmentSymbol() #endif // !defined(SOFTCODE) bool g_bProfilerEnabled = false; -int g_iTraceAllocations = 0; ////////////////////////////////////////////////////////////////////////// // global random number generator used by cry_random functions diff --git a/Code/CryEngine/CrySystem/AutoDetectSpec.cpp b/Code/CryEngine/CrySystem/AutoDetectSpec.cpp index 31eee85d90..aa344684e3 100644 --- a/Code/CryEngine/CrySystem/AutoDetectSpec.cpp +++ b/Code/CryEngine/CrySystem/AutoDetectSpec.cpp @@ -1044,11 +1044,9 @@ void CSystem::AutoDetectSpec(const bool detectResolution) unsigned int numSysCores(1), numProcCores(1); Win32SysInspect::GetNumCPUCores(numSysCores, numProcCores); CryLogAlways("--- Number of available cores: %d (out of %d)", numProcCores, numSysCores); - const int numLogicalProcs = gEnv->pi.numLogicalProcessors; - CryLogAlways("--- Number of logical processors: %d", numLogicalProcs); // get CPU rating - const int cpuRating = numLogicalProcs >= 8 ? 3 : (numLogicalProcs >= 6 ? 2 : 1); + const int cpuRating = numProcCores >= 4 ? 3 : (numProcCores >= 3 ? 2 : 1); // get GPU info unsigned int gpuVendorId(0), gpuDeviceId(0), totVidMem(0); diff --git a/Code/CryEngine/CrySystem/CMakeLists.txt b/Code/CryEngine/CrySystem/CMakeLists.txt index 1a5593e5d8..3261526e8e 100644 --- a/Code/CryEngine/CrySystem/CMakeLists.txt +++ b/Code/CryEngine/CrySystem/CMakeLists.txt @@ -89,7 +89,6 @@ ly_add_target( Legacy::CrySystem.Static AZ::AzCore Legacy::CryCommon - Legacy::CryCommon.EngineSettings.Static ) ################################################################################ @@ -109,7 +108,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) PRIVATE AZ::AzTest Legacy::CryCommon - Legacy::CryCommon.EngineSettings.Static Legacy::CrySystem.Static AZ::AzFramework ) diff --git a/Code/CryEngine/CrySystem/ConsoleBatchFile.cpp b/Code/CryEngine/CrySystem/ConsoleBatchFile.cpp index 946edb9b64..b6eced4df3 100644 --- a/Code/CryEngine/CrySystem/ConsoleBatchFile.cpp +++ b/Code/CryEngine/CrySystem/ConsoleBatchFile.cpp @@ -87,14 +87,6 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) filename = PathUtil::ReplaceExtension(filename, "cfg"); } -#if defined(CVARS_WHITELIST) - bool ignoreWhitelist = true; - if (_stricmp(sFilename, "autoexec.cfg") == 0) - { - ignoreWhitelist = false; - } -#endif // defined(CVARS_WHITELIST) - ////////////////////////////////////////////////////////////////////////// CCryFile file; @@ -179,18 +171,9 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) continue; } -#if defined(CVARS_WHITELIST) - if (ignoreWhitelist || (gEnv->pSystem->GetCVarsWhiteList() && gEnv->pSystem->GetCVarsWhiteList()->IsWhiteListed(strLine, false))) -#endif // defined(CVARS_WHITELIST) { m_pConsole->ExecuteString(strLine); } -#if defined(CVARS_WHITELIST) - else if (gEnv->IsDedicated()) - { - gEnv->pSystem->GetILog()->LogError("Failed to execute command: '%s' as it is not whitelisted\n", strLine.c_str()); - } -#endif // defined(CVARS_WHITELIST) } // See above // ((CXConsole*)m_pConsole)->SetStatus(bConsoleStatus); diff --git a/Code/CryEngine/CrySystem/CrySystem_precompiled.h b/Code/CryEngine/CrySystem/CrySystem_precompiled.h index b446199b4e..1fab2d4ce1 100644 --- a/Code/CryEngine/CrySystem/CrySystem_precompiled.h +++ b/Code/CryEngine/CrySystem/CrySystem_precompiled.h @@ -117,7 +117,6 @@ struct IRenderer; struct ISystem; struct ITimer; struct IFFont; -struct IKeyboard; struct ICVar; struct IConsole; struct IProcess; diff --git a/Code/CryEngine/CrySystem/CryThreadUtil_pthread.h b/Code/CryEngine/CrySystem/CryThreadUtil_pthread.h deleted file mode 100644 index 4c920898f0..0000000000 --- a/Code/CryEngine/CrySystem/CryThreadUtil_pthread.h +++ /dev/null @@ -1,259 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -////////////////////////////////////////////////////////////////////////// -// NOTE: INTERNAL HEADER NOT FOR PUBLIC USE -// This header should only be include by SystemThreading.cpp only -// It provides an interface for PThread intrinsics -// It's only client should be CThreadManager which should manage all thread interaction -#if !defined(INCLUDED_FROM_SYSTEM_THREADING_CPP) -# error "CRYTEK INTERNAL HEADER. ONLY INCLUDE FROM SYSTEMTHRADING.CPP." -#endif -////////////////////////////////////////////////////////////////////////// - -#define DEFAULT_THREAD_STACK_SIZE_KB 0 -#define CRY_PTHREAD_THREAD_NAME_MAX 16 - -////////////////////////////////////////////////////////////////////////// -// THREAD CREATION AND MANAGMENT -////////////////////////////////////////////////////////////////////////// -namespace CryThreadUtil -{ - // Define type for platform specific thread handle - typedef pthread_t TThreadHandle; - - struct SThreadCreationDesc - { - // Define platform specific thread entry function functor type - typedef void* (* EntryFunc)(void*); - - const char* szThreadName; - EntryFunc fpEntryFunc; - void* pArgList; - uint32 nStackSizeInBytes; - }; - - ////////////////////////////////////////////////////////////////////////// - TThreadHandle CryGetCurrentThreadHandle() - { - return (TThreadHandle)pthread_self(); - } - - ////////////////////////////////////////////////////////////////////////// - // Note: Handle must be closed lated via CryCloseThreadHandle() - TThreadHandle CryDuplicateThreadHandle(const TThreadHandle& hThreadHandle) - { - // Do not do anything - // If you add a new platform which duplicates handles make sure to mirror the change in CryCloseThreadHandle(..) - return hThreadHandle; - } - - ////////////////////////////////////////////////////////////////////////// - void CryCloseThreadHandle(TThreadHandle& hThreadHandle) - { - pthread_detach(hThreadHandle); - } - - ////////////////////////////////////////////////////////////////////////// - threadID CryGetCurrentThreadId() - { - return threadID(pthread_self()); - } - - ////////////////////////////////////////////////////////////////////////// - threadID CryGetThreadId(TThreadHandle hThreadHandle) - { - return threadID(hThreadHandle); - } - - ////////////////////////////////////////////////////////////////////////// - // Note: On OSX the thread name can only be set by the thread itself. - void CrySetThreadName(TThreadHandle pThreadHandle, const char* sThreadName) - { - char threadName[CRY_PTHREAD_THREAD_NAME_MAX]; - if (!cry_strcpy(threadName, sThreadName)) - { - CryLog(" CrySetThreadName: input thread name '%s' truncated to '%s'", sThreadName, threadName); - } -#if AZ_TRAIT_OS_PLATFORM_APPLE - // On OSX the thread name can only be set by the thread itself. - assert(pthread_equal(pthread_self(), (pthread_t )pThreadHandle)); - - if (pthread_setname_np(threadName) != 0) -#else - if (pthread_setname_np(pThreadHandle, threadName) != 0) -#endif - { - switch (errno) - { - case ERANGE: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadName: Unable to rename thread \"%s\". Error Msg: \"Name to long. Exceeds %d bytes.\"", sThreadName, CRY_PTHREAD_THREAD_NAME_MAX); - break; - default: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadName: Unsupported error code: %i", errno); - break; - } - } - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadAffinityMask(TThreadHandle pThreadHandle, DWORD dwAffinityMask) - { -#if defined(AZ_PLATFORM_ANDROID) - // Not supported on ANDROID - // Alternative solution - // Watch out that android will clear the mask after a core has been switched off hence loosing the affinity mask setting! - // http://stackoverflow.com/questions/16319725/android-set-thread-affinity -#elif AZ_TRAIT_OS_PLATFORM_APPLE -# pragma message "Warning: CrySetThreadAffinityMask not implemented for platform" - // Implementation details can be found here - // https://developer.apple.com/library/mac/releasenotes/Performance/RN-AffinityAPI/ -#else - cpu_set_t cpu_mask; - CPU_ZERO(&cpu_mask); - for (int cpu = 0; cpu < sizeof(cpu_mask) * 8; ++cpu) - { - if (dwAffinityMask & (1 << cpu)) - { - CPU_SET(cpu, &cpu_mask); - } - } - - if (sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask) != 0) - { - switch (errno) - { - case EFAULT: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: Supplied memory address was invalid."); - break; - case EINVAL: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: The affinity bit mask [%u] contains no processors that are currently physically on the system and permitted to the process .", dwAffinityMask); - break; - case EPERM: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: The calling process does not have appropriate privileges. Mask [%u].", dwAffinityMask); - break; - case ESRCH: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: The process whose ID is pid could not be found."); - break; - default: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: Unsupported error code: %i", errno); - break; - } - } -#endif - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadPriority(TThreadHandle pThreadHandle, DWORD dwPriority) - { - int policy; - struct sched_param param; - - pthread_getschedparam(pThreadHandle, &policy, ¶m); - param.sched_priority = sched_get_priority_max(dwPriority); - pthread_setschedparam(pThreadHandle, policy, ¶m); - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadPriorityBoost(TThreadHandle pThreadHandle, bool bEnabled) - { - // Not supported - } - - ////////////////////////////////////////////////////////////////////////// - bool CryCreateThread(TThreadHandle* pThreadHandle, const SThreadCreationDesc& threadDesc) - { - uint32 nStackSize = threadDesc.nStackSizeInBytes != 0 ? threadDesc.nStackSizeInBytes : DEFAULT_THREAD_STACK_SIZE_KB * 1024; - - assert(pThreadHandle != reinterpret_cast(THREADID_NULL)); - pthread_attr_t threadAttr; - sched_param schedParam; - pthread_attr_init(&threadAttr); - pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setstacksize(&threadAttr, nStackSize); - - const int err = pthread_create( - pThreadHandle, - &threadAttr, - threadDesc.fpEntryFunc, - threadDesc.pArgList); - - // Handle error on thread creation - switch (err) - { - case 0: - // No error - break; - case EAGAIN: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". Error Msg: \"Insufficient resources to create another thread, or a system-imposed limit on the number of threads was encountered.\"", threadDesc.szThreadName); - return false; - case EINVAL: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". Error Msg: \"Invalid attribute setting for thread creation.\"", threadDesc.szThreadName); - return false; - case EPERM: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". Error Msg: \"No permission to set the scheduling policy and parameters specified in attribute setting\"", threadDesc.szThreadName); - return false; - default: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". Unknown error message. Error code %i", threadDesc.szThreadName, err); - break; - } - - // Print info to log - CryComment(": New thread \"%s\" | StackSize: %u(KB)", threadDesc.szThreadName, threadDesc.nStackSizeInBytes / 1024); - return true; - } - - ////////////////////////////////////////////////////////////////////////// - void CryThreadExitCall() - { - // Notes on: pthread_exit - // A thread that was create with pthread_create implicitly calls pthread_exit when the thread returns from its start routine (the function that was first called after a thread was created). - // pthread_exit(NULL); - } -} - - -////////////////////////////////////////////////////////////////////////// -// FLOATING POINT EXCEPTIONS -////////////////////////////////////////////////////////////////////////// -namespace CryThreadUtil -{ - /////////////////////////////////////////////////////////////////////////// - void EnableFloatExceptions(EFPE_Severity eFPESeverity) - { - // TODO: - // Not implemented - // for potential implementation see http://linux.die.net/man/3/feenableexcept - } - - ////////////////////////////////////////////////////////////////////////// - void EnableFloatExceptions(threadID nThreadId, EFPE_Severity eFPESeverity) - { - // TODO: - // Not implemented - // for potential implementation see http://linux.die.net/man/3/feenableexcept - } - - ////////////////////////////////////////////////////////////////////////// - uint GetFloatingPointExceptionMask() - { - // Not implemented - return ~0; - } - - ////////////////////////////////////////////////////////////////////////// - void SetFloatingPointExceptionMask(uint nMask) - { - // Not implemented - } -} diff --git a/Code/CryEngine/CrySystem/CryThreadUtil_win32_thread.h b/Code/CryEngine/CrySystem/CryThreadUtil_win32_thread.h deleted file mode 100644 index e5c7510feb..0000000000 --- a/Code/CryEngine/CrySystem/CryThreadUtil_win32_thread.h +++ /dev/null @@ -1,432 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -////////////////////////////////////////////////////////////////////////// -// NOTE: INTERNAL HEADER NOT FOR PUBLIC USE -// This header should only be include by SystemThreading.cpp only -// It provides an interface for WinApi intrinsics -// It's only client should be CThreadManager which should manage all thread interaction - -#pragma once - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CRYTHREADUTIL_WIN32_THREAD_H_SECTION_1 1 -#define CRYTHREADUTIL_WIN32_THREAD_H_SECTION_2 2 -#endif - -#if !defined(INCLUDED_FROM_SYSTEM_THREADING_CPP) -# error "CRYTEK INTERNAL HEADER. ONLY INCLUDE FROM SYSTEMTHRADING.CPP." -#endif -////////////////////////////////////////////////////////////////////////// - -#define DEFAULT_THREAD_STACK_SIZE_KB 0 - -// Returns the last Win32 error, in string format. Returns an empty string if there is no error. -static string GetLastErrorAsString() -{ - // Get the error message, if any. - DWORD errorMessageID = GetLastError(); - if (errorMessageID == 0) - { - return ""; - } - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CRYTHREADUTIL_WIN32_THREAD_H_SECTION_1 -#include AZ_RESTRICTED_FILE(CryThreadUtil_win32_thread_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - LPSTR messageBuffer = nullptr; - size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), messageBuffer, 0, NULL); - - string message(messageBuffer, size); - - // Free the buffer. - LocalFree(messageBuffer); - - return message; -#endif -} - -////////////////////////////////////////////////////////////////////////// -// THREAD CREATION AND MANAGMENT -////////////////////////////////////////////////////////////////////////// -namespace CryThreadUtil -{ - // Define type for platform specific thread handle - typedef THREAD_HANDLE TThreadHandle; - - struct SThreadCreationDesc - { - // Define platform specific thread entry function functor type - typedef unsigned int(_stdcall * EntryFunc)(void*); - - const char* szThreadName; - EntryFunc fpEntryFunc; - void* pArgList; - uint32 nStackSizeInBytes; - }; - - ////////////////////////////////////////////////////////////////////////// - TThreadHandle CryGetCurrentThreadHandle() - { - return GetCurrentThread(); // most likely returns pseudo handle (0xfffffffe) - } - - ////////////////////////////////////////////////////////////////////////// - // Note: Handle must be closed lated via CryCloseThreadHandle() - TThreadHandle CryDuplicateThreadHandle(const TThreadHandle& hThreadHandle) - { - // NOTES: - // GetCurrentThread() may return a psydo handle to the current thread - // to avoid going into the slower kernel mode. - // Hence the handle is useless when being used from an other thread. - // - GetCurrentThread() -> 0xfffffffe - // - GetCurrentProcess() -> 0xffffffff - - HANDLE hRealHandle = 0; - DuplicateHandle(GetCurrentProcess(), // Source Process Handle. - hThreadHandle, // Source Handle to dup. - GetCurrentProcess(), // Target Process Handle. - &hRealHandle, // Target Handle pointer. - 0, // Options flag. - TRUE, // Inheritable flag - DUPLICATE_SAME_ACCESS); // Options - - return (TThreadHandle)hRealHandle; - } - - ////////////////////////////////////////////////////////////////////////// - void CryCloseThreadHandle(TThreadHandle& hThreadHandle) - { - if (hThreadHandle) - { - CloseHandle(hThreadHandle); - } - } - - ////////////////////////////////////////////////////////////////////////// - threadID CryGetCurrentThreadId() - { - return GetCurrentThreadId(); - } - - ////////////////////////////////////////////////////////////////////////// - threadID CryGetThreadId(TThreadHandle hThreadHandle) - { - return GetThreadId(hThreadHandle); - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadName(TThreadHandle pThreadHandle, const char* sThreadName) - { - const DWORD MS_VC_EXCEPTION = 0x406D1388; - - struct SThreadNameDesc - { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. - }; - - SThreadNameDesc info; - info.dwType = 0x1000; - info.szName = sThreadName; - info.dwThreadID = GetThreadId(pThreadHandle); - info.dwFlags = 0; -AZ_PUSH_DISABLE_WARNING(6312 6322, "-Wunknown-warning-option") - // warning C6312: Possible infinite loop: use of the constant EXCEPTION_CONTINUE_EXECUTION in the exception-filter expression of a try-except - // warning C6322: empty _except block - __try - { - // Raise exception to set thread name for attached debugger - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (ULONG_PTR*)&info); - } - __except (GetExceptionCode() == MS_VC_EXCEPTION ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER) - { - } -AZ_POP_DISABLE_WARNING - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadAffinityMask(TThreadHandle pThreadHandle, DWORD dwAffinityMask) - { - SetThreadAffinityMask(pThreadHandle, dwAffinityMask); - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadPriority(TThreadHandle pThreadHandle, DWORD dwPriority) - { - if (!SetThreadPriority(pThreadHandle, dwPriority)) - { - string errMsg = GetLastErrorAsString(); - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to set thread priority. System Error Msg: \"%s\"", errMsg.c_str()); - return; - } - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadPriorityBoost(TThreadHandle pThreadHandle, bool bEnabled) - { - SetThreadPriorityBoost(pThreadHandle, !bEnabled); - } - - ////////////////////////////////////////////////////////////////////////// - bool CryCreateThread(TThreadHandle* pThreadHandle, const SThreadCreationDesc& threadDesc) - { - const uint32 nStackSize = threadDesc.nStackSizeInBytes != 0 ? threadDesc.nStackSizeInBytes : DEFAULT_THREAD_STACK_SIZE_KB * 1024; - - // Create thread - unsigned int threadId = 0; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CRYTHREADUTIL_WIN32_THREAD_H_SECTION_2 -#include AZ_RESTRICTED_FILE(CryThreadUtil_win32_thread_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - *pThreadHandle = (void*)_beginthreadex(NULL, nStackSize, threadDesc.fpEntryFunc, threadDesc.pArgList, CREATE_SUSPENDED, &threadId); -#endif - - if (!(*pThreadHandle)) - { - string errMsg = GetLastErrorAsString(); - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". System Error Msg: \"%s\"", threadDesc.szThreadName, errMsg.c_str()); - return false; - } - - // Start thread - ResumeThread(*pThreadHandle); - - // Print info to log - CryComment(": New thread \"%s\" | StackSize: %u(KB)", threadDesc.szThreadName, threadDesc.nStackSizeInBytes / 1024); - return true; - } - - ////////////////////////////////////////////////////////////////////////// - void CryThreadExitCall() - { - // Note on: ExitThread() (from MSDN) - // ExitThread is the preferred method of exiting a thread in C code. - // However, in C++ code, the thread is exited before any destructor can be called or any other automatic cleanup can be performed. - // Therefore, in C++ code, you should return from your thread function. - } -} - -////////////////////////////////////////////////////////////////////////// -// FLOATING POINT EXCEPTIONS -////////////////////////////////////////////////////////////////////////// -namespace CryThreadUtil -{ - /////////////////////////////////////////////////////////////////////////// - void EnableFloatExceptions([[maybe_unused]] EFPE_Severity eFPESeverity) - { -AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option") - - // Optimization - // Enable DAZ/FZ - // Denormals Are Zeros - // Flush-to-Zero - _controlfp(_DN_FLUSH, _MCW_DN); - _mm_setcsr(_mm_getcsr() | _MM_FLUSH_ZERO_ON); - -#ifndef _RELEASE - if (eFPESeverity == eFPE_None) - { - // mask all floating exceptions off. - _controlfp(_MCW_EM, _MCW_EM); - _mm_setcsr(_mm_getcsr() | _MM_MASK_MASK); - } - else - { - // Clear pending exceptions - _fpreset(); - - if (eFPESeverity == eFPE_Basic) - { - // Enable: - // - _EM_ZERODIVIDE - // - _EM_INVALID - // - // Disable: - // - _EM_DENORMAL - // - _EM_OVERFLOW - // - _EM_UNDERFLOW - // - _EM_INEXACT - - _controlfp(_EM_INEXACT | _EM_DENORMAL | _EM_UNDERFLOW | _EM_OVERFLOW, _MCW_EM); - _mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (_MM_MASK_DENORM | _MM_MASK_INEXACT | _MM_MASK_UNDERFLOW | _MM_MASK_OVERFLOW)); - - //_mm_setcsr(_mm_getcsr() & ~0x280); - } - - if (eFPESeverity == eFPE_All) - { - // Enable: - // - _EM_ZERODIVIDE - // - _EM_INVALID - // - _EM_UNDERFLOW - // - _EM_OVERFLOW - // - // Disable: - // - _EM_INEXACT - // - _EM_DENORMAL - - _controlfp(_EM_INEXACT | _EM_DENORMAL, _MCW_EM); - _mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (_MM_MASK_INEXACT | _MM_MASK_DENORM)); - } - } -#endif // _RELEASE - -AZ_POP_DISABLE_WARNING -} - - ////////////////////////////////////////////////////////////////////////// - void EnableFloatExceptions(threadID nThreadId, EFPE_Severity eFPESeverity) - { - if (eFPESeverity >= eFPE_LastEntry) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Floating Point Exception (FPE) severity is out of range. (%i)", eFPESeverity); - } - - // Check if the thread ID matches the current thread - if (nThreadId == 0 || nThreadId == CryGetCurrentThreadId()) - { - EnableFloatExceptions(eFPESeverity); - return; - } - - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, true, nThreadId); - - if (hThread == 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Unable to open thread. %p", hThread); - return; - } - - SuspendThread(hThread); - - CONTEXT ctx; - memset(&ctx, 0, sizeof(ctx)); - ctx.ContextFlags = CONTEXT_ALL; - if (GetThreadContext(hThread, &ctx) == 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Unable to get thread context"); - ResumeThread(hThread); - CloseHandle(hThread); - return; - } - -#ifdef PLATFORM_64BIT - ////////////////////////////////////////////////////////////////////////// - // Note: - // DO NOT USE ctx.FltSave.MxCsr ... SetThreadContext() will copy the value of ctx.MxCsr into it - ////////////////////////////////////////////////////////////////////////// - DWORD& floatMxCsr = ctx.MxCsr; // Hold FPE Mask and Status for MMX (SSE) floating point registers - WORD& floatControlWord = ctx.FltSave.ControlWord; // Hold FPE Mask for floating point registers - #ifndef _RELEASE - WORD& floatStatuslWord = ctx.FltSave.StatusWord; // Holds FPE Status for floating point registers - #endif -#else - DWORD& floatMxCsr = *(DWORD*)(&ctx.ExtendedRegisters[24]); // Hold FPE Mask and Status for MMX (SSE) floating point registers - DWORD& floatControlWord = ctx.FloatSave.ControlWord; // Hold FPE Mask for floating point registers - DWORD& floatStatuslWord = ctx.FloatSave.StatusWord; // Holds FPE Status for floating point registers -#endif - - // Flush-To-Zero Mode - // Two conditions must be met for FTZ processing to occur: - // - The FTZ bit (bit 15) in the MXCSR register must be masked (value = 1). - // - The underflow exception (bit 11) needs to be masked (value = 1). - - // Set flush mode to zero mode - floatControlWord = (floatControlWord & ~_MCW_DN) | _DN_FLUSH; - floatMxCsr = (floatMxCsr & ~_MM_FLUSH_ZERO_MASK) | (_MM_FLUSH_ZERO_ON); - -#ifndef _RELEASE - - // Reset FPE bits - floatControlWord = floatControlWord | _MCW_EM; - floatMxCsr = floatMxCsr | _MM_MASK_MASK; - - // Clear pending exceptions - floatStatuslWord = floatStatuslWord & ~(_SW_INEXACT | _SW_UNDERFLOW | _SW_OVERFLOW | _SW_ZERODIVIDE | _SW_INVALID | _SW_DENORMAL); - floatMxCsr = floatMxCsr & ~(_MM_EXCEPT_INEXACT | _MM_EXCEPT_UNDERFLOW | _MM_EXCEPT_OVERFLOW | _MM_EXCEPT_DIV_ZERO | _MM_EXCEPT_INVALID | _MM_EXCEPT_DENORM); - - if (eFPESeverity == eFPE_Basic) - { - // Enable: - // - _EM_ZERODIVIDE - // - _EM_INVALID - // - // Disable: - // - _EM_DENORMAL - // - _EM_OVERFLOW - // - _EM_UNDERFLOW - // - _EM_INEXACT - - floatControlWord = (floatControlWord & ~_MCW_EM) | (_EM_DENORMAL | _EM_INEXACT | EM_UNDERFLOW | _EM_OVERFLOW); - floatMxCsr = (floatMxCsr & ~_MM_MASK_MASK) | (_MM_MASK_DENORM | _MM_MASK_INEXACT | _MM_MASK_UNDERFLOW | _MM_MASK_OVERFLOW); - } - - if (eFPESeverity == eFPE_All) - { - // Enable: - // - _EM_ZERODIVIDE - // - _EM_INVALID - // - _EM_UNDERFLOW - // - _EM_OVERFLOW - // - // Disable: - // - _EM_INEXACT - // - _EM_DENORMAL - - floatControlWord = (floatControlWord & ~_MCW_EM) | (_EM_INEXACT | _EM_DENORMAL); - floatMxCsr = (floatMxCsr & ~_MM_MASK_MASK) | (_MM_MASK_INEXACT | _MM_MASK_DENORM); - } -#endif - - ctx.ContextFlags = CONTEXT_ALL; - if (SetThreadContext(hThread, &ctx) == 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Error setting ThreadContext for ThreadID: %u", nThreadId); - ResumeThread(hThread); - CloseHandle(hThread); - return; - } - - ResumeThread(hThread); - CloseHandle(hThread); - } - - ////////////////////////////////////////////////////////////////////////// - uint GetFloatingPointExceptionMask() - { - uint nMask = 0; - _clearfp(); - _controlfp_s(&nMask, 0, 0); - return nMask; - } - - ////////////////////////////////////////////////////////////////////////// - void SetFloatingPointExceptionMask(uint nMask) - { - uint temp = 0; - _clearfp(); - const unsigned int kAllowedBits = _MCW_DN | _MCW_EM | _MCW_RC; - _controlfp_s(&temp, nMask, kAllowedBits); - } -} diff --git a/Code/CryEngine/CrySystem/DebugCallStack.cpp b/Code/CryEngine/CrySystem/DebugCallStack.cpp deleted file mode 100644 index f33e793db6..0000000000 --- a/Code/CryEngine/CrySystem/DebugCallStack.cpp +++ /dev/null @@ -1,926 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "DebugCallStack.h" - -#if defined(WIN32) || defined(WIN64) - -#include -#include -#include -#include "System.h" - -#include -#include - -#include "resource.h" -__pragma(comment(lib, "version.lib")) - -//! Needs one external of DLL handle. -extern HMODULE gDLLHandle; - -#include - -#define MAX_PATH_LENGTH 1024 -#define MAX_SYMBOL_LENGTH 512 - -static HWND hwndException = 0; -static bool g_bUserDialog = true; // true=on crash show dialog box, false=supress user interaction - -static int PrintException(EXCEPTION_POINTERS* pex); - -static bool IsFloatingPointException(EXCEPTION_POINTERS* pex); - -extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers); -extern LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExceptionPointers, const char* szDumpPath, MINIDUMP_TYPE mdumpValue); - -//============================================================================= -CONTEXT CaptureCurrentContext() -{ - CONTEXT context; - memset(&context, 0, sizeof(context)); - context.ContextFlags = CONTEXT_FULL; - RtlCaptureContext(&context); - - return context; -} - -LONG __stdcall CryUnhandledExceptionHandler(EXCEPTION_POINTERS* pex) -{ - return DebugCallStack::instance()->handleException(pex); -} - - -BOOL CALLBACK EnumModules( - PCSTR ModuleName, - DWORD64 BaseOfDll, - PVOID UserContext) -{ - DebugCallStack::TModules& modules = *static_cast(UserContext); - modules[(void*)BaseOfDll] = ModuleName; - - return TRUE; -} -//============================================================================= -// Class Statics -//============================================================================= - -// Return single instance of class. -IDebugCallStack* IDebugCallStack::instance() -{ - static DebugCallStack sInstance; - return &sInstance; -} - -//------------------------------------------------------------------------------------------------------------------------ -// Sets up the symbols for functions in the debug file. -//------------------------------------------------------------------------------------------------------------------------ -DebugCallStack::DebugCallStack() - : prevExceptionHandler(0) - , m_pSystem(0) - , m_nSkipNumFunctions(0) - , m_bCrash(false) - , m_szBugMessage(NULL) -{ -} - -DebugCallStack::~DebugCallStack() -{ -} - -void DebugCallStack::RemoveOldFiles() -{ - RemoveFile("error.log"); - RemoveFile("error.bmp"); - RemoveFile("error.dmp"); -} - -void DebugCallStack::RemoveFile(const char* szFileName) -{ - FILE* pFile = nullptr; - azfopen(&pFile, szFileName, "r"); - const bool bFileExists = (pFile != NULL); - - if (bFileExists) - { - fclose(pFile); - - WriteLineToLog("Removing file \"%s\"...", szFileName); - if (remove(szFileName) == 0) - { - WriteLineToLog("File successfully removed."); - } - else - { - WriteLineToLog("Couldn't remove file!"); - } - } -} - -void DebugCallStack::installErrorHandler(ISystem* pSystem) -{ - m_pSystem = pSystem; - prevExceptionHandler = (void*)SetUnhandledExceptionFilter(CryUnhandledExceptionHandler); -} - -////////////////////////////////////////////////////////////////////////// -void DebugCallStack::SetUserDialogEnable(const bool bUserDialogEnable) -{ - g_bUserDialog = bUserDialogEnable; -} - - -DWORD g_idDebugThreads[10]; -const char* g_nameDebugThreads[10]; -int g_nDebugThreads = 0; -volatile int g_lockThreadDumpList = 0; - -void MarkThisThreadForDebugging(const char* name) -{ - EBUS_EVENT(AZ::Debug::EventTraceDrillerSetupBus, SetThreadName, AZStd::this_thread::get_id(), name); - - WriteLock lock(g_lockThreadDumpList); - DWORD id = GetCurrentThreadId(); - if (g_nDebugThreads == sizeof(g_idDebugThreads) / sizeof(g_idDebugThreads[0])) - { - return; - } - for (int i = 0; i < g_nDebugThreads; i++) - { - if (g_idDebugThreads[i] == id) - { - return; - } - } - g_nameDebugThreads[g_nDebugThreads] = name; - g_idDebugThreads[g_nDebugThreads++] = id; - ((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions); -} - -void UnmarkThisThreadFromDebugging() -{ - WriteLock lock(g_lockThreadDumpList); - DWORD id = GetCurrentThreadId(); - for (int i = g_nDebugThreads - 1; i >= 0; i--) - { - if (g_idDebugThreads[i] == id) - { - memmove(g_idDebugThreads + i, g_idDebugThreads + i + 1, (g_nDebugThreads - 1 - i) * sizeof(g_idDebugThreads[0])); - memmove(g_nameDebugThreads + i, g_nameDebugThreads + i + 1, (g_nDebugThreads - 1 - i) * sizeof(g_nameDebugThreads[0])); - --g_nDebugThreads; - } - } -} - -extern int prev_sys_float_exceptions; -void UpdateFPExceptionsMaskForThreads() -{ - int mask = -iszero(g_cvars.sys_float_exceptions); - CONTEXT ctx; - for (int i = 0; i < g_nDebugThreads; i++) - { - if (g_idDebugThreads[i] != GetCurrentThreadId()) - { - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]); - ctx.ContextFlags = CONTEXT_ALL; - SuspendThread(hThread); - GetThreadContext(hThread, &ctx); -#ifndef WIN64 - (ctx.FloatSave.ControlWord |= 7) &= ~5 | mask; - (*(WORD*)(ctx.ExtendedRegisters + 24) |= 0x280) &= ~0x280 | mask; -#else - (ctx.FltSave.ControlWord |= 7) &= ~5 | mask; - (ctx.FltSave.MxCsr |= 0x280) &= ~0x280 | mask; -#endif - SetThreadContext(hThread, &ctx); - ResumeThread(hThread); - } - } -} - -////////////////////////////////////////////////////////////////////////// -int DebugCallStack::handleException(EXCEPTION_POINTERS* exception_pointer) -{ - if (gEnv == NULL) - { - return EXCEPTION_EXECUTE_HANDLER; - } - - ResetFPU(exception_pointer); - - prev_sys_float_exceptions = 0; - const int cached_sys_float_exceptions = g_cvars.sys_float_exceptions; - - ((CSystem*)gEnv->pSystem)->EnableFloatExceptions(0); - - if (g_cvars.sys_WER) - { - gEnv->pLog->FlushAndClose(); - return CryEngineExceptionFilterWER(exception_pointer); - } - - if (g_cvars.sys_no_crash_dialog) - { - DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX); - SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX); - } - - m_bCrash = true; - - if (g_cvars.sys_no_crash_dialog) - { - DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX); - SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX); - } - - static bool firstTime = true; - - if (g_cvars.sys_dump_aux_threads) - { - for (int i = 0; i < g_nDebugThreads; i++) - { - if (g_idDebugThreads[i] != GetCurrentThreadId()) - { - SuspendThread(OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i])); - } - } - } - - // uninstall our exception handler. - SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)prevExceptionHandler); - - if (!firstTime) - { - WriteLineToLog("Critical Exception! Called Multiple Times!"); - gEnv->pLog->FlushAndClose(); - // Exception called more then once. - return EXCEPTION_EXECUTE_HANDLER; - } - - // Print exception info: - { - char excCode[80]; - char excAddr[80]; - WriteLineToLog(""); - sprintf_s(excAddr, "0x%04X:0x%p", exception_pointer->ContextRecord->SegCs, exception_pointer->ExceptionRecord->ExceptionAddress); - sprintf_s(excCode, "0x%08X", exception_pointer->ExceptionRecord->ExceptionCode); - WriteLineToLog("Exception: %s, at Address: %s", excCode, excAddr); - - { - IMemoryManager::SProcessMemInfo memInfo; - if (gEnv->pSystem->GetIMemoryManager()->GetProcessMemInfo(memInfo)) - { - uint32 nMemUsage = (uint32)(memInfo.PagefileUsage / (1024 * 1024)); - WriteLineToLog("Virtual memory usage: %dMb", nMemUsage); - } - gEnv->szDebugStatus[SSystemGlobalEnvironment::MAX_DEBUG_STRING_LENGTH - 1] = '\0'; - WriteLineToLog("Debug Status: %s", gEnv->szDebugStatus); - } - } - - firstTime = false; - - const int ret = SubmitBug(exception_pointer); - - if (ret != IDB_IGNORE) - { - CryEngineExceptionFilterWER(exception_pointer); - } - - gEnv->pLog->FlushAndClose(); - - if (exception_pointer->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) - { - // This is non continuable exception. abort application now. - exit(exception_pointer->ExceptionRecord->ExceptionCode); - } - - //typedef long (__stdcall *ExceptionFunc)(EXCEPTION_POINTERS*); - //ExceptionFunc prevFunc = (ExceptionFunc)prevExceptionHandler; - //return prevFunc( (EXCEPTION_POINTERS*)exception_pointer ); - if (ret == IDB_EXIT) - { - // Immediate exit. - // on windows, exit() and _exit() do all sorts of things, unfortuantely - // TerminateProcess is the only way to die. - TerminateProcess(GetCurrentProcess(), exception_pointer->ExceptionRecord->ExceptionCode); // we crashed, so don't return a zero exit code! - // on linux based systems, _exit will not call ATEXIT and other things, which makes it more suitable for termination in an emergency such - // as an unhandled exception. - // however, this function is a windows exception handler. - } - else if (ret == IDB_IGNORE) - { -#ifndef WIN64 - exception_pointer->ContextRecord->FloatSave.StatusWord &= ~31; - exception_pointer->ContextRecord->FloatSave.ControlWord |= 7; - (*(WORD*)(exception_pointer->ContextRecord->ExtendedRegisters + 24) &= 31) |= 0x1F80; -#else - exception_pointer->ContextRecord->FltSave.StatusWord &= ~31; - exception_pointer->ContextRecord->FltSave.ControlWord |= 7; - (exception_pointer->ContextRecord->FltSave.MxCsr &= 31) |= 0x1F80; -#endif - firstTime = true; - prevExceptionHandler = (void*)SetUnhandledExceptionFilter(CryUnhandledExceptionHandler); - g_cvars.sys_float_exceptions = cached_sys_float_exceptions; - ((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions); - return EXCEPTION_CONTINUE_EXECUTION; - } - - // Continue; - return EXCEPTION_EXECUTE_HANDLER; -} - -void DebugCallStack::ReportBug(const char* szErrorMessage) -{ - WriteLineToLog("Reporting bug: %s", szErrorMessage); - - m_szBugMessage = szErrorMessage; - m_context = CaptureCurrentContext(); - SubmitBug(NULL); - m_szBugMessage = NULL; -} - -void DebugCallStack::dumpCallStack(std::vector& funcs) -{ - WriteLineToLog("============================================================================="); - int len = (int)funcs.size(); - for (int i = 0; i < len; i++) - { - const char* str = funcs[i].c_str(); - WriteLineToLog("%2d) %s", len - i, str); - } - WriteLineToLog("============================================================================="); -} - - -////////////////////////////////////////////////////////////////////////// -void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex) -{ - string path(""); - if ((gEnv) && (gEnv->pFileIO)) - { - const char* logAlias = gEnv->pFileIO->GetAlias("@log@"); - if (!logAlias) - { - logAlias = gEnv->pFileIO->GetAlias("@root@"); - } - if (logAlias) - { - path = logAlias; - path += "/"; - } - } - - string fileName = path; - fileName += "error.log"; - - struct stat fileInfo; - string timeStamp; - string backupPath; - if (gEnv->IsDedicated()) - { - backupPath = PathUtil::ToUnixPath(PathUtil::AddSlash(path + "DumpBackups")); - gEnv->pFileIO->CreatePath(backupPath.c_str()); - - if (stat(fileName.c_str(), &fileInfo) == 0) - { - // Backup log - tm creationTime; - localtime_s(&creationTime, &fileInfo.st_mtime); - char tempBuffer[32]; - strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime); - timeStamp = tempBuffer; - - string backupFileName = backupPath + timeStamp + " error.log"; - CopyFile(fileName.c_str(), backupFileName.c_str(), true); - } - } - - FILE* f = nullptr; - azfopen(&f, fileName.c_str(), "wt"); - - CDebugAllowFileAccess ignoreInvalidFileAccess; - - static char errorString[s_iCallStackSize]; - errorString[0] = 0; - - // Time and Version. - char versionbuf[1024]; - azstrcpy(versionbuf, AZ_ARRAY_SIZE(versionbuf), ""); - PutVersion(versionbuf, AZ_ARRAY_SIZE(versionbuf)); - cry_strcat(errorString, versionbuf); - cry_strcat(errorString, "\n"); - - char excCode[MAX_WARNING_LENGTH]; - char excAddr[80]; - char desc[1024]; - char excDesc[MAX_WARNING_LENGTH]; - - // make sure the mouse cursor is visible - ShowCursor(TRUE); - - const char* excName; - if (m_bIsFatalError || !pex) - { - const char* const szMessage = m_bIsFatalError ? s_szFatalErrorCode : m_szBugMessage; - excName = szMessage; - cry_strcpy(excCode, szMessage); - cry_strcpy(excAddr, ""); - cry_strcpy(desc, ""); - cry_strcpy(m_excModule, ""); - cry_strcpy(excDesc, szMessage); - } - else - { - sprintf_s(excAddr, "0x%04X:0x%p", pex->ContextRecord->SegCs, pex->ExceptionRecord->ExceptionAddress); - sprintf_s(excCode, "0x%08X", pex->ExceptionRecord->ExceptionCode); - excName = TranslateExceptionCode(pex->ExceptionRecord->ExceptionCode); - cry_strcpy(desc, ""); - sprintf_s(excDesc, "%s\r\n%s", excName, desc); - - - if (pex->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - { - if (pex->ExceptionRecord->NumberParameters > 1) - { - ULONG_PTR iswrite = pex->ExceptionRecord->ExceptionInformation[0]; - DWORD64 accessAddr = pex->ExceptionRecord->ExceptionInformation[1]; - if (iswrite) - { - sprintf_s(desc, "Attempt to write data to address 0x%08llu\r\nThe memory could not be \"written\"", accessAddr); - } - else - { - sprintf_s(desc, "Attempt to read from address 0x%08llu\r\nThe memory could not be \"read\"", accessAddr); - } - } - } - } - - - WriteLineToLog("Exception Code: %s", excCode); - WriteLineToLog("Exception Addr: %s", excAddr); - WriteLineToLog("Exception Module: %s", m_excModule); - WriteLineToLog("Exception Name : %s", excName); - WriteLineToLog("Exception Description: %s", desc); - - - cry_strcpy(m_excDesc, excDesc); - cry_strcpy(m_excAddr, excAddr); - cry_strcpy(m_excCode, excCode); - - - char errs[32768]; - sprintf_s(errs, "Exception Code: %s\nException Addr: %s\nException Module: %s\nException Description: %s, %s\n", - excCode, excAddr, m_excModule, excName, desc); - - - IMemoryManager::SProcessMemInfo memInfo; - if (gEnv->pSystem->GetIMemoryManager()->GetProcessMemInfo(memInfo)) - { - char memoryString[256]; - double MB = 1024 * 1024; - sprintf_s(memoryString, "Memory in use: %3.1fMB\n", (double)(memInfo.PagefileUsage) / MB); - cry_strcat(errs, memoryString); - } - { - const int tempStringSize = 256; - char tempString[tempStringSize]; - - gEnv->szDebugStatus[SSystemGlobalEnvironment::MAX_DEBUG_STRING_LENGTH - 1] = '\0'; - sprintf_s(tempString, tempStringSize, "Debug Status: %s\n", gEnv->szDebugStatus); - cry_strcat(errs, tempString); - - sprintf_s(tempString, tempStringSize, "Out of Memory: %d\n", gEnv->bIsOutOfMemory); - cry_strcat(errs, tempString); - } - cry_strcat(errs, "\nCall Stack Trace:\n"); - - std::vector funcs; - if (gEnv->bIsOutOfMemory) - { - cry_strcat(errs, "1) OUT_OF_MEMORY()\n"); - } - else - { - AZ::Debug::StackFrame frames[25]; - AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)]; - unsigned int numFrames = AZ::Debug::StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), 3); - if (numFrames) - { - AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines); - for (unsigned int i = 0; i < numFrames; i++) - { - funcs.push_back(lines[i]); - } - } - dumpCallStack(funcs); - // Fill call stack. - char str[s_iCallStackSize]; - cry_strcpy(str, ""); - for (unsigned int i = 0; i < funcs.size(); i++) - { - char temp[s_iCallStackSize]; - sprintf_s(temp, "%2zd) %s", funcs.size() - i, (const char*)funcs[i].c_str()); - cry_strcat(str, temp); - cry_strcat(str, "\r\n"); - cry_strcat(errs, temp); - cry_strcat(errs, "\n"); - } - cry_strcpy(m_excCallstack, str); - } - - cry_strcat(errorString, errs); - - if (f) - { - fwrite(errorString, strlen(errorString), 1, f); - if (!gEnv->bIsOutOfMemory) - { - if (g_cvars.sys_dump_aux_threads) - { - for (int i = 0; i < g_nDebugThreads; i++) - { - if (g_idDebugThreads[i] != GetCurrentThreadId()) - { - fprintf(f, "\n\nSuspended thread (%s):\n", g_nameDebugThreads[i]); - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]); - - // mirrors the AZ::Debug::Trace::PrintCallstack() functionality, but prints to a file - { - AZ::Debug::StackFrame frames[10]; - - // Without StackFrame explicit alignment frames array is aligned to 4 bytes - // which causes the stack tracing to fail. - AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)]; - - unsigned int numFrames = AZ::Debug::StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), 0, hThread); - if (numFrames) - { - AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines); - for (unsigned int i2 = 0; i2 < numFrames; ++i2) - { - fprintf(f, "%2d) %s\n", numFrames - i2, lines[i2]); - } - } - } - - ResumeThread(hThread); - } - } - } - } - fflush(f); - fclose(f); - } - - if (pex) - { - MINIDUMP_TYPE mdumpValue; - bool bDump = true; - switch (g_cvars.sys_dump_type) - { - case 0: - bDump = false; - break; - case 1: - mdumpValue = MiniDumpNormal; - break; - case 2: - mdumpValue = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithDataSegs); - break; - case 3: - mdumpValue = MiniDumpWithFullMemory; - break; - default: - mdumpValue = (MINIDUMP_TYPE)g_cvars.sys_dump_type; - break; - } - if (bDump) - { - fileName = path + "error.dmp"; - - if (gEnv->IsDedicated() && stat(fileName.c_str(), &fileInfo) == 0) - { - // Backup dump (use timestamp from error.log if available) - if (timeStamp.empty()) - { - tm creationTime; - localtime_s(&creationTime, &fileInfo.st_mtime); - char tempBuffer[32]; - strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime); - timeStamp = tempBuffer; - } - - string backupFileName = backupPath + timeStamp + " error.dmp"; - CopyFile(fileName.c_str(), backupFileName.c_str(), true); - } - - CryEngineExceptionFilterMiniDump(pex, fileName.c_str(), mdumpValue); - } - } - - //if no crash dialog don't even submit the bug - if (m_postBackupProcess && g_cvars.sys_no_crash_dialog == 0 && g_bUserDialog) - { - m_postBackupProcess(); - } - else - { - // lawsonn: Disabling the JIRA-based crash reporter for now - // we'll need to deal with it our own way, pending QA. - // if you're customizing the engine this is also your opportunity to deal with it. - if (g_cvars.sys_no_crash_dialog != 0 || !g_bUserDialog) - { - // ------------ place custom crash handler here --------------------- - // it should launch an executable! - /// by this time, error.bmp will be in the engine root folder - // error.log and error.dmp will also be present in the engine root folder - // if your error dumper wants those, it should zip them up and send them or offer to do so. - // ------------------------------------------------------------------ - } - } - const bool bQuitting = !gEnv || !gEnv->pSystem || gEnv->pSystem->IsQuitting(); - - //[AlexMcC|16.04.10] When the engine is shutting down, MessageBox doesn't display a box - // and immediately returns IDYES. Avoid this by just not trying to save if we're quitting. - // Don't ask to save if this isn't a real crash (a real crash has exception pointers) - if (g_cvars.sys_no_crash_dialog == 0 && g_bUserDialog && gEnv->IsEditor() && !bQuitting && pex) - { - BackupCurrentLevel(); - - const INT_PTR res = DialogBoxParam(gDLLHandle, MAKEINTRESOURCE(IDD_CONFIRM_SAVE_LEVEL), NULL, DebugCallStack::ConfirmSaveDialogProc, NULL); - if (res == IDB_CONFIRM_SAVE) - { - if (SaveCurrentLevel()) - { - MessageBox(NULL, "Level has been successfully saved!\r\nPress Ok to terminate Editor.", "Save", MB_OK); - } - else - { - MessageBox(NULL, "Error saving level.\r\nPress Ok to terminate Editor.", "Save", MB_OK | MB_ICONWARNING); - } - } - } - - if (g_cvars.sys_no_crash_dialog != 0 || !g_bUserDialog) - { - // terminate immediately - since we're in a crash, there is no point unwinding stack, we've already done access violation or worse. - // calling exit will only cause further death down the line... - TerminateProcess(GetCurrentProcess(), pex->ExceptionRecord->ExceptionCode); - } -} - - -INT_PTR CALLBACK DebugCallStack::ExceptionDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - static EXCEPTION_POINTERS* pex; - - static char errorString[32768] = ""; - - switch (message) - { - case WM_INITDIALOG: - { - pex = (EXCEPTION_POINTERS*)lParam; - HWND h; - - if (pex->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) - { - // Disable continue button for non continuable exceptions. - //h = GetDlgItem( hwndDlg,IDB_CONTINUE ); - //if (h) EnableWindow( h,FALSE ); - } - - DebugCallStack* pDCS = static_cast(DebugCallStack::instance()); - - h = GetDlgItem(hwndDlg, IDC_EXCEPTION_DESC); - if (h) - { - SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excDesc); - } - - h = GetDlgItem(hwndDlg, IDC_EXCEPTION_CODE); - if (h) - { - SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excCode); - } - - h = GetDlgItem(hwndDlg, IDC_EXCEPTION_MODULE); - if (h) - { - SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excModule); - } - - h = GetDlgItem(hwndDlg, IDC_EXCEPTION_ADDRESS); - if (h) - { - SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excAddr); - } - - // Fill call stack. - HWND callStack = GetDlgItem(hwndDlg, IDC_CALLSTACK); - if (callStack) - { - SendMessage(callStack, WM_SETTEXT, FALSE, (LPARAM)pDCS->m_excCallstack); - } - - if (hwndException) - { - DestroyWindow(hwndException); - hwndException = 0; - } - - if (IsFloatingPointException(pex)) - { - EnableWindow(GetDlgItem(hwndDlg, IDB_IGNORE), TRUE); - } - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDB_EXIT: - case IDB_IGNORE: - // Fall through. - - EndDialog(hwndDlg, wParam); - return TRUE; - } - } - return FALSE; -} - -INT_PTR CALLBACK DebugCallStack::ConfirmSaveDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, [[maybe_unused]] LPARAM lParam) -{ - switch (message) - { - case WM_INITDIALOG: - { - // The user might be holding down the spacebar while the engine crashes. - // If we don't remove keyboard focus from this dialog, the keypress will - // press the default button before the dialog actually appears, even if - // the user has already released the key, which is bad. - SetFocus(NULL); - } break; - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDB_CONFIRM_SAVE: // Fall through - case IDB_DONT_SAVE: - { - EndDialog(hwndDlg, wParam); - return TRUE; - } - } - } break; - } - - return FALSE; -} - -bool DebugCallStack::BackupCurrentLevel() -{ - CSystem* pSystem = static_cast(m_pSystem); - if (pSystem && pSystem->GetUserCallback()) - { - return pSystem->GetUserCallback()->OnBackupDocument(); - } - - return false; -} - -bool DebugCallStack::SaveCurrentLevel() -{ - CSystem* pSystem = static_cast(m_pSystem); - if (pSystem && pSystem->GetUserCallback()) - { - return pSystem->GetUserCallback()->OnSaveDocument(); - } - - return false; -} - -int DebugCallStack::SubmitBug(EXCEPTION_POINTERS* exception_pointer) -{ - int ret = IDB_EXIT; - - assert(!hwndException); - - RemoveOldFiles(); - - AZ::Debug::Trace::PrintCallstack("", 2); - - LogExceptionInfo(exception_pointer); - - if (IsFloatingPointException(exception_pointer)) - { - //! Print exception dialog. - ret = PrintException(exception_pointer); - } - - return ret; -} - -void DebugCallStack::ResetFPU(EXCEPTION_POINTERS* pex) -{ - if (IsFloatingPointException(pex)) - { - // How to reset FPU: http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_10310953.html - _clearfp(); -#ifndef WIN64 - pex->ContextRecord->FloatSave.ControlWord |= 0x2F; - pex->ContextRecord->FloatSave.StatusWord &= ~0x8080; -#endif - } -} - -string DebugCallStack::GetModuleNameForAddr(void* addr) -{ - if (m_modules.empty()) - { - return "[unknown]"; - } - - if (addr < m_modules.begin()->first) - { - return "[unknown]"; - } - - TModules::const_iterator it = m_modules.begin(); - TModules::const_iterator end = m_modules.end(); - for (; ++it != end; ) - { - if (addr < it->first) - { - return (--it)->second; - } - } - - //if address is higher than the last module, we simply assume it is in the last module. - return m_modules.rbegin()->second; -} - -void DebugCallStack::GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line) -{ - AZ::Debug::SymbolStorage::StackLine func, file, module; - AZ::Debug::SymbolStorage::FindFunctionFromIP(addr, &func, &file, &module, line, baseAddr); - procName = func; - filename = file; -} - -string DebugCallStack::GetCurrentFilename() -{ - char fullpath[MAX_PATH_LENGTH + 1]; - GetModuleFileName(NULL, fullpath, MAX_PATH_LENGTH); - return fullpath; -} - -static bool IsFloatingPointException(EXCEPTION_POINTERS* pex) -{ - if (!pex) - { - return false; - } - - DWORD exceptionCode = pex->ExceptionRecord->ExceptionCode; - switch (exceptionCode) - { - case EXCEPTION_FLT_DENORMAL_OPERAND: - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - case EXCEPTION_FLT_INEXACT_RESULT: - case EXCEPTION_FLT_INVALID_OPERATION: - case EXCEPTION_FLT_OVERFLOW: - case EXCEPTION_FLT_UNDERFLOW: - case STATUS_FLOAT_MULTIPLE_FAULTS: - case STATUS_FLOAT_MULTIPLE_TRAPS: - return true; - - default: - return false; - } -} - -int DebugCallStack::PrintException(EXCEPTION_POINTERS* exception_pointer) -{ - return (int)DialogBoxParam(gDLLHandle, MAKEINTRESOURCE(IDD_CRITICAL_ERROR), NULL, DebugCallStack::ExceptionDialogProc, (LPARAM)exception_pointer); -} - -#else -void MarkThisThreadForDebugging(const char*) {} -void UnmarkThisThreadFromDebugging() {} -void UpdateFPExceptionsMaskForThreads() {} -#endif //WIN32 diff --git a/Code/CryEngine/CrySystem/DebugCallStack.h b/Code/CryEngine/CrySystem/DebugCallStack.h deleted file mode 100644 index c37e6ba0d4..0000000000 --- a/Code/CryEngine/CrySystem/DebugCallStack.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H -#define CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H -#pragma once - - -#include "IDebugCallStack.h" - -#if defined (WIN32) || defined (WIN64) - -//! Limits the maximal number of functions in call stack. -const int MAX_DEBUG_STACK_ENTRIES_FILE_DUMP = 12; - -struct ISystem; - -//!============================================================================ -//! -//! DebugCallStack class, capture call stack information from symbol files. -//! -//!============================================================================ -class DebugCallStack - : public IDebugCallStack -{ -public: - DebugCallStack(); - virtual ~DebugCallStack(); - - ISystem* GetSystem() { return m_pSystem; }; - - virtual string GetModuleNameForAddr(void* addr); - virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line); - virtual string GetCurrentFilename(); - - void installErrorHandler(ISystem* pSystem); - virtual int handleException(EXCEPTION_POINTERS* exception_pointer); - - virtual void ReportBug(const char*); - - void dumpCallStack(std::vector& functions); - - void SetUserDialogEnable(const bool bUserDialogEnable); - - typedef std::map TModules; -protected: - static void RemoveOldFiles(); - static void RemoveFile(const char* szFileName); - - static int PrintException(EXCEPTION_POINTERS* exception_pointer); - static INT_PTR CALLBACK ExceptionDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK ConfirmSaveDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam); - - void LogExceptionInfo(EXCEPTION_POINTERS* exception_pointer); - bool BackupCurrentLevel(); - bool SaveCurrentLevel(); - int SubmitBug(EXCEPTION_POINTERS* exception_pointer); - void ResetFPU(EXCEPTION_POINTERS* pex); - - static const int s_iCallStackSize = 32768; - - char m_excLine[256]; - char m_excModule[128]; - - char m_excDesc[MAX_WARNING_LENGTH]; - char m_excCode[MAX_WARNING_LENGTH]; - char m_excAddr[80]; - char m_excCallstack[s_iCallStackSize]; - - void* prevExceptionHandler; - - bool m_bCrash; - const char* m_szBugMessage; - - ISystem* m_pSystem; - - int m_nSkipNumFunctions; - CONTEXT m_context; - - TModules m_modules; -}; - -#endif //WIN32 - -#endif // CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H diff --git a/Code/CryEngine/CrySystem/DllMain.cpp b/Code/CryEngine/CrySystem/DllMain.cpp index 6173ebc0c6..c3a15812ce 100644 --- a/Code/CryEngine/CrySystem/DllMain.cpp +++ b/Code/CryEngine/CrySystem/DllMain.cpp @@ -14,7 +14,6 @@ #include "CrySystem_precompiled.h" #include "System.h" #include -#include "DebugCallStack.h" #if defined(AZ_RESTRICTED_PLATFORM) #undef AZ_RESTRICTED_SECTION @@ -72,10 +71,6 @@ public: { switch (event) { - case ESYSTEM_EVENT_LEVEL_UNLOAD: - gEnv->pSystem->SetThreadState(ESubsys_Physics, false); - break; - case ESYSTEM_EVENT_LEVEL_LOAD_START: case ESYSTEM_EVENT_LEVEL_LOAD_END: { @@ -87,7 +82,6 @@ public: { CryCleanup(); STLALLOCATOR_CLEANUP; - gEnv->pSystem->SetThreadState(ESubsys_Physics, true); break; } } @@ -135,21 +129,6 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar startupParams.pUserCallback->OnSystemConnect(pSystem); } - // Environment Variable to signal we don't want to override our exception handler - our crash report system will set this - auto envVar = AZ::Environment::FindVariable("ExceptionHandlerIsSet"); - bool handlerIsSet = (envVar && *envVar); - - if (!startupParams.bMinimal && !handlerIsSet) // in minimal mode, we want to crash when we crash! - { -#if defined(WIN32) - // Install exception handler in Release modes. - ((DebugCallStack*)IDebugCallStack::instance())->installErrorHandler(pSystem); -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION DLLMAIN_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE(DllMain_cpp) -#endif - } - bool retVal = false; { AZ::Debug::StartupLogSinkReporter initLogSink; @@ -171,20 +150,5 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar return pSystem; } - -CRYSYSTEM_API void WINAPI CryInstallUnhandledExceptionHandler() -{ -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION DLLMAIN_CPP_SECTION_4 -#include AZ_RESTRICTED_FILE(DllMain_cpp) -#endif -} - -#if defined(ENABLE_PROFILING_CODE) && !defined(LINUX) && !defined(APPLE) -CRYSYSTEM_API void CryInstallPostExceptionHandler(void (* PostExceptionHandlerCallback)()) -{ - return IDebugCallStack::instance()->FileCreationCallback(PostExceptionHandlerCallback); -} -#endif }; diff --git a/Code/CryEngine/CrySystem/IDebugCallStack.cpp b/Code/CryEngine/CrySystem/IDebugCallStack.cpp deleted file mode 100644 index 3d865dee6c..0000000000 --- a/Code/CryEngine/CrySystem/IDebugCallStack.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : A multiplatform base class for handling errors and collecting call stacks - - -#include "CrySystem_precompiled.h" -#include "IDebugCallStack.h" -#include -#include "System.h" -#include -#include -#include -#include -//#if !defined(LINUX) - -#include - -const char* const IDebugCallStack::s_szFatalErrorCode = "FATAL_ERROR"; - -IDebugCallStack::IDebugCallStack() - : m_bIsFatalError(false) - , m_postBackupProcess(0) - , m_memAllocFileHandle(AZ::IO::InvalidHandle) -{ -} - -IDebugCallStack::~IDebugCallStack() -{ - StopMemLog(); -} - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_SINGLETON -IDebugCallStack* IDebugCallStack::instance() -{ - static IDebugCallStack sInstance; - return &sInstance; -} -#endif - -void IDebugCallStack::FileCreationCallback(void (* postBackupProcess)()) -{ - m_postBackupProcess = postBackupProcess; -} -////////////////////////////////////////////////////////////////////////// -void IDebugCallStack::LogCallstack() -{ - AZ::Debug::Trace::PrintCallstack("", 2); -} - -const char* IDebugCallStack::TranslateExceptionCode(DWORD dwExcept) -{ - switch (dwExcept) - { -#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_TRANSLATE - case EXCEPTION_ACCESS_VIOLATION: - return "EXCEPTION_ACCESS_VIOLATION"; - break; - case EXCEPTION_DATATYPE_MISALIGNMENT: - return "EXCEPTION_DATATYPE_MISALIGNMENT"; - break; - case EXCEPTION_BREAKPOINT: - return "EXCEPTION_BREAKPOINT"; - break; - case EXCEPTION_SINGLE_STEP: - return "EXCEPTION_SINGLE_STEP"; - break; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"; - break; - case EXCEPTION_FLT_DENORMAL_OPERAND: - return "EXCEPTION_FLT_DENORMAL_OPERAND"; - break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - return "EXCEPTION_FLT_DIVIDE_BY_ZERO"; - break; - case EXCEPTION_FLT_INEXACT_RESULT: - return "EXCEPTION_FLT_INEXACT_RESULT"; - break; - case EXCEPTION_FLT_INVALID_OPERATION: - return "EXCEPTION_FLT_INVALID_OPERATION"; - break; - case EXCEPTION_FLT_OVERFLOW: - return "EXCEPTION_FLT_OVERFLOW"; - break; - case EXCEPTION_FLT_STACK_CHECK: - return "EXCEPTION_FLT_STACK_CHECK"; - break; - case EXCEPTION_FLT_UNDERFLOW: - return "EXCEPTION_FLT_UNDERFLOW"; - break; - case EXCEPTION_INT_DIVIDE_BY_ZERO: - return "EXCEPTION_INT_DIVIDE_BY_ZERO"; - break; - case EXCEPTION_INT_OVERFLOW: - return "EXCEPTION_INT_OVERFLOW"; - break; - case EXCEPTION_PRIV_INSTRUCTION: - return "EXCEPTION_PRIV_INSTRUCTION"; - break; - case EXCEPTION_IN_PAGE_ERROR: - return "EXCEPTION_IN_PAGE_ERROR"; - break; - case EXCEPTION_ILLEGAL_INSTRUCTION: - return "EXCEPTION_ILLEGAL_INSTRUCTION"; - break; - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - return "EXCEPTION_NONCONTINUABLE_EXCEPTION"; - break; - case EXCEPTION_STACK_OVERFLOW: - return "EXCEPTION_STACK_OVERFLOW"; - break; - case EXCEPTION_INVALID_DISPOSITION: - return "EXCEPTION_INVALID_DISPOSITION"; - break; - case EXCEPTION_GUARD_PAGE: - return "EXCEPTION_GUARD_PAGE"; - break; - case EXCEPTION_INVALID_HANDLE: - return "EXCEPTION_INVALID_HANDLE"; - break; - //case EXCEPTION_POSSIBLE_DEADLOCK: return "EXCEPTION_POSSIBLE_DEADLOCK"; break ; - - case STATUS_FLOAT_MULTIPLE_FAULTS: - return "STATUS_FLOAT_MULTIPLE_FAULTS"; - break; - case STATUS_FLOAT_MULTIPLE_TRAPS: - return "STATUS_FLOAT_MULTIPLE_TRAPS"; - break; - - -#endif - default: - return "Unknown"; - break; - } -} - -void IDebugCallStack::PutVersion(char* str, size_t length) -{ -AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option") - - if (!gEnv || !gEnv->pSystem) - { - return; - } - - char sFileVersion[128]; - gEnv->pSystem->GetFileVersion().ToString(sFileVersion, sizeof(sFileVersion)); - - char sProductVersion[128]; - gEnv->pSystem->GetProductVersion().ToString(sProductVersion, sizeof(sFileVersion)); - - - //! Get time. - time_t ltime; - time(<ime); - tm* today = localtime(<ime); - - char s[1024]; - //! Use strftime to build a customized time string. - strftime(s, 128, "Logged at %#c\n", today); - azstrcat(str, length, s); - sprintf_s(s, "FileVersion: %s\n", sFileVersion); - azstrcat(str, length, s); - sprintf_s(s, "ProductVersion: %s\n", sProductVersion); - azstrcat(str, length, s); - - if (gEnv->pLog) - { - const char* logfile = gEnv->pLog->GetFileName(); - if (logfile) - { - sprintf (s, "LogFile: %s\n", logfile); - azstrcat(str, length, s); - } - } - - AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath(); - azstrcat(str, length, "ProjectDir: "); - azstrcat(str, length, projectPath.c_str()); - azstrcat(str, length, "\n"); - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_APPEND_MODULENAME - GetModuleFileNameA(NULL, s, sizeof(s)); - - // Log EXE filename only if possible (not full EXE path which could contain sensitive info) - AZStd::string exeName; - if (AZ::StringFunc::Path::GetFullFileName(s, exeName)) - { - azstrcat(str, length, "Executable: "); - azstrcat(str, length, exeName.c_str()); - -# ifdef AZ_DEBUG_BUILD - azstrcat(str, length, " (debug: yes"); -# else - azstrcat(str, length, " (debug: no"); -# endif - } -#endif -AZ_POP_DISABLE_WARNING -} - - -//Crash the application, in this way the debug callstack routine will be called and it will create all the necessary files (error.log, dump, and eventually screenshot) -void IDebugCallStack::FatalError(const char* description) -{ - m_bIsFatalError = true; - WriteLineToLog(description); - -#ifndef _RELEASE - bool bShowDebugScreen = g_cvars.sys_no_crash_dialog == 0; - // showing the debug screen is not safe when not called from mainthread - // it normally leads to a infinity recursion followed by a stack overflow, preventing - // useful call stacks, thus they are disabled - bShowDebugScreen = bShowDebugScreen && gEnv->mMainThreadId == CryGetCurrentThreadId(); - if (bShowDebugScreen) - { - EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "Open 3D Engine Fatal Error", description, false); - } -#endif - -#if defined(WIN32) || !defined(_RELEASE) - int* p = 0x0; - PREFAST_SUPPRESS_WARNING(6011) * p = 1; // we're intentionally crashing here -#endif -} - -void IDebugCallStack::WriteLineToLog(const char* format, ...) -{ - CDebugAllowFileAccess allowFileAccess; - - va_list ArgList; - char szBuffer[MAX_WARNING_LENGTH]; - va_start(ArgList, format); - vsnprintf_s(szBuffer, sizeof(szBuffer), sizeof(szBuffer) - 1, format, ArgList); - cry_strcat(szBuffer, "\n"); - szBuffer[sizeof(szBuffer) - 1] = '\0'; - va_end(ArgList); - - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - AZ::IO::FileIOBase::GetDirectInstance()->Open("@Log@\\error.log", AZ::IO::GetOpenModeFromStringMode("a+t"), fileHandle); - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::FileIOBase::GetDirectInstance()->Write(fileHandle, szBuffer, strlen(szBuffer)); - AZ::IO::FileIOBase::GetDirectInstance()->Flush(fileHandle); - AZ::IO::FileIOBase::GetDirectInstance()->Close(fileHandle); - } -} - -////////////////////////////////////////////////////////////////////////// -void IDebugCallStack::StartMemLog() -{ - AZ::IO::FileIOBase::GetDirectInstance()->Open("@Log@\\memallocfile.log", AZ::IO::OpenMode::ModeWrite, m_memAllocFileHandle); - - assert(m_memAllocFileHandle != AZ::IO::InvalidHandle); -} - -////////////////////////////////////////////////////////////////////////// -void IDebugCallStack::StopMemLog() -{ - if (m_memAllocFileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::FileIOBase::GetDirectInstance()->Close(m_memAllocFileHandle); - m_memAllocFileHandle = AZ::IO::InvalidHandle; - } -} -//#endif //!defined(LINUX) diff --git a/Code/CryEngine/CrySystem/IDebugCallStack.h b/Code/CryEngine/CrySystem/IDebugCallStack.h deleted file mode 100644 index f181b73913..0000000000 --- a/Code/CryEngine/CrySystem/IDebugCallStack.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : A multiplatform base class for handling errors and collecting call stacks - -#ifndef CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H -#define CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H -#pragma once - -#include "System.h" - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_FORWARD_EXCEPTION_POINTERS -struct EXCEPTION_POINTERS; -#endif -//! Limits the maximal number of functions in call stack. -enum -{ - MAX_DEBUG_STACK_ENTRIES = 80 -}; - -class IDebugCallStack -{ -public: - // Returns single instance of DebugStack - static IDebugCallStack* instance(); - - virtual int handleException([[maybe_unused]] EXCEPTION_POINTERS* exception_pointer){return 0; } - - // returns the module name of a given address - virtual string GetModuleNameForAddr([[maybe_unused]] void* addr) { return "[unknown]"; } - - // returns the function name of a given address together with source file and line number (if available) of a given address - virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line) - { - filename = "[unknown]"; - line = 0; - baseAddr = addr; -#if defined(PLATFORM_64BIT) - procName.Format("[%016llX]", addr); -#else - procName.Format("[%08X]", addr); -#endif - } - - // returns current filename - virtual string GetCurrentFilename() { return "[unknown]"; } - - //! Dumps Current Call Stack to log. - virtual void LogCallstack(); - //triggers a fatal error, so the DebugCallstack can create the error.log and terminate the application - void FatalError(const char*); - - //Reports a bug and continues execution - virtual void ReportBug(const char*) {} - - virtual void FileCreationCallback(void (* postBackupProcess)()); - - static void WriteLineToLog(const char* format, ...); - - virtual void StartMemLog(); - virtual void StopMemLog(); - -protected: - IDebugCallStack(); - virtual ~IDebugCallStack(); - - static const char* TranslateExceptionCode(DWORD dwExcept); - static void PutVersion(char* str, size_t length); - - bool m_bIsFatalError; - static const char* const s_szFatalErrorCode; - - void (* m_postBackupProcess)(); - - AZ::IO::HandleType m_memAllocFileHandle; -}; - - - -#endif // CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H diff --git a/Code/CryEngine/CrySystem/IThreadConfigManager.h b/Code/CryEngine/CrySystem/IThreadConfigManager.h deleted file mode 100644 index 97c4d7237b..0000000000 --- a/Code/CryEngine/CrySystem/IThreadConfigManager.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -struct SThreadConfig -{ - enum eThreadParamFlag - { - eThreadParamFlag_ThreadName = BIT(0), - eThreadParamFlag_StackSize = BIT(1), - eThreadParamFlag_Affinity = BIT(2), - eThreadParamFlag_Priority = BIT(3), - eThreadParamFlag_PriorityBoost = BIT(4), - }; - - typedef uint32 TThreadParamFlag; - - const char* szThreadName; - uint32 stackSizeBytes; - uint32 affinityFlag; - int32 priority; - bool bDisablePriorityBoost; - - TThreadParamFlag paramActivityFlag; -}; - -class IThreadConfigManager -{ -public: - virtual ~IThreadConfigManager() - { - } - - //! Called once during System startup. - //! Loads the thread configuration for the executing platform from file. - virtual bool LoadConfig(const char* pcPath) = 0; - - //! Returns true if a config has been loaded. - virtual bool ConfigLoaded() const = 0; - - //! Gets the thread configuration for the specified thread on the active platform. - //! If no matching config is found a default configuration is returned (which does not have the same name as the search string). - virtual const SThreadConfig* GetThreadConfig(const char* sThreadName, ...) = 0; - virtual const SThreadConfig* GetDefaultThreadConfig() const = 0; - - //! Dump a detailed description of the thread startup configurations for this platform to the log file. - virtual void DumpThreadConfigurationsToLog() = 0; -}; diff --git a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp index b8002b74a9..0af52d8cc4 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp @@ -17,7 +17,6 @@ #include "LevelSystem.h" #include #include "IMovieSystem.h" -#include "IMaterialEffects.h" #include #include #include "CryPath.h" @@ -648,20 +647,6 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName) AZStd::string levelPath(pLevelInfo->GetPath()); - /* - ICVar *pFileCache = gEnv->pConsole->GetCVar("sys_FileCache"); CRY_ASSERT(pFileCache); - - if(pFileCache->GetIVal()) - { - if(pPak->OpenPack("",pLevelInfo->GetPath()+string("/FileCache.dat"))) - gEnv->pLog->Log("FileCache.dat loaded"); - else - gEnv->pLog->Log("FileCache.dat not loaded"); - } - */ - - m_pSystem->SetThreadState(ESubsys_Physics, false); - ICVar* pSpamDelay = gEnv->pConsole->GetCVar("log_SpamDelay"); float spamDelay = 0.0f; if (pSpamDelay) @@ -768,8 +753,6 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName) gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0); - m_pSystem->SetThreadState(ESubsys_Physics, true); - return m_pCurrentLevel; } diff --git a/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp index 2a7f8d5c5e..8b3c75cce2 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp @@ -247,8 +247,6 @@ namespace LegacyLevelSystem auto pPak = gEnv->pCryPak; - m_pSystem->SetThreadState(ESubsys_Physics, false); - ICVar* pSpamDelay = gEnv->pConsole->GetCVar("log_SpamDelay"); float spamDelay = 0.0f; if (pSpamDelay) @@ -343,8 +341,6 @@ namespace LegacyLevelSystem gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0); - m_pSystem->SetThreadState(ESubsys_Physics, true); - return true; } diff --git a/Code/CryEngine/CrySystem/Log.cpp b/Code/CryEngine/CrySystem/Log.cpp index 62cf29fef9..c51947d8bc 100644 --- a/Code/CryEngine/CrySystem/Log.cpp +++ b/Code/CryEngine/CrySystem/Log.cpp @@ -920,13 +920,7 @@ bool CLog::LogToMainThread(const char* szString, ELogType logType, bool bAdd, SL msg.bAdd = bAdd; msg.destination = destination; msg.logType = logType; - // don't try to store the log message for later in case of out of memory, since then its very likely that this allocation - // also fails and results in a stack overflow. This way we should at least get a out of memory on-screen message instead of - // a not obvious crash - if ((gEnv) && (gEnv->bIsOutOfMemory == false)) - { - m_threadSafeMsgQueue.push(msg); - } + m_threadSafeMsgQueue.push(msg); return true; } return false; @@ -1448,8 +1442,6 @@ void CLog::UpdateLoadingScreen(const char* szFormat, ...) if (CryGetCurrentThreadId() == m_nMainThreadId) { - ((CSystem*)m_pSystem)->UpdateLoadingScreen(); - #ifndef LINUX // Take this opportunity to update streaming engine. if (IStreamEngine* pStreamEngine = GetISystem()->GetStreamEngine()) diff --git a/Code/CryEngine/CrySystem/NotificationNetwork.cpp b/Code/CryEngine/CrySystem/NotificationNetwork.cpp deleted file mode 100644 index a0bd3fb9e6..0000000000 --- a/Code/CryEngine/CrySystem/NotificationNetwork.cpp +++ /dev/null @@ -1,1345 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "NotificationNetwork.h" -#include - -#include -#include - -#undef LockDebug -//#define LockDebug(str1,str2) {string strMessage;strMessage.Format(str1,str2);if (m_clients.size()) OutputDebugString(strMessage.c_str());} -#define LockDebug(str1, str2) - -// - -extern bool RCON_IsRemoteAllowedToConnect(const AZ::AzSock::AzSocketAddress& connectee); - -using namespace NotificationNetwork; - -// - -#include -class CQueryNotification - : public INotificationNetworkListener -{ - // INotificationNetworkListener -public: - virtual void OnNotificationNetworkReceive([[maybe_unused]] const void* pBuffer, [[maybe_unused]] size_t length) - { - INotificationNetwork* pNotificationNetwork = - gEnv->pSystem->GetINotificationNetwork(); - if (!pNotificationNetwork) - { - return; - } - - AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath(); - if (projectPath.empty()) - { - return; - } - - pNotificationNetwork->Send("SystemInfo", projectPath.c_str(), projectPath.size()); - } -} g_queryNotification; - -AZSOCKET CConnectionBase::CreateSocket() -{ - AZSOCKET sock = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(sock)) - { - CryLog("CNotificationNetworkClient::Create: Failed to create socket."); - return AZ_SOCKET_INVALID; - } - - if (AZ::AzSock::SetSocketOption(sock, AZ::AzSock::AzSocketOption::REUSEADDR, true)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Create: Failed to set SO_REUSEADDR option."); - return AZ_SOCKET_INVALID; - } - -#if defined (WIN32) || defined(WIN64) //MS Platforms - if (AZ::AzSock::SetSocketBlockingMode(sock, false)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Connect: Failed to set socket to asynchronous operation."); - return AZ_SOCKET_INVALID; - } - -#endif - - // TCP_NODELAY required for win32 because of high latency connection otherwise -#if defined(WIN32) - if (AZ::AzSock::EnableTCPNoDelay(sock, true)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Create: Failed to set TCP_NODELAY option."); - return AZ_SOCKET_INVALID; - } -#endif - - return sock; -} - -bool CConnectionBase::Connect(const char* address, uint16 port) -{ - AZ::AzSock::AzSocketAddress socketAddress; - socketAddress.SetAddress(address, port); - - int result = AZ::AzSock::Connect(m_socket, socketAddress); - if (AZ::AzSock::SocketErrorOccured(result)) - { - AZ::AzSock::AzSockError err = AZ::AzSock::AzSockError(result); - if (err == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK_CONN) - { - return true; - } - - if (err == AZ::AzSock::AzSockError::eASE_EISCONN) - { - if (!m_boIsConnected) - { - m_boIsConnected = true; - m_boIsFailedToConnect = false; - OnConnect(true); - } - return true; - } - - if (err == AZ::AzSock::AzSockError::eASE_EALREADY) - { - // It will happen, in case of DNS problems, or if the console is not - // reachable or turned off. - //CryLog("CNotificationNetworkClient::Connect: Failed to connect. Reason: already conencted."); - return true; - } - - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - CryLog("CNotificationNetworkClient::Connect: Failed to connect. Reason: %d ", result); - return false; - } - - return true; -} - -/* - - CChannel - -*/ - -bool CChannel::IsNameValid(const char* name) -{ - if (!name) - { - return false; - } - if (!*name) - { - return false; - } - - if (::strlen(name) > NN_CHANNEL_NAME_LENGTH_MAX) - { - return false; - } - - return true; -} - -// - -CChannel::CChannel() -{ -} - -CChannel::CChannel(const char* name) -{ - if (!name) - { - return; - } - - if (!*name) - { - return; - } - - size_t length = MIN(::strlen(name), NN_CHANNEL_NAME_LENGTH_MAX); - ::memset(m_name, 0, NN_CHANNEL_NAME_LENGTH_MAX); - ::memcpy(m_name, name, length); -} - -CChannel::~CChannel() -{ -} - -// - -void CChannel::WriteToPacketHeader(void* pPacket) const -{ - ::memcpy((uint8*)pPacket + NN_PACKET_HEADER_OFFSET_CHANNEL, - m_name, NN_CHANNEL_NAME_LENGTH_MAX); -} - -void CChannel::ReadFromPacketHeader(void* pPacket) -{ - ::memcpy(m_name, (uint8*)pPacket + NN_PACKET_HEADER_OFFSET_CHANNEL, - NN_CHANNEL_NAME_LENGTH_MAX); -} - -// - -bool CChannel::operator ==(const CChannel& channel) const -{ - return ::strncmp(m_name, channel.m_name, NN_CHANNEL_NAME_LENGTH_MAX) == 0; -} - -bool CChannel::operator !=(const CChannel& channel) const -{ - return ::strncmp(m_name, channel.m_name, NN_CHANNEL_NAME_LENGTH_MAX) != 0; -} - -/* - - CListeners - -*/ - -CListeners::CListeners() -{ - m_pNotificationWrite = &m_notifications[0]; - m_pNotificationRead = &m_notifications[1]; -} - -CListeners::~CListeners() -{ - while (!m_pNotificationRead->empty()) - { - SBuffer buffer = m_pNotificationRead->front(); - m_pNotificationRead->pop(); - delete[] buffer.pData; - } - - while (!m_pNotificationWrite->empty()) - { - SBuffer buffer = m_pNotificationWrite->front(); - m_pNotificationWrite->pop(); - delete[] buffer.pData; - } -} - -// - -size_t CListeners::Count(const CChannel& channel) -{ - size_t count = 0; - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].second != channel) - { - continue; - } - - ++count; - } - - return count; -} - -CChannel* CListeners::Channel(INotificationNetworkListener* pListener) -{ - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].first != pListener) - { - continue; - } - - return &m_listeners[i].second; - } - - return nullptr; -} - -bool CListeners::Bind(const CChannel& channel, INotificationNetworkListener* pListener) -{ - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].first == pListener) - { - m_listeners[i].second = channel; - return true; - } - } - - m_listeners.push_back(std::pair()); - m_listeners.back().first = pListener; - m_listeners.back().second = channel; - return true; -} - -bool CListeners::Remove(INotificationNetworkListener* pListener) -{ - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].first != pListener) - { - continue; - } - - m_listeners[i] = m_listeners.back(); - m_listeners.pop_back(); - return true; - } - - return false; -} - -void CListeners::NotificationPush(const SBuffer& buffer) -{ - // TODO: Use auto lock. - m_notificationCriticalSection.Lock(); - m_pNotificationWrite->push(buffer); - m_notificationCriticalSection.Unlock(); -} - -void CListeners::NotificationsProcess() -{ - m_notificationCriticalSection.Lock(); - std::swap(m_pNotificationWrite, m_pNotificationRead); - m_notificationCriticalSection.Unlock(); - - while (!m_pNotificationRead->empty()) - { - SBuffer buffer = m_pNotificationRead->front(); - m_pNotificationRead->pop(); - - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].second != buffer.channel) - { - continue; - } - - m_listeners[i].first->OnNotificationNetworkReceive( - buffer.pData, buffer.length); - } - - delete[] buffer.pData; - } -} - -/* - - CConnectionBase - -*/ - -CConnectionBase::CConnectionBase(CNotificationNetwork* pNotificationNetwork) -{ - m_pNotificationNetwork = pNotificationNetwork; - - m_port = 0; - - m_socket = AZ_SOCKET_INVALID; - - m_buffer.pData = nullptr; - m_buffer.length = 0; - m_dataLeft = 0; - - m_boIsConnected = false; - m_boIsFailedToConnect = false; -} - -CConnectionBase::~CConnectionBase() -{ - if (m_buffer.pData) - { - delete[] m_buffer.pData; - } - - if (m_socket != AZ_SOCKET_INVALID) - { - CloseSocket_Internal(); - } -} - -// - -void CConnectionBase::SetAddress(const char* address, uint16 port) -{ - size_t length = MIN(::strlen(address), 15); - ::memset(m_address, 0, sizeof(m_address)); - ::memcpy(m_address, address, length); - m_port = port; -} - -bool CConnectionBase::Validate() -{ - if (m_socket != AZ_SOCKET_INVALID) - { - if (!m_port) - { - AZ::AzSock::AzSocketAddress socketAddress; - int result = AZ::AzSock::GetSockName(m_socket, socketAddress); - if (AZ::AzSock::SocketErrorOccured(result)) - { - return false; - } - } - - return Select_Internal(); - } - - if (!m_port) // If port is not set we don't want to try to reconnect. - { - return false; - } - - m_socket = CreateSocket(); - // If the create sockect will fail, it is likely that we will never be able to connect, - // we might want to signal that. - - Connect(m_address, m_port); - - return false; -} - -bool CConnectionBase::Send(const void* pBuffer, size_t length) -{ - if (!Validate()) - { - return false; - } - - size_t sent = 0; - while (sent < length) - { - int r = AZ::AzSock::Send(m_socket, (const char*)pBuffer + sent, length - sent, 0); - if (AZ::AzSock::SocketErrorOccured(r)) - { - AZ::AzSock::AzSockError nCurrentError = AZ::AzSock::AzSockError(r); - if (nCurrentError == AZ::AzSock::AzSockError::eASE_ENOTCONN) - { - r = 0; - break; - } - else if (nCurrentError == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK) - { - r = 0; - } - else - { - CryLog("CNotificationNetworkClient::Send: Failed to send package. Reason: %s", AZ::AzSock::GetStringForError(r)); - CloseSocket_Internal(); - return false; - } - } - - sent += r; - } - - return true; -} - -bool CConnectionBase::SendMessage(EMessage eMessage, const CChannel& channel, uint32 data) -{ - char header[NN_PACKET_HEADER_LENGTH]; - ::memset(header, 0, NN_PACKET_HEADER_LENGTH); - *(uint32*)&header[NN_PACKET_HEADER_OFFSET_MESSAGE] = AZ::AzSock::HostToNetLong(eMessage); - *(uint32*)&header[NN_PACKET_HEADER_OFFSET_DATA_LENGTH] = AZ::AzSock::HostToNetLong(data); - channel.WriteToPacketHeader(header); - - if (!Send(header, NN_PACKET_HEADER_LENGTH)) - { - return false; - } - - return true; -} - -bool CConnectionBase::Select_Internal() -{ - if (m_socket == AZ_SOCKET_INVALID) - { - return false; - } - - AZFD_SET stExceptions; - AZFD_SET stWriteSockets; - - FD_ZERO(&stExceptions); - FD_SET(m_socket, &stExceptions); - - FD_ZERO(&stWriteSockets); - FD_SET(m_socket, &stWriteSockets); - - AZTIMEVAL timeOut = { 0, 0 }; - - int r = AZ::AzSock::Select(m_socket, nullptr, &stWriteSockets, &stExceptions, &timeOut); - if (AZ::AzSock::SocketErrorOccured(r)) - { - CryLog("CNotificationNetworkClient:: Failed to select socket. Reason: %s", AZ::AzSock::GetStringForError(r)); - CloseSocket_Internal(); - m_boIsFailedToConnect = true; - return false; - } - else if (!r) - { - return m_boIsConnected; - } - - if (FD_ISSET(m_socket, &stExceptions)) - { - CloseSocket_Internal(); - m_boIsFailedToConnect = true; - OnConnect(m_boIsConnected); // Handles failed attempt to connect. - return false; - } - else if (FD_ISSET(m_socket, &stWriteSockets)) // In Windows a socket can be in both lists. - { - if (!m_boIsConnected) - { - m_boIsConnected = true; - m_boIsFailedToConnect = false; - OnConnect(m_boIsConnected); // Handles successful attempt to connect. - } - return true; - } - - return false; -} - -void CConnectionBase::CloseSocket_Internal() -{ - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - if (m_boIsConnected) - { - OnDisconnect(); - } - m_boIsConnected = false; -} - -bool CConnectionBase::SendNotification(const CChannel& channel, const void* pBuffer, size_t length) -{ - if (!SendMessage(eMessage_DataTransfer, channel, length)) - { - return false; - } - if (!length) - { - return true; - } - - if (!Send(pBuffer, length)) - { - return false; - } - - return true; -} - -bool CConnectionBase::ReceiveMessage(CListeners& listeners) -{ - if (!Validate()) - { - return false; - } - - if (!m_dataLeft) - { - m_dataLeft = NN_PACKET_HEADER_LENGTH; - } - int r = AZ::AzSock::Recv(m_socket, (char*)&m_bufferHeader[NN_PACKET_HEADER_LENGTH - m_dataLeft], m_dataLeft, 0); - if (!r) - { - // Connection terminated. - m_dataLeft = 0; - - CloseSocket_Internal(); - return false; - } - if (AZ::AzSock::SocketErrorOccured(r)) - { - m_dataLeft = 0; - - CryLog("CNotificationNetworkClient::ReceiveMessage: Failed to receive package. Reason: %s", AZ::AzSock::GetStringForError(r)); - CloseSocket_Internal(); - return false; - } - - if (m_dataLeft -= r) - { - return true; - } - - // The whole message was received, process it... - - EMessage eMessage = (EMessage)AZ::AzSock::NetToHostLong( - *(uint32*)&m_bufferHeader[NN_PACKET_HEADER_OFFSET_MESSAGE]); - const CChannel& channel = *(CChannel*)&m_bufferHeader[NN_PACKET_HEADER_OFFSET_CHANNEL]; - - if (eMessage == eMessage_DataTransfer) - { - m_dataLeft = AZ::AzSock::NetToHostLong(*(uint32*)&m_bufferHeader[NN_PACKET_HEADER_OFFSET_DATA_LENGTH]); - if (!m_dataLeft) - { - SBuffer buffer; - buffer.channel = channel; - buffer.pData = nullptr; - buffer.length = 0; - listeners.NotificationPush(buffer); - return true; - } - - m_buffer.pData = new uint8[m_buffer.length = m_dataLeft]; - if (!m_buffer.pData) - { - CryLog("CNotificationNetwork::CConnection::Receive: Failed to allocate buffer.\n"); - m_dataLeft = 0; - - CloseSocket_Internal(); - return false; - } - - m_buffer.channel.ReadFromPacketHeader(m_bufferHeader); - return +1; - } - - if (!OnMessage(eMessage, channel)) - { - CryLog("NotificationNetwork::CConnectionBase::ReceiveMessage: " - "Unknown message received, terminating Connection...\n"); - m_dataLeft = 0; - - CloseSocket_Internal(); - return false; - } - - return true; -} - -bool CConnectionBase::ReceiveNotification(CListeners& listeners) -{ - int r = AZ::AzSock::Recv(m_socket, (char*)&m_buffer.pData[m_buffer.length - m_dataLeft], m_dataLeft, 0); - if (!r) - { - CryLog("CNotificationNetworkClient::ReceiveNotification: Failed to receive package. Reason: Connection terminated."); - // Connection terminated. - m_dataLeft = 0; - - CloseSocket_Internal(); - return false; - } - - if (AZ::AzSock::SocketErrorOccured(r)) - { - m_dataLeft = 0; - - CryLog("CNotificationNetworkClient::ReceiveNotification: Failed to receive package. Reason: %s", AZ::AzSock::GetStringForError(r)); - CloseSocket_Internal(); - return false; - } - - if (m_dataLeft -= r) - { - return true; - } - - listeners.NotificationPush(m_buffer); - m_buffer.pData = nullptr; - m_buffer.length = 0; - m_dataLeft = 0; - return true; -} - -bool CConnectionBase::Receive(CListeners& listeners) -{ - if (m_buffer.pData) - { - return ReceiveNotification(listeners); - } - - return ReceiveMessage(listeners); -} - -bool CConnectionBase::GetIsConnectedFlag() -{ - return Select_Internal() || m_boIsConnected; -} - -bool CConnectionBase::GetIsFailedToConnectFlag() const -{ - return m_boIsFailedToConnect; -} - -/* - - CClient - -*/ - -CClient* CClient::Create(CNotificationNetwork* pNotificationNetwork, const char* address, uint16 port) -{ - CClient* pClient = new CClient(pNotificationNetwork); - AZSOCKET sock = pClient->CreateSocket(); - // In the current implementation, this is REALLY UNLIKELY to happen. - if (sock == AZ_SOCKET_INVALID) - { - delete pClient; - return nullptr; - } - - // - pClient->SetSocket(sock); - pClient->Connect(address, port); - - pClient->SetAddress(address, port); - pClient->SetSocket(sock); - return pClient; -} - -CClient* CClient::Create(CNotificationNetwork* pNotificationNetwork) -{ - CClient* pClient = new CClient(pNotificationNetwork); - return pClient; -} - -// - -CClient::CClient(CNotificationNetwork* pNotificationNetwork) - : CConnectionBase(pNotificationNetwork) -{ -} - -CClient::~CClient() -{ - GetNotificationNetwork()->ReleaseClients(this); -} - -// - -void CClient::Update() -{ - m_listeners.NotificationsProcess(); -} - -// CConnectionBase - -bool CClient::OnConnect(bool boConnected) -{ - if (boConnected) - { - for (size_t i = 0; i < m_listeners.Count(); ++i) - { - if (!SendMessage(eMessage_ChannelRegister, m_listeners.Channel(i), 0)) - { - return false; - } - } - } - - CryAutoLock lock(m_stConnectionCallbacksLock); - for (size_t nCount = 0; nCount < m_cNotificationNetworkConnectionCallbacks.size(); ++nCount) - { - m_cNotificationNetworkConnectionCallbacks[nCount]->OnConnect(this, boConnected); - } - - return boConnected; -} - -bool CClient::OnDisconnect() -{ - CryAutoLock lock(m_stConnectionCallbacksLock); - for (size_t nCount = 0; nCount < m_cNotificationNetworkConnectionCallbacks.size(); ++nCount) - { - m_cNotificationNetworkConnectionCallbacks[nCount]->OnDisconnected(this); - } - - return true; -} - -bool CClient::OnMessage([[maybe_unused]] EMessage eMessage, [[maybe_unused]] const CChannel& channel) -{ - return false; -} - -// INotificationNetworkClient - -bool CClient::Connect(const char* address, uint16 port) -{ - bool bReturnValue(false); - - if (m_socket == AZ_SOCKET_INVALID) - { - m_socket = CreateSocket(); - } - - bReturnValue = CConnectionBase::Connect(address, port); - if (bReturnValue) - { - SetAddress(address, port); - } - - return bReturnValue; -} - -bool CClient::ListenerBind(const char* channelName, INotificationNetworkListener* pListener) -{ - if (!CChannel::IsNameValid(channelName)) - { - return false; - } - - if (!m_listeners.Bind(CChannel(channelName), pListener)) - { - return false; - } - - if (!SendMessage(eMessage_ChannelRegister, CChannel(channelName), 0)) - { - return false; - } - - return true; -} - -bool CClient::ListenerRemove(INotificationNetworkListener* pListener) -{ - CChannel* pChannel = m_listeners.Channel(pListener); - if (!pChannel) - { - return false; - } - - if (!m_listeners.Remove(pListener)) - { - return false; - } - - if (!SendMessage(eMessage_ChannelUnregister, *pChannel, 0)) - { - return false; - } - - return true; -} - -bool CClient::Send(const char* channelName, const void* pBuffer, size_t length) -{ - CRY_ASSERT(CChannel::IsNameValid(channelName)); - // CRY_ASSERT_MESSAGE(channelLength <= NN_CHANNEL_NAME_LENGTH_MAX, - // "Channel name \"%s\" was passed to a Notification Network method, the name cannot be longer than %d chars.", - // channel, NN_CHANNEL_NAME_LENGTH_MAX); - - if (!CChannel::IsNameValid(channelName)) - { - return false; - } - if (!SendNotification(CChannel(channelName), pBuffer, length)) - { - return false; - } - - return true; -} - -bool CClient::RegisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) -{ - CryAutoLock lock(m_stConnectionCallbacksLock); - return stl::push_back_unique(m_cNotificationNetworkConnectionCallbacks, pConnectionCallback); -} - -bool CClient::UnregisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) -{ - CryAutoLock lock(m_stConnectionCallbacksLock); - return stl::find_and_erase(m_cNotificationNetworkConnectionCallbacks, pConnectionCallback); -} - -/* - - CNotificationNetwork::CConnection - -*/ - -CNotificationNetwork::CConnection::CConnection(CNotificationNetwork* pNotificationNetwork, AZSOCKET sock) - : CConnectionBase(pNotificationNetwork) -{ - SetSocket(sock); - m_listeningChannels.reserve(8); -} - -CNotificationNetwork::CConnection::~CConnection() -{ -} - -// - -bool CNotificationNetwork::CConnection::IsListening(const CChannel& channel) -{ - for (size_t i = 0; i < m_listeningChannels.size(); ++i) - { - if (m_listeningChannels[i] == channel) - { - return true; - } - } - - return false; -} - -// CConnectionBase - -bool CNotificationNetwork::CConnection::OnMessage(EMessage eMessage, const CChannel& channel) -{ - switch (eMessage) - { - case eMessage_ChannelRegister: - for (size_t i = 0; i < m_listeningChannels.size(); ++i) - { - if (m_listeningChannels[i] == channel) - { - return true; - } - } - m_listeningChannels.push_back(channel); - return true; - - case eMessage_ChannelUnregister: - for (size_t i = 0; i < m_listeningChannels.size(); ++i) - { - if (m_listeningChannels[i] != channel) - { - continue; - } - - m_listeningChannels[i] = m_listeningChannels.back(); - m_listeningChannels.pop_back(); - return true; - } - return true; - } - - return false; -} - -/* - - CNotificationNetwork::CThread - -*/ - -CNotificationNetwork::CThread::CThread() -{ - m_pNotificationNetwork = nullptr; - m_bRun = true; -} - -CNotificationNetwork::CThread::~CThread() -{ -} - -// - -bool CNotificationNetwork::CThread::Begin(CNotificationNetwork* pNotificationNetwork) -{ - m_pNotificationNetwork = pNotificationNetwork; - Start(-1, (char*)NN_THREAD_NAME); - return true; -} - - -void CNotificationNetwork::CThread::End() -{ - m_bRun = false; - // WaitForThread(); - - // TODO: Should properly close! -} - -// CryRunnable - -void CNotificationNetwork::CThread::Run() -{ - CryThreadSetName(threadID(THREADID_NULL), NN_THREAD_NAME); - while (m_bRun) - { - m_pNotificationNetwork->ProcessSockets(); - } -} - -/* - - CNotificationNetwork - -*/ - -CNotificationNetwork* CNotificationNetwork::Create() -{ - AZ::AzSock::Startup(); - - AZSOCKET sock = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(sock)) - { - CryLog("CNotificationNetwork::Create: Failed to create socket.\n"); - return nullptr; - } - - // Disable nagling of small blocks to fight high latency connection - int result = AZ::AzSock::EnableTCPNoDelay(sock, true); - if (AZ::AzSock::SocketErrorOccured(result)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Create: Failed to set TCP_NODELAY option."); - return nullptr; - } - - result = AZ::AzSock::SetSocketBlockingMode(sock, false); - if (AZ::AzSock::SocketErrorOccured(result)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Connect: Failed to set socket to asynchronous operation."); - return nullptr; - } - - // Editor uses a different port to avoid conflicts when running both editor and game on same PC - // But allows the lua remote debugger to connect to the editor - unsigned short port = gEnv && gEnv->IsEditor() ? 9433 : 9432; - - AZ::AzSock::AzSocketAddress addr; - addr.SetAddrPort(port); - - result = AZ::AzSock::Bind(sock, addr); - if (AZ::AzSock::SocketErrorOccured(result)) - { - CryLog("CNotificationNetwork::Create: Failed to bind socket.\n"); - AZ::AzSock::CloseSocket(sock); - return nullptr; - } - - result = AZ::AzSock::Listen(sock, 8); - if (AZ::AzSock::SocketErrorOccured(result)) - { - CryLog("CNotificationNetwork::Create: Failed to listen.\n"); - AZ::AzSock::CloseSocket(sock); - return nullptr; - } - - CNotificationNetwork* pNotificationNetwork = new CNotificationNetwork(); - pNotificationNetwork->m_socket = sock; - - pNotificationNetwork->m_thread.Begin(pNotificationNetwork); - - return pNotificationNetwork; -} - -// - -CNotificationNetwork::CNotificationNetwork() -{ - m_socket = AZ_SOCKET_INVALID; - - m_connections.reserve(4); - - m_listeners.Bind("Query", &g_queryNotification); -} - -CNotificationNetwork::~CNotificationNetwork() -{ - m_thread.End(); - m_thread.Stop(); - m_thread.WaitForThread(); - while (!m_connections.empty()) - { - delete m_connections.back(); - m_connections.pop_back(); - } - - if (m_socket != AZ_SOCKET_INVALID) - { - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - } - - AZ::AzSock::Cleanup(); -} - -// - -void CNotificationNetwork::ReleaseClients(CClient* pClient) -{ - // TODO: Use CryAutoLock - LockDebug("Lock %s\n", "CNotificationNetwork::ReleaseClients()"); - m_clientsCriticalSection.Lock(); - for (size_t i = 0; i < m_clients.size(); ++i) - { - if (m_clients[i] != pClient) - { - continue; - } - - m_clients[i] = m_clients.back(); - m_clients.pop_back(); - break; - } - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::ReleaseClients()"); -} - -void CNotificationNetwork::ProcessSockets() -{ - fd_set read; - FD_ZERO(&read); - AZSOCKET socketMax = 0; - if (m_socket != AZ_SOCKET_INVALID) - { - FD_SET(m_socket, &read); - socketMax = m_socket; - } - for (size_t i = 0; i < m_connections.size(); ++i) - { - if (m_connections[i]->Validate()) - { - AZSOCKET sock = m_connections[i]->GetSocket(); - FD_SET(sock, &read); - - if (socketMax < sock) - { - socketMax = sock; - } - - continue; - } - - // The Connection is invalid, remove it. - CConnection* pConnection = m_connections[i]; - m_connections[i] = m_connections.back(); - m_connections.pop_back(); - delete pConnection; - - // Invalidate the loop increment since we just removed a Connection and - // in the process potentially replaced its slot with an unprocessed one. - --i; - - CryLog("Notification Network Connection terminated, current total: %d\n", - (int)m_connections.size()); - } - - LockDebug("Lock %s\n", "CNotificationNetwork::ProcessSockets()"); - m_clientsCriticalSection.Lock(); - for (size_t i = 0; i < m_clients.size(); ++i) - { - if (!m_clients[i]->Validate()) - { - continue; - } - - AZSOCKET sock = m_clients[i]->GetSocket(); - FD_SET(sock, &read); - - if (socketMax < sock) - { - socketMax = sock; - } - } - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::ProcessSockets()"); - - AZTIMEVAL timeOut = { 1, 0 }; - int r = AZ::AzSock::Select(socketMax, &read, nullptr, nullptr, &timeOut); - if (r == 0) - { - return; - } - - // When we have no sockets, the select statement will fail and not - // block for even 1 second, as it should... - if (AZ::AzSock::SocketErrorOccured(r)) - { - // So we force the sleep here for now. - Sleep(1000); - return; - } - - for (size_t i = 0; i < m_connections.size(); ++i) - { - if (!FD_ISSET(m_connections[i]->GetSocket(), &read)) - { - continue; - } - - m_connections[i]->Receive(m_listeners); - } - - LockDebug("Lock 2 %s\n", "CNotificationNetwork::ProcessSockets()"); - m_clientsCriticalSection.Lock(); - for (size_t i = 0; i < m_clients.size(); ++i) - { - if (!FD_ISSET(m_clients[i]->GetSocket(), &read)) - { - continue; - } - - m_clients[i]->Receive(); - } - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock 2 %s\n", "CNotificationNetwork::ProcessSockets()"); - - if (m_socket == AZ_SOCKET_INVALID) - { - return; - } - if (!FD_ISSET(m_socket, &read)) - { - return; - } - - AZ::AzSock::AzSocketAddress addr; - AZSOCKET sock = AZ::AzSock::Accept(m_socket, addr); - if (!AZ::AzSock::IsAzSocketValid(sock)) - { - return; - } - - if (!RCON_IsRemoteAllowedToConnect(addr)) - { - AZ::AzSock::CloseSocket(sock); - return; - } - - m_connections.push_back(new CConnection(this, sock)); - - CryLog("Notification Network accepted new Connection, current total: %d\n", - (int)m_connections.size()); -} - -// INotificationNetwork - -INotificationNetworkClient* CNotificationNetwork::CreateClient() -{ - CClient* pClient = CClient::Create(this); - - LockDebug("Lock %s\n", "CNotificationNetwork::CreateClient()"); - m_clientsCriticalSection.Lock(); - m_clients.push_back(pClient); - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::CreateClient()"); - - return pClient; -} - -INotificationNetworkClient* CNotificationNetwork::Connect(const char* address, uint16 port) -{ - CClient* pClient = CClient::Create(this, address, port); - if (!pClient) - { - return nullptr; - } - - LockDebug("Lock %s\n", "CNotificationNetwork::Connect()"); - m_clientsCriticalSection.Lock(); - m_clients.push_back(pClient); - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::Connect()"); - - return pClient; -} - -size_t CNotificationNetwork::GetConnectionCount(const char* channelName) -{ - if (!channelName) - { - return m_connections.size(); - } - - if (!CChannel::IsNameValid(channelName)) - { - return 0; - } - - CChannel channel(channelName); - size_t count = 0; - for (size_t i = 0; i < m_connections.size(); ++i) - { - if (!m_connections[i]->IsListening(channel)) - { - continue; - } - - ++count; - } - return count; -} - -bool CNotificationNetwork::ListenerBind(const char* channelName, INotificationNetworkListener* pListener) -{ - if (!CChannel::IsNameValid(channelName)) - { - return false; - } - - return m_listeners.Bind(CChannel(channelName), pListener); -} - -bool CNotificationNetwork::ListenerRemove(INotificationNetworkListener* pListener) -{ - return m_listeners.Remove(pListener); -} - -void CNotificationNetwork::Update() -{ - m_listeners.NotificationsProcess(); - - LockDebug("Lock %s\n", "CNotificationNetwork::Update()"); - m_clientsCriticalSection.Lock(); - for (size_t i = 0; i < m_clients.size(); ++i) - { - m_clients[i]->Update(); - } - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::Update()"); -} - -uint32 CNotificationNetwork::Send(const char* channelName, const void* pBuffer, size_t length) -{ - if (!CChannel::IsNameValid(channelName)) - { - return 0; - } - - CChannel channel(channelName); - - // TODO: There should be a mutex lock here to ensure thread safety. - - uint32 count = 0; - for (size_t i = 0; i < m_connections.size(); ++i) - { - if (!m_connections[i]->IsListening(channel)) - { - continue; - } - - if (m_connections[i]->SendNotification(channel, pBuffer, length)) - { - ++count; - } - } - - return count; -} diff --git a/Code/CryEngine/CrySystem/NotificationNetwork.h b/Code/CryEngine/CrySystem/NotificationNetwork.h deleted file mode 100644 index ee336dbbb0..0000000000 --- a/Code/CryEngine/CrySystem/NotificationNetwork.h +++ /dev/null @@ -1,293 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H -#define CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H - -#pragma once - -#include -#include -#include - -#include - -class CNotificationNetwork; -namespace NotificationNetwork { - // Constants - - static const uint32 NN_PACKET_HEADER_LENGTH = 2 * sizeof(uint32) + NN_CHANNEL_NAME_LENGTH_MAX; - - static const uint32 NN_PACKET_HEADER_OFFSET_MESSAGE = 0; - static const uint32 NN_PACKET_HEADER_OFFSET_DATA_LENGTH = sizeof(uint32); - static const uint32 NN_PACKET_HEADER_OFFSET_CHANNEL = sizeof(uint32) + sizeof(uint32); - - static const char* NN_THREAD_NAME = "NotificationNetwork"; - - enum EMessage - { - eMessage_DataTransfer = 0xbada2217, - - eMessage_ChannelRegister = 0xab4eda30, - eMessage_ChannelUnregister = 0xfa4e3423, - }; - - // Classes - - struct CChannel - { - public: - static bool IsNameValid(const char* name); - - public: - CChannel(); - CChannel(const char* name); - ~CChannel(); - - public: - void WriteToPacketHeader(void* pPacket) const; - void ReadFromPacketHeader(void* pPacket); - - public: - bool operator ==(const CChannel& channel) const; - bool operator !=(const CChannel& channel) const; - - private: - char m_name[NN_CHANNEL_NAME_LENGTH_MAX]; - }; - - // TEMP - struct SBuffer - { - uint8* pData; - uint32 length; - CChannel channel; - }; - - class CListeners - { - public: - CListeners(); - ~CListeners(); - - public: - size_t Count() { return m_listeners.size(); } - size_t Count(const CChannel& channel); - - CChannel& Channel(size_t index) { return m_listeners[index].second; } - CChannel* Channel(INotificationNetworkListener* pListener); - - bool Bind(const CChannel& channel, INotificationNetworkListener* pListener); - bool Remove(INotificationNetworkListener* pListener); - - void NotificationPush(const SBuffer& buffer); - void NotificationsProcess(); - - private: - std::vector< std::pair > m_listeners; - - std::queue m_notifications[2]; - std::queue* m_pNotificationWrite; - std::queue* m_pNotificationRead; - CryCriticalSection m_notificationCriticalSection; - }; - - class CConnectionBase - { - public: - CConnectionBase(CNotificationNetwork* pNotificationNetwork); - virtual ~CConnectionBase(); - - public: - AZSOCKET CreateSocket(); - - bool Connect(const char* address, uint16 port); - - AZSOCKET GetSocket() { return m_socket; } - - bool Validate(); - - bool SendNotification(const CChannel& channel, const void* pBuffer, size_t length); - - bool Receive(CListeners& listeners); - - bool GetIsConnectedFlag(); - bool GetIsFailedToConnectFlag() const; - - protected: - CNotificationNetwork* GetNotificationNetwork() { return m_pNotificationNetwork; } - - void SetAddress(const char* address, uint16 port); - void SetSocket(AZSOCKET sock) { m_socket = sock; } - - bool Send(const void* pBuffer, size_t length); - bool SendMessage(EMessage eMessage, const CChannel& channel, uint32 data); - - bool Select_Internal(); - void CloseSocket_Internal(); - - virtual bool OnConnect([[maybe_unused]] bool bConnectionResult) { return true; } - virtual bool OnDisconnect() {return true; } - virtual bool OnMessage([[maybe_unused]] EMessage eMessage, [[maybe_unused]] const CChannel& channel) { return false; } - - private: - bool ReceiveMessage(CListeners& listeners); - bool ReceiveNotification(CListeners& listeners); - - protected: - CNotificationNetwork* m_pNotificationNetwork; - - char m_address[16]; - uint16 m_port; - - AZSOCKET m_socket; - - uint8 m_bufferHeader[NN_PACKET_HEADER_LENGTH]; - SBuffer m_buffer; - uint32 m_dataLeft; - - volatile bool m_boIsConnected; - volatile bool m_boIsFailedToConnect; - }; - - class CClient - : public CConnectionBase - , public INotificationNetworkClient - { - public: - typedef std::vector TDNotificationNetworkConnectionCallbacks; - - static CClient* Create(CNotificationNetwork* pNotificationNetwork, const char* address, uint16 port); - static CClient* Create(CNotificationNetwork* pNotificationNetwork); - - private: - CClient(CNotificationNetwork* pNotificationNetwork); - ~CClient(); - - public: - bool Receive() { return CConnectionBase::Receive(m_listeners); } - - void Update(); - - // CConnectionBase - public: - virtual bool OnConnect(bool bConnectionResult); - virtual bool OnDisconnect(); - virtual bool OnMessage(EMessage eMessage, const CChannel& channel); - - // INotificationNetworkClient - public: - bool Connect(const char* address, uint16 port); - - void Release() { delete this; } - - virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener); - virtual bool ListenerRemove(INotificationNetworkListener* pListener); - - virtual bool Send(const char* channelName, const void* pBuffer, size_t length); - - virtual bool IsConnected() {return CConnectionBase::GetIsConnectedFlag(); } - virtual bool IsFailedToConnect() const{return CConnectionBase::GetIsFailedToConnectFlag(); } - - virtual bool RegisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback); - virtual bool UnregisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback); - private: - CListeners m_listeners; - - TDNotificationNetworkConnectionCallbacks m_cNotificationNetworkConnectionCallbacks; - CryCriticalSection m_stConnectionCallbacksLock; - }; -} // namespace NotificationNetwork -class CNotificationNetwork - : public INotificationNetwork -{ -private: - class CConnection - : public NotificationNetwork::CConnectionBase - { - public: - CConnection(CNotificationNetwork* pNotificationNetwork, AZSOCKET sock); - virtual ~CConnection(); - - public: - bool IsListening(const NotificationNetwork::CChannel& channel); - - // CConnectionBase - protected: - virtual bool OnMessage(NotificationNetwork::EMessage eMessage, const NotificationNetwork::CChannel& channel); - - private: - std::vector m_listeningChannels; - }; - - class CThread - : public CryThread - { - public: - CThread(); - ~CThread(); - - public: - bool Begin(CNotificationNetwork* pNotificationNetwork); - void End(); - - // CryRunnable - public: - virtual void Run(); - - private: - CNotificationNetwork* m_pNotificationNetwork; - bool m_bRun; - } m_thread; - -public: - static CNotificationNetwork* Create(); - -public: - CNotificationNetwork(); - ~CNotificationNetwork(); - -public: - void ReleaseClients(NotificationNetwork::CClient* pClient); - -private: - void ProcessSockets(); - - // INotificationNetwork -public: - virtual void Release() { delete this; } - - virtual INotificationNetworkClient* CreateClient(); - - virtual INotificationNetworkClient* Connect(const char* address, uint16 port); - - virtual size_t GetConnectionCount(const char* channelName); - - virtual void Update(); - - virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener); - virtual bool ListenerRemove(INotificationNetworkListener* pListener); - - virtual uint32 Send(const char* channelName, const void* pBuffer, size_t length); - -private: - AZSOCKET m_socket; - - std::vector m_connections; - std::vector m_clients; - NotificationNetwork::CListeners m_listeners; - - CryCriticalSection m_clientsCriticalSection; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H diff --git a/Code/CryEngine/CrySystem/ProfileLogSystem.cpp b/Code/CryEngine/CrySystem/ProfileLogSystem.cpp deleted file mode 100644 index 2a86dfc2ef..0000000000 --- a/Code/CryEngine/CrySystem/ProfileLogSystem.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ProfileLogSystem.h" - -////////////////////////////////////////////////////////////////////////// -// class CLogElement -////////////////////////////////////////////////////////////////////////// - -CLogElement::CLogElement() - : m_pParent (NULL) - , m_time (0) -{ -} - -CLogElement::CLogElement(CLogElement* pParent) - : m_pParent (pParent) - , m_time (0) -{ -} - -CLogElement::CLogElement(CLogElement* pParent, const char* name, const char* message) - : m_pParent (pParent) - , m_strName (name) - , m_strMessage(message) - , m_time (0) -{ -} - -void CLogElement::Flush(stack_string& indent) -{ - if (m_logElements.empty()) - { - CryLog("%s%s [%.3f ms] %s", indent.c_str(), m_strName.c_str(), m_time, m_strMessage.c_str()); - return; - } - - CryLog("%s+%s [%.3f ms] %s", indent.c_str(), m_strName.c_str(), m_time, m_strMessage.c_str()); - - indent += " "; - for (std::list::iterator it = m_logElements.begin(); it != m_logElements.end(); ++it) - { - (*it).Flush(indent); - } - indent.erase(0, 2); - - CryLog("%s-%s", indent.c_str(), m_strName.c_str()); -} - -ILogElement* CLogElement::Log(const char* name, const char* message) -{ - m_logElements.push_back(CLogElement(this)); - m_logElements.back().m_strName = name; - m_logElements.back().m_strMessage = message; - - return &m_logElements.back(); -} - -ILogElement* CLogElement::SetTime(float time) -{ - m_time = time; - - return m_pParent; -} - -void CLogElement::Clear() -{ - m_logElements.resize(0); -} - -////////////////////////////////////////////////////////////////////////// -// class CProfileLogSystem -////////////////////////////////////////////////////////////////////////// - -CProfileLogSystem::CProfileLogSystem() - : m_rootElelent(NULL) - , m_pLastElelent(NULL) -{ -} - -CProfileLogSystem::~CProfileLogSystem() -{ -} - -ILogElement* CProfileLogSystem::Log(const char* name, const char* message) -{ - if (m_pLastElelent) - { - m_pLastElelent = m_pLastElelent->Log(name, message); - } - else - { - m_rootElelent.Clear(); - m_rootElelent.SetName(name); - m_rootElelent.SetMessage(message); - m_pLastElelent = &m_rootElelent; - } - - return m_pLastElelent; -} - -void CProfileLogSystem::SetTime(ILogElement* pElement, float time) -{ - if (pElement == NULL) - { - return; - } - - m_pLastElelent = pElement->SetTime(time); - if (m_pLastElelent) - { - return; - } - - stack_string indent; - m_rootElelent.Flush(indent); - m_rootElelent.Clear(); -} - -void CProfileLogSystem::Release() -{ - delete this; -} diff --git a/Code/CryEngine/CrySystem/ProfileLogSystem.h b/Code/CryEngine/CrySystem/ProfileLogSystem.h deleted file mode 100644 index b54e3067ec..0000000000 --- a/Code/CryEngine/CrySystem/ProfileLogSystem.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implementation of the IProfileLogSystem interface, which is used to -// save hierarchical log with SHierProfileLogItem - - -#ifndef CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H -#define CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H - -#pragma once - -#include "ProfileLog.h" - -class CLogElement - : public ILogElement -{ -public: - CLogElement(); - CLogElement(CLogElement* pParent); - CLogElement(CLogElement* pParent, const char* name, const char* message); - - virtual ILogElement* Log (const char* name, const char* message); - virtual ILogElement* SetTime (float time); - virtual void Flush (stack_string& indent); - - void Clear (); - - inline void SetName(const char* name) - { - m_strName = name; - } - - inline void SetMessage(const char* message) - { - m_strMessage = message; - } - -private: - string m_strName; - string m_strMessage; - float m_time; // milliSeconds - - CLogElement* m_pParent; - std::list m_logElements; -}; - -class CProfileLogSystem - : public IProfileLogSystem -{ -public: - CProfileLogSystem(); - ~CProfileLogSystem(); - - virtual ILogElement* Log (const char* name, const char* message); - virtual void SetTime (ILogElement* pElement, float time); - virtual void Release (); - -private: - CLogElement m_rootElelent; - ILogElement* m_pLastElelent; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H diff --git a/Code/CryEngine/CrySystem/ResourceManager.cpp b/Code/CryEngine/CrySystem/ResourceManager.cpp index f78538760f..5e9477a99c 100644 --- a/Code/CryEngine/CrySystem/ResourceManager.cpp +++ b/Code/CryEngine/CrySystem/ResourceManager.cpp @@ -699,7 +699,7 @@ void CResourceManager::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_P if (g_cvars.archiveVars.nLoadCache) { //Load the frontend common mode switch pak, this can considerably reduce the time spent switching especially from disc - if (!gEnv->bMultiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false) + if (LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false) { CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_SP); } @@ -710,14 +710,7 @@ void CResourceManager::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_P case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE: { - if (!gEnv->bMultiplayer) - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp"); - } - else - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP, FRONTEND_COMMON_LIST_FILENAME "_mp"); - } + UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp"); m_bLevelTransitioning = !m_sLevelName.empty(); diff --git a/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.cpp b/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.cpp deleted file mode 100644 index 9e141cc5a5..0000000000 --- a/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.cpp +++ /dev/null @@ -1,787 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#ifdef SOFTCODE_SYSTEM_ENABLED - -#ifndef SOFTCODE_ENABLED -// Even if this module isn't built with SC enabled, if the SC system is enabled we define -// it for this compilation unit to ensure we use the correct versions of the IType* interfaces. - #define SOFTCODE_ENABLED -#endif - -#include "SoftCodeMgr.h" -#include -#include -#include -#include // for function<> in find files - -// This should resolve to "GetTypeLibrary" but we export by ordinal to avoid overheads on 360 -// and keep everything consistent. -static const char* DLL_GETTYPELIBRARY = (LPCSTR)1; - -struct CInstanceData -{ - CInstanceData(void* pInstance, size_t memberCount) - : m_pOldInstance(pInstance) - , m_pNewInstance() - { - m_members.resize(memberCount); - } - - ~CInstanceData() - { - // Delete all members - for (TMemberVec::iterator iter(m_members.begin()); - iter != m_members.end(); - ++iter) - { - // TODO: Safe cross module? Same allocator? Use a Destroy() method? - delete *iter; - } - } - - void* Instance() { return m_pOldInstance; } - - void AddMember(size_t index, IExchangeValue& value) - { - // TODO: Add support for members with same name at different hierarchy levels - assert(m_members[index] == NULL); - assert(index != ~0); - - // Support expansion of m_members during while resolving members - if (index >= m_members.size()) - { - m_members.resize(index + 1); - } - - m_members[index] = value.Clone(); - } - - IExchangeValue* GetMember(size_t index) const - { - assert(index < m_members.size()); - return m_members[index]; - } - - void SetNewInstance(void* pNewInstance) { m_pNewInstance = pNewInstance; } - - void* m_pOldInstance; - void* m_pNewInstance; - - typedef std::vector TMemberVec; - TMemberVec m_members; -}; - - -class CExchanger - : public IExchanger -{ -public: - CExchanger() - : m_pInstanceData() - , m_instanceIndex(~0) - , m_state(eState_ResolvingMembers) - {} - - virtual ~CExchanger() - { - DestroyInstanceData(); - } - - virtual bool IsLoading() const { return m_state >= eState_WritingNewMembers; } - virtual size_t InstanceCount() const { return m_instances.size(); } - - virtual bool BeginInstance(void* pInstance) - { - if (IsLoading()) - { - if (++m_instanceIndex < m_instances.size()) - { - m_pInstanceData = m_instances[m_instanceIndex]; - m_pInstanceData->SetNewInstance(pInstance); - } - else - { - m_pInstanceData = NULL; - } - } - else // Reading/resolving members - { - m_instanceIndex = m_instances.size(); - m_pInstanceData = new CInstanceData(pInstance, m_memberMap.size()); - m_instances.push_back(m_pInstanceData); - } - - return m_pInstanceData != NULL; - } - - virtual bool SetValue(const char* name, IExchangeValue& value) - { - assert(!IsLoading()); - - const size_t index = FindMemberIndex(name); - const bool consumingValue = index != ~0; - - if (consumingValue) - { - m_pInstanceData->AddMember(index, value); - } - - return consumingValue; - } - - virtual IExchangeValue* GetValue(const char* name, void* pTarget, size_t targetSize) - { - assert(IsLoading()); - - const size_t index = FindMemberIndex(name); - - // If member resolved (may not be if restoring to old instances) - if (index != ~0) - { - // If member data available (may not be if member is new) - if (IExchangeValue* pValue = m_pInstanceData->GetMember(index)) - { - if (pValue->GetSizeOf() == targetSize) - { - return pValue; - } - else // Member size mismatch - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - "SoftCode: Member %s of instance %p has changed size (old: %d new: %d), setting to default value.", - name, m_pInstanceData->Instance(), (int)pValue->GetSizeOf(), (int)targetSize); - } - } - else // Member unknown - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - "SoftCode: Member %s (of instance %p) appears to be new.", - name, m_pInstanceData->Instance()); - - // TODO: Could attempt to validate against a known wipe pattern ie. 0xfefefefe - // This could catch most uninitialized variables... - - if (targetSize <= sizeof(void*)) - { - switch (targetSize) - { - case 1: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %d", *reinterpret_cast(pTarget)); - break; - case 2: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %04x", *reinterpret_cast(pTarget)); - break; - case 4: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %08x", *reinterpret_cast(pTarget)); - break; - case 8: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %llx", *reinterpret_cast(pTarget)); - break; - } - } - } - } - - // Indicate value should be default constructed - return NULL; - } - - // Used once required members have been established, members not already - // encountered will be ignored. - void LockMemberSet() - { - assert(m_state == eState_ResolvingMembers); - - DestroyInstanceData(); - m_state = eState_ReadingOldMembers; - } - - // Rewinds instance data and prepare for loading - void RewindForLoading() - { - assert(m_state == eState_ReadingOldMembers); - - m_pInstanceData = NULL; - m_instanceIndex = ~0; - m_state = eState_WritingNewMembers; - } - - // Rewinds instance data to prepare to restore old members (UNDO) - void RewindForRestore() - { - assert(m_state == eState_WritingNewMembers); - - m_pInstanceData = NULL; - m_instanceIndex = ~0; - m_state = eState_RestoringOldMembers; - } - - void NotifyListenerOfReplacements(ISoftCodeListener* pListener) - { - for (TInstanceVec::const_iterator iter(m_instances.begin()); iter != m_instances.end(); ++iter) - { - CInstanceData* pInstanceData = *iter; - pListener->InstanceReplaced(pInstanceData->m_pOldInstance, pInstanceData->m_pNewInstance); - } - } - -private: - void DestroyInstanceData() - { - m_pInstanceData = NULL; - m_instanceIndex = ~0; - - for (TInstanceVec::iterator iter(m_instances.begin()); iter != m_instances.end(); ++iter) - { - delete *iter; - } - - m_instances.resize(0); - } - - inline size_t FindMemberIndex(const string& memberName) - { - size_t index = ~0; - - // If needed members have been resolved - if (m_state != eState_ResolvingMembers) - { - TMemberMap::const_iterator iter(m_memberMap.find(memberName)); - if (iter != m_memberMap.end()) - { - index = iter->second; - } - } - else // Add this member to the map with a new index - { - // Ensure there's no member name duplicates - assert(m_memberMap.find(memberName) == m_memberMap.end()); - - // A new entry - index = m_memberMap.size(); - size_t& newIndex = m_memberMap[memberName]; - newIndex = index; - } - - return index; - } - -private: - CInstanceData* m_pInstanceData; - size_t m_instanceIndex; - - typedef std::vector TInstanceVec; - TInstanceVec m_instances; - - // Maps instance members to offsets in instance member vectors - typedef std::map TMemberMap; - TMemberMap m_memberMap; - - enum EState - { - eState_ResolvingMembers = 0, // Record new member names as found - eState_ReadingOldMembers, // Scrape requested member data from old instances - eState_WritingNewMembers, // Write old member data to new instances - eState_RestoringOldMembers, // Restore scraped values to old instances (UNDO) - }; - - EState m_state; -}; - - -// ---- - -DynamicTypeLibrary::DynamicTypeLibrary(const char* name) - : m_name(name) - , m_listeners(1) -{} - -const char* DynamicTypeLibrary::GetName() -{ - return m_name; -} - -void* DynamicTypeLibrary::CreateInstanceVoid(const char* typeName) -{ - TTypeMap::const_iterator typeIter(m_types.find(typeName)); - if (typeIter != m_types.end()) - { - ITypeRegistrar* pRegistrar = typeIter->second; - return pRegistrar->CreateInstance(); - } - - return NULL; -} - -void DynamicTypeLibrary::SetOverride(ITypeLibrary* /*pOverrideLib*/) -{ - CryFatalError("Unsupported: Attempting to SetOverride on a DynamicTypeLibrary!"); -} - -size_t DynamicTypeLibrary::GetTypes([[maybe_unused]] ITypeRegistrar** ppRegistrar, [[maybe_unused]] size_t& count) const -{ - CryFatalError("Unsupported: Attempting to GetTypes on a DynamicTypeLibrary!"); - return 0; -} - -void DynamicTypeLibrary::AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName) -{ - // This DynamicTypeLibrary could have been created by this listener request - // So ensure we have a name...! - if (!m_name) - { - m_name = libraryName; - } - - m_listeners.Add(pListener, listenerName); -} - -void DynamicTypeLibrary::RemoveListener(ISoftCodeListener* pListener) -{ - m_listeners.Remove(pListener); -} - -void DynamicTypeLibrary::IntegrateLibrary(ITypeLibrary* pLib, bool isDefault) -{ - typedef std::vector TTypeVec; - - // Resolve our name if we haven't already - if (!m_name) - { - m_name = pLib->GetName(); - } - - // Override the new lib immediately - pLib->SetOverride(this); - - // Query the new library for its types - size_t typeCount = 0; - pLib->GetTypes(NULL, typeCount); - if (typeCount > 0) - { - TTypeVec typeVec; - typeVec.resize(typeCount); - pLib->GetTypes(&(typeVec.front()), typeCount); - - if (!isDefault) - { - CryLogAlways("SoftCode: Integrating %d new types defined in %s...", (int)typeCount, m_name); - } - - // Attempt to integrate each type found - for (TTypeVec::iterator typeIter(typeVec.begin()); typeIter != typeVec.end(); ++typeIter) - { - IntegrateType(*typeIter, isDefault); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: New %s library has no registered types. Nothing to integrate.", pLib->GetName()); - } -} - -ITypeRegistrar* DynamicTypeLibrary::FindTypeForInstance(void* pInstance) const -{ - for (TTypeMap::const_iterator iter(m_types.begin()); iter != m_types.end(); ++iter) - { - ITypeRegistrar* pType = iter->second; - if (pType->HasInstance(pInstance)) - { - return pType; - } - } - - return NULL; -} - -void DynamicTypeLibrary::IntegrateType(ITypeRegistrar* pType, bool isDefault) -{ - const char* typeName = pType->GetName(); - - // If there's an existing registrar - ITypeRegistrar* pExistingType = m_types[typeName]; - assert(pExistingType != pType); // Sanity check - - // If the new type is the default (built-in) type but it's already been overridden - if (isDefault && pExistingType) - { - return; // Nothing to do - } - // TODO: Inform listeners that there's a new library available - // and ask if we should use it immediately or defer - - CExchanger exchanger; - - // If the type can be safely created, visited and destroyed - if (EvaluateType(pType, exchanger)) - { - // Override the type - m_types[typeName] = pType; - - if (!isDefault) - { - CryLogAlways("SoftCode: Overridden %s in library %s", typeName, m_name); - } - - const size_t instanceCount = (pExistingType) ? pExistingType->InstanceCount() : 0; - - // If there are any existing instances - if (instanceCount > 0) - { - CryLogAlways("SoftCode: Attempting to exchange %d %s instances to the new version...", (int)instanceCount, typeName); - - // Read instance members for type (removes data for resolved members) - if (pExistingType->ExchangeInstances(exchanger)) - { - exchanger.RewindForLoading(); - - // Write instance members for type - if (pType->ExchangeInstances(exchanger)) - { - // Success! Tell the listeners to fix up their pointers - for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next()) - { - exchanger.NotifyListenerOfReplacements(*notifier); - } - - CryLogAlways("SoftCode: %d %s instances successfully overridden to latest!", (int)instanceCount, typeName); - - // Clean up old instances - if (!pExistingType->DestroyInstances()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: Failed to destroy old instances of type %s - leak probable.", typeName); - } - } - else // Failed to create & write into new instances - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to create and write into new instances of %s. Attempting restore of old instances...", typeName); - if (!pType->DestroyInstances()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: Failed to destroy new instances of type %s - leak probable.", typeName); - } - - // Restore the original type library as the active one - m_types[typeName] = pExistingType; - - // Attempt to restore the old instances with their original data - exchanger.RewindForRestore(); - if (pExistingType->ExchangeInstances(exchanger)) - { - CryLogAlways("SoftCode: Type %s in library %s successfully restored to previous revision!", typeName, m_name); - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Restore of old %s instances failed. State now undefined!", typeName); - } - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to read members on %s", typeName); - } - } - } -} - -bool DynamicTypeLibrary::EvaluateType(ITypeRegistrar* pType, CExchanger& exchanger) -{ - // Try a full object life-time with a single instance of the - // new type before attempting a member exchange. This also allow the - // exchanger to determine the required members to be removed from the - // old instances. - bool testPassed = false; - - // Create a single test instance of the type - if (pType->CreateInstance()) - { - // Read the instance members (also prepares the exchanger member set) - if (pType->ExchangeInstances(exchanger)) - { - // Destroy the old instance - if (pType->DestroyInstances()) - { - // Indicate required members are now resolved - exchanger.LockMemberSet(); - testPassed = true; - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to destroy test instance of type: %s. New type will be skipped.", pType->GetName()); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to read members in test instance of type: %s. New type will be skipped.", pType->GetName()); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to create test instance of type: %s. New type will be skipped.", pType->GetName()); - } - - return testPassed; -} - -// ---- - -// The export we expect to find in the SoftCode modules -typedef ITypeLibrary* (__stdcall * TGetTypeLibraryFcn)(); - -static void SoftCode_UpdateCmd([[maybe_unused]] IConsoleCmdArgs* pArgs) -{ - gEnv->pSoftCodeMgr->LoadNewModules(); -} - -static int g_autoUpdatePeriod = 0; - -SoftCodeMgr::SoftCodeMgr() -{ - REGISTER_CVAR2("sc_autoupdate", &g_autoUpdatePeriod, 5, VF_CHEAT, "Set the auto-update poll period for new SoftCode modules. Set to zero to disable"); - REGISTER_COMMAND("sc_update", reinterpret_cast(&SoftCode_UpdateCmd), VF_CHEAT, "Loads any new SoftCode modules"); - - // Clear out any old modules - { - typedef std::vector TStringVec; - TStringVec filePaths; - - if (FindSoftCodeFiles("*", filePaths) > 0) - { - for (TStringVec::const_iterator iter(filePaths.begin()); iter != filePaths.end(); ++iter) - { - if (!DeleteFile(iter->c_str())) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to clean %s", iter->c_str()); - } - } - } - } -} - -SoftCodeMgr::~SoftCodeMgr() -{ - if (gEnv->pConsole) - { - gEnv->pConsole->RemoveCommand("sc_update"); - gEnv->pConsole->UnregisterVariable("sc_autoupdate"); - } -} - -// Used to register built-in libraries on first use -void SoftCodeMgr::RegisterLibrary(ITypeLibrary* pDefaultLib) -{ - DynamicTypeLibrary& typeLib = m_libraryMap[pDefaultLib->GetName()]; - typeLib.IntegrateLibrary(pDefaultLib, true); -} - -// Look for new SoftCode modules and load them, adding their types to the registry -void SoftCodeMgr::LoadNewModules() -{ - typedef std::vector TStringVec; - typedef TStringVec::const_iterator TModuleIter; - TStringVec modulePaths; - - // Find modules - FindSoftCodeFiles("*.dll", modulePaths); - - for (TModuleIter libIter(modulePaths.begin()); libIter != modulePaths.end(); ++libIter) - { - const char* moduleName = libIter->c_str(); - LoadModule(moduleName); - } -} - -void SoftCodeMgr::AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName) -{ - // Find an existing lib or create a new one to add the listener to - DynamicTypeLibrary& lib = m_libraryMap[libraryName]; - lib.AddListener(libraryName, pListener, listenerName); -} - -void SoftCodeMgr::RemoveListener(const char* libraryName, ISoftCodeListener* pListener) -{ - TLibMap::iterator iter(m_libraryMap.find(libraryName)); - - if (iter != m_libraryMap.end()) - { - iter->second.RemoveListener(pListener); - } -} - -// To be called regularly to poll for library updates -void SoftCodeMgr::PollForNewModules() -{ - if (g_autoUpdatePeriod > 0) - { - const CTimeValue frameStartTime(gEnv->pTimer->GetFrameStartTime(ITimer::ETIMER_UI)); - if (m_nextAutoCheckTime <= frameStartTime) - { - m_nextAutoCheckTime.SetSeconds((int64)g_autoUpdatePeriod); - m_nextAutoCheckTime += frameStartTime; - - // Attempt to find and load any new modules - LoadNewModules(); - } - } -} - -namespace -{ - // Util - class InstanceFixup - : public ISoftCodeListener - { - public: - InstanceFixup(void* pOldInstance) - : m_pOldInstance(pOldInstance) - , m_pNewInstance() {} - - virtual void InstanceReplaced(void* pOldInstance, void* pNewInstance) - { - if (m_pOldInstance == pOldInstance) - { - m_pNewInstance = pNewInstance; - } - } - - void* NewInstance() const { return m_pNewInstance; } - - private: - void* m_pOldInstance; - void* m_pNewInstance; - }; -} - -// Stops thread execution until a new SoftCode module is available -void* SoftCodeMgr::WaitForUpdate(void* pInstance) -{ - DynamicTypeLibrary* pOwningLib = NULL; - ITypeRegistrar* pOldType = NULL; - - // Find existing instance - for (TLibMap::iterator libIter(m_libraryMap.begin()); libIter != m_libraryMap.end(); ++libIter) - { - DynamicTypeLibrary& lib = libIter->second; - if (ITypeRegistrar* pType = lib.FindTypeForInstance(pInstance)) - { - pOwningLib = &lib; - pOldType = pType; - break; - } - } - - if (!pOwningLib) - { - CryFatalError("SoftCode: Attempting to wait for update on an unknown instance!"); - return NULL; - } - - InstanceFixup instanceFixup(pInstance); - pOwningLib->AddListener(pOwningLib->GetName(), &instanceFixup, "InstanceFixup"); - - while (true) - { - // Find and load new modules - LoadNewModules(); - - // Got a new instance? - if (instanceFixup.NewInstance()) - { - break; - } - - // Wait for a new module - CryLogAlways("SoftCode: Pausing execution until class %s in %s library is updated...", pOldType->GetName(), pOwningLib->GetName()); - __debugbreak(); // Stopped here? Check your log! - } - - pOwningLib->RemoveListener(&instanceFixup); - - return instanceFixup.NewInstance(); -} - -bool SoftCodeMgr::LoadModule(const char* moduleName) -{ - bool success = false; - - // If module not yet loaded - if (m_loadedSet.find(moduleName) == m_loadedSet.end()) - { - m_loadedSet.insert(moduleName); - - CryLogAlways("SoftCode: Found new module %s, attempting to load...", moduleName); - - HMODULE hModule = CryLoadLibrary(moduleName); - - if (hModule) - { - TGetTypeLibraryFcn pGetTypeLibraryFcn = reinterpret_cast(GetProcAddress(hModule, DLL_GETTYPELIBRARY)); - if (pGetTypeLibraryFcn) - { - // Add to list of loaded libs & override any earlier TypeLibraries already registered - ITypeLibrary* pTypeLibrary = pGetTypeLibraryFcn(); - if (pTypeLibrary) - { - const char* libraryName = pTypeLibrary->GetName(); - m_libraryMap[libraryName].IntegrateLibrary(pTypeLibrary, false); - - CryLogAlways("SoftCode: Loaded new type library \"%s\" from module %s.", libraryName, moduleName); - success = true; - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to resolve GetTypeLibrary() export in: %s (error: %x)", moduleName, GetLastError()); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load: %s (error: %x)", moduleName, GetLastError()); - } - } - - return success; -} - -size_t SoftCodeMgr::FindSoftCodeFiles(const string& searchName, std::vector& foundPaths) const -{ - foundPaths.clear(); - - stack_string scSoftCodeDir; - - TCHAR modulePath[MAX_PATH]; - GetModuleFileName(NULL, modulePath, sizeof(modulePath)); - scSoftCodeDir = PathUtil::GetParentDirectory(modulePath); - scSoftCodeDir += "\\SoftCode\\"; - - - gEnv->pFileIO->FindFiles(scSoftCodeDir.c_str(), searchName, [&](const char* filePath) -> bool - { - if (!gEnv->pFileIO->IsDirectory(filePath) && !gEnv->pFileIO->IsReadOnly(filePath)) - { - foundPaths.push_back(filePath); - } - - // Keep asking for more files, no early out - return true; - }); - - // Sort the paths into name order - std::sort(foundPaths.begin(), foundPaths.end()); - - return foundPaths.size(); -} - -#endif // SOFTCODE_ENABLED diff --git a/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.h b/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.h deleted file mode 100644 index f3f1b931a5..0000000000 --- a/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H -#define CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H -#pragma once - -#include - -#include "ISoftCodeMgr.h" - -struct ITypeLibrary; -struct ITypeRegistrar; -class CExchanger; - -// Internal: Performs the dynamic type management needed for SoftCoding -class DynamicTypeLibrary - : public ITypeLibrary -{ -public: - DynamicTypeLibrary(const char* name = NULL); - - // ITypeLibrary impl. - virtual const char* GetName(); - virtual void* CreateInstanceVoid(const char* typeName); - virtual void SetOverride(ITypeLibrary* pOverrideLib); - virtual size_t GetTypes(ITypeRegistrar** ppRegistrar, size_t& count) const; - - void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName); - void RemoveListener(ISoftCodeListener* pListener); - - // Attempts to add the library types the active set - void IntegrateLibrary(ITypeLibrary* pLib, bool isDefault); - - ITypeRegistrar* FindTypeForInstance(void* pInstance) const; - -private: - // Attempts to add the type the active set - void IntegrateType(ITypeRegistrar* pType, bool isDefault); - // Ensure the type can be safely created, visited, destroyed and prep exchanger - bool EvaluateType(ITypeRegistrar* pType, CExchanger& exchanger); - -private: - typedef std::vector TLibVec; - typedef std::map TTypeMap; - typedef CListenerSet TListeners; - - // The current set of active types - std::map m_types; - // Current set of loaded libraries - TLibVec m_history; - // Set of listeners to SC changes - TListeners m_listeners; - - const char* m_name; // Supplied by the first real library that registers -}; - - -// Implements the global singleton responsible for SoftCode management -class SoftCodeMgr - : public ISoftCodeMgr -{ -public: - SoftCodeMgr(); - virtual ~SoftCodeMgr(); - - // Used to register built-in libraries on first use - virtual void RegisterLibrary(ITypeLibrary* pLib); - - // Look for new SoftCode modules and load them, adding their types to the registry - virtual void LoadNewModules(); - - virtual void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName); - virtual void RemoveListener(const char* libraryName, ISoftCodeListener* pListener); - - // To be called regularly to poll for library updates - virtual void PollForNewModules(); - - // Stops thread execution until a new SoftCode module is available - virtual void* WaitForUpdate(void* pInstance); - -private: - bool LoadModule(const char* moduleName); - size_t FindSoftCodeFiles(const string& searchName, std::vector& foundPaths) const; - -private: - typedef std::map TLibMap; - typedef std::set TLoadedLibSet; - - // Records the history for each TypeLibrary keyed by library name - TLibMap m_libraryMap; - - // Records the library files already loaded - TLoadedLibSet m_loadedSet; - - // Used to determine when the next auto-update will occur - CTimeValue m_nextAutoCheckTime; -}; - - -#endif // CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H diff --git a/Code/CryEngine/CrySystem/System.cpp b/Code/CryEngine/CrySystem/System.cpp index 8a8cf14d91..9016ea99f1 100644 --- a/Code/CryEngine/CrySystem/System.cpp +++ b/Code/CryEngine/CrySystem/System.cpp @@ -124,8 +124,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include #include #include -#include -#include #include #include @@ -133,8 +131,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include #include "XConsole.h" #include "Log.h" -#include "NotificationNetwork.h" -#include "ProfileLog.h" #include "XML/xml.h" #include "XML/ReadWriteXMLSink.h" @@ -148,7 +144,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include "ServerThrottle.h" #include "ResourceManager.h" #include "HMDBus.h" -#include #include "IZLibCompressor.h" #include "IZlibDecompressor.h" @@ -267,22 +262,6 @@ namespace } #endif -#if defined(CVARS_WHITELIST) -struct SCVarsWhitelistConfigSink - : public ILoadConfigurationEntrySink -{ - virtual void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup) - { - ICVarsWhitelist* pCVarsWhitelist = gEnv->pSystem->GetCVarsWhiteList(); - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(szKey, false) : true; - if (whitelisted) - { - gEnv->pConsole->LoadConfigVar(szKey, szValue); - } - } -} g_CVarsWhitelistConfigSink; -#endif // defined(CVARS_WHITELIST) - ///////////////////////////////////////////////////////////////////////////////// // System Implementation. ////////////////////////////////////////////////////////////////////////// @@ -322,27 +301,13 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_env.pSystem = this; m_env.pTimer = &m_Time; m_env.pNameTable = &m_nameTable; - m_env.bServer = false; - m_env.bMultiplayer = false; - m_env.bHostMigrating = false; m_env.bIgnoreAllAsserts = false; m_env.bNoAssertDialog = false; - m_env.bTesting = false; m_env.pSharedEnvironment = pSharedEnvironment; - - m_env.SetFMVIsPlaying(false); - m_env.SetCutsceneIsPlaying(false); - - m_env.szDebugStatus[0] = '\0'; - -#if !defined(CONSOLE) - m_env.SetIsClient(false); -#endif ////////////////////////////////////////////////////////////////////////// m_pStreamEngine = NULL; - m_PhysThread = 0; m_pIFont = NULL; m_pIFontUi = NULL; @@ -370,7 +335,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_pILZ4Decompressor = NULL; m_pIZStdDecompressor = nullptr; m_pLocalizationManager = NULL; - m_sys_physics_CPU = 0; #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_2 #include AZ_RESTRICTED_FILE(System_cpp) @@ -378,15 +342,9 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_sys_min_step = 0; m_sys_max_step = 0; - m_pNotificationNetwork = NULL; - m_cvAIUpdate = NULL; m_pUserCallback = NULL; -#if defined(CVARS_WHITELIST) - m_pCVarsWhitelist = NULL; - m_pCVarsWhitelistConfigSink = &g_CVarsWhitelistConfigSink; -#endif // defined(CVARS_WHITELIST) m_sys_memory_debug = NULL; m_sysWarnings = NULL; m_sysKeyboard = NULL; @@ -409,13 +367,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_bNoCrashDialog = false; m_bNoErrorReportWindow = false; -#ifndef _RELEASE - m_checkpointLoadCount = 0; - m_loadOrigin = eLLO_Unknown; - m_hasJustResumed = false; - m_expectingMapCommand = false; -#endif - m_pCVarQuit = NULL; m_bForceNonDevMode = false; @@ -429,13 +380,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_nServerConfigSpec = CONFIG_VERYHIGH_SPEC; m_nMaxConfigSpec = CONFIG_VERYHIGH_SPEC; - //m_hPhysicsThread = INVALID_HANDLE_VALUE; - //m_hPhysicsActive = INVALID_HANDLE_VALUE; - //m_bStopPhysics = 0; - //m_bPhysicsActive = 0; - - m_pProgressListener = 0; - m_bPaused = false; m_bNoUpdate = false; m_nUpdateCounter = 0; @@ -444,12 +388,9 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_pXMLUtils = new CXmlUtils(this); m_pMemoryManager = CryGetIMemoryManager(); - m_pThreadTaskManager = new CThreadTaskManager; m_pResourceManager = new CResourceManager; m_pTextModeConsole = NULL; - InitThreadSystem(); - g_pPakHeap = new CMTSafeHeap; if (!AZ::AllocatorInstance::IsReady()) @@ -464,7 +405,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) AZ::Debug::Trace::Instance().Init(); } - m_UpdateTimesIdx = 0U; m_bNeedDoWorkDuringOcclusionChecks = false; m_eRuntimeState = ESYSTEM_EVENT_LEVEL_UNLOAD; @@ -478,15 +418,12 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) #endif m_ConfigPlatform = CONFIG_INVALID_PLATFORM; - - AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusConnect(); } ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// CSystem::~CSystem() { - AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusDisconnect(); ShutDown(); #if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_MESSAGE_HANDLER @@ -496,16 +433,8 @@ CSystem::~CSystem() CRY_ASSERT(m_windowMessageHandlers.empty() && "There exists a dangling window message handler somewhere"); SAFE_DELETE(m_pXMLUtils); - SAFE_DELETE(m_pThreadTaskManager); SAFE_DELETE(m_pResourceManager); SAFE_DELETE(m_pSystemEventDispatcher); - // SAFE_DELETE(m_pMemoryManager); - - if (gEnv && gEnv->pThreadManager) - { - gEnv->pThreadManager->UnRegisterThirdPartyThread("Main"); - } - ShutDownThreadSystem(); SAFE_DELETE(g_pPakHeap); @@ -617,8 +546,6 @@ void CSystem::ShutDown() SAFE_DELETE(m_pTextModeConsole); - KillPhysicsThread(); - if (m_sys_firstlaunch) { m_sys_firstlaunch->Set("0"); @@ -664,8 +591,6 @@ void CSystem::ShutDown() gEnv->pLyShine = nullptr; } - SAFE_DELETE(m_env.pResourceCompilerHelper); - SAFE_RELEASE(m_env.pMovieSystem); SAFE_RELEASE(m_env.pLyShine); SAFE_RELEASE(m_env.pCryFont); @@ -706,7 +631,6 @@ void CSystem::ShutDown() SAFE_RELEASE(m_sys_GraphicsQuality); SAFE_RELEASE(m_sys_firstlaunch); SAFE_RELEASE(m_sys_enable_budgetmonitoring); - SAFE_RELEASE(m_sys_physics_CPU); #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_3 @@ -716,9 +640,6 @@ void CSystem::ShutDown() SAFE_RELEASE(m_sys_min_step); SAFE_RELEASE(m_sys_max_step); - SAFE_RELEASE(m_pNotificationNetwork); - - SAFE_DELETE(m_env.pSoftCodeMgr); SAFE_DELETE(m_pDefaultValidator); m_pValidator = nullptr; @@ -743,7 +664,6 @@ void CSystem::ShutDown() SAFE_RELEASE(m_env.pConsole); // Log must be last thing released. - SAFE_RELEASE(m_env.pProfileLogSystem); if (m_env.pLog) { m_env.pLog->FlushAndClose(); @@ -752,10 +672,6 @@ void CSystem::ShutDown() ShutdownFileSystem(); -#if defined(MAP_LOADING_SLICING) - delete gEnv->pSystemScheduler; -#endif // defined(MAP_LOADING_SLICING) - ShutdownModuleLibraries(); EBUS_EVENT(CrySystemEventBus, OnCrySystemPostShutdown); @@ -841,273 +757,6 @@ ISystem* CSystem::GetCrySystem() return this; } -////////////////////////////////////////////////////////////////////////// -// Physics thread task -////////////////////////////////////////////////////////////////////////// -class CPhysicsThreadTask - : public IThreadTask -{ -public: - - CPhysicsThreadTask() - { - m_bStopRequested = 0; - m_bIsActive = 0; - m_stepRequested = 0; - m_bProcessing = 0; - m_doZeroStep = 0; - m_lastStepTimeTaken = 0U; - m_lastWaitTimeTaken = 0U; - } - - ////////////////////////////////////////////////////////////////////////// - // IThreadTask implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void OnUpdate() - { - Run(); - // At the end.. delete the task - delete this; - } - virtual void Stop() - { - Cancel(); - } - virtual SThreadTaskInfo* GetTaskInfo() { return &m_TaskInfo; } - ////////////////////////////////////////////////////////////////////////// - - virtual void Run() - { - m_bStopRequested = 0; - m_bIsActive = 1; - - float step, timeTaken, kSlowdown = 1.0f; - int nSlowFrames = 0; - int64 timeStart; -#ifdef ENABLE_LW_PROFILERS - LARGE_INTEGER stepStart, stepEnd; -#endif - LARGE_INTEGER waitStart, waitEnd; - MarkThisThreadForDebugging("Physics"); - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_5 -#include AZ_RESTRICTED_FILE(System_cpp) -#endif - while (true) - { - QueryPerformanceCounter(&waitStart); - m_FrameEvent.Wait(); // Wait untill new frame - QueryPerformanceCounter(&waitEnd); - m_lastWaitTimeTaken = waitEnd.QuadPart - waitStart.QuadPart; - - if (m_bStopRequested) - { - UnmarkThisThreadFromDebugging(); - return; - } - bool stepped = false; -#ifdef ENABLE_LW_PROFILERS - QueryPerformanceCounter(&stepStart); -#endif - while ((step = m_stepRequested) > 0 || m_doZeroStep) - { - stepped = true; - m_stepRequested = 0; - m_bProcessing = 1; - m_doZeroStep = 0; - - if (kSlowdown != 1.0f) - { - step = max(1, FtoI(step * kSlowdown * 50 - 0.5f)) * 0.02f; - } - timeStart = CryGetTicks(); - timeTaken = gEnv->pTimer->TicksToSeconds(CryGetTicks() - timeStart); - if (timeTaken > step * 0.9f) - { - if (++nSlowFrames > 5) - { - kSlowdown = step * 0.9f / timeTaken; - } - } - else - { - kSlowdown = 1.0f, nSlowFrames = 0; - } - m_bProcessing = 0; - //int timeSleep = (int)((m_timeTarget-gEnv->pTimer->GetAsyncTime()).GetMilliSeconds()*0.9f); - //Sleep(max(0,timeSleep)); - } - if (!stepped) - { - Sleep(0); - } - m_FrameDone.Set(); -#ifdef ENABLE_LW_PROFILERS - QueryPerformanceCounter(&stepEnd); - m_lastStepTimeTaken = stepEnd.QuadPart - stepStart.QuadPart; -#endif - } - } - virtual void Cancel() - { - Pause(); - m_bStopRequested = 1; - m_FrameEvent.Set(); - m_bIsActive = 0; - } - - int Pause() - { - if (m_bIsActive) - { - AZ_PROFILE_FUNCTION_STALL(AZ::Debug::ProfileCategory::System); - m_bIsActive = 0; - while (m_bProcessing) - { - ; - } - return 1; - } - return 0; - } - int Resume() - { - if (!m_bIsActive) - { - m_bIsActive = 1; - return 1; - } - return 0; - } - int IsActive() { return m_bIsActive; } - int RequestStep(float dt) - { - if (m_bIsActive && dt > FLT_EPSILON) - { - m_stepRequested += dt; - if (dt <= 0.0f) - { - m_doZeroStep = 1; - } - m_FrameEvent.Set(); - } - - return m_bProcessing; - } - float GetRequestedStep() { return m_stepRequested; } - - uint64 LastStepTaken() const - { - return m_lastStepTimeTaken; - } - - uint64 LastWaitTime() const - { - return m_lastWaitTimeTaken; - } - - void EnsureStepDone() - { - FRAME_PROFILER("SysUpdate:PhysicsEnsureDone", gEnv->pSystem, PROFILE_SYSTEM); - if (m_bIsActive) - { - while (m_stepRequested > 0.0f || m_bProcessing) - { - m_FrameDone.Wait(); - } - } - } - -protected: - - volatile int m_bStopRequested; - volatile int m_bIsActive; - volatile float m_stepRequested; - volatile int m_bProcessing; - volatile int m_doZeroStep; - volatile uint64 m_lastStepTimeTaken; - volatile uint64 m_lastWaitTimeTaken; - - CryEvent m_FrameEvent; - CryEvent m_FrameDone; - - SThreadTaskInfo m_TaskInfo; -}; - -void CSystem::CreatePhysicsThread() -{ - if (!m_PhysThread) - { - ////////////////////////////////////////////////////////////////////////// - SThreadTaskParams threadParams; - threadParams.name = "Physics"; - threadParams.nFlags = THREAD_TASK_BLOCKING; - threadParams.nStackSizeKB = PHYSICS_STACK_SIZE >> 10; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_6 -#include AZ_RESTRICTED_FILE(System_cpp) -#endif - - { - m_PhysThread = new CPhysicsThreadTask; - GetIThreadTaskManager()->RegisterTask(m_PhysThread, threadParams); - } - } - -} - -void CSystem::KillPhysicsThread() -{ - if (m_PhysThread) - { - GetIThreadTaskManager()->UnregisterTask(m_PhysThread); - m_PhysThread = 0; - } -} - -/////////////////////////////////////////////////////////////////////////// -// AzFramework::Terrain::TerrainDataNotificationBus START -void CSystem::OnTerrainDataCreateBegin() -{ - KillPhysicsThread(); -} - -void CSystem::OnTerrainDataDestroyBegin() -{ - OnTerrainDataCreateBegin(); -} - -// AzFramework::Terrain::TerrainDataNotificationBus END -/////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -int CSystem::SetThreadState(ESubsystem subsys, bool bActive) -{ - switch (subsys) - { - case ESubsys_Physics: - { - if (m_PhysThread) - { - return bActive ? ((CPhysicsThreadTask*)m_PhysThread)->Resume() : ((CPhysicsThreadTask*)m_PhysThread)->Pause(); - } - } - break; - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::SleepIfInactive() -{ - // ProcessSleep() - if (m_bDedicatedServer || m_bEditor || gEnv->bMultiplayer) - { - return; - } -} - ////////////////////////////////////////////////////////////////////////// void CSystem::SleepIfNeeded() { @@ -1180,11 +829,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) // do the dedicated sleep earlier than the frame profiler to avoid having it counted if (gEnv->IsDedicated()) { -#if defined(MAP_LOADING_SLICING) - gEnv->pSystemScheduler->SchedulingSleepIfNeeded(); -#else SleepIfNeeded(); -#endif // defined(MAP_LOADING_SLICING) } #endif //EXCLUDE_UPDATE_ON_CONSOLE @@ -1199,9 +844,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) m_nUpdateCounter++; #ifndef EXCLUDE_UPDATE_ON_CONSOLE - // Check if game needs to be sleeping when not active. - SleepIfInactive(); - if (m_pUserCallback) { m_pUserCallback->OnUpdate(); @@ -1216,7 +858,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) prev_sys_float_exceptions = g_cvars.sys_float_exceptions; EnableFloatExceptions(g_cvars.sys_float_exceptions); - UpdateFPExceptionsMaskForThreads(); } #endif //EXCLUDE_UPDATE_ON_CONSOLE ////////////////////////////////////////////////////////////////////////// @@ -1263,13 +904,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) } #endif //PROFILE_WITH_VTUNE -#ifdef SOFTCODE_SYSTEM_ENABLED - if (m_env.pSoftCodeMgr) - { - m_env.pSoftCodeMgr->PollForNewModules(); - } -#endif - if (m_pStreamEngine) { FRAME_PROFILER("StreamEngine::Update()", this, PROFILE_SYSTEM); @@ -1290,7 +924,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) if (m_sysNoUpdate && m_sysNoUpdate->GetIVal()) { bNoUpdate = true; - updateFlags = ESYSUPDATE_IGNORE_PHYSICS; } m_bNoUpdate = bNoUpdate; @@ -1373,16 +1006,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) return false; } -#ifndef EXCLUDE_UPDATE_ON_CONSOLE - - ////////////////////////////////////////////////////////////////////// - //update notification network system - if (m_pNotificationNetwork) - { - FRAME_PROFILER("SysUpdate:NotificationNetwork", this, PROFILE_SYSTEM); - m_pNotificationNetwork->Update(); - } -#endif //EXCLUDE_UPDATE_ON_CONSOLE ////////////////////////////////////////////////////////////////////// //update sound system Part 1 if in Editor / in Game Mode Viewsystem updates the Listeners if (!m_env.IsEditorGameMode()) @@ -1401,15 +1024,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) } } - ////////////////////////////////////////////////////////////////////////// - // Update Threads Task Manager. - ////////////////////////////////////////////////////////////////////////// - if (m_pThreadTaskManager) - { - FRAME_PROFILER("SysUpdate:ThreadTaskManager", this, PROFILE_SYSTEM); - m_pThreadTaskManager->OnUpdate(); - } - ////////////////////////////////////////////////////////////////////////// // Update Resource Manager. ////////////////////////////////////////////////////////////////////////// @@ -1418,77 +1032,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) m_pResourceManager->Update(); } - ////////////////////////////////////////////////////////////////////// - // update physic system - //static float time_zero = 0; - if (m_sys_physics_CPU->GetIVal() > 0 && !gEnv->IsDedicated()) - { - CreatePhysicsThread(); - } - else - { - KillPhysicsThread(); - } - - static int g_iPausedPhys = 0; - - CPhysicsThreadTask* pPhysicsThreadTask = ((CPhysicsThreadTask*)m_PhysThread); - if (!pPhysicsThreadTask) - { - FRAME_PROFILER_LEGACYONLY("SysUpdate:AllAIAndPhysics", this, PROFILE_SYSTEM); - AZ_TRACE_METHOD_NAME("SysUpdate::AllAIAndPhysics"); - - ////////////////////////////////////////////////////////////////////// - // update entity system (a little bit) before physics - if (nPauseMode != 1) - { - if (!bNoUpdate) - { - EBUS_EVENT(CrySystemEventBus, OnCrySystemPrePhysicsUpdate); - } - } - - // intermingle physics/AI updates so that if we get a big timestep (frame rate glitch etc) the - // AI gets to steer entities before they travel over cliffs etc. - const float maxTimeStep = 0.25f; - int maxSteps = 1; - //float fCurTime = m_Time.GetCurrTime(); - float timeToDo = m_Time.GetFrameTime();//fCurTime - fPrevTime; - if (m_env.bMultiplayer) - { - timeToDo = m_Time.GetRealFrameTime(); - } - - - - while (timeToDo > 0.0001f && maxSteps-- > 0) - { - float thisStep = min(maxTimeStep, timeToDo); - timeToDo -= thisStep; - - - EBUS_EVENT(CrySystemEventBus, OnCrySystemPostPhysicsUpdate); - } - - } - else - { - - // In multithreaded physics mode, post physics fires after physics events are dispatched on the main thread. - EBUS_EVENT(CrySystemEventBus, OnCrySystemPostPhysicsUpdate); - - ////////////////////////////////////////////////////////////////////// - // update entity system (a little bit) before physics - if (nPauseMode != 1) - { - if (!bNoUpdate) - { - EBUS_EVENT(CrySystemEventBus, OnCrySystemPrePhysicsUpdate); - } - } - - } - // Use UI timer for CryMovie, because it should not be affected by pausing game time const float fMovieFrameTime = m_Time.GetFrameTime(ITimer::ETIMER_UI); @@ -1550,8 +1093,6 @@ bool CSystem::UpdatePostTickBus(int updateFlags, int /*nPauseMode*/) m_updateTimes.push_back(std::make_pair(cur_time, updateTime)); } - UpdateUpdateTimes(); - { FRAME_PROFILER("SysUpdate - SystemEventDispatcher::Update", this, PROFILE_SYSTEM); m_pSystemEventDispatcher->Update(); @@ -1890,12 +1431,6 @@ ILocalizationManager* CSystem::GetLocalizationManager() return m_pLocalizationManager; } -////////////////////////////////////////////////////////////////////////// -IThreadTaskManager* CSystem::GetIThreadTaskManager() -{ - return m_pThreadTaskManager; -} - ////////////////////////////////////////////////////////////////////////// IResourceManager* CSystem::GetIResourceManager() { @@ -1960,10 +1495,6 @@ void CSystem::ExecuteCommandLine(bool deferred) if (pCmd->GetType() == eCLAT_Post) { string sLine = pCmd->GetName(); - -#if defined(CVARS_WHITELIST) - if (!GetCVarsWhiteList() || GetCVarsWhiteList()->IsWhiteListed(sLine, false)) -#endif { if (pCmd->GetValue()) { @@ -1973,12 +1504,6 @@ void CSystem::ExecuteCommandLine(bool deferred) GetILog()->Log("Executing command from command line: \n%s\n", sLine.c_str()); // - the actual command might be executed much later (e.g. level load pause) GetIConsole()->ExecuteString(sLine.c_str(), false, deferred); } -#if defined(CVARS_WHITELIST) - else if (gEnv->IsDedicated()) - { - GetILog()->LogError("Failed to execute command: '%s' as it is not whitelisted\n", sLine.c_str()); - } -#endif } } @@ -2078,93 +1603,6 @@ void CProfilingSystem::VTunePause() #endif } -////////////////////////////////////////////////////////////////////////// -sUpdateTimes& CSystem::GetCurrentUpdateTimeStats() -{ - return m_UpdateTimes[m_UpdateTimesIdx]; -} - -////////////////////////////////////////////////////////////////////////// -const sUpdateTimes* CSystem::GetUpdateTimeStats(uint32& index, uint32& num) -{ - index = m_UpdateTimesIdx; - num = NUM_UPDATE_TIMES; - return m_UpdateTimes; -} - -void CSystem::UpdateUpdateTimes() -{ - sUpdateTimes& sample = m_UpdateTimes[m_UpdateTimesIdx]; - if (m_PhysThread) - { - static uint64 lastPhysTime = 0U; - static uint64 lastMainTime = 0U; - static uint64 lastYields = 0U; - static uint64 lastPhysWait = 0U; - uint64 physTime = 0, mainTime = 0; - uint32 yields = 0; - physTime = ((CPhysicsThreadTask*)m_PhysThread)->LastStepTaken(); - mainTime = CryGetTicks() - lastMainTime; - lastMainTime = mainTime; - lastPhysWait = ((CPhysicsThreadTask*)m_PhysThread)->LastWaitTime(); - sample.PhysStepTime = physTime; - sample.SysUpdateTime = mainTime; - sample.PhysYields = yields; - sample.physWaitTime = lastPhysWait; - } - ++m_UpdateTimesIdx; - if (m_UpdateTimesIdx >= NUM_UPDATE_TIMES) - { - m_UpdateTimesIdx = 0; - } -} - - -#ifndef _RELEASE -void CSystem::GetCheckpointData(ICheckpointData& data) -{ - data.m_totalLoads = m_checkpointLoadCount; - data.m_loadOrigin = m_loadOrigin; -} - -void CSystem::IncreaseCheckpointLoadCount() -{ - if (!m_hasJustResumed) - { - ++m_checkpointLoadCount; - } - - m_hasJustResumed = false; -} - -void CSystem::SetLoadOrigin(LevelLoadOrigin origin) -{ - switch (origin) - { - case eLLO_NewLevel: // Intentional fall through - case eLLO_Level2Level: - m_expectingMapCommand = true; - break; - - case eLLO_Resumed: - m_hasJustResumed = true; - break; - - case eLLO_MapCmd: - if (m_expectingMapCommand) - { - // We knew a map command was coming, so don't process this. - m_expectingMapCommand = false; - return; - } - break; - } - - m_loadOrigin = origin; - m_checkpointLoadCount = 0; -} -#endif - bool CSystem::SteamInit() { #if USE_STEAM diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index c4f3bfabd6..e27dfe4866 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -26,14 +26,12 @@ #include "MTSafeAllocator.h" #include "CPUDetect.h" #include -#include "ThreadTask.h" #include "RenderBus.h" #include #include #include -#include namespace AzFramework { @@ -44,7 +42,6 @@ struct IConsoleCmdArgs; class CServerThrottle; struct IZLibCompressor; class CWatchdogThread; -class CThreadManager; #if defined(AZ_RESTRICTED_PLATFORM) #undef AZ_RESTRICTED_SECTION @@ -183,8 +180,6 @@ class CThreadManager; #include "CryLibrary.h" #endif -#define NUM_UPDATE_TIMES (128U) - #ifdef WIN32 typedef void* WIN_HMODULE; #else @@ -241,7 +236,6 @@ struct SSystemCVars int sys_WER; int sys_dump_type; int sys_ai; - int sys_physics; int sys_entitysystem; int sys_trackview; int sys_vtune; @@ -342,7 +336,6 @@ class CSystem , public IWindowMessageHandler , public AZ::RenderNotificationsBus::Handler , public CrySystemRequestBus::Handler - , private AzFramework::Terrain::TerrainDataNotificationBus::Handler { public: @@ -397,20 +390,8 @@ public: ISystem* GetCrySystem() override; //////////////////////////////////////////////////////////////////////// - //! Update screen during loading. - void UpdateLoadingScreen(); - - //! Update screen and call some important tick functions during loading. - void SynchronousLoadingTick(const char* pFunc, int line); - uint32 GetUsedMemory(); -#ifndef _RELEASE - virtual void GetCheckpointData(ICheckpointData& data); - virtual void IncreaseCheckpointLoadCount(); - virtual void SetLoadOrigin(LevelLoadOrigin origin); -#endif - virtual bool SteamInit(); void Relaunch(bool bRelaunch); @@ -425,8 +406,6 @@ public: virtual const char* GetUserName(); virtual int GetApplicationInstance(); int GetApplicationLogInstance(const char* logFilePath) override; - virtual sUpdateTimes& GetCurrentUpdateTimeStats(); - virtual const sUpdateTimes* GetUpdateTimeStats(uint32&, uint32&); ITimer* GetITimer(){ return m_env.pTimer; } AZ::IO::IArchive* GetIPak() { return m_env.pCryPak; }; @@ -434,7 +413,6 @@ public: IRemoteConsole* GetIRemoteConsole(); IMovieSystem* GetIMovieSystem() { return m_env.pMovieSystem; }; IMemoryManager* GetIMemoryManager(){ return m_pMemoryManager; } - IThreadManager* GetIThreadManager() override {return m_env.pThreadManager; } ICryFont* GetICryFont(){ return m_env.pCryFont; } ILog* GetILog(){ return m_env.pLog; } ICmdLine* GetICmdLine(){ return m_pCmdLine; } @@ -444,11 +422,8 @@ public: IViewSystem* GetIViewSystem(); ILevelSystem* GetILevelSystem(); ISystemEventDispatcher* GetISystemEventDispatcher() { return m_pSystemEventDispatcher; } - IThreadTaskManager* GetIThreadTaskManager(); IResourceManager* GetIResourceManager(); ITextModeConsole* GetITextModeConsole(); - IVisualLog* GetIVisualLog() { return m_env.pVisualLog; } - INotificationNetwork* GetINotificationNetwork() { return m_pNotificationNetwork; } IProfilingSystem* GetIProfilingSystem() { return &m_ProfilingSystem; } IZLibCompressor* GetIZLibCompressor() { return m_pIZLibCompressor; } IZLibDecompressor* GetIZLibDecompressor() { return m_pIZLibDecompressor; } @@ -459,19 +434,6 @@ public: CPNoise3* GetNoiseGen(); virtual uint64 GetUpdateCounter() { return m_nUpdateCounter; }; - virtual void SetLoadingProgressListener(ILoadingProgressListener* pLoadingProgressListener) - { - m_pProgressListener = pLoadingProgressListener; - }; - - virtual ILoadingProgressListener* GetLoadingProgressListener() const - { - return m_pProgressListener; - }; - - void SetIMaterialEffects(IMaterialEffects* pMaterialEffects) { m_env.pMaterialEffects = pMaterialEffects; } - void SetIOpticsManager(IOpticsManager* pOpticsManager) { m_env.pOpticsManager = pOpticsManager; } - void SetIVisualLog(IVisualLog* pVisualLog) { m_env.pVisualLog = pVisualLog; } void DetectGameFolderAccessRights(); virtual void ExecuteCommandLine(bool deferred=true); @@ -554,12 +516,6 @@ public: //! Return pointer to user defined callback. ISystemUserCallback* GetUserCallback() const { return m_pUserCallback; }; -#if defined(CVARS_WHITELIST) - virtual ICVarsWhitelist* GetCVarsWhiteList() const { return m_pCVarsWhitelist; }; - virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const { return m_pCVarsWhitelistConfigSink; } -#else - virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const { return nullptr; } -#endif // defined(CVARS_WHITELIST) ////////////////////////////////////////////////////////////////////////// virtual void SaveConfiguration(); @@ -571,7 +527,6 @@ public: virtual void SetConfigPlatform(ESystemConfigPlatform platform); ////////////////////////////////////////////////////////////////////////// - virtual int SetThreadState(ESubsystem subsys, bool bActive); virtual bool IsPaused() const { return m_bPaused; }; virtual ILocalizationManager* GetLocalizationManager(); @@ -608,8 +563,6 @@ private: // Release all resources. void ShutDown(); - void SleepIfInactive(); - bool LoadEngineDLLs(); //! @name Initialization routines @@ -623,12 +576,6 @@ private: //@} - ////////////////////////////////////////////////////////////////////////// - // Threading functions. - ////////////////////////////////////////////////////////////////////////// - void InitThreadSystem(); - void ShutDownThreadSystem(); - ////////////////////////////////////////////////////////////////////////// // Helper functions. ////////////////////////////////////////////////////////////////////////// @@ -645,9 +592,6 @@ private: void LogBuildInfo(); void SetDevMode(bool bEnable); - void CreatePhysicsThread(); - void KillPhysicsThread(); - #ifndef _RELEASE static void SystemVersionChanged(ICVar* pCVar); #endif // #ifndef _RELEASE @@ -676,7 +620,6 @@ public: virtual bool GetForceNonDevMode() const; virtual bool WasInDevMode() const { return m_bWasInDevMode; }; virtual bool IsDevMode() const { return m_bInDevMode && !GetForceNonDevMode(); } - virtual bool IsMinimalMode() const { return m_bMinimal; } virtual bool IsMODValid(const char* szMODName) const { if (!szMODName || strstr(szMODName, ".") || strstr(szMODName, "\\")) @@ -727,7 +670,6 @@ private: // ------------------------------------------------------ bool m_bRelaunch; //!< relaunching the app or not (true beforerelaunch) int m_iLoadingMode; //!< Game is loading w/o changing context (0 not, 1 quickloading, 2 full loading) bool m_bTestMode; //!< If running in testing mode. - bool m_bMinimal; //!< If running in 'minimal mode'. bool m_bEditor; //!< If running in Editor. bool m_bNoCrashDialog; bool m_bNoErrorReportWindow; @@ -742,16 +684,6 @@ private: // ------------------------------------------------------ SDefaultValidator* m_pDefaultValidator; //!< CCpuFeatures* m_pCpu; //!< CPU features int m_ttMemStatSS; //!< Time to memstat screenshot - string m_szCmdLine; - - int m_iTraceAllocations; - -#ifndef _RELEASE - int m_checkpointLoadCount;// Total times game has loaded from a checkpoint - LevelLoadOrigin m_loadOrigin; // Where the load was initiated from - bool m_hasJustResumed; // Has resume game just been called - bool m_expectingMapCommand; -#endif bool m_bDrawConsole; //!< Set to true if OK to draw the console. bool m_bDrawUI; //!< Set to true if OK to draw UI. @@ -867,8 +799,6 @@ private: // ------------------------------------------------------ ICVar* m_sys_asset_processor; ICVar* m_sys_load_files_to_memory; - ICVar* m_sys_physics_CPU; - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_H_SECTION_4 #include AZ_RESTRICTED_FILE(System_h) @@ -891,15 +821,6 @@ private: // ------------------------------------------------------ //! User define callback for system events. ISystemUserCallback* m_pUserCallback; -#if defined(CVARS_WHITELIST) - ////////////////////////////////////////////////////////////////////////// - //! User define callback for whitelisting cvars - ICVarsWhitelist* m_pCVarsWhitelist; - ILoadConfigurationEntrySink* m_pCVarsWhitelistConfigSink; -#endif // defined(CVARS_WHITELIST) - - //int m_nCurrentLogVerbosity; - SFileVersion m_fileVersion; SFileVersion m_productVersion; SFileVersion m_buildVersion; @@ -910,8 +831,6 @@ private: // ------------------------------------------------------ // Name table. CNameTable m_nameTable; - IThreadTask* m_PhysThread; - ESystemConfigSpec m_nServerConfigSpec; ESystemConfigSpec m_nMaxConfigSpec; ESystemConfigPlatform m_ConfigPlatform; @@ -919,8 +838,6 @@ private: // ------------------------------------------------------ std::unique_ptr m_pServerThrottle; CProfilingSystem m_ProfilingSystem; - sUpdateTimes m_UpdateTimes[NUM_UPDATE_TIMES]; - uint32 m_UpdateTimesIdx; // Pause mode. bool m_bPaused; @@ -991,26 +908,14 @@ private: ESystemGlobalState m_systemGlobalState; static const char* GetSystemGlobalStateName(const ESystemGlobalState systemGlobalState); - /////////////////////////////////////////////////////////////////////////// - // AzFramework::Terrain::TerrainDataNotificationBus START - void OnTerrainDataCreateBegin() override; - void OnTerrainDataDestroyBegin() override; - // AzFramework::Terrain::TerrainDataNotificationBus END - /////////////////////////////////////////////////////////////////////////// - public: void InitLocalization(); - void UpdateUpdateTimes(); protected: // ------------------------------------------------------------- - ILoadingProgressListener* m_pProgressListener; CCmdLine* m_pCmdLine; - CThreadManager* m_pThreadManager; - CThreadTaskManager* m_pThreadTaskManager; class CResourceManager* m_pResourceManager; ITextModeConsole* m_pTextModeConsole; - INotificationNetwork* m_pNotificationNetwork; string m_currentLanguageAudio; string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_es3.cfg or system_android_opengl.cfg or system_windows_pc.cfg diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index 8bf2fb8930..48cb5e0d9e 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -35,13 +35,9 @@ #define SYSTEMINIT_CPP_SECTION_17 17 #endif -#if defined(MAP_LOADING_SLICING) -#include "SystemScheduler.h" -#endif // defined(MAP_LOADING_SLICING) #include "CryLibrary.h" #include "CryPath.h" #include -#include #include #include @@ -103,16 +99,12 @@ #include "PhysRenderer.h" #include "LocalizedStringManager.h" #include "SystemEventDispatcher.h" -#include "ThreadConfigManager.h" #include "Validator.h" #include "ServerThrottle.h" #include "SystemCFG.h" #include "AutoDetectSpec.h" #include "ResourceManager.h" #include "MTSafeAllocator.h" -#include "NotificationNetwork.h" -#include "ProfileLogSystem.h" -#include "SoftCode/SoftCodeMgr.h" #include "ZLibCompressor.h" #include "ZLibDecompressor.h" #include "ZStdDecompressor.h" @@ -146,8 +138,6 @@ #include "MobileDetectSpec.h" #endif -#include "IDebugCallStack.h" - #include "WindowsConsole.h" #if defined(EXTERNAL_CRASH_REPORTING) @@ -163,11 +153,6 @@ # include #endif -// if we enable the built-in local version instead of remote: -#if defined(CRY_ENABLE_RC_HELPER) -#include "ResourceCompilerHelper.h" -#endif - #ifdef WIN32 extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers); #endif @@ -400,26 +385,20 @@ struct SysSpecOverrideSink } else { - // This could bypass the restricted/whitelisted cvar checks that exist elsewhere depending on + // This could bypass the restricted cvar checks that exist elsewhere depending on // the calling code so we also need check here before setting. bool isConst = pCvar->IsConstCVar(); bool isCheat = ((pCvar->GetFlags() & (VF_CHEAT | VF_CHEAT_NOCHECK | VF_CHEAT_ALWAYS_CHECK)) != 0); bool isReadOnly = ((pCvar->GetFlags() & VF_READONLY) != 0); bool isDeprecated = ((pCvar->GetFlags() & VF_DEPRECATED) != 0); bool allowApplyCvar = true; - bool whitelisted = true; - -#if defined CVARS_WHITELIST - ICVarsWhitelist* cvarWhitelist = gEnv->pSystem->GetCVarsWhiteList(); - whitelisted = cvarWhitelist ? cvarWhitelist->IsWhiteListed(szKey, true) : true; -#endif if ((isConst || isCheat || isReadOnly) || isDeprecated) { allowApplyCvar = !isDeprecated && (gEnv->pSystem->IsDevMode()) || (gEnv->IsEditor()); } - if ((allowApplyCvar && whitelisted) || ALLOW_CONST_CVAR_MODIFICATIONS) + if ((allowApplyCvar) || ALLOW_CONST_CVAR_MODIFICATIONS) { applyCvar = true; } @@ -1028,7 +1007,6 @@ bool CSystem::InitFileSystem() // get the DirectInstance FileIOBase which should be the AZ::LocalFileIO m_env.pFileIO = AZ::IO::FileIOBase::GetDirectInstance(); - m_env.pResourceCompilerHelper = nullptr; m_env.pCryPak = AZ::Interface::Get(); m_env.pFileIO = AZ::IO::FileIOBase::GetInstance(); @@ -1107,8 +1085,7 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&) { LOADING_TIME_PROFILE_SECTION; { - ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetCVarsWhiteListConfigSink(); - LoadConfiguration(m_systemConfigName.c_str(), pCVarsWhiteListConfigSink); + LoadConfiguration(m_systemConfigName.c_str()); AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Loading system configuration from %s...", m_systemConfigName.c_str()); } @@ -1118,13 +1095,6 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&) GetISystem()->SetConfigPlatform(GetDevicePlatform()); -#if defined(CRY_ENABLE_RC_HELPER) - if (!m_env.pResourceCompilerHelper) - { - m_env.pResourceCompilerHelper = new CResourceCompilerHelper(); - } -#endif - auto projectPath = AZ::Utils::GetProjectPath(); AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Path: %s\n", projectPath.empty() ? "None specified" : projectPath.c_str()); @@ -1179,7 +1149,6 @@ bool CSystem::InitAudioSystem(const SSystemInitParams& initParams) bool useRealAudioSystem = false; if (!initParams.bPreview - && !initParams.bMinimal && !m_bDedicatedServer && m_sys_audio_disable->GetIVal() == 0) { @@ -1672,12 +1641,8 @@ bool CSystem::Init(const SSystemInitParams& startupParams) gEnv->mMainThreadId = GetCurrentThreadId(); //Set this ASAP on startup InlineInitializationProcessing("CSystem::Init start"); - m_szCmdLine = startupParams.szSystemCmdLine; - m_env.szCmdLine = m_szCmdLine.c_str(); - m_env.bTesting = startupParams.bTesting; - m_env.bNoAssertDialog = startupParams.bTesting; - m_env.bNoRandomSeed = startupParams.bNoRandom; + m_env.bNoAssertDialog = false; m_bNoCrashDialog = gEnv->IsDedicated(); @@ -1754,16 +1719,10 @@ AZ_POP_DISABLE_WARNING m_bPreviewMode = startupParams.bPreview; m_bTestMode = startupParams.bTestMode; m_pUserCallback = startupParams.pUserCallback; - m_bMinimal = startupParams.bMinimal; -#if defined(CVARS_WHITELIST) - m_pCVarsWhitelist = startupParams.pCVarsWhitelist; -#endif // defined(CVARS_WHITELIST) m_bDedicatedServer = startupParams.bDedicatedServer; m_currentLanguageAudio = ""; - memcpy(gEnv->pProtectedFunctions, startupParams.pProtectedFunctions, sizeof(startupParams.pProtectedFunctions)); - #if !defined(CONSOLE) m_env.SetIsEditor(m_bEditor); m_env.SetIsEditorGameMode(false); @@ -1771,7 +1730,6 @@ AZ_POP_DISABLE_WARNING #endif m_env.SetToolMode(startupParams.bToolMode); - m_env.bIsOutOfMemory = false; if (m_bEditor) { @@ -1935,23 +1893,6 @@ AZ_POP_DISABLE_WARNING // so we log this immediately after setting the log filename LogVersion(); - //here we should be good to ask Crypak to do something - - // Initialise after pLog and CPU feature initialization - // AND after console creation (Editor only) - // May need access to engine folder .pak files - gEnv->pThreadManager->GetThreadConfigManager()->LoadConfig("config/engine_core.thread_config"); - - if (m_bEditor) - { - gEnv->pThreadManager->GetThreadConfigManager()->LoadConfig("config/engine_sandbox.thread_config"); - } - - // Setup main thread - void* pThreadHandle = 0; // Let system figure out thread handle - gEnv->pThreadManager->RegisterThirdPartyThread(pThreadHandle, "Main"); - m_env.pProfileLogSystem = new CProfileLogSystem(); - bool devModeEnable = true; #if defined(_RELEASE) @@ -1967,22 +1908,6 @@ AZ_POP_DISABLE_WARNING SetDevMode(devModeEnable); - ////////////////////////////////////////////////////////////////////////// - // CREATE NOTIFICATION NETWORK - ////////////////////////////////////////////////////////////////////////// - m_pNotificationNetwork = nullptr; -#ifndef _RELEASE - #ifndef LINUX - - if (!startupParams.bMinimal) - { - m_pNotificationNetwork = CNotificationNetwork::Create(); - } - #endif//LINUX -#endif // _RELEASE - - InlineInitializationProcessing("CSystem::Init NotificationNetwork"); - ////////////////////////////////////////////////////////////////////////// // CREATE CONSOLE ////////////////////////////////////////////////////////////////////////// @@ -2051,8 +1976,6 @@ AZ_POP_DISABLE_WARNING // CPU features detection. m_pCpu = new CCpuFeatures; m_pCpu->Detect(); - m_env.pi.numCoresAvailableToProcess = m_pCpu->GetCPUCount(); - m_env.pi.numLogicalProcessors = m_pCpu->GetLogicalCPUCount(); // Check hard minimum CPU requirements if (!CheckCPURequirements(m_pCpu, this)) @@ -2102,17 +2025,15 @@ AZ_POP_DISABLE_WARNING } { - ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetCVarsWhiteListConfigSink(); - // We have to load this file again since first time we did it without devmode - LoadConfiguration(m_systemConfigName.c_str(), pCVarsWhiteListConfigSink); + LoadConfiguration(m_systemConfigName.c_str()); // Optional user defined overrides - LoadConfiguration("user.cfg", pCVarsWhiteListConfigSink); + LoadConfiguration("user.cfg"); #if defined(ENABLE_STATS_AGENT) if (m_pCmdLine->FindArg(eCLAT_Pre, "useamblecfg")) { - LoadConfiguration("amble.cfg", pCVarsWhiteListConfigSink); + LoadConfiguration("amble.cfg"); } #endif } @@ -2159,7 +2080,7 @@ AZ_POP_DISABLE_WARNING InlineInitializationProcessing("CSystem::Init LoadConfigurations"); #ifdef WIN32 - if ((g_cvars.sys_WER) && (!startupParams.bMinimal)) + if ((g_cvars.sys_WER)) { SetUnhandledExceptionFilter(CryEngineExceptionFilterWER); } @@ -2169,7 +2090,6 @@ AZ_POP_DISABLE_WARNING ////////////////////////////////////////////////////////////////////////// // Localization ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bMinimal) { InitLocalization(); } @@ -2187,7 +2107,6 @@ AZ_POP_DISABLE_WARNING ////////////////////////////////////////////////////////////////////////// // AUDIO ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bMinimal) { if (InitAudioSystem(startupParams)) { @@ -2210,12 +2129,6 @@ AZ_POP_DISABLE_WARNING m_pUserCallback->OnInitProgress("First time asset processing - may take a minute..."); } -#ifdef SOFTCODE_SYSTEM_ENABLED - m_env.pSoftCodeMgr = new SoftCodeMgr(); -#else - m_env.pSoftCodeMgr = nullptr; -#endif - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // System cursor @@ -2225,8 +2138,7 @@ AZ_POP_DISABLE_WARNING // - System cursor has to be enabled manually by the Game if needed; the custom UiCursor will typically be used instead if (!gEnv->IsDedicated() && - !gEnv->IsEditor() && - !startupParams.bTesting) + !gEnv->IsEditor()) { AzFramework::InputSystemCursorRequestBus::Event(AzFramework::InputDeviceMouse::Id, &AzFramework::InputSystemCursorRequests::SetSystemCursorState, @@ -2322,27 +2234,6 @@ AZ_POP_DISABLE_WARNING InlineInitializationProcessing("CSystem::Init ZStdDecompressor"); - ////////////////////////////////////////////////////////////////////////// - // Initialize task threads. - ////////////////////////////////////////////////////////////////////////// - { - m_pThreadTaskManager->InitThreads(); - - SetAffinity(); - AZ_Assert(CryMemory::IsHeapValid(), "CryMemory heap must be valid before initializing VTune."); - - - if (strstr(startupParams.szSystemCmdLine, "-VTUNE") != 0 || g_cvars.sys_vtune != 0) - { - if (!InitVTuneProfiler()) - { - return false; - } - } - } - - InlineInitializationProcessing("CSystem::Init InitTaskThreads"); - if (m_env.pLyShine) { m_env.pLyShine->PostInit(); @@ -2366,8 +2257,6 @@ AZ_POP_DISABLE_WARNING } } EnableFloatExceptions(g_cvars.sys_float_exceptions); - - MarkThisThreadForDebugging("Main"); } InlineInitializationProcessing("CSystem::Init End"); @@ -2422,8 +2311,7 @@ static void LoadConfigurationCmd(IConsoleCmdArgs* pParams) return; } - ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetISystem()->GetCVarsWhiteListConfigSink(); - GetISystem()->LoadConfiguration(string("Config/") + pParams->GetArg(1), pCVarsWhiteListConfigSink); + GetISystem()->LoadConfiguration(string("Config/") + pParams->GetArg(1)); } @@ -2648,20 +2536,6 @@ void CmdDrillToFile(IConsoleCmdArgs* pArgs) } } -void ChangeLogAllocations(ICVar* pVal) -{ - g_iTraceAllocations = pVal->GetIVal(); - - if (g_iTraceAllocations == 2) - { - IDebugCallStack::instance()->StartMemLog(); - } - else - { - IDebugCallStack::instance()->StopMemLog(); - } -} - ////////////////////////////////////////////////////////////////////////// void CSystem::CreateSystemVars() { @@ -2719,9 +2593,6 @@ void CSystem::CreateSystemVars() m_cvAIUpdate = REGISTER_INT("ai_NoUpdate", 0, VF_CHEAT, "Disables AI system update when 1"); - m_iTraceAllocations = g_iTraceAllocations; - REGISTER_CVAR2_CB("sys_logallocations", &m_iTraceAllocations, m_iTraceAllocations, VF_DUMPTODISK, "Save allocation call stack", ChangeLogAllocations); - m_cvMemStats = REGISTER_INT("MemStats", 0, 0, "0/x=refresh rate in milliseconds\n" "Use 1000 to switch on and 0 to switch off\n" @@ -2860,16 +2731,6 @@ void CSystem::CreateSystemVars() m_sys_TaskThread_CPU[5] = REGISTER_INT("sys_TaskThread5_CPU", 1, 0, "Specifies the physical CPU index taskthread5 will run on"); - //if physics thread is excluded all locks inside are mapped to NO_LOCK - //var must be not visible to accidentally get enabled -#if defined(EXCLUDE_PHYSICS_THREAD) - m_sys_physics_CPU = REGISTER_INT("sys_physics_CPU_disabled", 0, 0, - "Specifies the physical CPU index physics will run on"); -#else - m_sys_physics_CPU = REGISTER_INT("sys_physics_CPU", 1, 0, - "Specifies the physical CPU index physics will run on"); -#endif - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_12 #include AZ_RESTRICTED_FILE(SystemInit_cpp) @@ -3033,7 +2894,6 @@ void CSystem::CreateSystemVars() "0=off / 1=enabled"); */ REGISTER_CVAR2("sys_AI", &g_cvars.sys_ai, 1, 0, "Enables AI Update"); - REGISTER_CVAR2("sys_physics", &g_cvars.sys_physics, 1, 0, "Enables Physics Update"); REGISTER_CVAR2("sys_entities", &g_cvars.sys_entitysystem, 1, 0, "Enables Entities Update"); REGISTER_CVAR2("sys_trackview", &g_cvars.sys_trackview, 1, 0, "Enables TrackView Update"); @@ -3068,10 +2928,6 @@ void CSystem::CreateSystemVars() REGISTER_STRING("dlc_directory", "", 0, "Holds the path to the directory where DLC should be installed to and read from"); -#if defined(MAP_LOADING_SLICING) - CreateSystemScheduler(this); -#endif // defined(MAP_LOADING_SLICING) - #if defined(WIN32) || defined(WIN64) REGISTER_INT("sys_screensaver_allowed", 0, VF_NULL, "Specifies if screen saver is allowed to start up while the game is running."); #endif diff --git a/Code/CryEngine/CrySystem/SystemRender.cpp b/Code/CryEngine/CrySystem/SystemRender.cpp index 9e148bbc2b..b608ef5335 100644 --- a/Code/CryEngine/CrySystem/SystemRender.cpp +++ b/Code/CryEngine/CrySystem/SystemRender.cpp @@ -39,8 +39,6 @@ #include #include -#include "ThreadInfo.h" - #include #if defined(AZ_RESTRICTED_PLATFORM) @@ -90,52 +88,6 @@ void CSystem::OnScene3DEnd() } } - -//! Update screen and call some important tick functions during loading. -void CSystem::SynchronousLoadingTick([[maybe_unused]] const char* pFunc, [[maybe_unused]] int line) -{ - LOADING_TIME_PROFILE_SECTION; - if (gEnv && gEnv->bMultiplayer && !gEnv->IsEditor()) - { - //UpdateLoadingScreen currently contains a couple of tick functions that need to be called regularly during the synchronous level loading, - //when the usual engine and game ticks are suspended. - UpdateLoadingScreen(); - -#if defined(MAP_LOADING_SLICING) - GetISystemScheduler()->SliceAndSleep(pFunc, line); -#endif - } -} - - -////////////////////////////////////////////////////////////////////////// -void CSystem::UpdateLoadingScreen() -{ - // Do not update the network thread from here - it will cause context corruption - use the NetworkStallTicker thread system - - if (GetCurrentThreadId() != gEnv->mMainThreadId) - { - return; - } - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMRENDERER_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(SystemRender_cpp) -#endif - -#if AZ_LOADSCREENCOMPONENT_ENABLED - EBUS_EVENT(LoadScreenBus, UpdateAndRender); -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED - - if (!m_bEditor && !IsQuitting()) - { - if (m_pProgressListener) - { - m_pProgressListener->OnLoadingProgress(0); - } - } -} - ////////////////////////////////////////////////////////////////////////// void CSystem::DisplayErrorMessage(const char* acMessage, diff --git a/Code/CryEngine/CrySystem/SystemScheduler.cpp b/Code/CryEngine/CrySystem/SystemScheduler.cpp deleted file mode 100644 index 5cee6d5529..0000000000 --- a/Code/CryEngine/CrySystem/SystemScheduler.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implementation of the CSystemScheduler class - - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "SystemScheduler.h" - -#include "MiniQueue.h" -#include "ClientHandler.h" -#include "ServerHandler.h" - -void CreateSystemScheduler(CSystem* pSystem) -{ - gEnv->pSystemScheduler = new CSystemScheduler(pSystem); -} - -CSystemScheduler::CSystemScheduler(CSystem* pSystem) - : m_pSystem(pSystem) - , m_lastSliceCheckTime(0.0f) - , m_sliceLoadingRef(0) -{ - int defaultSchedulingMode = 0; - if (gEnv->IsDedicated()) - { - defaultSchedulingMode = 2; - } - - m_svSchedulingMode = REGISTER_INT("sv_scheduling", defaultSchedulingMode, 0, "Scheduling mode\n" - " 0: Normal mode\n" - " 1: Client\n" - " 2: Server\n"); - - m_svSchedulingBucket = REGISTER_INT("sv_schedulingBucket", 0, 0, "Scheduling bucket\n"); - - m_svSchedulingAffinity = REGISTER_INT("sv_SchedulingAffinity", 0, 0, "Scheduling affinity\n"); - - m_svSchedulingClientTimeout = REGISTER_INT("sv_schedulingClientTimeout", 1000, 0, "Client wait server\n"); - m_svSchedulingServerTimeout = REGISTER_INT("sv_schedulingServerTimeout", 100, 0, "Server wait server\n"); - -#if defined(MAP_LOADING_SLICING) - m_svSliceLoadEnable = REGISTER_INT("sv_sliceLoadEnable", 1, 0, "Enable/disable slice loading logic\n"); - ; - m_svSliceLoadBudget = REGISTER_INT("sv_sliceLoadBudget", 10, 0, "Slice budget\n"); - ; - m_svSliceLoadLogging = REGISTER_INT("sv_sliceLoadLogging", 0, 0, "Enable/disable slice loading logging\n"); -#endif - - m_pLastSliceName = "INACTIVE"; - m_lastSliceLine = 0; -} - -CSystemScheduler::~CSystemScheduler(void) -{ -} - -void CSystemScheduler::SliceLoadingBegin() -{ - m_lastSliceCheckTime = gEnv->pTimer->GetAsyncTime(); - m_sliceLoadingRef++; - m_pLastSliceName = "START"; - m_lastSliceLine = 0; -} - -void CSystemScheduler::SliceLoadingEnd() -{ - m_sliceLoadingRef--; - m_pLastSliceName = "INACTIVE"; - m_lastSliceLine = 0; -} - -void CSystemScheduler::SliceAndSleep(const char* sliceName, int line) -{ -#if defined(MAP_LOADING_SLICING) - if (!gEnv->IsDedicated()) - { - return; - } - - if (!m_sliceLoadingRef) - { - return; - } - - if (!m_svSliceLoadEnable->GetIVal()) - { - return; - } - - SchedulingModeUpdate(); - - CTimeValue currTime = gEnv->pTimer->GetAsyncTime(); - - float sliceBudget = CLAMP(m_svSliceLoadBudget->GetFVal(), 0, 1000.0f / m_pSystem->GetDedicatedMaxRate()->GetFVal()); - bool doSleep = true; - if ((currTime - m_pSystem->GetLastTickTime()).GetMilliSeconds() < sliceBudget) - { - m_lastSliceCheckTime = currTime; - doSleep = false; - } - - if (doSleep) - { - if (m_svSliceLoadLogging->GetIVal()) - { - float diff = (currTime - m_lastSliceCheckTime).GetMilliSeconds(); - if (diff > sliceBudget) - { - CryLogAlways("[SliceAndSleep]: Interval between slice [%s:%i] and [%s:%i] was [%f] out of budget [%f]", m_pLastSliceName, m_lastSliceLine, sliceName, line, diff, sliceBudget); - } - } - - m_pSystem->SleepIfNeeded(); - } - - m_pLastSliceName = sliceName; - m_lastSliceLine = line; -#endif -} - -void CSystemScheduler::SchedulingSleepIfNeeded() -{ - if (!gEnv->IsDedicated()) - { - return; - } - - SchedulingModeUpdate(); - m_pSystem->SleepIfNeeded(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Scheduling mode routines -// -/////////////////////////////////////////////////////////////////////////////////////////////////// - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Scheduling mode update logic -// -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void CSystemScheduler::SchedulingModeUpdate() -{ - static std::unique_ptr m_client; - static std::unique_ptr m_server; - - if (int scheduling = m_svSchedulingMode->GetIVal()) - { - if (scheduling == 1) //client - { - if (!m_client.get()) - { - m_server.reset(); - m_client.reset(new ClientHandler(m_svSchedulingBucket->GetString(), m_svSchedulingAffinity->GetIVal(), m_svSchedulingClientTimeout->GetIVal())); - } - if (m_client->Sync()) - { - return; - } - } - else if (scheduling == 2) //server - { - if (!m_server.get()) - { - m_client.reset(); - m_server.reset(new ServerHandler(m_svSchedulingBucket->GetString(), m_svSchedulingAffinity->GetIVal(), m_svSchedulingServerTimeout->GetIVal())); - } - if (m_server->Sync()) - { - return; - } - } - } - else - { - m_client.reset(); - m_server.reset(); - } -} - -#endif // defined(MAP_LOADING_SLICING) - -extern "C" void SliceAndSleep(const char* pFunc, int line) -{ - if (GetISystemScheduler()) - { - GetISystemScheduler()->SliceAndSleep(pFunc, line); - } -} - diff --git a/Code/CryEngine/CrySystem/SystemScheduler.h b/Code/CryEngine/CrySystem/SystemScheduler.h deleted file mode 100644 index feb6e2850c..0000000000 --- a/Code/CryEngine/CrySystem/SystemScheduler.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H -#define CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H - -#pragma once - -#include "System.h" -#include - -class CSystemScheduler - : public ISystemScheduler -{ -public: - CSystemScheduler(CSystem* pSystem); - virtual ~CSystemScheduler(void); - - // ISystemScheduler - virtual void SliceAndSleep(const char* sliceName, int line); - virtual void SliceLoadingBegin(); - virtual void SliceLoadingEnd(); - - virtual void SchedulingSleepIfNeeded(void); - // ~ISystemScheduler - -protected: - void SchedulingModeUpdate(void); - -private: - CSystem* m_pSystem; - ICVar* m_svSchedulingAffinity; - ICVar* m_svSchedulingClientTimeout; - ICVar* m_svSchedulingServerTimeout; - ICVar* m_svSchedulingBucket; - ICVar* m_svSchedulingMode; - ICVar* m_svSliceLoadEnable; - ICVar* m_svSliceLoadBudget; - ICVar* m_svSliceLoadLogging; - - CTimeValue m_lastSliceCheckTime; - - int m_sliceLoadingRef; - - const char* m_pLastSliceName; - int m_lastSliceLine; -}; - -// Summary: -// Creates the system scheduler interface. -void CreateSystemScheduler(CSystem* pSystem); - -#endif // CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H diff --git a/Code/CryEngine/CrySystem/SystemThreading.cpp b/Code/CryEngine/CrySystem/SystemThreading.cpp deleted file mode 100644 index 9354e4e1c3..0000000000 --- a/Code/CryEngine/CrySystem/SystemThreading.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "ThreadConfigManager.h" -#include "IThreadManager.h" -#include -#include "CryUtils.h" - -#define INCLUDED_FROM_SYSTEM_THREADING_CPP - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define SYSTEMTHREADING_CPP_SECTION_1 1 -#define SYSTEMTHREADING_CPP_SECTION_2 2 -#define SYSTEMTHREADING_CPP_SECTION_3 3 -#endif - -#if defined(WIN32) || defined(WIN64) - #include "CryThreadUtil_win32_thread.h" -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(SystemThreading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - #include "CryThreadUtil_pthread.h" -#endif -#undef INCLUDED_FROM_SYSTEM_THREADING_CPP - -////////////////////////////////////////////////////////////////////////// -static void ApplyThreadConfig(CryThreadUtil::TThreadHandle pThreadHandle, const SThreadConfig& rThreadDesc) -{ - // Apply config - if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) - { - CryThreadUtil::CrySetThreadName(pThreadHandle, rThreadDesc.szThreadName); - } - if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) - { - CryThreadUtil::CrySetThreadAffinityMask(pThreadHandle, rThreadDesc.affinityFlag); - } - if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) - { - CryThreadUtil::CrySetThreadPriority(pThreadHandle, rThreadDesc.priority); - } - if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) - { - CryThreadUtil::CrySetThreadPriorityBoost(pThreadHandle, !rThreadDesc.bDisablePriorityBoost); - } - - CryComment(" Configured thread \"%s\" %s | AffinityMask: %u %s | Priority: %i %s | PriorityBoost: %s %s", - rThreadDesc.szThreadName, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) ? "" : "(ignored)", - rThreadDesc.affinityFlag, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) ? "" : "(ignored)", - rThreadDesc.priority, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) ? "" : "(ignored)", - !rThreadDesc.bDisablePriorityBoost ? "enabled" : "disabled", (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) ? "" : "(ignored)"); -} - -////////////////////////////////////////////////////////////////////////// -struct SThreadMetaData - : public CMultiThreadRefCount -{ - SThreadMetaData() - : m_pThreadTask(0) - , m_threadHandle(0) - , m_threadId(0) - , m_threadName("Cry_UnnamedThread") - , m_isRunning(false) - { - } - - IThread* m_pThreadTask; // Pointer to thread task to be executed - CThreadManager* m_pThreadMngr; // Pointer to thread manager - - CryThreadUtil::TThreadHandle m_threadHandle; // Thread handle - threadID m_threadId; // The active threadId, 0 = Invalid Id - - CryMutex m_threadExitMutex; // Mutex used to safeguard thread exit condition signaling - CryConditionVariable m_threadExitCondition; // Signaled when the thread is about to exit - - CryFixedStringT m_threadName; // Thread name - volatile bool m_isRunning; // Indicates the thread is not ready to exit yet -}; - -////////////////////////////////////////////////////////////////////////// -class CThreadManager - : public IThreadManager -{ -public: - // - virtual ~CThreadManager() - { - } - - virtual bool SpawnThread(IThread* pThread, const char* sThreadName, ...) override; - virtual bool JoinThread(IThread* pThreadTask, EJoinMode eJoinMode) override; - - virtual bool RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...) override; - virtual bool UnRegisterThirdPartyThread(const char* sThreadName, ...) override; - - virtual const char* GetThreadName(threadID nThreadId) override; - virtual threadID GetThreadId(const char* sThreadName, ...) override; - - virtual void ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData = 0) override; - - virtual void EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId = 0) override; - virtual void EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity) override; - - virtual uint GetFloatingPointExceptionMask() override; - virtual void SetFloatingPointExceptionMask(uint nMask) override; - - IThreadConfigManager* GetThreadConfigManager() override - { - return &m_threadConfigManager; - } - // -private: -#if defined(WIN32) || defined(WIN64) - static unsigned __stdcall RunThread(void* thisPtr); -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(SystemThreading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - static void* RunThread(void* thisPtr); -#endif - -private: - bool UnregisterThread(IThread* pThreadTask); - - bool SpawnThreadImpl(IThread* pThread, const char* sThreadName); - - bool RegisterThirdPartyThreadImpl(CryThreadUtil::TThreadHandle pThreadHandle, const char* sThreadName); - bool UnRegisterThirdPartyThreadImpl(const char* sThreadName); - - threadID GetThreadIdImpl(const char* sThreadName); - -private: - // Note: Guard SThreadMetaData with a _smart_ptr and lock to ensure that a thread waiting to be signaled by another still - // has access to valid SThreadMetaData even though the other thread terminated and as a result unregistered itself from the CThreadManager. - // An example would be the join method. Where one thread waits on a signal from an other thread to terminate and release its SThreadMetaData, - // sharing the same SThreadMetaData condition variable. - typedef std::map > SpawnedThreadMap; - typedef std::map >::iterator SpawnedThreadMapIter; - typedef std::map >::const_iterator SpawnedThreadMapConstIter; - typedef std::pair > ThreadMapPair; - - typedef std::map, _smart_ptr > SpawnedThirdPartyThreadMap; - typedef std::map, _smart_ptr >::iterator SpawnedThirdPartyThreadMapIter; - typedef std::map, _smart_ptr >::const_iterator SpawnedThirdPartyThreadMapConstIter; - typedef std::pair, _smart_ptr > ThirdPartyThreadMapPair; - - CryCriticalSection m_spawnedThreadsLock; // Use lock for the rare occasion a thread is created/destroyed - SpawnedThreadMap m_spawnedThreads; // Holds information of all spawned threads (through this system) - - CryCriticalSection m_spawnedThirdPartyThreadsLock; // Use lock for the rare occasion a thread is created/destroyed - SpawnedThirdPartyThreadMap m_spawnedThirdPartyThread; // Holds information of all registered 3rd party threads (through this system) - - CThreadConfigManager m_threadConfigManager; -}; - -////////////////////////////////////////////////////////////////////////// -#if defined(WIN32) || defined(WIN64) -unsigned __stdcall CThreadManager::RunThread(void* thisPtr) -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE(SystemThreading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -void* CThreadManager::RunThread(void* thisPtr) -#endif -{ - // Check that we are not spawning a thread before gEnv->pSystem has been set - // Otherwise we cannot enable floating point exceptions - if (!gEnv || !gEnv->pSystem) - { - CryFatalError("[Error]: CThreadManager::RunThread requires gEnv->pSystem to be initialized."); - } - - IThreadConfigManager* pThreadConfigMngr = gEnv->pThreadManager->GetThreadConfigManager(); - - SThreadMetaData* pThreadData = reinterpret_cast(thisPtr); - pThreadData->m_threadId = CryThreadUtil::CryGetCurrentThreadId(); - - // Apply config - const SThreadConfig* pThreadConfig = pThreadConfigMngr->GetThreadConfig(pThreadData->m_threadName.c_str()); - ApplyThreadConfig(pThreadData->m_threadHandle, *pThreadConfig); - - // Config not found, append thread name with no config tag - if (pThreadConfig == pThreadConfigMngr->GetDefaultThreadConfig()) - { - CryFixedStringT tmpString(pThreadData->m_threadName); - const char* cNoConfigAppendix = "(NoCfgFound)"; - int nNumCharsToReplace = strlen(cNoConfigAppendix); - - // Replace thread name ending - if (pThreadData->m_threadName.size() > THREAD_NAME_LENGTH_MAX - nNumCharsToReplace) - { - tmpString.replace(THREAD_NAME_LENGTH_MAX - nNumCharsToReplace, nNumCharsToReplace, cNoConfigAppendix, nNumCharsToReplace); - } - else - { - tmpString.append(cNoConfigAppendix); - } - - // Print to log - if (pThreadConfigMngr->ConfigLoaded()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " No Thread config found for thread %s using ... default config.", pThreadData->m_threadName.c_str()); - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Thread config not loaded yet. Hence no thread config was found for thread %s ... using default config.", pThreadData->m_threadName.c_str()); - } - - // Rename Thread - CryThreadUtil::CrySetThreadName(pThreadData->m_threadHandle, tmpString.c_str()); - } - - // Enable FPEs - gEnv->pThreadManager->EnableFloatExceptions((EFPE_Severity)g_cvars.sys_float_exceptions); - - // Execute thread code - pThreadData->m_pThreadTask->ThreadEntry(); - - // Disable FPEs - gEnv->pThreadManager->EnableFloatExceptions(eFPE_None); - - // Signal imminent thread end - pThreadData->m_threadExitMutex.Lock(); - pThreadData->m_isRunning = false; - pThreadData->m_threadExitCondition.Notify(); - pThreadData->m_threadExitMutex.Unlock(); - - // Unregister thread - // Note: Unregister after m_threadExitCondition.Notify() to ensure pThreadData is still valid - pThreadData->m_pThreadMngr->UnregisterThread(pThreadData->m_pThreadTask); - - CryThreadUtil::CryThreadExitCall(); - - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::JoinThread(IThread* pThreadTask, EJoinMode eJoinMode) -{ - // Get thread object - _smart_ptr pThreadImpl = 0; - { - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask); - if (res == m_spawnedThreads.end()) - { - // Thread has already finished and unregistered itself. - // As it is complete we cannot wait for it. - // Hence return true. - return true; - } - - pThreadImpl = res->second; // Keep object alive - } - - // On try join, exit if the thread is not in a state to exit - if (eJoinMode == eJM_TryJoin && pThreadImpl->m_isRunning) - { - return false; - } - - // Wait for completion of the target thread exit condition - pThreadImpl->m_threadExitMutex.Lock(); - while (pThreadImpl->m_isRunning) - { - pThreadImpl->m_threadExitCondition.Wait(pThreadImpl->m_threadExitMutex); - } - pThreadImpl->m_threadExitMutex.Unlock(); - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::UnregisterThread(IThread* pThreadTask) -{ - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask); - if (res == m_spawnedThreads.end()) - { - // Duplicate thread deletion - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": UnregisterThread: Unable to unregister thread. Thread name could not be found. Double deletion? IThread pointer: %p", pThreadTask); - return false; - } - - m_spawnedThreads.erase(res); - return true; -} - -////////////////////////////////////////////////////////////////////////// -const char* CThreadManager::GetThreadName(threadID nThreadId) -{ - // Loop over internally spawned threads - { - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapConstIter iter = m_spawnedThreads.begin(); - SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadId == nThreadId) - { - return iter->second->m_threadName.c_str(); - } - } - } - - // Loop over third party threads - { - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin(); - SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadId == nThreadId) - { - return iter->second->m_threadName.c_str(); - } - } - } - - return ""; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadManager::ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData) -{ - threadID nCurThreadId = CryThreadUtil::CryGetCurrentThreadId(); - - // Loop over internally spawned threads - { - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapConstIter iter = m_spawnedThreads.begin(); - SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadId != nCurThreadId) - { - fpThreadModiFunction(iter->second->m_threadId, pFuncData); - } - } - } - - // Loop over third party threads - { - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin(); - SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadId != nCurThreadId) - { - fpThreadModiFunction(iter->second->m_threadId, pFuncData); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::SpawnThread(IThread* pThreadTask, const char* sThreadName, ...) -{ - va_list args; - va_start(args, sThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1 || cNumCharsNeeded < 0) - { - strThreadName[THREAD_NAME_LENGTH_MAX - 1] = '\0'; // The WinApi only null terminates if strLen < bufSize - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Spawn thread - bool ret = SpawnThreadImpl(pThreadTask, strThreadName); - - if (!ret) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": CSystem::SpawnThread error spawning thread: \"%s\" ", strThreadName); - } - - va_end(args); - return ret; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::SpawnThreadImpl(IThread* pThreadTask, const char* sThreadName) -{ - if (pThreadTask == NULL) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, ": SpawnThread '%s' ThreadTask is NULL : ignoring", sThreadName); - return false; - } - - // Init thread meta data - SThreadMetaData* pThreadMetaData = new SThreadMetaData(); - pThreadMetaData->m_pThreadTask = pThreadTask; - pThreadMetaData->m_pThreadMngr = this; - pThreadMetaData->m_threadName = sThreadName; - - // Add thread to map - { - AUTO_LOCK(m_spawnedThreadsLock); - SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask); - if (res != m_spawnedThreads.end()) - { - // Thread with same name already spawned - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": SpawnThread: Thread \"%s\" already exists.", sThreadName); - delete pThreadMetaData; - return false; - } - - // Insert thread data - m_spawnedThreads.insert(ThreadMapPair(pThreadTask, pThreadMetaData)); - } - - // Load config if we can and if no config has been defined to be loaded - const SThreadConfig* pThreadConfig = gEnv->pThreadManager->GetThreadConfigManager()->GetThreadConfig(sThreadName); - - // Create thread description - CryThreadUtil::SThreadCreationDesc desc = {sThreadName, RunThread, pThreadMetaData, pThreadConfig->paramActivityFlag & SThreadConfig::eThreadParamFlag_StackSize ? pThreadConfig->stackSizeBytes : 0}; - - // Spawn new thread - pThreadMetaData->m_isRunning = CryThreadUtil::CryCreateThread(&(pThreadMetaData->m_threadHandle), desc); - - // Validate thread creation - if (!pThreadMetaData->m_isRunning) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": SpawnThread: Could not spawn thread \"%s\" .", sThreadName); - - // Remove thread from map (also releases SThreadMetaData _smart_ptr) - m_spawnedThreads.erase(m_spawnedThreads.find(pThreadTask)); - return false; - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...) -{ - if (!pThreadHandle) - { - pThreadHandle = reinterpret_cast(CryThreadUtil::CryGetCurrentThreadHandle()); - } - - va_list args; - va_start(args, sThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Register 3rd party thread - bool ret = RegisterThirdPartyThreadImpl(reinterpret_cast(pThreadHandle), strThreadName); - - va_end(args); - return ret; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::RegisterThirdPartyThreadImpl(CryThreadUtil::TThreadHandle threadHandle, const char* sThreadName) -{ - if (strcmp(sThreadName, "") == 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": CThreadManager::RegisterThirdPartyThread error registering third party thread. No name provided."); - return false; - } - // Init thread meta data - SThreadMetaData* pThreadMetaData = new SThreadMetaData(); - pThreadMetaData->m_pThreadTask = 0; - pThreadMetaData->m_pThreadMngr = this; - pThreadMetaData->m_threadName = sThreadName; - pThreadMetaData->m_threadHandle = CryThreadUtil::CryDuplicateThreadHandle(threadHandle); // Ensure that we are not storing a pseudo handle - pThreadMetaData->m_threadId = CryThreadUtil::CryGetThreadId(pThreadMetaData->m_threadHandle); - - { - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - // Check for duplicate - SpawnedThirdPartyThreadMapConstIter res = m_spawnedThirdPartyThread.find(sThreadName); - if (res != m_spawnedThirdPartyThread.end()) - { - CryFatalError("CThreadManager::RegisterThirdPartyThread - Unable to register thread \"%s\"" - "because another third party thread with the same name \"%s\" has already been registered with ThreadHandle: %p", - sThreadName, res->second->m_threadName.c_str(), reinterpret_cast(threadHandle)); - - delete pThreadMetaData; - return false; - } - - // Insert thread data - m_spawnedThirdPartyThread.insert(ThirdPartyThreadMapPair(pThreadMetaData->m_threadName.c_str(), pThreadMetaData)); - } - - // Get thread config - const SThreadConfig* pThreadConfig = gEnv->pThreadManager->GetThreadConfigManager()->GetThreadConfig(sThreadName); - - // Apply config (if not default config) - if (strcmp(pThreadConfig->szThreadName, sThreadName) == 0) - { - ApplyThreadConfig(threadHandle, *pThreadConfig); - } - - // Update FP exception mask for 3rd party thread - if (pThreadMetaData->m_threadId) - { - CryThreadUtil::EnableFloatExceptions(pThreadMetaData->m_threadId, (EFPE_Severity)g_cvars.sys_float_exceptions); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::UnRegisterThirdPartyThread(const char* sThreadName, ...) -{ - va_list args; - va_start(args, sThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Unregister 3rd party thread - bool ret = UnRegisterThirdPartyThreadImpl(strThreadName); - - va_end(args); - return ret; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::UnRegisterThirdPartyThreadImpl(const char* sThreadName) -{ - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - SpawnedThirdPartyThreadMapIter res = m_spawnedThirdPartyThread.find(sThreadName); - if (res == m_spawnedThirdPartyThread.end()) - { - // Duplicate thread deletion - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": UnRegisterThirdPartyThread: Unable to unregister thread. Thread name \"%s\" could not be found. Double deletion? ", sThreadName); - return false; - } - - // Close thread handle - CryThreadUtil::CryCloseThreadHandle(res->second->m_threadHandle); - - // Delete reference from container - m_spawnedThirdPartyThread.erase(res); - return true; -} - -////////////////////////////////////////////////////////////////////////// -threadID CThreadManager::GetThreadId(const char* sThreadName, ...) -{ - va_list args; - va_start(args, sThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Get thread name - threadID ret = GetThreadIdImpl(strThreadName); - - va_end(args); - return ret; -} - -////////////////////////////////////////////////////////////////////////// -threadID CThreadManager::GetThreadIdImpl(const char* sThreadName) -{ - // Loop over internally spawned threads - { - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapConstIter iter = m_spawnedThreads.begin(); - SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadName.compare(sThreadName) == 0) - { - return iter->second->m_threadId; - } - } - } - - // Loop over third party threads - { - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin(); - SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadName.compare(sThreadName) == 0) - { - return iter->second->m_threadId; - } - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -static void EnableFPExceptionsForThread(threadID nThreadId, void* pData) -{ - EFPE_Severity eFPESeverity = *(EFPE_Severity*)pData; - CryThreadUtil::EnableFloatExceptions(nThreadId, eFPESeverity); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadManager::EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId /*=0*/) -{ - CryThreadUtil::EnableFloatExceptions(nThreadId, eFPESeverity); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadManager::EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity) -{ - ForEachOtherThread(EnableFPExceptionsForThread, &eFPESeverity); -} - -////////////////////////////////////////////////////////////////////////// -uint CThreadManager::GetFloatingPointExceptionMask() -{ - return CryThreadUtil::GetFloatingPointExceptionMask(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadManager::SetFloatingPointExceptionMask(uint nMask) -{ - CryThreadUtil::SetFloatingPointExceptionMask(nMask); -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::InitThreadSystem() -{ - m_pThreadManager = new CThreadManager(); - m_env.pThreadManager = m_pThreadManager; -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::ShutDownThreadSystem() -{ - SAFE_DELETE(m_pThreadManager); -} diff --git a/Code/CryEngine/CrySystem/SystemWin32.cpp b/Code/CryEngine/CrySystem/SystemWin32.cpp index c694979a14..72c43bceed 100644 --- a/Code/CryEngine/CrySystem/SystemWin32.cpp +++ b/Code/CryEngine/CrySystem/SystemWin32.cpp @@ -46,8 +46,6 @@ #include #endif -#include "IDebugCallStack.h" - #if defined(APPLE) || defined(LINUX) #include #endif @@ -752,13 +750,6 @@ void CSystem::FatalError(const char* format, ...) } // Dump callstack. -#endif -#if defined (WIN32) - //Triggers a fatal error, so the DebugCallstack can create the error.log and terminate the application - IDebugCallStack::instance()->FatalError(szBuffer); -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMWIN32_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(SystemWin32_cpp) #endif CryDebugBreak(); @@ -800,8 +791,6 @@ void CSystem::ReportBug([[maybe_unused]] const char* format, ...) va_start(ArgList, format); azvsnprintf(szBuffer + strlen(sPrefix), MAX_WARNING_LENGTH - strlen(sPrefix), format, ArgList); va_end(ArgList); - - IDebugCallStack::instance()->ReportBug(szBuffer); #endif } @@ -910,10 +899,6 @@ void CSystem::LogSystemInfo() OSVERSIONINFO OSVerInfo; OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - // log Windows type - Win32SysInspect::GetOS(m_env.pi.winVer, m_env.pi.win64Bit, szBuffer, sizeof(szBuffer)); - CryLogAlways(szBuffer); - // log system language GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, szLanguageBuffer, sizeof(szLanguageBuffer)); azsprintf(szBuffer, "System language: %s", szLanguageBuffer); diff --git a/Code/CryEngine/CrySystem/ThreadConfigManager.cpp b/Code/CryEngine/CrySystem/ThreadConfigManager.cpp deleted file mode 100644 index b582aac578..0000000000 --- a/Code/CryEngine/CrySystem/ThreadConfigManager.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ThreadConfigManager.h" -#include "IConsole.h" -#include "System.h" -#include -#include -#include "CryUtils.h" -namespace -{ - const char* sCurThreadConfigFilename = ""; - const uint32 sPlausibleStackSizeLimitKB = (1024 * 100); // 100mb -} - -////////////////////////////////////////////////////////////////////////// -CThreadConfigManager::CThreadConfigManager() -{ - m_defaultConfig.szThreadName = "CryThread_Unnamed"; - m_defaultConfig.stackSizeBytes = 0; - m_defaultConfig.affinityFlag = -1; - m_defaultConfig.priority = THREAD_PRIORITY_NORMAL; - m_defaultConfig.bDisablePriorityBoost = false; - m_defaultConfig.paramActivityFlag = (SThreadConfig::TThreadParamFlag)~0; -} - -////////////////////////////////////////////////////////////////////////// -const SThreadConfig* CThreadConfigManager::GetThreadConfig(const char* szThreadName, ...) -{ - va_list args; - va_start(args, szThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), szThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Get Thread Config - const SThreadConfig* retThreasdConfig = GetThreadConfigImpl(strThreadName); - - va_end(args); - return retThreasdConfig; -} - -////////////////////////////////////////////////////////////////////////// -const SThreadConfig* CThreadConfigManager::GetThreadConfigImpl(const char* szThreadName) -{ - // Get thread config for platform - ThreadConfigMapConstIter threatRet = m_threadConfig.find(CryFixedStringT(szThreadName)); - if (threatRet == m_threadConfig.end()) - { - // Search in wildcard setups - ThreadConfigMapConstIter wildCardIter = m_wildcardThreadConfig.begin(); - ThreadConfigMapConstIter wildCardIterEnd = m_wildcardThreadConfig.end(); - for (; wildCardIter != wildCardIterEnd; ++wildCardIter) - { - if (CryStringUtils::MatchWildcard(szThreadName, wildCardIter->second.szThreadName)) - { - // Store new thread config - SThreadConfig threadConfig = wildCardIter->second; - std::pair res; - res = m_threadConfig.insert(ThreadConfigMapPair(CryFixedStringT(szThreadName), threadConfig)); - - // Store name (ref to key) - SThreadConfig& rMapThreadConfig = res.first->second; - rMapThreadConfig.szThreadName = res.first->first.c_str(); - - // Return new thread config - return &res.first->second; - } - } - - // Failure case, no match found - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": Unable to find config for thread:%s", szThreadName); - return &m_defaultConfig; - } - - // Return thread config - return &threatRet->second; -} - -////////////////////////////////////////////////////////////////////////// -const SThreadConfig* CThreadConfigManager::GetDefaultThreadConfig() const -{ - return &m_defaultConfig; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadConfigManager::LoadConfig(const char* pcPath) -{ - // Adjust filename for OnDisk or in .pak file loading - char szFullPathBuf[AZ::IO::IArchive::MaxPath]; - gEnv->pCryPak->AdjustFileName(pcPath, szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), 0); - - // Open file - XmlNodeRef xmlRoot = GetISystem()->LoadXmlFromFile(szFullPathBuf); - if (!xmlRoot) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": File \"%s\" not found!", pcPath); - return false; - } - - // Load config for active platform - sCurThreadConfigFilename = pcPath; - const char* strPlatformId = IdentifyPlatform(); - CryFixedStringT<32> tmpPlatformStr; - bool retValue = false; - - // Try load common platform settings - tmpPlatformStr.Format("%s_Common", strPlatformId); - LoadPlatformConfig(xmlRoot, tmpPlatformStr.c_str()); - -#if defined(CRY_PLATFORM_DESKTOP) - // Handle PC specifically as we do not know the core setup of the executing machine. - // Try and find the next power of 2 core setup. Otherwise fallback to a lower power of 2 core setup spec - - // Try and load next pow of 2 setup for active pc core configuration - const unsigned int numCPUs = ((CSystem*)GetISystem())->GetCPUFeatures()->GetLogicalCPUCount(); - uint32 i = numCPUs; - for (; i > 0; --i) - { - tmpPlatformStr.Format("%s_%i", strPlatformId, i); - retValue = LoadPlatformConfig(xmlRoot, tmpPlatformStr.c_str()); - if (retValue) - { - break; - } - } - - if (retValue && i != numCPUs) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": (%s: %u core) Unable to find platform config \"%s\". Next valid config found was %s_%u.", - strPlatformId, numCPUs, tmpPlatformStr.c_str(), strPlatformId, i); - } - -#else - tmpPlatformStr.Format("%s", strPlatformId); - retValue = LoadPlatformConfig(xmlRoot, strPlatformId); -#endif - - // Print out info - if (retValue) - { - CryLogAlways(": Thread profile loaded: \"%s\" (%s) ", tmpPlatformStr.c_str(), pcPath); - } - else - { - // Could not find any matching platform - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": Active platform identifier string \"%s\" not found in config \"%s\".", strPlatformId, sCurThreadConfigFilename); - } - - sCurThreadConfigFilename = ""; - return retValue; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadConfigManager::ConfigLoaded() const -{ - return !m_threadConfig.empty(); -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadConfigManager::LoadPlatformConfig(const XmlNodeRef& rXmlRoot, const char* sPlatformId) -{ - // Validate node - if (!rXmlRoot->isTag("ThreadConfig")) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": Unable to find root xml node \"ThreadConfig\""); - return false; - } - - // Find active platform - const uint32 numPlatforms = rXmlRoot->getChildCount(); - for (uint32 i = 0; i < numPlatforms; ++i) - { - const XmlNodeRef xmlPlatformNode = rXmlRoot->getChild(i); - - // Is platform node - if (!xmlPlatformNode->isTag("Platform")) - { - continue; - } - - // Is has Name attribute - if (!xmlPlatformNode->haveAttr("Name")) - { - continue; - } - - // Is platform of interest - const char* platformName = xmlPlatformNode->getAttr("Name"); - if (_stricmp(sPlatformId, platformName) == 0) - { - // Load platform - LoadThreadDefaultConfig(xmlPlatformNode); - LoadPlatformThreadConfigs(xmlPlatformNode); - return true; - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadPlatformThreadConfigs(const XmlNodeRef& rXmlPlatformRef) -{ - // Get thread configurations for active platform - const uint32 numThreads = rXmlPlatformRef->getChildCount(); - for (uint32 j = 0; j < numThreads; ++j) - { - const XmlNodeRef xmlThreadNode = rXmlPlatformRef->getChild(j); - - if (!xmlThreadNode->isTag("Thread")) - { - continue; - } - - // Ensure thread config has name - if (!xmlThreadNode->haveAttr("Name")) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Thread node without \"name\" attribute encountered."); - continue; - } - - // Load thread config - SThreadConfig loadedThreadConfig = SThreadConfig(m_defaultConfig); - LoadThreadConfig(xmlThreadNode, loadedThreadConfig); - - // Get thread name and check if it contains wildcard characters - const char* szThreadName = xmlThreadNode->getAttr("Name"); - bool bWildCard = strchr(szThreadName, '*') ? true : false; - ThreadConfigMap& threadConfig = bWildCard ? m_wildcardThreadConfig : m_threadConfig; - - // Check for duplicate and override it with new config if found - if (threadConfig.find(szThreadName) != threadConfig.end()) - { - CryLogAlways(": [XML Parsing] Thread with name \"%s\" already loaded. Overriding with new configuration", szThreadName); - threadConfig[szThreadName] = loadedThreadConfig; - continue; - } - - // Store new thread config - std::pair res; - res = threadConfig.insert(ThreadConfigMapPair(CryFixedStringT(szThreadName), loadedThreadConfig)); - - // Store name (ref to key) - SThreadConfig& rMapThreadConfig = res.first->second; - rMapThreadConfig.szThreadName = res.first->first.c_str(); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadConfigManager::LoadThreadDefaultConfig(const XmlNodeRef& rXmlPlatformRef) -{ - // Find default thread config node - const uint32 numNodes = rXmlPlatformRef->getChildCount(); - for (uint32 j = 0; j < numNodes; ++j) - { - const XmlNodeRef xmlNode = rXmlPlatformRef->getChild(j); - - // Load default config - if (xmlNode->isTag("ThreadDefault")) - { - LoadThreadConfig(xmlNode, m_defaultConfig); - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadAffinity(const XmlNodeRef& rXmlThreadRef, uint32& rAffinity, SThreadConfig::TThreadParamFlag& rParamActivityFlag) -{ - const char* szValidCharacters = "-,0123456789"; - uint32 affinity = 0; - - // Validate node - if (!rXmlThreadRef->haveAttr("Affinity")) - { - return; - } - - // Validate token - CryFixedStringT<32> affinityRawStr(rXmlThreadRef->getAttr("Affinity")); - if (affinityRawStr.empty()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Empty attribute \"Affinity\" encountered"); - return; - } - - if (affinityRawStr.compareNoCase("ignore") == 0) - { - // Param is inactive, clear bit - rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_Affinity; - return; - } - - CryFixedStringT<32>::size_type nPos = affinityRawStr.find_first_not_of(" -,0123456789"); - if (nPos != CryFixedStringT<32>::npos) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - ": [XML Parsing] Invalid character \"%c\" encountered in \"Affinity\" attribute. Valid characters:\"%s\" Offending token:\"%s\"", affinityRawStr.at(nPos), - szValidCharacters, affinityRawStr.c_str()); - return; - } - - // Tokenize comma separated string - int pos = 0; - CryFixedStringT<32> affnityTokStr = affinityRawStr.Tokenize(",", pos); - while (!affnityTokStr.empty()) - { - affnityTokStr.Trim(); - - long affinityId = strtol(affnityTokStr.c_str(), NULL, 10); - if (affinityId == LONG_MAX || affinityId == LONG_MIN) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Unknown value \"%s\" encountered for attribute \"Affinity\"", affnityTokStr.c_str()); - return; - } - - // Allow scheduler to pick thread - if (affinityId == -1) - { - affinity = ~0; - break; - } - - // Set affinity bit - affinity |= BIT(affinityId); - - // Move to next token - affnityTokStr = affinityRawStr.Tokenize(",", pos); - } - - // Set affinity reference - rAffinity = affinity; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadPriority(const XmlNodeRef& rXmlThreadRef, int32& rPriority, SThreadConfig::TThreadParamFlag& rParamActivityFlag) -{ - const char* szValidCharacters = "-,0123456789"; - - // Validate node - if (!rXmlThreadRef->haveAttr("Priority")) - { - return; - } - - // Validate token - CryFixedStringT<32> threadPrioStr(rXmlThreadRef->getAttr("Priority")); - threadPrioStr.Trim(); - if (threadPrioStr.empty()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Empty attribute \"Priority\" encountered"); - return; - } - - if (threadPrioStr.compareNoCase("ignore") == 0) - { - // Param is inactive, clear bit - rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_Priority; - return; - } - - // Test for character string (no numbers allowed) - if (threadPrioStr.find_first_of(szValidCharacters) == CryFixedStringT<32>::npos) - { - threadPrioStr.MakeLower(); - - // Set priority - if (threadPrioStr.compare("below_normal") == 0) - { - rPriority = THREAD_PRIORITY_BELOW_NORMAL; - } - else if (threadPrioStr.compare("normal") == 0) - { - rPriority = THREAD_PRIORITY_NORMAL; - } - else if (threadPrioStr.compare("above_normal") == 0) - { - rPriority = THREAD_PRIORITY_ABOVE_NORMAL; - } - else if (threadPrioStr.compare("idle") == 0) - { - rPriority = THREAD_PRIORITY_IDLE; - } - else if (threadPrioStr.compare("lowest") == 0) - { - rPriority = THREAD_PRIORITY_LOWEST; - } - else if (threadPrioStr.compare("highest") == 0) - { - rPriority = THREAD_PRIORITY_HIGHEST; - } - else if (threadPrioStr.compare("time_critical") == 0) - { - rPriority = THREAD_PRIORITY_TIME_CRITICAL; - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Platform unsupported value \"%s\" encountered for attribute \"Priority\"", threadPrioStr.c_str()); - return; - } - } - // Test for number string (no alphabetical characters allowed) - else if (threadPrioStr.find_first_not_of(szValidCharacters) == CryFixedStringT<32>::npos) - { - long numValue = strtol(threadPrioStr.c_str(), NULL, 10); - if (numValue == LONG_MAX || numValue == LONG_MIN) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Unsupported number type \"%s\" for for attribute \"Priority\"", threadPrioStr.c_str()); - return; - } - - // Set priority - rPriority = numValue; - } - else - { - // String contains characters and numbers - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Unsupported type \"%s\" encountered for attribute \"Priority\". Token containers numbers and characters", threadPrioStr.c_str()); - return; - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadDisablePriorityBoost(const XmlNodeRef& rXmlThreadRef, bool& rPriorityBoost, SThreadConfig::TThreadParamFlag& rParamActivityFlag) -{ - // Validate node - if (!rXmlThreadRef->haveAttr("DisablePriorityBoost")) - { - return; - } - - // Extract bool info - CryFixedStringT<16> sAttribToken(rXmlThreadRef->getAttr("DisablePriorityBoost")); - sAttribToken.Trim(); - sAttribToken.MakeLower(); - - if (sAttribToken.compare("ignore") == 0) - { - // Param is inactive, clear bit - rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_PriorityBoost; - return; - } - else if (sAttribToken.compare("true") == 0 || sAttribToken.compare("1") == 0) - { - rPriorityBoost = true; - } - else if (sAttribToken.compare("false") == 0 || sAttribToken.compare("0") == 0) - { - rPriorityBoost = false; - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Unsupported bool type \"%s\" encountered for attribute \"DisablePriorityBoost\"", - rXmlThreadRef->getAttr("DisablePriorityBoost")); - return; - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadStackSize(const XmlNodeRef& rXmlThreadRef, uint32& rStackSize, SThreadConfig::TThreadParamFlag& rParamActivityFlag) -{ - const char* sValidCharacters = "0123456789"; - - if (rXmlThreadRef->haveAttr("StackSizeKB")) - { - // Read stack size - CryFixedStringT<32> stackSize(rXmlThreadRef->getAttr("StackSizeKB")); - - // Validate stack size - if (stackSize.empty()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Empty attribute \"StackSize\" encountered"); - return; - } - else if (stackSize.compareNoCase("ignore") == 0) - { - // Param is inactive, clear bit - rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_StackSize; - return; - } - else if (stackSize.find_first_not_of(sValidCharacters) == CryFixedStringT<32>::npos) - { - // Convert string to long - long stackSizeVal = strtol(stackSize.c_str(), NULL, 10); - if (stackSizeVal == LONG_MAX || stackSizeVal == LONG_MIN) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Invalid number for \"StackSize\" encountered. \"%s\"", stackSize.c_str()); - return; - } - else if (stackSizeVal <= 0 || stackSizeVal > sPlausibleStackSizeLimitKB) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] \"StackSize\" value not plausible \"%" PRId64 "KB\"", (int64)stackSizeVal); - return; - } - - // Set stack size - rStackSize = stackSizeVal * 1024; // Convert to bytes - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadThreadConfig(const XmlNodeRef& rXmlThreadRef, SThreadConfig& rThreadConfig) -{ - LoadAffinity(rXmlThreadRef, rThreadConfig.affinityFlag, rThreadConfig.paramActivityFlag); - LoadPriority(rXmlThreadRef, rThreadConfig.priority, rThreadConfig.paramActivityFlag); - LoadDisablePriorityBoost(rXmlThreadRef, rThreadConfig.bDisablePriorityBoost, rThreadConfig.paramActivityFlag); - LoadStackSize(rXmlThreadRef, rThreadConfig.stackSizeBytes, rThreadConfig.paramActivityFlag); -} - -////////////////////////////////////////////////////////////////////////// -const char* CThreadConfigManager::IdentifyPlatform() -{ -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ThreadConfigManager_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(ANDROID) - return "android"; -#elif defined(LINUX) - return "linux"; -#elif defined(APPLE) - return "mac"; -#elif defined(WIN32) || defined(WIN64) - return "pc"; -#else -#error "Undefined platform" -#endif -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::DumpThreadConfigurationsToLog() -{ -#if !defined(RELEASE) - - // Print header - CryLogAlways("== Thread Startup Config List (\"%s\") ==", IdentifyPlatform()); - - // Print loaded default config - CryLogAlways(" (Default) 1. \"%s\" (StackSize:%uKB | Affinity:%u | Priority:%i | PriorityBoost:\"%s\")", m_defaultConfig.szThreadName, m_defaultConfig.stackSizeBytes / 1024, - m_defaultConfig.affinityFlag, m_defaultConfig.priority, m_defaultConfig.bDisablePriorityBoost ? "disabled" : "enabled"); - - // Print loaded thread configs - int listItemCounter = 1; - ThreadConfigMapConstIter iter = m_threadConfig.begin(); - ThreadConfigMapConstIter iterEnd = m_threadConfig.end(); - for (; iter != iterEnd; ++iter) - { - const SThreadConfig& threadConfig = iter->second; - CryLogAlways("%3d.\"%s\" %s (StackSize:%uKB %s | Affinity:%u %s | Priority:%i %s | PriorityBoost:\"%s\" %s)", ++listItemCounter, - threadConfig.szThreadName, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) ? "" : "(ignored)", - threadConfig.stackSizeBytes / 1024u, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_StackSize) ? "" : "(ignored)", - threadConfig.affinityFlag, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) ? "" : "(ignored)", - threadConfig.priority, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) ? "" : "(ignored)", - !threadConfig.bDisablePriorityBoost ? "enabled" : "disabled", (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) ? "" : "(ignored)"); - } -#endif -} diff --git a/Code/CryEngine/CrySystem/ThreadConfigManager.h b/Code/CryEngine/CrySystem/ThreadConfigManager.h deleted file mode 100644 index ef0c9dca3d..0000000000 --- a/Code/CryEngine/CrySystem/ThreadConfigManager.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include "IThreadConfigManager.h" - -/* -ThreadConfigManager: -Loads a thread configuration from an xml file and stores them. - -== XML File Layout and Rules: === - -= Platform names = -(case insensitive) -"ANDROID" -"PC" -"MAC" -etc. - -= Basic Layout = - - - - - -... - - - -... - - - -= Parser Order for Platform = -1. PlatformName_Common (valid for all potential platform configurations. Can be overridden by concert platform configuration) -2. PlatformName or PlatformName_X (for platforms with unknown CPU count where X is the number of potential cores. The equal or next lower matching configuration for the identified core count at runtime will be taken) - -Note: Overriding of thread configuration by later parsed configuration allowed. - -= and XML attributes = - -!!! -Note: Use "ignore" as value if you do not want the thread system to set the value specifically! - If a value is not defines the value of the parameter will be used. - This is useful when dealing with 3rdParty threads where you are not in control of the parameter setup. -!!! - -Name: - "x" (string) : Name of thread - "x*y" (string) : Name of thread with wildcard character - -Affinity: - "-1" : Put SW thread affinity in the hands of the scheduler - (default) - - "x" : Run thread on specified core - "x, y, ..." : Run thread on specified cores - -Priority: - "idle" : Hint to CryEngine to run thread with pre-set priority - "below_normal" : Hint to CryEngine to run thread with pre-set priority - "normal" : Hint to CryEngine to run thread with pre-set priority - (default) - - "above_normal" : Hint to CryEngine to run thread with pre-set priority - "highest" : Hint to CryEngine to run thread with pre-set priority - "time_critical" : Hint to CryEngine to run thread with pre-set priority - "x" (number) : User defined thread priority number - -StackSizeKB: - "0" : Let platform decide on the stack size - (default) - - "x" : Create thread with "x" KB of stack size - -DisablePriorityBoost: - "true" : Disable priority boosting - (default) - - "false" : Enable priority boosting -*/ - -class CThreadConfigManager - : public IThreadConfigManager -{ -public: - typedef std::map, SThreadConfig> ThreadConfigMap; - typedef std::pair, SThreadConfig> ThreadConfigMapPair; - typedef std::map, SThreadConfig>::iterator ThreadConfigMapIter; - typedef std::map, SThreadConfig>::const_iterator ThreadConfigMapConstIter; - -public: - CThreadConfigManager(); - ~CThreadConfigManager() - { - } - - // Called once during System startup. - // Loads the thread configuration for the executing platform from file. - virtual bool LoadConfig(const char* pcPath) override; - - // Returns true if a config has been loaded - virtual bool ConfigLoaded() const override; - - // Gets the thread configuration for the specified thread on the active platform. - // If no matching config is found a default configuration is returned - // (which does not have the same name as the search string). - virtual const SThreadConfig* GetThreadConfig(const char* sThreadName, ...) override; - virtual const SThreadConfig* GetDefaultThreadConfig() const override; - - virtual void DumpThreadConfigurationsToLog() override; - -private: - const char* IdentifyPlatform(); - - const SThreadConfig* GetThreadConfigImpl(const char* cThreadName); - - bool LoadPlatformConfig(const XmlNodeRef& rXmlRoot, const char* sPlatformId); - - void LoadPlatformThreadConfigs(const XmlNodeRef& rXmlPlatformRef); - bool LoadThreadDefaultConfig(const XmlNodeRef& rXmlPlatformRef); - void LoadThreadConfig(const XmlNodeRef& rXmlThreadRef, SThreadConfig& rThreadConfig); - - void LoadAffinity(const XmlNodeRef& rXmlThreadRef, uint32& rAffinity, SThreadConfig::TThreadParamFlag& rParamActivityFlag); - void LoadPriority(const XmlNodeRef& rXmlThreadRef, int32& rPriority, SThreadConfig::TThreadParamFlag& rParamActivityFlag); - void LoadDisablePriorityBoost(const XmlNodeRef& rXmlThreadRef, bool& rPriorityBoost, SThreadConfig::TThreadParamFlag& rParamActivityFlag); - void LoadStackSize(const XmlNodeRef& rXmlThreadRef, uint32& rStackSize, SThreadConfig::TThreadParamFlag& rParamActivityFlag); - -private: - ThreadConfigMap m_threadConfig; // Note: The map key is referenced by as const char* by the value's storage class. Other containers may not support this behaviour as they will re-allocate memory as they grow/shrink. - ThreadConfigMap m_wildcardThreadConfig; - SThreadConfig m_defaultConfig; -}; diff --git a/Code/CryEngine/CrySystem/ThreadInfo.cpp b/Code/CryEngine/CrySystem/ThreadInfo.cpp deleted file mode 100644 index 14285215b8..0000000000 --- a/Code/CryEngine/CrySystem/ThreadInfo.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ThreadInfo.h" -#include "System.h" - -//////////////////////////////////////////////////////////////////////////// - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define THREADINFO_CPP_SECTION_1 1 -#define THREADINFO_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION THREADINFO_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(ThreadInfo_cpp) -#endif - -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -#if AZ_LEGACY_CRYSYSTEM_TRAIT_THREADINFO_WINDOWS_STYLE -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::GetCurrentThreads(TThreadInfo& threadsOut) -{ - HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - DWORD currProcessId = GetCurrentProcessId(); - if (h != INVALID_HANDLE_VALUE) - { - THREADENTRY32 te; - te.dwSize = sizeof(te); - if (Thread32First(h, &te)) - { - do - { - if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) - { - if (te.th32OwnerProcessID == currProcessId) - { - threadsOut[te.th32ThreadID] = CryThreadGetName(te.th32ThreadID); - } - } - te.dwSize = sizeof(te); - } while (Thread32Next(h, &te)); - } - CloseHandle(h); - } -} - -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds /* = TThreadIds()*/, bool ignoreCurrThread /* = true*/) -{ - TThreadIds threadids = threadIds; - if (threadids.empty()) - { - TThreadInfo threads; - GetCurrentThreads(threads); - DWORD currThreadId = GetCurrentThreadId(); - for (TThreadInfo::iterator it = threads.begin(), end = threads.end(); it != end; ++it) - { - if (!ignoreCurrThread || it->first != currThreadId) - { - threadids.push_back(it->first); - } - } - } - for (TThreadIds::iterator it = threadids.begin(), end = threadids.end(); it != end; ++it) - { - SThreadHandle thread; - thread.Id = *it; - thread.Handle = OpenThread(THREAD_ALL_ACCESS, FALSE, *it); - threadsOut.push_back(thread); - } -} - -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::CloseThreadHandles(const TThreads& threads) -{ - for (TThreads::const_iterator it = threads.begin(), end = threads.end(); it != end; ++it) - { - CloseHandle(it->Handle); - } -} - -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION THREADINFO_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(ThreadInfo_cpp) -#elif defined(LINUX) || defined(APPLE) -void SThreadInfo::GetCurrentThreads(TThreadInfo& threadsOut) -{ - assert(false); // not implemented! -} - -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds /* = TThreadIds()*/, bool ignoreCurrThread /* = true*/) -{ - assert(false); // not implemented! -} - -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::CloseThreadHandles(const TThreads& threads) -{ - assert(false); // not implemented! -} - -//////////////////////////////////////////////////////////////////////////// -#endif diff --git a/Code/CryEngine/CrySystem/ThreadInfo.h b/Code/CryEngine/CrySystem/ThreadInfo.h deleted file mode 100644 index 4bcacf71d5..0000000000 --- a/Code/CryEngine/CrySystem/ThreadInfo.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_THREADINFO_H -#define CRYINCLUDE_CRYSYSTEM_THREADINFO_H -#pragma once - - -struct SThreadInfo -{ -public: - struct SThreadHandle - { - HANDLE Handle; - uint32 Id; - }; - - typedef std::vector TThreadIds; - typedef std::vector TThreads; - typedef std::map TThreadInfo; - - // returns thread info - static void GetCurrentThreads(TThreadInfo& threadsOut); - - // fills threadsOut vector with thread handles of given thread ids; if threadIds vector is emtpy it fills all running threads - // if ignoreCurrThread is true it will not return the current thread - static void OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds = TThreadIds(), bool ignoreCurrThread = true); - - // closes thread handles; should be called whenever GetCurrentThreads was called! - static void CloseThreadHandles(const TThreads& threads); -}; - -#endif // CRYINCLUDE_CRYSYSTEM_THREADINFO_H diff --git a/Code/CryEngine/CrySystem/ThreadTask.cpp b/Code/CryEngine/CrySystem/ThreadTask.cpp deleted file mode 100644 index d1ae7304e6..0000000000 --- a/Code/CryEngine/CrySystem/ThreadTask.cpp +++ /dev/null @@ -1,1046 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ThreadTask.h" -#include "CPUDetect.h" -#include "IConsole.h" -#include "System.h" - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define THREADTASK_CPP_SECTION_1 1 -#define THREADTASK_CPP_SECTION_2 2 -#endif - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif //WIN32 - -#include "BitFiddling.h" - -#if defined(ANDROID) -#include -#include -#endif -#if defined(LINUX) - -#endif -#if defined(APPLE) -// include for thread_policy_set -#include -#include -#endif - -#include - -////////////////////////////////////////////////////////////////////////// -CThreadTask_Thread::CThreadTask_Thread(CThreadTaskManager* pTaskMgr, const char* sName, - int nIndex, int nProcessor, int nThreadPriority, ThreadPoolHandle poolHandle /* = -1*/) - : tasks(64) -{ - m_nThreadPriority = nThreadPriority; - m_pTaskManager = pTaskMgr; - m_sThreadName = sName; - bStopThread = false; - bRunning = false; - m_hThreadHandle = 0; - m_nThreadIndex = nIndex; - m_nProcessor = nProcessor; - m_poolHandle = poolHandle; -} - -CThreadTask_Thread::~CThreadTask_Thread() -{ - while (!tasks.empty()) - { - tasks.pop()->m_pThread = 0; - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::SingleUpdate() -{ - while (true) - { - m_pProcessingTask = NULL; - - { - if (tasks.empty()) - { - break; - } - // remove from queue - m_pProcessingTask = tasks.pop(); - } - - if (m_pProcessingTask) - { - m_pProcessingTask->m_pTask->OnUpdate(); - } - - if (m_pProcessingTask) // push it back - { - tasks.push(m_pProcessingTask); - } - - if (bStopThread) - { - break; - } - } - - if (m_poolHandle != -1) // if this thread is in the pool, we need to reassign some tasks for it - { - m_pTaskManager->BalanceThreadInPool(this); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::Run() -{ - Init(); - - bRunning = true; - while (!bStopThread) - { - while (tasks.empty() && !bStopThread) - { - m_waitForTasks.Wait(); - } - - if (!bStopThread) - { - SingleUpdate(); - } - } - bRunning = false; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::Cancel() -{ - bStopThread = true; - m_waitForTasks.Set(); - Stop(); - - // for blocking thread notify the blocking task - if (m_nThreadIndex == -1) - { - if (m_pProcessingTask && m_pProcessingTask->m_params.nFlags & THREAD_TASK_BLOCKING) // check if we have a blocking task - { - if (m_pProcessingTask->m_pTask) // cancel it - { - m_pProcessingTask->m_pTask->Stop(); - } - } - } - - WaitForThread(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::Terminate() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::AddTask(SThreadTaskInfo* pTaskInfo) -{ - pTaskInfo->m_pThread = this; - tasks.push(pTaskInfo); - m_waitForTasks.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::RemoveTask(SThreadTaskInfo* pTaskInfo) -{ - if (!pTaskInfo) - { - return; - } - - if (m_pProcessingTask == pTaskInfo) - { - pTaskInfo->m_pThread = NULL; - m_pProcessingTask = NULL; - return; - } - - // search for task(mirrored search because of locklessness) - bool bFound = false; - Tasks newTasks; - while (!tasks.empty()) - { - SThreadTaskInfo* pTask = tasks.pop(); - if (pTask == pTaskInfo) - { - pTaskInfo->m_pThread = NULL; - bFound = true; - break; - } - if (pTask) - { - newTasks.push(pTask); - } - } - (void)bFound; - // Don't assert if newTasks is empty. There is a thread race condition between - // the thread shutting down and this code being executed (both update/use - // m_pProcessTask with no locks). newTasks will be empty - // and bFound == false when the race condition is won by the task thread and - // not by the thread that is executing this code - CRY_ASSERT(bFound || newTasks.empty()); - - // fill back - while (!newTasks.empty()) - { - tasks.push(newTasks.pop()); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::RemoveAllTasks() -{ - while (!tasks.empty()) - { - tasks.pop()->m_pThread = NULL; - } -} - -void CThreadTask_Thread::Init() -{ -#if AZ_TRAIT_OS_USE_WINDOWS_THREADS - m_hThreadHandle = GetCurrentThread(); -#endif - - // Name this thread. - CryThreadSetName(GetCurrentThreadId(), m_sThreadName); - - // Set affinity - if (m_nProcessor > 0) - { - ChangeProcessor(m_nProcessor); - } -#if defined(WIN32) - ((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions); -#endif -} - -void CThreadTask_Thread::ChangeProcessor(int nProcessor) -{ - // note this function is not thread-safe - m_nProcessor = nProcessor; -#if defined(WIN32) - DWORD_PTR mask1, mask2; - GetProcessAffinityMask(GetCurrentProcess(), &mask1, &mask2); - if (BIT64(m_nProcessor) & mask1) // Check if we have this affinity - { - SetThreadAffinityMask(m_hThreadHandle, BIT64(m_nProcessor)); - } - else // Reserve CPU 1 for main thread. - { - SetThreadAffinityMask(m_hThreadHandle, (mask1 & (~1))); - } - assert(THREAD_PRIORITY_IDLE <= m_nThreadPriority && m_nThreadPriority <= THREAD_PRIORITY_TIME_CRITICAL); - SetThreadPriority(m_hThreadHandle, m_nThreadPriority); -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION THREADTASK_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(ThreadTask_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(ANDROID) - int err, syscallres; - pid_t pid = gettid(); - syscallres = syscall(__NR_sched_setaffinity, pid, sizeof(nProcessor), &nProcessor); - if (syscallres) - { - err = errno; - CryLog("Error in the syscall setaffinity: mask=%d=0x%x sysconf#=%ld err=%d=0x%x", nProcessor, nProcessor, sysconf(_SC_NPROCESSORS_ONLN), err, err); - } -#elif defined(LINUX) - // Check if the processor is valid - assert(nProcessor < sysconf(_SC_NPROCESSORS_ONLN)); - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(nProcessor, &cpuset); - pthread_t current_thread = pthread_self(); - int ret = pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset); - (void) ret; - // check if the operation completed succesfully - assert(ret == 0 && "ChangeProcessor operation failed"); -#elif defined(APPLE) - assert(nProcessor != 0 && "CThreadTask_Thread::ChangeProcessor - If " - "nProcessor is equal to 0, the default afinity will be applied " - "to the thread. Can be fixed by incrementing nProcess by 1."); - thread_affinity_policy_data_t thread_affinity; - thread_affinity.affinity_tag = nProcessor; - thread_policy_set(pthread_mach_thread_np(pthread_self()), THREAD_AFFINITY_POLICY, (thread_policy_t)&thread_affinity, THREAD_AFFINITY_POLICY_COUNT); - //CryWarning(VALIDATOR_MODULE_SYSTEM,VALIDATOR_WARNING, "CThreadTask_Thread::ChangeProcessor: Feature is not supported on Mac OS X."); -#else - assert(0); -#endif -} - -////////////////////////////////////////////////////////////////////////// -CThreadTaskManager::CThreadTaskManager() -{ - m_nMaxThreads = 1; - - SetThreadName(GetCurrentThreadId(), "Main"); - - m_systemThreads.push_back(GetCurrentThreadId()); -} - -////////////////////////////////////////////////////////////////////////// -CThreadTaskManager::~CThreadTaskManager() -{ - CloseThreads(); - - AUTO_MODIFYLOCK(m_threadsPoolsLock); - while (!m_threadsPools.empty()) - { -#if !defined(NDEBUG) - bool res = -#endif - DestroyThreadsPool(m_threadsPools.begin()->m_hHandle); - assert(res); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::StopAllThreads() -{ - if (m_threads.empty()) - { - return; - } - - size_t i; - // Start from 2nd thread, 1st is main thread. - for (i = 1; i < m_threads.size(); i++) - { - CThreadTask_Thread* pThread = m_threads[i]; - pThread->Cancel(); - } - bool bAllStoped = true; - do - { - bAllStoped = true; - CrySleep(10); - for (i = 1; i < m_threads.size(); i++) - { - CThreadTask_Thread* pThread = m_threads[i]; - // Needs ReadWriteBarrier here. - if (pThread->bRunning) - { - bAllStoped = false; - } - } - } - while (!bAllStoped); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::CloseThreads() -{ - if (m_threads.size() > 0) - { - StopAllThreads(); - } - for (size_t i = MAIN_THREAD_INDEX, numThreads = m_threads.size(); i < numThreads; i++) - { - delete m_threads[i]; - } - m_threads.clear(); - //make sure blocking threads are cancelled - for (bool repeat = true; repeat; ) - { - CThreadTask_Thread* thr = NULL; - { - CryAutoCriticalSection lock(m_threadRemove); - - if (!m_blockingThreads.empty()) - { - thr = *m_blockingThreads.rbegin(); - m_blockingThreads.pop_back(); - } - } - - if (thr) - { - thr->Cancel(); - delete thr; - } - else - { - repeat = false; - } - } - - m_blockingThreads.clear(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::InitThreads() -{ - m_nMaxThreads = gEnv->IsDedicated() ? 1 : 4; - CloseThreads(); - - // Create a dummy thread that is used for main thread. - m_threads.resize(1); - m_threads[0] = new CThreadTask_Thread(this, "Main Thread", 0, AFFINITY_MASK_MAINTHREAD, THREAD_PRIORITY_NORMAL); - - CCpuFeatures* pCPU = ((CSystem*)gEnv->pSystem)->GetCPUFeatures(); - - int nThreads = min((int)m_nMaxThreads, (int)pCPU->GetCPUCount()); - - if (nThreads < 1) - { - nThreads = 1; - } - int nAddThreads = nThreads - 1; - - char str[32]; - m_threads.resize(1 + nAddThreads); - for (int i = 0; i < nAddThreads; i++) - { - int nIndex = i + 1; - int nCPU = i + 1; - sprintf_s(str, "TaskThread%d", i); - if (i < m_nMaxThreads) - { - nCPU = ((CSystem*)gEnv->pSystem)->m_sys_TaskThread_CPU[i]->GetIVal(); - } - - // Clamp to random thread between 1 and max, avoid cpu 0 with main thread - if (nCPU >= nThreads) - { - nCPU = (rand() % (nThreads - 1)) + 1; - } - m_threads[nIndex] = new CThreadTask_Thread(this, str, nIndex, nCPU, THREAD_PRIORITY_NORMAL); - m_threads[nIndex]->Start(0, str, THREAD_PRIORITY_NORMAL, SIMPLE_THREAD_STACK_SIZE_KB * 1024); - } - RescheduleTasks(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::SetMaxThreadCount(int nMaxThreads) -{ - if (nMaxThreads == m_nMaxThreads) - { - return; - } - - m_nMaxThreads = nMaxThreads; - - bool bReallocateThreads = false; - if (m_nMaxThreads < (int)m_threads.size()) - { - bReallocateThreads = true; - } - if (m_nMaxThreads > (int)m_threads.size()) - { - CCpuFeatures* pCPU = ((CSystem*)gEnv->pSystem)->GetCPUFeatures(); - if (m_threads.size() < pCPU->GetCPUCount()) - { - bReallocateThreads = true; - } - } - if (bReallocateThreads) - { - CloseThreads(); - InitThreads(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::RegisterTask(IThreadTask* pTask, const SThreadTaskParams& options) -{ - if (!pTask) - { - assert(0); - return; - } - SThreadTaskInfo* pTaskInfo = pTask->GetTaskInfo(); - pTaskInfo->m_pTask = pTask; - pTaskInfo->m_params = options; - - if ((options.nFlags & THREAD_TASK_BLOCKING) == 0) - { - ScheduleTask(pTaskInfo); - } - else - { - CryAutoCriticalSection lock(m_threadRemove); - // Blocking task will need it`s own thread. - const int threadPriority = THREAD_PRIORITY_NORMAL; - CThreadTask_Thread* pThread = - new CThreadTask_Thread(this, options.name, -1, options.nPreferedThread, threadPriority); - pThread->Start(0, (char*)options.name, threadPriority, options.nStackSizeKB * 1024); - pThread->AddTask(pTaskInfo); - - m_blockingThreads.push_back(pThread); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::UnregisterTask(IThreadTask* pTask) -{ - assert(pTask); - if (!pTask) - { - return; - } - SThreadTaskInfo* pTaskInfo = pTask->GetTaskInfo(); - assert(pTaskInfo); - - IThreadTask_Thread* pThread = pTaskInfo->m_pThread; - uint32 flags = pTaskInfo->m_params.nFlags; - - // Remove from thread. - if (pThread) - { - pThread->RemoveTask(pTaskInfo); - } - - pTask->Stop(); - - if (flags & THREAD_TASK_BLOCKING) - { - CThreadTask_Thread* thr = NULL; - { - CryAutoCriticalSection lock(m_threadRemove); - Threads::iterator end = m_blockingThreads.end(); - Threads::iterator toErase = std::find(m_blockingThreads.begin(), end, pThread); - - if (toErase != end) // impossible to find anything. no push_back done on m_blockingThreads - { - thr = *toErase; - m_blockingThreads.erase(toErase); - } - } - - if (thr) - { - thr->Cancel(); - delete thr; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::ScheduleTask(SThreadTaskInfo* pTaskInfo) -{ - size_t i; - - if (pTaskInfo->m_pThread) - { - assert(0); - pTaskInfo->m_pThread->RemoveTask(pTaskInfo); - } - - CThreadTask_Thread* pGoodThread = NULL; - - if (pTaskInfo->m_params.nFlags & THREAD_TASK_ASSIGN_TO_POOL) - { - AUTO_READLOCK(m_threadsPoolsLock); - - // find the pool - CThreadsPool* pool = NULL; - size_t nSize = m_threadsPools.size(); - for (i = 0; i < nSize; ++i) - { - if (m_threadsPools[i].m_hHandle == pTaskInfo->m_params.nThreadsGroupId) - { - pool = &m_threadsPools[i]; - } - } - - if (pool) - { - // Find available thread for the task. - for (i = 0; i < (int)pool->m_Threads.size(); ++i) - { - CThreadTask_Thread* pThread = pool->m_Threads[i]; - const bool threadIsFree = pThread->tasks.empty() && pThread->m_pProcessingTask == NULL; - if (threadIsFree || pGoodThread == NULL) - { - pGoodThread = pThread; - if (threadIsFree) - { - break; - } - } - } - } - else - { - gEnv->pLog->LogError("[Error]Task manager: threads pool not found!"); - assert(0); - } - } - else if (pTaskInfo->m_params.nPreferedThread >= 0 && pTaskInfo->m_params.nPreferedThread < (int)m_threads.size()) - { - assert((int)m_threads.size() > pTaskInfo->m_params.nPreferedThread); - // Assign task to desired thread. - pGoodThread = m_threads[pTaskInfo->m_params.nPreferedThread]; - } - else - { - // Find available thread for the task. - for (i = MAIN_THREAD_INDEX + 1; i < (int)m_threads.size(); i++) - { - CThreadTask_Thread* pThread = m_threads[i]; - PREFAST_ASSUME(pThread); - if (pThread->tasks.empty() || pGoodThread == NULL) - { - pGoodThread = pThread; - if (pThread->tasks.empty()) - { - break; - } - } - } - } - if (!pGoodThread && !m_threads.empty()) - { - // Assign to last thread. - pGoodThread = m_threads[m_threads.size() - 1]; - } - - if (pGoodThread) - { - pGoodThread->AddTask(pTaskInfo); - } - else - { - m_unassignedTasks.push(pTaskInfo); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::RescheduleTasks() -{ - // Un-schedule all tasks. - for (int i = 0; i < (int)m_threads.size(); i++) - { - while (!m_threads[i]->tasks.empty()) - { - SThreadTaskInfo* pTask = m_threads[i]->tasks.pop(); - if (!pTask) - { - break; - } - if (pTask->m_params.nFlags & THREAD_TASK_BLOCKING) // Do not schedule blocking tasks. - { - m_threads[i]->tasks.push(pTask); - break; - } - pTask->m_pThread = NULL; - m_unassignedTasks.push(pTask); - } - } - - while (!m_unassignedTasks.empty()) - { - ScheduleTask(m_unassignedTasks.pop()); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::OnUpdate() -{ - AZ_TRACE_METHOD(); - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_SYSTEM); - - // Emulate single update of the main thread. - if (m_threads[0]) - { - m_threads[0]->SingleUpdate(); - } - - // assign unassigned tasks - while (!m_unassignedTasks.empty()) - { - ScheduleTask(m_unassignedTasks.pop()); - } - - // balance all pools - AUTO_READLOCK(m_threadsPoolsLock); - size_t nSize = m_threadsPools.size(); - for (size_t itPool = 0; itPool < nSize; ++itPool) - { - BalanceThreadsPool(m_threadsPools[itPool].m_hHandle); - } -} - -struct THREADNAME_INFO_TASK -{ - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; -}; - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::SetThreadName(threadID dwThreadId, const char* sThreadName) -{ - if (dwThreadId == (THREADID_NULL)) - { - dwThreadId = GetCurrentThreadId(); - } - -#if defined(AZ_PROFILE_TELEMETRY) && AZ_TRAIT_OS_USE_WINDOWS_THREADS - AZStd::thread_desc desc; - desc.m_name = sThreadName; - // we broadcast to the "client" bus and then to the "driller" (profiling) bus - AZStd::ThreadEventBus::Broadcast(&AZStd::ThreadEventBus::Events::OnThreadEnter, AZStd::thread::id(dwThreadId), &desc); - AZStd::ThreadDrillerEventBus::Broadcast(&AZStd::ThreadDrillerEventBus::Events::OnThreadEnter, AZStd::thread::id(dwThreadId), &desc); -#endif - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_THREADTASK_EXCEPTIONS - ////////////////////////////////////////////////////////////////////////// - // Raise exception to set thread name for debugger. - ////////////////////////////////////////////////////////////////////////// - THREADNAME_INFO_TASK threadName; - threadName.dwType = 0x1000; - threadName.szName = sThreadName; - threadName.dwThreadID = dwThreadId; - threadName.dwFlags = 0; - - __try - { - RaiseException(0x406D1388, 0, sizeof(threadName) / sizeof(DWORD), (ULONG_PTR*)&threadName); - } - __except (EXCEPTION_CONTINUE_EXECUTION) - { - } -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION THREADTASK_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(ThreadTask_cpp) -#endif - - { - m_threadNameLock.Lock(); - m_threadNames[dwThreadId] = sThreadName; - m_threadNameLock.Unlock(); - } -} - -////////////////////////////////////////////////////////////////////////// -const char* CThreadTaskManager::GetThreadName(threadID dwThreadId) -{ - CryAutoCriticalSection lock(m_threadNameLock); - ThreadNames::const_iterator it = m_threadNames.find(dwThreadId); - if (it != m_threadNames.end()) - { - return it->second.c_str(); - } - - return ""; -} - -////////////////////////////////////////////////////////////////////////// -threadID CThreadTaskManager::GetThreadByName(const char* sThreadName) -{ - CryAutoCriticalSection lock(m_threadNameLock); - for (ThreadNames::const_iterator it = m_threadNames.begin(); it != m_threadNames.end(); ++it) - { - if (it->second.compareNoCase(sThreadName) == 0) - { - return it->first; - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::AddSystemThread(threadID nThreadId) -{ - CryAutoCriticalSection lock(m_systemThreadsLock); - m_systemThreads.push_back(nThreadId); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::RemoveSystemThread(threadID nThreadId) -{ - CryAutoCriticalSection lock(m_systemThreadsLock); - stl::find_and_erase(m_systemThreads, nThreadId); -} - -////////////////////////////////////////////////////////////////////////// -ThreadPoolHandle CThreadTaskManager::CreateThreadsPool(const ThreadPoolDesc& desc) -{ - AUTO_MODIFYLOCK(m_threadsPoolsLock); - - ThreadPoolHandle newId = m_threadsPools.empty() ? 0 : m_threadsPools.rbegin()->m_hHandle + 1; - - if (desc.AffinityMask == INVALID_AFFINITY) - { - assert(0); - return -1; - } - - // create the pool - m_threadsPools.push_back(CThreadsPool()); - CThreadsPool& rPool = m_threadsPools.back(); - - // assign the new handle - rPool.m_hHandle = newId; - - // fill up the desc - rPool.m_pDescription = desc; - - Threads& threads = rPool.m_Threads; - - size_t threadNameSize = desc.sPoolName.size() + 30; - std::vector threadName(threadNameSize); - uint32 iThread = 0; - for (uint32 nIndex = 0; nIndex < sizeof(desc.AffinityMask) * 8; ++nIndex) - { - // check if we have affinity mask bit set for this thread - if (!(desc.AffinityMask & (1 << nIndex))) - { - continue; - } - - const int32 nThreadPriority = (desc.nThreadPriority == -1) ? THREAD_PRIORITY_NORMAL : desc.nThreadPriority; - const int32 nThreadStackSizeKB = (desc.nThreadStackSizeKB == -1) ? SIMPLE_THREAD_STACK_SIZE_KB : desc.nThreadStackSizeKB; - - // create a thread - sprintf_s(&threadName[0], threadNameSize, "%s%d", desc.sPoolName.c_str(), iThread); - CThreadTask_Thread* thread = new CThreadTask_Thread(this, &threadName[0], iThread, nIndex, nThreadPriority, newId); - - // start thread - thread->Start(0, (char*)&threadName[0], nThreadPriority, nThreadStackSizeKB * 1024); - - // add to pool - threads.push_back(thread); - - iThread++; - } - - return newId; -} - -const bool CThreadTaskManager::DestroyThreadsPool(const ThreadPoolHandle& handle) -{ - AUTO_MODIFYLOCK(m_threadsPoolsLock); - - CThreadsPool* pPool = NULL; - size_t nSize = m_threadsPools.size(); - size_t iPool = 0; - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == handle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - Threads& threads = pPool->m_Threads; - size_t nThreads = threads.size(); - for (size_t iThread = 0; iThread < nThreads; ++iThread) - { - CThreadTask_Thread* pThread = threads[iThread]; - PREFAST_ASSUME(pThread); - pThread->Cancel(); - assert(!(pThread->bRunning)); - delete pThread; - } - - m_threadsPools.erase(m_threadsPools.begin() + iPool); - return true; - } - return false; -} - -const bool CThreadTaskManager::GetThreadsPoolDesc(const ThreadPoolHandle handle, ThreadPoolDesc* pDesc) const -{ - AUTO_READLOCK(m_threadsPoolsLock); - - const CThreadsPool* pPool = NULL; - size_t iPool = 0, nSize = m_threadsPools.size(); - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == handle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - if (pDesc) - { - *pDesc = pPool->m_pDescription; - return true; - } - } - - return false; -} - -const bool CThreadTaskManager::SetThreadsPoolAffinity(const ThreadPoolHandle handle, const ThreadPoolAffinityMask AffinityMask) -{ - CThreadsPool* pPool = NULL; - - AUTO_MODIFYLOCK(m_threadsPoolsLock); - - size_t iPool = 0, nSize = m_threadsPools.size(); - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == handle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - return pPool->SetAffinity(AffinityMask); - } - - return false; -} - -void CThreadTaskManager::BalanceThreadsPool(const ThreadPoolHandle& handle) -{ - CThreadsPool* pPool = NULL; - - AUTO_READLOCK(m_threadsPoolsLock); - - size_t iPool = 0, nSize = m_threadsPools.size(); - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == handle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - // balancing tasks in the pool - for (size_t itThread = 0, nThreads = pPool->m_Threads.size(); itThread < nThreads; ++itThread) - { - CThreadTask_Thread* pThread = pPool->m_Threads[itThread]; - if (pThread->tasks.empty()) // found free thread(without tasks) - { - BalanceThreadInPool(pThread, &pPool->m_Threads); - } - } - } - else - { - assert(0); - } -} - -void CThreadTaskManager::BalanceThreadInPool(CThreadTask_Thread* pFreeThread, Threads* pThreads /* = NULL */) -{ - assert(pFreeThread->m_poolHandle != -1); - - AUTO_READLOCK(m_threadsPoolsLock); - - if (pThreads == NULL) - { - CThreadsPool* pPool = NULL; - size_t iPool = 0, nSize = m_threadsPools.size(); - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == pFreeThread->m_poolHandle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - pThreads = &pPool->m_Threads; - } - } - assert(pThreads); - PREFAST_ASSUME(pThreads); - // search for thread with tasks - for (size_t itAnotherThread = 0, nThreads = pThreads->size(); itAnotherThread < nThreads; ++itAnotherThread) - { - CThreadTask_Thread* pAnotherThread = (*pThreads)[itAnotherThread]; - if (pFreeThread == pAnotherThread) - { - continue; - } - if (pAnotherThread->tasks.empty()) - { - continue; - } - - // we found a thread with more than one task - SThreadTaskInfo* pTask = pAnotherThread->tasks.pop(); - if (pTask) - { - assert(pTask->m_pThread == pAnotherThread); - // reassign the last task to another thread - pFreeThread->AddTask(pTask); - break; // process next free thread - } - } -} - -void CThreadTaskManager::MarkThisThreadForDebugging(const char* name, bool bDump) -{ - bDump ? ::MarkThisThreadForDebugging(name) : ::UnmarkThisThreadFromDebugging(); -} - - -const bool CThreadTaskManager::CThreadsPool::SetAffinity(const ThreadPoolAffinityMask AffinityMask) -{ - // check if all threads in the pool are covered by the bits of this mask - if (CountBits(AffinityMask) != m_Threads.size()) - { - // wrong arguments - return false; - } - - // update affinity mask - m_pDescription.AffinityMask = AffinityMask; - - size_t itThread = 0; - for (uint32 nProcessorIndex = 0; nProcessorIndex < sizeof(AffinityMask) * 8; ++nProcessorIndex) - { - assert(itThread < m_Threads.size()); - // check if we have affinity mask bit set for this thread - if (!(AffinityMask & (1 << nProcessorIndex))) - { - continue; - } - - // changin thread's affinity in the pool - m_Threads[itThread]->ChangeProcessor(nProcessorIndex); - ++itThread; - } - return true; -} diff --git a/Code/CryEngine/CrySystem/ThreadTask.h b/Code/CryEngine/CrySystem/ThreadTask.h deleted file mode 100644 index e528fedf5f..0000000000 --- a/Code/CryEngine/CrySystem/ThreadTask.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_THREADTASK_H -#define CRYINCLUDE_CRYSYSTEM_THREADTASK_H -#pragma once - - -#include -#include -#include - -#define MAIN_THREAD_INDEX 0 - -class CThreadTask_Thread; - - -void MarkThisThreadForDebugging(const char* name); -void UnmarkThisThreadFromDebugging(); -void UpdateFPExceptionsMaskForThreads(); - - -class CThreadTaskManager; -/// -struct IThreadTaskRunnable -{ - virtual ~IThreadTaskRunnable(){} - virtual void Run() = 0; - virtual void Cancel() = 0; -}; -////////////////////////////////////////////////////////////////////////// -class CThreadTask_Thread - : public CryThread - , public IThreadTask_Thread -{ -protected: - void Init(); -public: - CThreadTask_Thread(CThreadTaskManager* pTaskMgr, const char* sName, int nThreadIndex, int nProcessor, int nThreadPriority, ThreadPoolHandle poolHandle = -1); - ~CThreadTask_Thread(); - - // see IThreadTaskRunnable, CryThread<> - void Run() override; - void Cancel() override; - - // see CryThread<> - void Terminate() override; - - // IThreadTask_Thread - void AddTask(SThreadTaskInfo* pTaskInfo) override; - void RemoveTask(SThreadTaskInfo* pTaskInfo) override; - void RemoveAllTasks() override; - void SingleUpdate() override; - - void ChangeProcessor(int nProcessor); -public: - CThreadTaskManager* m_pTaskManager; - string m_sThreadName; - int m_nThreadIndex; // -1 means the thread is blocking - int m_nProcessor; - int m_nThreadPriority; - - THREAD_HANDLE m_hThreadHandle; - - // Tasks running on this thread. - typedef CryMT::CLocklessPointerQueue > Tasks; - Tasks tasks; - - // The task is being processing now - SThreadTaskInfo* m_pProcessingTask; - - CryEvent m_waitForTasks; - - // Set to true when thread must stop. - volatile bool bStopThread; - volatile bool bRunning; - - // handle of threads pool which this thread belongs to(if any) - ThreadPoolHandle m_poolHandle; -}; - -////////////////////////////////////////////////////////////////////////// -class CThreadTaskManager - : public IThreadTaskManager -{ -private: - typedef std::vector > Threads; - // note: this struct is auxilary and NOT thread-safe - // it is only for internal use inside the task manager - struct CThreadsPool - { - ThreadPoolHandle m_hHandle; - Threads m_Threads; - ThreadPoolDesc m_pDescription; - const bool SetAffinity(const ThreadPoolAffinityMask AffinityMask); - const bool operator < (const CThreadsPool& p) const { return m_hHandle < p.m_hHandle; } - const bool operator == (const CThreadsPool& p) const { return m_hHandle == p.m_hHandle; } - }; - - typedef std::vector ThreadsPools; - -public: - CThreadTaskManager(); - ~CThreadTaskManager(); - - void InitThreads(); - void CloseThreads(); - void StopAllThreads(); - - ////////////////////////////////////////////////////////////////////////// - // IThreadTaskManager - ////////////////////////////////////////////////////////////////////////// - virtual void RegisterTask(IThreadTask* pTask, const SThreadTaskParams& options); - virtual void UnregisterTask(IThreadTask* pTask); - virtual void SetMaxThreadCount(int nMaxThreads); - virtual void SetThreadName(threadID dwThreadId, const char* sThreadName); - virtual const char* GetThreadName(threadID dwThreadId); - virtual threadID GetThreadByName(const char* sThreadName); - - // Thread pool framework - virtual ThreadPoolHandle CreateThreadsPool(const ThreadPoolDesc& desc); - virtual const bool DestroyThreadsPool(const ThreadPoolHandle& handle); - virtual const bool GetThreadsPoolDesc(const ThreadPoolHandle handle, ThreadPoolDesc* pDesc) const; - virtual const bool SetThreadsPoolAffinity(const ThreadPoolHandle handle, const ThreadPoolAffinityMask AffinityMask); - - virtual void MarkThisThreadForDebugging(const char* name, bool bDump); - ////////////////////////////////////////////////////////////////////////// - - // This is on update function of the main thread. - void OnUpdate(); - - void AddSystemThread(threadID nThreadId); - void RemoveSystemThread(threadID nThreadId); - - // Balancing tasks in the pool between threads - void BalanceThreadsPool(const ThreadPoolHandle& handle); - void BalanceThreadInPool(CThreadTask_Thread* pFreeThread, Threads* pThreads = NULL); - -private: - void ScheduleTask(SThreadTaskInfo* pTaskInfo); - void RescheduleTasks(); -private: - - // User created threads pools - mutable CryReadModifyLock m_threadsPoolsLock; - ThreadsPools m_threadsPools; - - // Physical threads available to system. - Threads m_threads; - - // Threads with single blocking task attached. - Threads m_blockingThreads; - - typedef CryMT::CLocklessPointerQueue Tasks; - - Tasks m_unassignedTasks; - - mutable CryCriticalSection m_threadNameLock; - mutable CryCriticalSection m_threadRemove; - typedef std::map ThreadNames; - ThreadNames m_threadNames; - - mutable CryCriticalSection m_systemThreadsLock; - std::vector m_systemThreads; - - // Max threads that can be executed at same time. - int m_nMaxThreads; -}; - - -#endif // CRYINCLUDE_CRYSYSTEM_THREADTASK_H diff --git a/Code/CryEngine/CrySystem/UnitTests/CryMathTests.cpp b/Code/CryEngine/CrySystem/UnitTests/CryMathTests.cpp deleted file mode 100644 index 6fc9ae7830..0000000000 --- a/Code/CryEngine/CrySystem/UnitTests/CryMathTests.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "CrySystem_precompiled.h" -#include -#include - -namespace UnitTest -{ - class CryMathTestFixture - : public ::testing::Test - {}; - -#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS - TEST_F(CryMathTestFixture, DISABLED_InverserSqrt_HasAtLeast22BitsOfAccuracy) -#else - TEST_F(CryMathTestFixture, InverserSqrt_HasAtLeast22BitsOfAccuracy) -#endif - { - float testFloat(0.336950600); - const float result = isqrt_safe_tpl(testFloat * testFloat); - const float epsilon = 0.00001f; - EXPECT_NEAR(2.96779, result, epsilon); - } - -#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS - TEST_F(CryMathTestFixture, DISABLED_SimdSqrt_HasAtLeast23BitsOfAccuracy) -#else - TEST_F(CryMathTestFixture, SimdSqrt_HasAtLeast23BitsOfAccuracy) -#endif - { - float testFloat(3434.34839439); - const float result = sqrt_tpl(testFloat); - const float epsilon = 0.00001f; - EXPECT_NEAR(58.60331, result, epsilon); - } -} diff --git a/Code/CryEngine/CrySystem/UnitTests/CryPakUnitTests.cpp b/Code/CryEngine/CrySystem/UnitTests/CryPakUnitTests.cpp deleted file mode 100644 index 1935196570..0000000000 --- a/Code/CryEngine/CrySystem/UnitTests/CryPakUnitTests.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" - -#include -#include - -#include -#include // for max path decl -#include -#include -#include // for function<> in the find files callback. -#include -#include -#include -#include -#include - -namespace CryPakUnitTests -{ - -#if defined(AZ_PLATFORM_WINDOWS) - - // Note: none of the below is really a unit test, its all basic feature tests - // for critical functionality - - class Integ_CryPakUnitTests - : public ::testing::Test - { - protected: - bool IsPackValid(const char* path) - { - AZ::IO::IArchive* pak = gEnv->pCryPak; - if (!pak) - { - return false; - } - - if (!pak->OpenPack(path, AZ::IO::IArchive::FLAGS_PATH_REAL)) - { - return false; - } - - pak->ClosePack(path); - return true; - } - }; - - TEST_F(Integ_CryPakUnitTests, TestCryPakModTime) - { - AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance(); - ASSERT_NE(nullptr, fileIo); - - AZ::IO::IArchive* pak = gEnv->pCryPak; - // repeat the following test multiple times, since timing (seconds) can affect it and it involves time! - for (int iteration = 0; iteration < 10; ++iteration) - { - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds{ 100 }); - - // helper paths and strings - AZStd::string gameFolder = fileIo->GetAlias("@usercache@"); - - AZStd::string testFile = "unittest.bin"; - AZStd::string testFilePath = gameFolder + "\\" + testFile; - AZStd::string testPak = "unittest.pak"; - AZStd::string testPakPath = gameFolder + "\\" + testPak; - AZStd::string zipCmd = "-zip=" + testPakPath; - - // delete test files in case they already exist - fileIo->Remove(testFilePath.c_str()); - pak->ClosePack(testPakPath); - fileIo->Remove(testPakPath.c_str()); - - // create a test file - char data[] = "unittest"; - FILE* f = nullptr; - azfopen(&f, testFilePath.c_str(), "wb"); - EXPECT_TRUE(f != nullptr); // file successfully opened for writing - EXPECT_TRUE(fwrite(data, sizeof(char), sizeof(data), f) == sizeof(data)); // file written to successfully - EXPECT_TRUE(fclose(f) == 0); // file closed successfully - - AZ::IO::HandleType fDisk = pak->FOpen(testFilePath.c_str(), "rb"); - EXPECT_TRUE(fDisk > 0); // opened file on disk successfully - uint64_t modTimeDisk = pak->GetModificationTime(fDisk); // high res mod time extracted from file on disk - EXPECT_TRUE(pak->FClose(fDisk) == 0); // file closed successfully - - // create a low res copy of disk file's mod time - uint64_t absDiff, maxDiff = 20000000ul; - uint16_t dosDate, dosTime; - FILETIME ft; - LARGE_INTEGER lt; - - ft.dwHighDateTime = modTimeDisk >> 32; - ft.dwLowDateTime = modTimeDisk & 0xFFFFFFFF; - EXPECT_TRUE(FileTimeToDosDateTime(&ft, &dosDate, &dosTime) != FALSE); // converted to DOSTIME successfully - ft.dwHighDateTime = 0; - ft.dwLowDateTime = 0; - EXPECT_TRUE(DosDateTimeToFileTime(dosDate, dosTime, &ft) != FALSE); // converted to FILETIME successfully - lt.HighPart = ft.dwHighDateTime; - lt.LowPart = ft.dwLowDateTime; - uint64_t modTimeDiskLowRes = lt.QuadPart; - - absDiff = modTimeDiskLowRes >= modTimeDisk ? modTimeDiskLowRes - modTimeDisk : modTimeDisk - modTimeDiskLowRes; - EXPECT_LE(absDiff, maxDiff); // FILETIME (high res) and DOSTIME (low res) should be at most 2 seconds apart - - gEnv->pResourceCompilerHelper->CallResourceCompiler(testFilePath.c_str(), zipCmd.c_str()); - EXPECT_EQ(AZ::IO::ResultCode::Success, fileIo->Remove(testFilePath.c_str())); // test file on disk deleted successfully - - EXPECT_TRUE(pak->OpenPack(testPakPath)); // opened pak successfully - - AZ::IO::HandleType fPak = pak->FOpen(testFilePath.c_str(), "rb"); - EXPECT_GT(fPak, 0); // file (in pak) opened correctly - uint64_t modTimePak = pak->GetModificationTime(fPak); // low res mod time extracted from file in pak - EXPECT_EQ(0, pak->FClose(fPak)); // file closed successfully - - EXPECT_TRUE(pak->ClosePack(testPakPath)); // closed pak successfully - EXPECT_EQ(AZ::IO::ResultCode::Success, fileIo->Remove(testPakPath.c_str())); // test pak file deleted successfully - - absDiff = modTimePak >= modTimeDisk ? modTimePak - modTimeDisk : modTimeDisk - modTimePak; - // compare mod times. They are allowed to be up to 2 seconds apart but no more - EXPECT_LE(absDiff, maxDiff); // FILETIME (disk) and DOSTIME (pak) should be at most 2 seconds apart - // note: Do not directly compare the disk time and pack time, the resolution drops the last digit off in some cases in pak - // it only has a 2 second resolution. you may compare to make sure that the pak time is WITHIN 2 seconds (as above) but not equal. - - // we depend on the fact that crypak is rounding up, instead of down - EXPECT_GE(modTimePak, modTimeDisk); - } - } - - -#endif -} diff --git a/Code/CryEngine/CrySystem/UnixConsole.cpp b/Code/CryEngine/CrySystem/UnixConsole.cpp index d0a7bc15ff..5ec186b8b8 100644 --- a/Code/CryEngine/CrySystem/UnixConsole.cpp +++ b/Code/CryEngine/CrySystem/UnixConsole.cpp @@ -783,12 +783,6 @@ void CUNIXConsole::KeyEnter() if (pushCommand) { - CSystem* pSystem = static_cast(gEnv->pSystem); -#if defined(CVARS_WHITELIST) - ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList(); - bool execute = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(m_InputLine, false) : true; - if (execute) -#endif // defined(CVARS_WHITELIST) { m_CommandQueue.push_back(m_InputLine); } diff --git a/Code/CryEngine/CrySystem/XConsole.cpp b/Code/CryEngine/CrySystem/XConsole.cpp index 3b30a7eeed..32fe67dcc0 100644 --- a/Code/CryEngine/CrySystem/XConsole.cpp +++ b/Code/CryEngine/CrySystem/XConsole.cpp @@ -140,147 +140,6 @@ void Command_SetWaitFrames(IConsoleCmdArgs* pCmd) } } -/* - - CNotificationNetworkConsole - -*/ - -#include -class CNotificationNetworkConsole - : public INotificationNetworkListener -{ -private: - static const uint32 LENGTH_MAX = 256; - static CNotificationNetworkConsole* s_pInstance; - -public: - static bool Initialize() - { - if (s_pInstance) - { - return true; - } - - INotificationNetwork* pNotificationNetwork = gEnv->pSystem->GetINotificationNetwork(); - if (!pNotificationNetwork) - { - return false; - } - - s_pInstance = new CNotificationNetworkConsole(); - pNotificationNetwork->ListenerBind("Command", s_pInstance); - return true; - } - - static void Shutdown() - { - if (!s_pInstance) - { - return; - } - - delete s_pInstance; - s_pInstance = NULL; - } - - static void Update() - { - if (s_pInstance) - { - s_pInstance->ProcessCommand(); - } - } - -private: - CNotificationNetworkConsole() - { - m_pConsole = NULL; - - m_commandBuffer[0][0] = '\0'; - m_commandBuffer[1][0] = '\0'; - m_commandBufferIndex = 0; - m_commandCriticalSection = ::CryCreateCriticalSection(); - } - - ~CNotificationNetworkConsole() - { - if (m_commandCriticalSection) - { - ::CryDeleteCriticalSection(m_commandCriticalSection); - } - } - -private: - void ProcessCommand() - { - if (!ValidateConsole()) - { - return; - } - - char* command = NULL; - ::CryEnterCriticalSection(m_commandCriticalSection); - if (*m_commandBuffer[m_commandBufferIndex]) - { - command = m_commandBuffer[m_commandBufferIndex]; - } - ++m_commandBufferIndex &= 1; - ::CryLeaveCriticalSection(m_commandCriticalSection); - - if (command) - { - m_pConsole->ExecuteString(command); - *command = '\0'; - } - } - - bool ValidateConsole() - { - if (m_pConsole) - { - return true; - } - - if (!gEnv->pConsole) - { - return false; - } - - m_pConsole = gEnv->pConsole; - return true; - } - - // INotificationNetworkListener -public: - void OnNotificationNetworkReceive(const void* pBuffer, size_t length) - { - if (!ValidateConsole()) - { - return; - } - - if (length > LENGTH_MAX) - { - length = LENGTH_MAX; - } - - ::CryEnterCriticalSection(m_commandCriticalSection); - ::memcpy(m_commandBuffer[m_commandBufferIndex], pBuffer, length); - m_commandBuffer[m_commandBufferIndex][LENGTH_MAX - 1] = '\0'; - ::CryLeaveCriticalSection(m_commandCriticalSection); - } - -private: - IConsole* m_pConsole; - - char m_commandBuffer[2][LENGTH_MAX]; - size_t m_commandBufferIndex; - void* m_commandCriticalSection; -}; - -CNotificationNetworkConsole* CNotificationNetworkConsole::s_pInstance = NULL; - void ConsoleShow(IConsoleCmdArgs*) { gEnv->pConsole->ShowConsole(true); @@ -359,8 +218,6 @@ CXConsole::CXConsole() m_waitSeconds = 0.0f; m_blockCounter = 0; - CNotificationNetworkConsole::Initialize(); - AzFramework::ConsoleRequestBus::Handler::BusConnect(); AzFramework::CommandRegistrationBus::Handler::BusConnect(); @@ -379,8 +236,6 @@ CXConsole::~CXConsole() gEnv->pSystem->GetIRemoteConsole()->UnregisterListener(this); } - CNotificationNetworkConsole::Shutdown(); - if (!m_mapVariables.empty()) { while (!m_mapVariables.empty()) @@ -1205,8 +1060,6 @@ void CXConsole::Update() } } } - - CNotificationNetworkConsole::Update(); } //enable this for now, we need it for profiling etc @@ -1749,11 +1602,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) int devOnlyMask = VF_DEV_ONLY; int dediOnlyMask = VF_DEDI_ONLY; int excludeMask = cheatMask | constMask | readOnlyMask | devOnlyMask | dediOnlyMask; -#if defined(CVARS_WHITELIST) - CSystem* pSystem = static_cast(gEnv->pSystem); - ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList(); - bool excludeWhitelist = true; -#endif // defined(CVARS_WHITELIST) if (numArgs > 1) { @@ -1786,13 +1634,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) excludeMask &= ~dediOnlyMask; } -#if defined(CVARS_WHITELIST) - if (azstricmp(arg, "whitelist") == 0) - { - excludeWhitelist = false; - } -#endif // defined(CVARS_WHITELIST) - --numArgs; } } @@ -1810,11 +1651,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) int devOnlyFlags = (command.m_nFlags & devOnlyMask); int dediOnlyFlags = (command.m_nFlags & dediOnlyMask); bool shouldLog = ((cheatFlags | devOnlyFlags | dediOnlyFlags) == 0) || (((cheatFlags | devOnlyFlags | dediOnlyFlags) & ~excludeMask) != 0); -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(command.m_sName, true) : true; - shouldLog &= (!whitelisted || (whitelisted & !excludeWhitelist)); -#endif // defined(CVARS_WHITELIST) - if (shouldLog) { CryLogAlways("[CVARS]: [COMMAND] %s%s%s%s%s", @@ -1822,11 +1658,7 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) (cheatFlags != 0) ? " [VF_CHEAT]" : "", (devOnlyFlags != 0) ? " [VF_DEV_ONLY]" : "", (dediOnlyFlags != 0) ? " [VF_DEDI_ONLY]" : "", -#if defined(CVARS_WHITELIST) - (whitelisted == true) ? " [WHITELIST]" : "" -#else "" -#endif // defined(CVARS_WHITELIST) ); ++commandCount; } @@ -1843,11 +1675,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) int devOnlyFlags = (flags & devOnlyMask); int dediOnlyFlags = (flags & dediOnlyMask); bool shouldLog = ((cheatFlags | constFlags | readOnlyFlags | devOnlyFlags | dediOnlyFlags) == 0) || (((cheatFlags | constFlags | readOnlyFlags | devOnlyFlags | dediOnlyFlags) & ~excludeMask) != 0); -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(pVariable->GetName(), true) : true; - shouldLog &= (!whitelisted || (whitelisted & !excludeWhitelist)); -#endif // defined(CVARS_WHITELIST) - if (shouldLog) { CryLogAlways("[CVARS]: [VARIABLE] %s%s%s%s%s%s%s", @@ -1857,11 +1684,7 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) (readOnlyFlags != 0) ? " [VF_READONLY]" : "", (devOnlyFlags != 0) ? " [VF_DEV_ONLY]" : "", (dediOnlyFlags != 0) ? " [VF_DEDI_ONLY]" : "", -#if defined(CVARS_WHITELIST) - (whitelisted == true) ? " [WHITELIST]" : "" -#else "" -#endif // defined(CVARS_WHITELIST) ); ++cvarCount; } @@ -2520,11 +2343,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer) } } //try to search in command list - -#if defined(CVARS_WHITELIST) - CSystem* pSystem = static_cast(gEnv->pSystem); - ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList(); -#endif // defined(CVARS_WHITELIST) bool bArgumentAutoComplete = false; std::vector matches; @@ -2565,10 +2383,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer) string cmd = string(sVar) + " " + pArgumentAutoComplete->GetValue(i); if (_strnicmp(m_sPrevTab.c_str(), cmd.c_str(), m_sPrevTab.length()) == 0) { -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(cmd, true) : true; - if (whitelisted) -#endif // defined(CVARS_WHITELIST) { bArgumentAutoComplete = true; matches.push_back(cmd); @@ -2590,10 +2404,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer) { if (_strnicmp(m_sPrevTab.c_str(), itrCmds->first.c_str(), m_sPrevTab.length()) == 0) { -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(itrCmds->first, true) : true; - if (whitelisted) -#endif // defined(CVARS_WHITELIST) { matches.push_back((char* const)itrCmds->first.c_str()); } @@ -2613,10 +2423,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer) {//if(itrVars->first.compare(0,m_sPrevTab.length(),m_sPrevTab)==0) if (_strnicmp(m_sPrevTab.c_str(), itrVars->first, m_sPrevTab.length()) == 0) { -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(itrVars->first, true) : true; - if (whitelisted) -#endif // defined(CVARS_WHITELIST) { matches.push_back((char* const)itrVars->first); } @@ -2990,12 +2796,6 @@ void CXConsole::ExecuteInputBuffer() AddCommandToHistory(sTemp.c_str()); -#if defined(CVARS_WHITELIST) - CSystem* pSystem = static_cast(gEnv->pSystem); - ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList(); - bool execute = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(sTemp, false) : true; - if (execute) -#endif // defined(CVARS_WHITELIST) { ExecuteStringInternal(sTemp.c_str(), true); // from console } diff --git a/Code/CryEngine/CrySystem/XML/xml.cpp b/Code/CryEngine/CrySystem/XML/xml.cpp index 601b14eeb3..438b35b6c8 100644 --- a/Code/CryEngine/CrySystem/XML/xml.cpp +++ b/Code/CryEngine/CrySystem/XML/xml.cpp @@ -1809,8 +1809,6 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString, ParseEnd(); } - SYNCHRONOUS_LOADING_TICK(); - delete [] pFileContents; return root; diff --git a/Code/CryEngine/CrySystem/crysystem_files.cmake b/Code/CryEngine/CrySystem/crysystem_files.cmake index 5dc8a68f8b..50cbdc24e4 100644 --- a/Code/CryEngine/CrySystem/crysystem_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_files.cmake @@ -19,14 +19,11 @@ set(FILES ConsoleBatchFile.cpp ConsoleHelpGen.cpp CryAsyncMemcpy.cpp - DebugCallStack.cpp GeneralMemoryHeap.cpp HandlerBase.cpp - IDebugCallStack.cpp AsyncPakManager.cpp Log.cpp SystemRender.cpp - NotificationNetwork.cpp PhysRenderer.cpp ResourceManager.cpp ServerHandler.cpp @@ -36,7 +33,6 @@ set(FILES SystemCFG.cpp SystemEventDispatcher.cpp SystemInit.cpp - SystemScheduler.cpp SystemWin32.cpp Timer.cpp UnixConsole.cpp @@ -52,7 +48,6 @@ set(FILES ServerHandler.h ServerThrottle.h SyncLock.h - SystemScheduler.h UnixConsole.h SystemInit.h XML/ReadWriteXMLSink.h @@ -63,12 +58,8 @@ set(FILES ConsoleBatchFile.h ConsoleHelpGen.h CryWaterMark.h - DebugCallStack.h GeneralMemoryHeap.h - IDebugCallStack.h - IThreadConfigManager.h Log.h - NotificationNetwork.h resource.h SimpleStringPool.h CrySystem_precompiled.h @@ -107,24 +98,12 @@ set(FILES XML/WriteXMLSource.cpp ZipFile.h ZipFileFormat_info.h - ProfileLogSystem.cpp Sampler.cpp - ProfileLogSystem.h Sampler.h LocalizedStringManager.cpp LocalizedStringManager.h - CryThreadUtil_win32_thread.h - ThreadInfo.cpp - ThreadInfo.h - ThreadTask.h - ThreadTask.cpp - ThreadConfigManager.h - ThreadConfigManager.cpp - SystemThreading.cpp ZLibCompressor.cpp ZLibCompressor.h - SoftCode/SoftCodeMgr.cpp - SoftCode/SoftCodeMgr.h Huffman.cpp Huffman.h RemoteConsole/RemoteConsole.cpp diff --git a/Code/CryEngine/CrySystem/crysystem_test_files.cmake b/Code/CryEngine/CrySystem/crysystem_test_files.cmake index a57ba57f77..d8f6887da6 100644 --- a/Code/CryEngine/CrySystem/crysystem_test_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_test_files.cmake @@ -18,7 +18,5 @@ set(FILES Tests/Test_Localization.cpp Tests/test_Main.cpp Tests/test_MaterialUtils.cpp - UnitTests/CryMathTests.cpp - UnitTests/CryPakUnitTests.cpp DllMain.cpp ) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserComponent.cpp index 8d3513cbcb..c505639338 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserComponent.cpp @@ -263,8 +263,6 @@ namespace AzToolsFramework return SourceFileDetails("Icons/AssetBrowser/XML_16.svg"); } - - // this is here to prevent having to include IResourceCompilerHelper, which is in CryCommon. static const char* sourceFormats[] = { ".tif", ".bmp", ".gif", ".jpg", ".jpeg", ".jpe", ".tga", ".png" }; for (unsigned int sourceImageFormatIndex = 0, numSources = AZ_ARRAY_SIZE(sourceFormats); sourceImageFormatIndex < numSources; ++sourceImageFormatIndex) diff --git a/Code/LauncherUnified/Launcher.cpp b/Code/LauncherUnified/Launcher.cpp index 033169ac6d..1f29478399 100644 --- a/Code/LauncherUnified/Launcher.cpp +++ b/Code/LauncherUnified/Launcher.cpp @@ -573,11 +573,6 @@ namespace O3DELauncher systemInitParams.hWnd = mainInfo.m_window; systemInitParams.pPrintSync = mainInfo.m_printSink; - if (strstr(mainInfo.m_commandLine, "-norandom")) - { - systemInitParams.bNoRandom = true; - } - systemInitParams.bDedicatedServer = IsDedicatedServer(); if (IsDedicatedServer()) { diff --git a/Code/Sandbox/Editor/BackgroundScheduleManager.cpp b/Code/Sandbox/Editor/BackgroundScheduleManager.cpp deleted file mode 100644 index 23eee6daf4..0000000000 --- a/Code/Sandbox/Editor/BackgroundScheduleManager.cpp +++ /dev/null @@ -1,629 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "BackgroundScheduleManager.h" - -namespace BackgroundScheduleManager -{ - //----------------------------------------------------------------------------- - - CScheduleItem::CScheduleItem(const char* szName) - : m_name(szName) - , m_refCount(1) - , m_state(eScheduleItemState_Pending) - { - } - - CScheduleItem::~CScheduleItem() - { - CRY_ASSERT(m_refCount == 0); - - for (TWorkItems::const_iterator it = m_workItems.begin(); - it != m_workItems.end(); ++it) - { - (*it)->Release(); - } - } - - const char* CScheduleItem::GetDescription() const - { - return m_name.c_str(); - } - - EScheduleItemState CScheduleItem::GetState() const - { - return m_state; - } - - const float CScheduleItem::GetProgress() const - { - if (m_workItems.empty()) - { - return 1.0f; - } - else - { - float totalProgress = 0.0f; - - for (TWorkItems::const_iterator it = m_workItems.begin(); - it != m_workItems.end(); ++it) - { - totalProgress += (*it)->GetProgress(); - } - - return totalProgress / (float)m_workItems.size(); - } - } - - const uint32 CScheduleItem::GetNumWorkItems() const - { - return m_workItems.size(); - } - - IBackgroundScheduleItemWork* CScheduleItem::GetWorkItem(const uint32 index) const - { - return m_workItems[index]; - } - - void CScheduleItem::AddWorkItem(IBackgroundScheduleItemWork* pWork) - { - // cannot add new work items when item has finished or failed - if (m_state == eScheduleItemState_Failed || m_state == eScheduleItemState_Completed) - { - CryFatalError("Cannot add new work items when item has finished or failed"); - return; - } - - // add to the work list - if (m_state == eScheduleItemState_Processing) - { - m_addedWorkItems.push_back(pWork); - } - else - { - m_workItems.push_back(pWork); - } - } - - void CScheduleItem::AddRef() - { - CryInterlockedIncrement(&m_refCount); - } - - void CScheduleItem::Release() - { - const int nCount = CryInterlockedDecrement(&m_refCount); - assert(nCount >= 0); - if (nCount == 0) - { - delete this; - } - else if (nCount < 0) - { - assert(0); - CryFatalError("Deleting Reference Counted Object Twice"); - } - } - - void CScheduleItem::RequestStop() - { - if (m_state == eScheduleItemState_Pending) - { - // we can stop right away :) - m_state = eScheduleItemState_Failed; - } - else if (m_state == eScheduleItemState_Processing) - { - m_state = eScheduleItemState_Stopping; - - // signal all pending work to stop - uint32 curIndex = 0; - while (curIndex < m_processedWorkItems.size()) - { - IBackgroundScheduleItemWork* pWork = m_processedWorkItems[curIndex]; - if (pWork->OnStop()) - { - // if the work was stopped remove it from list - m_processedWorkItems.erase(m_processedWorkItems.begin() + curIndex); - continue; - } - else - { - // this work item cannot be stopped this frame - curIndex += 1; - } - } - - // if all pending work has been stopped we can assume the failed state - if (m_processedWorkItems.empty()) - { - m_state = eScheduleItemState_Failed; - } - } - } - - EScheduleWorkItemStatus CScheduleItem::Update() - { - EScheduleWorkItemStatus retStatus = eScheduleWorkItemStatus_NotFinished; - - switch (m_state) - { - // finial state - work failed - case eScheduleItemState_Failed: - { - retStatus = eScheduleWorkItemStatus_Failed; - break; - } - - // final state - work completed - case eScheduleItemState_Completed: - { - retStatus = eScheduleWorkItemStatus_Finished; - break; - } - - // first update, start all the work items - case eScheduleItemState_Pending: - { - // start all of the tasks - bool bHasFailedStarts = false; - for (TWorkItems::const_iterator it = m_workItems.begin(); - it != m_workItems.end(); ++it) - { - IBackgroundScheduleItemWork* pWork = (*it); - - if (pWork->OnStart()) - { - m_processedWorkItems.push_back(pWork); - } - else - { - bHasFailedStarts = true; - break; - } - } - - if (bHasFailedStarts) - { - m_state = eScheduleItemState_Stopping; - break; - } - else - { - m_state = eScheduleItemState_Processing; - /* FALLS THROUGHT TO PROCESSING STATE */ - } - } - - // work processing state - case eScheduleItemState_Processing: - { - // process new work items that were added while the schedule was created - if (!m_addedWorkItems.empty()) - { - for (TWorkItems::const_iterator it = m_addedWorkItems.begin(); - it != m_addedWorkItems.end(); ++it) - { - IBackgroundScheduleItemWork* pWork = (*it); - pWork->OnStart(); - m_processedWorkItems.push_back(pWork); - m_workItems.push_back(pWork); - } - - m_addedWorkItems.clear(); - } - - // update work items - bool bHasFailedItems = false; - TWorkItems completedItems; - for (TWorkItems::const_iterator it = m_processedWorkItems.begin(); - it != m_processedWorkItems.end(); ++it) - { - IBackgroundScheduleItemWork* pWork = (*it); - - // update given work item - const EScheduleWorkItemStatus status = pWork->OnUpdate(); - if (status == eScheduleWorkItemStatus_Finished) - { - completedItems.push_back(pWork); - continue; - } - - // item failed - we need to stop other tasks - if (status == eScheduleWorkItemStatus_Failed) - { - bHasFailedItems = true; - break; - } - } - - // cleanup completed items - for (TWorkItems::iterator it = completedItems.begin(); - it != completedItems.end(); ++it) - { - IBackgroundScheduleItemWork* pWork = (*it); - TWorkItems::iterator jt = std::find(m_processedWorkItems.begin(), m_processedWorkItems.end(), pWork); - m_processedWorkItems.erase(jt); - } - - if (!bHasFailedItems) - { - // all work has finished - if (m_processedWorkItems.empty()) - { - retStatus = eScheduleWorkItemStatus_Finished; - m_state = eScheduleItemState_Completed; - } - - break; - } - else - { - // some of the items failed - m_state = eScheduleItemState_Stopping; - /* FALL THROUGH TO STOPPING STATE */ - } - } - - // We are stopping failed work - case eScheduleItemState_Stopping: - { - uint32 curIndex = 0; - while (curIndex < m_processedWorkItems.size()) - { - IBackgroundScheduleItemWork* pWork = m_processedWorkItems[curIndex]; - if (pWork->OnStop()) - { - // if the work was stopped remove it from list - m_processedWorkItems.erase(m_processedWorkItems.begin() + curIndex); - continue; - } - else - { - // this work item cannot be stopped this frame - curIndex += 1; - } - } - - // if all pending work has been stopped we can assume the failed state - if (m_processedWorkItems.empty()) - { - m_state = eScheduleItemState_Failed; - return eScheduleWorkItemStatus_Failed; - } - } - } - - return retStatus; - } - - //----------------------------------------------------------------------------- - - CSchedule::CSchedule(const char* szName) - : m_name(szName) - , m_refCount(1) - , m_bCanceled(false) - , m_currentItem(0) - , m_state(eScheduleState_Pending) - { - } - - CSchedule::~CSchedule() - { - CRY_ASSERT(m_refCount == 0); - - for (TItems::const_iterator it = m_items.begin(); - it != m_items.end(); ++it) - { - CScheduleItem* pItem = *it; - SAFE_RELEASE(pItem); - } - - m_items.clear(); - } - - const char* CSchedule::GetDescription() const - { - return m_name.c_str(); - } - - float CSchedule::GetProgress() const - { - if (m_currentItem >= m_items.size()) - { - return 1.0f; - } - else - { - const float itemProgress = 1.0f / (float)(m_items.size()); - const IBackgroundScheduleItem* pItem = m_items[m_currentItem]; - return (m_currentItem + pItem->GetProgress()) * itemProgress; - } - } - - IBackgroundScheduleItem* CSchedule::GetProcessedItem() const - { - if (m_currentItem >= m_items.size()) - { - return NULL; - } - else - { - IBackgroundScheduleItem* pItem = m_items[m_currentItem]; - return pItem; - } - } - - const uint32 CSchedule::GetNumItems() const - { - return m_items.size(); - } - - IBackgroundScheduleItem* CSchedule::GetItem(const uint32 index) const - { - return m_items[index]; - } - - EScheduleState CSchedule::GetState() const - { - return m_state; - } - - void CSchedule::Cancel() - { - m_bCanceled = true; - } - - bool CSchedule::IsCanceled() const - { - return m_bCanceled; - } - - void CSchedule::AddItem(IBackgroundScheduleItem* pItem) - { - if (NULL == pItem) - { - return; - } - - // we can add items only in the "pending" state - if (pItem->GetState() != eScheduleItemState_Pending) - { - CryFatalError("Schedule items can be added to schedule only before their work starts"); - return; - } - - // item has no jobs, do not add - if (pItem->GetNumWorkItems() == 0) - { - return; - } - - m_items.push_back(static_cast(pItem)); - pItem->AddRef(); - } - - void CSchedule::AddRef() - { - CryInterlockedIncrement(&m_refCount); - } - - void CSchedule::Release() - { - const int nCount = CryInterlockedDecrement(&m_refCount); - assert(nCount >= 0); - if (nCount == 0) - { - delete this; - } - else if (nCount < 0) - { - assert(0); - CryFatalError("Deleting Reference Counted Object Twice"); - } - } - - EScheduleWorkItemStatus CSchedule::Update() - { - EScheduleWorkItemStatus retStatus = eScheduleWorkItemStatus_NotFinished; - - // we have a cancel request - if (m_bCanceled) - { - CryLog("Schedule '%s' was canceled", GetDescription()); - - if (m_state == eScheduleState_Processing && m_currentItem < m_items.size()) - { - // stop the current item - CScheduleItem* pItem = m_items[m_currentItem]; - pItem->RequestStop(); - m_state = eSccheduleState_Stopping; - } - else if (m_state != eScheduleState_Completed) - { - m_state = eScheduleState_Failed; - return eScheduleWorkItemStatus_Failed; - } - } - - // process internal state machine - switch (m_state) - { - // final state - work failed - case eScheduleState_Failed: - { - retStatus = eScheduleWorkItemStatus_Failed; - break; - } - - // final state - work completed - case eScheduleState_Completed: - { - retStatus = eScheduleWorkItemStatus_Finished; - break; - } - - // stopping current task - case eSccheduleState_Stopping: - { - if (m_currentItem < m_items.size()) - { - CScheduleItem* pItem = m_items[m_currentItem]; - if (pItem->Update() != eScheduleWorkItemStatus_NotFinished) - { - // task was finally stopped - m_state = eScheduleState_Failed; - retStatus = eScheduleWorkItemStatus_Failed; - } - } - - break; - } - - // first update, switch to processing - case eScheduleState_Pending: - { - m_state = eScheduleState_Processing; - m_currentItem = 0; - /* FALLS THROUGHT */ - } - - // if we were in the processing phase inform the current schedule item to stop all it's work - case eScheduleState_Processing: - { - // update schedule items - while (m_currentItem < m_items.size()) - { - CScheduleItem* pItem = m_items[m_currentItem]; - - const EScheduleWorkItemStatus itemStatus = pItem->Update(); - if (itemStatus == eScheduleWorkItemStatus_Finished) - { - m_currentItem += 1; - continue; - } - else if (itemStatus == eScheduleWorkItemStatus_Failed) - { - m_state = eScheduleState_Failed; - retStatus = eScheduleWorkItemStatus_Failed; - gEnv->pLog->LogWarning("Schedule '%s' failed on item '%s'.", GetDescription(), pItem->GetDescription()); - } - - break; - } - - // all items updated - if (m_currentItem >= m_items.size()) - { - // empty schedule, complete in one tick - m_state = eScheduleState_Completed; - retStatus = eScheduleWorkItemStatus_Finished; - CryLog("Schedule '%s' completed", GetDescription()); - } - - break; - } - } - - return retStatus; - } - - //----------------------------------------------------------------------------- - - CScheduleManager::CScheduleManager() - { - GetIEditor()->RegisterNotifyListener(this); - } - - CScheduleManager::~CScheduleManager() - { - GetIEditor()->UnregisterNotifyListener(this); - - for (TSchedules::const_iterator it = m_schedules.begin(); - it != m_schedules.end(); ++it) - { - CSchedule* pSchedule = *it; - SAFE_RELEASE(pSchedule); - } - - m_schedules.clear(); - } - - IBackgroundSchedule* CScheduleManager::CreateSchedule(const char* szName) - { - return new CSchedule(szName); - } - - IBackgroundScheduleItem* CScheduleManager::CreateScheduleItem(const char* szName) - { - return new CScheduleItem(szName); - } - - void CScheduleManager::SubmitSchedule(IBackgroundSchedule* pSchedule) - { - if (NULL != pSchedule) - { - if (pSchedule->GetState() != eScheduleState_Pending) - { - CryFatalError("Only schedules with pending state can be submitted"); - return; - } - - pSchedule->AddRef(); - m_schedules.push_back(static_cast(pSchedule)); - } - } - - const uint32 CScheduleManager::GetNumSchedules() const - { - return m_schedules.size(); - } - - IBackgroundSchedule* CScheduleManager::GetSchedule(const uint32 index) const - { - return m_schedules[index]; - } - - void CScheduleManager::Update() - { - while (!m_schedules.empty()) - { - CSchedule* pSchedule = m_schedules[0]; - - const EScheduleWorkItemStatus status = pSchedule->Update(); - if (status == eScheduleWorkItemStatus_NotFinished) - { - // we need more work next frame - break; - } - - // schedule has finished, remove current reference - m_schedules.erase(m_schedules.begin()); - SAFE_RELEASE(pSchedule); - } - } - - void CScheduleManager::OnEditorNotifyEvent(EEditorNotifyEvent ev) - { - switch (ev) - { - case eNotify_OnQuit: - GetIEditor()->UnregisterNotifyListener(this); - break; - } - } - - //----------------------------------------------------------------------------- -} // BackgroundScheduleManager diff --git a/Code/Sandbox/Editor/BackgroundScheduleManager.h b/Code/Sandbox/Editor/BackgroundScheduleManager.h deleted file mode 100644 index 4deeaba64f..0000000000 --- a/Code/Sandbox/Editor/BackgroundScheduleManager.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITOR_BACKGROUNDSCHEDULEMANAGER_H -#define CRYINCLUDE_EDITOR_BACKGROUNDSCHEDULEMANAGER_H -#pragma once - -#include "Include/IBackgroundScheduleManager.h" - -namespace BackgroundScheduleManager -{ - class CScheduleItem - : public IBackgroundScheduleItem - { - private: - std::string m_name; - volatile int m_refCount; - - EScheduleItemState m_state; - - typedef std::vector TWorkItems; - TWorkItems m_workItems; - TWorkItems m_addedWorkItems; - TWorkItems m_processedWorkItems; - - public: - CScheduleItem(const char* szName); - virtual ~CScheduleItem(); - - // IBackgroundScheduleItem interface - virtual const char* GetDescription() const; - virtual EScheduleItemState GetState() const; - virtual const float GetProgress() const; - virtual const uint32 GetNumWorkItems() const; - virtual IBackgroundScheduleItemWork* GetWorkItem(const uint32 index) const; - virtual void AddWorkItem(IBackgroundScheduleItemWork* pWork); - virtual void AddRef(); - virtual void Release(); - - // Update schedule item - EScheduleWorkItemStatus Update(); - - // Request to stop work in this item - void RequestStop(); - }; - - class CSchedule - : public IBackgroundSchedule - { - private: - std::string m_name; - volatile int m_refCount; - bool m_bCanceled; - - EScheduleState m_state; - - typedef std::vector TItems; - TItems m_items; - - uint32 m_currentItem; - - public: - CSchedule(const char* szName); - virtual ~CSchedule(); - - // IBackgroundSchedule interface - virtual const char* GetDescription() const; - virtual float GetProgress() const; - virtual IBackgroundScheduleItem* GetProcessedItem() const; - virtual const uint32 GetNumItems() const; - virtual IBackgroundScheduleItem* GetItem(const uint32 index) const; - virtual EScheduleState GetState() const; - virtual void Cancel(); - virtual bool IsCanceled() const; - virtual void AddItem(IBackgroundScheduleItem* pItem); - virtual void AddRef(); - virtual void Release(); - - // Update schedule item - EScheduleWorkItemStatus Update(); - }; - - class CScheduleManager - : public IBackgroundScheduleManager - , public IEditorNotifyListener - { - private: - typedef std::vector TSchedules; - TSchedules m_schedules; - - public: - CScheduleManager(); - virtual ~CScheduleManager(); - - // IBackgroundScheduleManager interface - virtual IBackgroundSchedule* CreateSchedule(const char* szName); - virtual IBackgroundScheduleItem* CreateScheduleItem(const char* szName); - virtual void SubmitSchedule(IBackgroundSchedule* pSchedule); - virtual const uint32 GetNumSchedules() const; - virtual IBackgroundSchedule* GetSchedule(const uint32 index) const; - virtual void Update(); - - // IEditorNotifyListener interface implementation - virtual void OnEditorNotifyEvent(EEditorNotifyEvent ev) override; - }; -} -#endif // CRYINCLUDE_EDITOR_BACKGROUNDSCHEDULEMANAGER_H diff --git a/Code/Sandbox/Editor/BackgroundTaskManager.cpp b/Code/Sandbox/Editor/BackgroundTaskManager.cpp deleted file mode 100644 index c05e709fd0..0000000000 --- a/Code/Sandbox/Editor/BackgroundTaskManager.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "BackgroundTaskManager.h" - -namespace BackgroundTaskManager -{ - //----------------------------------------------------------------------------- - - CTaskManager::CThread::CThread(class CTaskManager* pManager, CQueue* pQueue) - : m_pManager(pManager) - , m_pQueue(pQueue) - { - start(); - } - - CTaskManager::CThread::~CThread() - { - } - - void CTaskManager::CThread::WaitForThread() - { - wait(); - } - - void CTaskManager::CThread::run() - { - CryThreadSetName(-1, "BackgroundTaskThread"); - - while (!m_pManager->IsStopped()) - { - STaskHandle taskHandle; - - // This blocks on Semaphore waiting for task from queue - m_pQueue->PopTask(taskHandle); - - // Should not happen but it's a stupid way to crash :) - if (NULL == taskHandle.pTask) - { - continue; - } - - if (taskHandle.pTask->IsCanceled()) - { - // Task was canceled before we got here - m_pManager->AddCompletedTask(taskHandle, eTaskResult_Canceled); - } - else - { - const ETaskResult state = taskHandle.pTask->Work(); - - if (state == eTaskResult_Resume) - { - // Put it back into queue, so more important task can take over. - m_pManager->AddTask(taskHandle); - } - else - { - // Finish task - m_pManager->AddCompletedTask(taskHandle, state); - } - } - } - } - - //----------------------------------------------------------------------------- - - CTaskManager::CQueue::CQueue() - : m_semaphore(INT_MAX, 0) // no good maximum value, assume worst case - { - } - - void CTaskManager::CQueue::AddTask(const STaskHandle& taskHandle) - { - { - CryAutoLock lock(m_lock); - - // TODO: use heap? - m_pendingTasks.insert(m_pendingTasks.begin(), taskHandle); - std::stable_sort(m_pendingTasks.begin(), m_pendingTasks.end()); - } - - taskHandle.pTask->SetState(eTaskState_Pending); - - // release internal semaphore so threads can pick up the work - m_semaphore.Release(); - } - - void CTaskManager::CQueue::PopTask(STaskHandle& outTaskHandle) - { - // wait for job - m_semaphore.Acquire(); - - { - CryAutoLock lock(m_lock); - - if (m_pendingTasks.empty()) - { - outTaskHandle.pTask = NULL; - } - else - { - outTaskHandle = m_pendingTasks.back(); - outTaskHandle.pTask->SetState(eTaskState_Working); - m_pendingTasks.pop_back(); - } - } - } - - void CTaskManager::CQueue::ReleaseSemaphore() - { - m_semaphore.Release(); - } - - void CTaskManager::CQueue::Clear() - { - CryAutoLock lock(m_lock); - for (uint i = 0; i < m_pendingTasks.size(); ++i) - { - m_pendingTasks[i].pTask->Release(); - } - - m_pendingTasks.clear(); - } - - //----------------------------------------------------------------------------- - - CTaskManager::CTaskManager() - : m_bStop(false) - , m_nextTaskID(1) - , m_listeners(1) - { - GetIEditor()->RegisterNotifyListener(this); - } - - CTaskManager::~CTaskManager() - { - if (!m_bStop) - { - Stop(); - } - } - - void CTaskManager::Start(const uint32 threadCount /*=kDefaultThreadCount*/) - { - m_bStop = false; - - if (m_pThreads.empty()) - { - // Always create one IO thread - { - CThread* pThread = new CThread(this, &m_pendingTasks[ eTaskThreadMask_IO ]); - m_pThreads.push_back(pThread); - } - - // We also need at least one generic thread - const uint32 numGenericThreads = max(threadCount, 1); - for (uint32 i = 0; i < numGenericThreads; ++i) - { - CThread* pThread = new CThread(this, &m_pendingTasks[ eTaskThreadMask_Any ]); - m_pThreads.push_back(pThread); - } - } - } - - void CTaskManager::StartScheduledTasks() - { - CryAutoLock lock(m_tasksLock); - - if (!m_scheduledTasks.empty()) - { - const unsigned int time = GetTickCount(); - while (!m_scheduledTasks.empty()) - { - const int delta = (int)(time - m_scheduledTasks[0].time); - if (delta > 0) - { - // the soonest task on the list is still in the future, no point in looking at the next entries in the list - break; - } - - // promote the scheduled task to be a full task - AddTask(m_scheduledTasks[0].handle); - - // We held a reference to the task on list, release it - m_scheduledTasks[0].handle.pTask->Release(); - - m_scheduledTasks.erase(m_scheduledTasks.begin()); - } - } - } - - void CTaskManager::Stop() - { - if (!m_bStop) - { - m_bStop = true; - GetIEditor()->UnregisterNotifyListener(this); - - // clear queues - no new tasks will be processed - for (uint32 i = 0; i < eTaskThreadMask_COUNT; ++i) - { - m_pendingTasks[i].Clear(); - } - - // kick all the threads to allow them to quit - for (uint32 j = 0; j < m_pThreads.size(); ++j) - { - for (uint32 i = 0; i < eTaskThreadMask_COUNT; ++i) - { - m_pendingTasks[i].ReleaseSemaphore(); - } - } - - // Stop threads - for (TWorkerThreads::iterator it = m_pThreads.begin(); - it != m_pThreads.end(); ++it) - { - (*it)->WaitForThread(); - delete *it; - } - - m_pThreads.clear(); - } - } - - void CTaskManager::AddListener(IBackgroundTaskManagerListener* pListener, const char* name) - { - m_listeners.Add(pListener, name); - } - - void CTaskManager::RemoveListener(IBackgroundTaskManagerListener* pListener) - { - m_listeners.Remove(pListener); - } - - void CTaskManager::AddTask(IBackgroundTask* pTask, ETaskPriority priority, ETaskThreadMask threadMask) - { - MAKE_SURE(pTask != 0, return ); - - // keep an extra reference to the task in the manager - pTask->AddRef(); - - STaskHandle handle; - handle.id = CryInterlockedIncrement(&m_nextTaskID); - handle.priority = priority; - handle.threadMask = threadMask; - handle.pTask = pTask; - - AddTask(handle); - - for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next()) - { - notifier->OnBackgroundTaskAdded(pTask->Description()); - } - } - - void CTaskManager::ScheduleTask(IBackgroundTask* pTask, ETaskPriority priority, int delayMilliseconds, ETaskThreadMask threadMask) - { - MAKE_SURE(delayMilliseconds >= 0, return ); - MAKE_SURE(pTask != 0, return ); - - // keep an extra reference to the task in the manager - pTask->AddRef(); - - SScheduledTask task; - task.time = GetTickCount() + delayMilliseconds; - task.handle.pTask = pTask; - task.handle.id = CryInterlockedIncrement(&m_nextTaskID); - task.handle.threadMask = threadMask; - task.handle.priority = priority; - - { - CryAutoLock lock(m_tasksLock); - m_scheduledTasks.push_back(task); - } - - for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next()) - { - notifier->OnBackgroundTaskAdded(pTask->Description()); - } - } - - void CTaskManager::AddTask(const STaskHandle& handle) - { - MAKE_SURE(handle.pTask != 0, return ); - MAKE_SURE(handle.id != 0, return ); - - // add task to appropriate queue (every thread mask has it's own queue) - m_pendingTasks[handle.threadMask].AddTask(handle); - } - - void CTaskManager::AddCompletedTask(const STaskHandle& handle, ETaskResult resultState) - { - CryAutoLock lock(m_tasksLock); - - CRY_ASSERT(handle.pTask->GetState() == eTaskState_Working); - CRY_ASSERT(resultState != eTaskResult_Resume); - - // Update task state - switch (resultState) - { - case eTaskResult_Canceled: - { - handle.pTask->SetState(eTaskState_Canceled); - break; - } - - case eTaskResult_Completed: - { - handle.pTask->SetState(eTaskState_Completed); - break; - } - - case eTaskResult_Failed: - { - handle.pTask->SetState(eTaskState_Failed); - break; - } - } - - // add to the list of completed tasks (for calling the Finalize) - // TODO: some of the tasks do not require Finalize() and they could be released here instead of the main thread - SCompletedTask info; - info.pTask = handle.pTask; - info.id = handle.id; - info.state = resultState; - m_completedTasks.push_back(info); - } - - void CTaskManager::Update() - { - std::vector completedTasks; - { - CryAutoLock lock(m_tasksLock); - m_completedTasks.swap(completedTasks); - } - - // call finalize for the completed tasks - for (size_t i = 0; i < completedTasks.size(); ++i) - { - SCompletedTask& handle = completedTasks[i]; - - if (NULL != handle.pTask) - { - string description = handle.pTask->Description(); // copy string as the description is used after pTask is destroyed - - if (handle.state == eTaskResult_Completed) - { - if (description && description[0] != '\0') - { - gEnv->pLog->Log("Task Completed: %s", description.c_str()); - } - } - else if (handle.state == eTaskResult_Failed) - { - if (description && description[0] != '\0' && !handle.pTask->FailReported()) - { - gEnv->pLog->LogError("Task Failed: %s ", description.c_str()); - - const char* errorMessage = handle.pTask->ErrorMessage(); - if (errorMessage && errorMessage[0] != '\0') - { - gEnv->pLog->LogError("\tReason: [%s]", errorMessage); - } - } - } - - handle.pTask->Finalize(); - - // release the internal (task manager) reference. - // Tthis is usually the last reference to the task so it gets deleted here. - handle.pTask->Release(); - - for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next()) - { - notifier->OnBackgroundTaskCompleted(handle.state, description.c_str()); - } - } - } - } - - void CTaskManager::OnEditorNotifyEvent(EEditorNotifyEvent ev) - { - switch (ev) - { - case eNotify_OnInit: - Start(); - break; - case eNotify_OnIdleUpdate: - Update(); - break; - case eNotify_OnQuit: - Stop(); - break; - } - } -} diff --git a/Code/Sandbox/Editor/BackgroundTaskManager.h b/Code/Sandbox/Editor/BackgroundTaskManager.h deleted file mode 100644 index b440c66f1a..0000000000 --- a/Code/Sandbox/Editor/BackgroundTaskManager.h +++ /dev/null @@ -1,161 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_EDITOR_BACKGROUNDTASKMANAGER_H -#define CRYINCLUDE_EDITOR_BACKGROUNDTASKMANAGER_H -#pragma once - -#include "Include/IBackgroundTaskManager.h" -#include "CryListenerSet.h" - -#include - -namespace BackgroundTaskManager -{ - typedef int TTaskID; - - struct STaskHandle - { - ETaskPriority priority; - ETaskThreadMask threadMask; - TTaskID id; - IBackgroundTask* pTask; - - bool operator<(const STaskHandle& rhs) const - { - if (priority < rhs.priority) - { - return true; - } - if (priority > rhs.priority) - { - return false; - } - return id < rhs.id; - } - }; - - struct SCompletedTask - { - ETaskResult state; - TTaskID id; - ETaskThreadMask threadMask; - IBackgroundTask* pTask; - }; - - struct SScheduledTask - { - unsigned int time; - STaskHandle handle; - }; - - class CTaskManager - : public IBackgroundTaskManager - , public IEditorNotifyListener - { - public: - CTaskManager(); - ~CTaskManager(); - - // IBackgroundTaskManager interface implementation - virtual void AddTask(IBackgroundTask* pTask, ETaskPriority priority, ETaskThreadMask threadMask) override; - virtual void ScheduleTask(IBackgroundTask* pTask, ETaskPriority priority, int delayMilliseconds, ETaskThreadMask threadMask) override; - void AddListener(IBackgroundTaskManagerListener* pListener, const char* name) override; - void RemoveListener(IBackgroundTaskManagerListener* pListener) override; - - private: - // IEditorNotifyListener interface implementation - virtual void OnEditorNotifyEvent(EEditorNotifyEvent ev) override; - - void Start(const uint32 threadCount = kDefaultThreadCount); - void Stop(); - void StartScheduledTasks(); - void AddTask(const STaskHandle& outTask); - void AddCompletedTask(const STaskHandle& outTask, ETaskResult resultState); - void Update(); - - inline bool IsStopped() const - { - return m_bStop; - } - - private: - // Internal queue (per thread mask) - class CQueue - { - public: - CQueue(); - - // Add task to list - void AddTask(const STaskHandle& taskHandle); - - // Pop task from list - void PopTask(STaskHandle& outTaskHandle); - - // Release thread semaphore without adding a task - void ReleaseSemaphore(); - - // Remove all pending tasks - void Clear(); - - private: - CrySemaphore m_semaphore; - std::vector m_pendingTasks; - CryMutex m_lock; - }; - - // Worker thread class implementation - class CThread : public QThread - { - public: - CThread(CTaskManager* pManager, CQueue* pQueue); - ~CThread(); - - void WaitForThread(); - - private: - void run() override; - - private: - CTaskManager* m_pManager; - CQueue* m_pQueue; - }; - - private: - static const uint32 kMaxThreadCloseWaitTime = 10000; // ms - static const uint32 kDefaultThreadCount = 4; // good enough for LiveCreate (main user right now), do not set to less than 2 - - CQueue m_pendingTasks[ eTaskThreadMask_COUNT ]; - - // Task scheduled for execution in the future - std::vector m_scheduledTasks; - - // Completed tasks (waiting for the "finalize" call) - std::vector m_completedTasks; - - volatile TTaskID m_nextTaskID; - - typedef std::vector TWorkerThreads; - TWorkerThreads m_pThreads; - - CryMutex m_tasksLock; - bool m_bStop; - - typedef CListenerSet TListeners; - TListeners m_listeners; - }; -} - -//----------------------------------------------------------------------------- - -#endif // CRYINCLUDE_EDITOR_BACKGROUNDTASKMANAGER_H diff --git a/Code/Sandbox/Editor/CMakeLists.txt b/Code/Sandbox/Editor/CMakeLists.txt index 726f7ac2c7..7d89717391 100644 --- a/Code/Sandbox/Editor/CMakeLists.txt +++ b/Code/Sandbox/Editor/CMakeLists.txt @@ -112,7 +112,6 @@ ly_add_target( 3rdParty::zlib 3rdParty::AWSNativeSDK::STS Legacy::CryCommon - Legacy::CryCommon.EngineSettings.Static Legacy::EditorCommon AZ::AzCore AZ::AzToolsFramework diff --git a/Code/Sandbox/Editor/CryEdit.cpp b/Code/Sandbox/Editor/CryEdit.cpp index 6e33d32c6e..0bbc48d5f9 100644 --- a/Code/Sandbox/Editor/CryEdit.cpp +++ b/Code/Sandbox/Editor/CryEdit.cpp @@ -85,7 +85,6 @@ AZ_POP_DISABLE_WARNING // Editor #include "Settings.h" -#include "Include/IBackgroundScheduleManager.h" #include "GameExporter.h" #include "GameResourcesExporter.h" @@ -2314,15 +2313,6 @@ int CCryEditApp::IdleProcessing(bool bBackgroundUpdate) #endif } - // process the work schedule - regardless if the app is active or not - GetIEditor()->GetBackgroundScheduleManager()->Update(); - - // if there are active schedules keep updating the application - if (GetIEditor()->GetBackgroundScheduleManager()->GetNumSchedules() > 0) - { - bActive = true; - } - m_bPrevActive = bActive; AZStd::chrono::system_clock::time_point now = AZStd::chrono::system_clock::now(); diff --git a/Code/Sandbox/Editor/GameEngine.cpp b/Code/Sandbox/Editor/GameEngine.cpp index 1c91ce58aa..2112d00d64 100644 --- a/Code/Sandbox/Editor/GameEngine.cpp +++ b/Code/Sandbox/Editor/GameEngine.cpp @@ -420,7 +420,6 @@ AZ::Outcome CGameEngine::Init( #else sip.hWnd = hwndForInputSystem; #endif - sip.hWndForInputSystem = hwndForInputSystem; sip.pLogCallback = &m_logFile; sip.sLogFileName = "@log@/Editor.log"; @@ -503,7 +502,6 @@ AZ::Outcome CGameEngine::Init( bool CGameEngine::InitGame(const char*) { - // in editor we do it later, bExecuteCommandLine was set to false m_pISystem->ExecuteCommandLine(); return true; @@ -608,8 +606,6 @@ void CGameEngine::SwitchToInGame() GetIEditor()->Notify(eNotify_OnBeginGameMode); - m_pISystem->SetThreadState(ESubsys_Physics, false); - m_pISystem->GetIMovieSystem()->EnablePhysicsEvents(true); m_bInGameMode = true; @@ -646,8 +642,6 @@ void CGameEngine::SwitchToInEditor() } m_pISystem->GetIMovieSystem()->Reset(false, false); - m_pISystem->SetThreadState(ESubsys_Physics, false); - CViewport* pGameViewport = GetIEditor()->GetViewManager()->GetGameViewport(); m_pISystem->GetIMovieSystem()->EnablePhysicsEvents(m_bSimulationMode); @@ -791,8 +785,6 @@ void CGameEngine::SetSimulationMode(bool enabled, bool bOnlyPhysics) // Enables engine to know about simulation mode. gEnv->SetIsEditorSimulationMode(enabled); - m_pISystem->SetThreadState(ESubsys_Physics, false); - if (m_bSimulationMode) { // [Anton] the order of the next 3 calls changed, since, EVENT_INGAME loads physics state (if any), @@ -903,19 +895,6 @@ void CGameEngine::Update() // [marco] check current sound and vis areas for music etc. // but if in game mode, 'cos is already done in the above call to game->update() unsigned int updateFlags = ESYSUPDATE_EDITOR; - - if (!m_bSimulationMode) - { - updateFlags |= ESYSUPDATE_IGNORE_PHYSICS; - } - - bool bUpdateAIPhysics = GetSimulationMode(); - - if (bUpdateAIPhysics) - { - updateFlags |= ESYSUPDATE_EDITOR_AI_PHYSICS; - } - GetIEditor()->GetAnimation()->Update(); GetIEditor()->GetSystem()->UpdatePreTickBus(updateFlags); componentApplication->Tick(gEnv->pTimer->GetFrameTime(ITimer::ETIMER_GAME)); diff --git a/Code/Sandbox/Editor/IEditor.h b/Code/Sandbox/Editor/IEditor.h index 62672a6505..af98158037 100644 --- a/Code/Sandbox/Editor/IEditor.h +++ b/Code/Sandbox/Editor/IEditor.h @@ -550,7 +550,6 @@ struct IEditor virtual class CViewManager* GetViewManager() = 0; virtual class CViewport* GetActiveView() = 0; virtual void SetActiveView(CViewport* viewport) = 0; - virtual struct IBackgroundTaskManager* GetBackgroundTaskManager() = 0; virtual struct IEditorFileMonitor* GetFileMonitor() = 0; // These are needed for Qt integration: @@ -720,7 +719,6 @@ struct IEditor virtual ESystemConfigPlatform GetEditorConfigPlatform() const = 0; virtual void ReloadTemplates() = 0; virtual IResourceSelectorHost* GetResourceSelectorHost() = 0; - virtual struct IBackgroundScheduleManager* GetBackgroundScheduleManager() = 0; virtual void ShowStatusText(bool bEnable) = 0; // Provides a way to extend the context menu of an object. The function gets called every time the menu is opened. diff --git a/Code/Sandbox/Editor/IEditorImpl.cpp b/Code/Sandbox/Editor/IEditorImpl.cpp index fb9b737733..380fc80e66 100644 --- a/Code/Sandbox/Editor/IEditorImpl.cpp +++ b/Code/Sandbox/Editor/IEditorImpl.cpp @@ -66,8 +66,6 @@ AZ_POP_DISABLE_WARNING #include "Objects/SelectionGroup.h" #include "Objects/ObjectManager.h" -#include "BackgroundTaskManager.h" -#include "BackgroundScheduleManager.h" #include "EditorFileMonitor.h" #include "MainStatusBar.h" @@ -176,8 +174,6 @@ CEditorImpl::CEditorImpl() regCtx.pCommandManager = m_pCommandManager; regCtx.pClassFactory = m_pClassFactory; m_pEditorFileMonitor.reset(new CEditorFileMonitor()); - m_pBackgroundTaskManager.reset(new BackgroundTaskManager::CTaskManager); - m_pBackgroundScheduleManager.reset(new BackgroundScheduleManager::CScheduleManager); m_pUIEnumsDatabase = new CUIEnumsDatabase; m_pDisplaySettings = new CDisplaySettings; m_pDisplaySettings->LoadRegistry(); @@ -843,16 +839,6 @@ IIconManager* CEditorImpl::GetIconManager() return m_pIconManager; } -IBackgroundTaskManager* CEditorImpl::GetBackgroundTaskManager() -{ - return m_pBackgroundTaskManager.get(); -} - -IBackgroundScheduleManager* CEditorImpl::GetBackgroundScheduleManager() -{ - return m_pBackgroundScheduleManager.get(); -} - IEditorFileMonitor* CEditorImpl::GetFileMonitor() { return m_pEditorFileMonitor.get(); diff --git a/Code/Sandbox/Editor/IEditorImpl.h b/Code/Sandbox/Editor/IEditorImpl.h index 7ad97d79e5..0ebd02b5fd 100644 --- a/Code/Sandbox/Editor/IEditorImpl.h +++ b/Code/Sandbox/Editor/IEditorImpl.h @@ -43,15 +43,12 @@ class CGameEngine; class CExportManager; class CErrorsDlg; class CIconManager; -class CBackgroundTaskManager; class CTrackViewSequenceManager; class CEditorFileMonitor; class AzAssetWindow; class AzAssetBrowserRequestHandler; class AssetEditorRequestsHandler; class CAlembicCompiler; -struct IBackgroundTaskManager; -struct IBackgroundScheduleManager; struct IEditorFileMonitor; class CVegetationMap; @@ -61,16 +58,6 @@ namespace Editor class EditorQtApplication; } -namespace BackgroundScheduleManager -{ - class CScheduleManager; -} - -namespace BackgroundTaskManager -{ - class CTaskManager; -} - namespace WinWidget { class WinWidgetManager; @@ -179,8 +166,6 @@ public: IDataBaseManager* GetDBItemManager(EDataBaseItemType itemType); CMusicManager* GetMusicManager() { return m_pMusicManager; }; - IBackgroundTaskManager* GetBackgroundTaskManager() override; - IBackgroundScheduleManager* GetBackgroundScheduleManager() override; IEditorFileMonitor* GetFileMonitor() override; void RegisterEventLoopHook(IEventLoopHook* pHook) override; void UnregisterEventLoopHook(IEventLoopHook* pHook) override; @@ -394,8 +379,6 @@ protected: //! Export manager for exporting objects and a terrain from the game to DCC tools CExportManager* m_pExportManager; - std::unique_ptr m_pBackgroundTaskManager; - std::unique_ptr m_pBackgroundScheduleManager; std::unique_ptr m_pEditorFileMonitor; std::unique_ptr m_pResourceSelectorHost; QString m_selectFileBuffer; diff --git a/Code/Sandbox/Editor/Include/IBackgroundScheduleManager.h b/Code/Sandbox/Editor/Include/IBackgroundScheduleManager.h deleted file mode 100644 index bfa9eb6333..0000000000 --- a/Code/Sandbox/Editor/Include/IBackgroundScheduleManager.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// -// IBackgroundScheduleManager manages schedule of group of larger operations that should be run in sequence -// -// Schedules are derived from IBackgroundSchedule and consist of a list of IBackgroundScheduleItems. -// Each schedule item is executed IN ORDER for the previous item to complete first. -// Each IBackgroundScheduleItems consists of list of user defined work via IBackgroundScheduleItemsWork classes. -// Each schedule item work is executed IN PARALEL (they are all started when the item starts). -// -// Whenever a work item fails to complete the other work items are stopped, the schedule item is marked as "failed" -// and so is the whole schedule. -// -// All logic is performed on the main thread although schedule items are free to use threads. -// It is recommended to use IBackgroundTaskManager for dispatching a task list for every schedule work item. -// -// All objects in the schedule system are reference counted. -// - -// State of the whole schedule - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDSCHEDULEMANAGER_H -#define CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDSCHEDULEMANAGER_H -#pragma once -enum EScheduleState -{ - // Item has not started yet but is on the list - eScheduleState_Pending, - - // We are processing this item - eScheduleState_Processing, - - // We are stopping the schedule - eSccheduleState_Stopping, - - // Schedule item has failed - eScheduleState_Failed, - - // Schedule item was canceled - eScheduleState_Canceled, - - // Schedule item has completed it's work - eScheduleState_Completed, -}; - -// State of the single schedule item -enum EScheduleItemState -{ - // Item has not started yet but is on the list - eScheduleItemState_Pending, - - // We are processing this item - eScheduleItemState_Processing, - - // We are stopping this item - eScheduleItemState_Stopping, - - // Schedule item has failed - eScheduleItemState_Failed, - - // Schedule item has completed it's work - eScheduleItemState_Completed, -}; - -// Work item status -enum EScheduleWorkItemStatus -{ - // Work is still not finished - eScheduleWorkItemStatus_NotFinished, - - // Work has failed - eScheduleWorkItemStatus_Failed, - - // Work has finished - eScheduleWorkItemStatus_Finished, -}; - -struct IBackgroundScheduleItemWork -{ - // Get human readable description - virtual const char* GetDescription() const = 0; - - // Get work item progress - virtual float GetProgress() const = 0; - - // Called when the schedule item containing this work piece has started - // If the work cannot be started for any reason return false. - virtual bool OnStart() = 0; - - // Called when the schedule item containing this work piece has been canceled or failed externally - // Not called when schedule item completed without errors. - // If the work cannot be stopped this frame return false. - virtual bool OnStop() = 0; - - // Called every frame to advance and check the work state - // Should return one of the EBackgroundScheduleWorkItemStatus value - virtual EScheduleWorkItemStatus OnUpdate() = 0; - - // Reference counting - virtual void AddRef() = 0; - virtual void Release() = 0; - -protected: - virtual ~IBackgroundScheduleItemWork() {}; -}; - -struct IBackgroundScheduleItem -{ - // Get name of the schedule (debug & display) - virtual const char* GetDescription() const = 0; - - // Get interal state - virtual EScheduleItemState GetState() const = 0; - - // Get overall progress of this schedule item - virtual const float GetProgress() const = 0; - - // Get number of work items in this schedule item - virtual const uint32 GetNumWorkItems() const = 0; - - // Get n-th work item from the schedule item - virtual IBackgroundScheduleItemWork* GetWorkItem(const uint32 index) const = 0; - - // Add work item to the schedule item - virtual void AddWorkItem(IBackgroundScheduleItemWork* pWork) = 0; - - // Reference counting - virtual void AddRef() = 0; - virtual void Release() = 0; - -protected: - virtual ~IBackgroundScheduleItem() {}; -}; - -struct IBackgroundSchedule -{ - // Get name of the schedule (debug & display) - virtual const char* GetDescription() const = 0; - - // Get overall progress of the whole schedule - virtual float GetProgress() const = 0; - - // Get item being currently processed - virtual IBackgroundScheduleItem* GetProcessedItem() const = 0; - - // Get number of items in the schedule - virtual const uint32 GetNumItems() const = 0; - - // Get single schedule item - virtual IBackgroundScheduleItem* GetItem(const uint32 index) const = 0; - - // Get schedule item - virtual EScheduleState GetState() const = 0; - - // Cancel the whole schedule - virtual void Cancel() = 0; - - // Is the schedule canceled ? - virtual bool IsCanceled() const = 0; - - // Add schedule item at the end of the list - virtual void AddItem(IBackgroundScheduleItem* pItem) = 0; - - // Reference counting - virtual void AddRef() = 0; - virtual void Release() = 0; - -protected: - virtual ~IBackgroundSchedule() {}; -}; - -struct IBackgroundScheduleManager -{ - virtual ~IBackgroundScheduleManager() {}; - - // Create empty schedule - virtual IBackgroundSchedule* CreateSchedule(const char* szName) = 0; - - // Create empty schedule item - virtual IBackgroundScheduleItem* CreateScheduleItem(const char* szName) = 0; - - // Issue a schedule to the list (will start processing it) - virtual void SubmitSchedule(IBackgroundSchedule* pSchedule) = 0; - - // Get number of schedules on the list - virtual const uint32 GetNumSchedules() const = 0; - - // Get n-th schedule - virtual IBackgroundSchedule* GetSchedule(const uint32 index) const = 0; - - // Advance work on the schedules - virtual void Update() = 0; -}; - - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDSCHEDULEMANAGER_H diff --git a/Code/Sandbox/Editor/Include/IBackgroundTaskManager.h b/Code/Sandbox/Editor/Include/IBackgroundTaskManager.h deleted file mode 100644 index b586e3022f..0000000000 --- a/Code/Sandbox/Editor/Include/IBackgroundTaskManager.h +++ /dev/null @@ -1,230 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// -// IBackgroundTaskManager runs background tasks in worker thread. -// -// Tasks are derived from IBackgroundTask. Each task is split in two parts for: -// Work - done in background thread. -// Finalize - called afterward in main thread to apply results. -// -// Task objects are reference counted. Task manager will hold its own reference to the task object -// for as long as the task is pending or being executed. If you want to keep the task object around -// in your code you will have to call AddRef() and Release() on the task object by yourself so there -// will be an extra reference to the task object held by your code. -// -// Work returns the state of the task. Task can be resumed, then the Work -// method will be called again. Other tasks can work between calls to Work. -// It is possible to Cancel task. Work method is not invoked any more for -// Canceled tasks. -// - -#ifndef CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDTASKMANAGER_H -#define CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDTASKMANAGER_H -#pragma once - -enum ETaskPriority -{ - eTaskPriority_FileUpdateFinal, - eTaskPriority_BackgroundScan, - eTaskPriority_FileUpdate, - eTaskPriority_RealtimePreview -}; - -// Result code returned by task Work() function -enum ETaskResult -{ - // Task has not yet completed, add it back to the task queue with the same parameters (priority and thread mask) - eTaskResult_Resume, - - // Task has completed without errors (it's assumed that the result the task was supposed to achieve was achieved) - eTaskResult_Completed, - - // Task was canceled - eTaskResult_Canceled, - - // Task has failed to complete it's work - eTaskResult_Failed, -}; - -// Internal task tracking state -enum ETaskState -{ - // Task was just created. - eTaskState_Created, - - // Task was scheduled to be executed in the future. - eTaskState_Scheduled, - - // Task was added to the task queue and is waiting for it's time to be executed. - eTaskState_Pending, - - // Task is being processed right now. - eTaskState_Working, - - // Task was canceled before it has finished (indication that TaskManager has seen the Cancel() call). - eTaskState_Canceled, - - // Task Work() function was called but it ended with an error code. - eTaskState_Failed, - - // Task has completed it's Work() function without errors. - eTaskState_Completed, -}; - -// Thread mask controls which on which threads given task can be executed. -enum ETaskThreadMask -{ - // Task can run only on the IO thread (default) - // There is only one IO thread so all task with this flag are run in a sequence. - eTaskThreadMask_IO, - - // Task can run on any thread (concurrent tasks allowed) - // There can be many threads with this mask so there's no limit on the concurrent task count. - eTaskThreadMask_Any, - - eTaskThreadMask_COUNT, -}; - -struct IBackgroundTask -{ -public: - IBackgroundTask() - : m_bCanceled(false) - , m_state(eTaskState_Created) - , m_progress(-1.0f) - , m_refCount(0) - , m_bFailReported(false) - {} - - void Cancel() - { - m_bCanceled = true; - } - - bool IsCanceled() const - { - return m_bCanceled; - } - - bool HasFinished() const - { - return (m_state == eTaskState_Canceled) || - (m_state == eTaskState_Completed) || - (m_state == eTaskState_Failed); - } - - bool HasFinishedWithoutError() const - { - return (m_state == eTaskState_Completed); - } - - ETaskState GetState() const - { - return m_state; - } - - void SetState(ETaskState state) - { - m_state = state; - } - - float GetProgress() const - { - return m_progress; - } - - int AddRef() - { - return CryInterlockedIncrement(&m_refCount); - } - - int Release() - { - const int nCount = CryInterlockedDecrement(&m_refCount); - assert(nCount >= 0); - if (nCount == 0) - { - Delete(); - } - else if (nCount < 0) - { - assert(0); - CryFatalError("Deleting Reference Counted Object Twice"); - } - return nCount; - } - - bool FailReported() const{ return m_bFailReported; } - - // Get the user readable description (name) of this task, used for logging - virtual const char* Description() const { return ""; } - - // Get the user readable error message (in case when the task fails), used for logging the errors - virtual const char* ErrorMessage() const { return ""; } - - // Called from main thread after task is completed just before the task gets destroyed - virtual void Finalize() {} - - // Since there's a possibility that task object were created using different allocator - // we need a way to delete the task object once we are done with it - virtual void Delete() = 0; - - // Invoked from worker thread, actual work is done here - virtual ETaskResult Work() = 0; - -protected: - void SetProgress(float progress) { m_progress = progress; } - void SetFailReported() { m_bFailReported = true; } - - // destructor is hidden to indicate that we should use Release() method - virtual ~IBackgroundTask() {} - -private: - volatile int m_refCount; - ETaskState m_state; - float m_progress; - bool m_bCanceled; - bool m_bFailReported; -}; - -struct IBackgroundTaskManagerListener -{ - virtual ~IBackgroundTaskManagerListener() {} - - virtual void OnBackgroundTaskAdded(const char* description) = 0; - virtual void OnBackgroundTaskCompleted(ETaskResult taskResult, const char* description) = 0; -}; - -struct IBackgroundTaskManager -{ - enum - { - BACKGROUND_TASK_ID_INVALID = 0 - }; - - virtual ~IBackgroundTaskManager() {} - - // Add task to the queue with given priority and thread mask - virtual void AddTask(IBackgroundTask* pTask, ETaskPriority priority, ETaskThreadMask threadMask) = 0; - - // Schedule task to be executed in the future - virtual void ScheduleTask(IBackgroundTask* pTask, ETaskPriority priority, int delayMilliseconds, ETaskThreadMask threadMask) = 0; - - virtual void AddListener(IBackgroundTaskManagerListener* pListener, const char* name) = 0; - - virtual void RemoveListener(IBackgroundTaskManagerListener* pListener) = 0; -}; - - -#endif // CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDTASKMANAGER_H diff --git a/Code/Sandbox/Editor/LevelInfo.cpp b/Code/Sandbox/Editor/LevelInfo.cpp index 81441a3797..55c432094a 100644 --- a/Code/Sandbox/Editor/LevelInfo.cpp +++ b/Code/Sandbox/Editor/LevelInfo.cpp @@ -97,10 +97,6 @@ void CLevelInfo::ValidateObjects() pObject->Validate(m_pReport); - CUsedResources rs; - pObject->GatherUsedResources(rs); - rs.Validate(m_pReport); - m_pReport->SetCurrentValidatorObject(NULL); } diff --git a/Code/Sandbox/Editor/Lib/Tests/IEditorMock.h b/Code/Sandbox/Editor/Lib/Tests/IEditorMock.h index 38a35e6684..949bc72e03 100644 --- a/Code/Sandbox/Editor/Lib/Tests/IEditorMock.h +++ b/Code/Sandbox/Editor/Lib/Tests/IEditorMock.h @@ -102,7 +102,6 @@ public: MOCK_METHOD0(GetViewManager, class CViewManager* ()); MOCK_METHOD0(GetActiveView, class CViewport* ()); MOCK_METHOD1(SetActiveView, void(CViewport*)); - MOCK_METHOD0(GetBackgroundTaskManager, struct IBackgroundTaskManager* ()); MOCK_METHOD0(GetFileMonitor, struct IEditorFileMonitor* ()); MOCK_METHOD1(RegisterEventLoopHook, void(IEventLoopHook* )); MOCK_METHOD1(UnregisterEventLoopHook, void(IEventLoopHook* )); @@ -184,7 +183,6 @@ public: MOCK_CONST_METHOD0(GetEditorConfigPlatform, ESystemConfigPlatform()); MOCK_METHOD0(ReloadTemplates, void()); MOCK_METHOD0(GetResourceSelectorHost, IResourceSelectorHost* ()); - MOCK_METHOD0(GetBackgroundScheduleManager, struct IBackgroundScheduleManager* ()); MOCK_METHOD1(ShowStatusText, void(bool )); MOCK_METHOD1(RegisterObjectContextMenuExtension, void(TContextMenuExtensionFunc )); MOCK_METHOD0(GetEnv, SSystemGlobalEnvironment* ()); diff --git a/Code/Sandbox/Editor/MainStatusBarItems.h b/Code/Sandbox/Editor/MainStatusBarItems.h index 3f43f1818f..095183363f 100644 --- a/Code/Sandbox/Editor/MainStatusBarItems.h +++ b/Code/Sandbox/Editor/MainStatusBarItems.h @@ -13,7 +13,6 @@ #pragma once #include -#include #include #include #include diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index e9b27ee9b8..6f6b600a84 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -92,7 +92,6 @@ AZ_POP_DISABLE_WARNING #include "ErrorReportDialog.h" #include "Dialogs/PythonScriptsDialog.h" -#include "EngineSettingsManager.h" #include "AzAssetBrowser/AzAssetBrowserWindow.h" #include "AssetEditor/AssetEditorWindow.h" @@ -1941,12 +1940,6 @@ void MainWindow::ConnectivityStateChanged(const AzToolsFramework::SourceControlS } } -#if defined(CRY_ENABLE_RC_HELPER) - CEngineSettingsManager settingsManager; - settingsManager.SetModuleSpecificBoolEntry("RC_EnableSourceControl", connected); - settingsManager.StoreData(); -#endif - gSettings.enableSourceControl = connected; gSettings.SaveEnableSourceControlFlag(false); } diff --git a/Code/Sandbox/Editor/Objects/EntityObject.h b/Code/Sandbox/Editor/Objects/EntityObject.h index 85368f7804..b367384f08 100644 --- a/Code/Sandbox/Editor/Objects/EntityObject.h +++ b/Code/Sandbox/Editor/Objects/EntityObject.h @@ -35,7 +35,6 @@ class CEntityObject; class QMenu; -class IOpticsElementBase; /*! * CEntityEventTarget is an Entity event target and type. diff --git a/Code/Sandbox/Editor/UsedResources.cpp b/Code/Sandbox/Editor/UsedResources.cpp index 35384b0f34..013d35d4a7 100644 --- a/Code/Sandbox/Editor/UsedResources.cpp +++ b/Code/Sandbox/Editor/UsedResources.cpp @@ -27,38 +27,3 @@ void CUsedResources::Add(const char* pResourceFileName) files.insert(pResourceFileName); } } - -void CUsedResources::Validate(IErrorReport* pReport) -{ - auto pPak = gEnv->pCryPak; - - for (TResourceFiles::iterator it = files.begin(); it != files.end(); ++it) - { - const QString& filename = *it; - - bool fileExists = pPak->IsFileExist(filename.toUtf8().data()); - - if (!fileExists) - { - for (int i = 0; !fileExists && i < IResourceCompilerHelper::GetNumEngineImageFormats(); ++i) - { - fileExists = gEnv->pCryPak->IsFileExist(PathUtil::ReplaceExtension(filename.toUtf8().data(), IResourceCompilerHelper::GetEngineImageFormat(i, true)).c_str()); - } - for (int i = 0; !fileExists && i < IResourceCompilerHelper::GetNumSourceImageFormats(); ++i) - { - fileExists = gEnv->pCryPak->IsFileExist(PathUtil::ReplaceExtension(filename.toUtf8().data(), IResourceCompilerHelper::GetSourceImageFormat(i, true)).c_str()); - } - } - - - if (!fileExists) - { - CErrorRecord err; - - err.error = QObject::tr("Resource File %1 not found,").arg(filename); - err.severity = CErrorRecord::ESEVERITY_ERROR; - err.flags |= CErrorRecord::FLAG_NOFILE; - pReport->ReportError(err); - } - } -} diff --git a/Code/Sandbox/Editor/UsedResources.h b/Code/Sandbox/Editor/UsedResources.h index e22c672d30..acf8b79783 100644 --- a/Code/Sandbox/Editor/UsedResources.h +++ b/Code/Sandbox/Editor/UsedResources.h @@ -36,8 +36,6 @@ public: CUsedResources(); void Add(const char* pResourceFileName); - //! validate gathered resources, reports warning if resource is not found - void Validate(struct IErrorReport* pReport); AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING TResourceFiles files; diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index 3d6112d186..401b7c6e39 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -280,8 +280,6 @@ set(FILES Include/IAnimationCompressionManager.h Include/IAssetItem.h Include/IAssetItemDatabase.h - Include/IBackgroundScheduleManager.h - Include/IBackgroundTaskManager.h Include/ICommandManager.h Include/IConsoleConnectivity.h Include/IDataBaseItem.h @@ -343,10 +341,6 @@ set(FILES AssetEditor/AssetEditorWindow.cpp AssetEditor/AssetEditorWindow.h AssetEditor/AssetEditorWindow.ui - BackgroundTaskManager.cpp - BackgroundScheduleManager.cpp - BackgroundTaskManager.h - BackgroundScheduleManager.h Commands/CommandManager.cpp Commands/CommandManager.h Controls/BitmapToolTip.cpp diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index 33d4b5baf4..f38b295128 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -160,7 +160,6 @@ void SandboxIntegrationManager::Setup() AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusConnect(); AzFramework::DisplayContextRequestBus::Handler::BusConnect(); - SetupFileExtensionMap(); MainWindow::instance()->GetActionManager()->RegisterActionHandler(ID_FILE_SAVE_SLICE_TO_ROOT, [this]() { SaveSlice(false); @@ -1926,30 +1925,6 @@ void SandboxIntegrationManager::MakeSliceFromEntities(const AzToolsFramework::En AzToolsFramework::SliceUtilities::MakeNewSlice(entitiesAndDescendants, path, inheritSlices, setAsDynamic); } -void SandboxIntegrationManager::SetupFileExtensionMap() -{ - // There's no central registry for geometry file types. - const char* geometryFileExtensions[] = - { - CRY_GEOMETRY_FILE_EXT, // .cgf - CRY_SKEL_FILE_EXT, // .chr - CRY_CHARACTER_DEFINITION_FILE_EXT, // .cdf - }; - - // Cry geometry file extensions. - for (const char* extension : geometryFileExtensions) - { - m_extensionToFileType[AZ::Crc32(extension)] = IFileUtil::EFILE_TYPE_GEOMETRY; - } - - // Cry image file extensions. - for (size_t i = 0; i < IResourceCompilerHelper::GetNumSourceImageFormats(); ++i) - { - const char* extension = IResourceCompilerHelper::GetSourceImageFormat(i, false); - m_extensionToFileType[AZ::Crc32(extension)] = IFileUtil::EFILE_TYPE_TEXTURE; - } -} - void SandboxIntegrationManager::RegisterViewPane(const char* name, const char* category, const AzToolsFramework::ViewPaneOptions& viewOptions, const WidgetCreationFunc& widgetCreationFunc) { QtViewPaneManager::instance()->RegisterPane(name, category, widgetCreationFunc, viewOptions); diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h index b3c60bca45..14f52591a4 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h @@ -319,12 +319,10 @@ private: void OnLayerComponentDeactivated(AZ::EntityId entityId) override; private: - void SetupFileExtensionMap(); // Right click context menu when a layer is included in the selection. void SetupLayerContextMenu(QMenu* menu); void SetupSliceContextMenu(QMenu* menu); void SetupSliceContextMenu_Modify(QMenu* menu, const AzToolsFramework::EntityIdList& selectedEntities, const AZ::u32 numEntitiesInSlices); - void SetupScriptCanvasContextMenu(QMenu* menu); void SaveSlice(const bool& QuickPushToFirstLevel); void GetEntitiesInSlices(const AzToolsFramework::EntityIdList& selectedEntities, AZ::u32& entitiesInSlices, AZStd::vector& sliceInstances); @@ -348,9 +346,6 @@ private: }; private: - typedef AZStd::unordered_map ExtensionMap; - ExtensionMap m_extensionToFileType; - AZ::Vector2 m_contextMenuViewPoint; AZ::Vector3 m_sliceWorldPos; diff --git a/Code/Sandbox/Plugins/MaglevControlPanel/CloudCanvasPythonWorkerInterface.h b/Code/Sandbox/Plugins/MaglevControlPanel/CloudCanvasPythonWorkerInterface.h deleted file mode 100644 index 1d557e35f7..0000000000 --- a/Code/Sandbox/Plugins/MaglevControlPanel/CloudCanvasPythonWorkerInterface.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -#include - -using PythonWorkerRequestId = int; - -//! Interface to signal the python worker output -class PythonWorkerEventsInterface -{ -protected: - PythonWorkerEventsInterface() = default; - virtual ~PythonWorkerEventsInterface() = default; - PythonWorkerEventsInterface(PythonWorkerEventsInterface&&) = delete; - PythonWorkerEventsInterface& operator=(PythonWorkerEventsInterface&&) = delete; - -public: - AZ_RTTI(PythonWorkerEventsInterface, "{60C83A5A-B8DD-4B98-B8C6-DC2F5914D7C4}"); - - // if any OnOutput returns true, it means the command was handled and the worker won't process any further - virtual bool OnPythonWorkerOutput(PythonWorkerRequestId requestId, const QString& key, const QVariant& value) = 0; -}; - -//! Interface to send the python worker requests -class PythonWorkerRequestsInterface -{ -protected: - PythonWorkerRequestsInterface() = default; - virtual ~PythonWorkerRequestsInterface() = default; - PythonWorkerRequestsInterface(PythonWorkerRequestsInterface&&) = delete; - PythonWorkerRequestsInterface& operator=(PythonWorkerRequestsInterface&&) = delete; - -public: - AZ_RTTI(PythonWorkerRequestsInterface, "{B0293028-3575-408E-8CE3-D1B7F3C59A6C}"); - - virtual PythonWorkerRequestId AllocateRequestId() = 0; - virtual void ExecuteAsync(PythonWorkerRequestId requestId, const char* command, const QVariantMap& args = QVariantMap{}) = 0; - virtual bool IsStarted() = 0; -}; - diff --git a/Code/Sandbox/Plugins/MaglevControlPanel/MaglevControlPanelPlugin_stub.cpp b/Code/Sandbox/Plugins/MaglevControlPanel/MaglevControlPanelPlugin_stub.cpp deleted file mode 100644 index 1508e9f7b0..0000000000 --- a/Code/Sandbox/Plugins/MaglevControlPanel/MaglevControlPanelPlugin_stub.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "stdafx.h" -#include -#include - -const char* TAG = "MaglevControlPanelPlugin"; - -MaglevControlPanelPlugin::MaglevControlPanelPlugin(IEditor* editor) - : m_pluginSettings(QSettings::IniFormat, QSettings::UserScope, "Amazon", "Lumberyard") -{ - -} - -void MaglevControlPanelPlugin::Release() -{ -} - -void MaglevControlPanelPlugin::OnEditorNotify(EEditorNotifyEvent aEventId) -{ -} - diff --git a/Code/Tools/CryCommonTools/Export/AnimationData.cpp b/Code/Tools/CryCommonTools/Export/AnimationData.cpp deleted file mode 100644 index 2b2c5966a6..0000000000 --- a/Code/Tools/CryCommonTools/Export/AnimationData.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "AnimationData.h" - -AnimationData::AnimationData(int modelCount, float fps, float startTime) - : m_entries(modelCount) - , m_frameCount(0) - , m_startTime(startTime) - , m_fps(fps) -{ -} - -void AnimationData::SetFrameData(int modelIndex, int frameIndex, float translation[3], float rotation[3], float scale[3]) -{ - State& state = m_entries[modelIndex].samples[frameIndex]; - state.translation[0] = translation[0]; - state.translation[1] = translation[1]; - state.translation[2] = translation[2]; - state.rotation[0] = rotation[0]; - state.rotation[1] = rotation[1]; - state.rotation[2] = rotation[2]; - state.scale[0] = scale[0]; - state.scale[1] = scale[1]; - state.scale[2] = scale[2]; -} - -void AnimationData::SetFrameCount(int frameCount) -{ - m_frameCount = frameCount; - for (int modelIndex = 0, modelCount = int(m_entries.size()); modelIndex < modelCount; ++modelIndex) - { - m_entries[modelIndex].samples.resize(frameCount); - } -} - -void AnimationData::SetModelFlags(int modelIndex, unsigned modelFlags) -{ - m_entries[modelIndex].flags = modelFlags; -} - -void AnimationData::GetFrameData(int modelIndex, int frameIndex, const float*& translation, const float*& rotation, const float*& scale) const -{ - translation = m_entries[modelIndex].samples[frameIndex].translation; - rotation = m_entries[modelIndex].samples[frameIndex].rotation; - scale = m_entries[modelIndex].samples[frameIndex].scale; -} - -void AnimationData::GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const -{ - translation = m_entries[modelIndex].samples[frameIndex].translation; -} - -void AnimationData::GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const -{ - rotation = m_entries[modelIndex].samples[frameIndex].rotation; -} - -void AnimationData::GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const -{ - scale = m_entries[modelIndex].samples[frameIndex].scale; -} - -int AnimationData::GetFrameCount() const -{ - return m_frameCount; -} - -unsigned AnimationData::GetModelFlags(int modelIndex) const -{ - return m_entries[modelIndex].flags; -} - -AnimationData::State::State() -{ - translation[0] = translation[1] = translation[2] = 0.0f; - rotation[0] = rotation[1] = rotation[2] = 0.0f; - scale[0] = scale[1] = scale[2] = 1.0f; -} - -AnimationData::ModelEntry::ModelEntry() - : flags(0) -{ -} - -/////////////////////////////////////////////////////////////////////////// -NonSkeletalAnimationData::NonSkeletalAnimationData(int modelCount) - : m_entries(modelCount) -{ -} - -void NonSkeletalAnimationData::SetModelFlags(int modelIndex, unsigned modelFlags) -{ - m_entries[modelIndex].flags = modelFlags; -} - -unsigned NonSkeletalAnimationData::GetModelFlags(int modelIndex) const -{ - return m_entries[modelIndex].flags; -} - -void NonSkeletalAnimationData::SetFrameTimePos(int modelIndex, int frameIndex, float time) -{ - State& state = m_entries[modelIndex].samplesPos[frameIndex]; - state.time = time; -} - -void NonSkeletalAnimationData::SetFrameDataPos(int modelIndex, int frameIndex, float translation[3]) -{ - State& state = m_entries[modelIndex].samplesPos[frameIndex]; - state.data[0] = translation[0]; - state.data[1] = translation[1]; - state.data[2] = translation[2]; -} - -void NonSkeletalAnimationData::SetFrameCountPos(int modelIndex, int frameCount) -{ - m_entries[modelIndex].samplesPos.resize(frameCount); -} - -void NonSkeletalAnimationData::SetFrameTimeRot(int modelIndex, int frameIndex, float time) -{ - State& state = m_entries[modelIndex].samplesRot[frameIndex]; - state.time = time; -} - -void NonSkeletalAnimationData::SetFrameDataRot(int modelIndex, int frameIndex, float rotation[3]) -{ - State& state = m_entries[modelIndex].samplesRot[frameIndex]; - state.data[0] = rotation[0]; - state.data[1] = rotation[1]; - state.data[2] = rotation[2]; -} - -void NonSkeletalAnimationData::SetFrameCountRot(int modelIndex, int frameCount) -{ - m_entries[modelIndex].samplesRot.resize(frameCount); -} - -void NonSkeletalAnimationData::SetFrameTimeScl(int modelIndex, int frameIndex, float time) -{ - State& state = m_entries[modelIndex].samplesScl[frameIndex]; - state.time = time; -} - -void NonSkeletalAnimationData::SetFrameDataScl(int modelIndex, int frameIndex, float scale[3]) -{ - State& state = m_entries[modelIndex].samplesScl[frameIndex]; - state.data[0] = scale[0]; - state.data[1] = scale[1]; - state.data[2] = scale[2]; -} - -void NonSkeletalAnimationData::SetFrameCountScl(int modelIndex, int frameCount) -{ - m_entries[modelIndex].samplesScl.resize(frameCount); -} - -float NonSkeletalAnimationData::GetFrameTimePos(int modelIndex, int frameIndex) const -{ - return m_entries[modelIndex].samplesPos[frameIndex].time; -} - -void NonSkeletalAnimationData::GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const -{ - translation = m_entries[modelIndex].samplesPos[frameIndex].data; -} - -int NonSkeletalAnimationData::GetFrameCountPos(int modelIndex) const -{ - return int(m_entries[modelIndex].samplesPos.size()); -} - -float NonSkeletalAnimationData::GetFrameTimeRot(int modelIndex, int frameIndex) const -{ - return m_entries[modelIndex].samplesRot[frameIndex].time; -} - -void NonSkeletalAnimationData::GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const -{ - rotation = m_entries[modelIndex].samplesRot[frameIndex].data; -} - -int NonSkeletalAnimationData::GetFrameCountRot(int modelIndex) const -{ - return int(m_entries[modelIndex].samplesRot.size()); -} - -float NonSkeletalAnimationData::GetFrameTimeScl(int modelIndex, int frameIndex) const -{ - return m_entries[modelIndex].samplesScl[frameIndex].time; -} - -void NonSkeletalAnimationData::GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const -{ - scale = m_entries[modelIndex].samplesScl[frameIndex].data; -} - -int NonSkeletalAnimationData::GetFrameCountScl(int modelIndex) const -{ - return int(m_entries[modelIndex].samplesScl.size()); -} - -void NonSkeletalAnimationData::SetFrameTCBPos(int modelIndex, int frameIndex, IAnimationData::TCB tcb) -{ - State& state = m_entries[modelIndex].samplesPos[frameIndex]; - state.tcb = tcb; -} - -void NonSkeletalAnimationData::SetFrameTCBRot(int modelIndex, int frameIndex, IAnimationData::TCB tcb) -{ - State& state = m_entries[modelIndex].samplesRot[frameIndex]; - state.tcb = tcb; -} - -void NonSkeletalAnimationData::SetFrameTCBScl(int modelIndex, int frameIndex, IAnimationData::TCB tcb) -{ - State& state = m_entries[modelIndex].samplesScl[frameIndex]; - state.tcb = tcb; -} - -void NonSkeletalAnimationData::SetFrameEaseInOutPos(int modelIndex, int frameIndex, IAnimationData::Ease ease) -{ - State& state = m_entries[modelIndex].samplesPos[frameIndex]; - state.ease = ease; -} - -void NonSkeletalAnimationData::SetFrameEaseInOutRot(int modelIndex, int frameIndex, IAnimationData::Ease ease) -{ - State& state = m_entries[modelIndex].samplesRot[frameIndex]; - state.ease = ease; -} - -void NonSkeletalAnimationData::SetFrameEaseInOutScl(int modelIndex, int frameIndex, IAnimationData::Ease ease) -{ - State& state = m_entries[modelIndex].samplesScl[frameIndex]; - state.ease = ease; -} - -void NonSkeletalAnimationData::GetFrameTCBPos(int modelIndex, int frameIndex, IAnimationData::TCB& tcb) const -{ - const State& state = m_entries[modelIndex].samplesPos[frameIndex]; - tcb = state.tcb; -} - -void NonSkeletalAnimationData::GetFrameTCBRot(int modelIndex, int frameIndex, IAnimationData::TCB& tcb) const -{ - const State& state = m_entries[modelIndex].samplesRot[frameIndex]; - tcb = state.tcb; -} - -void NonSkeletalAnimationData::GetFrameTCBScl(int modelIndex, int frameIndex, IAnimationData::TCB& tcb) const -{ - const State& state = m_entries[modelIndex].samplesScl[frameIndex]; - tcb = state.tcb; -} - -void NonSkeletalAnimationData::GetFrameEaseInOutPos(int modelIndex, int frameIndex, IAnimationData::Ease& ease) const -{ - const State& state = m_entries[modelIndex].samplesPos[frameIndex]; - ease = state.ease; -} - -void NonSkeletalAnimationData::GetFrameEaseInOutRot(int modelIndex, int frameIndex, IAnimationData::Ease& ease) const -{ - const State& state = m_entries[modelIndex].samplesRot[frameIndex]; - ease = state.ease; -} - -void NonSkeletalAnimationData::GetFrameEaseInOutScl(int modelIndex, int frameIndex, IAnimationData::Ease& ease) const -{ - const State& state = m_entries[modelIndex].samplesScl[frameIndex]; - ease = state.ease; -} - - -NonSkeletalAnimationData::State::State() -{ - time = 0.0f; - data[0] = data[1] = data[2] = 0.0f; -} - -NonSkeletalAnimationData::ModelEntry::ModelEntry() - : flags(0) -{ -} diff --git a/Code/Tools/CryCommonTools/Export/AnimationData.h b/Code/Tools/CryCommonTools/Export/AnimationData.h deleted file mode 100644 index 65b699e49b..0000000000 --- a/Code/Tools/CryCommonTools/Export/AnimationData.h +++ /dev/null @@ -1,211 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ANIMATIONDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ANIMATIONDATA_H -#pragma once - - -#include "IAnimationData.h" - -#include - -// Animation data class for skeletal animations -// It has a same count of samples for all models(bones) -// and always has translation/rotation/scaling data together as a set. -class AnimationData - : public IAnimationData -{ -public: - AnimationData(int modelCount, float fps, float startTime); - virtual ~AnimationData() {} - - // IAnimationData - virtual void SetFrameData(int modelIndex, int frameIndex, float translation[3], float rotation[3], float scale[3]); - virtual void SetFrameCount(int frameCount); - virtual void SetModelFlags(int modelIndex, unsigned modelFlags); - - virtual void SetFrameTimePos(int modelIndex, int frameIndex, float time) - { assert(0); } - virtual void SetFrameDataPos(int modelIndex, int frameIndex, float translation[3]) - { assert(0); } - virtual void SetFrameCountPos(int modelIndex, int frameCount) - { assert(0); } - virtual void SetFrameTimeRot(int modelIndex, int frameIndex, float time) - { assert(0); } - virtual void SetFrameDataRot(int modelIndex, int frameIndex, float rotation[3]) - { assert(0); } - virtual void SetFrameCountRot(int modelIndex, int frameCount) - { assert(0); } - virtual void SetFrameTimeScl(int modelIndex, int frameIndex, float time) - { assert(0); } - virtual void SetFrameDataScl(int modelIndex, int frameIndex, float scale[3]) - { assert(0); } - virtual void SetFrameCountScl(int modelIndex, int frameCount) - { assert(0); } - - virtual void GetFrameData(int modelIndex, int frameIndex, const float*& translation, const float*& rotation, const float*& scale) const; - virtual int GetFrameCount() const; - virtual unsigned GetModelFlags(int modelIndex) const; - - virtual float GetFrameTimePos(int modelIndex, int frameIndex) const - { return m_startTime + frameIndex / m_fps; } - virtual void GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const; - virtual int GetFrameCountPos(int) const - { return GetFrameCount(); } - virtual float GetFrameTimeRot(int modelIndex, int frameIndex) const - { return m_startTime + frameIndex / m_fps; } - virtual void GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const; - virtual int GetFrameCountRot(int) const - { return GetFrameCount(); } - virtual float GetFrameTimeScl(int modelIndex, int frameIndex) const - { return m_startTime + frameIndex / m_fps; } - virtual void GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const; - virtual int GetFrameCountScl(int) const - { return GetFrameCount(); } - - // TCB & Ease-In/-Out not supported for the skeletal animation. - virtual void SetFrameTCBPos(int modelIndex, int frameIndex, TCB tcb) - { assert(0); } - virtual void SetFrameTCBRot(int modelIndex, int frameIndex, TCB tcb) - { assert(0); } - virtual void SetFrameTCBScl(int modelIndex, int frameIndex, TCB tcb) - { assert(0); } - virtual void SetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease ease) - { assert(0); } - virtual void SetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease ease) - { assert(0); } - virtual void SetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease ease) - { assert(0); } - virtual void GetFrameTCBPos(int modelIndex, int frameIndex, TCB& tcb) const - { assert(0); } - virtual void GetFrameTCBRot(int modelIndex, int frameIndex, TCB& tcb) const - { assert(0); } - virtual void GetFrameTCBScl(int modelIndex, int frameIndex, TCB& tcb) const - { assert(0); } - virtual void GetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease& ease) const - { assert(0); } - virtual void GetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease& ease) const - { assert(0); } - virtual void GetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease& ease) const - { assert(0); } - -private: - struct State - { - public: - State(); - float translation[3]; - float rotation[3]; - float scale[3]; - }; - - struct ModelEntry - { - ModelEntry(); - - unsigned flags; - std::vector samples; - }; - - std::vector m_entries; - int m_frameCount; - float m_startTime; - float m_fps; -}; - -// Animation data class for non-skeletal animations -// It can have different counts of samples for each model -// and each channel of transformation data. -class NonSkeletalAnimationData - : public IAnimationData -{ -public: - NonSkeletalAnimationData(int modelCount); - virtual ~NonSkeletalAnimationData() {} - - // IAnimationData - virtual void SetFrameData(int modelIndex, int frameIndex, float translation[3], float rotation[3], float scale[3]) - { assert(0); } - virtual void SetFrameCount(int frameCount) - { assert(0); } - virtual void SetModelFlags(int modelIndex, unsigned modelFlags); - - virtual void SetFrameTimePos(int modelIndex, int frameIndex, float time); - virtual void SetFrameDataPos(int modelIndex, int frameIndex, float translation[3]); - virtual void SetFrameCountPos(int modelIndex, int frameCount); - virtual void SetFrameTimeRot(int modelIndex, int frameIndex, float time); - virtual void SetFrameDataRot(int modelIndex, int frameIndex, float rotation[3]); - virtual void SetFrameCountRot(int modelIndex, int frameCount); - virtual void SetFrameTimeScl(int modelIndex, int frameIndex, float time); - virtual void SetFrameDataScl(int modelIndex, int frameIndex, float scale[3]); - virtual void SetFrameCountScl(int modelIndex, int frameCount); - - virtual void GetFrameData(int modelIndex, int frameIndex, const float*& translation, const float*& rotation, const float*& scale) const - { assert(0); } - virtual int GetFrameCount() const - { - assert(0); - return 0; - } - virtual unsigned GetModelFlags(int modelIndex) const; - - virtual float GetFrameTimePos(int modelIndex, int frameIndex) const; - virtual void GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const; - virtual int GetFrameCountPos(int) const; - virtual float GetFrameTimeRot(int modelIndex, int frameIndex) const; - virtual void GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const; - virtual int GetFrameCountRot(int) const; - virtual float GetFrameTimeScl(int modelIndex, int frameIndex) const; - virtual void GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const; - virtual int GetFrameCountScl(int) const; - - virtual void SetFrameTCBPos(int modelIndex, int frameIndex, TCB tcb); - virtual void SetFrameTCBRot(int modelIndex, int frameIndex, TCB tcb); - virtual void SetFrameTCBScl(int modelIndex, int frameIndex, TCB tcb); - virtual void SetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease ease); - virtual void SetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease ease); - virtual void SetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease ease); - - virtual void GetFrameTCBPos(int modelIndex, int frameIndex, TCB& tcb) const; - virtual void GetFrameTCBRot(int modelIndex, int frameIndex, TCB& tcb) const; - virtual void GetFrameTCBScl(int modelIndex, int frameIndex, TCB& tcb) const; - virtual void GetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease& ease) const; - virtual void GetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease& ease) const; - virtual void GetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease& ease) const; - -private: - struct State - { - public: - State(); - float time; - float data[3]; - TCB tcb; - Ease ease; - }; - - struct ModelEntry - { - ModelEntry(); - - unsigned flags; - std::vector samplesPos; - std::vector samplesRot; - std::vector samplesScl; - }; - - std::vector m_entries; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ANIMATIONDATA_H diff --git a/Code/Tools/CryCommonTools/Export/CBAHelpers.cpp b/Code/Tools/CryCommonTools/Export/CBAHelpers.cpp deleted file mode 100644 index d724e349be..0000000000 --- a/Code/Tools/CryCommonTools/Export/CBAHelpers.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "CBAHelpers.h" -#include "../PathHelpers.h" -#include "StringHelpers.h" - -static string FindRootContainingFileGoingUpwards(const char* filePath, const char* filePathToLookFor, IPakSystem* pakSystem) -{ - // Here we just search upwards from the current directory, looking for a directory that - // contains a file at the relative path "Animations/Animations.cba". This is designed to - // handle root Game paths that differ from the default "Game". - string rootDirCandidate = PathHelpers::GetDirectory(filePath); - string rootDir; - while (!rootDirCandidate.empty()) - { - string cbaCandidatePath = PathHelpers::Join(rootDirCandidate, filePathToLookFor); - if (PakSystemFile* file = pakSystem->Open(cbaCandidatePath.c_str(), "r")) - { - // File exists, we have found the correct root path. - pakSystem->Close(file); - - rootDir = rootDirCandidate; - break; - } - - string previousCandidate = rootDirCandidate; - rootDirCandidate = PathHelpers::GetDirectory(rootDirCandidate); - if (rootDirCandidate == previousCandidate) - { - break; - } - } - - return (rootDir.empty() ? rootDir : PathHelpers::Join(rootDir, filePathToLookFor)); -} - -string CBAHelpers::FindCBAFileForFile(const char* filePath, IPakSystem* pakSystem) -{ - return FindRootContainingFileGoingUpwards(filePath, "Animations/Animations.cba", pakSystem); -} - -string CBAHelpers::FindSkeletonListForFile(const char* filePath, IPakSystem* pakSystem) -{ - return FindRootContainingFileGoingUpwards(filePath, "Animations/SkeletonList.xml", pakSystem); -} diff --git a/Code/Tools/CryCommonTools/Export/CBAHelpers.h b/Code/Tools/CryCommonTools/Export/CBAHelpers.h deleted file mode 100644 index 48af5c74d2..0000000000 --- a/Code/Tools/CryCommonTools/Export/CBAHelpers.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_CBAHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_CBAHELPERS_H -#pragma once - - -#include "IPakSystem.h" - -namespace CBAHelpers -{ - string FindCBAFileForFile(const char* filePath, IPakSystem* pakSystem); - string FindSkeletonListForFile(const char* filePath, IPakSystem* pakSystem); -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_CBAHELPERS_H diff --git a/Code/Tools/CryCommonTools/Export/ColladaExportWriter.cpp b/Code/Tools/CryCommonTools/Export/ColladaExportWriter.cpp deleted file mode 100644 index d0796a4838..0000000000 --- a/Code/Tools/CryCommonTools/Export/ColladaExportWriter.cpp +++ /dev/null @@ -1,556 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" - -#include "ColladaExportWriter.h" -#include "ColladaWriter.h" -#include "IExportSource.h" -#include "PathHelpers.h" -#include "ResourceCompilerHelper.h" -#include "SettingsManagerHelpers.h" -#include "IExportContext.h" -#include "ProgressRange.h" -#include "XMLWriter.h" -#include "XMLPakFileSink.h" -#include "ISettings.h" -#include "SingleAnimationExportSourceAdapter.h" -#include "GeometryExportSourceAdapter.h" -#include "ModelData.h" -#include "MaterialData.h" -#include "GeometryFileData.h" -#include "FileUtil.h" -#include "CBAHelpers.h" -#include "ModuleHelpers.h" -#include "PropertyHelpers.h" -#include "StringHelpers.h" -#include -#include - -namespace -{ - class ResourceCompilerLogListener - : public IResourceCompilerListener - { - public: - ResourceCompilerLogListener(IExportContext* context) - : m_context(context) - { - } - - virtual void OnRCMessage(IResourceCompilerListener::MessageSeverity severity, const char* text) - { - ILogger::ESeverity outSeverity; - switch (severity) - { - case IResourceCompilerListener::MessageSeverity_Debug: - case IResourceCompilerListener::MessageSeverity_Info: // normal RC text should just be debug - outSeverity = ILogger::eSeverity_Debug; - break; - case IResourceCompilerListener::MessageSeverity_Warning: - outSeverity = ILogger::eSeverity_Warning; - break; - case IResourceCompilerListener::MessageSeverity_Error: - outSeverity = ILogger::eSeverity_Error; - break; - default: - outSeverity = ILogger::eSeverity_Error; - break; - } - - m_context->Log(outSeverity, "%s", text); - } - - private: - IExportContext* m_context; - }; -} - -void ColladaExportWriter::Export(IExportSource* source, IExportContext* context) -{ - // Create an object to report on our progress to the export context. - ProgressRange progressRange(context, &IExportContext::SetProgress); - CResourceCompilerHelper compiler; // we need a real instance of this specific implementation. - - // Log build information. - context->Log(ILogger::eSeverity_Info, "Exporter build created on " __DATE__); - -#ifdef STLPORT - context->Log(ILogger::eSeverity_Info, "Using STLport C++ Standard Library implementation"); -#else //STLPORT - context->Log(ILogger::eSeverity_Info, "Using Microsoft (tm) C++ Standard Library implementation"); -#endif //STLPORT - -#if defined(_DEBUG) - context->Log(ILogger::eSeverity_Info, "******DEBUG BUILD******"); -#else //_DEBUG - context->Log(ILogger::eSeverity_Info, "Release build."); -#endif //_DEBUG - - context->Log(ILogger::eSeverity_Debug, "Bit count == %d.", (sizeof(void*) * 8)); - - std::string exePath = StringHelpers::ConvertString(ModuleHelpers::GetCurrentModulePath(ModuleHelpers::CurrentModuleSpecifier_Executable)); - context->Log(ILogger::eSeverity_Debug, "Application path: %s", exePath.c_str()); - - std::string exporterPath = StringHelpers::ConvertString(ModuleHelpers::GetCurrentModulePath(ModuleHelpers::CurrentModuleSpecifier_Library)); - context->Log(ILogger::eSeverity_Debug, "Exporter path: %s", exporterPath.c_str()); - - bool const bExportCompressed = (GetSetting(context->GetSettings(), "ExportCompressedCOLLADA", 1)) != 0; - context->Log(ILogger::eSeverity_Debug, "ExportCompressedCOLLADA key: %d", (bExportCompressed ? 1 : 0)); - - std::string const exportExtension = bExportCompressed ? ".dae.zip" : ".dae"; - - // Log the start time. - { - char buf[1024]; - std::time_t t = std::time(0); - std::strftime(buf, sizeof(buf) / sizeof(buf[0]), "%H:%M:%S on %a, %d/%m/%Y", std::localtime(&t)); - context->Log(ILogger::eSeverity_Info, "Export begun at %s", buf); - } - - // Select the name of the directory to export to. - std::string const originalExportDirectory = source->GetExportDirectory(); - if (originalExportDirectory.empty()) - { - throw IExportContext::NeedSaveError("Scene must be saved before exporting."); - } - - GeometryFileData geometryFileData; - std::vector colladaGeometryFileNameList; - std::vector assetGeometryFileNameList; - typedef std::vector, std::string> > AnimationFileNameList; - AnimationFileNameList animationFileNameList; - AnimationFileNameList animationCompileFileNameList; - { - CurrentTaskScope currentTask(context, "dae"); - - // Choose the files to which to export all the animations. - std::list animationExportSources; - std::list geometryExportSources; - typedef std::vector > ExportList; - ExportList exportList; - std::vector geometryFileIndices; - { - ProgressRange readProgressRange(progressRange, 0.2f); - - source->ReadGeometryFiles(context, &geometryFileData); - - for (int geometryFileIndex = 0; geometryFileIndex < geometryFileData.GetGeometryFileCount(); ++geometryFileIndex) - { - const std::string geometryFileName = geometryFileData.GetGeometryFileName(geometryFileIndex); - - IGeometryFileData::SProperties properties = geometryFileData.GetProperties(geometryFileIndex); - if (properties.filetypeInt == CRY_FILE_TYPE_CAF) - { - // LDS: This is a temporary fix for some old hacky code that would activate a deprecated compression path during export - // It needs a proper fix by tearing out the old compression code and moving the system to the new i_caf system by default. - // See for http://docs.cryengine.com/display/SDKDOC3/Transition+from+CBA+to+AnimSettings details. - properties.filetypeInt = CRY_FILE_TYPE_INTERMEDIATE_CAF; - geometryFileData.SetProperties(geometryFileIndex, properties); - } - - bool const hasGeometry = (properties.filetypeInt != CRY_FILE_TYPE_CAF && - properties.filetypeInt != CRY_FILE_TYPE_INTERMEDIATE_CAF); - - if (hasGeometry && !geometryFileName.empty()) - { - geometryFileIndices.push_back(geometryFileIndex); - } - } - - if (!geometryFileIndices.empty()) - { - std::string name = PathHelpers::RemoveExtension(PathHelpers::GetFilename(source->GetDCCFileName())); - std::replace(name.begin(), name.end(), ' ', '_'); - std::string const colladaPath = PathHelpers::Join(originalExportDirectory, name + exportExtension); - colladaGeometryFileNameList.push_back(colladaPath); - - geometryExportSources.push_back(GeometryExportSourceAdapter(source, &geometryFileData, geometryFileIndices)); - exportList.push_back(std::make_pair(colladaPath, &geometryExportSources.back())); - } - - for (int geometryFileIndex = 0; geometryFileIndex < geometryFileData.GetGeometryFileCount(); ++geometryFileIndex) - { - std::string const geometryFileName = geometryFileData.GetGeometryFileName(geometryFileIndex); - int const fileTypeInt = geometryFileData.GetProperties(geometryFileIndex).filetypeInt; - std::string customExportPath = geometryFileData.GetProperties(geometryFileIndex).customExportPath; - bool const hasGeometry = (fileTypeInt != CRY_FILE_TYPE_CAF && - fileTypeInt != CRY_FILE_TYPE_INTERMEDIATE_CAF); - - if (hasGeometry && !geometryFileName.empty()) - { - std::string extension = "missingextension"; - if (fileTypeInt == CRY_FILE_TYPE_CGF) - { - extension = "cgf"; - } - else if ((fileTypeInt == CRY_FILE_TYPE_CGA) || (fileTypeInt == (CRY_FILE_TYPE_CGA | CRY_FILE_TYPE_ANM))) - { - extension = "cga"; - } - else if (fileTypeInt == CRY_FILE_TYPE_ANM) - { - extension = "anm"; - } - else if (fileTypeInt == CRY_FILE_TYPE_CHR || - (fileTypeInt == (CRY_FILE_TYPE_CHR | CRY_FILE_TYPE_CAF)) || - (fileTypeInt == (CRY_FILE_TYPE_CHR | CRY_FILE_TYPE_INTERMEDIATE_CAF))) - { - extension = "chr"; - } - else if (fileTypeInt == CRY_FILE_TYPE_SKIN) - { - extension = "skin"; - } - - std::string safeGeometryFileName = geometryFileName; - std::replace(safeGeometryFileName.begin(), safeGeometryFileName.end(), ' ', '_'); - std::string finalFileName; - if (customExportPath.size() > 0) - { - if (PathHelpers::IsRelative(customExportPath)) - { - std::string const assetRelativePath = PathHelpers::Join(originalExportDirectory, customExportPath); - finalFileName = PathHelpers::Join(assetRelativePath, safeGeometryFileName + "." + extension); - } - else - { - context->Log(ILogger::eSeverity_Warning, "An absolute path was specified for export of node %s (%s) - This is unlikely to be correct", geometryFileName.c_str(), customExportPath.c_str()); - finalFileName = PathHelpers::Join(customExportPath, safeGeometryFileName + "." + extension); - } - } - else - { - // no relative path, just export it in the original directory. - finalFileName = PathHelpers::Join(originalExportDirectory, safeGeometryFileName + "." + extension); - } - if (finalFileName.size() > 0) - { - assetGeometryFileNameList.push_back(finalFileName); - if (!FileUtil::EnsureDirectoryExists(PathHelpers::GetDirectory(finalFileName).c_str())) - { - context->Log(ILogger::eSeverity_Error, "Unable to create directory for %s", finalFileName.c_str()); - return; - } - } - } - - if ((fileTypeInt & (CRY_FILE_TYPE_CAF | CRY_FILE_TYPE_INTERMEDIATE_CAF)) != 0) - { - for (int animationIndex = 0; animationIndex < source->GetAnimationCount(); ++animationIndex) - { - std::string const animationName = source->GetAnimationName(&geometryFileData, geometryFileIndex, animationIndex); - - // Animations beginning with an underscore should be ignored. - bool const ignoreAnimation = animationName.empty() || (animationName[0] == '_'); - - if (!ignoreAnimation) - { - std::string safeAnimationName = animationName; - std::replace(safeAnimationName.begin(), safeAnimationName.end(), ' ', '_'); - - std::string exportPath = PathHelpers::Join(originalExportDirectory, safeAnimationName + exportExtension); - animationFileNameList.push_back(std::make_pair(std::make_pair(animationIndex, geometryFileIndex), exportPath)); - if (fileTypeInt & CRY_FILE_TYPE_CAF) - { - animationCompileFileNameList.push_back(std::make_pair(std::make_pair(animationIndex, geometryFileIndex), exportPath)); - } - animationExportSources.push_back(SingleAnimationExportSourceAdapter(source, &geometryFileData, geometryFileIndex, animationIndex)); - exportList.push_back(std::make_pair(exportPath, &animationExportSources.back())); - } - } - } - } - } - - // Export the COLLADA file to the chosen file. - { - ProgressRange exportProgressRange(progressRange, 0.6f); - - size_t const daeCount = exportList.size(); - float const daeProgressRangeSlice = 1.0f / (daeCount > 0 ? daeCount : 1); - for (ExportList::iterator itFile = exportList.begin(); itFile != exportList.end(); ++itFile) - { - const std::string& colladaFileName = (*itFile).first; - IExportSource* fileExportSource = (*itFile).second; - - ProgressRange animationExportProgressRange(exportProgressRange, daeProgressRangeSlice); - - try - { - context->Log(ILogger::eSeverity_Info, "Exporting to file '%s'", colladaFileName.c_str()); - - // Try to create the directory for the file. - if (!FileUtil::EnsureDirectoryExists(PathHelpers::GetDirectory(colladaFileName).c_str())) - { - context->Log(ILogger::eSeverity_Error, "Unable to create directory for %s", colladaFileName.c_str()); - return; - } - - bool ok; - - if (bExportCompressed) - { - IPakSystem* pakSystem = (context ? context->GetPakSystem() : 0); - if (!pakSystem) - { - throw IExportContext::PakSystemError("No pak system provided."); - } - - std::string const archivePath = colladaFileName; - std::string archiveRelativePath = colladaFileName.substr(0, colladaFileName.length() - exportExtension.length()) + ".dae"; - archiveRelativePath = PathHelpers::GetFilename(archiveRelativePath); - - XMLPakFileSink sink(pakSystem, archivePath, archiveRelativePath); - ok = ColladaWriter::Write(fileExportSource, context, &sink, animationExportProgressRange); - } - else - { - XMLFileSink fileSink(colladaFileName); - ok = ColladaWriter::Write(fileExportSource, context, &fileSink, animationExportProgressRange); - } - - if (!ok) - { - // FIXME: erase the resulting file somehow - context->Log(ILogger::eSeverity_Error, "Failed to export '%s'", colladaFileName.c_str()); - return; - } - } - catch (IXMLSink::OpenFailedError e) - { - context->Log(ILogger::eSeverity_Error, "Unable to open output file: %s", e.what()); - return; - } - catch (...) - { - context->Log(ILogger::eSeverity_Error, "Unexpected crash in COLLADA exporter"); - return; - } - } - } - } - - // Get the RC path. If a custom one isn't specified then fall back to the registry method as per the default. - wchar_t resourceCompilerPath[512]; - { - const std::string resourceCompilerPathString = source->GetResourceCompilerPath(); - if (!resourceCompilerPathString.empty()) - { - SettingsManagerHelpers::ConvertUtf8ToUtf16(resourceCompilerPathString.c_str(), SettingsManagerHelpers::CWCharBuffer(resourceCompilerPath, sizeof(resourceCompilerPath))); - } - } - - // Run the resource compiler on the COLLADA file to generate uncompressed CAFs. - { - ProgressRange compilerProgressRange(progressRange, 0.075f); - - CurrentTaskScope currentTask(context, "rc"); - - size_t const daeCount = animationFileNameList.size(); - float const animationProgressRangeSlice = 1.0f / (daeCount > 0 ? daeCount : 1); - for (AnimationFileNameList::iterator itFile = animationFileNameList.begin(); itFile != animationFileNameList.end(); ++itFile) - { - std::string colladaFileName = (*itFile).second; - int geometryFileIndex = itFile->first.second; - - std::string expectedCAFPath; - { - bool isIntermediateCAF = (geometryFileData.GetProperties(geometryFileIndex).filetypeInt & CRY_FILE_TYPE_INTERMEDIATE_CAF) != 0; - string nameWithoutExtension = colladaFileName.substr(0, colladaFileName.length() - exportExtension.length()); - expectedCAFPath = nameWithoutExtension + (isIntermediateCAF ? ".i_caf" : ".caf"); - } - - if (FileUtil::FileExists(expectedCAFPath.c_str())) - { - if (!DeleteFileA(expectedCAFPath.c_str())) - { - context->Log(ILogger::eSeverity_Error, "Failed to remove existing animation file: %s", expectedCAFPath.c_str()); - continue; - } - } - - string arguments = "/refresh"; - - ProgressRange animationCompileProgressRange(compilerProgressRange, animationProgressRangeSlice); - ResourceCompilerLogListener listener(context); - - context->Log(ILogger::eSeverity_Info, "Calling RC to generate uncompressed CAF file: %s", colladaFileName.c_str()); - CResourceCompilerHelper::ERcCallResult result = compiler.CallResourceCompiler( // actual instance of compiler used - colladaFileName.c_str(), - arguments.c_str(), - &listener, - true, false, false, 0, resourceCompilerPath); - - if (result != CResourceCompilerHelper::eRcCallResult_success) - { - context->Log(ILogger::eSeverity_Error, "%s", compiler.GetCallResultDescription(result)); - continue; - } - - context->Log(ILogger::eSeverity_Debug, "RC finished: %s", colladaFileName.c_str()); - if (!FileUtil::FileExists(expectedCAFPath.c_str())) - { - context->Log(ILogger::eSeverity_Error, "Following Animation file is expected to be created by RC: %s", expectedCAFPath.c_str()); - context->Log(ILogger::eSeverity_Error, "Do you have an old RC version?"); - } - -#if !defined(_DEBUG) - // Delete the Collada file. - DeleteFileA(colladaFileName.c_str()); -#endif - } - } - - // Run the resource compiler on the COLLADA file to generate the geometry assets. - { - ProgressRange compilerProgressRange(progressRange, 0.075f); - - CurrentTaskScope currentTask(context, "rc"); - - size_t const daeCount = colladaGeometryFileNameList.size(); - float const assetProgressRangeSlice = 1.0f / (daeCount > 0 ? daeCount : 1); - for (size_t i = 0; i < daeCount; ++i) - { - const std::string& colladaFileName = colladaGeometryFileNameList[i]; - - ProgressRange assetCompileProgressRange(compilerProgressRange, assetProgressRangeSlice); - ResourceCompilerLogListener listener(context); - context->Log(ILogger::eSeverity_Info, "Calling RC to generate raw asset file: %s", colladaFileName.c_str()); - CResourceCompilerHelper::ERcCallResult result = compiler.CallResourceCompiler( - colladaFileName.c_str(), - "/refresh", - &listener, - true, false, false, 0, resourceCompilerPath); - -#if !defined(_DEBUG) - // Delete the Collada file. - DeleteFileA(colladaFileName.c_str()); -#endif - - if (result == CResourceCompilerHelper::eRcCallResult_success) - { - context->Log(ILogger::eSeverity_Debug, "RC finished: %s", colladaFileName.c_str()); - } - else - { - context->Log(ILogger::eSeverity_Error, "%s", compiler.GetCallResultDescription(result)); - return; - } - } - } - - { - // Create an RC helper - do it outside the loop, since it queries the registry on construction. - ResourceCompilerLogListener listener(context); - - // Check the registry to see whether we should compress the animations or not. - int processAnimations = GetSetting(context->GetSettings(), "CompressCAFs", 1); - - if (!processAnimations) - { - context->Log(ILogger::eSeverity_Warning, "CompressCAFs registry key set to 0 - not compressing CAFs"); - } - else - { - // Run the resource compiler again on the generated CAF files to compress/process them. - context->Log(ILogger::eSeverity_Debug, "CompressCAFs not set or set to 1 - compressing CAFs"); - - CurrentTaskScope currentTask(context, "compress"); - ProgressRange compressRange(progressRange, 0.025f); - - size_t const cafCount = animationCompileFileNameList.size(); - float const animationProgressRangeSlice = 1.0f / (cafCount > 0 ? cafCount : 1); - for (AnimationFileNameList::iterator itFile = animationCompileFileNameList.begin(); itFile != animationCompileFileNameList.end(); ++itFile) - { - std::string colladaFileName = (*itFile).second; - ProgressRange animationProgressRange(compressRange, animationProgressRangeSlice); - - // Assume the RC generated the CAF file using the take name and adding .CAF. - std::string cafPath = colladaFileName.substr(0, colladaFileName.length() - exportExtension.length()) + ".caf"; - std::string cbaPath = StringHelpers::ConvertString(CBAHelpers::FindCBAFileForFile(cafPath.c_str(), context->GetPakSystem())); - - if (cbaPath.empty()) - { - context->Log(ILogger::eSeverity_Error, "Unable to find CBA file for file \"%s\" (looked for a root game directory that contains a relative path of \"Animations/Animations.cba\"", cafPath.c_str()); - } - else - { - char buffer[2048]; - sprintf(buffer, "/file=\"%s\" /refresh /SkipDba", cafPath.c_str()); - context->Log(ILogger::eSeverity_Info, "Calling RC to compress CAF file: (CBA file = %s) %s", cbaPath.c_str(), buffer); - CResourceCompilerHelper::ERcCallResult result = compiler.CallResourceCompiler(cbaPath.c_str(), buffer, &listener, true, resourceCompilerPathType, false, false, 0, resourceCompilerPath); - if (result == CResourceCompilerHelper::eRcCallResult_success) - { - context->Log(ILogger::eSeverity_Debug, "RC finished: %s %s", cbaPath.c_str(), buffer); - } - else - { - context->Log(ILogger::eSeverity_Error, "%s", compiler.GetCallResultDescription(result)); - return; - } - } - } - } - - // Check the registry to see whether we should optimize the geometry files or not. - int optimizeGeometry = GetSetting(context->GetSettings(), "OptimizeAssets", 1); - - // Run the resource compiler again on the generated geometry files to compress/process them. - // TODO: This should not be necessary, the RC should be modified so that assets are automatically - // compressed when exported from COLLADA. - if (!optimizeGeometry) - { - context->Log(ILogger::eSeverity_Warning, "OptimizeAssets registry key set to 0 - not compressing CAFs"); - } - else - { - context->Log(ILogger::eSeverity_Debug, "OptimizeAssets not set or set to 1 - optimizing geometry"); - - CurrentTaskScope currentTask(context, "compress"); - ProgressRange compressRange(progressRange, 0.025f); - - size_t const assetCount = assetGeometryFileNameList.size(); - float const assetProgressRangeSlice = 1.0f / (assetCount > 0 ? assetCount : 1); - for (size_t i = 0; i < assetCount; ++i) - { - const std::string& assetFileName = assetGeometryFileNameList[i]; - ProgressRange animationProgressRange(compressRange, assetProgressRangeSlice); - - // note: we skip some asset types because we know that they are "optimized" already - if (StringHelpers::EndsWithIgnoreCase(assetFileName, ".anm") || StringHelpers::EndsWithIgnoreCase(assetFileName, ".chr") || StringHelpers::EndsWithIgnoreCase(assetFileName, ".skin")) - { - context->Log(ILogger::eSeverity_Info, "Calling RC to optimize asset \"%s\"", assetFileName.c_str()); - CResourceCompilerHelper::ERcCallResult result = compiler.CallResourceCompiler(assetFileName.c_str(), "/refresh", &listener, true, resourceCompilerPathType, false, false, 0, resourceCompilerPath); - if (result == CResourceCompilerHelper::eRcCallResult_success) - { - context->Log(ILogger::eSeverity_Debug, "RC finished: %s", assetFileName.c_str()); - } - else - { - context->Log(ILogger::eSeverity_Error, "%s", compiler.GetCallResultDescription(result)); - return; - } - } - } - } - } - - // Log the end time. - { - char buf[1024]; - std::time_t t = std::time(0); - std::strftime(buf, sizeof(buf) / sizeof(buf[0]), "%H:%M:%S on %a, %d/%m/%Y", std::localtime(&t)); - context->Log(ILogger::eSeverity_Info, "Export finished at %s", buf); - } -} diff --git a/Code/Tools/CryCommonTools/Export/ColladaExportWriter.h b/Code/Tools/CryCommonTools/Export/ColladaExportWriter.h deleted file mode 100644 index 8dc53ad62f..0000000000 --- a/Code/Tools/CryCommonTools/Export/ColladaExportWriter.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAEXPORTWRITER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAEXPORTWRITER_H -#pragma once - - -#include "IExportWriter.h" - -class ColladaExportWriter - : public IExportWriter -{ -public: - // IExportWriter - virtual void Export(IExportSource* source, IExportContext* context); -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAEXPORTWRITER_H diff --git a/Code/Tools/CryCommonTools/Export/ColladaWriter.cpp b/Code/Tools/CryCommonTools/Export/ColladaWriter.cpp deleted file mode 100644 index 106ed02ba4..0000000000 --- a/Code/Tools/CryCommonTools/Export/ColladaWriter.cpp +++ /dev/null @@ -1,2918 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "ColladaWriter.h" -#include "IExportSource.h" -#include "ISettings.h" -#include "XMLWriter.h" -#include "SkeletonData.h" -#include "AnimationData.h" -#include "ProgressRange.h" -#include "ModelData.h" -#include "IExportContext.h" -#include "GeometryFileData.h" -#include "GeometryData.h" -#include "MaterialData.h" -#include "SkinningData.h" -#include "Cry_Math.h" -#include "LocaleChanger.h" -#include "MorphData.h" -#include "StringHelpers.h" -#include "GeometryMaterialData.h" -#include "ColladaShared.h" -#include -#include -#include -#include - -namespace -{ - bool FloatingPointHasPrecisionIssues() - { - Matrix44 m; - - m.m00 = 0.729367f; - m.m01 = -0.143863f; - m.m02 = -0.668825f; - m.m03 = 0.595435f; - - m.m10 = -0.573746f; - m.m11 = 0.403844f; - m.m12 = -0.712549f; - m.m13 = 1.14523f; - - m.m20 = 0.37261f; - m.m21 = 0.903445f; - m.m22 = 0.21201f; - m.m23 = 0.0669039f; - - m.m30 = 0; - m.m31 = 0; - m.m32 = 0; - m.m33 = 1; - - m.Invert(); - - return m.m33 <= 0.999f || m.m33 >= 1.001f; - - // For testing with www.wolframalpha.com: - // string a = StringHelpers::Format("inverse{{%g,%g,%g,%g},{%g,%g,%g,%g},{%g,%g,%g,%g},{%g,%g,%g,%g}}", - // m.m00, m.m01, m.m02, m.m03, - // m.m10, m.m11, m.m12, m.m13, - // m.m20, m.m21, m.m22, m.m23, - // m.m30, m.m31, m.m32, m.m33); - } -} - - -namespace -{ - void DecomposeTransform(Vec3& translation, CryQuat& rotation, Vec3& scale, const Matrix34& transform) - { - translation = transform.GetTranslation(); - Matrix33 orientation(transform); - scale.x = Vec3(orientation.m00, orientation.m10, orientation.m20).GetLength(); - scale.y = Vec3(orientation.m01, orientation.m11, orientation.m21).GetLength(); - scale.z = Vec3(orientation.m02, orientation.m12, orientation.m22).GetLength(); - orientation.OrthonormalizeFast(); - rotation = !CryQuat(orientation); - } - - struct BoneEntry - { - std::string name; - std::string physName; - std::string parentFrameName; - }; - - typedef std::map, SkeletonData> SkeletonDataMap; - typedef std::map, MorphData> MorphDataMap; - typedef std::map, std::vector > BoneDataMap; - - struct GeometryEntry - { - GeometryEntry(const std::string& name, int geometryFileIndex, int modelIndex) - : name(name) - , geometryFileIndex(geometryFileIndex) - , modelIndex(modelIndex) {} - std::string name; - int geometryFileIndex; - int modelIndex; - }; - - struct BoneGeometryEntry - { - BoneGeometryEntry(const std::string& name, int geometryFileIndex, int modelIndex, int boneIndex) - : name(name) - , geometryFileIndex(geometryFileIndex) - , modelIndex(modelIndex) - , boneIndex(boneIndex) {} - std::string name; - int geometryFileIndex; - int modelIndex; - int boneIndex; - }; - - struct MorphGeometryEntry - { - MorphGeometryEntry(const std::string& name, const std::string& morphName, int geometryFileIndex, int modelIndex, int morphIndex) - : name(name) - , morphName(morphName) - , geometryFileIndex(geometryFileIndex) - , modelIndex(modelIndex) - , morphIndex(morphIndex) {} - std::string name; - std::string morphName; - int geometryFileIndex; - int modelIndex; - int morphIndex; - }; - - struct EffectsEntry - { - EffectsEntry(const std::string& name) - : name(name) {} - - std::string name; - }; - - struct MaterialEntry - { - MaterialEntry(const std::string& name) - : name(name) {} - - std::string name; - }; - - struct SkinControllerEntry - { - std::string name; - int geometryFileIndex; - int modelIndex; - }; - - struct MorphControllerEntry - { - std::string name; - int geometryFileIndex; - int modelIndex; - }; - - typedef std::map, MorphControllerEntry> MorphControllerMap; - - void BindMaterials(XMLWriter& writer, IExportContext* context, MaterialData& materialData, const ModelData& modelData, int modelIndex, const std::map& materialMaterialMap, const std::vector& materials, IExportSource* source) - { - // Instance any materials that the node uses. - GeometryMaterialData geometryMaterialData; - source->ReadGeometryMaterialData(context, &geometryMaterialData, &modelData, &materialData, modelIndex); - - std::set usedMaterialIndices; - for (int materialIndex = 0, materialCount = geometryMaterialData.GetUsedMaterialCount(); materialIndex < materialCount; ++materialIndex) - { - usedMaterialIndices.insert(geometryMaterialData.GetUsedMaterialIndex(materialIndex)); - } - if (!usedMaterialIndices.empty()) - { - XMLWriter::Element bindMaterialElement(writer, "bind_material"); - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - for (std::set::const_iterator usedMtlPos = usedMaterialIndices.begin(), usedMtlEnd = usedMaterialIndices.end(); usedMtlPos != usedMtlEnd; ++usedMtlPos) - { - std::map::const_iterator entryMapPos = materialMaterialMap.find(*usedMtlPos); - int entryIndex = (entryMapPos != materialMaterialMap.end() ? (*entryMapPos).second : -1); - std::string name = (entryIndex >= 0 ? materials[entryIndex].name : "UNKNOWN_INSTANCED_MATERIAL"); - - XMLWriter::Element instanceMaterialElement(writer, "instance_material"); - instanceMaterialElement.Attribute("symbol", name); - instanceMaterialElement.Attribute("target", "#" + name); - } - } - } - - void BindBoneMaterials(XMLWriter& writer, IExportContext* context, MaterialData& materialData, SkeletonData& skeletonData, int boneIndex, const std::map& materialMaterialMap, const std::vector& materials, IExportSource* source) - { - // Instance any materials that the node uses. - GeometryMaterialData geometryMaterialData; - source->ReadBoneGeometryMaterialData(context, &geometryMaterialData, &skeletonData, boneIndex, &materialData); - - std::set usedMaterialIndices; - for (int materialIndex = 0, materialCount = geometryMaterialData.GetUsedMaterialCount(); materialIndex < materialCount; ++materialIndex) - { - usedMaterialIndices.insert(geometryMaterialData.GetUsedMaterialIndex(materialIndex)); - } - if (!usedMaterialIndices.empty()) - { - XMLWriter::Element bindMaterialElement(writer, "bind_material"); - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - for (std::set::const_iterator usedMtlPos = usedMaterialIndices.begin(), usedMtlEnd = usedMaterialIndices.end(); usedMtlPos != usedMtlEnd; ++usedMtlPos) - { - std::map::const_iterator entryMapPos = materialMaterialMap.find(*usedMtlPos); - int entryIndex = (entryMapPos != materialMaterialMap.end() ? (*entryMapPos).second : -1); - std::string name = (entryIndex >= 0 ? materials[entryIndex].name : "UNKNOWN_INSTANCED_MATERIAL"); - - XMLWriter::Element instanceMaterialElement(writer, "instance_material"); - instanceMaterialElement.Attribute("symbol", name); - instanceMaterialElement.Attribute("target", "#" + name); - } - } - - //// Instance any materials that the node uses. - //std::vector materialIDs; - //for (int materialIndex = 0, materialCount = materialData.GetMaterialCount(); materialIndex < materialCount; ++materialIndex) - //{ - // int parentIndex = materialData.GetParentIndex(materialIndex); - // if (parentIndex >= 0 && parentIndex == skeletonData.GetMaterial(boneIndex)) - // materialIDs.push_back(materialIndex); - //} - - //if (!materialIDs.empty()) - //{ - // XMLWriter::Element bindMaterialElement(writer, "bind_material"); - // XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - // for (int i = 0, count = int(materialIDs.size()); i < count; ++i) - // { - // std::map::const_iterator entryMapPos = materialMaterialMap.find(materialIDs[i]); - // int entryIndex = (entryMapPos != materialMaterialMap.end() ? (*entryMapPos).second : -1); - // std::string name = (entryIndex >= 0 ? materials[entryIndex].name : 0); - - // XMLWriter::Element instanceMaterialElement(writer, "instance_material"); - // instanceMaterialElement.Attribute("symbol", name); - // instanceMaterialElement.Attribute("target", "#" + name); - // } - //} - } - - void WriteExtraData(XMLWriter& writer, const SHelperData& helperData, const std::string& properties) - { - // Write helper data (if it's helper node) and properties - if ((!properties.empty()) || (helperData.m_eHelperType != SHelperData::eHelperType_UNKNOWN)) - { - XMLWriter::Element elem(writer, "extra"); - { - XMLWriter::Element elem(writer, "technique"); - elem.Attribute("profile", "CryEngine"); - { - if (!properties.empty()) - { - // TODO: Sokov: check for invalid characters in properties string, like '<', '>', <' ', >127 etc. - XMLWriter::Element elem(writer, "properties"); - elem.Content(properties); - } - - if (helperData.m_eHelperType != SHelperData::eHelperType_UNKNOWN) - { - XMLWriter::Element elem(writer, "helper"); - switch (helperData.m_eHelperType) - { - case SHelperData::eHelperType_Point: - elem.Attribute("type", "point"); - break; - case SHelperData::eHelperType_Dummy: - elem.Attribute("type", "dummy"); - { - XMLWriter::Element elem(writer, "bound_box_min"); - elem.ContentArrayElement(helperData.m_boundBoxMin[0]); - elem.ContentArrayElement(helperData.m_boundBoxMin[1]); - elem.ContentArrayElement(helperData.m_boundBoxMin[2]); - } - { - XMLWriter::Element elem(writer, "bound_box_max"); - elem.ContentArrayElement(helperData.m_boundBoxMax[0]); - elem.ContentArrayElement(helperData.m_boundBoxMax[1]); - elem.ContentArrayElement(helperData.m_boundBoxMax[2]); - } - break; - default: - assert(false); - elem.Attribute("type", "UNKNOWN"); - break; - } - } - } - } - } - - // ****** I dont think we need this anymore. These files are not readable by XSI as far as I know. ****** - // ****** Removed 03-Jan-2012 - // Write special properties for importing to the XSI. - /*{ - XMLWriter::Element elem(writer, "technique"); - elem.Attribute("profile","XSI"); - { - XMLWriter::Element elem(writer, "XSI_CustomPSet"); - elem.Attribute("name","ObjectProperties"); - { - XMLWriter::Element elem(writer, "propagation"); - elem.Content("NODE"); - } - { - XMLWriter::Element elem(writer, "type"); - elem.Content("CryNodeProperties"); - } - { - XMLWriter::Element elem(writer, "XSI_Parameter"); - elem.Attribute("id","Props"); - elem.Attribute("type","Text"); - elem.Attribute("value",properties.c_str()); - } - } - }*/ - } - - void WriteSkeletonRecurse(XMLWriter& writer, IExportContext* context, const std::string& modelName, SkeletonData& skeletonData, int boneIndex, const std::string& name, const std::vector& bones, std::map, int>, int>& boneGeometryMap, std::vector& boneGeometries, int geometryFileIndex, int modelIndex, MaterialData& materialData, const std::map& materialMaterialMap, const std::vector& materials, IExportSource* source, ProgressRange& progressRange) - { - XMLWriter::Element nodeElement(writer, "node"); - nodeElement.Attribute("id", name); // The ID must be unique. - nodeElement.Attribute("name", name); // The name must not include model name as prefix, so it can match the skeleton. - - // Calculate the transforms for the bone and its parent. This could be made a lot simpler by using proper - // transforms in the skeleton data. - Matrix34 transform; - { - Matrix44 transforms[2]; - int boneIndices[2] = {boneIndex, skeletonData.GetBoneParentIndex(boneIndex)}; - for (int i = 0; i < 2; ++i) - { - transforms[i] = IDENTITY; - - if (boneIndices[i] >= 0) - { - Vec3 scaleParams; - skeletonData.GetScale((float*)&scaleParams, boneIndices[i]); - Matrix44 scale = Matrix33::CreateScale(scaleParams); - - Ang3 rotationParams; - skeletonData.GetRotation((float*)&rotationParams, boneIndices[i]); - Matrix44 rotation = Matrix33::CreateRotationXYZ(rotationParams); - - Vec3 translationParams; - skeletonData.GetTranslation((float*)&translationParams, boneIndices[i]); - Matrix44 translation(IDENTITY); - translation.SetTranslation(translationParams); - - transforms[i] = translation * (rotation * scale); - } - } - transform = Matrix34(transforms[1].GetInverted() * transforms[0]); - } - - Vec3 translation, scaling; - CryQuat orientation; - DecomposeTransform(translation, orientation, scaling, transform); - Ang3 rotation = Ang3::GetAnglesXYZ(orientation); - - // Write translation element. - { - XMLWriter::Element translateElement(writer, "translate"); - translateElement.Attribute("sid", "translation"); - translateElement.ContentArrayElement(translation[0]); - translateElement.ContentArrayElement(translation[1]); - translateElement.ContentArrayElement(translation[2]); - } - - // Write rotation elements. - for (int axisIndex = 0; axisIndex < 3; ++axisIndex) - { - XMLWriter::Element rotateElement(writer, "rotate"); - char sidBuffer[1024]; - sprintf(sidBuffer, "rotation_%c", 'z' - axisIndex); - rotateElement.Attribute("sid", sidBuffer); - rotateElement.ContentArrayElement(axisIndex == 2 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(axisIndex == 1 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(axisIndex == 0 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(rotation[2 - axisIndex] * 180.0f / 3.14159f); - } - - // Write scale elements - { - XMLWriter::Element scaleElement(writer, "scale"); - scaleElement.Attribute("sid", "scale"); - scaleElement.ContentArrayElement(scaling[0]); - scaleElement.ContentArrayElement(scaling[1]); - scaleElement.ContentArrayElement(scaling[2]); - } - - // If the node has geometry, write out the reference to it. - std::map, int>, int>::iterator boneGeometryMapPos = boneGeometryMap.find(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), boneIndex)); - if (boneGeometryMapPos != boneGeometryMap.end()) - { - const std::string& boneGeometryName = boneGeometries[(*boneGeometryMapPos).second].name; - XMLWriter::Element instanceGeometryElement(writer, "instance_geometry"); - instanceGeometryElement.Attribute("url", std::string("#") + boneGeometryName); - - BindBoneMaterials(writer, context, materialData, skeletonData, boneIndex, materialMaterialMap, materials, source); - } - - SHelperData dummyHelperData; - WriteExtraData(writer, dummyHelperData, skeletonData.GetBoneProperties(boneIndex)); - - int childIndexCount = skeletonData.GetChildCount(boneIndex); - float progressRangeSlice = 1.0f / (childIndexCount > 0 ? float(childIndexCount) : 1.0f); - for (int childIndexIndex = 0; childIndexIndex < childIndexCount; ++childIndexIndex) - { - int childIndex = skeletonData.GetChildIndex(boneIndex, childIndexIndex); - WriteSkeletonRecurse(writer, context, modelName, skeletonData, childIndex, bones[childIndex].name, bones, boneGeometryMap, boneGeometries, geometryFileIndex, modelIndex, materialData, materialMaterialMap, materials, source, ProgressRange(progressRange, progressRangeSlice)); - } - } - - void WritePhysSkeletonRecurse(XMLWriter& writer, const std::string& modelName, const SkeletonData& skeletonData, int boneIndex, const std::vector& bones, ProgressRange& progressRange, const Matrix34& physFrameTM, const Matrix34& parentTM) - { - Matrix34 currentPhysFrameTM = physFrameTM; - - // Output a node for the parent frame. - bool shouldWriteParentFrame = skeletonData.HasParentFrame(boneIndex); - XMLWriter::Element parentFrameElement(writer, "node", shouldWriteParentFrame); - if (shouldWriteParentFrame) - { - parentFrameElement.Attribute("id", bones[boneIndex].parentFrameName); // The ID must be unique. - parentFrameElement.Attribute("name", bones[boneIndex].parentFrameName); // The name must not include model name as prefix, so it can match the skeleton. - - // Write translation element. - float translation[3]; - skeletonData.GetParentFrameTranslation(boneIndex, translation); - { - XMLWriter::Element translateElement(writer, "translate"); - translateElement.Attribute("sid", "translation"); - translateElement.ContentArrayElement(translation[0]); - translateElement.ContentArrayElement(translation[1]); - translateElement.ContentArrayElement(translation[2]); - } - - // Write rotation elements. - float rotation[3]; - skeletonData.GetParentFrameRotation(boneIndex, rotation); - for (int axisIndex = 0; axisIndex < 3; ++axisIndex) - { - XMLWriter::Element rotateElement(writer, "rotate"); - char sidBuffer[1024]; - sprintf(sidBuffer, "rotation_%c", 'z' - axisIndex); - rotateElement.Attribute("sid", sidBuffer); - rotateElement.ContentArrayElement(axisIndex == 2 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(axisIndex == 1 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(axisIndex == 0 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(rotation[2 - axisIndex] * 180.0f / 3.14159f); - } - - // Write scale elements - float scaling[3]; - skeletonData.GetParentFrameScale(boneIndex, scaling); - { - XMLWriter::Element scaleElement(writer, "scale"); - scaleElement.Attribute("sid", "scale"); - scaleElement.ContentArrayElement(scaling[0]); - scaleElement.ContentArrayElement(scaling[1]); - scaleElement.ContentArrayElement(scaling[2]); - } - - Matrix34 tm(IDENTITY); - Matrix34 translationTM(IDENTITY); - translationTM.SetTranslation(Vec3(translation[0], translation[1], translation[2])); - Matrix34 rotationTM = Matrix33::CreateRotationXYZ(Ang3(rotation[0], rotation[1], rotation[2])); - Matrix34 scaleTM = Matrix33::CreateScale(Vec3(scaling[0], scaling[1], scaling[2])); - Matrix34 transform = translationTM * (rotationTM * scaleTM); - - currentPhysFrameTM = transform * currentPhysFrameTM; - } - - Matrix34 worldTM; - { - float translation[3]; - skeletonData.GetTranslation(translation, boneIndex); - float rotation[3]; - skeletonData.GetRotation(rotation, boneIndex); - float scaling[3]; - skeletonData.GetScale(scaling, boneIndex); - Matrix34 tm(IDENTITY); - Matrix34 translationTM(IDENTITY); - translationTM.SetTranslation(Vec3(translation[0], translation[1], translation[2])); - Matrix34 rotationTM = Matrix33::CreateRotationXYZ(Ang3(rotation[0], rotation[1], rotation[2])); - Matrix34 scaleTM = Matrix33::CreateScale(Vec3(scaling[0], scaling[1], scaling[2])); - worldTM = translationTM * (rotationTM * scaleTM); - } - Matrix34 transform = parentTM.GetInverted() * worldTM; - - XMLWriter::Element nodeElement(writer, "node", skeletonData.GetPhysicalized(boneIndex)); - if (skeletonData.GetPhysicalized(boneIndex)) - { - Matrix34 physTM = currentPhysFrameTM.GetInverted() * worldTM; - Vec3 translation, scaling; - CryQuat orientation; - DecomposeTransform(translation, orientation, scaling, physTM); - Ang3 rotation = Ang3::GetAnglesXYZ(orientation); - - nodeElement.Attribute("id", bones[boneIndex].physName); // The ID must be unique. - nodeElement.Attribute("name", bones[boneIndex].physName); // The name must not include model name as prefix, so it can match the skeleton. - - // Write translation element. - { - XMLWriter::Element translateElement(writer, "translate"); - translateElement.Attribute("sid", "translation"); - translateElement.ContentArrayElement(translation[0]); - translateElement.ContentArrayElement(translation[1]); - translateElement.ContentArrayElement(translation[2]); - } - - // Write rotation elements. - for (int axisIndex = 0; axisIndex < 3; ++axisIndex) - { - XMLWriter::Element rotateElement(writer, "rotate"); - char sidBuffer[1024]; - sprintf(sidBuffer, "rotation_%c", 'z' - axisIndex); - rotateElement.Attribute("sid", sidBuffer); - rotateElement.ContentArrayElement(axisIndex == 2 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(axisIndex == 1 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(axisIndex == 0 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(rotation[2 - axisIndex] * 180.0f / 3.14159f); - } - - // Write scale elements - { - XMLWriter::Element scaleElement(writer, "scale"); - scaleElement.Attribute("sid", "scale"); - scaleElement.ContentArrayElement(scaling[0]); - scaleElement.ContentArrayElement(scaling[1]); - scaleElement.ContentArrayElement(scaling[2]); - } - - currentPhysFrameTM = worldTM; - } - - SHelperData dummyHelperData; - WriteExtraData(writer, dummyHelperData, skeletonData.GetBoneGeomProperties(boneIndex)); - - int childIndexCount = skeletonData.GetChildCount(boneIndex); - float progressRangeSlice = 1.0f / (childIndexCount > 0 ? float(childIndexCount) : 1.0f); - for (int childIndexIndex = 0; childIndexIndex < childIndexCount; ++childIndexIndex) - { - int childIndex = skeletonData.GetChildIndex(boneIndex, childIndexIndex); - WritePhysSkeletonRecurse(writer, modelName, skeletonData, childIndex, bones, ProgressRange(progressRange, progressRangeSlice), currentPhysFrameTM, worldTM); - } - } - - void WriteGeometryData(XMLWriter& writer, const std::string& id, const std::string& name, GeometryData& geometryData, MaterialData& materialData, std::map& materialMaterialMap, std::vector& materials) - { - XMLWriter::Element geometryElement(writer, "geometry"); - geometryElement.Attribute("id", id); - if (!name.empty()) - { - geometryElement.Attribute("name", name); - } - XMLWriter::Element meshElement(writer, "mesh"); - - // Write out the positions. - std::string posSourceName = id + "-pos"; - { - XMLWriter::Element sourceElement(writer, "source"); - sourceElement.Attribute("id", posSourceName); - - std::string arrayName = posSourceName + "-array"; - { - XMLWriter::Element arrayElement(writer, "float_array"); - arrayElement.Attribute("id", arrayName); - arrayElement.Attribute("count", int(geometryData.positions.size()) * 3); - for (int positionIndex = 0, positionCount = int(geometryData.positions.size()); positionIndex < positionCount; ++positionIndex) - { - arrayElement.ContentArrayElement(geometryData.positions[positionIndex].x); - arrayElement.ContentArrayElement(geometryData.positions[positionIndex].y); - arrayElement.ContentArrayElement(geometryData.positions[positionIndex].z); - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", std::string("#") + arrayName); - accessorElement.Attribute("count", int(geometryData.positions.size())); - accessorElement.Attribute("stride", 3); - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "X"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "Y"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "Z"); - paramElement.Attribute("type", "float"); - } - } - - // Write out the normals. - std::string normalSourceName = id + "-normal"; - { - XMLWriter::Element sourceElement(writer, "source"); - sourceElement.Attribute("id", normalSourceName); - - std::string arrayName = normalSourceName + "-array"; - { - XMLWriter::Element arrayElement(writer, "float_array"); - arrayElement.Attribute("id", arrayName); - arrayElement.Attribute("count", int(geometryData.normals.size()) * 3); - for (int normalIndex = 0, normalCount = int(geometryData.normals.size()); normalIndex < normalCount; ++normalIndex) - { - arrayElement.ContentArrayElement(geometryData.normals[normalIndex].x); - arrayElement.ContentArrayElement(geometryData.normals[normalIndex].y); - arrayElement.ContentArrayElement(geometryData.normals[normalIndex].z); - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", std::string("#") + arrayName); - accessorElement.Attribute("count", int(geometryData.normals.size())); - accessorElement.Attribute("stride", 3); - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "X"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "Y"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "Z"); - paramElement.Attribute("type", "float"); - } - } - - // Write out the texture coordinates. - std::string textureCoordinateSourceName = id + "-uvs"; - if (!geometryData.textureCoordinates.empty()) - { - XMLWriter::Element sourceElement(writer, "source"); - sourceElement.Attribute("id", textureCoordinateSourceName); - - std::string arrayName = textureCoordinateSourceName + "-array"; - { - XMLWriter::Element arrayElement(writer, "float_array"); - arrayElement.Attribute("id", arrayName); - arrayElement.Attribute("count", int(geometryData.textureCoordinates.size()) * 2); - for (int textureCoordinateIndex = 0, textureCoordinateCount = int(geometryData.textureCoordinates.size()); textureCoordinateIndex < textureCoordinateCount; ++textureCoordinateIndex) - { - arrayElement.ContentArrayElement(geometryData.textureCoordinates[textureCoordinateIndex].u); - arrayElement.ContentArrayElement(geometryData.textureCoordinates[textureCoordinateIndex].v); - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", std::string("#") + arrayName); - accessorElement.Attribute("count", int(geometryData.textureCoordinates.size())); - accessorElement.Attribute("stride", 2); - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "S"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "T"); - paramElement.Attribute("type", "float"); - } - } - - // Write out the vertex colors. - std::string vertexColorSourceName = id + "-vcol"; - if (!geometryData.vertexColors.empty()) - { - XMLWriter::Element sourceElement(writer, "source"); - sourceElement.Attribute("id", vertexColorSourceName); - - std::string arrayName = vertexColorSourceName + "-array"; - { - XMLWriter::Element arrayElement(writer, "float_array"); - arrayElement.Attribute("id", arrayName); - arrayElement.Attribute("count", int(geometryData.vertexColors.size()) * 4); - for (int vertexColorIndex = 0, vertexColorCount = int(geometryData.vertexColors.size()); vertexColorIndex < vertexColorCount; ++vertexColorIndex) - { - arrayElement.ContentArrayElement(geometryData.vertexColors[vertexColorIndex].r); - arrayElement.ContentArrayElement(geometryData.vertexColors[vertexColorIndex].g); - arrayElement.ContentArrayElement(geometryData.vertexColors[vertexColorIndex].b); - arrayElement.ContentArrayElement(geometryData.vertexColors[vertexColorIndex].a); - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", std::string("#") + arrayName); - accessorElement.Attribute("count", int(geometryData.vertexColors.size())); - accessorElement.Attribute("stride", 4); - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "R"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "G"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "B"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "A"); - paramElement.Attribute("type", "float"); - } - } - - // Write out the vertex elements. - std::string vertexName = id + "-vtx"; - { - XMLWriter::Element vertexElement(writer, "vertices"); - vertexElement.Attribute("id", vertexName); - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "POSITION"); - inputElement.Attribute("source", std::string("#") + posSourceName); - } - - // Sort the triangles by material. - std::vector > polygonsByMaterial(materialData.GetMaterialCount() + 1); - for (int polygonIndex = 0, polygonCount = int(geometryData.polygons.size()); polygonIndex < polygonCount; ++polygonIndex) - { - polygonsByMaterial[geometryData.polygons[polygonIndex].mtlID + 1].push_back(geometryData.polygons[polygonIndex]); - } - - // Write out the triangles. - for (int materialIndex = -1, materialCount = materialData.GetMaterialCount(); materialIndex < materialCount; ++materialIndex) - { - if (!polygonsByMaterial[materialIndex + 1].empty()) - { - std::map::iterator materialMapPos = materialMaterialMap.find(materialIndex); - int materialEntryIndex = (materialMapPos != materialMaterialMap.end() ? (*materialMapPos).second : -1); - - std::vector& polygons = polygonsByMaterial[materialIndex + 1]; - - XMLWriter::Element trianglesElement(writer, "triangles"); - trianglesElement.Attribute("count", int(polygons.size())); - if (materialEntryIndex >= 0) - { - trianglesElement.Attribute("material", materials[materialEntryIndex].name); - } - int offset = 0; - bool hasPositions = false; - if (!geometryData.positions.empty()) - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "VERTEX"); - inputElement.Attribute("source", std::string("#") + vertexName); - inputElement.Attribute("offset", offset++); - hasPositions = true; - } - bool hasNormals = false; - if (!geometryData.normals.empty()) - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "NORMAL"); - inputElement.Attribute("source", std::string("#") + normalSourceName); - inputElement.Attribute("offset", offset++); - hasNormals = true; - } - bool hasUVs = false; - if (!geometryData.textureCoordinates.empty()) - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "TEXCOORD"); - inputElement.Attribute("source", std::string("#") + textureCoordinateSourceName); - inputElement.Attribute("offset", offset++); - hasUVs = true; - } - bool hasColors = false; - if (!geometryData.vertexColors.empty()) - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "COLOR"); - inputElement.Attribute("source", std::string("#") + vertexColorSourceName); - inputElement.Attribute("offset", offset++); - hasColors = true; - } - - XMLWriter::Element pElement(writer, "p"); - for (int polygonIndex = 0, polygonCount = int(polygons.size()); polygonIndex < polygonCount; ++polygonIndex) - { - for (int vertexIndex = 0; vertexIndex < 3; ++vertexIndex) - { - if (hasPositions && polygons[polygonIndex].v[vertexIndex].positionIndex >= 0) - { - pElement.ContentArrayElement(polygons[polygonIndex].v[vertexIndex].positionIndex); - } - if (hasNormals && polygons[polygonIndex].v[vertexIndex].normalIndex >= 0) - { - pElement.ContentArrayElement(polygons[polygonIndex].v[vertexIndex].normalIndex); - } - if (hasUVs && polygons[polygonIndex].v[vertexIndex].textureCoordinateIndex >= 0) - { - pElement.ContentArrayElement(polygons[polygonIndex].v[vertexIndex].textureCoordinateIndex); - } - if (hasColors && polygons[polygonIndex].v[vertexIndex].vertexColorIndex >= 0) - { - pElement.ContentArrayElement(polygons[polygonIndex].v[vertexIndex].vertexColorIndex); - } - } - } - } - } - } - - bool WriteGeometries(IExportContext* context, XMLWriter& writer, std::vector& geometries, GeometryFileData& geometryFileData, const std::vector& modelData, MorphDataMap& morphData, MaterialData& materialData, std::vector& materials, std::map& materialMaterialMap, SkeletonDataMap& skeletonData, std::vector& boneGeometries, std::map, int>, int>& boneGeometryMap, std::map, int>, int>& morphGeometryMap, std::vector& morphGeometries, IExportSource* source, ProgressRange& progressRange) - { - XMLWriter::Element libraryGeometriesElement(writer, "library_geometries"); - - // Loop through all the geometries. - for (int geometryIndex = 0, geometryCount = int(geometries.size()); geometryIndex < geometryCount; ++geometryIndex) - { - GeometryEntry& geometryEntry = geometries[geometryIndex]; - - // Read in the geometry data. - GeometryData geometryData; - bool ok = source->ReadGeometry(context, &geometryData, &modelData[geometryEntry.geometryFileIndex], &materialData, geometryEntry.modelIndex); - if (!ok) - { - return false; - } - - WriteGeometryData(writer, geometryEntry.name, "", geometryData, materialData, materialMaterialMap, materials); - } - - // Loop through all the bone geometries. - for (int boneGeometryIndex = 0, boneGeometryCount = int(boneGeometries.size()); boneGeometryIndex < boneGeometryCount; ++boneGeometryIndex) - { - BoneGeometryEntry& boneGeometryEntry = boneGeometries[boneGeometryIndex]; - - GeometryData geometryData; - SkeletonDataMap::iterator skeletonDataPos = skeletonData.find(std::make_pair(boneGeometryEntry.geometryFileIndex, boneGeometryEntry.modelIndex)); - if (skeletonDataPos != skeletonData.end()) - { - source->ReadBoneGeometry(context, &geometryData, &(*skeletonDataPos).second, boneGeometryEntry.boneIndex, &materialData); - } - - WriteGeometryData(writer, boneGeometryEntry.name, "", geometryData, materialData, materialMaterialMap, materials); - } - - // Loop through all the morph geometries. - for (int morphGeometryIndex = 0, morphGeometryCount = int(morphGeometries.size()); morphGeometryIndex < morphGeometryCount; ++morphGeometryIndex) - { - MorphGeometryEntry& morphGeometryEntry = morphGeometries[morphGeometryIndex]; - - GeometryData geometryData; - MorphDataMap::iterator morphDataPos = morphData.find(std::make_pair(morphGeometryEntry.geometryFileIndex, morphGeometryEntry.modelIndex)); - if (morphDataPos != morphData.end()) - { - source->ReadMorphGeometry(context, &geometryData, &modelData[morphGeometryEntry.geometryFileIndex], morphGeometryEntry.modelIndex, &(*morphDataPos).second, morphGeometryEntry.morphIndex, &materialData); - } - - WriteGeometryData(writer, morphGeometryEntry.name, morphGeometryEntry.morphName, geometryData, materialData, materialMaterialMap, materials); - } - - return true; - } - - void WriteExportNodeProperties(const IExportSource& source, XMLWriter& writer, const char* geomFilename, const IGeometryFileData::SProperties& properties) - { - XMLWriter::Element elem(writer, "extra"); - { - XMLWriter::Element elem(writer, "technique"); - elem.Attribute("profile", "CryEngine"); - { - std::string const filetypeStr = ExportFileTypeHelpers::CryFileTypeToString(properties.filetypeInt); - std::string props = std::string("fileType=") + filetypeStr; - if (properties.bDoNotMerge) - { - props += std::string("\r\n") + "DoNotMerge"; - } - if (properties.bUseCustomNormals) - { - props += std::string("\r\n") + "UseCustomNormals"; - } - if (properties.filetypeInt == CRY_FILE_TYPE_SKIN && properties.b8WeightsPerVertex) - { - props += std::string("\r\n") + "EightWeightsPerVertex"; - } - if (properties.bUseF32VertexFormat) - { - props += std::string("\r\n") + "UseF32VertexFormat"; - } - - props += std::string("\r\n") + std::string("CustomExportPath=") + properties.customExportPath; - XMLWriter::Element elem(writer, "properties"); - elem.Content(props); - } - } - - // Write special properties for importing to the XSI. - { - XMLWriter::Element elem(writer, "technique"); - elem.Attribute("profile", "XSI"); - { - XMLWriter::Element elem(writer, "XSI_CustomPSet"); - elem.Attribute("name", "ExportProperties"); - { - XMLWriter::Element elem(writer, "propagation"); - elem.Content("NODE"); - } - { - XMLWriter::Element elem(writer, "type"); - elem.Content("CryExportNodeProperties"); - } - { - XMLWriter::Element elem(writer, "XSI_Parameter"); - elem.Attribute("id", "Filetype"); - elem.Attribute("type", "Integer"); - elem.Attribute("value", properties.filetypeInt); - } - { - XMLWriter::Element elem(writer, "XSI_Parameter"); - elem.Attribute("id", "Filename"); - elem.Attribute("type", "Text"); - elem.Attribute("value", geomFilename); - } - { - XMLWriter::Element elem(writer, "XSI_Parameter"); - elem.Attribute("id", "Exportable"); - elem.Attribute("type", "Boolean"); - elem.Attribute("value", "1"); - } - { - XMLWriter::Element elem(writer, "XSI_Parameter"); - elem.Attribute("id", "MergeObjects"); - elem.Attribute("type", "Boolean"); - elem.Attribute("value", (!properties.bDoNotMerge)); - } - } - } - } - - - void WriteHierarchyRecurse( - XMLWriter& writer, - IExportContext* context, - int geometryFileIndex, - MaterialData& materialData, - const std::map& materialMaterialMap, - const std::vector& materials, - const ModelData& modelData, - int const modelIndex, - std::map, int>& modelGeometryMap, - std::vector& geometries, - std::map, int>& modelControllerMap, - std::vector& controllers, - std::map, int>& modelMorphControllerMap, - std::vector& morphControllers, - IExportSource* source, - ProgressRange& progressRange) - { - XMLWriter::Element nodeElement(writer, "node"); - nodeElement.Attribute("id", modelData.GetModelName(modelIndex)); // The ID must be unique. - - { - float translation[3]; - float rotation[3]; - float scaling[3]; - modelData.GetTranslationRotationScale(modelIndex, translation, rotation, scaling); - - // Write translation element. - { - XMLWriter::Element translateElement(writer, "translate"); - translateElement.Attribute("sid", "translation"); - translateElement.ContentArrayElement(translation[0]); - translateElement.ContentArrayElement(translation[1]); - translateElement.ContentArrayElement(translation[2]); - } - - // Write rotation elements. - for (int axisIndex = 0; axisIndex < 3; ++axisIndex) - { - XMLWriter::Element rotateElement(writer, "rotate"); - char sidBuffer[1024]; - sprintf(sidBuffer, "rotation_%c", 'z' - axisIndex); - rotateElement.Attribute("sid", sidBuffer); - rotateElement.ContentArrayElement(axisIndex == 2 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(axisIndex == 1 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(axisIndex == 0 ? 1.0f : 0.0f); - rotateElement.ContentArrayElement(rotation[2 - axisIndex] * 180.0f / 3.14159f); - } - - // Write scale elements - { - XMLWriter::Element scaleElement(writer, "scale"); - scaleElement.Attribute("sid", "scale"); - scaleElement.ContentArrayElement(scaling[0]); - scaleElement.ContentArrayElement(scaling[1]); - scaleElement.ContentArrayElement(scaling[2]); - } - } - - // If the node has a controller, write out the reference to it. - std::map, int>::iterator modelControllerMapPos = modelControllerMap.find(std::make_pair(geometryFileIndex, modelIndex)); - std::map, int>::iterator modelMorphControllerMapPos = modelMorphControllerMap.find(std::make_pair(geometryFileIndex, modelIndex)); - if (modelControllerMapPos != modelControllerMap.end()) - { - const std::string& controllerName = controllers[(*modelControllerMapPos).second].name; - XMLWriter::Element instanceControllerElement(writer, "instance_controller"); - instanceControllerElement.Attribute("url", "#" + controllerName); - - BindMaterials(writer, context, materialData, modelData, modelIndex, materialMaterialMap, materials, source); - } - else if (modelMorphControllerMapPos != modelMorphControllerMap.end()) - { - const std::string& controllerName = morphControllers[(*modelMorphControllerMapPos).second].name; - XMLWriter::Element instanceControllerElement(writer, "instance_controller"); - instanceControllerElement.Attribute("url", "#" + controllerName); - - BindMaterials(writer, context, materialData, modelData, modelIndex, materialMaterialMap, materials, source); - } - else - { - // If the node has geometry, write out the reference to it. - std::map, int>::iterator modelGeometryMapPos = modelGeometryMap.find(std::make_pair(geometryFileIndex, modelIndex)); - if (modelGeometryMapPos != modelGeometryMap.end()) - { - const std::string& geometryName = geometries[(*modelGeometryMapPos).second].name; - XMLWriter::Element instanceGeometryElement(writer, "instance_geometry"); - instanceGeometryElement.Attribute("url", std::string("#") + geometryName); - - BindMaterials(writer, context, materialData, modelData, modelIndex, materialMaterialMap, materials, source); - } - } - - // Recurse to the child nodes. - int childIndexCount = modelData.GetChildCount(modelIndex); - float progressRangeSlice = 1.0f / (childIndexCount > 0 ? float(childIndexCount) : 1.0f); - for (int childIndexIndex = 0; childIndexIndex < childIndexCount; ++childIndexIndex) - { - int childIndex = modelData.GetChildIndex(modelIndex, childIndexIndex); - WriteHierarchyRecurse(writer, context, geometryFileIndex, materialData, materialMaterialMap, materials, modelData, childIndex, modelGeometryMap, geometries, modelControllerMap, controllers, modelMorphControllerMap, morphControllers, source, ProgressRange(progressRange, progressRangeSlice)); - } - - // Write properties, HelperData - WriteExtraData(writer, modelData.GetHelperData(modelIndex), modelData.GetProperties(modelIndex)); - } - - void WriteHierarchy( - XMLWriter& writer, - IExportContext* context, - const GeometryFileData& geometryFileData, - MaterialData& materialData, - const std::map& materialMaterialMap, - const std::vector& materials, - const std::vector& modelData, - SkeletonDataMap& skeletonData, - std::map, int>& modelGeometryMap, - std::vector& geometries, - std::map, int>& modelControllerMap, - std::vector& controllers, - BoneDataMap& boneDataMap, - std::map, int>, int>& boneGeometryMap, - std::vector& boneGeometries, - std::map, int>& modelMorphControllerMap, - std::vector& morphControllers, - IExportSource* source, - ProgressRange& progressRange) - { - XMLWriter::Element libraryVisualScenesElement(writer, "library_visual_scenes"); - XMLWriter::Element visualSceneElement(writer, "visual_scene"); - visualSceneElement.Attribute("id", "visual_scene_0"); - visualSceneElement.Attribute("name", "untitled"); - - int geometryFileCount = geometryFileData.GetGeometryFileCount(); - float geometryFileRangeSlice = 1.0f / (geometryFileCount > 0 ? float(geometryFileCount) : 1.0f); - for (int geometryFileIndex = 0; geometryFileIndex < geometryFileCount; ++geometryFileIndex) - { - ProgressRange geometryFileRange(progressRange, geometryFileRangeSlice); - - // Make sure to write out a LumberyardExportNode - this is expected by the RC. - std::string nodeName; - - nodeName = geometryFileData.GetGeometryFileName(geometryFileIndex); - XMLWriter::Element nodeElement(writer, "node"); - nodeElement.Attribute("id", nodeName); - nodeElement.Attribute(g_LumberyardExportNodeTag, true); - - // Write translation element. - { - XMLWriter::Element translateElement(writer, "translate"); - translateElement.Attribute("sid", "translation"); - translateElement.Content("0 0 0"); - } - - // Write rotation elements. - { - XMLWriter::Element rotateElement(writer, "rotate"); - rotateElement.Attribute("sid", "rotation_z"); - rotateElement.Content("0 0 1 0"); - } - - { - XMLWriter::Element rotateElement(writer, "rotate"); - rotateElement.Attribute("sid", "rotation_y"); - rotateElement.Content("0 1 0 0"); - } - - { - XMLWriter::Element rotateElement(writer, "rotate"); - rotateElement.Attribute("sid", "rotation_x"); - rotateElement.Content("1 0 0 0"); - } - - // Write scale elements - { - XMLWriter::Element scaleElement(writer, "scale"); - scaleElement.Attribute("sid", "scale"); - scaleElement.Content("1 1 1"); - } - - { - ProgressRange modelProgressRange(geometryFileRange, 0.5f); - int rootIndexCount = modelData[geometryFileIndex].GetRootCount(); - float progressRangeSlice = 1.0f / (rootIndexCount > 0 ? float(rootIndexCount) : 1.0f); - for (int rootIndexIndex = 0; rootIndexIndex < rootIndexCount; ++rootIndexIndex) - { - int rootModelIndex = modelData[geometryFileIndex].GetRootIndex(rootIndexIndex); - WriteHierarchyRecurse(writer, context, geometryFileIndex, materialData, materialMaterialMap, materials, modelData[geometryFileIndex], rootModelIndex, modelGeometryMap, geometries, modelControllerMap, controllers, modelMorphControllerMap, morphControllers, source, ProgressRange(modelProgressRange, progressRangeSlice)); - } - } - - { - ProgressRange skeletonProgressRange(geometryFileRange, 0.5f); - //write the skeleton for the first model in the geometry file only - //for (int modelIndex = 0, modelCount = modelData[geometryFileIndex].GetModelCount(); modelIndex < modelCount; ++modelIndex) - if (modelData[geometryFileIndex].GetModelCount() > 0) - { - int modelIndex = 0; - int modelCount = 1; - SkeletonDataMap::iterator skeletonDataPos = skeletonData.find(std::make_pair(geometryFileIndex, modelIndex)); - if (skeletonDataPos != skeletonData.end()) - { - SkeletonData& skeletonDataInstance = (*skeletonDataPos).second; - const std::vector& bones = (*boneDataMap.find(std::make_pair(geometryFileIndex, modelIndex))).second; - int rootIndexCount = skeletonDataInstance.GetRootCount(); - float progressRangeSlice = 1.0f / ((rootIndexCount > 0 ? float(rootIndexCount) : 1.0f) * modelCount); - for (int rootIndexIndex = 0; rootIndexIndex < rootIndexCount; ++rootIndexIndex) - { - int rootBoneIndex = skeletonDataInstance.GetRootIndex(rootIndexIndex); - WriteSkeletonRecurse(writer, context, geometryFileData.GetGeometryFileName(geometryFileIndex), skeletonDataInstance, rootBoneIndex, bones[rootBoneIndex].name, bones, boneGeometryMap, boneGeometries, geometryFileIndex, modelIndex, materialData, materialMaterialMap, materials, source, ProgressRange(skeletonProgressRange, progressRangeSlice * 0.5f)); - WritePhysSkeletonRecurse(writer, geometryFileData.GetGeometryFileName(geometryFileIndex), skeletonDataInstance, rootBoneIndex, bones, ProgressRange(skeletonProgressRange, progressRangeSlice * 0.5f), Matrix34(IDENTITY), Matrix34(IDENTITY)); - } - } - } - } - - // Write properties if they exist - WriteExportNodeProperties(*source, writer, geometryFileData.GetGeometryFileName(geometryFileIndex), geometryFileData.GetProperties(geometryFileIndex)); - } - } - - void WriteMetaData(IExportSource* pExportSource, XMLWriter& writer, ProgressRange& progressRange) - { - SExportMetaData metaData; - pExportSource->GetMetaData(metaData); - - XMLWriter::Element assetElement(writer, "asset"); - { - XMLWriter::Element contributorElement(writer, "contributor"); - contributorElement.Child("author", metaData.author); - contributorElement.Child("authoring_tool", metaData.authoring_tool); - contributorElement.Child("source_data", metaData.source_data); - } - - std::time_t time = std::time(0); - std::tm dateTime = *std::localtime(&time); - char scratchBuffer[1024]; - std::strftime(scratchBuffer, sizeof(scratchBuffer) / sizeof(scratchBuffer[0]), "%Y-%m-%dT%H:%M:%SZ", &dateTime); - assetElement.Child("created", scratchBuffer); - assetElement.Child("modified", scratchBuffer); - assetElement.Child("revision", metaData.revision); - { - XMLWriter::Element unitElement(writer, "unit"); - unitElement.Attribute("meter", metaData.fMeterUnit); - unitElement.Attribute("name", "meter"); - } - - switch (metaData.up_axis) - { - case SExportMetaData::X_UP: - assetElement.Child("up_axis", "X_UP"); - break; - case SExportMetaData::Y_UP: - assetElement.Child("up_axis", "Y_UP"); - break; - case SExportMetaData::Z_UP: - default: - assetElement.Child("up_axis", "Z_UP"); - break; - } - - int framesPerSecond = metaData.fFramesPerSecond <= 0.f ? 30 : static_cast(metaData.fFramesPerSecond); - sprintf_s(scratchBuffer, sizeof(scratchBuffer) / sizeof(scratchBuffer[0]), "%i", framesPerSecond); - XMLWriter::Element frameRateElement(writer, "framerate"); - frameRateElement.Attribute("fps", scratchBuffer); - } - - enum AnimationBoneParameter - { - AnimationBoneParameter_TransX, - AnimationBoneParameter_TransY, - AnimationBoneParameter_TransZ, - AnimationBoneParameter_RotX, - AnimationBoneParameter_RotY, - AnimationBoneParameter_RotZ, - AnimationBoneParameter_SclX, - AnimationBoneParameter_SclY, - AnimationBoneParameter_SclZ, - }; - const char* parameterStrings[] = { - "posx", - "posy", - "posz", - "rotx", - "roty", - "rotz", - "sclx", - "scly", - "sclz" - }; - const char* parameterTargetStrings[] = { - "translation.X", - "translation.Y", - "translation.Z", - "rotation_x.ANGLE", - "rotation_y.ANGLE", - "rotation_z.ANGLE", - "scale.X", - "scale.Y", - "scale.Z" - }; - struct AnimationBoneParameterEntry - { - std::string name; - int boneIndex; - AnimationBoneParameter parameter; - }; - struct AnimationEntry - { - std::string name; - int geometryFileIndex; - int modelIndex; - int animationIndex; - float start; - float stop; - std::vector parameters; - }; - void AddParametersRecursive(AnimationEntry& animation, AnimationData& animationData, const SkeletonData& skeletonData, int boneIndex, ProgressRange& progressRange) - { - for (AnimationBoneParameter parameter = AnimationBoneParameter_TransX; parameter <= AnimationBoneParameter_SclZ; parameter = AnimationBoneParameter(parameter + 1)) - { - animation.parameters.push_back(AnimationBoneParameterEntry()); - AnimationBoneParameterEntry& parameterEntry = animation.parameters.back(); - parameterEntry.boneIndex = boneIndex; - parameterEntry.parameter = parameter; - parameterEntry.name = animation.name + "-" + skeletonData.GetSafeName(boneIndex) + "_" + parameterStrings[parameter] + "-anim"; - - // Encode the flags as naming conventions. - unsigned modelFlags = animationData.GetModelFlags(boneIndex); - if (modelFlags & IAnimationData::ModelFlags_NoExport) - { - parameterEntry.name += "-NoExport"; - } - } - - int childIndexCount = skeletonData.GetChildCount(boneIndex); - float progressRangeSlice = 1.0f / (childIndexCount > 0 ? float(childIndexCount) : 1.0f); - for (int childIndexIndex = 0; childIndexIndex < childIndexCount; ++childIndexIndex) - { - AddParametersRecursive(animation, animationData, skeletonData, skeletonData.GetChildIndex(boneIndex, childIndexIndex), ProgressRange(progressRange, progressRangeSlice)); - } - } - - void AddParametersForNoSkeleton(AnimationEntry& animation, int modelIndex, const std::string& modelName, AnimationBoneParameter whichParameter) - { - for (AnimationBoneParameter parameter = whichParameter; parameter < whichParameter + 3; parameter = AnimationBoneParameter(parameter + 1)) - { - animation.parameters.push_back(AnimationBoneParameterEntry()); - AnimationBoneParameterEntry& parameterEntry = animation.parameters.back(); - parameterEntry.boneIndex = modelIndex; - parameterEntry.parameter = parameter; - parameterEntry.name = animation.name + "-" + modelName + "_" + parameterStrings[parameter] + "-anim"; - } - } - - void AddAnimationEntry(std::vector& animations, int animationIndex, int geometryFileIndex, int modelIndex, IExportSource* source, GeometryFileData& geometryFileData) - { - animations.push_back(AnimationEntry()); - AnimationEntry& animation = animations.back(); - animation.animationIndex = animationIndex; - animation.geometryFileIndex = geometryFileIndex; - animation.modelIndex = modelIndex; - - std::string safeAnimationName = source->GetAnimationName(&geometryFileData, geometryFileIndex, animationIndex); - std::replace(safeAnimationName.begin(), safeAnimationName.end(), ' ', '_'); - animation.name = safeAnimationName + std::string("-") + geometryFileData.GetGeometryFileName(geometryFileIndex); - source->GetAnimationTimeSpan(animation.start, animation.stop, animationIndex); - } - - void GenerateAnimationList(IExportContext* context, std::vector& animations, GeometryFileData& geometryFileData, const std::vector& modelData, SkeletonDataMap& skeletonData, IExportSource* source, ProgressRange& progressRange) - { - int geometryFileCount = geometryFileData.GetGeometryFileCount(); - float geometryFileProgressRangeSlice = 1.0f / (geometryFileCount > 0 ? float(geometryFileCount) : 1.0f); - for (int geometryFileIndex = 0; geometryFileIndex < geometryFileCount; ++geometryFileIndex) - { - ProgressRange geometryFileProgressRange(progressRange, geometryFileProgressRangeSlice); - - int modelCount = modelData[geometryFileIndex].GetModelCount(); - float modelProgressRangeSlice = 1.0f / (modelCount > 0 ? float(modelCount) : 1.0f); - - int animationCount = source->GetAnimationCount(); - float animProgressRangeSlice = 1.0f / (animationCount > 0 ? float(animationCount) : 1.0f); - for (int animationIndex = 0; animationIndex < animationCount; ++animationIndex) - { - ProgressRange animationProgressRange(geometryFileProgressRange, animProgressRangeSlice); - - if (skeletonData.empty()) // Non-skeletal mesh - { - AddAnimationEntry(animations, animationIndex, geometryFileIndex, -1, source, geometryFileData); - } - else // Skeletal mesh - { - AddAnimationEntry(animations, animationIndex, geometryFileIndex, 0, source, geometryFileData); - } - AnimationEntry& animation = animations.back(); - for (int modelIndex = 0; modelIndex < modelCount; ++modelIndex) - { - ProgressRange modelProgressRange(animationProgressRange, modelProgressRangeSlice); - - if (skeletonData.empty()) // Non-skeletal mesh - { - bool hasPos = source->HasValidPosController(&modelData[geometryFileIndex], modelIndex); - bool hasRot = source->HasValidRotController(&modelData[geometryFileIndex], modelIndex); - bool hasScl = source->HasValidSclController(&modelData[geometryFileIndex], modelIndex); - if (hasPos || hasRot || hasScl) - { - std::string modelName = modelData[geometryFileIndex].GetModelName(modelIndex); - std::replace_if(modelName.begin(), modelName.end(), std::isspace, '_'); - if (hasPos) - { - AddParametersForNoSkeleton(animation, modelIndex, modelName, - AnimationBoneParameter_TransX); - } - if (hasRot) - { - AddParametersForNoSkeleton(animation, modelIndex, modelName, - AnimationBoneParameter_RotX); - } - if (hasScl) - { - AddParametersForNoSkeleton(animation, modelIndex, modelName, - AnimationBoneParameter_SclX); - } - } - } - else // Skeletal mesh - { - ProgressRange animationProgressRange(modelProgressRange, animProgressRangeSlice); - - // Read the animation flags. - SkeletonDataMap::const_iterator skeletonDataPos = skeletonData.find(std::make_pair(geometryFileIndex, modelIndex)); - if (skeletonDataPos != skeletonData.end()) - { - const SkeletonData& skeletonDataInstance = (*skeletonDataPos).second; - float FPS = ExportGlobal::g_defaultFrameRate; // This is only used for reading flags, using the default since it will have no impact - AnimationData animationData(skeletonDataInstance.GetBoneCount(), FPS, 0); - source->ReadAnimationFlags(context, &animationData, &geometryFileData, &modelData[geometryFileIndex], modelIndex, &skeletonDataInstance, animationIndex); - - int rootIndexCount = skeletonDataInstance.GetRootCount(); - float rootProgressRangeSlice = 1.0f / (rootIndexCount > 0 ? float(rootIndexCount) : 1.0f); - for (int rootIndexIndex = 0; rootIndexIndex < rootIndexCount; ++rootIndexIndex) - { - ProgressRange rootProgressRange(animationProgressRange, rootProgressRangeSlice); - - int rootBoneIndex = skeletonDataInstance.GetRootIndex(rootIndexIndex); - - // Generate the list of animated parameters for this animation - by generating the names in one place, we can - // use them in both passes to refer to each other. - AddParametersRecursive(animation, animationData, skeletonDataInstance, rootBoneIndex, rootProgressRange); - } - } - } - } - } - } - } - - void GenerateSkinControllerList(IExportContext* context, std::vector& controllers, std::map, int>& modelControllerMap, SkeletonDataMap& skeletonData, GeometryFileData& geometryFileData, const std::vector& modelData, std::map, int>& modelGeometryMap, std::vector& geometries, ProgressRange& progressRange) - { - for (int geometryFileIndex = 0, geometryFileCount = geometryFileData.GetGeometryFileCount(); geometryFileIndex < geometryFileCount; ++geometryFileIndex) - { - for (int modelIndex = 0, modelCount = modelData[geometryFileIndex].GetModelCount(); modelIndex < modelCount; ++modelIndex) - { - std::map, int>::iterator modelGeometryPos = modelGeometryMap.find(std::make_pair(geometryFileIndex, modelIndex)); - SkeletonDataMap::const_iterator skeletonDataPos = skeletonData.find(std::make_pair(geometryFileIndex, modelIndex)); - if (skeletonDataPos != skeletonData.end() && modelGeometryPos != modelGeometryMap.end()) - { - const SkeletonData& skeleton = (*skeletonDataPos).second; - - int controllerIndex = int(controllers.size()); - controllers.resize(controllers.size() + 1); - - SkinControllerEntry& entry = controllers.back(); - char nameBuf[1024]; - sprintf(nameBuf, "controller_%d", controllerIndex); - entry.name = nameBuf; - entry.geometryFileIndex = geometryFileIndex; - entry.modelIndex = modelIndex; - - modelControllerMap.insert(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), controllerIndex)); - } - } - } - } - - void GenerateMorphControllerList(IExportContext* context, std::vector& morphControllers, std::map, int>& modelMorphControllerMap, MorphDataMap& morphData, GeometryFileData& geometryFileData, const std::vector& modelData, std::map, int>& modelGeometryMap, std::vector& geometries, ProgressRange& progressRange) - { - for (int geometryFileIndex = 0, geometryFileCount = geometryFileData.GetGeometryFileCount(); geometryFileIndex < geometryFileCount; ++geometryFileIndex) - { - for (int modelIndex = 0, modelCount = modelData[geometryFileIndex].GetModelCount(); modelIndex < modelCount; ++modelIndex) - { - std::map, int>::iterator modelGeometryPos = modelGeometryMap.find(std::make_pair(geometryFileIndex, modelIndex)); - MorphDataMap::const_iterator morphDataPos = morphData.find(std::make_pair(geometryFileIndex, modelIndex)); - if (morphDataPos != morphData.end() && modelGeometryPos != modelGeometryMap.end()) - { - int controllerIndex = int(morphControllers.size()); - morphControllers.resize(morphControllers.size() + 1); - - MorphControllerEntry& entry = morphControllers.back(); - char nameBuf[1024]; - sprintf(nameBuf, "morphController_%d", controllerIndex); - entry.name = nameBuf; - entry.geometryFileIndex = geometryFileIndex; - entry.modelIndex = modelIndex; - - modelMorphControllerMap.insert(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), controllerIndex)); - } - } - } - } - - void GenerateEffectsList(IExportContext* context, std::map& materialFXMap, std::vector& effects, MaterialData& materialData) - { - for (int materialIndex = 0, materialCount = materialData.GetMaterialCount(); materialIndex < materialCount; ++materialIndex) - { - std::string name; - - std::string mtlName = materialData.GetName(materialIndex); - assert(!mtlName.empty()); - - name = mtlName; - - char buffer[100]; - const int id = materialData.GetID(materialIndex); - assert(id >= 0); - sprintf(buffer, "-%d", id + 1); - - name += buffer; - - name += "-submat"; - - name += "-effect"; - - const int effectIndex = int(effects.size()); - effects.push_back(EffectsEntry(name)); - - materialFXMap.insert(std::make_pair(materialIndex, effectIndex)); - } - } - - void GenerateMaterialList(IExportContext* context, std::map& materialMaterialMap, std::map& materialFXMap, std::vector& effects, std::vector& materials, MaterialData& materialData) - { - for (int materialIndex = 0, materialCount = materialData.GetMaterialCount(); materialIndex < materialCount; ++materialIndex) - { - // Material needs to be named according to a specific format - this communicates information to - // the resource compiler about the settings to be used for the material. - // Format is: ____[__...] - - std::string name; - - std::string mtlName = materialData.GetName(materialIndex); - assert(!mtlName.empty()); - - std::string mtlProperties = materialData.GetProperties(materialIndex); - assert(!mtlProperties.empty()); - - name = mtlName; - - char buffer[100]; - const int id = materialData.GetID(materialIndex); - assert(id >= 0); - sprintf(buffer, "__%d", id + 1); - - name += buffer; - - name += "__"; - name += materialData.GetSubMatName(materialIndex); - - name += mtlProperties; - - const int index = int(materials.size()); - materials.push_back(MaterialEntry(name)); - - materialMaterialMap.insert(std::make_pair(materialIndex, index)); - } - } - - void GenerateGeometryList(IExportContext* context, std::map, int>& modelGeometryMap, std::vector& geometries, GeometryFileData& geometryFileData, const std::vector& modelData) - { - for (int geometryFileIndex = 0, geometryFileCount = geometryFileData.GetGeometryFileCount(); geometryFileIndex < geometryFileCount; ++geometryFileIndex) - { - for (int modelIndex = 0, modelCount = modelData[geometryFileIndex].GetModelCount(); modelIndex < modelCount; ++modelIndex) - { - if (modelData[geometryFileIndex].HasGeometry(modelIndex)) - { - std::string geometryName = std::string(geometryFileData.GetGeometryFileName(geometryFileIndex)) + "_" + modelData[geometryFileIndex].GetModelName(modelIndex) + "_geometry"; - int geometryIndex = int(geometries.size()); - geometries.push_back(GeometryEntry(geometryName, geometryFileIndex, modelIndex)); - modelGeometryMap.insert(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), geometryIndex)); - } - } - } - } - - void GenerateBoneGeometryList(IExportContext* context, std::map, int>, int>& boneGeometryMap, std::vector& boneGeometries, GeometryFileData& geometryFileData, const std::vector& modelData, SkeletonDataMap& skeletonData) - { - for (int geometryFileIndex = 0, geometryFileCount = geometryFileData.GetGeometryFileCount(); geometryFileIndex < geometryFileCount; ++geometryFileIndex) - { - for (int modelIndex = 0, modelCount = modelData[geometryFileIndex].GetModelCount(); modelIndex < modelCount; ++modelIndex) - { - SkeletonDataMap::iterator skeletonDataPos = skeletonData.find(std::make_pair(geometryFileIndex, modelIndex)); - if (skeletonDataPos != skeletonData.end()) - { - SkeletonData& modelSkeletonData = (*skeletonDataPos).second; - for (int boneIndex = 0, boneCount = modelSkeletonData.GetBoneCount(); boneIndex < boneCount; ++boneIndex) - { - if (modelSkeletonData.HasGeometry(boneIndex)) - { - std::string geometryName = std::string(geometryFileData.GetGeometryFileName(geometryFileIndex)) + "_" + modelData[geometryFileIndex].GetModelName(modelIndex) + "_" + modelSkeletonData.GetSafeName(boneIndex) + "_boneGeometry"; - int geometryIndex = int(boneGeometries.size()); - boneGeometries.push_back(BoneGeometryEntry(geometryName, geometryFileIndex, modelIndex, boneIndex)); - boneGeometryMap.insert(std::make_pair(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), boneIndex), geometryIndex)); - } - } - } - } - } - } - - void GenerateMorphGeometryList(IExportContext* context, std::map, int>, int>& morphGeometryMap, std::vector& morphGeometries, GeometryFileData& geometryFileData, const std::vector& modelData, MorphDataMap& morphData) - { - for (int geometryFileIndex = 0, geometryFileCount = geometryFileData.GetGeometryFileCount(); geometryFileIndex < geometryFileCount; ++geometryFileIndex) - { - for (int modelIndex = 0, modelCount = modelData[geometryFileIndex].GetModelCount(); modelIndex < modelCount; ++modelIndex) - { - MorphDataMap::iterator morphDataPos = morphData.find(std::make_pair(geometryFileIndex, modelIndex)); - if (morphDataPos != morphData.end()) - { - MorphData& modelMorphData = (*morphDataPos).second; - for (int morphIndex = 0, morphCount = modelMorphData.GetMorphCount(); morphIndex < morphCount; ++morphIndex) - { - std::string geometryName = std::string(geometryFileData.GetGeometryFileName(geometryFileIndex)) + "_" + modelData[geometryFileIndex].GetModelName(modelIndex) + "_" + modelMorphData.GetMorphFullName(morphIndex) + "_morphGeometry"; - int geometryIndex = int(morphGeometries.size()); - morphGeometries.push_back(MorphGeometryEntry(geometryName, modelMorphData.GetMorphName(morphIndex), geometryFileIndex, modelIndex, morphIndex)); - morphGeometryMap.insert(std::make_pair(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), morphIndex), geometryIndex)); - } - } - } - } - } - - void GenerateIKPropertyList(const SkeletonData& skeletonData, int boneIndex, std::vector >& propertyList) - { - // Loop through each axis, adding the properties for this axis to the list. - for (int axis = 0; axis < 3; ++axis) - { - // Add the limit properties for this axis. - const char* extremeNames[] = {"min", "max"}; - for (int extreme = 0; extreme < 2; ++extreme) - { - std::string key; - key += ('x' + axis); - key += extremeNames[extreme]; - if (skeletonData.HasLimit(boneIndex, ISkeletonData::Axis(axis), ISkeletonData::Limit(extreme))) - { - float limit = skeletonData.GetLimit(boneIndex, ISkeletonData::Axis(axis), ISkeletonData::Limit(extreme)); - char buffer[1024]; - sprintf(buffer, "%f", limit * 180.0f / 3.14159f); // Convert to degrees. - propertyList.push_back(std::make_pair(key, buffer)); - } - } - - // Add the remaining properties. - const char* propNames[] = {"damping", "springangle", "springtension"}; - typedef bool (SkeletonData::* HasMember)(int boneIndex, ISkeletonData::Axis axis) const; - typedef float (SkeletonData::* GetMember)(int boneIndex, ISkeletonData::Axis axis) const; - HasMember hasMembers[] = {&SkeletonData::HasAxisDamping, &SkeletonData::HasSpringAngle, &SkeletonData::HasSpringTension}; - GetMember getMembers[] = {&SkeletonData::GetAxisDamping, &SkeletonData::GetSpringAngle, &SkeletonData::GetSpringTension}; - for (int propIndex = 0; propIndex < 3; ++propIndex) - { - std::string key; - key += ('x' + axis); - key += propNames[propIndex]; - if ((skeletonData.*(hasMembers[propIndex]))(boneIndex, ISkeletonData::Axis(axis))) - { - float value = (skeletonData.*(getMembers[propIndex]))(boneIndex, ISkeletonData::Axis(axis)); - char buffer[1024]; - sprintf(buffer, "%f", value); - propertyList.push_back(std::make_pair(key, buffer)); - } - } - } - } - - void GenerateBoneList(IExportContext* context, BoneDataMap& boneDataMap, const SkeletonDataMap& skeletonData, const std::vector& modelData) - { - for (SkeletonDataMap::const_iterator skeletonDataPos = skeletonData.begin(), skeletonDataEnd = skeletonData.end(); skeletonDataPos != skeletonDataEnd; ++skeletonDataPos) - { - int geometryFileIndex = (*skeletonDataPos).first.first; - int modelIndex = (*skeletonDataPos).first.second; - const SkeletonData& skeleton = (*skeletonDataPos).second; - - BoneDataMap::iterator boneDataPos = boneDataMap.insert(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), std::vector())).first; - std::vector& bones = (*boneDataPos).second; - bones.resize(skeleton.GetBoneCount()); - - std::string modelName = modelData[geometryFileIndex].GetModelName(modelIndex); - - for (int boneIndex = 0, boneCount = skeleton.GetBoneCount(); boneIndex < boneCount; ++boneIndex) - { - typedef std::string BoneEntry::* BoneNamePtr; - BoneNamePtr boneNames[3] = {&BoneEntry::name, &BoneEntry::physName, &BoneEntry::parentFrameName}; - const char* suffixes[3] = {"", " Phys", " Phys ParentFrame"}; - std::vector > properties[3]; - - // Add the IK properties to the phys bone. - GenerateIKPropertyList(skeleton, boneIndex, properties[1]); - - for (int nameIndex = 0; nameIndex < 3; ++nameIndex) - { - std::string unsafeName = skeleton.GetName(boneIndex); - unsafeName += suffixes[nameIndex]; - bool containsSpaces = (unsafeName.find_first_of(" \t") != std::string::npos); - std::string name = unsafeName; - if (containsSpaces) - { - std::string overrideName = unsafeName; - std::replace_if(overrideName.begin(), overrideName.end(), std::isspace, '*'); - - std::string safeName = unsafeName; - std::replace_if(safeName.begin(), safeName.end(), std::isspace, '_'); - - name = safeName + "%" + modelName + "%" + "--PRprops_name=" + overrideName; - - // Add all the properties. - for (size_t propIndex = 0, propCount = properties[nameIndex].size(); propIndex < propCount; ++propIndex) - { - name += "_" + properties[nameIndex][propIndex].first + "=" + properties[nameIndex][propIndex].second; - } - - name += "__"; - } - else - { - name = unsafeName + "%" + modelName + "%"; - } - (bones[boneIndex].*(boneNames[nameIndex])) = name; - } - } - } - } - - void WriteAnimationList(XMLWriter& writer, std::vector& animations, ProgressRange& progressRange) - { - // Write out all the animations in the library_animation_clips element. Each animation lists the name and timespan - // of the clip, and the controllers for each model parameter. The actual animation data is written out in a separate pass. - XMLWriter::Element libraryAnimationClipsElement(writer, "library_animation_clips"); - - for (int animationEntryIndex = 0, animationEntryCount = int(animations.size()); animationEntryIndex < animationEntryCount; ++animationEntryIndex) - { - AnimationEntry& entry = animations[animationEntryIndex]; - - XMLWriter::Element animationClipElement(writer, "animation_clip"); - animationClipElement.Attribute("start", entry.start); - animationClipElement.Attribute("end", entry.stop); - animationClipElement.Attribute("id", entry.name); - - // For each parameter write out a reference to the controller for that parameter. - for (int parameterEntryIndex = 0, parameterEntryCount = int(entry.parameters.size()); parameterEntryIndex < parameterEntryCount; ++parameterEntryIndex) - { - AnimationBoneParameterEntry& parameter = entry.parameters[parameterEntryIndex]; - - XMLWriter::Element instanceAnimationElement(writer, "instance_animation"); - instanceAnimationElement.Attribute("url", std::string("#") + parameter.name); - } - } - } - - void WriteAnimationTags( - ProgressRange& animationEntryProgressRange, - const AnimationEntry& entry, - const IAnimationData* animationData, - XMLWriter& writer, - const std::vector* pBones, - const IModelData* pModelData) - { - // Loop through all the parameters of all the models. - ProgressRange writeAnimProgressRange(animationEntryProgressRange, 0.5f); - for (int parameterEntryIndex = 0, parameterEntryCount = int(entry.parameters.size()); parameterEntryIndex < parameterEntryCount; ++parameterEntryIndex) - { - const AnimationBoneParameterEntry& parameter = entry.parameters[parameterEntryIndex]; - - int frameCount = 0; - switch (parameter.parameter) - { - case AnimationBoneParameter_TransX: - case AnimationBoneParameter_TransY: - case AnimationBoneParameter_TransZ: - frameCount = animationData->GetFrameCountPos(parameter.boneIndex); - break; - case AnimationBoneParameter_RotX: - case AnimationBoneParameter_RotY: - case AnimationBoneParameter_RotZ: - frameCount = animationData->GetFrameCountRot(parameter.boneIndex); - break; - case AnimationBoneParameter_SclX: - case AnimationBoneParameter_SclY: - case AnimationBoneParameter_SclZ: - frameCount = animationData->GetFrameCountScl(parameter.boneIndex); - break; - } - - XMLWriter::Element animationElement(writer, "animation"); - animationElement.Attribute("id", parameter.name); - - std::string inputID = parameter.name + "-input"; - std::string outputID = parameter.name + "-output"; - std::string interpID = parameter.name + "-interp"; - std::string tcbID = parameter.name + "-tcb"; - std::string easeinoutID = parameter.name + "-easeinout"; - - // Write out the times. - { - XMLWriter::Element inputElement(writer, "source"); - inputElement.Attribute("id", inputID); - std::string arrayID = inputID + "-array"; - { - XMLWriter::Element array(writer, "float_array"); - array.Attribute("count", frameCount); - array.Attribute("id", arrayID); - - float floatBuffer[24]; - int bufferCount = 0; - for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) - { - switch (parameter.parameter) - { - case AnimationBoneParameter_TransX: - case AnimationBoneParameter_TransY: - case AnimationBoneParameter_TransZ: - floatBuffer[bufferCount++] = animationData->GetFrameTimePos(parameter.boneIndex, frameIndex); - break; - case AnimationBoneParameter_RotX: - case AnimationBoneParameter_RotY: - case AnimationBoneParameter_RotZ: - floatBuffer[bufferCount++] = animationData->GetFrameTimeRot(parameter.boneIndex, frameIndex); - break; - case AnimationBoneParameter_SclX: - case AnimationBoneParameter_SclY: - case AnimationBoneParameter_SclZ: - floatBuffer[bufferCount++] = animationData->GetFrameTimeScl(parameter.boneIndex, frameIndex); - break; - } - if (bufferCount == 24) - { - array.ContentArrayFloat24(floatBuffer, bufferCount); - bufferCount = 0; - } - } - if (bufferCount > 0) - { - array.ContentArrayFloat24(floatBuffer, bufferCount); - bufferCount = 0; - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", arrayID); - accessorElement.Attribute("count", frameCount); - accessorElement.Attribute("stride", 1); - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "TIME"); - paramElement.Attribute("type", "float"); - } - - // Write out the values. - { - XMLWriter::Element inputElement(writer, "source"); - inputElement.Attribute("id", outputID); - std::string arrayID = outputID + "-array"; - { - XMLWriter::Element array(writer, "float_array"); - array.Attribute("count", frameCount); - array.Attribute("id", arrayID); - - float floatBuffer[24]; - int bufferCount = 0; - for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) - { - const float* translation, * rotation, * scale; - switch (parameter.parameter) - { - case AnimationBoneParameter_TransX: - case AnimationBoneParameter_TransY: - case AnimationBoneParameter_TransZ: - animationData->GetFrameDataPos(parameter.boneIndex, frameIndex, translation); - floatBuffer[bufferCount++] = translation[parameter.parameter - AnimationBoneParameter_TransX]; - break; - case AnimationBoneParameter_RotX: - case AnimationBoneParameter_RotY: - case AnimationBoneParameter_RotZ: - animationData->GetFrameDataRot(parameter.boneIndex, frameIndex, rotation); - floatBuffer[bufferCount++] = rotation[parameter.parameter - AnimationBoneParameter_RotX]; - break; - case AnimationBoneParameter_SclX: - case AnimationBoneParameter_SclY: - case AnimationBoneParameter_SclZ: - animationData->GetFrameDataScl(parameter.boneIndex, frameIndex, scale); - floatBuffer[bufferCount++] = scale[parameter.parameter - AnimationBoneParameter_SclX]; - break; - } - if (bufferCount == 24) - { - array.ContentArrayFloat24(floatBuffer, bufferCount); - bufferCount = 0; - } - } - if (bufferCount > 0) - { - array.ContentArrayFloat24(floatBuffer, bufferCount); - bufferCount = 0; - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", arrayID); - accessorElement.Attribute("count", frameCount); - accessorElement.Attribute("stride", 1); - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "VALUE"); - paramElement.Attribute("type", "float"); - } - - // Write out the interpolation method. - { - XMLWriter::Element inputElement(writer, "source"); - inputElement.Attribute("id", interpID); - std::string arrayID = interpID + "-array"; - { - XMLWriter::Element array(writer, "Name_array"); - array.Attribute("count", frameCount); - array.Attribute("id", arrayID); - for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) - { - array.WriteDirectText(" CONSTANT"); - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", arrayID); - accessorElement.Attribute("count", frameCount); - accessorElement.Attribute("stride", 1); - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "INTERPOLATION"); - paramElement.Attribute("type", "Name"); - } - - if (pModelData) // only for the non-skeletal animation - { - // Write out the TCB values. - { - const int stride = 3; - XMLWriter::Element inputElement(writer, "source"); - inputElement.Attribute("id", tcbID); - std::string arrayID = tcbID + "-array"; - { - XMLWriter::Element array(writer, "float_array"); - array.Attribute("count", frameCount * stride); - array.Attribute("id", arrayID); - for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) - { - IAnimationData::TCB tcb; - switch (parameter.parameter) - { - case AnimationBoneParameter_TransX: - case AnimationBoneParameter_TransY: - case AnimationBoneParameter_TransZ: - animationData->GetFrameTCBPos(parameter.boneIndex, frameIndex, tcb); - break; - case AnimationBoneParameter_RotX: - case AnimationBoneParameter_RotY: - case AnimationBoneParameter_RotZ: - animationData->GetFrameTCBRot(parameter.boneIndex, frameIndex, tcb); - break; - case AnimationBoneParameter_SclX: - case AnimationBoneParameter_SclY: - case AnimationBoneParameter_SclZ: - animationData->GetFrameTCBScl(parameter.boneIndex, frameIndex, tcb); - break; - } - array.ContentArrayElement(tcb.tension); - array.ContentArrayElement(tcb.continuity); - array.ContentArrayElement(tcb.bias); - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", arrayID); - accessorElement.Attribute("count", frameCount); - accessorElement.Attribute("stride", stride); - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "TENSION"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "CONTINUITY"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "BIAS"); - paramElement.Attribute("type", "float"); - } - } - - // Write out the ease-in/-out values. - { - const int stride = 2; - XMLWriter::Element inputElement(writer, "source"); - inputElement.Attribute("id", easeinoutID); - std::string arrayID = easeinoutID + "-array"; - { - XMLWriter::Element array(writer, "float_array"); - array.Attribute("count", frameCount * stride); - array.Attribute("id", arrayID); - for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) - { - IAnimationData::Ease ease; - switch (parameter.parameter) - { - case AnimationBoneParameter_TransX: - case AnimationBoneParameter_TransY: - case AnimationBoneParameter_TransZ: - animationData->GetFrameEaseInOutPos(parameter.boneIndex, frameIndex, ease); - break; - case AnimationBoneParameter_RotX: - case AnimationBoneParameter_RotY: - case AnimationBoneParameter_RotZ: - animationData->GetFrameEaseInOutRot(parameter.boneIndex, frameIndex, ease); - break; - case AnimationBoneParameter_SclX: - case AnimationBoneParameter_SclY: - case AnimationBoneParameter_SclZ: - animationData->GetFrameEaseInOutScl(parameter.boneIndex, frameIndex, ease); - break; - } - array.ContentArrayElement(ease.in); - array.ContentArrayElement(ease.out); - } - } - - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", arrayID); - accessorElement.Attribute("count", frameCount); - accessorElement.Attribute("stride", stride); - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "EASE_IN"); - paramElement.Attribute("type", "float"); - } - { - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "EASE_OUT"); - paramElement.Attribute("type", "float"); - } - } - } - - // Write out the sampler element. - std::string samplerID = parameter.name + "-sampler"; - { - XMLWriter::Element samplerElement(writer, "sampler"); - samplerElement.Attribute("id", samplerID); - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "INPUT"); - inputElement.Attribute("source", std::string("#") + inputID); - } - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "OUTPUT"); - inputElement.Attribute("source", std::string("#") + outputID); - } - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "INTERPOLATION"); - inputElement.Attribute("source", std::string("#") + interpID); - } - if (pModelData) // only for the non-skeletal animation - { - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "TCB"); - inputElement.Attribute("source", std::string("#") + tcbID); - } - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "EASE_IN_OUT"); - inputElement.Attribute("source", std::string("#") + easeinoutID); - } - } - } - - // Write out the channel element. - XMLWriter::Element channelElement(writer, "channel"); - channelElement.Attribute("source", std::string("#") + samplerID); - std::string targetName; - if (pBones) - { - targetName = (*pBones)[parameter.boneIndex].name; - } - else - { - assert(pModelData); - targetName = pModelData->GetModelName(parameter.boneIndex); - } - targetName = targetName + "/" + parameterTargetStrings[parameter.parameter]; - channelElement.Attribute("target", targetName); - } - } - - void WriteAnimationData( - IExportContext* context, - XMLWriter& writer, - std::vector& animations, - GeometryFileData& geometryFileData, - const std::vector& modelData, - SkeletonDataMap& skeletonData, - const BoneDataMap& boneDataMap, - IExportSource* source, - ProgressRange& progressRange) - { - XMLWriter::Element libraryAnimationsElement(writer, "library_animations"); - - int animationEntryCount = int(animations.size()); - float animationEntryProgressSlice = (1.0f / (animationEntryCount ? float(animationEntryCount) : 1.0f)); - for (int animationEntryIndex = 0; animationEntryIndex < animationEntryCount; ++animationEntryIndex) - { - float FPS = source->GetDCCFrameRate(); - ProgressRange animationEntryProgressRange(progressRange, animationEntryProgressSlice); - - AnimationEntry& entry = animations[animationEntryIndex]; - - if (skeletonData.empty()) // Non-skeletal mesh - { - IAnimationData* animationData = NULL; - { - ProgressRange readAnimProgressRange(animationEntryProgressRange, 0.5f); - animationData = source->ReadAnimation(context, &geometryFileData, &modelData[0], -1, NULL, animationEntryIndex, FPS); - } - - if (animationData) - { - WriteAnimationTags(animationEntryProgressRange, entry, animationData, writer, NULL, &modelData[0]); - delete animationData; - } - } - else // Skeletal mesh - { - // Read the animation data. - SkeletonDataMap::const_iterator skeletonDataPos = skeletonData.find(std::make_pair(entry.geometryFileIndex, entry.modelIndex)); - if (skeletonDataPos != skeletonData.end()) - { - IAnimationData* animationData = NULL; - const SkeletonData& skeletonDataInstance = (*skeletonDataPos).second; - { - ProgressRange readAnimProgressRange(animationEntryProgressRange, 0.5f); - - animationData = source->ReadAnimation(context, &geometryFileData, &modelData[entry.modelIndex], entry.modelIndex, &skeletonDataInstance, entry.animationIndex, FPS); - } - - // Look up the bone entries for this model. - BoneDataMap::const_iterator boneDataPos = boneDataMap.find(std::make_pair(entry.geometryFileIndex, entry.modelIndex)); - const std::vector& bones = (*boneDataPos).second; - - if (animationData) - { - WriteAnimationTags(animationEntryProgressRange, entry, animationData, writer, &bones, NULL); - delete animationData; - } - } - } - } - } - - void WriteEffects(XMLWriter& writer, std::vector& effects, ProgressRange& progressRange) - { - XMLWriter::Element libraryEffectsElement(writer, "library_effects"); - for (int effectIndex = 0, effectCount = int(effects.size()); effectIndex < effectCount; ++effectIndex) - { - XMLWriter::Element effectElement(writer, "effect"); - effectElement.Attribute("id", effects[effectIndex].name); - - // Write out dummy effects values. - XMLWriter::Element profileElement(writer, "profile_COMMON"); - XMLWriter::Element techniqueElement(writer, "technique"); - techniqueElement.Attribute("sid", "default"); - XMLWriter::Element phongElement(writer, "phong"); - { - XMLWriter::Element emissionElement(writer, "emission"); - XMLWriter::Element colorElement(writer, "color"); - colorElement.Attribute("sid", "emission"); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(1.0f); - } - { - XMLWriter::Element ambientElement(writer, "ambient"); - XMLWriter::Element colorElement(writer, "color"); - colorElement.Attribute("sid", "ambient"); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(1.0f); - } - { - XMLWriter::Element diffuseElement(writer, "diffuse"); - XMLWriter::Element colorElement(writer, "color"); - colorElement.Attribute("sid", "diffuse"); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(1.0f); - } - { - XMLWriter::Element specularElement(writer, "specular"); - XMLWriter::Element colorElement(writer, "color"); - colorElement.Attribute("sid", "specular"); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(1.0f); - } - { - XMLWriter::Element shininessElement(writer, "shininess"); - XMLWriter::Element floatElement(writer, "float"); - floatElement.Attribute("sid", "shininess"); - floatElement.ContentArrayElement(0.0f); - } - { - XMLWriter::Element reflectiveElement(writer, "reflective"); - XMLWriter::Element colorElement(writer, "color"); - colorElement.Attribute("sid", "reflective"); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(1.0f); - } - { - XMLWriter::Element reflectivityElement(writer, "reflectivity"); - XMLWriter::Element floatElement(writer, "float"); - floatElement.Attribute("sid", "reflectivity"); - floatElement.ContentArrayElement(0.0f); - } - { - XMLWriter::Element transparentElement(writer, "transparent"); - transparentElement.Attribute("opaque", "RGB_ZERO"); - XMLWriter::Element colorElement(writer, "color"); - colorElement.Attribute("sid", "transparent"); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - colorElement.ContentArrayElement(0.0f); - } - { - XMLWriter::Element transparencyElement(writer, "transparency"); - XMLWriter::Element floatElement(writer, "float"); - floatElement.Attribute("sid", "transparency"); - floatElement.ContentArrayElement(0.0f); - } - { - XMLWriter::Element refractionElement(writer, "index_of_refraction"); - XMLWriter::Element floatElement(writer, "float"); - floatElement.Attribute("sid", "index_of_refraction"); - floatElement.ContentArrayElement(0.0f); - } - } - } - - void WriteControllers( - XMLWriter& writer, - IExportContext* context, - IExportSource* exportSource, - std::vector& skinControllers, - std::vector& morphControllers, - std::map, int> modelMorphControllerMap, - GeometryFileData& geometryFileData, - const std::vector& modelData, - SkeletonDataMap& skeletonData, - MorphDataMap& morphData, - std::vector& morphGeometries, - std::map, int>, int>& morphGeometryMap, - std::vector& geometries, - std::map, int>& modelGeometryMap, - const BoneDataMap& boneDataMap, - ProgressRange& progressRange) - { - // - XMLWriter::Element libraryControllersElement(writer, "library_controllers"); - for (int controllerIndex = 0, controllerCount = int(skinControllers.size()); controllerIndex < controllerCount; ++controllerIndex) - { - SkinControllerEntry& controller = skinControllers[controllerIndex]; - SkeletonDataMap::iterator skeletonDataPos = skeletonData.find(std::make_pair(controller.geometryFileIndex, controller.modelIndex)); - if (skeletonDataPos == skeletonData.end()) - { - continue; - } - - SkeletonData skeleton = (*skeletonDataPos).second; - - // - XMLWriter::Element controllerElement(writer, "controller"); - controllerElement.Attribute("id", controller.name); - - // - std::string geometryName; - bool sourceFound = false; - { - std::map, int>::const_iterator modelMorphControllerMapPos = modelMorphControllerMap.find(std::make_pair(controller.geometryFileIndex, controller.modelIndex)); - int morphControllerIndex = (modelMorphControllerMapPos != modelMorphControllerMap.end() ? (*modelMorphControllerMapPos).second : -1); - geometryName = (morphControllerIndex >= 0 ? morphControllers[morphControllerIndex].name : "MISSING MORPH CONTROLLER NAME"); - sourceFound = (morphControllerIndex >= 0); - } - if (!sourceFound) - { - std::map, int>::const_iterator geometryMapPos = modelGeometryMap.find(std::make_pair(controller.geometryFileIndex, controller.modelIndex)); - int geometryIndex = (geometryMapPos != modelGeometryMap.end() ? (*geometryMapPos).second : -1); - geometryName = (geometryIndex >= 0 ? geometries[geometryIndex].name : "MISSING GEOMETRY NAME"); - sourceFound = (geometryIndex >= 0); - } - XMLWriter::Element skinElement(writer, "skin"); - skinElement.Attribute("source", "#" + geometryName); - - // - // 1.000000 0.000000 0.000000 0.000000 - // 0.000000 1.000000 0.000000 0.000000 - // 0.000000 0.000000 1.000000 0.000000 - // 0.000000 0.000000 0.000000 1.000000 - // - { - XMLWriter::Element bindMatrixElement(writer, "bind_shape_matrix"); - bindMatrixElement.ContentArrayElement(1.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(1.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(1.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(0.0f); - bindMatrixElement.ContentArrayElement(1.0f); - } - - // - std::string jointsSourceName = controller.name + "_joints"; - { - XMLWriter::Element jointsSourceElement(writer, "source"); - jointsSourceElement.Attribute("id", jointsSourceName); - - // - const std::vector& bones = (*boneDataMap.find(std::make_pair(controller.geometryFileIndex, controller.modelIndex))).second; - std::string arrayName = jointsSourceName + "_array"; - { - XMLWriter::Element idArrayElement(writer, "IDREF_array"); - idArrayElement.Attribute("id", arrayName); - idArrayElement.Attribute("count", skeleton.GetBoneCount()); - for (int boneIndex = 0, boneCount = skeleton.GetBoneCount(); boneIndex < boneCount; ++boneIndex) - { - idArrayElement.ContentArrayElement(bones[boneIndex].name); - } - } - - // - { - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - // - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("count", skeleton.GetBoneCount()); - accessorElement.Attribute("stride", 1); - accessorElement.Attribute("source", "#" + arrayName); - - // - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("type", std::string("IDREF")); - // - // - // - } - } - - // - std::string matricesSourceName = controller.name + "_matrices"; - { - XMLWriter::Element sourceElement(writer, "source"); - sourceElement.Attribute("id", matricesSourceName); - - // - std::string arrayName = matricesSourceName + "_array"; - { - XMLWriter::Element arrayElement(writer, "float_array"); - arrayElement.Attribute("id", arrayName); - arrayElement.Attribute("count", skeleton.GetBoneCount() * 16); - arrayElement.ContentLine(""); - for (int boneIndex = 0, boneCount = skeleton.GetBoneCount(); boneIndex < boneCount; ++boneIndex) - { - Vec3 scaleParams; - skeleton.GetScale((float*)&scaleParams, boneIndex); - Matrix44 scale = Matrix33::CreateScale(scaleParams); - - Ang3 rotationParams; - skeleton.GetRotation((float*)&rotationParams, boneIndex); - Matrix44 rotation = Matrix33::CreateRotationXYZ(rotationParams); - - Vec3 translationParams; - skeleton.GetTranslation((float*)&translationParams, boneIndex); - Matrix44 translation(IDENTITY); - translation.SetTranslation(translationParams); - - Matrix44 transform = translation * (rotation * scale); - transform.Invert(); - for (int i = 0; i < 4; ++i) - { - for (int j = 0; j < 4; ++j) - { - arrayElement.ContentArrayElement(transform(i, j)); - } - arrayElement.ContentLine(""); - } - } - } - - // - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - - // - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("count", skeleton.GetBoneCount()); - accessorElement.Attribute("stride", 16); - accessorElement.Attribute("source", "#" + arrayName); - - // - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("type", std::string("float4x4")); - - // - // - // - } - - // Read in the skinning info. - SkinningData skinningData; - exportSource->ReadSkinning(context, &skinningData, &modelData[controller.geometryFileIndex], controller.modelIndex, &skeleton); - - // Build a single array of weights. - std::vector weightsArray; - std::vector > weightIndexArray; - int vertexCount = skinningData.GetVertexCount(); - weightIndexArray.resize(vertexCount); - for (int vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) - { - int linkCount = skinningData.GetBoneLinkCount(vertexIndex); - weightIndexArray[vertexIndex].resize(linkCount); - for (int linkIndex = 0; linkIndex < linkCount; ++linkIndex) - { - int weightIndex = int(weightsArray.size()); - weightsArray.push_back(skinningData.GetWeight(vertexIndex, linkIndex)); - weightIndexArray[vertexIndex][linkIndex] = weightIndex; - } - } - - // - std::string weightsSourceName = controller.name + "_weights"; - { - XMLWriter::Element weightsSourceElement(writer, "source"); - weightsSourceElement.Attribute("id", weightsSourceName); - - // - int weightCount = int(weightsArray.size()); - std::string arrayName = weightsSourceName + "_array"; - { - XMLWriter::Element floatArrayElement(writer, "float_array"); - floatArrayElement.Attribute("count", weightCount); - floatArrayElement.Attribute("id", arrayName); - - for (int weightIndex = 0; weightIndex < weightCount; ++weightIndex) - { - floatArrayElement.ContentArrayElement(weightsArray[weightIndex]); - } - } - - // - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - - // - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("count", weightCount); - accessorElement.Attribute("stride", 1); - accessorElement.Attribute("source", "#" + arrayName); - - // - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("type", "float"); - - // - // - // - } - - { - // - XMLWriter::Element jointsElement(writer, "joints"); - - // - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "JOINT"); - inputElement.Attribute("source", "#" + jointsSourceName); - } - - // - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "INV_BIND_MATRIX"); - inputElement.Attribute("source", "#" + matricesSourceName); - } - - // - } - - { - // - XMLWriter::Element vertexWeightsElement(writer, "vertex_weights"); - int vertexCount = skinningData.GetVertexCount(); - vertexWeightsElement.Attribute("count", vertexCount); - - // - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "JOINT"); - inputElement.Attribute("offset", 0); - inputElement.Attribute("source", "#" + jointsSourceName); - } - - // - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "WEIGHT"); - inputElement.Attribute("offset", 1); - inputElement.Attribute("source", "#" + weightsSourceName); - } - - // - { - XMLWriter::Element vcountElement(writer, "vcount"); - - for (int vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) - { - vcountElement.ContentArrayElement(int(weightIndexArray[vertexIndex].size())); - } - } - - // - { - XMLWriter::Element vElement(writer, "v"); - vElement.ContentLine(""); - - for (int vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) - { - for (int linkIndex = 0, linkCount = int(weightIndexArray[vertexIndex].size()); linkIndex < linkCount; ++linkIndex) - { - vElement.ContentArrayElement(skinningData.GetBoneIndex(vertexIndex, linkIndex)); - vElement.ContentArrayElement(weightIndexArray[vertexIndex][linkIndex]); - } - vElement.ContentLine(""); - } - - // - } - // - } - - // - // - // - } - - // Write out the morph controllers. - for (int controllerIndex = 0, controllerCount = int(morphControllers.size()); controllerIndex < controllerCount; ++controllerIndex) - { - MorphControllerEntry& controller = morphControllers[controllerIndex]; - - // Find the geometry and morphs for the model. - std::map, int>::const_iterator modelGeometryMapPos = modelGeometryMap.find(std::make_pair(controller.geometryFileIndex, controller.modelIndex)); - MorphDataMap::const_iterator modelMorphDataPos = morphData.find(std::make_pair(controller.geometryFileIndex, controller.modelIndex)); - - if (modelGeometryMapPos != modelGeometryMap.end() && modelMorphDataPos != morphData.end()) - { - GeometryEntry& geometry = geometries[(*modelGeometryMapPos).second]; - const MorphData& modelMorphData = (*modelMorphDataPos).second; - - XMLWriter::Element controllerElement(writer, "controller"); - controllerElement.Attribute("id", controller.name); - XMLWriter::Element morphElement(writer, "morph"); - morphElement.Attribute("source", "#" + geometry.name); - - std::string targetsSourceID = controller.name + "-source_targets"; - { - XMLWriter::Element sourceElement(writer, "source"); - sourceElement.Attribute("id", targetsSourceID); - std::string arrayID = targetsSourceID + "-array"; - { - XMLWriter::Element idrefArrayElement(writer, "IDREF_array"); - idrefArrayElement.Attribute("id", arrayID); - idrefArrayElement.Attribute("count", modelMorphData.GetMorphCount()); - for (int morphIndex = 0, morphCount = modelMorphData.GetMorphCount(); morphIndex < morphCount; ++morphIndex) - { - // Look up the geometry for this morph. - //std::vector& morphGeometries - std::map, int>, int>::const_iterator morphGeometryMapPos = morphGeometryMap.find(std::make_pair(std::make_pair(controller.geometryFileIndex, controller.modelIndex), morphIndex)); - int morphGeometryIndex = (morphGeometryMapPos != morphGeometryMap.end() ? (*morphGeometryMapPos).second : -1); - if (morphGeometryIndex >= -1) - { - const MorphGeometryEntry& morphGeometry = morphGeometries[morphGeometryIndex]; - idrefArrayElement.ContentArrayElement(morphGeometry.name); - } - } - } - { - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", "#" + arrayID); - accessorElement.Attribute("count", modelMorphData.GetMorphCount()); - accessorElement.Attribute("offset", 0); - accessorElement.Attribute("stride", 1); - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "MORPH_TARGET"); - paramElement.Attribute("type", "IDREF"); - } - } - std::string weightsSourceID = controller.name + "-source_weights"; - { - XMLWriter::Element sourceElement(writer, "source"); - sourceElement.Attribute("id", weightsSourceID); - std::string arrayID = weightsSourceID + "-array"; - { - XMLWriter::Element floatArrayElement(writer, "float_array"); - floatArrayElement.Attribute("id", arrayID); - floatArrayElement.Attribute("count", modelMorphData.GetMorphCount()); - for (int morphIndex = 0, morphCount = modelMorphData.GetMorphCount(); morphIndex < morphCount; ++morphIndex) - { - // Look up the geometry for this morph. - //std::vector& morphGeometries - std::map, int>, int>::const_iterator morphGeometryMapPos = morphGeometryMap.find(std::make_pair(std::make_pair(controller.geometryFileIndex, controller.modelIndex), morphIndex)); - int morphGeometryIndex = (morphGeometryMapPos != morphGeometryMap.end() ? (*morphGeometryMapPos).second : -1); - if (morphGeometryIndex >= -1) - { - const MorphGeometryEntry& morphGeometry = morphGeometries[morphGeometryIndex]; - floatArrayElement.ContentArrayElement(0); - } - } - } - { - XMLWriter::Element techniqueCommonElement(writer, "technique_common"); - XMLWriter::Element accessorElement(writer, "accessor"); - accessorElement.Attribute("source", "#" + arrayID); - accessorElement.Attribute("count", modelMorphData.GetMorphCount()); - accessorElement.Attribute("offset", 0); - accessorElement.Attribute("stride", 1); - XMLWriter::Element paramElement(writer, "param"); - paramElement.Attribute("name", "MORPH_WEIGHT"); - paramElement.Attribute("type", "float"); - } - } - XMLWriter::Element targestElement(writer, "targets"); - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "MORPH_TARGET"); - inputElement.Attribute("source", "#" + targetsSourceID); - } - { - XMLWriter::Element inputElement(writer, "input"); - inputElement.Attribute("semantic", "MORPH_WEIGHT"); - inputElement.Attribute("source", "#" + weightsSourceID); - } - } - } - } - - void WriteImages(XMLWriter& writer, ProgressRange& progressRange) - { - XMLWriter::Element libraryImagesElement(writer, "library_images"); - } - - void WriteMaterials(XMLWriter& writer, MaterialData& materialData, std::map& materialFXMap, std::vector& effects, std::map& materialMaterialMap, std::vector& materials, ProgressRange& progressRange) - { - XMLWriter::Element libraryMaterialsElement(writer, "library_materials"); - - for (int materialIndex = 0, materialCount = materialData.GetMaterialCount(); materialIndex < materialCount; ++materialIndex) - { - std::map::iterator materialMapPos = materialMaterialMap.find(materialIndex); - int entryIndex = (materialMapPos != materialMaterialMap.end() ? (*materialMapPos).second : -1); - std::map::iterator effectMapPos = materialFXMap.find(materialIndex); - int effectIndex = (effectMapPos != materialFXMap.end() ? (*effectMapPos).second : -1); - - if (entryIndex >= 0) - { - std::string name = materials[entryIndex].name; - XMLWriter::Element materialElement(writer, "material"); - materialElement.Attribute("id", name); - if (effectIndex >= 0) - { - XMLWriter::Element effectElement(writer, "instance_effect"); - effectElement.Attribute("url", "#" + effects[effectIndex].name); - } - } - } - } - - void WriteScene(XMLWriter& writer, ProgressRange& progressRange) - { - XMLWriter::Element sceneElement(writer, "scene"); - XMLWriter::Element instanceElement(writer, "instance_visual_scene"); - instanceElement.Attribute("url", "#visual_scene_0"); - } -} - -bool ColladaWriter::Write(IExportSource* source, IExportContext* context, IXMLSink* sink, ProgressRange& progressRange) -{ - if (FloatingPointHasPrecisionIssues()) - { - // If you hit this point, please change floating point settings in your VS project (and recompile it): - // ConfigurationProperties -> C/C++ -> CodeGeneration -> FloatingPointModel: "/fp:strict". - // Note: using "/fp:precise" doesn't help. - assert(0); - context->Log(ILogger::eSeverity_Error, "Cannot write Collada file, because the writer has precision issues. Contact Crytek tools programmers."); - return false; - } - - // Temporarily change the current locale so that floats get written out using periods rather than commas. - LocaleChanger localeChangeToStandard(LC_NUMERIC, "C"); - - // Create an object to format the xml. - XMLWriter writer(sink); - - // Export the animations to the file. - { - XMLWriter::Element colladaElement(writer, "COLLADA"); - colladaElement.Attribute("xmlns", "http://www.collada.org/2005/11/COLLADASchema"); - colladaElement.Attribute("version", "1.4.1"); - - // Write out the document metadata. - WriteMetaData(source, writer, ProgressRange(progressRange, 0.01f)); - - // Read the skeleton. - GeometryFileData geometryFileData; - MaterialData materialData; - std::vector modelData; - SkeletonDataMap skeletonData; - MorphDataMap morphData; - { - ProgressRange subProgressRange(progressRange, 0.1f); - - source->ReadGeometryFiles(context, &geometryFileData); - - bool ok = source->ReadMaterials(context, &geometryFileData, &materialData); - if (!ok) - { - return false; - } - - modelData.resize(geometryFileData.GetGeometryFileCount()); - - for (int geometryFileIndex = 0, geometryFileCount = geometryFileData.GetGeometryFileCount(); geometryFileIndex < geometryFileCount; ++geometryFileIndex) - { - source->ReadModels(&geometryFileData, geometryFileIndex, &modelData[geometryFileIndex]); - - for (int modelIndex = 0, modelCount = modelData[geometryFileIndex].GetModelCount(); modelIndex < modelCount; ++modelIndex) - { - MorphDataMap::iterator morphDataPos = morphData.insert(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), MorphData())).first; - source->ReadMorphs(context, &(*morphDataPos).second, &modelData[geometryFileIndex], modelIndex); - if ((*morphDataPos).second.GetMorphCount() == 0) - { - morphData.erase(morphDataPos); - } - - SkeletonDataMap::iterator skeletonDataPos = skeletonData.insert(std::make_pair(std::make_pair(geometryFileIndex, modelIndex), SkeletonData())).first; - if (!source->ReadSkeleton(&geometryFileData, geometryFileIndex, &modelData[geometryFileIndex], modelIndex, &materialData, &(*skeletonDataPos).second)) - { - skeletonData.erase(skeletonDataPos); - } - -#if !defined(HACK_HACK_FORCE_PELVIS_TO_BE_BONE_1_BECAUSE_LOADING_CODE_EXPECTS_IT) -# define HACK_HACK_FORCE_PELVIS_TO_BE_BONE_1_BECAUSE_LOADING_CODE_EXPECTS_IT 0 -#endif //!defined(HACK_HACK_FORCE_PELVIS_TO_BE_BONE_1_BECAUSE_LOADING_CODE_EXPECTS_IT) - - skeletonDataPos = skeletonData.find(std::make_pair(geometryFileIndex, modelIndex)); - if (skeletonDataPos != skeletonData.end()) - { - SkeletonData newData, & oldData = (*skeletonDataPos).second; - int pelvisIndex = -1; - for (int i = 0, count = oldData.GetBoneCount(); i < count; ++i) - { - pelvisIndex = ((_stricmp(oldData.GetName(i).c_str(), "Bip01 Pelvis") == 0) ? i : pelvisIndex); - } - if (pelvisIndex >= 0) - { - if (pelvisIndex != 1) - { - context->Log(ILogger::eSeverity_Warning, "`Bip01 Pelvis` should be the second bone."); - } -#if HACK_HACK_FORCE_PELVIS_TO_BE_BONE_1_BECAUSE_LOADING_CODE_EXPECTS_IT == 1 - std::vector oldToNewMap(oldData.GetBoneCount()); - std::vector newToOldMap(oldData.GetBoneCount()); - for (int i = 0, count = oldData.GetBoneCount(); i < count; ++i) - { - oldToNewMap[i] = i, newToOldMap[i] = i; - } - std::swap(oldToNewMap[pelvisIndex], oldToNewMap[1]); - std::swap(newToOldMap[pelvisIndex], newToOldMap[1]); - for (int i = 0, count = oldData.GetBoneCount(); i < count; ++i) - { - int oldIndex = newToOldMap[i]; - void* handle = oldData.GetBoneHandle(oldIndex); - std::string name = oldData.GetName(oldIndex); - int oldParentIndex = oldData.GetParentIndex(oldIndex); - int parentIndex = (oldParentIndex >= 0 ? oldToNewMap[oldParentIndex] : -1); - float translation[3], rotation[3], scale[3]; - oldData.GetTranslation(translation, oldIndex); - oldData.GetRotation(rotation, oldIndex); - oldData.GetScale(scale, oldIndex); - - int boneIndex = newData.AddBone(handle, name.c_str(), parentIndex); - newData.SetTranslation(boneIndex, translation); - newData.SetRotation(boneIndex, rotation); - newData.SetScale(boneIndex, scale); - - newData.SetHasGeometry(boneIndex, oldData.HasGeometry(oldIndex)); - - if (oldData.HasParentFrame(oldIndex)) - { - float parentFrameTranslation[3], parentFrameRotation[3], parentFrameScale[3]; - oldData.GetParentFrameTranslation(oldIndex, parentFrameTranslation); - oldData.GetParentFrameRotation(oldIndex, parentFrameRotation); - oldData.GetParentFrameScale(oldIndex, parentFrameScale); - newData.SetParentFrameTranslation(boneIndex, parentFrameTranslation); - newData.SetParentFrameRotation(boneIndex, parentFrameRotation); - newData.SetParentFrameScale(boneIndex, parentFrameScale); - } - for (int axisIndex = 0; axisIndex < 3; ++axisIndex) - { - ISkeletonData::Axis axis = ISkeletonData::Axis(axisIndex); - if (oldData.HasLimit(oldIndex, axis, ISkeletonData::LimitMin)) - { - newData.SetLimit(boneIndex, axis, ISkeletonData::LimitMin, oldData.GetLimit(oldIndex, axis, ISkeletonData::LimitMin)); - } - if (oldData.HasLimit(oldIndex, axis, ISkeletonData::LimitMax)) - { - newData.SetLimit(boneIndex, axis, ISkeletonData::LimitMax, oldData.GetLimit(oldIndex, axis, ISkeletonData::LimitMax)); - } - if (oldData.HasSpringTension(oldIndex, axis)) - { - newData.SetSpringTension(boneIndex, axis, oldData.GetSpringTension(oldIndex, axis)); - } - if (oldData.HasSpringAngle(oldIndex, axis)) - { - newData.SetSpringAngle(boneIndex, axis, oldData.GetSpringAngle(oldIndex, axis)); - } - if (oldData.HasAxisDamping(oldIndex, axis)) - { - newData.SetAxisDamping(boneIndex, axis, oldData.GetAxisDamping(oldIndex, axis)); - } - newData.SetPhysicalized(boneIndex, oldData.GetPhysicalized(oldIndex)); - } - } - (*skeletonDataPos).second = newData; -#endif //HACK_HACK_FORCE_PELVIS_TO_BE_BONE_1_BECAUSE_LOADING_CODE_EXPECTS_IT == 1 - } - } - } - } - } - - // Generate a list of fx to export. - std::map materialFXMap; - std::vector effects; - GenerateEffectsList(context, materialFXMap, effects, materialData); - - // Generate a list of geometry to export. - std::map, int> modelGeometryMap; - std::vector geometries; - GenerateGeometryList(context, modelGeometryMap, geometries, geometryFileData, modelData); - - // Generate a list of bone geometries to export. - std::map, int>, int> boneGeometryMap; - std::vector boneGeometries; - GenerateBoneGeometryList(context, boneGeometryMap, boneGeometries, geometryFileData, modelData, skeletonData); - - // Generate a list of morph geometries to export. - std::map, int>, int> morphGeometryMap; - std::vector morphGeometries; - GenerateMorphGeometryList(context, morphGeometryMap, morphGeometries, geometryFileData, modelData, morphData); - - BoneDataMap boneDataMap; - GenerateBoneList(context, boneDataMap, skeletonData, modelData); - - // Generate a list of animations to export. - std::vector animations; - GenerateAnimationList(context, animations, geometryFileData, modelData, skeletonData, source, ProgressRange(progressRange, 0.025f)); - - // Generate a list of morph controllers to export. - std::vector morphControllers; - std::map, int> modelMorphControllerMap; - GenerateMorphControllerList(context, morphControllers, modelMorphControllerMap, morphData, geometryFileData, modelData, modelGeometryMap, geometries, ProgressRange(progressRange, 0.0125f)); - - // Generate a list of skin controllers to export. - std::vector controllers; - std::map, int> modelControllerMap; - GenerateSkinControllerList(context, controllers, modelControllerMap, skeletonData, geometryFileData, modelData, modelGeometryMap, geometries, ProgressRange(progressRange, 0.0125f)); - - // Write out all the animations. - WriteAnimationList(writer, animations, ProgressRange(progressRange, 0.025f)); - WriteAnimationData(context, writer, animations, geometryFileData, modelData, skeletonData, boneDataMap, source, ProgressRange(progressRange, 0.475f)); - - // Write out all the effects. - WriteEffects(writer, effects, ProgressRange(progressRange, 0.01f)); - - // Write out the materials. - std::map materialMaterialMap; - std::vector materials; - GenerateMaterialList(context, materialMaterialMap, materialFXMap, effects, materials, materialData); - WriteMaterials(writer, materialData, materialFXMap, effects, materialMaterialMap, materials, ProgressRange(progressRange, 0.005f)); - - // Write out all the geometries. - bool ok = WriteGeometries(context, writer, geometries, geometryFileData, modelData, morphData, materialData, materials, materialMaterialMap, skeletonData, boneGeometries, boneGeometryMap, morphGeometryMap, morphGeometries, source, ProgressRange(progressRange, 0.2f)); - if (!ok) - { - return false; - } - - // Write out all the controllers. - WriteControllers(writer, context, source, controllers, morphControllers, modelMorphControllerMap, geometryFileData, modelData, skeletonData, morphData, morphGeometries, morphGeometryMap, geometries, modelGeometryMap, boneDataMap, ProgressRange(progressRange, 0.005f)); - - // Write out the list of models. - WriteHierarchy(writer, context, geometryFileData, materialData, materialMaterialMap, materials, modelData, skeletonData, modelGeometryMap, geometries, modelControllerMap, controllers, boneDataMap, boneGeometryMap, boneGeometries, modelMorphControllerMap, morphControllers, source, ProgressRange(progressRange, 0.1f)); - - // Write out all the other libraries. - WriteImages(writer, ProgressRange(progressRange, 0.01f)); - WriteScene(writer, ProgressRange(progressRange, 0.01f)); - } - - return true; -} diff --git a/Code/Tools/CryCommonTools/Export/ColladaWriter.h b/Code/Tools/CryCommonTools/Export/ColladaWriter.h deleted file mode 100644 index f880e8ce1b..0000000000 --- a/Code/Tools/CryCommonTools/Export/ColladaWriter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAWRITER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAWRITER_H -#pragma once - - -#include - -class IExportSource; -class IExportContext; -class ProgressRange; -class IXMLSink; - -class ColladaWriter -{ -public: - static bool Write(IExportSource* source, IExportContext* context, IXMLSink* sink, ProgressRange& progressRange); -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_COLLADAWRITER_H diff --git a/Code/Tools/CryCommonTools/Export/ExportFileType.cpp b/Code/Tools/CryCommonTools/Export/ExportFileType.cpp deleted file mode 100644 index 8e552f361b..0000000000 --- a/Code/Tools/CryCommonTools/Export/ExportFileType.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "ExportFileType.h" -#include "StringHelpers.h" - - -struct SFileTypeInfo -{ - int type; - const char* name; -}; - -SFileTypeInfo s_fileTypes[] = -{ - { CRY_FILE_TYPE_CGF, "cgf" }, - { CRY_FILE_TYPE_CGA, "cga" }, - { CRY_FILE_TYPE_CHR, "chr" }, - { CRY_FILE_TYPE_CAF, "caf" }, - { CRY_FILE_TYPE_ANM, "anm" }, - { CRY_FILE_TYPE_CHR | CRY_FILE_TYPE_CAF, "chrcaf" }, - { CRY_FILE_TYPE_CGA | CRY_FILE_TYPE_ANM, "cgaanm" }, - { CRY_FILE_TYPE_SKIN, "skin" }, - { CRY_FILE_TYPE_INTERMEDIATE_CAF, "i_caf" }, -}; - -static const int s_fileTypeCount = (sizeof(s_fileTypes) / sizeof(s_fileTypes[0])); - - -const char* ExportFileTypeHelpers::CryFileTypeToString(int const cryFileType) -{ - for (int i = 0; i < s_fileTypeCount; ++i) - { - if (s_fileTypes[i].type == cryFileType) - { - return s_fileTypes[i].name; - } - } - return "unknown"; -} - -int ExportFileTypeHelpers::StringToCryFileType(const char* str) -{ - if (str) - { - for (int i = 0; i < s_fileTypeCount; ++i) - { - if (_stricmp(str, s_fileTypes[i].name) == 0) - { - return s_fileTypes[i].type; - } - } - } - return CRY_FILE_TYPE_NONE; -} diff --git a/Code/Tools/CryCommonTools/Export/ExportFileType.h b/Code/Tools/CryCommonTools/Export/ExportFileType.h deleted file mode 100644 index 11d68f699b..0000000000 --- a/Code/Tools/CryCommonTools/Export/ExportFileType.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTFILETYPE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTFILETYPE_H -#pragma once - - -enum CryFileType -{ - CRY_FILE_TYPE_NONE = 0x0000, - CRY_FILE_TYPE_CGF = 0x0001, - CRY_FILE_TYPE_CGA = 0x0002, - CRY_FILE_TYPE_CHR = 0x0004, - CRY_FILE_TYPE_CAF = 0x0008, - CRY_FILE_TYPE_ANM = 0x0010, - CRY_FILE_TYPE_SKIN = 0x0020, - CRY_FILE_TYPE_INTERMEDIATE_CAF = 0x0040, - //START: Add Skinned Geometry (.CGF) export type (for touch bending vegetation) - CRY_FILE_TYPE_SKIN_CGF = 0x0080, - //END: Add Skinned Geometry (.CGF) export type (for touch bending vegetation) -}; - -namespace ExportFileTypeHelpers -{ - const char* CryFileTypeToString(int cryFileType); - int StringToCryFileType(const char* str); -}; - - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTFILETYPE_H - diff --git a/Code/Tools/CryCommonTools/Export/ExportHelpers.h b/Code/Tools/CryCommonTools/Export/ExportHelpers.h deleted file mode 100644 index 00780696fe..0000000000 --- a/Code/Tools/CryCommonTools/Export/ExportHelpers.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTHELPERS_H -#pragma once - - -#include - -namespace ExportHelpers -{ - inline void GenerateTextureCoordinates(float* const res_s, float* const res_t, const float x, const float y, const float z) - { - const float ax = ::fabs(x); - const float ay = ::fabs(y); - const float az = ::fabs(z); - - float s = 0.0f; - float t = 0.0f; - - if (ax > 1e-3f || ay > 1e-3f || az > 1e-3f) - { - if (ax > ay) - { - if (ax > az) - { - // X rules - s = y / ax; - t = z / ax; - } - else - { - // Z rules - s = x / az; - t = y / az; - } - } - else - { - // ax <= ay - if (ay > az) - { - // Y rules - s = x / ay; - t = z / ay; - } - else - { - // Z rules - s = x / az; - t = y / az; - } - } - } - - // Now the texture coordinates are in the range [-1,1]. - // We want normalized [0,1] texture coordinates. - s = (s + 1) * 0.5f; - t = (t + 1) * 0.5f; - - if (res_s) - { - *res_s = s; - } - if (res_t) - { - *res_t = t; - } - } -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTHELPERS_H diff --git a/Code/Tools/CryCommonTools/Export/ExportSourceDecoratorBase.cpp b/Code/Tools/CryCommonTools/Export/ExportSourceDecoratorBase.cpp deleted file mode 100644 index 5fd0cb855f..0000000000 --- a/Code/Tools/CryCommonTools/Export/ExportSourceDecoratorBase.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "ExportSourceDecoratorBase.h" - -ExportSourceDecoratorBase::ExportSourceDecoratorBase(IExportSource* source) - : source(source) -{ -} - -void ExportSourceDecoratorBase::GetMetaData(SExportMetaData& metaData) const -{ - this->source->GetMetaData(metaData); -} - -std::string ExportSourceDecoratorBase::GetDCCFileName() const -{ - return this->source->GetDCCFileName(); -} - -std::string ExportSourceDecoratorBase::GetExportDirectory() const -{ - return this->source->GetExportDirectory(); -} - -void ExportSourceDecoratorBase::ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData) -{ - this->source->ReadGeometryFiles(context, geometryFileData); -} - -bool ExportSourceDecoratorBase::ReadMaterials(IExportContext* context, const IGeometryFileData* const geometryFileData, IMaterialData* materialData) -{ - return this->source->ReadMaterials(context, geometryFileData, materialData); -} - -void ExportSourceDecoratorBase::ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData) -{ - this->source->ReadModels(geometryFileData, geometryFileIndex, modelData); -} - -void ExportSourceDecoratorBase::ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* const modelData, int modelIndex, ISkeletonData* skeletonData) -{ - this->source->ReadSkinning(context, skinningData, modelData, modelIndex, skeletonData); -} - -bool ExportSourceDecoratorBase::ReadSkeleton(const IGeometryFileData* const geometryFileData, int geometryFileIndex, const IModelData* const modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData) -{ - return this->source->ReadSkeleton(geometryFileData, geometryFileIndex, modelData, modelIndex, materialData, skeletonData); -} - -int ExportSourceDecoratorBase::GetAnimationCount() const -{ - return this->source->GetAnimationCount(); -} - -std::string ExportSourceDecoratorBase::GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const -{ - return this->source->GetAnimationName(geometryFileData, geometryFileIndex, animationIndex); -} - -void ExportSourceDecoratorBase::GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const -{ - this->source->GetAnimationTimeSpan(start, stop, animationIndex); -} - -void ExportSourceDecoratorBase::ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* const geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const -{ - this->source->ReadAnimationFlags(context, animationData, geometryFileData, modelData, modelIndex, skeletonData, animationIndex); -} - -IAnimationData* ExportSourceDecoratorBase::ReadAnimation(IExportContext* context, const IGeometryFileData* const geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const -{ - return this->source->ReadAnimation(context, geometryFileData, modelData, modelIndex, skeletonData, animationIndex, fps); -} - -bool ExportSourceDecoratorBase::ReadGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* const modelData, const IMaterialData* const materialData, int modelIndex) -{ - return this->source->ReadGeometry(context, geometry, modelData, materialData, modelIndex); -} - -bool ExportSourceDecoratorBase::ReadGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, const IModelData* const modelData, const IMaterialData* const materialData, int modelIndex) const -{ - return this->source->ReadGeometryMaterialData(context, geometryMaterialData, modelData, materialData, modelIndex); -} - -bool ExportSourceDecoratorBase::ReadBoneGeometry(IExportContext* context, IGeometryData* geometry, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* const materialData) -{ - return this->source->ReadBoneGeometry(context, geometry, skeletonData, boneIndex, materialData); -} - -bool ExportSourceDecoratorBase::ReadBoneGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* const materialData) const -{ - return this->source->ReadBoneGeometryMaterialData(context, geometryMaterialData, skeletonData, boneIndex, materialData); -} - -void ExportSourceDecoratorBase::ReadMorphs(IExportContext* context, IMorphData* morphData, const IModelData* const modelData, int modelIndex) -{ - this->source->ReadMorphs(context, morphData, modelData, modelIndex); -} - -bool ExportSourceDecoratorBase::ReadMorphGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* const modelData, int modelIndex, const IMorphData* const morphData, int morphIndex, const IMaterialData* materialData) -{ - return this->source->ReadMorphGeometry(context, geometry, modelData, modelIndex, morphData, morphIndex, materialData); -} - -bool ExportSourceDecoratorBase::HasValidPosController(const IModelData* modelData, int modelIndex) const -{ - return this->source->HasValidPosController(modelData, modelIndex); -} - -bool ExportSourceDecoratorBase::HasValidRotController(const IModelData* modelData, int modelIndex) const -{ - return this->source->HasValidRotController(modelData, modelIndex); -} - -bool ExportSourceDecoratorBase::HasValidSclController(const IModelData* modelData, int modelIndex) const -{ - return this->source->HasValidSclController(modelData, modelIndex); -} diff --git a/Code/Tools/CryCommonTools/Export/ExportSourceDecoratorBase.h b/Code/Tools/CryCommonTools/Export/ExportSourceDecoratorBase.h deleted file mode 100644 index df5bea80ee..0000000000 --- a/Code/Tools/CryCommonTools/Export/ExportSourceDecoratorBase.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSOURCEDECORATORBASE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSOURCEDECORATORBASE_H -#pragma once - - -#include "IExportSource.h" - -class ExportSourceDecoratorBase - : public IExportSource -{ -public: - ExportSourceDecoratorBase(IExportSource* source); - - virtual std::string GetResourceCompilerPath() const { return std::string(""); }; - virtual void GetMetaData(SExportMetaData& metaData) const; - virtual std::string GetDCCFileName() const; - virtual std::string GetExportDirectory() const; - virtual void ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData); - virtual bool ReadMaterials(IExportContext* context, const IGeometryFileData* geometryFileData, IMaterialData* materialData); - virtual void ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData); - virtual void ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* modelData, int modelIndex, ISkeletonData* skeletonData); - virtual bool ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData); - virtual int GetAnimationCount() const; - virtual std::string GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const; - virtual void GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const; - virtual void ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const; - virtual IAnimationData* ReadAnimation(IExportContext* context, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const; - virtual bool ReadGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* modelData, const IMaterialData* materialData, int modelIndex); - virtual bool ReadGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, const IModelData* modelData, const IMaterialData* materialData, int modelIndex) const; - virtual bool ReadBoneGeometry(IExportContext* context, IGeometryData* geometry, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* materialData); - virtual bool ReadBoneGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* materialData) const; - virtual void ReadMorphs(IExportContext* context, IMorphData* morphData, const IModelData* modelData, int modelIndex); - virtual bool ReadMorphGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* modelData, int modelIndex, const IMorphData* morphData, int morphIndex, const IMaterialData* materialData); - virtual bool HasValidPosController(const IModelData* modelData, int modelIndex) const; - virtual bool HasValidRotController(const IModelData* modelData, int modelIndex) const; - virtual bool HasValidSclController(const IModelData* modelData, int modelIndex) const; -protected: - IExportSource* source; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSOURCEDECORATORBASE_H diff --git a/Code/Tools/CryCommonTools/Export/ExportStatusWindow.cpp b/Code/Tools/CryCommonTools/Export/ExportStatusWindow.cpp deleted file mode 100644 index bc10a107e7..0000000000 --- a/Code/Tools/CryCommonTools/Export/ExportStatusWindow.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "ExportStatusWindow.h" -#include "UI/Win32GUI.h" -#include "StringHelpers.h" -#include -#include - -enum -{ - WM_USER_TASK_FINISHED = WM_USER + 53, - WM_USER_ACCEPTED -}; - -struct ThreadData -{ - ExportStatusWindow* statusWindow; - void (ExportStatusWindow::* initialize)(int width, int height, const std::vector >& tasks); - void (ExportStatusWindow::* run)(); - int width; - int height; - const std::vector >* tasks; - HANDLE initializedSemaphore; -}; -unsigned int __stdcall ThreadFunc(void* threadDataMemory) -{ - ThreadData* data = static_cast(threadDataMemory); - ExportStatusWindow* statusWindow = data->statusWindow; - void (ExportStatusWindow::* initialize)(int width, int height, const std::vector >& tasks) = data->initialize; - void (ExportStatusWindow::* run)() = data->run; - int width = data->width; - int height = data->height; - const std::vector >& tasks = *data->tasks; - HANDLE initializedSemaphore = data->initializedSemaphore; - - // Initialize the data. - (statusWindow->*initialize)(width, height, tasks); - - // Let the creating thread know that we have read the data - it is - // now safe for it to clear it. - ReleaseSemaphore(initializedSemaphore, 1, 0); - - // Perform the main thread processing. - (statusWindow->*run)(); - return 0; -} - -#pragma warning(push) -#pragma warning(disable: 4355) // 'this' : used in base member initializer list -ExportStatusWindow::ExportStatusWindow(int width, int height, const std::vector >& tasks) - : m_threadHandle(0) - , m_warningsEncountered(false) - , m_errorsEncountered(false) - , m_waitState(WaitState_WarningsAndErrors) - , m_okButtonSpacer(0, 0, 2000, 0) - , m_okButton(_T("OK"), this, &ExportStatusWindow::OkPressed) - , m_okButtonLayout(Layout::DirectionHorizontal) -{ - OutputDebugString(_T("Showing status window.\n")); - - Win32GUI::Initialize(); - - HANDLE initializedSemaphore = CreateSemaphore(0, 0, 1, 0); - - // Create a thread to handle the message pump for the window. - ThreadData threadData; - threadData.statusWindow = this; - threadData.initialize = &ExportStatusWindow::Initialize; - threadData.run = &ExportStatusWindow::Run; - threadData.width = width; - threadData.height = height; - threadData.tasks = &tasks; - threadData.initializedSemaphore = initializedSemaphore; - m_threadHandle = (HANDLE)_beginthreadex( - 0, //void *security, - 0, //unsigned stack_size, - ThreadFunc, //unsigned ( *start_address )( void * ), - &threadData, //void *arglist, - 0, //unsigned initflag, - 0); //unsigned *thrdaddr - - // Wait until the thread has read the data, since once we return the data will be lost. - WaitForSingleObject(initializedSemaphore, INFINITE); - CloseHandle(initializedSemaphore); -} -#pragma warning(pop) - -ExportStatusWindow::~ExportStatusWindow() -{ - OutputDebugString(_T("Hiding status window.\n")); - - // Tell the thread to exit and then wait for it to do so. - if (HWND hwnd = (HWND)m_frameWindow.GetHWND()) - { - PostMessage(hwnd, WM_USER_TASK_FINISHED, 0, 0); - m_okButton.Enable(true); - WaitForSingleObject((HANDLE)m_threadHandle, INFINITE); - } -} - -void ExportStatusWindow::Initialize(int width, int height, const std::vector >& tasks) -{ - OutputDebugString(_T("Beginning status window thread.\n")); - - for (int taskIndex = 0, taskCount = int(tasks.size()); taskIndex < taskCount; ++taskIndex) - { - m_taskList.AddTask(tasks[taskIndex].first, tasks[taskIndex].second); - } - - m_okButtonLayout.AddComponent(&m_okButtonSpacer); - m_okButtonLayout.AddComponent(&m_okButton); - m_okButton.Enable(false); - - m_frameWindow.AddComponent(&m_taskList); - m_frameWindow.AddComponent(&m_progressBar); - m_frameWindow.AddComponent(&m_logWindow); - m_frameWindow.AddComponent(&m_okButtonLayout); - m_frameWindow.Show(true, width, height); -} - -void ExportStatusWindow::Run() -{ - MSG msg; - BOOL status; - bool waitingAcceptance = false; - while ((status = GetMessage(&msg, HWND(0), UINT(0), UINT(0))) != 0) - { - if (status == -1) - { - break; - } - else if (msg.message == WM_USER_TASK_FINISHED) - { - if (m_waitState == WaitState_Always || - (m_waitState == WaitState_WarningsAndErrors && m_warningsEncountered || m_errorsEncountered) || - (m_waitState == WaitState_ErrorsOnly && m_errorsEncountered)) - { - waitingAcceptance = true; - } - else - { - break; - } - } - else if (waitingAcceptance && msg.message == WM_USER_ACCEPTED) - { - break; - } - else - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - m_frameWindow.Show(false, 0, 0); - OutputDebugString(_T("Ending status window thread.\n")); -} - -void ExportStatusWindow::OkPressed() -{ - if (HWND hwnd = (HWND)m_frameWindow.GetHWND()) - { - PostMessage(hwnd, WM_USER_ACCEPTED, 0, 0); - } -} - -void ExportStatusWindow::SetWaitState(WaitState state) -{ - m_waitState = state; -} - -void ExportStatusWindow::AddTask(const std::string& id, const std::string& description) -{ - m_taskList.AddTask(id, description); -} - -void ExportStatusWindow::SetCurrentTask(const std::string& id) -{ - m_taskList.SetCurrentTask(id); -} - -void ExportStatusWindow::SetProgress(float progress) -{ - TCHAR buffer[2048]; - _sntprintf_s(buffer, sizeof(buffer), _TRUNCATE, _T("%.1f%% complete - exporting scene."), progress * 100); - m_frameWindow.SetCaption(buffer); - m_progressBar.SetProgress(progress); -} - -void ExportStatusWindow::Log(ILogger::ESeverity eSeverity, const char* message) -{ - if (eSeverity == ILogger::eSeverity_Error) - { - m_errorsEncountered = true; - } - else if (eSeverity == ILogger::eSeverity_Warning) - { - m_warningsEncountered = true; - } - - m_logWindow.Log(eSeverity, StringHelpers::ConvertString(message).c_str()); -} diff --git a/Code/Tools/CryCommonTools/Export/ExportStatusWindow.h b/Code/Tools/CryCommonTools/Export/ExportStatusWindow.h deleted file mode 100644 index d82869ae96..0000000000 --- a/Code/Tools/CryCommonTools/Export/ExportStatusWindow.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSTATUSWINDOW_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSTATUSWINDOW_H -#pragma once - - -#include "UI/FrameWindow.h" -#include "UI/ProgressBar.h" -#include "UI/TaskList.h" -#include "UI/LogWindow.h" -#include "UI/Spacer.h" -#include "UI/Layout.h" -#include "UI/PushButton.h" -#include "ILogger.h" - -class ExportStatusWindow -{ -public: - enum WaitState - { - WaitState_WarningsAndErrors, - WaitState_ErrorsOnly, - WaitState_Always, - WaitState_Never, - }; - - ExportStatusWindow(int width, int height, const std::vector >& tasks); - ~ExportStatusWindow(); - - void SetWaitState(WaitState state); - - void AddTask(const std::string& id, const std::string& description); - void SetCurrentTask(const std::string& id); - void SetProgress(float progress); - void Log(ILogger::ESeverity eSeverity, const char* message); - -private: - void Initialize(int width, int height, const std::vector >& tasks); - void Run(); - void OkPressed(); - - FrameWindow m_frameWindow; - TaskList m_taskList; - ProgressBar m_progressBar; - Spacer m_okButtonSpacer; - PushButton m_okButton; - Layout m_okButtonLayout; - LogWindow m_logWindow; - void* m_threadHandle; - bool m_warningsEncountered; - bool m_errorsEncountered; - WaitState m_waitState; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_EXPORTSTATUSWINDOW_H diff --git a/Code/Tools/CryCommonTools/Export/GeometryData.cpp b/Code/Tools/CryCommonTools/Export/GeometryData.cpp deleted file mode 100644 index dd82d90181..0000000000 --- a/Code/Tools/CryCommonTools/Export/GeometryData.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "GeometryData.h" - -GeometryData::GeometryData() -{ -} - -int GeometryData::AddPosition(float x, float y, float z) -{ - int positionIndex = int(this->positions.size()); - this->positions.push_back(Vector(x, y, z)); - return positionIndex; -} - -int GeometryData::AddNormal(float x, float y, float z) -{ - int normalIndex = int(this->normals.size()); - this->normals.push_back(Vector(x, y, z)); - return normalIndex; -} - -int GeometryData::AddTextureCoordinate(float u, float v) -{ - int textureCoordinateIndex = int(this->textureCoordinates.size()); - this->textureCoordinates.push_back(TextureCoordinate(u, v)); - return textureCoordinateIndex; -} - -int GeometryData::AddVertexColor(float r, float g, float b, float a) -{ - int vertexColorIndex = int(this->vertexColors.size()); - this->vertexColors.push_back(VertexColor(r, g, b, a)); - return vertexColorIndex; -} - -int GeometryData::AddPolygon(const int* indices, int mtlID) -{ - int polygonIndex = int(this->polygons.size()); - this->polygons.push_back(Polygon(mtlID, - Polygon::Vertex(indices[0], indices[1], indices[2], indices[3]), - Polygon::Vertex(indices[4], indices[5], indices[6], indices[7]), - Polygon::Vertex(indices[8], indices[9], indices[10], indices[11]))); - return polygonIndex; -} - -int GeometryData::GetNumberOfPositions() const -{ - return (int)this->positions.size(); -} - -int GeometryData::GetNumberOfNormals() const -{ - return (int)this->normals.size(); -} - -int GeometryData::GetNumberOfTextureCoordinates() const -{ - return (int)this->textureCoordinates.size(); -} - -int GeometryData::GetNumberOfVertexColors() const -{ - return (int)this->vertexColors.size(); -} - -int GeometryData::GetNumberOfPolygons() const -{ - return (int)this->polygons.size(); -} diff --git a/Code/Tools/CryCommonTools/Export/GeometryData.h b/Code/Tools/CryCommonTools/Export/GeometryData.h deleted file mode 100644 index aa42925128..0000000000 --- a/Code/Tools/CryCommonTools/Export/GeometryData.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYDATA_H -#pragma once - - -#include "IGeometryData.h" -#include - -class GeometryData - : public IGeometryData -{ -public: - GeometryData(); - - // IGeometryData - virtual int AddPosition(float x, float y, float z); - virtual int AddNormal(float x, float y, float z); - virtual int AddTextureCoordinate(float u, float v); - virtual int AddVertexColor(float r, float g, float b, float a); - - virtual int AddPolygon(const int* indices, int mtlID); - - virtual int GetNumberOfPositions() const; - virtual int GetNumberOfNormals() const; - virtual int GetNumberOfTextureCoordinates() const; - virtual int GetNumberOfVertexColors() const; - - virtual int GetNumberOfPolygons() const; - - struct Vector - { - Vector(float x, float y, float z) - : x(x) - , y(y) - , z(z) {} - float x, y, z; - }; - - struct TextureCoordinate - { - TextureCoordinate(float u, float v) - : u(u) - , v(v) {} - float u, v; - }; - - struct VertexColor - { - VertexColor(float r, float g, float b, float a) - : r(r) - , g(g) - , b(b) - , a(a) {} - float r, g, b, a; - }; - - struct Polygon - { - struct Vertex - { - Vertex() {} - Vertex(int positionIndex, int normalIndex, int textureCoordinateIndex, int vertexColorIndex) - : positionIndex(positionIndex) - , normalIndex(normalIndex) - , textureCoordinateIndex(textureCoordinateIndex) - , vertexColorIndex(vertexColorIndex) {} - int positionIndex, normalIndex, textureCoordinateIndex, vertexColorIndex; - }; - - Polygon(int mtlID, const Vertex& v0, const Vertex& v1, const Vertex& v2) - : mtlID(mtlID) - { - v[0] = v0; - v[1] = v1; - v[2] = v2; - } - - int mtlID; - Vertex v[3]; - }; - - std::vector positions; - std::vector normals; - std::vector textureCoordinates; - std::vector vertexColors; - std::vector polygons; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYDATA_H diff --git a/Code/Tools/CryCommonTools/Export/GeometryExportSourceAdapter.cpp b/Code/Tools/CryCommonTools/Export/GeometryExportSourceAdapter.cpp deleted file mode 100644 index 3333e12ca6..0000000000 --- a/Code/Tools/CryCommonTools/Export/GeometryExportSourceAdapter.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "GeometryExportSourceAdapter.h" -#include "IGeometryFileData.h" -#include - -GeometryExportSourceAdapter::GeometryExportSourceAdapter(IExportSource* source, IGeometryFileData* geometryFileData, const std::vector& geometryFileIndices) - : ExportSourceDecoratorBase(source) - , m_geometryFileData(geometryFileData) - , m_geometryFileIndices(geometryFileIndices) -{ - assert(m_geometryFileIndices.size() <= m_geometryFileData->GetGeometryFileCount()); - for (size_t i = 0; i < m_geometryFileIndices.size(); ++i) - { - int const geometryFileIndex = m_geometryFileIndices[i]; - assert(geometryFileIndex >= 0 && geometryFileIndex < m_geometryFileData->GetGeometryFileCount()); - } -} - -void GeometryExportSourceAdapter::ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData) -{ - for (size_t i = 0; i < m_geometryFileIndices.size(); ++i) - { - int const geometryFileIndex = m_geometryFileIndices[i]; - int const newGeometryFileIndex = geometryFileData->AddGeometryFile( - m_geometryFileData->GetGeometryFileHandle(geometryFileIndex), - m_geometryFileData->GetGeometryFileName(geometryFileIndex), - m_geometryFileData->GetProperties(geometryFileIndex)); - } -} - -void GeometryExportSourceAdapter::ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData) -{ - assert(geometryFileIndex >= 0 && geometryFileIndex < m_geometryFileIndices.size()); - this->source->ReadModels(m_geometryFileData, m_geometryFileIndices[geometryFileIndex], modelData); -} - -bool GeometryExportSourceAdapter::ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData) -{ - assert(geometryFileIndex >= 0 && geometryFileIndex < m_geometryFileIndices.size()); - return this->source->ReadSkeleton(m_geometryFileData, m_geometryFileIndices[geometryFileIndex], modelData, modelIndex, materialData, skeletonData); -} diff --git a/Code/Tools/CryCommonTools/Export/GeometryExportSourceAdapter.h b/Code/Tools/CryCommonTools/Export/GeometryExportSourceAdapter.h deleted file mode 100644 index 7fb6ee081d..0000000000 --- a/Code/Tools/CryCommonTools/Export/GeometryExportSourceAdapter.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYEXPORTSOURCEADAPTER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYEXPORTSOURCEADAPTER_H -#pragma once - - -#include "ExportSourceDecoratorBase.h" - -class GeometryExportSourceAdapter - : public ExportSourceDecoratorBase -{ -public: - GeometryExportSourceAdapter(IExportSource* source, IGeometryFileData* geometryFileData, const std::vector& geometryFileIndices); - - virtual void ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData); - virtual void ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData); - virtual bool ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData); - -private: - IGeometryFileData* m_geometryFileData; - std::vector m_geometryFileIndices; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYEXPORTSOURCEADAPTER_H diff --git a/Code/Tools/CryCommonTools/Export/GeometryFileData.cpp b/Code/Tools/CryCommonTools/Export/GeometryFileData.cpp deleted file mode 100644 index f67c0905dd..0000000000 --- a/Code/Tools/CryCommonTools/Export/GeometryFileData.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "GeometryFileData.h" - -int GeometryFileData::AddGeometryFile(const void* handle, const char* name, const SProperties& properties) -{ - const int geometryFileIndex = int(m_geometryFiles.size()); - m_geometryFiles.push_back(GeometryFileEntry(handle, name, properties)); - return geometryFileIndex; -} - -int GeometryFileData::GetGeometryFileCount() const -{ - return int(m_geometryFiles.size()); -} - -const void* GeometryFileData::GetGeometryFileHandle(int geometryFileIndex) const -{ - return m_geometryFiles[geometryFileIndex].handle; -} - -const char* GeometryFileData::GetGeometryFileName(int geometryFileIndex) const -{ - return m_geometryFiles[geometryFileIndex].name.c_str(); -} - -////////////////////////////////////////////////////////////////////////// -const IGeometryFileData::SProperties& GeometryFileData::GetProperties(int geometryFileIndex) const -{ - if (size_t(geometryFileIndex) >= m_geometryFiles.size()) - { - assert(0); - static SProperties badValue; - return badValue; - } - return m_geometryFiles[geometryFileIndex].properties; -} - -void GeometryFileData::SetProperties(int geometryFileIndex, const IGeometryFileData::SProperties& properties) -{ - if (size_t(geometryFileIndex) >= m_geometryFiles.size()) - { - assert(0); - return; - } - m_geometryFiles[geometryFileIndex].properties = properties; -} diff --git a/Code/Tools/CryCommonTools/Export/GeometryFileData.h b/Code/Tools/CryCommonTools/Export/GeometryFileData.h deleted file mode 100644 index 975a9cc5f7..0000000000 --- a/Code/Tools/CryCommonTools/Export/GeometryFileData.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYFILEDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYFILEDATA_H -#pragma once - - -#include "IGeometryFileData.h" -#include "STLHelpers.h" - -class GeometryFileData - : public IGeometryFileData -{ -public: - // IGeometryFileData - virtual int AddGeometryFile(const void* handle, const char* name, const SProperties& properties); - virtual const SProperties& GetProperties(int geometryFileIndex) const; - virtual void SetProperties(int geometryFileIndex, const SProperties& properties); - virtual int GetGeometryFileCount() const; - virtual const void* GetGeometryFileHandle(int geometryFileIndex) const; - virtual const char* GetGeometryFileName(int geometryFileIndex) const; - -private: - struct GeometryFileEntry - { - GeometryFileEntry(const void* a_handle, const char* a_name, const SProperties& a_properties) - : handle(a_handle) - , name(a_name) - , properties(a_properties) - { - } - - const void* handle; - std::string name; - SProperties properties; - }; - - std::vector m_geometryFiles; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYFILEDATA_H diff --git a/Code/Tools/CryCommonTools/Export/GeometryMaterialData.cpp b/Code/Tools/CryCommonTools/Export/GeometryMaterialData.cpp deleted file mode 100644 index ddc27daf52..0000000000 --- a/Code/Tools/CryCommonTools/Export/GeometryMaterialData.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "GeometryMaterialData.h" - -void GeometryMaterialData::AddUsedMaterialIndex(int materialIndex) -{ - std::map::iterator usedMaterialPos = m_usedMaterialIndexIndexMap.find(materialIndex); - if (usedMaterialPos == m_usedMaterialIndexIndexMap.end()) - { - int materialIndexIndex = int(m_usedMaterialIndices.size()); - m_usedMaterialIndices.push_back(materialIndex); - m_usedMaterialIndexIndexMap.insert(std::make_pair(materialIndex, materialIndexIndex)); - } -} - -int GeometryMaterialData::GetUsedMaterialCount() const -{ - return int(m_usedMaterialIndices.size()); -} - -int GeometryMaterialData::GetUsedMaterialIndex(int usedMaterialIndex) const -{ - return m_usedMaterialIndices[usedMaterialIndex]; -} diff --git a/Code/Tools/CryCommonTools/Export/GeometryMaterialData.h b/Code/Tools/CryCommonTools/Export/GeometryMaterialData.h deleted file mode 100644 index b2fb5deb30..0000000000 --- a/Code/Tools/CryCommonTools/Export/GeometryMaterialData.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYMATERIALDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYMATERIALDATA_H -#pragma once - - -#include "IGeometryMaterialData.h" - -class GeometryMaterialData - : public IGeometryMaterialData -{ -public: - // IGeometryMaterialData - virtual void AddUsedMaterialIndex(int materialIndex); - virtual int GetUsedMaterialCount() const; - virtual int GetUsedMaterialIndex(int usedMaterialIndex) const; - -private: - std::vector m_usedMaterialIndices; - std::map m_usedMaterialIndexIndexMap; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_GEOMETRYMATERIALDATA_H diff --git a/Code/Tools/CryCommonTools/Export/HelperData.h b/Code/Tools/CryCommonTools/Export/HelperData.h deleted file mode 100644 index adede42194..0000000000 --- a/Code/Tools/CryCommonTools/Export/HelperData.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_HELPERDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_HELPERDATA_H -#pragma once - - -struct SHelperData -{ -public: - enum EHelperType - { - eHelperType_UNKNOWN, - eHelperType_Point, - eHelperType_Dummy - }; - -public: - SHelperData() - : m_eHelperType(eHelperType_UNKNOWN) - { - } - -public: - EHelperType m_eHelperType; - float m_boundBoxMin[3]; // used for eHelperType_Dummy only - float m_boundBoxMax[3]; // used for eHelperType_Dummy only -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_HELPERDATA_H diff --git a/Code/Tools/CryCommonTools/Export/IAnimationData.h b/Code/Tools/CryCommonTools/Export/IAnimationData.h deleted file mode 100644 index 4ac11abbb5..0000000000 --- a/Code/Tools/CryCommonTools/Export/IAnimationData.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IANIMATIONDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IANIMATIONDATA_H -#pragma once - - -class IAnimationData -{ -public: - virtual ~IAnimationData() {} - - virtual void SetFrameData(int modelIndex, int frameIndex, float translation[3], float rotation[3], float scale[3]) = 0; - virtual void SetFrameCount(int frameCount) = 0; - - virtual void SetFrameTimePos(int modelIndex, int frameIndex, float time) = 0; - virtual void SetFrameDataPos(int modelIndex, int frameIndex, float translation[3]) = 0; - virtual void SetFrameCountPos(int modelIndex, int frameCount) = 0; - virtual void SetFrameTimeRot(int modelIndex, int frameIndex, float time) = 0; - virtual void SetFrameDataRot(int modelIndex, int frameIndex, float rotation[3]) = 0; - virtual void SetFrameCountRot(int modelIndex, int frameCount) = 0; - virtual void SetFrameTimeScl(int modelIndex, int frameIndex, float time) = 0; - virtual void SetFrameDataScl(int modelIndex, int frameIndex, float scale[3]) = 0; - virtual void SetFrameCountScl(int modelIndex, int frameCount) = 0; - - // For TCB & Ease-In/-Out support - struct TCB - { - float tension; - float continuity; - float bias; - - TCB() - : tension(0) - , continuity(0) - , bias(0) {} - }; - struct Ease - { - float in; - float out; - - Ease() - : in(0) - , out(0) {} - }; - virtual void SetFrameTCBPos(int modelIndex, int frameIndex, TCB tcb) = 0; - virtual void SetFrameTCBRot(int modelIndex, int frameIndex, TCB tcb) = 0; - virtual void SetFrameTCBScl(int modelIndex, int frameIndex, TCB tcb) = 0; - virtual void SetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease ease) = 0; - virtual void SetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease ease) = 0; - virtual void SetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease ease) = 0; - - enum ModelFlags - { - ModelFlags_NoExport = 1 << 0 - }; - - virtual void SetModelFlags(int modelIndex, unsigned modelFlags) = 0; - - virtual void GetFrameData(int modelIndex, int frameIndex, const float*& translation, const float*& rotation, const float*& scale) const = 0; - virtual int GetFrameCount() const = 0; - - virtual float GetFrameTimePos(int modelIndex, int frameIndex) const = 0; - virtual void GetFrameDataPos(int modelIndex, int frameIndex, const float*& translation) const = 0; - virtual int GetFrameCountPos(int modelIndex) const = 0; - virtual float GetFrameTimeRot(int modelIndex, int frameIndex) const = 0; - virtual void GetFrameDataRot(int modelIndex, int frameIndex, const float*& rotation) const = 0; - virtual int GetFrameCountRot(int modelIndex) const = 0; - virtual float GetFrameTimeScl(int modelIndex, int frameIndex) const = 0; - virtual void GetFrameDataScl(int modelIndex, int frameIndex, const float*& scale) const = 0; - virtual int GetFrameCountScl(int modelIndex) const = 0; - - // For TCB & Ease-In/-Out support - virtual void GetFrameTCBPos(int modelIndex, int frameIndex, TCB& tcb) const = 0; - virtual void GetFrameTCBRot(int modelIndex, int frameIndex, TCB& tcb) const = 0; - virtual void GetFrameTCBScl(int modelIndex, int frameIndex, TCB& tcb) const = 0; - virtual void GetFrameEaseInOutPos(int modelIndex, int frameIndex, Ease& ease) const = 0; - virtual void GetFrameEaseInOutRot(int modelIndex, int frameIndex, Ease& ease) const = 0; - virtual void GetFrameEaseInOutScl(int modelIndex, int frameIndex, Ease& ease) const = 0; - - virtual unsigned GetModelFlags(int modelIndex) const = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IANIMATIONDATA_H diff --git a/Code/Tools/CryCommonTools/Export/IExportContext.h b/Code/Tools/CryCommonTools/Export/IExportContext.h deleted file mode 100644 index b2da053e6f..0000000000 --- a/Code/Tools/CryCommonTools/Export/IExportContext.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTCONTEXT_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTCONTEXT_H -#pragma once - - -#include -#include "Exceptions.h" -#include "ILogger.h" - -struct IPakSystem; -class ISettings; - -class IExportContext - : public ILogger -{ -public: - // Declare an exception type to report the case where the scene must be saved before exporting. - struct NeedSaveErrorTag {}; - typedef Exception NeedSaveError; - struct PakSystemErrorTag {}; - typedef Exception PakSystemError; - - virtual void SetProgress(float progress) = 0; - virtual void SetCurrentTask(const std::string& id) = 0; - virtual IPakSystem* GetPakSystem() = 0; - virtual ISettings* GetSettings() = 0; - virtual void GetRootPath(char* buffer, int bufferSizeInBytes) = 0; - -protected: - // ILogger - virtual void LogImpl(ILogger::ESeverity eSeverity, const char* message) = 0; -}; - -struct CurrentTaskScope -{ - CurrentTaskScope(IExportContext* context, const std::string& id) - : context(context) {context->SetCurrentTask(id); } - ~CurrentTaskScope() {context->SetCurrentTask(""); } - IExportContext* context; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTCONTEXT_H diff --git a/Code/Tools/CryCommonTools/Export/IExportSource.h b/Code/Tools/CryCommonTools/Export/IExportSource.h deleted file mode 100644 index 61051d6a2a..0000000000 --- a/Code/Tools/CryCommonTools/Export/IExportSource.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTSOURCE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTSOURCE_H -#pragma once - - -#include "Exceptions.h" - -class ISkeletonData; -class IAnimationData; -class IExportContext; -class IModelData; -class IGeometryFileData; -class IGeometryData; -class IMaterialData; -class ISkinningData; -class IMorphData; -class IGeometryMaterialData; - -namespace ExportGlobal -{ - const float g_defaultFrameRate = 30.f; -}; - -struct SExportMetaData -{ - enum EAxisUp - { - X_UP, - Y_UP, - Z_UP - }; - - char authoring_tool[128]; - char source_data[1024]; // Filename of the source. - char author[128]; // Name of the author. - char revision[64]; - EAxisUp up_axis; - float fMeterUnit; - float fFramesPerSecond; - - SExportMetaData() - { - fMeterUnit = 1.0f; - up_axis = Z_UP; - fFramesPerSecond = ExportGlobal::g_defaultFrameRate; - strcpy(authoring_tool, "CryENGINE Collada Exporter"); - strcpy(source_data, ""); - strcpy(author, ""); - strcpy(revision, "1.4.1"); - } -}; - -class IExportSource -{ -public: - virtual ~IExportSource() - { - } - virtual std::string GetResourceCompilerPath() const = 0; - virtual void GetMetaData(SExportMetaData& metaData) const = 0; - virtual std::string GetDCCFileName() const = 0; - virtual float GetDCCFrameRate() const{ return ExportGlobal::g_defaultFrameRate; } - virtual std::string GetExportDirectory() const = 0; - virtual void ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData) = 0; - virtual bool ReadMaterials(IExportContext* context, const IGeometryFileData* geometryFileData, IMaterialData* materialData) = 0; - virtual void ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData) = 0; - virtual void ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* modelData, int modelIndex, ISkeletonData* skeletonData) = 0; - virtual bool ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData) = 0; - virtual int GetAnimationCount() const = 0; - virtual std::string GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const = 0; - virtual void GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const = 0; - virtual void ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const = 0; - virtual IAnimationData* ReadAnimation(IExportContext* context, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const = 0; - virtual bool ReadGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* modelData, const IMaterialData* materialData, int modelIndex) = 0; - virtual bool ReadGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, const IModelData* modelData, const IMaterialData* materialData, int modelIndex) const = 0; - virtual bool ReadBoneGeometry(IExportContext* context, IGeometryData* geometry, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* materialData) = 0; - virtual bool ReadBoneGeometryMaterialData(IExportContext* context, IGeometryMaterialData* geometryMaterialData, ISkeletonData* skeletonData, int boneIndex, const IMaterialData* materialData) const = 0; - virtual void ReadMorphs(IExportContext* context, IMorphData* morphData, const IModelData* modelData, int modelIndex) = 0; - virtual bool ReadMorphGeometry(IExportContext* context, IGeometryData* geometry, const IModelData* modelData, int modelIndex, const IMorphData* morphData, int morphIndex, const IMaterialData* materialData) = 0; - virtual bool HasValidPosController(const IModelData* modelData, int modelIndex) const = 0; - virtual bool HasValidRotController(const IModelData* modelData, int modelIndex) const = 0; - virtual bool HasValidSclController(const IModelData* modelData, int modelIndex) const = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTSOURCE_H diff --git a/Code/Tools/CryCommonTools/Export/IExportWriter.h b/Code/Tools/CryCommonTools/Export/IExportWriter.h deleted file mode 100644 index 5f53f01049..0000000000 --- a/Code/Tools/CryCommonTools/Export/IExportWriter.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTWRITER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTWRITER_H -#pragma once - - -class IExportSource; -class IExportContext; - -class IExportWriter -{ -public: - virtual void Export(IExportSource* source, IExportContext* context) = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IEXPORTWRITER_H diff --git a/Code/Tools/CryCommonTools/Export/IGeometryData.h b/Code/Tools/CryCommonTools/Export/IGeometryData.h deleted file mode 100644 index 0869c97421..0000000000 --- a/Code/Tools/CryCommonTools/Export/IGeometryData.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYDATA_H -#pragma once - - -class IGeometryData -{ -public: - virtual int AddPosition(float x, float y, float z) = 0; - virtual int AddNormal(float x, float y, float z) = 0; - virtual int AddTextureCoordinate(float u, float v) = 0; - virtual int AddVertexColor(float r, float g, float b, float a) = 0; - virtual int AddPolygon(const int* indices, int mtlID) = 0; - - virtual int GetNumberOfPositions() const = 0; - virtual int GetNumberOfNormals() const = 0; - virtual int GetNumberOfTextureCoordinates() const = 0; - virtual int GetNumberOfVertexColors() const = 0; - virtual int GetNumberOfPolygons() const = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYDATA_H diff --git a/Code/Tools/CryCommonTools/Export/IGeometryFileData.h b/Code/Tools/CryCommonTools/Export/IGeometryFileData.h deleted file mode 100644 index bc81366ab2..0000000000 --- a/Code/Tools/CryCommonTools/Export/IGeometryFileData.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYFILEDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYFILEDATA_H -#pragma once - - -#include "ExportFileType.h" -#include - -class IGeometryFileData -{ -public: - struct SProperties - { - int filetypeInt; // combination of flags from CryFileType - bool bDoNotMerge; - bool bUseCustomNormals; - bool bUseF32VertexFormat; - bool b8WeightsPerVertex; - std::string customExportPath; - - SProperties() - : filetypeInt(CRY_FILE_TYPE_NONE) - , bDoNotMerge(false) - , bUseCustomNormals(false) - , bUseF32VertexFormat(false) - , b8WeightsPerVertex(false) - { - } - }; -public: - virtual int AddGeometryFile(const void* handle, const char* name, const SProperties& properties) = 0; - virtual const SProperties& GetProperties(int geometryFileIndex) const = 0; - virtual int GetGeometryFileCount() const = 0; - - // return an implementation-specific handle (for example a maya Dag Path string, or a MAX node name or whatever) - // its opaque to the exporter, but you can cast it yourself. - virtual const void* GetGeometryFileHandle(int geometryFileIndex) const = 0; - virtual const char* GetGeometryFileName(int geometryFileIndex) const = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYFILEDATA_H diff --git a/Code/Tools/CryCommonTools/Export/IGeometryMaterialData.h b/Code/Tools/CryCommonTools/Export/IGeometryMaterialData.h deleted file mode 100644 index 1c4eca55bf..0000000000 --- a/Code/Tools/CryCommonTools/Export/IGeometryMaterialData.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYMATERIALDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYMATERIALDATA_H -#pragma once - - -class IGeometryMaterialData -{ -public: - virtual void AddUsedMaterialIndex(int materialIndex) = 0; - virtual int GetUsedMaterialCount() const = 0; - virtual int GetUsedMaterialIndex(int usedMaterialIndex) const = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IGEOMETRYMATERIALDATA_H diff --git a/Code/Tools/CryCommonTools/Export/IMaterialData.h b/Code/Tools/CryCommonTools/Export/IMaterialData.h deleted file mode 100644 index 82102eb3ce..0000000000 --- a/Code/Tools/CryCommonTools/Export/IMaterialData.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMATERIALDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMATERIALDATA_H -#pragma once - - -class IMaterialData -{ -public: - // the handle represents an implementation specific underlying handle (like a maya pointer to a string dag name). - virtual int AddMaterial(const char* name, int id, const void* handle, const char* properties) = 0; - virtual int AddMaterial(const char* name, int id, const char* subMatName, const void* handle, const char* properties) = 0; - virtual int GetMaterialCount() const = 0; - virtual const char* GetName(int materialIndex) const = 0; - virtual int GetID(int materialIndex) const = 0; - virtual const char* GetSubMatName(int materialIndex) const = 0; - virtual const void* GetHandle(int materialIndex) const = 0; - virtual const char* GetProperties(int materialIndex) const = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMATERIALDATA_H diff --git a/Code/Tools/CryCommonTools/Export/IModelData.h b/Code/Tools/CryCommonTools/Export/IModelData.h deleted file mode 100644 index 26ea7ed385..0000000000 --- a/Code/Tools/CryCommonTools/Export/IModelData.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMODELDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMODELDATA_H -#pragma once - - -#include "HelperData.h" -#include - -class IModelData -{ -public: - virtual int AddModel(const void* handle, const char* modelName, int parentModelIndex, bool geometry, const SHelperData& helperData, const std::string& propertiesString) = 0; - virtual int GetModelCount() const = 0; - virtual const void* GetModelHandle(int modelIndex) const = 0; - virtual const char* GetModelName(int modelIndex) const = 0; - virtual void SetTranslationRotationScale(int modelIndex, const float* translation, const float* rotation, const float* scale) = 0; - virtual void GetTranslationRotationScale(int modelIndex, float* translation, float* rotation, float* scale) const = 0; - virtual const SHelperData& GetHelperData(int modelIndex) const = 0; - virtual const std::string& GetProperties(int modelIndex) const = 0; - virtual bool IsRoot(int modelIndex) const = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMODELDATA_H diff --git a/Code/Tools/CryCommonTools/Export/IMorphData.h b/Code/Tools/CryCommonTools/Export/IMorphData.h deleted file mode 100644 index 26c4f05e71..0000000000 --- a/Code/Tools/CryCommonTools/Export/IMorphData.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMORPHDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMORPHDATA_H -#pragma once - - -class IMorphData -{ -public: - virtual void SetHandle(const void* handle) = 0; - virtual void AddMorph(const void* handle, const char* name, const char* fullName = NULL) = 0; - virtual const void* GetHandle() const = 0; - virtual int GetMorphCount() const = 0; - virtual const void* GetMorphHandle(int morphIndex) const = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_IMORPHDATA_H diff --git a/Code/Tools/CryCommonTools/Export/ISkeletonData.h b/Code/Tools/CryCommonTools/Export/ISkeletonData.h deleted file mode 100644 index 75f3317343..0000000000 --- a/Code/Tools/CryCommonTools/Export/ISkeletonData.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKELETONDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKELETONDATA_H -#pragma once - - -class ISkeletonData -{ -public: - enum Axis - { - AxisX, - AxisY, - AxisZ - }; - enum Limit - { - LimitMin, - LimitMax - }; - - virtual int AddBone(const void* handle, const char* name, int parentIndex) = 0; - virtual int FindBone(const char* name) const = 0; - virtual const void* GetBoneHandle(int boneIndex) const = 0; - virtual int GetBoneParentIndex(int boneIndex) const = 0; - virtual int GetBoneCount() const = 0; - virtual void SetTranslation(int boneIndex, const float* vec) = 0; - virtual void SetRotation(int boneIndex, const float* vec) = 0; - virtual void SetScale(int boneIndex, const float* vec) = 0; - virtual void SetParentFrameTranslation(int boneIndex, const float* vec) = 0; - virtual void SetParentFrameRotation(int boneIndex, const float* vec) = 0; - virtual void SetParentFrameScale(int boneIndex, const float* vec) = 0; - virtual void SetPhysicalized(int boneIndex, bool physicalized) = 0; - virtual void SetHasGeometry(int boneIndex, bool hasGeometry) = 0; - virtual void SetBoneProperties(int boneIndex, const char* propertiesString) = 0; - virtual void SetBoneGeomProperties(int boneIndex, const char* propertiesString) = 0; - - virtual void SetLimit(int boneIndex, Axis axis, Limit extreme, float limit) = 0; - virtual void SetSpringTension(int boneIndex, Axis axis, float springTension) = 0; - virtual void SetSpringAngle(int boneIndex, Axis axis, float springAngle) = 0; - virtual void SetAxisDamping(int boneIndex, Axis axis, float damping) = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKELETONDATA_H diff --git a/Code/Tools/CryCommonTools/Export/ISkinningData.h b/Code/Tools/CryCommonTools/Export/ISkinningData.h deleted file mode 100644 index d20a3ad301..0000000000 --- a/Code/Tools/CryCommonTools/Export/ISkinningData.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKINNINGDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKINNINGDATA_H -#pragma once - - -class ISkinningData -{ -public: - virtual void SetVertexCount(int vertexCount) = 0; - virtual void AddWeight(int vertexIndex, int boneIndex, float weight) = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_ISKINNINGDATA_H diff --git a/Code/Tools/CryCommonTools/Export/MaterialData.cpp b/Code/Tools/CryCommonTools/Export/MaterialData.cpp deleted file mode 100644 index 243a0dcd93..0000000000 --- a/Code/Tools/CryCommonTools/Export/MaterialData.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "MaterialData.h" - -int MaterialData::AddMaterial(const char* name, int id, const void* handle, const char* properties) -{ - const int materialIndex = int(m_materials.size()); - m_materials.push_back(MaterialEntry(name, id, "submat", handle, properties)); - return materialIndex; -} - -int MaterialData::AddMaterial(const char* name, int id, const char* subMatName, const void* handle, const char* properties) -{ - const int materialIndex = int(m_materials.size()); - m_materials.push_back(MaterialEntry(name, id, subMatName, handle, properties)); - return materialIndex; -} - -int MaterialData::GetMaterialCount() const -{ - return int(m_materials.size()); -} - -const char* MaterialData::GetName(int materialIndex) const -{ - assert(materialIndex >= 0); - assert(materialIndex < int(m_materials.size())); - return m_materials[materialIndex].name.c_str(); -} - -int MaterialData::GetID(int materialIndex) const -{ - assert(materialIndex >= 0); - assert(materialIndex < int(m_materials.size())); - return m_materials[materialIndex].id; -} - -const char* MaterialData::GetSubMatName(int materialIndex) const -{ - assert(materialIndex >= 0); - assert(materialIndex < int(m_materials.size())); - return m_materials[materialIndex].subMatName.c_str(); -} - -const void* MaterialData::GetHandle(int materialIndex) const -{ - assert(materialIndex >= 0); - assert(materialIndex < int(m_materials.size())); - return m_materials[materialIndex].handle; -} - -const char* MaterialData::GetProperties(int materialIndex) const -{ - assert(materialIndex >= 0); - assert(materialIndex < int(m_materials.size())); - return m_materials[materialIndex].properties.c_str(); -} diff --git a/Code/Tools/CryCommonTools/Export/MaterialData.h b/Code/Tools/CryCommonTools/Export/MaterialData.h deleted file mode 100644 index 5916f56f9b..0000000000 --- a/Code/Tools/CryCommonTools/Export/MaterialData.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALDATA_H -#pragma once - - -#include "IMaterialData.h" - -class MaterialData - : public IMaterialData -{ -public: - virtual int AddMaterial(const char* name, int id, const void* handle, const char* properties); - virtual int AddMaterial(const char* name, int id, const char* subMatName, const void* handle, const char* properties); - virtual int GetMaterialCount() const; - virtual const char* GetName(int materialIndex) const; - virtual int GetID(int materialIndex) const; - virtual const char* GetSubMatName(int materialIndex) const; - virtual const void* GetHandle(int materialIndex) const; - virtual const char* GetProperties(int materialIndex) const; - -private: - struct MaterialEntry - { - MaterialEntry(const char* a_name, int a_id, const char* a_subMatName, const void* a_handle, const char* a_properties) - : name(a_name) - , id(a_id) - , subMatName(a_subMatName) - , handle(a_handle) - , properties(a_properties ? a_properties : "") - { - } - - string name; - int id; - string subMatName; - const void* handle; - string properties; - }; - - std::vector m_materials; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALDATA_H diff --git a/Code/Tools/CryCommonTools/Export/MaterialHelpers.cpp b/Code/Tools/CryCommonTools/Export/MaterialHelpers.cpp deleted file mode 100644 index 82b9d1b88d..0000000000 --- a/Code/Tools/CryCommonTools/Export/MaterialHelpers.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "MaterialHelpers.h" -#include "StringHelpers.h" -#include "PathHelpers.h" -#include "properties.h" - -MaterialHelpers::MaterialInfo::MaterialInfo() -{ - this->id = -1; - this->name = ""; - this->physicalize = "None"; - this->diffuseTexture = ""; - this->diffuseColor[0] = this->diffuseColor[1] = this->diffuseColor[2] = 1.0f; - this->specularColor[0] = this->specularColor[1] = this->specularColor[2] = 1.0f; - this->emissiveColor[0] = this->emissiveColor[1] = this->emissiveColor[2] = 0.0f; -} - -std::string MaterialHelpers::PhysicsIDToString(const int physicsID) -{ - switch (physicsID) - { - case 1: - return "Default"; - break; - case 2: - return "ProxyNoDraw"; - break; - case 3: - return "NoCollide"; - break; - case 4: - return "Obstruct"; - break; - default: - return "None"; - break; - } -} - -bool MaterialHelpers::WriteMaterials(const std::string& filename, const std::vector& materialList) -{ - FILE* materialFile = fopen(filename.c_str(), "w"); - if (materialFile) - { - fprintf(materialFile, "\n"); - fprintf(materialFile, " \n"); - for (int i = 0; i < materialList.size(); i++) - { - const MaterialInfo& material = materialList[i]; - - fprintf(materialFile, " \n"); - - fprintf(materialFile, " \n"); - - // Write out diffuse texture. - if (material.diffuseTexture.length() > 0) - { - //fprintf( materialFile, " \n", ProcessTexturePath( material.diffuseTexture ).c_str() ); - fprintf(materialFile, " \n", material.diffuseTexture.c_str()); - fprintf(materialFile, " \n"); - fprintf(materialFile, " \n"); - } - - fprintf(materialFile, " \n"); - fprintf(materialFile, " \n"); - } - fprintf(materialFile, " \n"); - fprintf(materialFile, "\n"); - fclose(materialFile); - - return true; - } - else - { - return false; - } -} diff --git a/Code/Tools/CryCommonTools/Export/MaterialHelpers.h b/Code/Tools/CryCommonTools/Export/MaterialHelpers.h deleted file mode 100644 index 0afe9de48c..0000000000 --- a/Code/Tools/CryCommonTools/Export/MaterialHelpers.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALHELPERS_H -#pragma once - - -namespace MaterialHelpers -{ - struct MaterialInfo - { - MaterialInfo();// : id(-1) { } - - std::string name; - std::string physicalize; - int id; - - float diffuseColor[3]; - float specularColor[3]; - float emissiveColor[3]; - std::string diffuseTexture; - }; - - std::string PhysicsIDToString(const int physicsID); - bool WriteMaterials(const std::string& filename, const std::vector& materialList); -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MATERIALHELPERS_H diff --git a/Code/Tools/CryCommonTools/Export/MaxHelpers.h b/Code/Tools/CryCommonTools/Export/MaxHelpers.h deleted file mode 100644 index bbb1cf17b7..0000000000 --- a/Code/Tools/CryCommonTools/Export/MaxHelpers.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXHELPERS_H -#pragma once - - -#include "CompileTimeAssert.h" -#include "PathHelpers.h" -#include "StringHelpers.h" - - -namespace MaxHelpers -{ - enum - { - kBadChar = '_' - }; - -#if !defined(MAX_PRODUCT_VERSION_MAJOR) - #error MAX_PRODUCT_VERSION_MAJOR is undefined -#elif (MAX_PRODUCT_VERSION_MAJOR >= 15) - COMPILE_TIME_ASSERT(sizeof(MCHAR) == 2); - #define MAX_MCHAR_SIZE 2 - typedef wstring MaxCompatibleString; -#elif (MAX_PRODUCT_VERSION_MAJOR >= 12) - COMPILE_TIME_ASSERT(sizeof(MCHAR) == 1); - #define MAX_MCHAR_SIZE 1 - typedef string MaxCompatibleString; -#else - #error 3dsMax 2009 and older are not supported anymore -#endif - - inline string CreateAsciiString(const char* s_ansi) - { - return StringHelpers::ConvertAnsiToAscii(s_ansi, kBadChar); - } - - - inline string CreateAsciiString(const wchar_t* s_utf16) - { - const string s_ansi = StringHelpers::ConvertUtf16ToAnsi(s_utf16, kBadChar); - return CreateAsciiString(s_ansi.c_str()); - } - - - inline string CreateUtf8String(const char* s_ansi) - { - return StringHelpers::ConvertAnsiToUtf8(s_ansi); - } - - - inline string CreateUtf8String(const wchar_t* s_utf16) - { - return StringHelpers::ConvertUtf16ToUtf8(s_utf16); - } - - - inline string CreateTidyAsciiNodeName(const char* s_ansi) - { - const size_t len = strlen(s_ansi); - - string res; - res.reserve(len); - - for (size_t i = 0; i < len; ++i) - { - char c = s_ansi[i]; - if (c < ' ' || c >= 127) - { - c = kBadChar; - } - res.append(1, c); - } - return res; - } - - - inline string CreateTidyAsciiNodeName(const wchar_t* s_utf16) - { - const string s_ansi = StringHelpers::ConvertUtf16ToAnsi(s_utf16, kBadChar); - return CreateTidyAsciiNodeName(s_ansi.c_str()); - ; - } - - - inline MSTR CreateMaxStringFromAscii(const char* s_ascii) - { -#if (MAX_MCHAR_SIZE == 2) - return MSTR(StringHelpers::ConvertAsciiToUtf16(s_ascii).c_str()); -#else - return MSTR(s_ascii); -#endif - } - - - inline MaxCompatibleString CreateMaxCompatibleStringFromAscii(const char* s_ascii) - { -#if (MAX_MCHAR_SIZE == 2) - return StringHelpers::ConvertAsciiToUtf16(s_ascii); -#else - return MaxCompatibleString(s_ascii); -#endif - } - - - inline string GetAbsoluteAsciiPath(const char* s_ansi) - { - if (!s_ansi || !s_ansi[0]) - { - return string(); - } - return PathHelpers::GetAbsoluteAsciiPath(StringHelpers::ConvertAnsiToUtf16(s_ansi).c_str()); - } - - - inline string GetAbsoluteAsciiPath(const wchar_t* s_utf16) - { - if (!s_utf16 || !s_utf16[0]) - { - return string(); - } - return PathHelpers::GetAbsoluteAsciiPath(s_utf16); - } -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXHELPERS_H diff --git a/Code/Tools/CryCommonTools/Export/MaxUserPropertyHelpers.cpp b/Code/Tools/CryCommonTools/Export/MaxUserPropertyHelpers.cpp deleted file mode 100644 index 2afe2ca0b0..0000000000 --- a/Code/Tools/CryCommonTools/Export/MaxUserPropertyHelpers.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "MaxUserPropertyHelpers.h" -#include "StringHelpers.h" -#include "MaxHelpers.h" - - -std::string MaxUserPropertyHelpers::GetNodeProperties(INode* node) -{ - if (node == 0) - { - return std::string(); - } - - MSTR buf; - node->GetUserPropBuffer(buf); - - return MaxHelpers::CreateAsciiString(buf); -} - - -std::string MaxUserPropertyHelpers::GetStringNodeProperty(INode* node, const char* name, const char* defaultValue) -{ - if (node == 0) - { - return defaultValue; - } - - MSTR val; - if (!node->GetUserPropString(MaxHelpers::CreateMaxStringFromAscii(name), val)) - { - return defaultValue; - } - - return MaxHelpers::CreateAsciiString(val); -} - - -float MaxUserPropertyHelpers::GetFloatNodeProperty(INode* node, const char* name, float defaultValue) -{ - if (node == 0) - { - return defaultValue; - } - - float val; - if (!node->GetUserPropFloat(MaxHelpers::CreateMaxStringFromAscii(name), val)) - { - return defaultValue; - } - - return val; -} - - -int MaxUserPropertyHelpers::GetIntNodeProperty(INode* node, const char* name, int defaultValue) -{ - if (node == 0) - { - return defaultValue; - } - - int val; - if (!node->GetUserPropInt(MaxHelpers::CreateMaxStringFromAscii(name), val)) - { - return defaultValue; - } - - return val; -} - - -bool MaxUserPropertyHelpers::GetBoolNodeProperty(INode* node, const char* name, bool defaultValue) -{ - if (node == 0) - { - return defaultValue; - } - - BOOL val; - if (!node->GetUserPropBool(MaxHelpers::CreateMaxStringFromAscii(name), val)) - { - return defaultValue; - } - - return (val != 0); -} diff --git a/Code/Tools/CryCommonTools/Export/MaxUserPropertyHelpers.h b/Code/Tools/CryCommonTools/Export/MaxUserPropertyHelpers.h deleted file mode 100644 index efef23e167..0000000000 --- a/Code/Tools/CryCommonTools/Export/MaxUserPropertyHelpers.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXUSERPROPERTYHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXUSERPROPERTYHELPERS_H -#pragma once - - -#include - -class INode; - -namespace MaxUserPropertyHelpers -{ - std::string GetNodeProperties(INode* node); - std::string GetStringNodeProperty(INode* node, const char* name, const char* defaultValue); - float GetFloatNodeProperty(INode* node, const char* name, float defaultValue); - int GetIntNodeProperty(INode* node, const char* name, int defaultValue); - bool GetBoolNodeProperty(INode* node, const char* name, bool defaultValue); -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MAXUSERPROPERTYHELPERS_H diff --git a/Code/Tools/CryCommonTools/Export/MeshUtils.h b/Code/Tools/CryCommonTools/Export/MeshUtils.h deleted file mode 100644 index 81b456bffb..0000000000 --- a/Code/Tools/CryCommonTools/Export/MeshUtils.h +++ /dev/null @@ -1,914 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MESHUTILS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MESHUTILS_H -#pragma once - - -#include "BaseTypes.h" // uint8 -#include "Cry_Vector3.h" // Vec3 -#include "IIndexedMesh.h" // CMesh -namespace MeshUtils -{ - struct Face - { - int vertexIndex[3]; - }; - - struct Color - { - uint8 r; - uint8 g; - uint8 b; - }; - - // Stores linking of a vertex to bone(s) - class VertexLinks - { - public: - struct Link - { - int boneId; - float weight; - Vec3 offset; - - Link() - : boneId(-1) - , weight(-1.0f) - , offset(0.0f, 0.0f, 0.0f) - { - } - }; - - enum ESort - { - eSort_ByWeight, - eSort_ByBoneId, - }; - - public: - std::vector links; - - public: - // minWeightToDelete: links with weights <= minWeightToDelete will be deleted - const char* Normalize(ESort eSort, const float minWeightToDelete, const int maxLinkCount) - { - if (minWeightToDelete < 0 || minWeightToDelete >= 1) - { - return "Bad minWeightToDelete passed"; - } - if (maxLinkCount <= 0) - { - return "Bad maxLinkCount passed"; - } - - // Merging links with matching bone ids - { - DeleteByWeight(0.0f); - - if (links.empty()) - { - return "All bone links of a vertex have zero weight"; - } - - std::sort(links.begin(), links.end(), CompareLinksByBoneId); - - size_t dst = 0; - for (size_t i = 1; i < links.size(); ++i) - { - if (links[i].boneId == links[dst].boneId) - { - const float w0 = links[dst].weight; - const float w1 = links[i].weight; - const float a = w0 / (w0 + w1); - links[dst].offset = links[dst].offset * a + links[i].offset * (1 - a); - links[dst].weight = w0 + w1; - } - else - { - links[++dst] = links[i]; - } - } - - links.resize(dst + 1); - } - - // Deleting links, normalizing link weights. - // - // Note: we produce meaningful results even in cases like this: - // input weights are { 0.03, 0.01 }, minWeightTodelete is 0.2. - // Output weights produced are { 0.75, 0.25 }. - { - std::sort(links.begin(), links.end(), CompareLinksByWeight); - - if (links.size() > maxLinkCount) - { - links.resize(maxLinkCount); - } - - NormalizeWeights(); - - const size_t oldSize = links.size(); - - DeleteByWeight(minWeightToDelete); - - if (links.empty()) - { - return "All bone links of a vertex are deleted (minWeightToDelete is too big)"; - } - - if (links.size() != oldSize) - { - NormalizeWeights(); - } - } - - switch (eSort) - { - case eSort_ByWeight: - // Do nothing because we already sorted links by weight (see above) - break; - case eSort_ByBoneId: - std::sort(links.begin(), links.end(), CompareLinksByBoneId); - break; - default: - assert(0); - break; - } - - return 0; - } - - private: - void DeleteByWeight(float minWeightToDelete) - { - for (size_t i = 0; i < links.size(); ++i) - { - if (links[i].weight <= minWeightToDelete) - { - if (i < links.size() - 1) - { - links[i] = links[links.size() - 1]; - } - links.resize(links.size() - 1); - --i; - } - } - } - - void NormalizeWeights() - { - assert(!links.empty() && links[0].weight > 0); - - float w = 0; - - for (size_t i = 0; i < links.size(); ++i) - { - w += links[i].weight; - } - - w = 1 / w; - - for (size_t i = 0; i < links.size(); ++i) - { - links[i].weight *= w; - } - } - - static bool CompareLinksByBoneId(const Link& left, const Link& right) - { - if (left.boneId != right.boneId) - { - return left.boneId < right.boneId; - } - if (left.weight != right.weight) - { - return left.weight < right.weight; - } - return memcmp(&left.offset, &right.offset, sizeof(left.offset)) < 0; - } - - static bool CompareLinksByWeight(const Link& left, const Link& right) - { - if (left.weight != right.weight) - { - return left.weight > right.weight; - } - if (left.boneId != right.boneId) - { - return left.boneId < right.boneId; - } - return memcmp(&left.offset, &right.offset, sizeof(left.offset)) < 0; - } - }; - - - class Mesh - { - public: - // Vertex data - std::vector m_positions; - std::vector m_topologyIds; - std::vector m_normals; - std::vector> m_texCoords; - std::vector m_colors; - std::vector m_alphas; - std::vector m_links; - std::vector m_vertexMatIds; - size_t m_auxSizeof; - std::vector m_aux; - - // Face data - std::vector m_faces; - std::vector m_faceMatIds; - - // Mappings computed and filled by ComputeVertexRemapping() - std::vector m_vertexOldToNew; - std::vector m_vertexNewToOld; - - public: - Mesh() - : m_auxSizeof(0) - { - } - - int GetVertexCount() const - { - return m_positions.size(); - } - - int GetFaceCount() const - { - return m_faces.size(); - } - - ////////////////////////////////////////////////////////////////////////// - // Setters - - void Clear() - { - m_positions.clear(); - m_topologyIds.clear(); - m_normals.clear(); - m_texCoords.clear(); - m_colors.clear(); - m_alphas.clear(); - m_links.clear(); - m_vertexMatIds.clear(); - m_aux.clear(); - - m_faces.clear(); - m_faceMatIds.clear(); - - m_vertexOldToNew.clear(); - m_vertexNewToOld.clear(); - } - - const char* SetPositions(const float* pVec3, int count, int stride, const float scale) - { - if (count <= 0) - { - return "bad position count"; - } - if (stride < 0 || (stride > 0 && stride < sizeof(Vec3))) - { - return "bad position stride"; - } - - m_positions.resize(count); - - for (int i = 0; i < count; ++i) - { - const float* const p = (const float*)(((const char*)pVec3) + ((size_t)i * stride)); - if (!_finite(p[0]) || !_finite(p[1]) || !_finite(p[2])) - { - m_positions.clear(); - return "Illegal (NAN) vertex position. Fix the 3d Model."; - } - m_positions[i].x = p[0] * scale; - m_positions[i].y = p[1] * scale; - m_positions[i].z = p[2] * scale; - } - - return 0; - } - - const char* SetTopologyIds(const int* pTopo, int count, int stride) - { - if (count <= 0) - { - return "bad topologyId count"; - } - if (stride < 0 || (stride > 0 && stride < sizeof(int))) - { - return "bad topologyId stride"; - } - - m_topologyIds.resize(count); - - for (int i = 0; i < count; ++i) - { - const int* const p = (const int*)(((const char*)pTopo) + ((size_t)i * stride)); - m_topologyIds[i] = p[0]; - } - - return 0; - } - - const char* SetNormals(const float* pVec3, int count, int stride) - { - if (count <= 0) - { - return "bad normal count"; - } - if (stride < 0 || (stride > 0 && stride < sizeof(Vec3))) - { - return "bad normal stride"; - } - - m_normals.resize(count); - - for (int i = 0; i < count; ++i) - { - const float* const p = (const float*)(((const char*)pVec3) + ((size_t)i * stride)); - if (!_finite(p[0]) || !_finite(p[1]) || !_finite(p[2])) - { - m_normals.clear(); - return "Illegal (NAN) vertex normal. Fix the 3d Model."; - } - m_normals[i].x = p[0]; - m_normals[i].y = p[1]; - m_normals[i].z = p[2]; - m_normals[i] = m_normals[i].GetNormalizedSafe(Vec3_OneZ); - } - - return 0; - } - - const char* SetTexCoords(const float* pVec2, int count, int stride, bool bFlipT, uint streamIndex) - { - if (count <= 0) - { - return "bad texCoord count"; - } - if (stride < 0 || (stride > 0 && stride < sizeof(float) * 2)) - { - return "bad texCoord stride"; - } - if (m_texCoords.size() <= streamIndex) - { - m_texCoords.resize(streamIndex + 1); - } - - m_texCoords[streamIndex].resize(count); - - for (int i = 0; i < count; ++i) - { - const float* const p = (const float*)(((const char*)pVec2) + ((size_t)i * stride)); - if (!_finite(p[0]) || !_finite(p[1])) - { - m_texCoords[streamIndex].clear(); - return "Illegal (NAN) texture coordinate. Fix the 3d Model."; - } - m_texCoords[streamIndex][i].x = p[0]; - m_texCoords[streamIndex][i].y = bFlipT ? 1 - p[1] : p[1]; - } - - return 0; - } - - const char* SetColors(const uint8* pRgb, int count, int stride) - { - if (count <= 0) - { - return "bad color count"; - } - if (stride < 0 || (stride > 0 && stride < 3)) - { - return "bad color stride"; - } - - m_colors.resize(count); - - for (int i = 0; i < count; ++i) - { - const uint8* const p = (((const uint8*)pRgb) + ((size_t)i * stride)); - m_colors[i].r = p[0]; - m_colors[i].g = p[1]; - m_colors[i].b = p[2]; - } - - return 0; - } - - const char* SetAlphas(const uint8* pAlpha, int count, int stride) - { - if (count <= 0) - { - return "bad alpha count"; - } - if (stride < 0) - { - return "bad alpha stride"; - } - - m_alphas.resize(count); - - for (int i = 0; i < count; ++i) - { - const uint8* const p = (((const uint8*)pAlpha) + ((size_t)i * stride)); - m_alphas[i] = p[0]; - } - - return 0; - } - - const char* SetFaces(const int* pVertIdx3, int count, int stride) - { - if (count <= 0) - { - return "bad face count"; - } - if (stride < 0 || (stride > 0 && stride < 3 * sizeof(int))) - { - return "bad face stride"; - } - - m_faces.resize(count); - - for (int i = 0; i < count; ++i) - { - const int* const p = (const int*)(((const char*)pVertIdx3) + ((size_t)i * stride)); - for (int j = 0; j < 3; ++j) - { - if (p[j] < 0 || p[j] >= m_positions.size()) - { - return "bad vertex index found in a face"; - } - m_faces[i].vertexIndex[j] = p[j]; - } - } - - return 0; - } - - const char* SetFaceMatIds(const int* pMatIds, int count, int stride, int maxMaterialId) - { - if (count <= 0) - { - return "bad face materialId count"; - } - if (stride < 0 || (stride > 0 && stride < sizeof(int))) - { - return "bad face materialIdstride"; - } - - m_faceMatIds.resize(count); - - for (int i = 0; i < count; ++i) - { - const int* const p = (const int*)(((const char*)pMatIds) + ((size_t)i * stride)); - if (p[0] < 0) - { - return "negative material ID found in a face"; - } - if (p[0] >= maxMaterialId) - { - return "material ID found in a face is outside of allowed ranges"; - } - m_faceMatIds[i] = p[0]; - } - - return 0; - } - - const char* SetAux(size_t auxSizeof, const void* pData, int count, int stride) - { - if (auxSizeof <= 0) - { - return "bad aux sizeof"; - } - if (count <= 0) - { - return "bad aux count"; - } - if (stride < 0 || (stride > 0 && stride < auxSizeof)) - { - return "bad aux stride"; - } - - m_auxSizeof = auxSizeof; - - m_aux.resize(count * m_auxSizeof); - - for (int i = 0; i < count; ++i) - { - const uint8* const p = (((const uint8*)pData) + ((size_t)i * stride)); - memcpy(&m_aux[i * m_auxSizeof], p, m_auxSizeof); - } - - return 0; - } - - ////////////////////////////////////////////////////////////////////////// - // Validation - - // Returns 0 if ok, or pointer to the error text - const char* Validate() const - { - const int nVerts = (int)m_positions.size(); - if (nVerts <= 0) - { - return "No vertices"; - } - - const int nFaces = (int)m_faces.size(); - if (nFaces <= 0) - { - return "No faces"; - } - - if (!m_topologyIds.empty() && nVerts != (int)m_topologyIds.size()) - { - return "Mismatch in the number of topology IDs"; - } - - if (!m_normals.empty() && nVerts != (int)m_normals.size()) - { - return "Mismatch in the number of normals"; - } - - for (uint streamIndex = 0; streamIndex < m_texCoords.size(); ++streamIndex) - { - if (!m_texCoords[streamIndex].empty() && nVerts != (int)m_texCoords[streamIndex].size()) - { - return "Mismatch in the number of texture coordinates"; - } - } - - if (!m_colors.empty() && nVerts != (int)m_colors.size()) - { - return "Mismatch in the number of colors"; - } - - if (!m_alphas.empty() && nVerts != (int)m_alphas.size()) - { - return "Mismatch in the number of alphas"; - } - - if (!m_links.empty() && nVerts != (int)m_links.size()) - { - return "Mismatch in the number of vertex-bone links"; - } - - for (size_t i = 0; i < m_links.size(); ++i) - { - if (m_links[i].links.empty()) - { - return "Found a vertex without bone linking"; - } - } - - if (!m_vertexMatIds.empty() && nVerts != (int)m_vertexMatIds.size()) - { - return "Mismatch in the number of vertex materials"; - } - - if (!m_aux.empty() && nVerts != (int)(m_aux.size() / m_auxSizeof)) - { - return "Mismatch in the number of auxiliary elements"; - } - - if (!m_faceMatIds.empty() && nFaces != (int)m_faceMatIds.size()) - { - return "Mismatch in the number of face materials"; - } - - return 0; - } - - ////////////////////////////////////////////////////////////////////////// - // Computation - - void RemoveDegenerateFaces() - { - int writePos = 0; - for (int readPos = 0; readPos < (int)m_faces.size(); ++readPos) - { - const Face& face = m_faces[readPos]; - if (face.vertexIndex[0] != face.vertexIndex[1] && - face.vertexIndex[1] != face.vertexIndex[2] && - face.vertexIndex[0] != face.vertexIndex[2]) - { - m_faces[writePos] = m_faces[readPos]; - if (!m_faceMatIds.empty()) - { - m_faceMatIds[writePos] = m_faceMatIds[readPos]; - } - ++writePos; - } - } - m_faces.resize(writePos); - if (!m_faceMatIds.empty()) - { - m_faceMatIds.resize(writePos); - } - } - - int AddVertexCopy(int sourceVertexIndex) - { - if (sourceVertexIndex < 0 || sourceVertexIndex >= m_positions.size()) - { - assert(0); - return -1; - } - - m_positions.push_back(m_positions[sourceVertexIndex]); - if (!m_topologyIds.empty()) - { - m_topologyIds.push_back(m_topologyIds[sourceVertexIndex]); - } - if (!m_normals.empty()) - { - m_normals.push_back(m_normals[sourceVertexIndex]); - } - for (uint streamIndex = 0; streamIndex < m_texCoords.size(); ++streamIndex) - { - if (!m_texCoords[streamIndex].empty()) - { - m_texCoords[streamIndex].push_back(m_texCoords[streamIndex][sourceVertexIndex]); - } - } - if (!m_colors.empty()) - { - m_colors.push_back(m_colors[sourceVertexIndex]); - } - if (!m_alphas.empty()) - { - m_alphas.push_back(m_alphas[sourceVertexIndex]); - } - if (!m_links.empty()) - { - m_links.push_back(m_links[sourceVertexIndex]); - } - if (!m_vertexMatIds.empty()) - { - m_vertexMatIds.push_back(m_vertexMatIds[sourceVertexIndex]); - } - if (!m_aux.empty()) - { - m_aux.resize(m_aux.size() + m_auxSizeof); - memcpy(&m_aux[m_aux.size() - m_auxSizeof], &m_aux[sourceVertexIndex * m_auxSizeof], m_auxSizeof); - } - return (int)m_positions.size() - 1; - } - - // Note: might create new vertices and modify vertex indices in faces - void SetVertexMaterialIdsFromFaceMaterialIds() - { - m_vertexMatIds.clear(); - if (m_faceMatIds.empty()) - { - return; - } - m_vertexMatIds.resize(m_positions.size(), -1); - - for (size_t i = 0; i < m_faces.size(); ++i) - { - const int faceMatId = m_faceMatIds[i]; - for (int j = 0; j < 3; ++j) - { - int v = m_faces[i].vertexIndex[j]; - if (m_vertexMatIds[v] >= 0 && m_vertexMatIds[v] != faceMatId) - { - v = AddVertexCopy(v); - m_faces[i].vertexIndex[j] = v; - } - m_vertexMatIds[v] = faceMatId; - } - } - } - - // Computes m_vertexOldToNew and m_vertexNewToOld by detecting duplicate vertices - void ComputeVertexRemapping() - { - const size_t nVerts = m_positions.size(); - - m_vertexNewToOld.resize(nVerts); - for (size_t i = 0; i < nVerts; ++i) - { - m_vertexNewToOld[i] = i; - } - - VertexLess less(*this); - std::sort(m_vertexNewToOld.begin(), m_vertexNewToOld.end(), less); - - m_vertexOldToNew.resize(nVerts); - - int nVertsNew = 0; - for (size_t i = 0; i < nVerts; ++i) - { - if (i == 0 || less(m_vertexNewToOld[i - 1], m_vertexNewToOld[i])) - { - m_vertexNewToOld[nVertsNew++] = m_vertexNewToOld[i]; - } - m_vertexOldToNew[m_vertexNewToOld[i]] = nVertsNew - 1; - } - m_vertexNewToOld.resize(nVertsNew); - } - - // Changes order of vertices, number of vertices, vertex indices in faces - void RemoveVerticesByUsingComputedRemapping() - { - CompactVertices(m_positions, m_vertexNewToOld); - CompactVertices(m_topologyIds, m_vertexNewToOld); - CompactVertices(m_normals, m_vertexNewToOld); - for (uint streamIndex = 0; streamIndex < m_texCoords.size(); ++streamIndex) - { - CompactVertices(m_texCoords[streamIndex], m_vertexNewToOld); - } - CompactVertices(m_colors, m_vertexNewToOld); - CompactVertices(m_alphas, m_vertexNewToOld); - CompactVertices(m_links, m_vertexNewToOld); - CompactVertices(m_vertexMatIds, m_vertexNewToOld); - CompactVerticesRaw(m_aux, m_auxSizeof, m_vertexNewToOld); - - for (size_t i = 0, count = m_faces.size(); i < count; ++i) - { - for (int j = 0; j < 3; ++j) - { - const int oldVertedIdx = m_faces[i].vertexIndex[j]; - assert(oldVertedIdx >= 0 && (size_t)oldVertedIdx < m_vertexOldToNew.size()); - const int newVertexIndex = m_vertexOldToNew[oldVertedIdx]; - m_faces[i].vertexIndex[j] = newVertexIndex; - } - } - } - - // Deleting degraded faces (faces with two or more vertices - // sharing same position in space) - void RemoveDegradedFaces() - { - size_t j = 0; - - for (size_t i = 0, count = m_faces.size(); i < count; ++i) - { - const Vec3& p0 = m_positions[m_faces[i].vertexIndex[0]]; - const Vec3& p1 = m_positions[m_faces[i].vertexIndex[1]]; - const Vec3& p2 = m_positions[m_faces[i].vertexIndex[2]]; - if (p0 != p1 && p1 != p2 && p2 != p0) - { - m_faces[j] = m_faces[i]; - if (!m_faceMatIds.empty()) - { - m_faceMatIds[j] = m_faceMatIds[i]; - } - ++j; - } - } - - m_faces.resize(j); - if (!m_faceMatIds.empty()) - { - m_faceMatIds.resize(j); - } - } - - private: - ////////////////////////////////////////////////////////////////////////// - // Internal helpers - - template - static void CompactVertices(std::vector& arr, const std::vector& newToOld) - { - if (arr.empty()) - { - return; - } - - const size_t newCount = newToOld.size(); - - std::vector tmp; - tmp.reserve(newCount); - - for (size_t i = 0; i < newCount; ++i) - { - tmp.push_back(arr[newToOld[i]]); - } - - arr.swap(tmp); - } - - static void CompactVerticesRaw(std::vector& arr, size_t elemSizeof, const std::vector& newToOld) - { - if (arr.empty()) - { - return; - } - - const size_t newCount = newToOld.size(); - - std::vector tmp; - tmp.resize(newCount * elemSizeof); - - for (size_t i = 0; i < newCount; ++i) - { - memcpy(&tmp[i * elemSizeof], &arr[newToOld[i] * elemSizeof], elemSizeof); - } - - arr.swap(tmp); - } - - struct VertexLess - { - const Mesh& m; - - VertexLess(const Mesh& mesh) - : m(mesh) - { - } - - bool operator()(int a, int b) const - { - if (!m.m_topologyIds.empty()) - { - const int res = m.m_topologyIds[a] - m.m_topologyIds[b]; - if (res != 0) - { - return res < 0; - } - } - - { - const int res = memcmp(&m.m_positions[a], &m.m_positions[b], sizeof(m.m_positions[0])); - if (res != 0) - { - return res < 0; - } - } - - int res = 0; - - if (res == 0 && !m.m_normals.empty()) - { - res = memcmp(&m.m_normals[a], &m.m_normals[b], sizeof(m.m_normals[0])); - } - - for (uint streamIndex = 0; streamIndex < m.m_texCoords.size(); ++streamIndex) - { - if (res == 0 && !m.m_texCoords[streamIndex].empty()) - { - res = memcmp(&m.m_texCoords[streamIndex][a], &m.m_texCoords[streamIndex][b], sizeof(m.m_texCoords[streamIndex][0])); - } - } - - if (res == 0 && !m.m_colors.empty()) - { - res = memcmp(&m.m_colors[a], &m.m_colors[b], sizeof(m.m_colors[0])); - } - - if (res == 0 && !m.m_alphas.empty()) - { - res = (int)m.m_alphas[a] - (int)m.m_alphas[b]; - } - - if (res == 0 && !m.m_links.empty()) - { - if (m.m_links[a].links.size() != m.m_links[b].links.size()) - { - res = (m.m_links[a].links.size() < m.m_links[b].links.size()) ? -1 : +1; - } - else - { - res = memcmp(&m.m_links[a].links[0], &m.m_links[b].links[0], sizeof(m.m_links[a].links[0]) * m.m_links[a].links.size()); - } - } - - if (res == 0 && !m.m_vertexMatIds.empty()) - { - res = m.m_vertexMatIds[a] - m.m_vertexMatIds[b]; - } - - if (res == 0 && !m.m_aux.empty()) - { - res = memcmp(&m.m_aux[a * m.m_auxSizeof], &m.m_aux[b * m.m_auxSizeof], m.m_auxSizeof); - } - - return res < 0; - } - }; - }; -} // namespace MeshUtils - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MESHUTILS_H diff --git a/Code/Tools/CryCommonTools/Export/ModelData.cpp b/Code/Tools/CryCommonTools/Export/ModelData.cpp deleted file mode 100644 index 5a6baf170c..0000000000 --- a/Code/Tools/CryCommonTools/Export/ModelData.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "ModelData.h" - -int ModelData::AddModel(const void* handle, const char* modelName, int parentModelIndex, bool geometry, const SHelperData& helperData, const std::string& propertiesString) -{ - int modelIndex = int(m_models.size()); - m_models.push_back(ModelEntry(handle, modelName, parentModelIndex, geometry, helperData, propertiesString)); - if (parentModelIndex >= 0) - { - m_models[parentModelIndex].children.push_back(modelIndex); - } - else - { - m_roots.push_back(modelIndex); - } - return modelIndex; -} - -const void* ModelData::GetModelHandle(int modelIndex) const -{ - return m_models[modelIndex].handle; -} - -const char* ModelData::GetModelName(int modelIndex) const -{ - return m_models[modelIndex].name.c_str(); -} - -void ModelData::SetTranslationRotationScale(int const modelIndex, const float* const translation, const float* const rotation, const float* const scale) -{ - for (int i = 0; i < 3; ++i) - { - m_models[modelIndex].translation[i] = translation[i]; - m_models[modelIndex].rotation[i] = rotation[i]; - m_models[modelIndex].scale[i] = scale[i]; - } -} - -void ModelData::GetTranslationRotationScale(int const modelIndex, float* const translation, float* const rotation, float* const scale) const -{ - for (int i = 0; i < 3; ++i) - { - translation[i] = m_models[modelIndex].translation[i]; - rotation[i] = m_models[modelIndex].rotation[i]; - scale[i] = m_models[modelIndex].scale[i]; - } -} - -const SHelperData& ModelData::GetHelperData(int modelIndex) const -{ - return m_models[modelIndex].helperData; -} - -const std::string& ModelData::GetProperties(int modelIndex) const -{ - return m_models[modelIndex].propertiesString; -} - -bool ModelData::IsRoot(int modelIndex) const -{ - return (m_models[modelIndex].parentIndex < 0); -} - -int ModelData::GetModelCount() const -{ - return int(m_models.size()); -} - -int ModelData::GetRootCount() const -{ - return int(m_roots.size()); -} - -int ModelData::GetRootIndex(int rootIndex) const -{ - return m_roots[rootIndex]; -} - -int ModelData::GetChildCount(int modelIndex) const -{ - return int(m_models[modelIndex].children.size()); -} - -int ModelData::GetChildIndex(int modelIndex, int childIndexIndex) const -{ - return m_models[modelIndex].children[childIndexIndex]; -} - -bool ModelData::HasGeometry(int modelIndex) const -{ - return m_models[modelIndex].geometry; -} - -ModelData::ModelEntry::ModelEntry(const void* a_handle, const std::string& a_name, int a_parentIndex, bool a_geometry, const SHelperData& a_helperData, const std::string& a_propertiesString) - : handle(a_handle) - , name(a_name) - , parentIndex(a_parentIndex) - , geometry(a_geometry) - , helperData(a_helperData) - , propertiesString(a_propertiesString) -{ - translation[0] = translation[1] = translation[2] = 0.0f; - rotation[0] = rotation[1] = rotation[2] = 0.0f; - scale[0] = scale[1] = scale[2] = 1.0f; -} diff --git a/Code/Tools/CryCommonTools/Export/ModelData.h b/Code/Tools/CryCommonTools/Export/ModelData.h deleted file mode 100644 index f6dcb1a921..0000000000 --- a/Code/Tools/CryCommonTools/Export/ModelData.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MODELDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MODELDATA_H -#pragma once - - -#include "IModelData.h" - -class ModelData - : public IModelData -{ -public: - // IModelData - virtual int AddModel(const void* handle, const char* name, int parentModelIndex, bool geometry, const SHelperData& helperData, const std::string& propertiesString); - virtual int GetModelCount() const; - virtual const void* GetModelHandle(int modelIndex) const; - virtual const char* GetModelName(int modelIndex) const; - virtual void SetTranslationRotationScale(int modelIndex, const float* translation, const float* rotation, const float* scale); - virtual void GetTranslationRotationScale(int modelIndex, float* translation, float* rotation, float* scale) const; - virtual const SHelperData& GetHelperData(int modelIndex) const; - virtual const std::string& GetProperties(int modelIndex) const; - virtual bool IsRoot(int modelIndex) const; - - int GetRootCount() const; - int GetRootIndex(int rootIndex) const; - int GetChildCount(int modelIndex) const; - int GetChildIndex(int modelIndex, int childIndexIndex) const; - bool HasGeometry(int modelIndex) const; - -private: - struct ModelEntry - { - ModelEntry(const void* handle, const std::string& name, int parentIndex, bool geometry, const SHelperData& helperData, const std::string& propertiesString); - - const void* handle; - std::string name; - int parentIndex; - bool geometry; - std::vector children; - float translation[3]; - float rotation[3]; - float scale[3]; - SHelperData helperData; - std::string propertiesString; - }; - - std::vector m_models; - std::vector m_roots; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MODELDATA_H diff --git a/Code/Tools/CryCommonTools/Export/MorphData.cpp b/Code/Tools/CryCommonTools/Export/MorphData.cpp deleted file mode 100644 index feadb87a33..0000000000 --- a/Code/Tools/CryCommonTools/Export/MorphData.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "MorphData.h" - -MorphData::MorphData() - : m_handle(0) -{ -} - -void MorphData::SetHandle(const void* handle) -{ - m_handle = handle; -} - -void MorphData::AddMorph(const void* handle, const char* name, const char* fullname) -{ - m_morphs.push_back(Entry(handle, name, fullname ? fullname : "")); -} - -const void* MorphData::GetHandle() const -{ - return m_handle; -} - -int MorphData::GetMorphCount() const -{ - return int(m_morphs.size()); -} - -std::string MorphData::GetMorphName(int morphIndex) const -{ - return m_morphs[morphIndex].name; -} - -std::string MorphData::GetMorphFullName(int morphIndex) const -{ - return m_morphs[morphIndex].fullname.length() > 0 ? m_morphs[morphIndex].fullname : m_morphs[morphIndex].name; -} - -const void* MorphData::GetMorphHandle(int morphIndex) const -{ - return m_morphs[morphIndex].handle; -} diff --git a/Code/Tools/CryCommonTools/Export/MorphData.h b/Code/Tools/CryCommonTools/Export/MorphData.h deleted file mode 100644 index c9c942905a..0000000000 --- a/Code/Tools/CryCommonTools/Export/MorphData.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MORPHDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MORPHDATA_H -#pragma once - - -#include "IMorphData.h" - -class MorphData - : public IMorphData -{ -public: - MorphData(); - - virtual void SetHandle(const void* handle); - virtual void AddMorph(const void* handle, const char* name, const char* fullname); - virtual const void* GetHandle() const; - virtual int GetMorphCount() const; - virtual const void* GetMorphHandle(int morphIndex) const; - - std::string GetMorphName(int morphIndex) const; - std::string GetMorphFullName(int morphIndex) const; - -private: - struct Entry - { - Entry(const void* handle, const std::string& name, const std::string& fullname) - : handle(handle) - , name(name) - , fullname(fullname) {} - const void* handle; - std::string name; - std::string fullname; - }; - - const void* m_handle; - std::vector m_morphs; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_MORPHDATA_H diff --git a/Code/Tools/CryCommonTools/Export/SingleAnimationExportSourceAdapter.cpp b/Code/Tools/CryCommonTools/Export/SingleAnimationExportSourceAdapter.cpp deleted file mode 100644 index be924eedf3..0000000000 --- a/Code/Tools/CryCommonTools/Export/SingleAnimationExportSourceAdapter.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "SingleAnimationExportSourceAdapter.h" -#include "IGeometryFileData.h" -#include - -SingleAnimationExportSourceAdapter::SingleAnimationExportSourceAdapter(IExportSource* source, IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) - : ExportSourceDecoratorBase(source) - , animationIndex(animationIndex) - , geometryFileData(geometryFileData) - , geometryFileIndex(geometryFileIndex) -{ - assert(this->animationIndex < this->source->GetAnimationCount()); -} - -float SingleAnimationExportSourceAdapter::GetDCCFrameRate() const -{ - return this->source->GetDCCFrameRate(); -} - -void SingleAnimationExportSourceAdapter::ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData) -{ - const int geometryFileIndex = geometryFileData->AddGeometryFile( - this->geometryFileData->GetGeometryFileHandle(this->geometryFileIndex), - this->geometryFileData->GetGeometryFileName(this->geometryFileIndex), - this->geometryFileData->GetProperties(this->geometryFileIndex)); -} - -void SingleAnimationExportSourceAdapter::ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData) -{ - assert(geometryFileIndex == 0); - this->source->ReadModels(this->geometryFileData, this->geometryFileIndex, modelData); -} - -void SingleAnimationExportSourceAdapter::ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* const modelData, int modelIndex, ISkeletonData* skeletonData) -{ - this->source->ReadSkinning(context, skinningData, modelData, modelIndex, skeletonData); -} - -bool SingleAnimationExportSourceAdapter::ReadSkeleton(const IGeometryFileData* const geometryFileData, int geometryFileIndex, const IModelData* const modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData) -{ - assert(geometryFileIndex == 0); - return this->source->ReadSkeleton(this->geometryFileData, this->geometryFileIndex, modelData, modelIndex, materialData, skeletonData); -} - -int SingleAnimationExportSourceAdapter::GetAnimationCount() const -{ - return 1; -} - -std::string SingleAnimationExportSourceAdapter::GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const -{ - assert(geometryFileIndex == 0); - assert(animationIndex == 0); - return this->source->GetAnimationName(this->geometryFileData, this->geometryFileIndex, this->animationIndex); -} - -void SingleAnimationExportSourceAdapter::GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const -{ - assert(animationIndex == 0); - this->source->GetAnimationTimeSpan(start, stop, this->animationIndex); -} - -void SingleAnimationExportSourceAdapter::ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* const geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const -{ - assert(animationIndex == 0); - this->source->ReadAnimationFlags(context, animationData, geometryFileData, modelData, modelIndex, skeletonData, this->animationIndex); -} - -IAnimationData* SingleAnimationExportSourceAdapter::ReadAnimation(IExportContext* context, const IGeometryFileData* const geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const -{ - assert(animationIndex == 0); - return this->source->ReadAnimation(context, geometryFileData, modelData, modelIndex, skeletonData, this->animationIndex, fps); -} diff --git a/Code/Tools/CryCommonTools/Export/SingleAnimationExportSourceAdapter.h b/Code/Tools/CryCommonTools/Export/SingleAnimationExportSourceAdapter.h deleted file mode 100644 index 13da9b47a0..0000000000 --- a/Code/Tools/CryCommonTools/Export/SingleAnimationExportSourceAdapter.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SINGLEANIMATIONEXPORTSOURCEADAPTER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SINGLEANIMATIONEXPORTSOURCEADAPTER_H -#pragma once - - -#include "ExportSourceDecoratorBase.h" - -class SingleAnimationExportSourceAdapter - : public ExportSourceDecoratorBase -{ -public: - SingleAnimationExportSourceAdapter(IExportSource* source, IGeometryFileData* geometryData, int geometryFileIndex, int animationIndex); - - virtual float GetDCCFrameRate() const; - - virtual void ReadGeometryFiles(IExportContext* context, IGeometryFileData* geometryFileData); - virtual void ReadModels(const IGeometryFileData* geometryFileData, int geometryFileIndex, IModelData* modelData); - virtual void ReadSkinning(IExportContext* context, ISkinningData* skinningData, const IModelData* modelData, int modelIndex, ISkeletonData* skeletonData); - virtual bool ReadSkeleton(const IGeometryFileData* geometryFileData, int geometryFileIndex, const IModelData* modelData, int modelIndex, const IMaterialData* materialData, ISkeletonData* skeletonData); - virtual int GetAnimationCount() const; - virtual std::string GetAnimationName(const IGeometryFileData* geometryFileData, int geometryFileIndex, int animationIndex) const; - virtual void GetAnimationTimeSpan(float& start, float& stop, int animationIndex) const; - virtual void ReadAnimationFlags(IExportContext* context, IAnimationData* animationData, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex) const; - virtual IAnimationData* ReadAnimation(IExportContext* context, const IGeometryFileData* geometryFileData, const IModelData* modelData, int modelIndex, const ISkeletonData* skeletonData, int animationIndex, float fps) const; - -private: - int animationIndex; - IGeometryFileData* geometryFileData; - int geometryFileIndex; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SINGLEANIMATIONEXPORTSOURCEADAPTER_H diff --git a/Code/Tools/CryCommonTools/Export/SkeletonData.cpp b/Code/Tools/CryCommonTools/Export/SkeletonData.cpp deleted file mode 100644 index 13d38678b2..0000000000 --- a/Code/Tools/CryCommonTools/Export/SkeletonData.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "SkeletonData.h" -#include - -int SkeletonData::AddBone(const void* handle, const char* name, int parentIndex) -{ - int modelIndex = int(m_bones.size()); - m_bones.push_back(BoneEntry(handle, name, parentIndex)); - m_nameBoneIndexMap.insert(std::make_pair(name, modelIndex)); - if (parentIndex >= 0) - { - m_bones[parentIndex].children.push_back(modelIndex); - } - else - { - m_roots.push_back(modelIndex); - } - return modelIndex; -} - -int SkeletonData::FindBone(const char* name) const -{ - std::map::const_iterator modelPos = m_nameBoneIndexMap.find(name); - return (modelPos != m_nameBoneIndexMap.end() ? (*modelPos).second : -1); -} - -const void* SkeletonData::GetBoneHandle(int boneIndex) const -{ - return m_bones[boneIndex].handle; -} - -int SkeletonData::GetBoneParentIndex(int boneIndex) const -{ - return m_bones[boneIndex].parentIndex; -} - -int SkeletonData::GetBoneCount() const -{ - return int(m_bones.size()); -} - -void SkeletonData::SetTranslation(int modelIndex, const float* vec) -{ - for (int i = 0; i < 3; ++i) - { - m_bones[modelIndex].translation[i] = vec[i]; - } -} - -void SkeletonData::SetRotation(int modelIndex, const float* vec) -{ - for (int i = 0; i < 3; ++i) - { - m_bones[modelIndex].rotation[i] = vec[i]; - } -} - -void SkeletonData::SetScale(int modelIndex, const float* vec) -{ - for (int i = 0; i < 3; ++i) - { - m_bones[modelIndex].scale[i] = vec[i]; - } -} - -void SkeletonData::SetParentFrameTranslation(int boneIndex, const float* vec) -{ - EnsureParentFrameExists(boneIndex); - std::copy(vec, vec + 3, m_bones[boneIndex].parentFrameTranslation); -} - -void SkeletonData::SetParentFrameRotation(int boneIndex, const float* vec) -{ - EnsureParentFrameExists(boneIndex); - std::copy(vec, vec + 3, m_bones[boneIndex].parentFrameRotation); -} - -void SkeletonData::SetParentFrameScale(int boneIndex, const float* vec) -{ - EnsureParentFrameExists(boneIndex); - std::copy(vec, vec + 3, m_bones[boneIndex].parentFrameScale); -} - -void SkeletonData::SetLimit(int boneIndex, Axis axis, Limit extreme, float limit) -{ - m_bones[boneIndex].limits.insert(std::make_pair(AxisLimit(axis, extreme), limit)); -} - -void SkeletonData::SetSpringTension(int boneIndex, Axis axis, float springTension) -{ - m_bones[boneIndex].springTensions.insert(std::make_pair(axis, springTension)); -} - -void SkeletonData::SetSpringAngle(int boneIndex, Axis axis, float springAngle) -{ - m_bones[boneIndex].springAngles.insert(std::make_pair(axis, springAngle)); -} - -void SkeletonData::SetAxisDamping(int boneIndex, Axis axis, float damping) -{ - m_bones[boneIndex].dampings.insert(std::make_pair(axis, damping)); -} - -void SkeletonData::SetPhysicalized(int boneIndex, bool physicalized) -{ - m_bones[boneIndex].physicalized = physicalized; -} - -void SkeletonData::SetHasGeometry(int boneIndex, bool hasGeometry) -{ - m_bones[boneIndex].hasGeometry = hasGeometry; -} - -void SkeletonData::SetBoneProperties(int boneIndex, const char* propertiesString) -{ - m_bones[boneIndex].propertiesString = propertiesString; -} - -void SkeletonData::SetBoneGeomProperties(int boneIndex, const char* propertiesString) -{ - m_bones[boneIndex].geomPropertiesString = propertiesString; -} - -bool SkeletonData::HasParentFrame(int boneIndex) const -{ - return m_bones[boneIndex].hasParentFrame; -} - -void SkeletonData::GetParentFrameTranslation(int boneIndex, float* vec) const -{ - std::copy(m_bones[boneIndex].parentFrameTranslation, m_bones[boneIndex].parentFrameTranslation + 3, vec); -} - -void SkeletonData::GetParentFrameRotation(int boneIndex, float* vec) const -{ - std::copy(m_bones[boneIndex].parentFrameRotation, m_bones[boneIndex].parentFrameRotation + 3, vec); -} - -void SkeletonData::GetParentFrameScale(int boneIndex, float* vec) const -{ - std::copy(m_bones[boneIndex].parentFrameScale, m_bones[boneIndex].parentFrameScale + 3, vec); -} - -bool SkeletonData::HasLimit(int boneIndex, Axis axis, Limit extreme) const -{ - return m_bones[boneIndex].limits.find(AxisLimit(axis, extreme)) != m_bones[boneIndex].limits.end(); -} - -float SkeletonData::GetLimit(int boneIndex, Axis axis, Limit extreme) const -{ - return (*m_bones[boneIndex].limits.find(AxisLimit(axis, extreme))).second; -} - -bool SkeletonData::HasSpringTension(int boneIndex, Axis axis) const -{ - return m_bones[boneIndex].springTensions.find(axis) != m_bones[boneIndex].springTensions.end(); -} - -float SkeletonData::GetSpringTension(int boneIndex, Axis axis) const -{ - return (*m_bones[boneIndex].springTensions.find(axis)).second; -} - -bool SkeletonData::HasSpringAngle(int boneIndex, Axis axis) const -{ - return m_bones[boneIndex].springAngles.find(axis) != m_bones[boneIndex].springAngles.end(); -} - -float SkeletonData::GetSpringAngle(int boneIndex, Axis axis) const -{ - return (*m_bones[boneIndex].springAngles.find(axis)).second; -} - -bool SkeletonData::HasAxisDamping(int boneIndex, Axis axis) const -{ - return m_bones[boneIndex].dampings.find(axis) != m_bones[boneIndex].dampings.end(); -} - -float SkeletonData::GetAxisDamping(int boneIndex, Axis axis) const -{ - return (*m_bones[boneIndex].dampings.find(axis)).second; -} - -bool SkeletonData::GetPhysicalized(int boneIndex) const -{ - return m_bones[boneIndex].physicalized; -} - -bool SkeletonData::HasGeometry(int boneIndex) const -{ - return m_bones[boneIndex].hasGeometry; -} - -int SkeletonData::GetRootCount() const -{ - return int(m_roots.size()); -} - -int SkeletonData::GetRootIndex(int rootIndex) const -{ - return m_roots[rootIndex]; -} - -int SkeletonData::GetParentIndex(int modelIndex) const -{ - return m_bones[modelIndex].parentIndex; -} - -const std::string SkeletonData::GetName(int modelIndex) const -{ - std::string copy(m_bones[modelIndex].name); - for (int i = 0, count = int(copy.size()); i < count; ++i) - { - if (!std::isalnum(copy[i]) && copy[i] != ' ') - { - copy[i] = '_'; - } - } - return copy; -} - - -const std::string SkeletonData::GetSafeName(int modelIndex) const -{ - std::string name = GetName(modelIndex); - std::replace_if(name.begin(), name.end(), std::isspace, '_'); - return name; -} - -int SkeletonData::GetChildCount(int modelIndex) const -{ - return int(m_bones[modelIndex].children.size()); -} - -int SkeletonData::GetChildIndex(int modelIndex, int childIndexIndex) const -{ - return m_bones[modelIndex].children[childIndexIndex]; -} - -void SkeletonData::GetTranslation(float* vec, int modelIndex) const -{ - for (int i = 0; i < 3; ++i) - { - vec[i] = m_bones[modelIndex].translation[i]; - } -} - -void SkeletonData::GetRotation(float* vec, int modelIndex) const -{ - for (int i = 0; i < 3; ++i) - { - vec[i] = m_bones[modelIndex].rotation[i]; - } -} - -void SkeletonData::GetScale(float* vec, int modelIndex) const -{ - for (int i = 0; i < 3; ++i) - { - vec[i] = m_bones[modelIndex].scale[i]; - } -} - -const std::string SkeletonData::GetBoneProperties(int boneIndex) const -{ - return m_bones[boneIndex].propertiesString; -} - -const std::string SkeletonData::GetBoneGeomProperties(int boneIndex) const -{ - return m_bones[boneIndex].geomPropertiesString; -} - -void SkeletonData::EnsureParentFrameExists(int boneIndex) -{ - if (!m_bones[boneIndex].hasParentFrame) - { - std::fill(m_bones[boneIndex].parentFrameTranslation, m_bones[boneIndex].parentFrameTranslation + 3, 0.0f); - std::fill(m_bones[boneIndex].parentFrameRotation, m_bones[boneIndex].parentFrameRotation + 3, 0.0f); - std::fill(m_bones[boneIndex].parentFrameScale, m_bones[boneIndex].parentFrameScale + 3, 0.0f); - m_bones[boneIndex].hasParentFrame = true; - } -} - -SkeletonData::BoneEntry::BoneEntry(const void* handle, const std::string& name, int parentIndex) - : handle(handle) - , name(name) - , parentIndex(parentIndex) - , hasParentFrame(false) - , physicalized(false) - , hasGeometry(hasGeometry) -{ - translation[0] = translation[1] = translation[2] = 0.0f; - rotation[0] = rotation[1] = rotation[2] = 0.0f; - scale[0] = scale[1] = scale[2] = 1.0f; -} diff --git a/Code/Tools/CryCommonTools/Export/SkeletonData.h b/Code/Tools/CryCommonTools/Export/SkeletonData.h deleted file mode 100644 index 60bd8274b7..0000000000 --- a/Code/Tools/CryCommonTools/Export/SkeletonData.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKELETONDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKELETONDATA_H -#pragma once - - -#include "ISkeletonData.h" -#include -#include -#include - -class SkeletonData - : public ISkeletonData -{ -public: - // ISkeletonData - virtual int AddBone(const void* handle, const char* name, int parentIndex); - virtual int FindBone(const char* name) const; - virtual const void* GetBoneHandle(int boneIndex) const; - virtual int GetBoneParentIndex(int boneIndex) const; - virtual int GetBoneCount() const; - virtual void SetTranslation(int boneIndex, const float* vec); - virtual void SetRotation(int boneIndex, const float* vec); - virtual void SetScale(int boneIndex, const float* vec); - virtual void SetParentFrameTranslation(int boneIndex, const float* vec); - virtual void SetParentFrameRotation(int boneIndex, const float* vec); - virtual void SetParentFrameScale(int boneIndex, const float* vec); - virtual void SetLimit(int boneIndex, Axis axis, Limit extreme, float limit); - virtual void SetSpringTension(int boneIndex, Axis axis, float springTension); - virtual void SetSpringAngle(int boneIndex, Axis axis, float springAngle); - virtual void SetAxisDamping(int boneIndex, Axis axis, float damping); - virtual void SetPhysicalized(int boneIndex, bool physicalized); - virtual void SetHasGeometry(int boneIndex, bool hasGeometry); - virtual void SetBoneProperties(int boneIndex, const char* propertiesString); - virtual void SetBoneGeomProperties(int boneIndex, const char* propertiesString); - - bool HasParentFrame(int boneIndex) const; - void GetParentFrameTranslation(int boneIndex, float* vec) const; - void GetParentFrameRotation(int boneIndex, float* vec) const; - void GetParentFrameScale(int boneIndex, float* vec) const; - bool HasLimit(int boneIndex, Axis axis, Limit extreme) const; - float GetLimit(int boneIndex, Axis axis, Limit extreme) const; - bool HasSpringTension(int boneIndex, Axis axis) const; - float GetSpringTension(int boneIndex, Axis axis) const; - bool HasSpringAngle(int boneIndex, Axis axis) const; - float GetSpringAngle(int boneIndex, Axis axis) const; - bool HasAxisDamping(int boneIndex, Axis axis) const; - float GetAxisDamping(int boneIndex, Axis axis) const; - bool GetPhysicalized(int boneIndex) const; - bool HasGeometry(int boneIndex) const; - - int GetRootCount() const; - int GetRootIndex(int rootIndex) const; - int GetParentIndex(int boneIndex) const; - const std::string GetName(int boneIndex) const; - const std::string GetSafeName(int boneIndex) const; - int GetChildCount(int boneIndex) const; - int GetChildIndex(int boneIndex, int childIndexIndex) const; - void GetTranslation(float* vec, int boneIndex) const; - void GetRotation(float* vec, int boneIndex) const; - void GetScale(float* vec, int boneIndex) const; - const std::string GetBoneProperties(int boneIndex) const; - const std::string GetBoneGeomProperties(int boneIndex) const; - -private: - void EnsureParentFrameExists(int boneIndex); - - typedef std::pair AxisLimit; - typedef std::map AxisLimitLimitMap; - typedef std::map AxisSpringTensionMap; - typedef std::map AxisSpringAngleMap; - typedef std::map AxisDampingMap; - - struct BoneEntry - { - public: - BoneEntry(const void* handle, const std::string& name, int parentIndex); - const void* handle; - std::string name; - int parentIndex; - AxisLimitLimitMap limits; - AxisSpringTensionMap springTensions; - AxisSpringAngleMap springAngles; - AxisDampingMap dampings; - bool hasParentFrame; - float parentFrameTranslation[3]; - float parentFrameRotation[3]; - float parentFrameScale[3]; - bool physicalized; - std::vector children; - float translation[3]; - float rotation[3]; - float scale[3]; - bool hasGeometry; - std::string propertiesString; - std::string geomPropertiesString; - }; - - std::vector m_bones; - std::vector m_roots; - std::map m_nameBoneIndexMap; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKELETONDATA_H diff --git a/Code/Tools/CryCommonTools/Export/SkinningData.cpp b/Code/Tools/CryCommonTools/Export/SkinningData.cpp deleted file mode 100644 index eeef150cad..0000000000 --- a/Code/Tools/CryCommonTools/Export/SkinningData.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "SkinningData.h" - -void SkinningData::SetVertexCount(int vertexCount) -{ - m_weights.resize(vertexCount); -} - -void SkinningData::AddWeight(int vertexIndex, int boneIndex, float weight) -{ - m_weights[vertexIndex].push_back(BoneWeight(boneIndex, weight)); -} - -int SkinningData::GetVertexCount() const -{ - return int(m_weights.size()); -} - -int SkinningData::GetBoneLinkCount(int vertexIndex) const -{ - return int(m_weights[vertexIndex].size()); -} - -int SkinningData::GetBoneIndex(int vertexIndex, int linkIndex) const -{ - return m_weights[vertexIndex][linkIndex].boneIndex; -} - -float SkinningData::GetWeight(int vertexIndex, int linkIndex) const -{ - return m_weights[vertexIndex][linkIndex].weight; -} diff --git a/Code/Tools/CryCommonTools/Export/SkinningData.h b/Code/Tools/CryCommonTools/Export/SkinningData.h deleted file mode 100644 index 6e3a9a6712..0000000000 --- a/Code/Tools/CryCommonTools/Export/SkinningData.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKINNINGDATA_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKINNINGDATA_H -#pragma once - - -#include "ISkinningData.h" - -class SkinningData - : public ISkinningData -{ -public: - virtual void SetVertexCount(int vertexCount); - virtual void AddWeight(int vertexIndex, int boneIndex, float weight); - - int GetVertexCount() const; - int GetBoneLinkCount(int vertexIndex) const; - int GetBoneIndex(int vertexIndex, int linkIndex) const; - float GetWeight(int vertexIndex, int linkIndex) const; - -private: - struct BoneWeight - { - BoneWeight(int boneIndex, float weight) - : boneIndex(boneIndex) - , weight(weight) {} - int boneIndex; - float weight; - }; - - std::vector > m_weights; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_SKINNINGDATA_H diff --git a/Code/Tools/CryCommonTools/Export/TransformHelpers.h b/Code/Tools/CryCommonTools/Export/TransformHelpers.h deleted file mode 100644 index cdddd78337..0000000000 --- a/Code/Tools/CryCommonTools/Export/TransformHelpers.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_TRANSFORMHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_TRANSFORMHELPERS_H -#pragma once - - -#include "Cry_Math.h" - - -namespace TransformHelpers -{ - // Format of forwardUpAxes: "". - // Example of forwardUpAxes: "-Y+Z". - // Returns 0 if successful, or returns a pointer to an error message in case of an error. - // In case of success: X axis in res represents "forward" direction, - // Y axis represents "up" direction. - inline const char* GetForwardUpAxesMatrix(Matrix33& res, const char* forwardUpAxes) - { - Vec3 axisX(ZERO); - Vec3 axisY(ZERO); - - for (int i = 0; i < 2; ++i) - { - Vec3& v = (i == 0) ? axisX : axisY; - - const float val = forwardUpAxes[i * 2 + 0] == '-' ? -1.0f : +1.0f; - - switch (forwardUpAxes[i * 2 + 1]) - { - case 'X': - case 'x': - v.x = val; - break; - case 'Y': - case 'y': - v.y = val; - break; - case 'Z': - case 'z': - v.z = val; - break; - default: - assert(0); - return "Found a bad axis character in forwardUpAxes string"; - } - } - - if (axisX == axisY) - { - assert(0); - return "Forward and up axes are equal in forwardUpAxes string"; - } - - const Vec3 axisZ = axisX.cross(axisY); - - res.SetFromVectors(axisX, axisY, axisZ); - - return 0; - } - - - // Computes transform matrix that converts everything from forwardUpAxesSrc - // coordinate system to forwardUpAxesDst coordinate system. - // Format of forwardUpAxesXXX: "". - // Example of forwardUpAxesXXX: "-Y+Z". - // Returns 0 if successful, or returns a pointer to an error message in case of an error. - // In case of success puts computed transform into res. - // See comments to GetForwardUpAxesMatrix(). - inline const char* ComputeForwardUpAxesTransform(Matrix34& res, const char* forwardUpAxesSrc, const char* forwardUpAxesDst) - { - Matrix33 srcToWorld; - Matrix33 dstToWorld; - - const char* const err0 = GetForwardUpAxesMatrix(srcToWorld, forwardUpAxesSrc); - const char* const err1 = GetForwardUpAxesMatrix(dstToWorld, forwardUpAxesDst); - - if (err0 || err1) - { - return err0 ? err0 : err1; - } - - res = Matrix34(dstToWorld * srcToWorld.GetTransposed()); - - return 0; - } - - - inline Matrix34 ComputeOrthonormalMatrix(const Matrix34& m) - { - Vec3 x = m.GetColumn0(); - x.Normalize(); - - Vec3 y = m.GetColumn1(); - - Vec3 z = x.cross(y); - z.Normalize(); - - y = z.cross(x); - - Matrix34 result; - result.SetFromVectors(x, y, z, m.GetTranslation()); - - return result; - } -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXPORT_TRANSFORMHELPERS_H diff --git a/Code/Tools/CryCommonTools/UI/EULADialog.cpp b/Code/Tools/CryCommonTools/UI/EULADialog.cpp deleted file mode 100644 index a4b8696eea..0000000000 --- a/Code/Tools/CryCommonTools/UI/EULADialog.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "EULADialog.h" -#include "Win32GUI.h" -#include "ModuleHelpers.h" -#include "Richedit.h" -#include - -EULADialog::EULADialog() - : m_frameWindow() - , m_cancelButton(_T("Cancel"), this, &EULADialog::CancelPressed) - , m_buttonSpacer(0, 0, 2000, 0) - , m_acceptButton(_T("Accept"), this, &EULADialog::AcceptPressed) - , m_buttonLayout(Layout::DirectionHorizontal) - , m_edit() -{ - Win32GUI::Initialize(); - - m_buttonLayout.AddComponent(&m_buttonSpacer); - m_buttonLayout.AddComponent(&m_cancelButton); - m_buttonLayout.AddComponent(&m_acceptButton); - - m_frameWindow.AddComponent(&m_edit); - m_frameWindow.AddComponent(&m_buttonLayout); -} - -namespace -{ - class EditStreamCallbackObject - { - public: - EditStreamCallbackObject(const char* data, int size) - : data(data) - , position(0) - , size(size) {} - static DWORD WINAPI EditStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb) - { - return ((EditStreamCallbackObject*)dwCookie)->EditStreamCallback_Member(dwCookie, pbBuff, cb, pcb); - } - - private: - DWORD EditStreamCallback_Member(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb) - { - int bytesToRead = (std::min)(this->size - this->position, (int)cb); - std::memcpy(pbBuff, this->data + this->position, bytesToRead); - this->position += bytesToRead; - if (pcb) - { - *pcb = bytesToRead; - } - return 0; - } - - const char* data; - int position; - int size; - }; -} - -EULADialog::UserResponse EULADialog::Run(int width, int height, TCHAR* resourceID) -{ - m_frameWindow.Show(true, width, height); - - // Attempt to load the resource. - HINSTANCE module = ModuleHelpers::GetCurrentModule(ModuleHelpers::CurrentModuleSpecifier_Library); - HRSRC resource = (resourceID ? FindResource(module, resourceID, RT_RCDATA) : 0); - int resourceLength = (resource ? SizeofResource(module, resource) : 0); - HGLOBAL resourceGlobal = (resource ? LoadResource(module, resource) : 0); - void* resourceData = (resourceGlobal ? LockResource(resourceGlobal) : 0); - // No need to unlock/delete data. - - m_userResponse = UserResponseNone; - - // Load the text. - if (resourceData && resourceLength > 0) - { - EditStreamCallbackObject callbackObject((const char*)resourceData, resourceLength); - EDITSTREAM editStream; - std::memset(&editStream, 0, sizeof(editStream)); - editStream.dwCookie = (DWORD_PTR)&callbackObject; - editStream.pfnCallback = &EditStreamCallbackObject::EditStreamCallback; - SendMessage((HWND)m_edit.m_edit, EM_STREAMIN, SF_RTF, (LPARAM)&editStream); - } - - MSG msg; - BOOL status; - bool waitingAcceptance = false; - while (m_userResponse == UserResponseNone && (status = GetMessage(&msg, HWND(0), UINT(0), UINT(0))) != 0) - { - if (status == -1) - { - break; - } - else - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - m_frameWindow.Show(false, 0, 0); - - return m_userResponse; -} - -void EULADialog::CancelPressed() -{ - m_userResponse = UserResponseCancel; -} - -void EULADialog::AcceptPressed() -{ - m_userResponse = UserResponseAccept; -} - -EULADialog::UserResponse EULADialog::Show(int width, int height, TCHAR* resourceID) -{ - EULADialog dlg; - return dlg.Run(width, height, resourceID); -} diff --git a/Code/Tools/CryCommonTools/UI/EULADialog.h b/Code/Tools/CryCommonTools/UI/EULADialog.h deleted file mode 100644 index 4af9bde758..0000000000 --- a/Code/Tools/CryCommonTools/UI/EULADialog.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_EULADIALOG_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_EULADIALOG_H -#pragma once - - -#include "FrameWindow.h" -#include "EditControl.h" -#include "Spacer.h" -#include "Layout.h" -#include "PushButton.h" - -class EULADialog -{ -public: - enum UserResponse - { - UserResponseNone, - UserResponseCancel, - UserResponseAccept - }; - - static UserResponse Show(int width, int height, TCHAR* resourceID); - -private: - EULADialog(); - - UserResponse Run(int width, int height, TCHAR* resourceID); - - void CancelPressed(); - void AcceptPressed(); - - FrameWindow m_frameWindow; - PushButton m_cancelButton; - Spacer m_buttonSpacer; - PushButton m_acceptButton; - Layout m_buttonLayout; - EditControl m_edit; - - UserResponse m_userResponse; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_EULADIALOG_H diff --git a/Code/Tools/CryCommonTools/UI/EditControl.cpp b/Code/Tools/CryCommonTools/UI/EditControl.cpp deleted file mode 100644 index 61ac51f41d..0000000000 --- a/Code/Tools/CryCommonTools/UI/EditControl.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "EditControl.h" -#include "Win32GUI.h" -#include -#include -#include - -EditControl::EditControl() - : m_edit(0) -{ -} - -void EditControl::CreateUI(void* window, int left, int top, int width, int height) -{ - m_edit = Win32GUI::CreateControl(RICHEDIT_CLASS, ES_MULTILINE /*| ES_READONLY*/, (HWND)window, left, top, width, height); -} - -void EditControl::Resize(void* window, int left, int top, int width, int height) -{ - MoveWindow((HWND)m_edit, left, top, width, height, true); -} - -void EditControl::DestroyUI(void* window) -{ - DestroyWindow((HWND)m_edit); - m_edit = 0; -} - -void EditControl::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - minWidth = 20; - maxWidth = 2000; - minHeight = 20; - maxHeight = 2000; -} diff --git a/Code/Tools/CryCommonTools/UI/EditControl.h b/Code/Tools/CryCommonTools/UI/EditControl.h deleted file mode 100644 index da00059e94..0000000000 --- a/Code/Tools/CryCommonTools/UI/EditControl.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_EDITCONTROL_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_EDITCONTROL_H -#pragma once - - -#include "IUIComponent.h" - -class EditControl - : public IUIComponent -{ -public: - EditControl(); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - - void* m_edit; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_EDITCONTROL_H diff --git a/Code/Tools/CryCommonTools/UI/FrameWindow.cpp b/Code/Tools/CryCommonTools/UI/FrameWindow.cpp deleted file mode 100644 index feaa7ab293..0000000000 --- a/Code/Tools/CryCommonTools/UI/FrameWindow.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "FrameWindow.h" -#include "Win32GUI.h" -#include "IUIComponent.h" -#include -#include - -FrameWindow::FrameWindow() - : m_hwnd(0) - , m_layout(Layout::DirectionVertical) -{ -} - -FrameWindow::~FrameWindow() -{ - if (m_hwnd) - { - Show(false, 0, 0); - } -} - -void FrameWindow::AddComponent(IUIComponent* component) -{ - assert(m_hwnd == 0); - m_layout.AddComponent(component); -} - -void FrameWindow::Show(bool show, int width, int height) -{ - if (show) - { - assert(m_hwnd == 0); - TCHAR* className = _T("CustomFrameWindowClass212"); - Win32GUI::RegisterFrameClass(className); - m_hwnd = Win32GUI::CreateFrame(className, WS_MINIMIZEBOX | WS_OVERLAPPED | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX, width, height); - Win32GUI::SetCallback((HWND)m_hwnd, this, &FrameWindow::CalculateExtremeDimensions); - Win32GUI::SetCallback((HWND)m_hwnd, this, &FrameWindow::OnSizeChanged); - std::pair size = InitializeSize(); - m_layout.CreateUI(m_hwnd, 0, 0, size.first, size.second); - ShowWindow((HWND)m_hwnd, SW_SHOWDEFAULT); - } - else - { - m_layout.DestroyUI(m_hwnd); - assert(m_hwnd != 0); - DestroyWindow((HWND)m_hwnd); - m_hwnd = 0; - } -} - -void FrameWindow::SetCaption(const TCHAR* caption) -{ - SendMessage((HWND)m_hwnd, WM_SETTEXT, 0, (LPARAM)caption); -} - -void* FrameWindow::GetHWND() -{ - return m_hwnd; -} - -std::pair FrameWindow::InitializeSize() -{ - int minW, maxW, minH, maxH; - CalculateExtremeDimensions(minW, maxW, minH, maxH); - RECT rect; - GetWindowRect((HWND)m_hwnd, &rect); - int width = int((std::min)(maxW, (std::max)(minW, int(rect.right - rect.left)))); - int height = int((std::min)(maxH, (std::max)(minH, int(rect.bottom - rect.top)))); - MoveWindow((HWND)m_hwnd, rect.left, rect.top, width, height, false); - return std::make_pair(width, height); -} - -void FrameWindow::CalculateExtremeDimensions(int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - int minW = 0; - int maxW = 0; - int minH = 0; - int maxH = 0; - m_layout.GetExtremeDimensions(m_hwnd, minW, maxW, minH, maxH); - - // Add the space required for the window decorations. - RECT rect; - rect.left = 0, rect.top = 0, rect.right = minW, rect.bottom = minH; - unsigned style = GetWindowLong((HWND)m_hwnd, GWL_STYLE); - AdjustWindowRect(&rect, style, false); - minW = rect.right - rect.left; - minH = rect.bottom - rect.top; - - rect.left = 0, rect.top = 0, rect.right = maxW, rect.bottom = maxH; - AdjustWindowRect(&rect, style, false); - maxW = rect.right - rect.left; - maxH = rect.bottom - rect.top; - - minWidth = minW; - maxWidth = maxW; - minHeight = minH; - maxHeight = maxH; -} - -void FrameWindow::OnSizeChanged(int width, int height) -{ - m_layout.Resize(m_hwnd, 0, 0, width, height); -} diff --git a/Code/Tools/CryCommonTools/UI/FrameWindow.h b/Code/Tools/CryCommonTools/UI/FrameWindow.h deleted file mode 100644 index ff1bba893d..0000000000 --- a/Code/Tools/CryCommonTools/UI/FrameWindow.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_FRAMEWINDOW_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_FRAMEWINDOW_H -#pragma once - - -#include -#include "Layout.h" - -class IUIComponent; - -class FrameWindow -{ -public: - FrameWindow(); - ~FrameWindow(); - void AddComponent(IUIComponent* component); - void Show(bool show, int width, int height); - void SetCaption(const TCHAR* caption); - void* GetHWND(); - -private: - void UpdateComponentUI(bool create); - std::pair InitializeSize(); - void CalculateExtremeDimensions(int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - void OnSizeChanged(int width, int height); - - void* m_hwnd; - Layout m_layout; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_FRAMEWINDOW_H diff --git a/Code/Tools/CryCommonTools/UI/IUIComponent.h b/Code/Tools/CryCommonTools/UI/IUIComponent.h deleted file mode 100644 index 08b06c424b..0000000000 --- a/Code/Tools/CryCommonTools/UI/IUIComponent.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_IUICOMPONENT_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_IUICOMPONENT_H -#pragma once - - -class IUIComponent -{ -public: - virtual void CreateUI(void* window, int left, int top, int width, int height) = 0; - virtual void Resize(void* window, int left, int top, int width, int height) = 0; - virtual void DestroyUI(void* window) = 0; - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_IUICOMPONENT_H diff --git a/Code/Tools/CryCommonTools/UI/Layout.cpp b/Code/Tools/CryCommonTools/UI/Layout.cpp deleted file mode 100644 index 3225544be2..0000000000 --- a/Code/Tools/CryCommonTools/UI/Layout.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "Layout.h" -#include -#include - -Layout::Layout(Direction direction) - : m_direction(direction) -{ -} - -void Layout::AddComponent(IUIComponent* component) -{ - m_components.push_back(ComponentEntry(component)); -} - -void Layout::CreateUI(void* window, int left, int top, int width, int height) -{ - UpdateLayout(window, left, top, width, height); - - for (int componentIndex = 0, componentCount = int(m_components.size()); componentIndex < componentCount; ++componentIndex) - { - IUIComponent* component = m_components[componentIndex].component; - component->CreateUI(window, m_components[componentIndex].left, m_components[componentIndex].top, m_components[componentIndex].width, m_components[componentIndex].height); - } -} - -void Layout::Resize(void* window, int left, int top, int width, int height) -{ - UpdateLayout(window, left, top, width, height); - - for (int componentIndex = 0, componentCount = int(m_components.size()); componentIndex < componentCount; ++componentIndex) - { - IUIComponent* component = m_components[componentIndex].component; - component->Resize(window, m_components[componentIndex].left, m_components[componentIndex].top, m_components[componentIndex].width, m_components[componentIndex].height); - } -} - -void Layout::DestroyUI(void* window) -{ - for (int componentIndex = 0, componentCount = int(m_components.size()); componentIndex < componentCount; ++componentIndex) - { - IUIComponent* component = m_components[componentIndex].component; - component->DestroyUI(window); - } -} - -void Layout::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - int minW = 0; - int maxW = 0; - int minH = 0; - int maxH = 0; - for (int componentIndex = 0, componentCount = int(m_components.size()); componentIndex < componentCount; ++componentIndex) - { - IUIComponent* component = m_components[componentIndex].component; - int compMinW, compMaxW, compMinH, compMaxH; - component->GetExtremeDimensions(window, compMinW, compMaxW, compMinH, compMaxH); - switch (m_direction) - { - case DirectionVertical: - minW = (minW > compMinW ? minW : compMinW); - maxW = (maxW > compMaxW ? maxW : compMaxW); // Deliberately take the larger maximum. - minH += compMinH; - maxH += compMaxH; - break; - case DirectionHorizontal: - minW += compMinW; - maxW += compMaxW; - minH = (minH > compMinH ? minH : compMinH); - maxH = (maxH > compMaxH ? maxH : compMaxH); // Deliberately take the larger maximum. - break; - } - } - - // Make sure the window is at least a certain size; - minW = (minW >= 10 ? minW : 10); - maxW = (maxW >= minW ? maxW : minW); - minH = (minH >= 10 ? minH : 10); - maxH = (maxH >= minH ? maxH : minH); - - minWidth = minW; - maxWidth = maxW; - minHeight = minH; - maxHeight = maxH; -} - -void Layout::UpdateLayout(void* window, int left, int top, int width, int height) -{ - assert(window); - - int remainingToAllocate; - switch (m_direction) - { - case DirectionVertical: - remainingToAllocate = height; - break; - case DirectionHorizontal: - remainingToAllocate = width; - break; - } - - int smallestAllocationAmount = INT_MAX; - int canBeExtendedCount = 0; - for (int componentIndex = 0, componentCount = int(m_components.size()); componentIndex < componentCount; ++componentIndex) - { - IUIComponent* component = m_components[componentIndex].component; - int compMinW, compMaxW, compMinH, compMaxH; - component->GetExtremeDimensions(window, compMinW, compMaxW, compMinH, compMaxH); - - switch (m_direction) - { - case DirectionVertical: - { - int allocationAmount = compMaxH - compMinH; - if (allocationAmount > 0) - { - ++canBeExtendedCount; - smallestAllocationAmount = (smallestAllocationAmount < allocationAmount ? smallestAllocationAmount : allocationAmount); - } - m_components[componentIndex].height = compMinH; - m_components[componentIndex].width = (width > compMaxW ? compMaxW : width); - remainingToAllocate -= m_components[componentIndex].height; - } - break; - - case DirectionHorizontal: - { - int allocationAmount = compMaxW - compMinW; - if (allocationAmount > 0) - { - ++canBeExtendedCount; - smallestAllocationAmount = (smallestAllocationAmount < allocationAmount ? smallestAllocationAmount : allocationAmount); - } - m_components[componentIndex].width = compMinW; - m_components[componentIndex].height = (height > compMaxH ? compMaxH : height); - remainingToAllocate -= m_components[componentIndex].width; - } - break; - } - } - - while (remainingToAllocate > 0 && canBeExtendedCount > 0) - { - int equitablePerCompAllocation = remainingToAllocate / canBeExtendedCount; - int compAllocation = (equitablePerCompAllocation < smallestAllocationAmount ? equitablePerCompAllocation : smallestAllocationAmount); - compAllocation = (compAllocation > 0 ? compAllocation : 1); - canBeExtendedCount = 0; - smallestAllocationAmount = INT_MAX; - for (int componentIndex = 0, componentCount = int(m_components.size()); componentIndex < componentCount; ++componentIndex) - { - IUIComponent* component = m_components[componentIndex].component; - int compMinW, compMaxW, compMinH, compMaxH; - component->GetExtremeDimensions(window, compMinW, compMaxW, compMinH, compMaxH); - switch (m_direction) - { - case DirectionVertical: - { - int componentExpandAmount = compMaxH - m_components[componentIndex].height; - if (componentExpandAmount > 0) - { - m_components[componentIndex].height += compAllocation; - assert(m_components[componentIndex].height <= compMaxH); - componentExpandAmount -= compAllocation; - remainingToAllocate -= compAllocation; - if (componentExpandAmount > 0) - { - smallestAllocationAmount = (smallestAllocationAmount < componentExpandAmount ? smallestAllocationAmount : componentExpandAmount); - ++canBeExtendedCount; - } - } - } - break; - - case DirectionHorizontal: - { - int componentExpandAmount = compMaxW - m_components[componentIndex].width; - if (componentExpandAmount > 0) - { - m_components[componentIndex].width += compAllocation; - assert(m_components[componentIndex].width <= compMaxW); - componentExpandAmount -= compAllocation; - remainingToAllocate -= compAllocation; - if (componentExpandAmount > 0) - { - smallestAllocationAmount = (smallestAllocationAmount < componentExpandAmount ? smallestAllocationAmount : componentExpandAmount); - ++canBeExtendedCount; - } - } - } - break; - } - } - } - - switch (m_direction) - { - case DirectionVertical: - { - int posY = top; - for (int componentIndex = 0, componentCount = int(m_components.size()); componentIndex < componentCount; ++componentIndex) - { - m_components[componentIndex].left = left; - m_components[componentIndex].top = posY; - posY += m_components[componentIndex].height; - } - } - break; - case DirectionHorizontal: - { - int posX = left; - for (int componentIndex = 0, componentCount = int(m_components.size()); componentIndex < componentCount; ++componentIndex) - { - m_components[componentIndex].top = top; - m_components[componentIndex].left = posX; - posX += m_components[componentIndex].width; - } - } - break; - } -} diff --git a/Code/Tools/CryCommonTools/UI/Layout.h b/Code/Tools/CryCommonTools/UI/Layout.h deleted file mode 100644 index a2de6c4f69..0000000000 --- a/Code/Tools/CryCommonTools/UI/Layout.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_LAYOUT_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_LAYOUT_H -#pragma once - - -#include "IUIComponent.h" -#include - -class Layout - : public IUIComponent -{ -public: - enum Direction - { - DirectionHorizontal, - DirectionVertical - }; - Layout(Direction direction); - void AddComponent(IUIComponent* component); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - -private: - void UpdateLayout(void* window, int left, int top, int width, int height); - - struct ComponentEntry - { - explicit ComponentEntry(IUIComponent* component) - : component(component) - , left(0) - , top(0) - , width(0) - , height(0) {} - IUIComponent* component; - int left; - int top; - int width; - int height; - }; - std::vector m_components; - Direction m_direction; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_LAYOUT_H diff --git a/Code/Tools/CryCommonTools/UI/ListView.cpp b/Code/Tools/CryCommonTools/UI/ListView.cpp deleted file mode 100644 index dc43d41fc8..0000000000 --- a/Code/Tools/CryCommonTools/UI/ListView.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "ListView.h" -#include "Win32GUI.h" -#include "resource.h" -#include "ModuleHelpers.h" -#include -#include -#include - -ListView::ListView() - : m_list(0) -{ -} - -void ListView::Add(int imageIndex, const TCHAR* message) -{ - int itemCount = int(SendMessage((HWND)m_list, LVM_GETITEMCOUNT, 0, 0)); - - LVITEM item; - std::memset(&item, 0, sizeof(item)); - item.mask = LVIF_TEXT | LVIF_IMAGE; - item.iItem = itemCount; - item.iSubItem = 0; - item.pszText = (TCHAR*)message; - item.iImage = imageIndex; - - SendMessage((HWND)m_list, LVM_INSERTITEM, 0, (LPARAM)&item); -} - -void ListView::Clear() -{ - SendMessage((HWND)m_list, LVM_DELETEALLITEMS, 0, 0); -} - -void ListView::CreateUI(void* window, int left, int top, int width, int height) -{ - m_list = Win32GUI::CreateControl(WC_LISTVIEW, LVS_REPORT | LVS_NOCOLUMNHEADER, (HWND)window, left, top, width, height); - - LVCOLUMN column; - std::memset(&column, 0, sizeof(column)); - column.mask = LVCF_TEXT | LVCF_WIDTH; - column.pszText = _T("Message"); - column.cx = width; - SendMessage((HWND)m_list, LVM_INSERTCOLUMN, 0, (LPARAM)&column); - - HIMAGELIST imageList = (HIMAGELIST)CreateImageList(); - SendMessage((HWND)m_list, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)imageList); -} - -void ListView::Resize(void* window, int left, int top, int width, int height) -{ - MoveWindow((HWND)m_list, left, top, width, height, true); - SendMessage((HWND)m_list, LVM_SETCOLUMNWIDTH, 0, width); -} - -void ListView::DestroyUI(void* window) -{ - DestroyWindow((HWND)m_list); - m_list = 0; -} - -void ListView::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - minWidth = 20; - maxWidth = 2000; - minHeight = 20; - maxHeight = 2000; -} - -void* ListView::CreateImageList() -{ - HINSTANCE instance = ModuleHelpers::GetCurrentModule(ModuleHelpers::CurrentModuleSpecifier_Library); - - HBITMAP image = (HBITMAP)LoadImage(instance, MAKEINTRESOURCE(IDB_LOG_ICONS), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); - DIBSECTION dibSection; - GetObject(image, sizeof(dibSection), &dibSection); - int height = dibSection.dsBmih.biHeight; - int width = height; - int count = dibSection.dsBmih.biWidth / width; - HIMAGELIST imageList = ImageList_Create(16, 16, ILC_COLOR32, count, 0); - ImageList_Add(imageList, image, 0); - return imageList; -} diff --git a/Code/Tools/CryCommonTools/UI/ListView.h b/Code/Tools/CryCommonTools/UI/ListView.h deleted file mode 100644 index 60531dd13d..0000000000 --- a/Code/Tools/CryCommonTools/UI/ListView.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_LISTVIEW_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_LISTVIEW_H -#pragma once - - -#include "IUIComponent.h" - -class ListView - : public IUIComponent -{ -public: - ListView(); - - void Add(int imageIndex, const TCHAR* message); - void Clear(); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - -private: - void* CreateImageList(); - - void* m_list; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_LISTVIEW_H diff --git a/Code/Tools/CryCommonTools/UI/LogWindow.cpp b/Code/Tools/CryCommonTools/UI/LogWindow.cpp deleted file mode 100644 index af96a389e1..0000000000 --- a/Code/Tools/CryCommonTools/UI/LogWindow.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "LogWindow.h" - -LogWindow::LogWindow() - : m_mainLayout(Layout::DirectionVertical) - , m_toolbarLayout(Layout::DirectionHorizontal) - , m_filterFlags(0) -{ - m_buttons.push_back(new ToggleButton(_T("Debug"), this, &LogWindow::DebugToggled)); - m_buttons.push_back(new ToggleButton(_T("Info"), this, &LogWindow::InfoToggled)); - m_buttons.push_back(new ToggleButton(_T("Warnings"), this, &LogWindow::WarningsToggled)); - m_buttons.push_back(new ToggleButton(_T("Errors"), this, &LogWindow::ErrorsToggled)); - - SetFilter(ILogger::eSeverity_Error, true); - SetFilter(ILogger::eSeverity_Warning, true); - SetFilter(ILogger::eSeverity_Info, true); - SetFilter(ILogger::eSeverity_Debug, false); - - m_toolbarLayout.AddComponent(m_buttons[3]); - m_toolbarLayout.AddComponent(m_buttons[2]); - m_toolbarLayout.AddComponent(m_buttons[1]); - m_toolbarLayout.AddComponent(m_buttons[0]); - - m_mainLayout.AddComponent(&m_toolbarLayout); - m_mainLayout.AddComponent(&m_list); -} - -LogWindow::~LogWindow() -{ - for (std::vector::iterator button = m_buttons.begin(), end = m_buttons.end(); button != end; ++button) - { - delete *button; - } -} - -void LogWindow::Log(ILogger::ESeverity eSeverity, const TCHAR* message) -{ - m_messages.push_back(LogMessage(eSeverity, message)); - - if (m_filterFlags & (1 << GetSeverityIndex(eSeverity))) - { - m_list.Add(GetImageIndex(eSeverity), message); - } -} - -void LogWindow::SetFilter(ILogger::ESeverity eSeverity, bool visible) -{ - int index = GetSeverityIndex(eSeverity); - if (visible) - { - m_filterFlags |= (1 << index); - } - else - { - m_filterFlags &= ~(1 << index); - } - m_buttons[index]->SetState(visible); - RefillList(); -} - -void LogWindow::CreateUI(void* window, int left, int top, int width, int height) -{ - m_mainLayout.CreateUI(window, left, top, width, height); -} - -void LogWindow::Resize(void* window, int left, int top, int width, int height) -{ - m_mainLayout.Resize(window, left, top, width, height); -} - -void LogWindow::DestroyUI(void* window) -{ - m_mainLayout.DestroyUI(window); -} - -void LogWindow::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - m_mainLayout.GetExtremeDimensions(window, minWidth, maxWidth, minHeight, maxHeight); -} - -void LogWindow::ErrorsToggled(bool value) -{ - SetFilter(ILogger::eSeverity_Error, value); -} - -void LogWindow::WarningsToggled(bool value) -{ - SetFilter(ILogger::eSeverity_Warning, value); -} - -void LogWindow::InfoToggled(bool value) -{ - SetFilter(ILogger::eSeverity_Info, value); -} - -void LogWindow::DebugToggled(bool value) -{ - SetFilter(ILogger::eSeverity_Debug, value); -} - -void LogWindow::RefillList() -{ - m_list.Clear(); - for (int messageIndex = 0, messageCount = int(m_messages.size()); messageIndex < messageCount; ++messageIndex) - { - if (m_filterFlags & (1 << m_messages[messageIndex].severity)) - { - m_list.Add(GetImageIndex(m_messages[messageIndex].severity), m_messages[messageIndex].message.c_str()); - } - } -} - -int LogWindow::GetImageIndex(ILogger::ESeverity eSeverity) -{ - switch (eSeverity) - { - case ILogger::eSeverity_Debug: - return 2; - case ILogger::eSeverity_Info: - return -1; - case ILogger::eSeverity_Warning: - return 1; - case ILogger::eSeverity_Error: - return 0; - default: - return 0; - } -} - -int LogWindow::GetSeverityIndex(ILogger::ESeverity eSeverity) -{ - switch (eSeverity) - { - case ILogger::eSeverity_Debug: - return 0; - case ILogger::eSeverity_Info: - return 1; - case ILogger::eSeverity_Warning: - return 2; - case ILogger::eSeverity_Error: - return 3; - default: - return 3; - } -} diff --git a/Code/Tools/CryCommonTools/UI/LogWindow.h b/Code/Tools/CryCommonTools/UI/LogWindow.h deleted file mode 100644 index 13afeac57c..0000000000 --- a/Code/Tools/CryCommonTools/UI/LogWindow.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_LOGWINDOW_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_LOGWINDOW_H -#pragma once - - -#include "IUIComponent.h" -#include "Layout.h" -#include "ListView.h" -#include "ToggleButton.h" -#include -#include "ILogger.h" - -class LogWindow - : public IUIComponent -{ -public: - LogWindow(); - ~LogWindow(); - - void Log(ILogger::ESeverity eSeverity, const TCHAR* message); - void SetFilter(ILogger::ESeverity eSeverity, bool visible); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - -private: - struct LogMessage - { - LogMessage(ILogger::ESeverity severity, tstring message) - : severity(severity) - , message(message) - { - } - ILogger::ESeverity severity; - tstring message; - }; - - void ErrorsToggled(bool value); - void WarningsToggled(bool value); - void InfoToggled(bool value); - void DebugToggled(bool value); - void RefillList(); - static int GetImageIndex(ILogger::ESeverity eSeverity); - static int GetSeverityIndex(ILogger::ESeverity eSeverity); - - Layout m_mainLayout; - Layout m_toolbarLayout; - ListView m_list; - std::vector m_buttons; - std::vector m_messages; - - unsigned m_filterFlags; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_LOGWINDOW_H diff --git a/Code/Tools/CryCommonTools/UI/ProgressBar.cpp b/Code/Tools/CryCommonTools/UI/ProgressBar.cpp deleted file mode 100644 index d83c8bf3ad..0000000000 --- a/Code/Tools/CryCommonTools/UI/ProgressBar.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "ProgressBar.h" -#include -#include - -ProgressBar::ProgressBar() - : m_progressBar(0) -{ -} - -void ProgressBar::CreateUI(void* window, int left, int top, int width, int height) -{ - m_progressBar = CreateWindowEx( - 0, - PROGRESS_CLASS, - 0, - WS_CHILD | WS_VISIBLE, - left, - top, - width, - height, - (HWND)window, - (HMENU)0, - GetModuleHandle(0), - 0); - SendMessage((HWND)m_progressBar, PBM_SETRANGE, 0, MAKELPARAM(0, 1000)); - SendMessage((HWND)m_progressBar, PBM_SETSTEP, (WPARAM) 1, 0); -} - -void ProgressBar::Resize(void* window, int left, int top, int width, int height) -{ - MoveWindow((HWND)m_progressBar, left, top, width, height, true); -} - -void ProgressBar::DestroyUI(void* window) -{ - DestroyWindow((HWND)m_progressBar); -} - -void ProgressBar::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - minWidth = 200; - maxWidth = 2000; - minHeight = 30; - maxHeight = 30; -} - -void ProgressBar::SetProgress(float progress) -{ - int newPos = int(progress * 1000.0f); - SendMessage((HWND)m_progressBar, PBM_SETPOS, newPos, 0); -} diff --git a/Code/Tools/CryCommonTools/UI/ProgressBar.h b/Code/Tools/CryCommonTools/UI/ProgressBar.h deleted file mode 100644 index 16ce456abe..0000000000 --- a/Code/Tools/CryCommonTools/UI/ProgressBar.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_PROGRESSBAR_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_PROGRESSBAR_H -#pragma once - - -#include "IUIComponent.h" - -class ProgressBar - : public IUIComponent -{ -public: - ProgressBar(); - - void SetProgress(float progress); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - -private: - void* m_progressBar; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_PROGRESSBAR_H diff --git a/Code/Tools/CryCommonTools/UI/PushButton.cpp b/Code/Tools/CryCommonTools/UI/PushButton.cpp deleted file mode 100644 index e1458db0d6..0000000000 --- a/Code/Tools/CryCommonTools/UI/PushButton.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "PushButton.h" -#include "Win32GUI.h" - -PushButton::~PushButton() -{ - m_callback->Release(); -} - -void PushButton::Enable(bool enabled) -{ - m_enabled = enabled; - EnableWindow((HWND)m_button, m_enabled); -} - -void PushButton::CreateUI(void* window, int left, int top, int width, int height) -{ - m_button = Win32GUI::CreateControl(_T("BUTTON"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, (HWND)window, left, top, 40, 20); - m_font = Win32GUI::CreateFont(); - SendMessage((HWND)m_button, WM_SETFONT, (WPARAM)m_font, 0); - SendMessage((HWND)m_button, WM_SETTEXT, 0, (LPARAM)m_text.c_str()); - EnableWindow((HWND)m_button, m_enabled); - - Win32GUI::SetCallback((HWND)m_button, this, &PushButton::OnPushed); -} - -void PushButton::Resize(void* window, int left, int top, int width, int height) -{ - MoveWindow((HWND)m_button, left, top, width, height, true); -} - -void PushButton::DestroyUI(void* window) -{ - DestroyWindow((HWND)m_button); - m_button = 0; - DeleteObject(m_font); - m_font = 0; -} - -void PushButton::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - minWidth = 50; - maxWidth = 50; - minHeight = 20; - maxHeight = 20; -} - -void PushButton::OnPushed() -{ - m_callback->Call(); -} diff --git a/Code/Tools/CryCommonTools/UI/PushButton.h b/Code/Tools/CryCommonTools/UI/PushButton.h deleted file mode 100644 index a6199208d5..0000000000 --- a/Code/Tools/CryCommonTools/UI/PushButton.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_PUSHBUTTON_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_PUSHBUTTON_H -#pragma once - - -#include "IUIComponent.h" -#include - -class PushButton - : public IUIComponent -{ -public: - template - PushButton(const TCHAR* text, T* object, void (T::* method)()); - ~PushButton(); - - void Enable(bool enabled); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - -private: - PushButton(const PushButton&); - PushButton& operator=(const PushButton&); - - struct ICallback - { - virtual void Release() = 0; - virtual void Call() = 0; - }; - - template - struct Callback - : public ICallback - { - Callback(T* object, void (T::* method)()) - : object(object) - , method(method) {} - virtual void Release() {delete this; } - virtual void Call() {(object->*method)(); } - T* object; - void (T::* method)(); - }; - - void OnPushed(); - - std::basic_string m_text; - void* m_button; - void* m_font; - ICallback* m_callback; - bool m_enabled; -}; - -template -PushButton::PushButton(const TCHAR* text, T* object, void (T::* method)()) - : m_text(text) - , m_callback(new Callback(object, method)) - , m_enabled(true) -{ -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_PUSHBUTTON_H diff --git a/Code/Tools/CryCommonTools/UI/Spacer.cpp b/Code/Tools/CryCommonTools/UI/Spacer.cpp deleted file mode 100644 index 822831116e..0000000000 --- a/Code/Tools/CryCommonTools/UI/Spacer.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "Spacer.h" - -Spacer::Spacer(int minWidth, int minHeight, int maxWidth, int maxHeight) - : m_minWidth(minWidth) - , m_minHeight(minHeight) - , m_maxWidth(maxWidth) - , m_maxHeight(maxHeight) -{ -} - -void Spacer::CreateUI(void* window, int left, int top, int width, int height) -{ -} - -void Spacer::Resize(void* window, int left, int top, int width, int height) -{ -} - -void Spacer::DestroyUI(void* window) -{ -} - -void Spacer::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - minWidth = m_minWidth; - maxWidth = m_maxWidth; - minHeight = m_minHeight; - maxHeight = m_maxHeight; -} diff --git a/Code/Tools/CryCommonTools/UI/Spacer.h b/Code/Tools/CryCommonTools/UI/Spacer.h deleted file mode 100644 index 173fb7ab13..0000000000 --- a/Code/Tools/CryCommonTools/UI/Spacer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_SPACER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_SPACER_H -#pragma once - - -#include "IUIComponent.h" - -class Spacer - : public IUIComponent -{ -public: - Spacer(int minWidth, int minHeight, int maxWidth, int maxHeight); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - -private: - int m_minWidth; - int m_minHeight; - int m_maxWidth; - int m_maxHeight; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_SPACER_H diff --git a/Code/Tools/CryCommonTools/UI/TaskList.cpp b/Code/Tools/CryCommonTools/UI/TaskList.cpp deleted file mode 100644 index 477041fd59..0000000000 --- a/Code/Tools/CryCommonTools/UI/TaskList.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "TaskList.h" -#include "Win32GUI.h" -#include -#include -#include -#include - -TaskList::TaskList() - : m_edit(0) -{ -} - -void TaskList::AddTask(const std::string& id, const std::string description) -{ - int taskIndex = int(m_tasks.size()); - m_tasks.push_back(std::make_pair(id, description)); - m_idTaskMap.insert(std::make_pair(id, taskIndex)); -} - -void TaskList::SetCurrentTask(const std::string& id) -{ - SetText(id); -} - -void TaskList::SetColor() -{ - SendMessage((HWND)m_edit, EM_SETBKGNDCOLOR, 0, GetSysColor(COLOR_3DFACE)); -} - -void TaskList::SetText(const std::string& highlightedTask) -{ - PARAFORMAT2 paragraphFormat; - std::memset(¶graphFormat, 0, sizeof(paragraphFormat)); - paragraphFormat.cbSize = sizeof(paragraphFormat); - paragraphFormat.dwMask = PFM_LINESPACING | PFM_SPACEBEFORE; - paragraphFormat.bLineSpacingRule = 5; // Specify spacing in 20ths of a line. - paragraphFormat.dyLineSpacing = 22; - paragraphFormat.dySpaceBefore = 70; - SendMessage((HWND)m_edit, EM_SETPARAFORMAT, 0, (LPARAM)¶graphFormat); - - CHARFORMAT format; - std::memset(&format, 0, sizeof(format)); - format.cbSize = sizeof(format); - format.dwMask = CFM_BOLD; - format.dwEffects = 0; - SendMessage((HWND)m_edit, EM_SETCHARFORMAT, 0, (LPARAM)&format); - - SETTEXTEX textEx; - std::memset(&textEx, 0, sizeof(textEx)); - textEx.flags = ST_DEFAULT; - textEx.codepage = CP_ACP; - SendMessage((HWND)m_edit, EM_SETTEXTEX, (WPARAM)&textEx, (LPARAM)_T("")); - int highlightedLineStart = 0; - int highlightedLineEnd = 0; - - for (std::vector >::const_iterator taskPos = m_tasks.begin(), taskEnd = m_tasks.end(); taskPos != taskEnd; ++taskPos) - { - textEx.flags = ST_SELECTION; - const std::string& id = (*taskPos).first; - const std::string& description = (*taskPos).second; - const char* margin = " "; - if (highlightedTask == id) - { - margin = "* "; - CHARRANGE range; - SendMessage((HWND)m_edit, EM_EXGETSEL, 0, (LPARAM)&range); - highlightedLineStart = range.cpMin; - } - SendMessageA((HWND)m_edit, EM_SETTEXTEX, (WPARAM)&textEx, (LPARAM)margin); - SendMessageA((HWND)m_edit, EM_SETTEXTEX, (WPARAM)&textEx, (LPARAM)description.c_str()); - SendMessageA((HWND)m_edit, EM_SETTEXTEX, (WPARAM)&textEx, (LPARAM)"\n"); - if (highlightedTask == id) - { - CHARRANGE range; - SendMessage((HWND)m_edit, EM_EXGETSEL, 0, (LPARAM)&range); - highlightedLineEnd = range.cpMin; - } - } - - CHARRANGE range = {highlightedLineStart, highlightedLineEnd}; - SendMessage((HWND)m_edit, EM_EXSETSEL, 0, (LPARAM)&range); - - format.dwEffects = CFE_BOLD; - SendMessage((HWND)m_edit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format); - - range.cpMin = 0; - range.cpMax = 0; - SendMessage((HWND)m_edit, EM_EXSETSEL, 0, (LPARAM)&range); -} - -void TaskList::CreateUI(void* window, int left, int top, int width, int height) -{ - // Create the window. - LoadLibrary(_T("Riched20.dll")); - m_edit = CreateWindowEx( - 0, //DWORD dwExStyle, - RICHEDIT_CLASS, //LPCTSTR lpClassName, - 0, //LPCTSTR lpWindowName, - WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE | ES_READONLY, //DWORD dwStyle, - left, //int x, - top, //int y, - width, //int nWidth, - height, //int nHeight, - (HWND)window, //HWND hWndParent, - 0, //HMENU hMenu, - GetModuleHandle(0), //HINSTANCE hInstance, - 0); //LPVOID lpParam); - HFONT font = Win32GUI::CreateFont(); - SendMessage((HWND)m_edit, WM_SETFONT, (WPARAM)font, 0); - DeleteObject(font); - SetColor(); - - SetText(""); -} - -void TaskList::Resize(void* window, int left, int top, int width, int height) -{ - MoveWindow((HWND)m_edit, left, top, width, height, true); -} - -void TaskList::DestroyUI(void* window) -{ - DestroyWindow((HWND)m_edit); - m_edit = 0; -} - -void TaskList::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - minWidth = 10; - maxWidth = 2000; - int height = 25 * int(m_tasks.size()); - minHeight = height; - maxHeight = height; -} diff --git a/Code/Tools/CryCommonTools/UI/TaskList.h b/Code/Tools/CryCommonTools/UI/TaskList.h deleted file mode 100644 index 54f825a5b5..0000000000 --- a/Code/Tools/CryCommonTools/UI/TaskList.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_TASKLIST_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_TASKLIST_H -#pragma once - - -#include "IUIComponent.h" -#include -#include -#include - -class TaskList - : public IUIComponent -{ -public: - TaskList(); - - void AddTask(const std::string& id, const std::string description); - void SetCurrentTask(const std::string& id); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - -private: - void SetColor(); - void SetText(const std::string& highlightedTask); - - std::map m_idTaskMap; - std::vector > m_tasks; - void* m_edit; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_TASKLIST_H diff --git a/Code/Tools/CryCommonTools/UI/ToggleButton.cpp b/Code/Tools/CryCommonTools/UI/ToggleButton.cpp deleted file mode 100644 index 6f93a9c303..0000000000 --- a/Code/Tools/CryCommonTools/UI/ToggleButton.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "ToggleButton.h" -#include "Win32GUI.h" - -ToggleButton::~ToggleButton() -{ - m_callback->Release(); -} - -void ToggleButton::SetState(bool state) -{ - m_state = state; - SendMessage((HWND)m_button, BM_SETCHECK, m_state, 0); -} - -void ToggleButton::CreateUI(void* window, int left, int top, int width, int height) -{ - m_button = Win32GUI::CreateControl(_T("BUTTON"), WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BS_NOTIFY | BS_PUSHLIKE, (HWND)window, left, top, 40, 20); - m_font = Win32GUI::CreateFont(); - SendMessage((HWND)m_button, WM_SETFONT, (WPARAM)m_font, 0); - SendMessage((HWND)m_button, WM_SETTEXT, 0, (LPARAM)m_text.c_str()); - SendMessage((HWND)m_button, BM_SETCHECK, m_state, 0); - - Win32GUI::SetCallback((HWND)m_button, this, &ToggleButton::OnChecked); -} - -void ToggleButton::Resize(void* window, int left, int top, int width, int height) -{ - MoveWindow((HWND)m_button, left, top, width, height, true); -} - -void ToggleButton::DestroyUI(void* window) -{ - DestroyWindow((HWND)m_button); - m_button = 0; - DeleteObject(m_font); - m_font = 0; -} - -void ToggleButton::GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight) -{ - minWidth = 50; - maxWidth = 50; - minHeight = 20; - maxHeight = 20; -} - -void ToggleButton::OnChecked(bool checked) -{ - m_state = checked; - m_callback->Call(checked); -} diff --git a/Code/Tools/CryCommonTools/UI/ToggleButton.h b/Code/Tools/CryCommonTools/UI/ToggleButton.h deleted file mode 100644 index 27eec0906c..0000000000 --- a/Code/Tools/CryCommonTools/UI/ToggleButton.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_TOGGLEBUTTON_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_TOGGLEBUTTON_H -#pragma once - - -#include "IUIComponent.h" -#include - -class ToggleButton - : public IUIComponent -{ -public: - template - ToggleButton(const TCHAR* text, T* object, void (T::* method)(bool value)); - ~ToggleButton(); - - void SetState(bool value); - - // IUIComponent - virtual void CreateUI(void* window, int left, int top, int width, int height); - virtual void Resize(void* window, int left, int top, int width, int height); - virtual void DestroyUI(void* window); - virtual void GetExtremeDimensions(void* window, int& minWidth, int& maxWidth, int& minHeight, int& maxHeight); - -private: - ToggleButton(const ToggleButton&); - ToggleButton& operator=(const ToggleButton); - - struct ICallback - { - virtual void Release() = 0; - virtual void Call(bool value) = 0; - }; - - template - struct Callback - : public ICallback - { - Callback(T* object, void (T::* method)(bool value)) - : object(object) - , method(method) {} - virtual void Release() {delete this; } - virtual void Call(bool value) {(object->*method)(value); } - T* object; - void (T::* method)(bool value); - }; - - void OnChecked(bool checked); - - tstring m_text; - void* m_button; - void* m_font; - bool m_state; - ICallback* m_callback; -}; - -template -ToggleButton::ToggleButton(const TCHAR* text, T* object, void (T::* method)(bool value)) - : m_text(text) - , m_state(false) - , m_callback(new Callback(object, method)) -{ -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_TOGGLEBUTTON_H diff --git a/Code/Tools/CryCommonTools/UI/Win32GUI.cpp b/Code/Tools/CryCommonTools/UI/Win32GUI.cpp deleted file mode 100644 index e34348271d..0000000000 --- a/Code/Tools/CryCommonTools/UI/Win32GUI.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "StdAfx.h" -#include "Win32GUI.h" -#include -#include -#include -#include -#include "commctrl.h" -#include "StringHelpers.h" - -namespace Win32GUI -{ - const int WM_REFLECT_BASE = WM_USER + 0x1c00; - const int WM_COMMAND_REFLECT = WM_REFLECT_BASE + WM_COMMAND; - const int WM_NOTIFY_REFLECT = WM_REFLECT_BASE + WM_NOTIFY; - - class Window - { - public: - typedef LRESULT (Window::* WindowProcMethod)(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - - Window(WindowProcMethod windowProc); - ~Window(); - static LRESULT CALLBACK StaticWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - LRESULT FrameWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - - void Subclass(HWND window); - void Unsubclass(HWND window); - - WNDPROC m_oldWndProc; - WindowProcMethod m_windowProc; - typedef std::multimap CallbackMap; - CallbackMap m_callbackMap; - }; -} - -void Win32GUI::Initialize() -{ - InitCommonControls(); - LoadLibrary(_T("riched20.dll")); -} - -void Win32GUI::RegisterFrameClass(const TCHAR* name) -{ - WNDCLASS cls; - std::memset(&cls, 0, sizeof(cls)); - cls.style = 0; - cls.lpfnWndProc = &Window::StaticWindowProc; - cls.cbClsExtra = 0; - cls.cbWndExtra = 0; - cls.hInstance = GetModuleHandle(0); - cls.hIcon = 0; - cls.hCursor = LoadCursor(0, IDC_ARROW); - cls.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); - cls.lpszMenuName = 0; - cls.lpszClassName = name; - - RegisterClass(&cls); -} - -HWND Win32GUI::CreateFrame(const TCHAR* className, unsigned style, int width, int height) -{ - Window* window = new Window(&Window::FrameWindowProc); - - HWND hwnd = CreateWindow( - className, // LPCTSTR lpClassName, - TEXT(""), // LPCTSTR lpWindowName, - style, // DWORD dwStyle, - CW_USEDEFAULT, // int x, - CW_USEDEFAULT, // int y, - width, // int nWidth, - height, // int nHeight, - 0, // HWND hWndParent, - 0, // HMENU hMenu, - GetModuleHandle(0), // HINSTANCE hInstance, - window); // LPVOID lpParam - - return hwnd; -} - -HWND Win32GUI::CreateControl(const TCHAR* className, unsigned style, HWND parent, int left, int top, int width, int height) -{ - Window* window = new Window(&Window::WindowProc); - - HWND hwnd = CreateWindow( - className, // LPCTSTR lpClassName, - 0, // LPCTSTR lpWindowName, - style | WS_CHILD | WS_VISIBLE, // DWORD dwStyle, - left, // int x, - top, // int y, - width, // int nWidth, - height, // int nHeight, - parent, // HWND hWndParent, - 0, // HMENU hMenu, - GetModuleHandle(0), // HINSTANCE hInstance, - 0); // LPVOID lpParam - - window->Subclass(hwnd); - - return hwnd; -} - -int Win32GUI::Run() -{ - MSG msg; - BOOL status; - while ((status = GetMessage(&msg, HWND(0), UINT(0), UINT(0))) != 0) - { - if (status == -1) - { - return -1; - } - else - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - return (int)msg.wParam; -} - -Win32GUI::Window::Window(WindowProcMethod windowProc) - : m_windowProc(windowProc) - , m_oldWndProc(0) -{ -} - -Win32GUI::Window::~Window() -{ - for (CallbackMap::iterator callbackPos = m_callbackMap.begin(); callbackPos != m_callbackMap.end(); ++callbackPos) - { - (*callbackPos).second->Release(); - } -} - -LRESULT CALLBACK Win32GUI::Window::StaticWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - Window* window = 0; - { - if (uMsg == WM_CREATE) - { - CREATESTRUCT* create_struct = (CREATESTRUCT*)lParam; - window = (Window*)create_struct->lpCreateParams; -#if defined(_WIN64) - SetWindowLongPtr(hwnd, GWLP_USERDATA, LONG_PTR(window)); -#else //defined(_WIN64) - SetWindowLong(hwnd, GWL_USERDATA, PtrToLong(window)); -#endif //defined(_WIN64) - } - else - { -#if defined(_WIN64) - window = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA); -#else //defined(_WIN64) - window = (Window*)LongToPtr(GetWindowLong(hwnd, GWL_USERDATA)); -#endif //defined(_WIN64) - } - } - - LRESULT result = 0; - if (window) - { - result = (window->*(window->m_windowProc))(hwnd, uMsg, wParam, lParam); - } - else - { - result = DefWindowProc(hwnd, uMsg, wParam, lParam); - } - - if (uMsg == WM_DESTROY) - { - delete window; -#if defined(_WIN64) - SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); -#else //defined(_WIN64) - SetWindowLong(hwnd, GWL_USERDATA, 0); -#endif //defined(_WIN64) - } - - return result; -} - -LRESULT Win32GUI::Window::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_COMMAND: - { - HWND control = (HWND)lParam; - if (control) - { - SendMessage(control, WM_COMMAND_REFLECT, wParam, lParam); - } - } - break; - - case WM_NOTIFY: - { - NMHDR* notify_header = reinterpret_cast(lParam); - if (notify_header->hwndFrom) - { - SendMessage(notify_header->hwndFrom, WM_NOTIFY_REFLECT, wParam, lParam); - } - } - break; - - case WM_COMMAND_REFLECT: - switch (HIWORD(wParam)) - { - case EN_CHANGE: - { - std::string text = GetWindowString(hwnd); - - std::pair range = m_callbackMap.equal_range(EventCallbacks::TextChanged::ID); - for (CallbackMap::iterator callbackPos = range.first; callbackPos != range.second; ++callbackPos) - { - EventCallbacks::IStringCallback* callback = static_cast((*callbackPos).second); - callback->Call(text); - } - } - break; - - case BN_CLICKED: - { - if (GetWindowLong(hwnd, GWL_STYLE) & BS_CHECKBOX) - { - bool checked = (0 != SendMessage(hwnd, BM_GETCHECK, 0, 0)); - std::pair range = m_callbackMap.equal_range(EventCallbacks::Checked::ID); - for (CallbackMap::iterator callbackPos = range.first; callbackPos != range.second; ++callbackPos) - { - EventCallbacks::IBoolCallback* callback = static_cast((*callbackPos).second); - callback->Call(checked); - } - } - else - { - std::pair range = m_callbackMap.equal_range(EventCallbacks::Pushed::ID); - for (CallbackMap::iterator callbackPos = range.first; callbackPos != range.second; ++callbackPos) - { - EventCallbacks::IVoidCallback* callback = static_cast((*callbackPos).second); - callback->Call(); - } - } - } - break; - } - break; - - case WM_GETMINMAXINFO: - { - int minW = 0, maxW = 0, minH = 100000, maxH = 100000; - - std::pair range = m_callbackMap.equal_range(EventCallbacks::GetDimensions::ID); - for (CallbackMap::iterator callbackPos = range.first; callbackPos != range.second; ++callbackPos) - { - EventCallbacks::IGetDimensionsCallback* callback = static_cast((*callbackPos).second); - callback->Call(minW, maxW, minH, maxH); - } - - MINMAXINFO* minMaxInfo = (MINMAXINFO*)lParam; - minMaxInfo->ptMinTrackSize.x = minW; - minMaxInfo->ptMaxTrackSize.x = maxW; - minMaxInfo->ptMinTrackSize.y = minH; - minMaxInfo->ptMaxTrackSize.y = maxH; - } - break; - - case WM_SIZE: - { - int width = LOWORD(lParam); - int height = HIWORD(lParam); - std::pair range = m_callbackMap.equal_range(EventCallbacks::SizeChanged::ID); - for (CallbackMap::iterator callbackPos = range.first; callbackPos != range.second; ++callbackPos) - { - EventCallbacks::ISizeCallback* callback = static_cast((*callbackPos).second); - callback->Call(width, height); - } - } - break; - - case WM_NOTIFY_REFLECT: - break; - } - - LRESULT result = 0; - if (m_oldWndProc) - { - result = CallWindowProc(m_oldWndProc, hwnd, uMsg, wParam, lParam); - } - else - { - result = DefWindowProc(hwnd, uMsg, wParam, lParam); - } - - return result; -} - -LRESULT Win32GUI::Window::FrameWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_CLOSE: - PostQuitMessage(0); - break; - } - - return WindowProc(hwnd, uMsg, wParam, lParam); -} - -void Win32GUI::Window::Subclass(HWND window) -{ -#if defined(_WIN64) - SetWindowLongPtr(window, GWLP_USERDATA, LONG_PTR(this)); - m_oldWndProc = (WNDPROC)GetWindowLongPtr(window, GWLP_WNDPROC); - SetWindowLongPtr(window, GWLP_WNDPROC, LONG_PTR(&Window::StaticWindowProc)); -#else //defined(_WIN64) - SetWindowLong(window, GWL_USERDATA, PtrToLong(this)); - m_oldWndProc = (WNDPROC)LongToPtr(GetWindowLong(window, GWL_WNDPROC)); - SetWindowLong(window, GWL_WNDPROC, PtrToLong(&Window::StaticWindowProc)); -#endif //defined(_WIN64) -} - -void Win32GUI::Window::Unsubclass(HWND window) -{ -#if defined(_WIN64) - SetWindowLongPtr(window, GWLP_USERDATA, 0); - SetWindowLongPtr(window, GWLP_WNDPROC, LONG_PTR(m_oldWndProc)); -#else //defined(_WIN64) - SetWindowLongPtr(window, GWL_USERDATA, 0); - SetWindowLong(window, GWLP_WNDPROC, PtrToLong(m_oldWndProc)); -#endif //defined(_WIN64) - m_oldWndProc = 0; -} - -std::string Win32GUI::GetWindowString(HWND hwnd) -{ - LRESULT length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); - std::wstring wtext(length, 0); - SendMessageW(hwnd, WM_GETTEXT, length + 1, (LPARAM)&wtext[0]); - return StringHelpers::ConvertUtf16ToAnsi(wtext.c_str(), '?'); -} - -void Win32GUI::SetWindowString(HWND hwnd, const std::string& text) -{ - std::wstring wtext = StringHelpers::ConvertAnsiToUtf16(text.c_str()); - SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)&wtext[0]); -} - -HFONT Win32GUI::CreateFont() -{ - HFONT hFont = 0; - HFONT hGuiFont = static_cast(::GetStockObject(DEFAULT_GUI_FONT)); - - LOGFONT lfGuiFont = { 0 }; - if (::GetObject(hGuiFont, sizeof(LOGFONT), &lfGuiFont) == sizeof(LOGFONT)) - { - _tcsncpy(lfGuiFont.lfFaceName, _T("MS Shell Dlg 2"), sizeof(lfGuiFont.lfFaceName) / sizeof(TCHAR)); - lfGuiFont.lfFaceName[(sizeof(lfGuiFont.lfFaceName) / sizeof(TCHAR)) - 1] = '\0'; - - hFont = ::CreateFontIndirect(&lfGuiFont); - - return hFont; - } - return 0; -} - -void Win32GUI::SetCallbackObject(HWND hwnd, unsigned eventID, EventCallbacks::ICallback* callback) -{ -#if defined(_WIN64) - Window* window = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA); -#else //defined(_WIN64) - Window* window = (Window*)LongToPtr(GetWindowLong(hwnd, GWL_USERDATA)); -#endif //defined(_WIN64) - - window->m_callbackMap.insert(std::make_pair(eventID, callback)); -} diff --git a/Code/Tools/CryCommonTools/UI/Win32GUI.h b/Code/Tools/CryCommonTools/UI/Win32GUI.h deleted file mode 100644 index 60b91ece9f..0000000000 --- a/Code/Tools/CryCommonTools/UI/Win32GUI.h +++ /dev/null @@ -1,216 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_UI_WIN32GUI_H -#define CRYINCLUDE_CRYCOMMONTOOLS_UI_WIN32GUI_H -#pragma once - - -#include -#include - -namespace Win32GUI -{ - void Initialize(); - void RegisterFrameClass(const TCHAR* name); - HWND CreateFrame(const TCHAR* className, unsigned style, int width, int height); - HWND CreateControl(const TCHAR* className, unsigned style, HWND parent, int left, int top, int width, int height); - int Run(); - std::string GetWindowString(HWND hwnd); - void SetWindowString(HWND hwnd, const std::string& text); - HFONT CreateFont(); - - namespace EventCallbacks - { - class ICallback - { - public: - virtual ~ICallback() {} - virtual void Release() = 0; - }; - - struct IVoidCallback - : public ICallback - { - virtual void Call() = 0; - }; - - struct VoidCallback - { - template - struct Callback - : public IVoidCallback - { - typedef void (O::* Signature)(); - - Callback(O* object, Signature method) - : m_object(object) - , m_method(method) {} - virtual void Release() {delete this; } - virtual void Call() {(m_object->*m_method)(); } - O* m_object; - Signature m_method; - }; - }; - - struct IStringCallback - : public ICallback - { - virtual void Call(const std::string& text) = 0; - }; - - struct StringCallback - { - template - struct Callback - : public IStringCallback - { - typedef void (O::* Signature)(const std::string& text); - - Callback(O* object, Signature method) - : m_object(object) - , m_method(method) {} - virtual void Release() {delete this; } - virtual void Call(const std::string& text) {(m_object->*m_method)(text); } - O* m_object; - Signature m_method; - }; - }; - - struct IGetDimensionsCallback - : public ICallback - { - virtual void Call(int& minW, int& maxW, int& minH, int& maxH) = 0; - }; - - struct GetDimensionsCallback - { - template - struct Callback - : public IGetDimensionsCallback - { - typedef void (O::* Signature)(int& minW, int& maxW, int& minH, int& maxH); - - Callback(O* object, Signature method) - : m_object(object) - , m_method(method) {} - virtual void Release() {delete this; } - virtual void Call(int& minW, int& maxW, int& minH, int& maxH) {(m_object->*m_method)(minW, maxW, minH, maxH); } - O* m_object; - Signature m_method; - }; - }; - - struct ISizeCallback - : public ICallback - { - virtual void Call(int width, int height) = 0; - }; - - struct SizeCallback - { - template - struct Callback - : public ISizeCallback - { - typedef void (O::* Signature)(int width, int height); - - Callback(O* object, Signature method) - : m_object(object) - , m_method(method) {} - virtual void Release() {delete this; } - virtual void Call(int width, int height) {(m_object->*m_method)(width, height); } - O* m_object; - Signature m_method; - }; - }; - - struct IBoolCallback - : public ICallback - { - virtual void Call(bool value) = 0; - }; - - struct BoolCallback - { - template - struct Callback - : public IBoolCallback - { - typedef void (O::* Signature)(bool callback); - Callback(O* object, Signature method) - : m_object(object) - , m_method(method) {} - virtual void Release() {delete this; } - virtual void Call(bool value) {(m_object->*m_method)(value); } - O* m_object; - Signature m_method; - }; - }; - - struct TextChanged - : public StringCallback - { - enum - { - ID = 0x00005001 - }; - }; - struct GetDimensions - : public GetDimensionsCallback - { - enum - { - ID = 0x00005002 - }; - }; - struct SizeChanged - : public SizeCallback - { - enum - { - ID = 0x00005003 - }; - }; - struct Pushed - : public VoidCallback - { - enum - { - ID = 0x00005004 - }; - }; - struct Checked - : public BoolCallback - { - enum - { - ID = 0x00005005 - }; - }; - }; - - void SetCallbackObject(HWND hwnd, unsigned eventID, EventCallbacks::ICallback* callback); - template - inline void SetCallback(HWND hwnd, O* object, typename T::template Callback::Signature method); -} - -template -inline void Win32GUI::SetCallback(HWND hwnd, O* object, typename T::template Callback::Signature method) -{ - typedef T::template Callback Callback; - Callback* callback = new Callback(object, method); - SetCallbackObject(hwnd, T::ID, callback); -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_UI_WIN32GUI_H diff --git a/Gems/LyShine/Code/Editor/PropertyHandlerSprite.cpp b/Gems/LyShine/Code/Editor/PropertyHandlerSprite.cpp index 20721d4624..5123d120d5 100644 --- a/Gems/LyShine/Code/Editor/PropertyHandlerSprite.cpp +++ b/Gems/LyShine/Code/Editor/PropertyHandlerSprite.cpp @@ -27,8 +27,6 @@ #include "SpriteBorderEditorCommon.h" -#include - #include #include From 33f7da764e16ad7ee5026aa4ac4c2c8a39a01e41 Mon Sep 17 00:00:00 2001 From: Shirang Jia Date: Wed, 12 May 2021 10:05:42 -0700 Subject: [PATCH 150/225] Remove unneeded scripts that have internal service references (#683) --- scripts/build/tools/alert_build_failures.py | 76 ------------ scripts/build/tools/email_to_lionbridge.py | 128 -------------------- 2 files changed, 204 deletions(-) delete mode 100755 scripts/build/tools/alert_build_failures.py delete mode 100755 scripts/build/tools/email_to_lionbridge.py diff --git a/scripts/build/tools/alert_build_failures.py b/scripts/build/tools/alert_build_failures.py deleted file mode 100755 index 486d84123d..0000000000 --- a/scripts/build/tools/alert_build_failures.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -import os -from incremental_build_util import get_iam_role_credentials -try: - import requests -except ImportError: - import pip - pip.main(['install', 'requests', '--ignore-installed', '-q']) - import requests -try: - from requests_aws4auth import AWS4Auth -except ImportError: - import pip - pip.main(['install', 'requests_aws4auth', '--ignore-installed', '-q']) - from requests_aws4auth import AWS4Auth - -IAM_ROLE_NAME = 'ec2-jenkins-node' -TEAM = 'lumberyard-build' -CHIME_ROOM_WEB_HOOK = "https://hooks.chime.aws/incomingwebhooks/2a6018c9-3bf5-4e03-851c-32ba82c7c4e2?token=YWhTVXZsWVJ8MXxaLTg5RkVZNlA5Q1NiMVdfQndGeS1TSHNnYW5VREVha3pjX1pUUEd5b1JF" - - -def find_curr_oncalls_for_team(team): - host = "who-is-oncall-pdx.corp.amazon.com" - service_name = "who-is-oncall" - aws_region = "us-west-2" - headers = {"content-type": "application/json", "host": host} - - credentials = get_iam_role_credentials(IAM_ROLE_NAME) - try: - aws_access_key_id = credentials['AccessKeyId'] - aws_secret_access_key = credentials['SecretAccessKey'] - aws_session_token = credentials['Token'] - except Exception as e: - print(f'ERROR: Cannot get AWS credentials.\n{e}') - return ['All'] - - auth = AWS4Auth(aws_access_key_id, aws_secret_access_key, aws_region, service_name, session_token=aws_session_token) - r = requests.get(f"https://who-is-oncall-pdx.corp.amazon.com/teams/{team}", headers=headers, auth=auth, verify=False) - if r.ok: - res = r.json() - try: - return res['currOncalls'] - except KeyError: - return ['All'] - return ['All'] - - -def send_alert_to_chime_room(web_hook, content): - data = '{"Content":"' + content + '"}' - headers = {'Content-Type': 'application/json'} - requests.post(web_hook, headers=headers, data=data) - - -def create_content(): - content = '' - oncalls = find_curr_oncalls_for_team(TEAM) - for oncall in oncalls: - content += f'@{oncall} ' - job_name = os.environ['JOB_NAME'] - build_url = os.environ['BUILD_URL'] - content += fr'\nJob {job_name} failed\nBuild URL: {build_url}\n' - return content - - -send_alert_to_chime_room(CHIME_ROOM_WEB_HOOK, create_content()) - diff --git a/scripts/build/tools/email_to_lionbridge.py b/scripts/build/tools/email_to_lionbridge.py deleted file mode 100755 index 7f522bb564..0000000000 --- a/scripts/build/tools/email_to_lionbridge.py +++ /dev/null @@ -1,128 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -""" -This script will be used in the Sandobx Jenkins job PACKAGE_COPY_S3 -PACKAGE_COPY_S3 is a downstream job of nightly packaging job, it copies the nightly packages from Infra S3 bucket to Lionbridge S3 bucket based on the INCLUDE_FILTER passed from packaging job -""" -import os -import re -import json -import requests -from requests.auth import HTTPBasicAuth -import boto3 -from util import error, warn - - -# Write EMAIL_TEMPLATE to a file and inject it into the email sent to Lionbridge -EMAIL_TEMPLATE = '''Packages are uploaded to S3 bucket {} -Package List: -{} - - -Changelists: -{} -''' - - -def get_jenkins_env(key): - try: - return os.environ[key] - except KeyError: - print('Error: Jenkins parameters {} is not set.'.format(key)) - return None - - -JENKINS_USERNAME = get_jenkins_env('JENKINS_USERNAME') -JENKINS_API_TOKEN = get_jenkins_env('JENKINS_API_TOKEN') -JENKINS_URL = get_jenkins_env('JENKINS_URL') -WORKSPACE = get_jenkins_env('WORKSPACE') -S3_TARGET = get_jenkins_env('S3_TARGET') -INCLUDE_FILTER = get_jenkins_env('INCLUDE_FILTER') -EMAIL_TEMPLATE_FILE = get_jenkins_env('EMAIL_TEMPLATE_FILE') -if None in [JENKINS_USERNAME, JENKINS_API_TOKEN, JENKINS_URL, WORKSPACE, S3_TARGET, INCLUDE_FILTER, EMAIL_TEMPLATE_FILE]: - error('Please make sure all Jenkins parameters are set correctly.') - - -def parse_include_filter(include_filter): - try: - res = re.search('^(\w*)-*lumberyard-(\d+)\.(\d+)-(\d+)-(\w+).*\*(\d+)\.\*', include_filter) - branch = res.group(1) - major_version = int(res.group(2)) - minor_version = int(res.group(3)) - changelist_number = res.group(4) - platform = res.group(5) - build_number = res.group(6) - return branch, major_version, minor_version, changelist_number, platform, build_number - except (AttributeError, IndexError): - error('Unable to parse INCLUDE_FILTER, please make sure the INCLUDE_FILTER is set correctly') - - -# Get the changelists that trigger the build -def get_changelists(job_name, build_number): - changelists = [] - headers = {'Content-type': 'application/json', 'Accept': 'application/json'} - try: - res = requests.get('{}/job/{}/{}/api/json'.format(JENKINS_URL, job_name, build_number), - auth=HTTPBasicAuth(JENKINS_USERNAME, JENKINS_API_TOKEN), headers=headers, verify=False) - res = json.loads(res.content) - changelists = res.get('changeSet').get('items') - return changelists - except: - warn('Error: Failed to get changes from build {} in job {}'.format(build_number, job_name)) - return [] - - -def get_packaging_job_name(branch, major_version, minor_version, platform): - if branch == '': - branch = 'ML' if major_version + minor_version == 0 else 'v{}_{}'.format(major_version, minor_version) - job_name = 'PKG_{}_{}'.format(branch, platform.capitalize()) - return job_name - - -# Get package names by looking up S3 bucket -def get_package_names(branch, major_version, minor_version, include_filter, build_number): - package_names = [] - prefix = include_filter[:include_filter.find('*')] - pattern = '.*{}.*{}..*'.format(prefix, build_number) - if branch == '': - bucket_name = 'ly-packages-mainline' if major_version + minor_version == 0 else 'ly-packages-release-candidate' - folder = 'lumberyard-packages' - else: - bucket_name = 'ly-packages-feature-branches' - folder = 'lumberyard-packages/{}'.format(branch) - s3 = boto3.resource('s3') - bucket = s3.Bucket(bucket_name) - for obj in bucket.objects.filter(Prefix='{}/{}'.format(folder, prefix)): - package_name = obj.key - if re.match(pattern, package_name): - package_names.append(package_name.replace('{}/'.format(folder), '')) - return package_names - - -if __name__ == "__main__": - branch, major_version, minor_version, changelist_number, platform, build_number = parse_include_filter(INCLUDE_FILTER) - packaging_job_name = get_packaging_job_name(branch, major_version, minor_version, platform) - changelists = get_changelists(packaging_job_name, build_number) - package_names = get_package_names(branch, major_version, minor_version, INCLUDE_FILTER, build_number) - with open(os.path.join(WORKSPACE, EMAIL_TEMPLATE_FILE), 'w+') as output: - if len(package_names) > 0: - package_list_str = '\n'.join(package_names) - changelists_str = '' - for item in changelists: - changelists_str += '---------------------------------------------------------------------------------------------\n' - try: - changelists_str += 'CL{} by {} on {}\n{}\n'.format(item['changeNumber'], item['author']['fullName'], item['changeTime'], item['msg'].encode('utf-8', 'ignore')) - except KeyError: - error('Internal error, check the output of Jenkins API.') - output.write(EMAIL_TEMPLATE.format(S3_TARGET, package_list_str, changelists_str)) - - From 3383cfc95a33145114893ba6dd98cc9775a90ab5 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Wed, 12 May 2021 10:20:03 -0700 Subject: [PATCH 151/225] Fix Jenkins failure during engine registration for iOS --- scripts/build/Platform/iOS/build_config.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/build/Platform/iOS/build_config.json b/scripts/build/Platform/iOS/build_config.json index 4566d243ee..bb5f2d2fe6 100644 --- a/scripts/build/Platform/iOS/build_config.json +++ b/scripts/build/Platform/iOS/build_config.json @@ -27,7 +27,7 @@ "PARAMETERS": { "CONFIGURATION": "debug", "OUTPUT_DIRECTORY": "build/ios", - "CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE", + "CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS" @@ -44,7 +44,7 @@ "PARAMETERS": { "CONFIGURATION": "profile", "OUTPUT_DIRECTORY": "build/ios", - "CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE", + "CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS" @@ -60,7 +60,7 @@ "PARAMETERS": { "CONFIGURATION": "profile", "OUTPUT_DIRECTORY": "build/ios", - "CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=FALSE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE", + "CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=FALSE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS" @@ -94,7 +94,7 @@ "PARAMETERS": { "CONFIGURATION": "release", "OUTPUT_DIRECTORY": "build/ios", - "CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE", + "CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS" From 3569ac9b873f1a996d306eb06646195574710095 Mon Sep 17 00:00:00 2001 From: Aristo7 <5432499+Aristo7@users.noreply.github.com> Date: Wed, 12 May 2021 13:13:28 -0500 Subject: [PATCH 152/225] Bringing back RHI modules to tools deps --- .../Source/Platform/Linux/additional_linux_tool_deps.cmake | 3 +++ .../Code/Source/Platform/Mac/additional_mac_tool_deps.cmake | 3 +++ .../Source/Platform/Windows/additional_windows_tool_deps.cmake | 3 +++ 3 files changed, 9 insertions(+) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake index 908417b1f8..c76527afa0 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Linux/additional_linux_tool_deps.cmake @@ -10,6 +10,9 @@ # set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_Metal.Private Gem::Atom_RHI_Vulkan.Builders Gem::Atom_RHI_DX12.Builders Gem::Atom_RHI_Metal.Builders diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake index 445a416a68..81046d3071 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Mac/additional_mac_tool_deps.cmake @@ -10,6 +10,9 @@ # set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Metal.Private + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_DX12.Private Gem::Atom_RHI_Metal.Builders Gem::Atom_RHI_Vulkan.Builders Gem::Atom_RHI_DX12.Builders diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake index 908417b1f8..c76527afa0 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Platform/Windows/additional_windows_tool_deps.cmake @@ -10,6 +10,9 @@ # set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_Metal.Private Gem::Atom_RHI_Vulkan.Builders Gem::Atom_RHI_DX12.Builders Gem::Atom_RHI_Metal.Builders From 931a127b7b8b42f92f7a391c37cb4ac5c77bc69c Mon Sep 17 00:00:00 2001 From: guthadam Date: Wed, 12 May 2021 13:47:47 -0500 Subject: [PATCH 153/225] ATOM-15223 updating material assignment ID to be portable to other models The bug was reported that copy and paste did not work with the material component. Copy and paste to take the worked fine. All of the material assignments/overrides get mapped using the LOD and asset ID of materials provided with the model. The asset IDs of materials exported by atom builders, using the scene API, are the combination of the same UUID as the model asset ID and the unique sub ID that is now hashed from the material name provided by the DCC tool. If we map material assignments using the entire asset ID that was generated in the model builder then the mapping will only work with that specific model. This change updates the material assignment ID equality operators and hash function to only use the sub ID portion of the asset ID. As long as the sub IDs are generated consistently the material assignment mappings will be portable to models with the same material names. Also moved material assignment structures to atom common features static library so this was to be moved to cpp files --- .../Feature/Material/MaterialAssignment.h | 125 ++++-------------- .../Feature/Material/MaterialAssignmentId.h | 101 +++++--------- .../Source/Material/MaterialAssignment.cpp | 98 +++++++++++++- .../Source/Material/MaterialAssignmentId.cpp | 67 +++++++++- .../Code/atom_feature_common_files.cmake | 4 - ...m_feature_common_staticlibrary_files.cmake | 4 + .../EMotionFXAtom/Code/CMakeLists.txt | 1 + 7 files changed, 232 insertions(+), 168 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Material/MaterialAssignment.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Material/MaterialAssignment.h index 089f4e8c62..58fb2e0f8a 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Material/MaterialAssignment.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Material/MaterialAssignment.h @@ -1,21 +1,21 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once -#include -#include -#include #include +#include +#include #include +#include namespace AZ { @@ -31,39 +31,19 @@ namespace AZ MaterialAssignment() = default; - MaterialAssignment(const AZ::Data::AssetId& materialAssetId) - : m_materialInstance() - { - m_materialAsset.Create(materialAssetId); - } + MaterialAssignment(const AZ::Data::AssetId& materialAssetId); - MaterialAssignment(const Data::Asset& asset) - : m_materialAsset(asset) - , m_materialInstance() - { - } + MaterialAssignment(const Data::Asset& asset); - MaterialAssignment(const Data::Asset& asset, const Data::Instance& instance) - : m_materialAsset(asset) - , m_materialInstance(instance) - { - } + MaterialAssignment(const Data::Asset& asset, const Data::Instance& instance); - void RebuildInstance() - { - if (m_materialAsset.IsReady()) - { - m_materialInstance = m_propertyOverrides.empty() ? RPI::Material::FindOrCreate(m_materialAsset) : RPI::Material::Create(m_materialAsset); - AZ_Error("MaterialAssignment", m_materialInstance, "Material instance not initialized"); - } - } + //! Recreates the material instance from the asset if it has been loaded. + //! If amy property overrides have been specified then a unique instance will be created. + //! Otherwise an attempt will be made to find or create a shared instance. + void RebuildInstance(); - AZStd::string ToString() const - { - AZStd::string assetPathString; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetPathString, &AZ::Data::AssetCatalogRequests::GetAssetPathById, m_materialAsset.GetId()); - return assetPathString; - } + //! Returns a string composed of the asset path. + AZStd::string ToString() const; Data::Asset m_materialAsset; Data::Instance m_materialInstance; @@ -77,64 +57,15 @@ namespace AZ static const MaterialAssignmentMap DefaultMaterialAssignmentMap; //! Utility function for retrieving a material entry from a MaterialAssignmentMap - AZ_INLINE const MaterialAssignment& GetMaterialAssignmentFromMap(const MaterialAssignmentMap& materials, const MaterialAssignmentId& id) - { - const auto& materialItr = materials.find(id); - return materialItr != materials.end() ? materialItr->second : DefaultMaterialAssignment; - } + const MaterialAssignment& GetMaterialAssignmentFromMap(const MaterialAssignmentMap& materials, const MaterialAssignmentId& id); - //! Utility function for retrieving a material entry from a MaterialAssignmentMap, falling back to defaults for a particular asset or the entire model - AZ_INLINE const MaterialAssignment& GetMaterialAssignmentFromMapWithFallback(const MaterialAssignmentMap& materials, const MaterialAssignmentId& id) - { - const MaterialAssignment& lodAssignment = GetMaterialAssignmentFromMap(materials, id); - if (lodAssignment.m_materialInstance.get()) - { - return lodAssignment; - } - - const MaterialAssignment& assetAssignment = GetMaterialAssignmentFromMap(materials, MaterialAssignmentId::CreateFromAssetOnly(id.m_materialAssetId)); - if (assetAssignment.m_materialInstance.get()) - { - return assetAssignment; - } - - const MaterialAssignment& defaultAssignment = GetMaterialAssignmentFromMap(materials, DefaultMaterialAssignmentId); - if (defaultAssignment.m_materialInstance.get()) - { - return defaultAssignment; - } - - return DefaultMaterialAssignment; - } + //! Utility function for retrieving a material entry from a MaterialAssignmentMap, falling back to defaults for a particular asset + //! or the entire model + const MaterialAssignment& GetMaterialAssignmentFromMapWithFallback( + const MaterialAssignmentMap& materials, const MaterialAssignmentId& id); //! Utility function for generating a set of available material assignments in a model - AZ_INLINE MaterialAssignmentMap GetMaterialAssignmentsFromModel(Data::Instance model) - { - MaterialAssignmentMap materials; - materials[DefaultMaterialAssignmentId] = MaterialAssignment(); - - if (model) - { - size_t lodIndex = 0; - for (const Data::Instance& lod : model->GetLods()) - { - for (const AZ::RPI::ModelLod::Mesh& mesh : lod->GetMeshes()) - { - if (mesh.m_material) - { - const MaterialAssignmentId generalId = MaterialAssignmentId::CreateFromAssetOnly(mesh.m_material->GetAssetId()); - materials[generalId] = MaterialAssignment(mesh.m_material->GetAsset(), mesh.m_material); - - const MaterialAssignmentId specificId = MaterialAssignmentId::CreateFromLodAndAsset(lodIndex, mesh.m_material->GetAssetId()); - materials[specificId] = MaterialAssignment(mesh.m_material->GetAsset(), mesh.m_material); - } - } - ++lodIndex; - } - } - - return materials; - } + MaterialAssignmentMap GetMaterialAssignmentsFromModel(Data::Instance model); } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Material/MaterialAssignmentId.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Material/MaterialAssignmentId.h index 267e65743a..80de6d8041 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Material/MaterialAssignmentId.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Material/MaterialAssignmentId.h @@ -1,20 +1,20 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ #pragma once +#include #include #include -#include #include #include #include @@ -26,6 +26,9 @@ namespace AZ { using MaterialAssignmentLodIndex = AZ::u64; + //! MaterialAssignmentId is used to address available and overridable material slots on a model. + //! The LOD and one of the model's original material asset IDs are used as coordinates that identify + //! a specific material slot or a set of slots matching either. struct MaterialAssignmentId final { AZ_RTTI(AZ::Render::MaterialAssignmentId, "{EB603581-4654-4C17-B6DE-AE61E79EDA97}"); @@ -34,69 +37,37 @@ namespace AZ MaterialAssignmentId() = default; - MaterialAssignmentId(MaterialAssignmentLodIndex lodIndex, const AZ::Data::AssetId& materialAssetId) - : m_lodIndex(lodIndex) - , m_materialAssetId(materialAssetId) - { - } + MaterialAssignmentId(MaterialAssignmentLodIndex lodIndex, const AZ::Data::AssetId& materialAssetId); - static MaterialAssignmentId CreateDefault() - { - return MaterialAssignmentId(NonLodIndex, AZ::Data::AssetId()); - } + //! Create an ID that maps to all material slots, regardless of asset ID or LOD, effectively applying to an entire model. + static MaterialAssignmentId CreateDefault(); - static MaterialAssignmentId CreateFromAssetOnly(AZ::Data::AssetId materialAssetId) - { - return MaterialAssignmentId(NonLodIndex, materialAssetId); - } + //! Create an ID that maps to all material slots with a corresponding asset ID, regardless of LOD. + static MaterialAssignmentId CreateFromAssetOnly(AZ::Data::AssetId materialAssetId); - static MaterialAssignmentId CreateFromLodAndAsset(MaterialAssignmentLodIndex lodIndex, AZ::Data::AssetId materialAssetId) - { - return MaterialAssignmentId(lodIndex, materialAssetId); - } + //! Create an ID that maps to a specific material slot with a corresponding asset ID and LOD. + static MaterialAssignmentId CreateFromLodAndAsset(MaterialAssignmentLodIndex lodIndex, AZ::Data::AssetId materialAssetId); - bool IsDefault() const - { - return m_lodIndex == NonLodIndex && !m_materialAssetId.IsValid(); - } + //! Returns true if the asset ID and LOD are invalid + bool IsDefault() const; - bool IsAssetOnly() const - { - return m_lodIndex == NonLodIndex && m_materialAssetId.IsValid(); - } + //! Returns true if the asset ID is valid and LOD is invalid + bool IsAssetOnly() const; - bool IsLodAndAsset() const - { - return m_lodIndex != NonLodIndex && m_materialAssetId.IsValid(); - } + //! Returns true if the asset ID and LOD are both valid + bool IsLodAndAsset() const; + //! Creates a string composed of the asset path and LOD + AZStd::string ToString() const; - AZStd::string ToString() const - { - AZStd::string assetPathString; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetPathString, &AZ::Data::AssetCatalogRequests::GetAssetPathById, m_materialAssetId); - AZ::StringFunc::Path::StripPath(assetPathString); - AZ::StringFunc::Path::StripExtension(assetPathString); - return AZStd::string::format("%s:%llu", assetPathString.c_str(), m_lodIndex); - } + //! Creates a hash composed of the asset ID sub ID and LOD + size_t GetHash() const; - size_t GetHash() const - { - size_t seed = 0; - AZStd::hash_combine(seed, m_lodIndex); - AZStd::hash_combine(seed, m_materialAssetId); - return seed; - } + //! Returns true if both asset ID sub IDs and LODs match + bool operator==(const MaterialAssignmentId& rhs) const; - bool operator==(const MaterialAssignmentId& rhs) const - { - return m_lodIndex == rhs.m_lodIndex && m_materialAssetId == rhs.m_materialAssetId; - } - - bool operator!=(const MaterialAssignmentId& rhs) const - { - return m_lodIndex != rhs.m_lodIndex || m_materialAssetId != rhs.m_materialAssetId; - } + //! Returns true if both asset ID sub IDs and LODs do not match + bool operator!=(const MaterialAssignmentId& rhs) const; static constexpr MaterialAssignmentLodIndex NonLodIndex = -1; MaterialAssignmentLodIndex m_lodIndex = NonLodIndex; @@ -116,4 +87,4 @@ namespace AZStd return id.GetHash(); } }; -} //namespace AZStd +} // namespace AZStd diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignment.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignment.cpp index f817e8324b..ffb5469aef 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignment.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignment.cpp @@ -11,8 +11,8 @@ */ #include -#include #include +#include namespace AZ { @@ -67,5 +67,101 @@ namespace AZ } } + + MaterialAssignment::MaterialAssignment(const AZ::Data::AssetId& materialAssetId) + : m_materialInstance() + { + m_materialAsset.Create(materialAssetId); + } + + MaterialAssignment::MaterialAssignment(const Data::Asset& asset) + : m_materialAsset(asset) + , m_materialInstance() + { + } + + MaterialAssignment::MaterialAssignment(const Data::Asset& asset, const Data::Instance& instance) + : m_materialAsset(asset) + , m_materialInstance(instance) + { + } + + void MaterialAssignment::RebuildInstance() + { + if (m_materialAsset.IsReady()) + { + m_materialInstance = + m_propertyOverrides.empty() ? RPI::Material::FindOrCreate(m_materialAsset) : RPI::Material::Create(m_materialAsset); + AZ_Error("MaterialAssignment", m_materialInstance, "Material instance not initialized"); + } + } + + AZStd::string MaterialAssignment::ToString() const + { + AZStd::string assetPathString; + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + assetPathString, &AZ::Data::AssetCatalogRequests::GetAssetPathById, m_materialAsset.GetId()); + return assetPathString; + } + + const MaterialAssignment& GetMaterialAssignmentFromMap(const MaterialAssignmentMap& materials, const MaterialAssignmentId& id) + { + const auto& materialItr = materials.find(id); + return materialItr != materials.end() ? materialItr->second : DefaultMaterialAssignment; + } + + const MaterialAssignment& GetMaterialAssignmentFromMapWithFallback( + const MaterialAssignmentMap& materials, const MaterialAssignmentId& id) + { + const MaterialAssignment& lodAssignment = GetMaterialAssignmentFromMap(materials, id); + if (lodAssignment.m_materialInstance.get()) + { + return lodAssignment; + } + + const MaterialAssignment& assetAssignment = + GetMaterialAssignmentFromMap(materials, MaterialAssignmentId::CreateFromAssetOnly(id.m_materialAssetId)); + if (assetAssignment.m_materialInstance.get()) + { + return assetAssignment; + } + + const MaterialAssignment& defaultAssignment = GetMaterialAssignmentFromMap(materials, DefaultMaterialAssignmentId); + if (defaultAssignment.m_materialInstance.get()) + { + return defaultAssignment; + } + + return DefaultMaterialAssignment; + } + + MaterialAssignmentMap GetMaterialAssignmentsFromModel(Data::Instance model) + { + MaterialAssignmentMap materials; + materials[DefaultMaterialAssignmentId] = MaterialAssignment(); + + if (model) + { + size_t lodIndex = 0; + for (const Data::Instance& lod : model->GetLods()) + { + for (const AZ::RPI::ModelLod::Mesh& mesh : lod->GetMeshes()) + { + if (mesh.m_material) + { + const MaterialAssignmentId generalId = MaterialAssignmentId::CreateFromAssetOnly(mesh.m_material->GetAssetId()); + materials[generalId] = MaterialAssignment(mesh.m_material->GetAsset(), mesh.m_material); + + const MaterialAssignmentId specificId = + MaterialAssignmentId::CreateFromLodAndAsset(lodIndex, mesh.m_material->GetAssetId()); + materials[specificId] = MaterialAssignment(mesh.m_material->GetAsset(), mesh.m_material); + } + } + ++lodIndex; + } + } + + return materials; + } } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentId.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentId.cpp index 4813136d2e..0fe89d49b8 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentId.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentId.cpp @@ -11,8 +11,8 @@ */ #include -#include #include +#include namespace AZ { @@ -47,5 +47,70 @@ namespace AZ ; } } + + MaterialAssignmentId::MaterialAssignmentId(MaterialAssignmentLodIndex lodIndex, const AZ::Data::AssetId& materialAssetId) + : m_lodIndex(lodIndex) + , m_materialAssetId(materialAssetId) + { + } + + MaterialAssignmentId MaterialAssignmentId::CreateDefault() + { + return MaterialAssignmentId(NonLodIndex, AZ::Data::AssetId()); + } + + MaterialAssignmentId MaterialAssignmentId::CreateFromAssetOnly(AZ::Data::AssetId materialAssetId) + { + return MaterialAssignmentId(NonLodIndex, materialAssetId); + } + + MaterialAssignmentId MaterialAssignmentId::CreateFromLodAndAsset( + MaterialAssignmentLodIndex lodIndex, AZ::Data::AssetId materialAssetId) + { + return MaterialAssignmentId(lodIndex, materialAssetId); + } + + bool MaterialAssignmentId::IsDefault() const + { + return m_lodIndex == NonLodIndex && !m_materialAssetId.IsValid(); + } + + bool MaterialAssignmentId::IsAssetOnly() const + { + return m_lodIndex == NonLodIndex && m_materialAssetId.IsValid(); + } + + bool MaterialAssignmentId::IsLodAndAsset() const + { + return m_lodIndex != NonLodIndex && m_materialAssetId.IsValid(); + } + + AZStd::string MaterialAssignmentId::ToString() const + { + AZStd::string assetPathString; + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + assetPathString, &AZ::Data::AssetCatalogRequests::GetAssetPathById, m_materialAssetId); + AZ::StringFunc::Path::StripPath(assetPathString); + AZ::StringFunc::Path::StripExtension(assetPathString); + return AZStd::string::format("%s:%llu", assetPathString.c_str(), m_lodIndex); + } + + size_t MaterialAssignmentId::GetHash() const + { + size_t seed = 0; + AZStd::hash_combine(seed, m_lodIndex); + AZStd::hash_combine(seed, m_materialAssetId.m_subId); + return seed; + } + + bool MaterialAssignmentId::operator==(const MaterialAssignmentId& rhs) const + { + return m_lodIndex == rhs.m_lodIndex && m_materialAssetId.m_subId == rhs.m_materialAssetId.m_subId; + } + + bool MaterialAssignmentId::operator!=(const MaterialAssignmentId& rhs) const + { + return m_lodIndex != rhs.m_lodIndex || m_materialAssetId.m_subId != rhs.m_materialAssetId.m_subId; + } } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake index 47000d8a5c..8926b0c19f 100644 --- a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake +++ b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake @@ -27,8 +27,6 @@ set(FILES Include/Atom/Feature/ImGui/SystemBus.h Include/Atom/Feature/ImageBasedLights/ImageBasedLightFeatureProcessor.h Include/Atom/Feature/LookupTable/LookupTableAsset.h - Include/Atom/Feature/Material/MaterialAssignment.h - Include/Atom/Feature/Material/MaterialAssignmentId.h Include/Atom/Feature/Mesh/MeshFeatureProcessor.h Include/Atom/Feature/PostProcessing/PostProcessingConstants.h Include/Atom/Feature/PostProcessing/SMAAFeatureProcessorInterface.h @@ -155,8 +153,6 @@ set(FILES Source/LookupTable/LookupTableAsset.cpp Source/Material/ConvertEmissiveUnitFunctor.cpp Source/Material/ConvertEmissiveUnitFunctor.h - Source/Material/MaterialAssignment.cpp - Source/Material/MaterialAssignmentId.cpp Source/Material/ShaderEnableFunctor.cpp Source/Material/ShaderEnableFunctor.h Source/Material/SubsurfaceTransmissionParameterFunctor.cpp diff --git a/Gems/Atom/Feature/Common/Code/atom_feature_common_staticlibrary_files.cmake b/Gems/Atom/Feature/Common/Code/atom_feature_common_staticlibrary_files.cmake index d33e861c02..553f307409 100644 --- a/Gems/Atom/Feature/Common/Code/atom_feature_common_staticlibrary_files.cmake +++ b/Gems/Atom/Feature/Common/Code/atom_feature_common_staticlibrary_files.cmake @@ -10,8 +10,12 @@ # set(FILES + Include/Atom/Feature/Material/MaterialAssignment.h + Include/Atom/Feature/Material/MaterialAssignmentId.h Include/Atom/Feature/Utils/LightingPreset.h Include/Atom/Feature/Utils/ModelPreset.h + Source/Material/MaterialAssignment.cpp + Source/Material/MaterialAssignmentId.cpp Source/Utils/LightingPreset.cpp Source/Utils/ModelPreset.cpp ) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/CMakeLists.txt b/Gems/AtomLyIntegration/EMotionFXAtom/Code/CMakeLists.txt index dc969d61d3..6492f4f13a 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/CMakeLists.txt @@ -25,6 +25,7 @@ ly_add_target( Gem::Atom_Utils.Static Gem::Atom_Feature_Common Gem::Atom_Feature_Common.Public + Gem::Atom_Feature_Common.Static Gem::Atom_RPI.Public Gem::Atom_RHI.Reflect Gem::AtomLyIntegration_CommonFeatures.Public From b5d7ae829a4c44a9d89bb104b55135ffc9059d19 Mon Sep 17 00:00:00 2001 From: zsolleci Date: Wed, 12 May 2021 14:10:54 -0500 Subject: [PATCH 154/225] addressed internal review feedback --- .../scripting/Node_HappyPath_DuplicateNode.py | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py b/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py index 9d8cccd027..77d3b2fcde 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py @@ -12,9 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # fmt: off class Tests(): - open_sc_window = ("Script Canvas window is opened", "Failed to open Script Canvas window") - node_added = ("Successfully added node to graph", "Failed to add node to graph") - node_duplicated = ("Successfully duplicated node", "Failed to duplicate the node") + node_duplicated = ("Successfully duplicated node", "Failed to duplicate the node") # fmt: on @@ -30,9 +28,8 @@ def Node_HappyPath_DuplicateNode(): 1) Open Script Canvas window (Tools > Script Canvas) 2) Open a new graph 3) Add node to graph - 4) Select node in graph to verify existence - 5) Mock Ctrl+D to duplicate node - 6) Verify the node was duplicated + 4) Duplicate node + 5) Verify the node was duplicated6) Verify the node was duplicated Note: - This test file must be called from the Open 3D Engine Editor command terminal @@ -68,11 +65,9 @@ def Node_HappyPath_DuplicateNode(): def grab_title_text(): scroll_area = node_inspector.findChild(QtWidgets.QScrollArea, "") QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES) - general.idle_wait(1.0) background = scroll_area.findChild(QtWidgets.QFrame, "Background") title = background.findChild(QtWidgets.QLabel, "Title") text = title.findChild(QtWidgets.QLabel, "Title") - print(text.text()) return text.text() # 1) Open Script Canvas window (Tools > Script Canvas) @@ -80,29 +75,35 @@ def Node_HappyPath_DuplicateNode(): general.open_pane("Script Canvas") helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - # # 2) Open a new graph + # 2) Open a new graph editor_window = pyside_utils.get_editor_main_window() sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") sc_main = sc.findChild(QtWidgets.QMainWindow) create_new_graph = pyside_utils.find_child_by_pattern( sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} ) + if sc.findChild(QtWidgets.QDockWidget, "NodeInspector") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Inspector", "type": QtWidgets.QAction}) + action.trigger() node_inspector = sc.findChild(QtWidgets.QDockWidget, "NodeInspector") create_new_graph.trigger() # 3) Add node command_line_input("add_node Print") - # 4) Select node in graph to verify existence + # 4) Duplicate node graph_view = sc.findChild(QtWidgets.QFrame, "graphicsViewFrame") graph = graph_view.findChild(QtWidgets.QWidget, "") - - # 5) Duplicate node + # There are currently no utilities available to directly duplicate the node, + # therefore the node is selected using CTRL+A on the graph to select + # it and then CTRL+D to duplicate sc_main.activateWindow() QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES) QtTest.QTest.keyClick(graph, "d", Qt.ControlModifier, WAIT_FRAMES) - # 6) Verify the node was duplicated + # 5) Verify the node was duplicated + # As direct interaction with node is not available the text on the label + # inside the Node Inspector is validated showing two nodes exist after_dup = grab_title_text() Report.result(Tests.node_duplicated, after_dup == EXPECTED_STRING) From 98a579abefc0ac64e6ee4ae021c7e8e824dafaa5 Mon Sep 17 00:00:00 2001 From: srikappa Date: Wed, 12 May 2021 12:17:36 -0700 Subject: [PATCH 155/225] Added a comment --- .../AzToolsFramework/Prefab/PrefabPublicHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 3214905721..9649818ed9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -149,6 +149,7 @@ namespace AzToolsFramework undoBatch.GetUndoBatch(), containerEntityId, false); }); + // Create a link between the templates of the newly created instance and the instance it's being parented under. CreateLink( topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(), commonRootEntityId); From 2787e5053d8514afd470df38881da916d231bb39 Mon Sep 17 00:00:00 2001 From: catdo Date: Wed, 12 May 2021 13:18:32 -0700 Subject: [PATCH 156/225] addressed some nits and added comments --- .../prefab/PrefabLevel_OpensLevelWithEntities.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py index ca59bbc2f8..3401c6a0a9 100644 --- a/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py +++ b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py @@ -14,7 +14,7 @@ class Tests(): find_empty_entity = ("Entity: 'EmptyEntity' found", "Entity: 'EmptyEntity' *not* found in level") empty_entity_pos = ("'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position") find_pxentity = ("Entity: 'EntityWithPxCollider' found", "Entity: 'EntityWithPxCollider' *not* found in level") - pxentity_component = ("Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' has *not* a Physx Collider") + pxentity_component = ("Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' does *not* have a Physx Collider") # fmt:on @@ -50,17 +50,19 @@ def PrefabLevel_OpensLevelWithEntities(): if entityIds[0].IsValid(): return entityIds[0] return None - +#Checks for an entity called "EmptyEntity" helper.wait_for_condition(lambda: find_entity("EmptyEntity").IsValid(), 5.0) empty_entity_id = find_entity("EmptyEntity") Report.result(Tests.find_empty_entity, empty_entity_id.IsValid()) +# Checks if the EmptyEntity is in the correct position and if it fails, it will provide the expected postion and the actual postion of the entity in the Editor log empty_entity_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", empty_entity_id) is_at_position = empty_entity_pos.IsClose(EXPECTED_EMPTY_ENTITY_POS) Report.result(Tests.empty_entity_pos, is_at_position) if not is_at_position: Report.info(f'Expected position: {EXPECTED_EMPTY_ENTITY_POS.ToString()}, actual position: {empty_entity_pos.ToString()}') +#Checks for an entity called "EntityWithPxCollider" and if it has the PhysX Collider component pxentity = find_entity("EntityWithPxCollider") Report.result(Tests.find_pxentity, pxentity.IsValid()) From 059f69e5e639a006b3cefaaa64b7055770d5c93a Mon Sep 17 00:00:00 2001 From: greerdv Date: Wed, 12 May 2021 21:20:23 +0100 Subject: [PATCH 157/225] tidy up NonUniformScaleService compatibility --- .../Components/NonUniformScaleComponent.cpp | 23 ------------------- .../EditorNonUniformScaleComponent.cpp | 23 ------------------- .../Code/Source/DebugDrawObbComponent.cpp | 2 +- .../Integration/Components/ActorComponent.h | 1 + .../Components/SimpleMotionComponent.h | 1 + .../Components/GradientTransformComponent.cpp | 1 + .../Source/Shape/CapsuleShapeComponent.cpp | 1 + .../Source/Shape/CompoundShapeComponent.h | 1 + .../Source/Shape/CylinderShapeComponent.cpp | 1 + .../Code/Source/Shape/DiskShapeComponent.cpp | 1 + .../Shape/EditorCapsuleShapeComponent.cpp | 6 +++++ .../Shape/EditorCapsuleShapeComponent.h | 2 ++ .../Shape/EditorCompoundShapeComponent.cpp | 6 +++++ .../Shape/EditorCompoundShapeComponent.h | 2 ++ .../Shape/EditorCylinderShapeComponent.cpp | 6 +++++ .../Shape/EditorCylinderShapeComponent.h | 2 ++ .../Source/Shape/EditorDiskShapeComponent.cpp | 6 +++++ .../Source/Shape/EditorDiskShapeComponent.h | 1 + .../Shape/EditorSphereShapeComponent.cpp | 6 +++++ .../Source/Shape/EditorSphereShapeComponent.h | 2 ++ .../Source/Shape/EditorSplineComponent.cpp | 1 + .../Source/Shape/EditorTubeShapeComponent.cpp | 6 +++++ .../Source/Shape/EditorTubeShapeComponent.h | 1 + .../Source/Shape/SphereShapeComponent.cpp | 1 + .../Code/Source/Shape/SplineComponent.h | 1 + .../Code/Source/Shape/TubeShapeComponent.cpp | 1 + .../Components/EditorSequenceComponent.h | 1 + .../Source/Components/SequenceComponent.cpp | 5 ++++ .../Source/Components/SequenceComponent.h | 2 ++ .../Code/Source/Components/ClothComponent.cpp | 5 ++++ .../Code/Source/Components/ClothComponent.h | 1 + .../Components/EditorClothComponent.cpp | 5 ++++ .../Source/Components/EditorClothComponent.h | 1 + .../Code/Source/EditorBallJointComponent.cpp | 5 ++++ .../Code/Source/EditorBallJointComponent.h | 1 + .../Code/Source/EditorFixedJointComponent.cpp | 5 ++++ .../Code/Source/EditorFixedJointComponent.h | 1 + .../Code/Source/EditorHingeJointComponent.cpp | 5 ++++ .../Code/Source/EditorHingeJointComponent.h | 1 + .../Components/CharacterControllerComponent.h | 1 + .../Components/CharacterGameplayComponent.cpp | 1 + .../EditorCharacterControllerComponent.h | 1 + .../EditorCharacterGameplayComponent.cpp | 1 + .../Components/RagdollComponent.h | 1 + .../EditorWhiteBoxColliderComponent.cpp | 5 ++++ .../EditorWhiteBoxColliderComponent.h | 1 + .../Components/WhiteBoxColliderComponent.cpp | 5 ++++ .../Components/WhiteBoxColliderComponent.h | 1 + .../Code/Source/EditorWhiteBoxComponent.cpp | 5 ++++ .../Code/Source/EditorWhiteBoxComponent.h | 1 + 50 files changed, 119 insertions(+), 47 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp index 57f14ddb38..d51f3645d3 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp @@ -37,29 +37,6 @@ namespace AzFramework void NonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); - - incompatible.push_back(AZ_CRC_CE("DebugDrawObbService")); - incompatible.push_back(AZ_CRC_CE("DebugDrawService")); - incompatible.push_back(AZ_CRC_CE("EMotionFXActorService")); - incompatible.push_back(AZ_CRC_CE("EMotionFXSimpleMotionService")); - incompatible.push_back(AZ_CRC_CE("GradientTransformService")); - incompatible.push_back(AZ_CRC_CE("LegacyMeshService")); - incompatible.push_back(AZ_CRC_CE("LookAtService")); - incompatible.push_back(AZ_CRC_CE("SequenceService")); - incompatible.push_back(AZ_CRC_CE("ClothMeshService")); - incompatible.push_back(AZ_CRC_CE("PhysXJointService")); - incompatible.push_back(AZ_CRC_CE("PhysXCharacterControllerService")); - incompatible.push_back(AZ_CRC_CE("PhysXRagdollService")); - incompatible.push_back(AZ_CRC_CE("WhiteBoxService")); - incompatible.push_back(AZ_CRC_CE("NavigationAreaService")); - incompatible.push_back(AZ_CRC_CE("GeometryService")); - incompatible.push_back(AZ_CRC_CE("CapsuleShapeService")); - incompatible.push_back(AZ_CRC_CE("CompoundShapeService")); - incompatible.push_back(AZ_CRC_CE("CylinderShapeService")); - incompatible.push_back(AZ_CRC_CE("DiskShapeService")); - incompatible.push_back(AZ_CRC_CE("SphereShapeService")); - incompatible.push_back(AZ_CRC_CE("SplineService")); - incompatible.push_back(AZ_CRC_CE("TubeShapeService")); } void NonUniformScaleComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp index 989398f196..a61f042049 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp @@ -63,29 +63,6 @@ namespace AzToolsFramework void EditorNonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); - - incompatible.push_back(AZ_CRC_CE("DebugDrawObbService")); - incompatible.push_back(AZ_CRC_CE("DebugDrawService")); - incompatible.push_back(AZ_CRC_CE("EMotionFXActorService")); - incompatible.push_back(AZ_CRC_CE("EMotionFXSimpleMotionService")); - incompatible.push_back(AZ_CRC_CE("GradientTransformService")); - incompatible.push_back(AZ_CRC_CE("LegacyMeshService")); - incompatible.push_back(AZ_CRC_CE("LookAtService")); - incompatible.push_back(AZ_CRC_CE("SequenceService")); - incompatible.push_back(AZ_CRC_CE("ClothMeshService")); - incompatible.push_back(AZ_CRC_CE("PhysXJointService")); - incompatible.push_back(AZ_CRC_CE("PhysXCharacterControllerService")); - incompatible.push_back(AZ_CRC_CE("PhysXRagdollService")); - incompatible.push_back(AZ_CRC_CE("WhiteBoxService")); - incompatible.push_back(AZ_CRC_CE("NavigationAreaService")); - incompatible.push_back(AZ_CRC_CE("GeometryService")); - incompatible.push_back(AZ_CRC_CE("CapsuleShapeService")); - incompatible.push_back(AZ_CRC_CE("CompoundShapeService")); - incompatible.push_back(AZ_CRC_CE("CylinderShapeService")); - incompatible.push_back(AZ_CRC_CE("DiskShapeService")); - incompatible.push_back(AZ_CRC_CE("SphereShapeService")); - incompatible.push_back(AZ_CRC_CE("SplineService")); - incompatible.push_back(AZ_CRC_CE("TubeShapeService")); } void EditorNonUniformScaleComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) diff --git a/Gems/DebugDraw/Code/Source/DebugDrawObbComponent.cpp b/Gems/DebugDraw/Code/Source/DebugDrawObbComponent.cpp index df13bb56ce..72bbaba2b7 100644 --- a/Gems/DebugDraw/Code/Source/DebugDrawObbComponent.cpp +++ b/Gems/DebugDraw/Code/Source/DebugDrawObbComponent.cpp @@ -71,7 +71,7 @@ namespace DebugDraw void DebugDrawObbComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - (void)incompatible; + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void DebugDrawObbComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h index 416705bff4..8188da19b4 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h +++ b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h @@ -136,6 +136,7 @@ namespace EMotionFX { incompatible.push_back(AZ_CRC("EMotionFXActorService", 0xd6e8f48d)); incompatible.push_back(AZ_CRC("MeshService", 0x71d8a455)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/SimpleMotionComponent.h b/Gems/EMotionFX/Code/Source/Integration/Components/SimpleMotionComponent.h index 5f5066b9bb..6820bfe33f 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/SimpleMotionComponent.h +++ b/Gems/EMotionFX/Code/Source/Integration/Components/SimpleMotionComponent.h @@ -87,6 +87,7 @@ namespace EMotionFX { incompatible.push_back(AZ_CRC("EMotionFXAnimGraphService", 0x9ec3c819)); incompatible.push_back(AZ_CRC("EMotionFXSimpleMotionService", 0xea7a05d8)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } static void Reflect(AZ::ReflectContext* /*context*/); diff --git a/Gems/GradientSignal/Code/Source/Components/GradientTransformComponent.cpp b/Gems/GradientSignal/Code/Source/Components/GradientTransformComponent.cpp index 0b967a6957..f99a8a8dfb 100644 --- a/Gems/GradientSignal/Code/Source/Components/GradientTransformComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/GradientTransformComponent.cpp @@ -200,6 +200,7 @@ namespace GradientSignal void GradientTransformComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) { services.push_back(AZ_CRC("GradientTransformService", 0x8c8c5ecc)); + services.push_back(AZ_CRC_CE("NonUniformScaleService")); } void GradientTransformComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services) diff --git a/Gems/LmbrCentral/Code/Source/Shape/CapsuleShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/CapsuleShapeComponent.cpp index 46eb69dbd8..2341f93dbb 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/CapsuleShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/CapsuleShapeComponent.cpp @@ -32,6 +32,7 @@ namespace LmbrCentral { incompatible.push_back(AZ_CRC("ShapeService", 0xe86aa5fe)); incompatible.push_back(AZ_CRC("CapsuleShapeService", 0x9bc1122c)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void CapsuleShapeComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/LmbrCentral/Code/Source/Shape/CompoundShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/CompoundShapeComponent.h index 25204cd4c0..1000609cf3 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/CompoundShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/CompoundShapeComponent.h @@ -76,6 +76,7 @@ namespace LmbrCentral { incompatible.push_back(AZ_CRC("ShapeService", 0xe86aa5fe)); incompatible.push_back(AZ_CRC("CompoundShapeService", 0x4f7c640a)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } static void Reflect(AZ::ReflectContext* context); diff --git a/Gems/LmbrCentral/Code/Source/Shape/CylinderShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/CylinderShapeComponent.cpp index 493cdef3e8..ff4ae9a9c5 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/CylinderShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/CylinderShapeComponent.cpp @@ -31,6 +31,7 @@ namespace LmbrCentral { incompatible.push_back(AZ_CRC("ShapeService", 0xe86aa5fe)); incompatible.push_back(AZ_CRC("CylinderShapeService", 0x507c688e)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void CylinderShapeComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/LmbrCentral/Code/Source/Shape/DiskShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/DiskShapeComponent.cpp index 2d0673f299..f4a0f778c5 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/DiskShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/DiskShapeComponent.cpp @@ -28,6 +28,7 @@ namespace LmbrCentral { incompatible.push_back(AZ_CRC("ShapeService", 0xe86aa5fe)); incompatible.push_back(AZ_CRC("DiskShapeService", 0xd90c482b)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void DiskShapeComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorCapsuleShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorCapsuleShapeComponent.cpp index 93fdfae29f..6c37d2f1ec 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorCapsuleShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorCapsuleShapeComponent.cpp @@ -78,6 +78,12 @@ namespace LmbrCentral EditorBaseShapeComponent::Deactivate(); } + void EditorCapsuleShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + EditorBaseShapeComponent::GetIncompatibleServices(incompatible); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorCapsuleShapeComponent::DisplayEntityViewport( [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorCapsuleShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/EditorCapsuleShapeComponent.h index 6bb34b1b9e..3accb8f29d 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorCapsuleShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorCapsuleShapeComponent.h @@ -40,6 +40,8 @@ namespace LmbrCentral provided.push_back(AZ_CRC("CapsuleShapeService", 0x9bc1122c)); } + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + // EditorComponentBase void BuildGameEntity(AZ::Entity* gameEntity) override; diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorCompoundShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorCompoundShapeComponent.cpp index c61f54ab08..18957fae36 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorCompoundShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorCompoundShapeComponent.cpp @@ -59,6 +59,12 @@ namespace LmbrCentral } } + void EditorCompoundShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + EditorBaseShapeComponent::GetIncompatibleServices(incompatible); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorCompoundShapeComponent::Init() { // setup the contained runtime component so that it can manage the child entities in the editor. diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorCompoundShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/EditorCompoundShapeComponent.h index 24f06ee336..c725c2ef34 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorCompoundShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorCompoundShapeComponent.h @@ -41,6 +41,8 @@ namespace LmbrCentral provided.push_back(AZ_CRC("CompoundShapeService", 0x4f7c640a)); } + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + AZ::u32 ConfigurationChanged(); private: diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorCylinderShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorCylinderShapeComponent.cpp index 89de8410f5..fe5a525fa8 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorCylinderShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorCylinderShapeComponent.cpp @@ -55,6 +55,12 @@ namespace LmbrCentral } } + void EditorCylinderShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + EditorBaseShapeComponent::GetIncompatibleServices(incompatible); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorCylinderShapeComponent::Init() { EditorBaseShapeComponent::Init(); diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorCylinderShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/EditorCylinderShapeComponent.h index a34ec6f548..3bbcf3286b 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorCylinderShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorCylinderShapeComponent.h @@ -40,6 +40,8 @@ namespace LmbrCentral provided.push_back(AZ_CRC("CylinderShapeService", 0x507c688e)); } + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + // EditorComponentBase void BuildGameEntity(AZ::Entity* gameEntity) override; diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorDiskShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorDiskShapeComponent.cpp index 3d6181cde6..c1bfc04e7d 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorDiskShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorDiskShapeComponent.cpp @@ -55,6 +55,12 @@ namespace LmbrCentral provided.push_back(AZ_CRC("DiskShapeService", 0xd90c482b)); } + void EditorDiskShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + EditorBaseShapeComponent::GetIncompatibleServices(incompatible); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorDiskShapeComponent::Init() { EditorBaseShapeComponent::Init(); diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorDiskShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/EditorDiskShapeComponent.h index 1d20f2a338..d936a4a9ec 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorDiskShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorDiskShapeComponent.h @@ -39,6 +39,7 @@ namespace LmbrCentral protected: static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); private: AZ_DISABLE_COPY_MOVE(EditorDiskShapeComponent) diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorSphereShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorSphereShapeComponent.cpp index 0d9885191d..0323ec2dfe 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorSphereShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorSphereShapeComponent.cpp @@ -60,6 +60,12 @@ namespace LmbrCentral } } + void EditorSphereShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + EditorBaseShapeComponent::GetIncompatibleServices(incompatible); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorSphereShapeComponent::Init() { EditorBaseShapeComponent::Init(); diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorSphereShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/EditorSphereShapeComponent.h index f4a80d91ed..48f1d6cb2e 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorSphereShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorSphereShapeComponent.h @@ -44,6 +44,8 @@ namespace LmbrCentral provided.push_back(AZ_CRC("SphereShapeService", 0x90c8dc80)); } + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + private: AZ_DISABLE_COPY_MOVE(EditorSphereShapeComponent) diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorSplineComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorSplineComponent.cpp index 144713c8ec..212ec49c93 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorSplineComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorSplineComponent.cpp @@ -44,6 +44,7 @@ namespace LmbrCentral { incompatible.push_back(AZ_CRC("VariableVertexContainerService", 0x70c58740)); incompatible.push_back(AZ_CRC("FixedVertexContainerService", 0x83f1bbf2)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void EditorSplineComponent::Reflect(AZ::ReflectContext* context) diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponent.cpp index c8c03e2811..6ffb9e3308 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponent.cpp @@ -59,6 +59,12 @@ namespace LmbrCentral } } + void EditorTubeShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + EditorBaseShapeComponent::GetIncompatibleServices(incompatible); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorTubeShapeComponent::Init() { EditorBaseShapeComponent::Init(); diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponent.h index b7b57310e5..6ffe7e9b73 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponent.h @@ -57,6 +57,7 @@ namespace LmbrCentral required.push_back(AZ_CRC("SplineService", 0x2b674d3c)); } + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); private: AZ_DISABLE_COPY_MOVE(EditorTubeShapeComponent) diff --git a/Gems/LmbrCentral/Code/Source/Shape/SphereShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/SphereShapeComponent.cpp index 3bddc9b695..7faa455398 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/SphereShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/SphereShapeComponent.cpp @@ -29,6 +29,7 @@ namespace LmbrCentral { incompatible.push_back(AZ_CRC("ShapeService", 0xe86aa5fe)); incompatible.push_back(AZ_CRC("SphereShapeService", 0x90c8dc80)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void SphereShapeComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/LmbrCentral/Code/Source/Shape/SplineComponent.h b/Gems/LmbrCentral/Code/Source/Shape/SplineComponent.h index eaa3fde457..f4cd73574b 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/SplineComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/SplineComponent.h @@ -103,6 +103,7 @@ namespace LmbrCentral incompatible.push_back(AZ_CRC("SplineService", 0x2b674d3c)); incompatible.push_back(AZ_CRC("VariableVertexContainerService", 0x70c58740)); incompatible.push_back(AZ_CRC("FixedVertexContainerService", 0x83f1bbf2)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp index f757da2107..014612daa1 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/TubeShapeComponent.cpp @@ -28,6 +28,7 @@ namespace LmbrCentral { incompatible.push_back(AZ_CRC("ShapeService", 0xe86aa5fe)); incompatible.push_back(AZ_CRC("TubeShapeService", 0x3fe791b4)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void TubeShapeComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/Maestro/Code/Source/Components/EditorSequenceComponent.h b/Gems/Maestro/Code/Source/Components/EditorSequenceComponent.h index 294f7b4370..f5689f3f65 100644 --- a/Gems/Maestro/Code/Source/Components/EditorSequenceComponent.h +++ b/Gems/Maestro/Code/Source/Components/EditorSequenceComponent.h @@ -98,6 +98,7 @@ namespace Maestro { // This guarantees that only one SequenceComponent will ever be on an entity incompatible.push_back(AZ_CRC("SequenceService", 0x7cbe5938)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } // Required Reflect function. diff --git a/Gems/Maestro/Code/Source/Components/SequenceComponent.cpp b/Gems/Maestro/Code/Source/Components/SequenceComponent.cpp index c1470ccf15..f1951c12a3 100644 --- a/Gems/Maestro/Code/Source/Components/SequenceComponent.cpp +++ b/Gems/Maestro/Code/Source/Components/SequenceComponent.cpp @@ -139,6 +139,11 @@ namespace Maestro } } + void SequenceComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void SequenceComponent::ReflectCinematicsLib(AZ::ReflectContext* context) { // The Movie System itself diff --git a/Gems/Maestro/Code/Source/Components/SequenceComponent.h b/Gems/Maestro/Code/Source/Components/SequenceComponent.h index 20e7d22fe3..48cd7f25c9 100644 --- a/Gems/Maestro/Code/Source/Components/SequenceComponent.h +++ b/Gems/Maestro/Code/Source/Components/SequenceComponent.h @@ -97,6 +97,8 @@ namespace Maestro provided.push_back(AZ_CRC("SequenceService", 0x7cbe5938)); } + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + // Required Reflect function. static void Reflect(AZ::ReflectContext* context); private: diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp index ddd2d6fa36..912255c798 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp @@ -47,6 +47,11 @@ namespace NvCloth required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); } + void ClothComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void ClothComponent::Activate() { // Cloth components do not run on dedicated servers. diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponent.h b/Gems/NvCloth/Code/Source/Components/ClothComponent.h index 9b8458d276..bb7a645b61 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponent.h +++ b/Gems/NvCloth/Code/Source/Components/ClothComponent.h @@ -38,6 +38,7 @@ namespace NvCloth static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); const ClothComponentMesh* GetClothComponentMesh() const { return m_clothComponentMesh.get(); } diff --git a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp index 4705a9f2c2..1254a13cb2 100644 --- a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp +++ b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.cpp @@ -415,6 +415,11 @@ namespace NvCloth required.push_back(AZ_CRC("MeshService", 0x71d8a455)); } + void EditorClothComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + const MeshNodeList& EditorClothComponent::GetMeshNodeList() const { return m_meshNodeList; diff --git a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.h b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.h index 9727895a43..2ef3123942 100644 --- a/Gems/NvCloth/Code/Source/Components/EditorClothComponent.h +++ b/Gems/NvCloth/Code/Source/Components/EditorClothComponent.h @@ -39,6 +39,7 @@ namespace NvCloth static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); const MeshNodeList& GetMeshNodeList() const; const AZStd::unordered_set& GetMeshNodesWithBackstopData() const; diff --git a/Gems/PhysX/Code/Source/EditorBallJointComponent.cpp b/Gems/PhysX/Code/Source/EditorBallJointComponent.cpp index f3bdb83325..deb1d0d231 100644 --- a/Gems/PhysX/Code/Source/EditorBallJointComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorBallJointComponent.cpp @@ -63,6 +63,11 @@ namespace PhysX required.push_back(AZ_CRC("PhysXRigidBodyService", 0x1d4c64a8)); } + void EditorBallJointComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorBallJointComponent::Activate() { EditorJointComponent::Activate(); diff --git a/Gems/PhysX/Code/Source/EditorBallJointComponent.h b/Gems/PhysX/Code/Source/EditorBallJointComponent.h index fbff44b38e..44f96b3fa8 100644 --- a/Gems/PhysX/Code/Source/EditorBallJointComponent.h +++ b/Gems/PhysX/Code/Source/EditorBallJointComponent.h @@ -33,6 +33,7 @@ namespace PhysX static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); // AZ::Component void Activate() override; diff --git a/Gems/PhysX/Code/Source/EditorFixedJointComponent.cpp b/Gems/PhysX/Code/Source/EditorFixedJointComponent.cpp index a2b496672c..1645d8c932 100644 --- a/Gems/PhysX/Code/Source/EditorFixedJointComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorFixedJointComponent.cpp @@ -60,6 +60,11 @@ namespace PhysX required.push_back(AZ_CRC("PhysXRigidBodyService", 0x1d4c64a8)); } + void EditorFixedJointComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorFixedJointComponent::Activate() { EditorJointComponent::Activate(); diff --git a/Gems/PhysX/Code/Source/EditorFixedJointComponent.h b/Gems/PhysX/Code/Source/EditorFixedJointComponent.h index c66ba661be..8642f83472 100644 --- a/Gems/PhysX/Code/Source/EditorFixedJointComponent.h +++ b/Gems/PhysX/Code/Source/EditorFixedJointComponent.h @@ -33,6 +33,7 @@ namespace PhysX static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); // AZ::Component void Activate() override; diff --git a/Gems/PhysX/Code/Source/EditorHingeJointComponent.cpp b/Gems/PhysX/Code/Source/EditorHingeJointComponent.cpp index fde1ff980b..6d136e898b 100644 --- a/Gems/PhysX/Code/Source/EditorHingeJointComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorHingeJointComponent.cpp @@ -63,6 +63,11 @@ namespace PhysX required.push_back(AZ_CRC("PhysXRigidBodyService", 0x1d4c64a8)); } + void EditorHingeJointComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorHingeJointComponent::Activate() { EditorJointComponent::Activate(); diff --git a/Gems/PhysX/Code/Source/EditorHingeJointComponent.h b/Gems/PhysX/Code/Source/EditorHingeJointComponent.h index 3b3182068b..ef555d145e 100644 --- a/Gems/PhysX/Code/Source/EditorHingeJointComponent.h +++ b/Gems/PhysX/Code/Source/EditorHingeJointComponent.h @@ -33,6 +33,7 @@ namespace PhysX static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); // AZ::Component void Activate() override; diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h index 31f5051ac4..a7a1a92ad2 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h @@ -59,6 +59,7 @@ namespace PhysX static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("PhysXCharacterControllerService", 0x428de4fa)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterGameplayComponent.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterGameplayComponent.cpp index 70373f8db2..d557919627 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterGameplayComponent.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterGameplayComponent.cpp @@ -51,6 +51,7 @@ namespace PhysX void CharacterGameplayComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("PhysXCharacterGameplayService", 0xfacd7876)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void CharacterGameplayComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/EditorCharacterControllerComponent.h b/Gems/PhysX/Code/Source/PhysXCharacters/Components/EditorCharacterControllerComponent.h index d42c1c9537..cc2a93d0b8 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/EditorCharacterControllerComponent.h +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/EditorCharacterControllerComponent.h @@ -64,6 +64,7 @@ namespace PhysX incompatible.push_back(AZ_CRC("PhysXCharacterControllerService", 0x428de4fa)); incompatible.push_back(AZ_CRC("LegacyCryPhysicsService", 0xbb370351)); incompatible.push_back(AZ_CRC("PhysXRigidBodyService", 0x1d4c64a8)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/EditorCharacterGameplayComponent.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/Components/EditorCharacterGameplayComponent.cpp index 03ff0e0aea..dc67870fb2 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/EditorCharacterGameplayComponent.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/EditorCharacterGameplayComponent.cpp @@ -23,6 +23,7 @@ namespace PhysX void EditorCharacterGameplayComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("PhysXCharacterGameplayService", 0xfacd7876)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void EditorCharacterGameplayComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.h b/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.h index e7397af877..a02e9c47fb 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.h +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.h @@ -49,6 +49,7 @@ namespace PhysX { incompatible.push_back(AZ_CRC("PhysXRagdollService", 0x6d889c70)); incompatible.push_back(AZ_CRC("LegacyCryPhysicsService", 0xbb370351)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.cpp b/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.cpp index 6e2e4be0a2..97bce7631d 100644 --- a/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.cpp +++ b/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.cpp @@ -75,6 +75,11 @@ namespace WhiteBox required.push_back(AZ_CRC("WhiteBoxService", 0x2f2f42b8)); } + void EditorWhiteBoxColliderComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void EditorWhiteBoxColliderComponent::Activate() { AzToolsFramework::Components::EditorComponentBase::Activate(); diff --git a/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.h b/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.h index 5b46d0b99e..635abbb1bd 100644 --- a/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.h +++ b/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.h @@ -46,6 +46,7 @@ namespace WhiteBox private: static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); // AZ::Component ... void Activate() override; diff --git a/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.cpp b/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.cpp index 3179a2cd72..117b175cda 100644 --- a/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.cpp +++ b/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.cpp @@ -44,6 +44,11 @@ namespace WhiteBox required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); } + void WhiteBoxColliderComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + WhiteBoxColliderComponent::WhiteBoxColliderComponent( const Physics::CookedMeshShapeConfiguration& shapeConfiguration, const Physics::ColliderConfiguration& physicsColliderConfiguration, diff --git a/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.h b/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.h index 1ad773652d..0b50c834d8 100644 --- a/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.h +++ b/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.h @@ -41,6 +41,7 @@ namespace WhiteBox private: static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); // AZ::Component ... void Activate() override; diff --git a/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp b/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp index d4ab543404..e8e03556e2 100644 --- a/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp +++ b/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp @@ -265,6 +265,11 @@ namespace WhiteBox provided.push_back(AZ_CRC("WhiteBoxService", 0x2f2f42b8)); } + void EditorWhiteBoxComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + EditorWhiteBoxComponent::EditorWhiteBoxComponent() = default; EditorWhiteBoxComponent::~EditorWhiteBoxComponent() diff --git a/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.h b/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.h index 02b50a9407..c4dd6c2b0b 100644 --- a/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.h +++ b/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.h @@ -89,6 +89,7 @@ namespace WhiteBox private: static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); // EditorComponentBase overrides ... void BuildGameEntity(AZ::Entity* gameEntity) override; From 7bdf44a0996b93bea061c5146e5627e7abbb8b21 Mon Sep 17 00:00:00 2001 From: srikappa Date: Wed, 12 May 2021 13:38:44 -0700 Subject: [PATCH 158/225] Detect cyclical dependencies in the nested prefabs of the prefab being instantiated --- .../Prefab/PrefabDomUtils.cpp | 37 ++++++++++++++++ .../AzToolsFramework/Prefab/PrefabDomUtils.h | 14 +++++++ .../Prefab/PrefabPublicHandler.cpp | 42 ++++++++++--------- .../Prefab/PrefabPublicHandler.h | 18 ++++---- 4 files changed, 84 insertions(+), 27 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index 0bffd26be0..145a293ab8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -199,6 +199,43 @@ namespace AzToolsFramework return true; } + void GetTemplateSourcePaths(const PrefabDomValue& prefabDom, AZStd::unordered_set& templateSourcePaths) + { + PrefabDomValueConstReference findSourceResult = PrefabDomUtils::FindPrefabDomValue(prefabDom, PrefabDomUtils::SourceName); + if (!findSourceResult.has_value() || !(findSourceResult->get().IsString()) || + findSourceResult->get().GetStringLength() == 0) + { + AZ_Assert( + false, + "PrefabDomUtils::GetDependentTemplatePath - Source value of prefab in the provided DOM is not a valid string."); + return; + } + + templateSourcePaths.emplace(findSourceResult->get().GetString()); + PrefabDomValueConstReference instancesReference = GetInstancesValue(prefabDom); + if (instancesReference.has_value()) + { + const PrefabDomValue& instances = instancesReference->get(); + + for (PrefabDomValue::ConstMemberIterator instanceIterator = instances.MemberBegin(); + instanceIterator != instances.MemberEnd(); ++instanceIterator) + { + GetTemplateSourcePaths(instanceIterator->value, templateSourcePaths); + } + } + } + + PrefabDomValueConstReference GetInstancesValue(const PrefabDomValue& prefabDom) + { + PrefabDomValueConstReference findInstancesResult = FindPrefabDomValue(prefabDom, PrefabDomUtils::InstancesName); + if (!findInstancesResult.has_value() || !(findInstancesResult->get().IsObject())) + { + return AZStd::nullopt; + } + + return findInstancesResult->get(); + } + void PrintPrefabDomValue( [[maybe_unused]] const AZStd::string_view printMessage, [[maybe_unused]] const PrefabDomValue& prefabDomValue) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index c7c2827770..6f7d2fe9b1 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -100,6 +100,20 @@ namespace AzToolsFramework .Append(instanceName); }; + /** + * Gets a set of all the template source paths in the given dom. + * @param prefabDom The DOM to get the template source paths from. + * @param templateSourcePaths The set of template source paths to populate. + */ + void GetTemplateSourcePaths(const PrefabDomValue& prefabDom, AZStd::unordered_set& templateSourcePaths); + + /** + * Gets the instances DOM value from the given prefab DOM. + * + * @return the instances DOM value or AZStd::nullopt if it instances can't be found. + */ + PrefabDomValueConstReference GetInstancesValue(const PrefabDomValue& prefabDom); + /** * Prints the contents of the given prefab DOM value to the debug output console in a readable format. * @param printMessage The message that will be printed before printing the PrefabDomValue diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 14537683ef..e2c616d5d8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -191,25 +191,30 @@ namespace AzToolsFramework auto relativePath = m_prefabLoaderInterface->GetRelativePathToProject(filePath); Prefab::TemplateId templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(relativePath); - // If the template isn't currently loaded, there's no way for it to be in the hierarchy so we just skip the check. - if (templateId != Prefab::InvalidTemplateId && IsPrefabInInstanceAncestorHierarchy(templateId, instanceToParentUnder->get())) + if (templateId == InvalidTemplateId) { - return AZ::Failure( - AZStd::string::format( - "Instantiate Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).", - relativePath.Native().c_str(), - instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str() - ) - ); + // Load the template from the file + templateId = m_prefabLoaderInterface->LoadTemplateFromFile(filePath); + AZ_Assert(templateId != InvalidTemplateId, "Template with source path %s couldn't be loaded correctly.", filePath); } - + + const PrefabDom& templateDom = m_prefabSystemComponentInterface->FindTemplateDom(templateId); + AZStd::unordered_set templatePaths; + PrefabDomUtils::GetTemplateSourcePaths(templateDom, templatePaths); + + if (IsCyclicalDependencyFound(instanceToParentUnder->get(), templatePaths)) + { + return AZ::Failure(AZStd::string::format( + "Instantiate Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).", + relativePath.Native().c_str(), instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str())); + } + { // Initialize Undo Batch object ScopedUndoBatch undoBatch("Instantiate Prefab"); PrefabDom instanceToParentUnderDomBeforeCreate; - m_instanceToTemplateInterface->GenerateDomForInstance( - instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get()); + m_instanceToTemplateInterface->GenerateDomForInstance(instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get()); // Instantiate the Prefab auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(relativePath, instanceToParentUnder); @@ -223,8 +228,7 @@ namespace AzToolsFramework PrefabUndoHelpers::UpdatePrefabInstance( instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch()); - CreateLink({}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), - undoBatch.GetUndoBatch(), parent); + CreateLink({}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), undoBatch.GetUndoBatch(), parent); AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId(); // Apply position @@ -277,17 +281,17 @@ namespace AzToolsFramework return AZ::Success(); } - bool PrefabPublicHandler::IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance) + bool PrefabPublicHandler::IsCyclicalDependencyFound( + InstanceOptionalConstReference instance, AZStd::unordered_set& templateSourcePaths) { InstanceOptionalConstReference currentInstance = instance; while (currentInstance.has_value()) { - if (currentInstance->get().GetTemplateId() == prefabTemplateId) + if (templateSourcePaths.contains(currentInstance->get().GetTemplateSourcePath())) { return true; } - currentInstance = currentInstance->get().GetParentInstance(); } @@ -966,5 +970,5 @@ namespace AzToolsFramework return true; } - } -} + } // namespace Prefab +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 03b3827328..519c7ca53f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -12,8 +12,8 @@ #pragma once -#include #include +#include #include #include @@ -106,13 +106,15 @@ namespace AzToolsFramework const AZStd::vector& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities, AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance); - /* Detects whether an instance of prefabTemplateId is present in the hierarchy of ancestors of instance. + /* Checks whether the template source path of any of the ancestors in the instance hierarchy matches with one of the + * paths provided in a set. * - * \param prefabTemplateId The template id to test for - * \param instance The instance whose ancestor hierarchy prefabTemplateId will be tested against. - * \return true if an instance of the template of id prefabTemplateId could be found in the ancestor hierarchy of instance, false otherwise. + * \param instance The instance whose ancestor hierarchy the provided set of template source paths will be tested against. + * \param templateSourcePaths The template source paths provided to be checked against the instance ancestor hierarchy. + * \return true if any of the template source paths could be found in the ancestor hierarchy of instance, false otherwise. */ - bool IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance); + bool IsCyclicalDependencyFound( + InstanceOptionalConstReference instance, AZStd::unordered_set& templateSourcePaths); static Instance* GetParentInstance(Instance* instance); static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant); @@ -128,5 +130,5 @@ namespace AzToolsFramework uint64_t m_newEntityCounter = 1; }; - } -} + } // namespace Prefab +} // namespace AzToolsFramework From d0b006c209573e0be961b6bc27fd3bde1cbaf3ad Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 13:41:18 -0700 Subject: [PATCH 159/225] Some cleanup to better support backward reconciliation as well as dynamic player spawning on connect --- Code/CryEngine/CrySystem/SystemInit.cpp | 2 +- Gems/Multiplayer/Code/Include/IMultiplayer.h | 79 +++++++++++++++++-- .../Code/Include/INetworkEntityManager.h | 42 +++++----- Gems/Multiplayer/Code/Include/INetworkTime.h | 34 ++------ .../AutoGen/AutoComponentTypes_Source.jinja | 2 +- .../Source/AutoGen/AutoComponent_Source.jinja | 23 ++++-- .../LocalPredictionPlayerInputComponent.cpp | 6 +- .../Source/MultiplayerSystemComponent.cpp | 73 ++++++++++++----- .../Code/Source/MultiplayerSystemComponent.h | 5 ++ .../EntityReplicationManager.cpp | 2 +- .../EntityReplication/EntityReplicator.cpp | 4 +- .../NetworkEntity/NetworkEntityManager.cpp | 29 +++++-- .../NetworkEntity/NetworkEntityManager.h | 19 +++-- .../Source/NetworkInput/NetworkInputChild.cpp | 2 +- .../NetworkInputMigrationVector.cpp | 2 +- .../Code/Source/NetworkTime/NetworkTime.cpp | 52 ++++++++---- .../Code/Source/NetworkTime/NetworkTime.h | 7 +- .../Source/NetworkTime/RewindableObject.inl | 4 +- .../ServerToClientReplicationWindow.cpp | 2 +- .../ServerToClientReplicationWindow.h | 2 +- 20 files changed, 262 insertions(+), 129 deletions(-) diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index 8bf2fb8930..6181fde615 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -1247,7 +1247,7 @@ bool CSystem::InitShine([[maybe_unused]] const SSystemInitParams& initParams) if (!m_env.pLyShine) { - AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "LYShine System did not initialize correctly. Please check that the LyShine gem is enabled for this project in ProjectConfigurator."); + AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "LYShine System did not initialize correctly. Please check that the LyShine gem is enabled for this project in *_dependencies.cmake."); return false; } return true; diff --git a/Gems/Multiplayer/Code/Include/IMultiplayer.h b/Gems/Multiplayer/Code/Include/IMultiplayer.h index 039b86b2a6..80bdaa68eb 100644 --- a/Gems/Multiplayer/Code/Include/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/IMultiplayer.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ namespace Multiplayer using ConnectionAcquiredEvent = AZ::Event; using SessionInitEvent = AZ::Event; using SessionShutdownEvent = AZ::Event; + using OnConnectFunctor = AZStd::function; //! IMultiplayer provides insight into the Multiplayer session and its Agents class IMultiplayer @@ -55,26 +57,30 @@ namespace Multiplayer virtual ~IMultiplayer() = default; - //! Gets the type of Agent this IMultiplayer impl represents + //! Gets the type of Agent this IMultiplayer impl represents. //! @return The type of agents represented virtual MultiplayerAgentType GetAgentType() const = 0; - //! Sets the type of this Multiplayer connection and calls any related callback + //! Sets the type of this Multiplayer connection and calls any related callback. //! @param state The state of this connection virtual void InitializeMultiplayer(MultiplayerAgentType state) = 0; - //! Adds a ConnectionAcquiredEvent Handler which is invoked when a new endpoint connects to the session + //! Adds a ConnectionAcquiredEvent Handler which is invoked when a new endpoint connects to the session. //! @param handler The SessionInitEvent Handler to add virtual void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) = 0; - //! Adds a SessionInitEvent Handler which is invoked when a new network session starts + //! Adds a SessionInitEvent Handler which is invoked when a new network session starts. //! @param handler The SessionInitEvent Handler to add virtual void AddSessionInitHandler(SessionInitEvent::Handler& handler) = 0; - //! Adds a SessionShutdownEvent Handler which is invoked when the current network session ends + //! Adds a SessionShutdownEvent Handler which is invoked when the current network session ends. //! @param handler The SessionShutdownEvent handler to add virtual void AddSessionShutdownHandler(SessionShutdownEvent::Handler& handler) = 0; + //! Overrides the default connect behaviour with the provided functor. + //! @param functor the function to invoke during a new connection event + virtual void SetOnConnectFunctor(const OnConnectFunctor& functor) = 0; + //! Sends a packet telling if entity update messages can be sent //! @param readyForEntityUpdates Ready for entity updates or not virtual void SendReadyForEntityUpdates(bool readyForEntityUpdates) = 0; @@ -87,6 +93,14 @@ namespace Multiplayer //! @return the current server time in milliseconds virtual AZ::TimeMs GetCurrentHostTimeMs() const = 0; + //! Returns the network time instance bound to this multiplayer instance. + //! @return pointer to the network time instance bound to this multiplayer instance + virtual INetworkTime* GetNetworkTime() = 0; + + //! Returns the network entity manager instance bound to this multiplayer instance. + //! @return pointer to the network entity manager instance bound to this multiplayer instance + virtual INetworkEntityManager* GetNetworkEntityManager() = 0; + //! Returns the gem name associated with the provided component index. //! @param netComponentId the componentId to return the gem name of //! @return the name of the gem that contains the requested component @@ -117,6 +131,61 @@ namespace Multiplayer MultiplayerStats m_stats; }; + // Convenience helpers + inline IMultiplayer* GetMultiplayer() + { + return AZ::Interface::Get(); + } + + inline INetworkTime* GetNetworkTime() + { + return GetMultiplayer()->GetNetworkTime(); + } + + inline INetworkEntityManager* GetNetworkEntityManager() + { + return GetMultiplayer()->GetNetworkEntityManager(); + } + + inline NetworkEntityTracker* GetNetworkEntityTracker() + { + return GetNetworkEntityManager()->GetNetworkEntityTracker(); + } + + inline NetworkEntityAuthorityTracker* GetNetworkEntityAuthorityTracker() + { + return GetNetworkEntityManager()->GetNetworkEntityAuthorityTracker(); + } + + inline MultiplayerComponentRegistry* GetMultiplayerComponentRegistry() + { + return GetNetworkEntityManager()->GetMultiplayerComponentRegistry(); + } + + //! @class ScopedAlterTime + //! @brief This is a wrapper that temporarily adjusts global program time for backward reconciliation purposes. + class ScopedAlterTime final + { + public: + inline ScopedAlterTime(HostFrameId frameId, AZ::TimeMs timeMs, AzNetworking::ConnectionId connectionId) + { + INetworkTime* time = GetNetworkTime(); + m_previousHostFrameId = time->GetHostFrameId(); + m_previousHostTimeMs = time->GetHostTimeMs(); + m_previousRewindConnectionId = time->GetRewindingConnectionId(); + time->AlterTime(frameId, timeMs, connectionId); + } + inline ~ScopedAlterTime() + { + INetworkTime* time = GetNetworkTime(); + time->AlterTime(m_previousHostFrameId, m_previousHostTimeMs, m_previousRewindConnectionId); + } + private: + HostFrameId m_previousHostFrameId = InvalidHostFrameId; + AZ::TimeMs m_previousHostTimeMs = AZ::TimeMs{ 0 }; + AzNetworking::ConnectionId m_previousRewindConnectionId = AzNetworking::InvalidConnectionId; + }; + inline const char* GetEnumString(MultiplayerAgentType value) { switch (value) diff --git a/Gems/Multiplayer/Code/Include/INetworkEntityManager.h b/Gems/Multiplayer/Code/Include/INetworkEntityManager.h index d9b611ece0..ebb95e2281 100644 --- a/Gems/Multiplayer/Code/Include/INetworkEntityManager.h +++ b/Gems/Multiplayer/Code/Include/INetworkEntityManager.h @@ -59,9 +59,24 @@ namespace Multiplayer //! Creates new entities of the given archetype //! @param prefabEntryId the name of the spawnable to spawn - virtual EntityList CreateEntitiesImmediate( - const PrefabEntityId& prefabEntryId, NetEntityId netEntityId, NetEntityRole netEntityRole, AutoActivate autoActivate, - const AZ::Transform& transform) = 0; + virtual EntityList CreateEntitiesImmediate + ( + const PrefabEntityId& prefabEntryId, + NetEntityRole netEntityRole, + const AZ::Transform& transform + ) = 0; + + //! Creates new entities of the given archetype + //! This interface is internally used to spawn replicated entities + //! @param prefabEntryId the name of the spawnable to spawn + virtual EntityList CreateEntitiesImmediate + ( + const PrefabEntityId& prefabEntryId, + NetEntityId netEntityId, + NetEntityRole netEntityRole, + AutoActivate autoActivate, + const AZ::Transform& transform + ) = 0; //! Returns an ConstEntityPtr for the provided entityId. //! @param netEntityId the netEntityId to get an ConstEntityPtr for @@ -134,25 +149,4 @@ namespace Multiplayer //! @param entityRpcMessage the local rpc message to handle virtual void HandleLocalRpcMessage(NetworkEntityRpcMessage& message) = 0; }; - - // Convenience helpers - inline INetworkEntityManager* GetNetworkEntityManager() - { - return AZ::Interface::Get(); - } - - inline NetworkEntityTracker* GetNetworkEntityTracker() - { - return GetNetworkEntityManager()->GetNetworkEntityTracker(); - } - - inline NetworkEntityAuthorityTracker* GetNetworkEntityAuthorityTracker() - { - return GetNetworkEntityManager()->GetNetworkEntityAuthorityTracker(); - } - - inline MultiplayerComponentRegistry* GetMultiplayerComponentRegistry() - { - return GetNetworkEntityManager()->GetMultiplayerComponentRegistry(); - } } diff --git a/Gems/Multiplayer/Code/Include/INetworkTime.h b/Gems/Multiplayer/Code/Include/INetworkTime.h index 5346a0e0d0..1ccf08bbdc 100644 --- a/Gems/Multiplayer/Code/Include/INetworkTime.h +++ b/Gems/Multiplayer/Code/Include/INetworkTime.h @@ -47,9 +47,6 @@ namespace Multiplayer //! @return the hosts current timeMs virtual AZ::TimeMs GetHostTimeMs() const = 0; - //! Synchronizes rewindable entity state for the current application time. - virtual void SyncRewindableEntityState() = 0; - //! Get the controlling connection that may be currently altering global game time. //! Note this abstraction is required at a relatively high level to allow for 'don't rewind the shooter' semantics //! @return the ConnectionId of the connection requesting the rewind operation @@ -67,6 +64,13 @@ namespace Multiplayer //! @param rewindConnectionId the rewinding ConnectionId virtual void AlterTime(HostFrameId frameId, AZ::TimeMs timeMs, AzNetworking::ConnectionId rewindConnectionId) = 0; + //! Syncs all entities contained within a volume to the current rewind state. + //! @param rewindVolume the volume to rewind entities within (needed for physics entities) + virtual void SyncEntitiesToRewindState(const AZ::Aabb& rewindVolume) = 0; + + //! Restores all rewound entities to the current application time. + virtual void ClearRewoundEntities() = 0; + AZ_DISABLE_COPY_MOVE(INetworkTime); }; @@ -79,28 +83,4 @@ namespace Multiplayer static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; }; using INetworkTimeRequestBus = AZ::EBus; - - //! @class ScopedAlterTime - //! @brief This is a wrapper that temporarily adjusts global program time for backward reconciliation purposes. - class ScopedAlterTime final - { - public: - inline ScopedAlterTime(HostFrameId frameId, AZ::TimeMs timeMs, AzNetworking::ConnectionId connectionId) - { - INetworkTime* time = AZ::Interface::Get(); - m_previousHostFrameId = time->GetHostFrameId(); - m_previousHostTimeMs = time->GetHostTimeMs(); - m_previousRewindConnectionId = time->GetRewindingConnectionId(); - time->AlterTime(frameId, timeMs, connectionId); - } - inline ~ScopedAlterTime() - { - INetworkTime* time = AZ::Interface::Get(); - time->AlterTime(m_previousHostFrameId, m_previousHostTimeMs, m_previousRewindConnectionId); - } - private: - HostFrameId m_previousHostFrameId = InvalidHostFrameId; - AZ::TimeMs m_previousHostTimeMs = AZ::TimeMs{ 0 }; - AzNetworking::ConnectionId m_previousRewindConnectionId = AzNetworking::InvalidConnectionId; - }; } diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja index 2bae618d94..2acc252729 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja @@ -22,7 +22,7 @@ namespace {{ Namespace }} void RegisterMultiplayerComponents() { Multiplayer::MultiplayerComponentRegistry* multiplayerComponentRegistry = GetMultiplayerComponentRegistry(); - Multiplayer::MultiplayerStats& stats = AZ::Interface::Get()->GetStats(); + Multiplayer::MultiplayerStats& stats = GetMultiplayer()->GetStats(); {% for Component in dataFiles %} {% set ComponentName = Component.attrib['Name'] %} {% set ComponentBaseName = ComponentName %} diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 6e54ec3d58..d719cbe47b 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -476,7 +476,7 @@ bool {{ ClassName }}::Serialize{{ AutoComponentMacros.GetNetPropertiesSetName(Re {%- if networkPropertyCount.update({'value': networkPropertyCount.value + 1}) %}{% endif -%} {% endcall %} {% if networkPropertyCount.value > 0 %} - MultiplayerStats& stats = AZ::Interface::Get()->GetStats(); + MultiplayerStats& stats = GetMultiplayer()->GetStats(); // We modify the record if we are writing an update so that we don't notify for a change that really didn't change the value (just a duplicated send from the server) [[maybe_unused]] bool modifyRecord = serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject; {% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %} @@ -1141,16 +1141,23 @@ namespace {{ Component.attrib['Namespace'] }} AZ::EditContext* editContext = serializeContext->GetEditContext(); if (editContext) { - editContext->Class<{{ ComponentName }}>("{{ ComponentName }}", "{{ Component.attrib['Description'] }}") + editContext->Class<{{ ComponentBaseName }}>("{{ ComponentBaseName }}", "{{ Component.attrib['Description'] }}") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::Category, "Multiplayer") ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game")) - {{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Authority', ComponentName)|indent(20) -}} -{{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Server', ComponentName)|indent(20) -}} -{{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Client', ComponentName)|indent(20) -}} -{{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Autonomous', ComponentName)|indent(20) -}} -{{ DefineNetworkPropertyEditReflection(Component, 'Autonomous', 'Authority', ComponentName)|indent(20) }} - {{ DefineArchetypePropertyEditReflection(Component, ComponentName)|indent(20) }}; + {{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Authority', ComponentBaseName)|indent(20) -}} +{{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Server', ComponentBaseName)|indent(20) -}} +{{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Client', ComponentBaseName)|indent(20) -}} +{{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Autonomous', ComponentBaseName)|indent(20) -}} +{{ DefineNetworkPropertyEditReflection(Component, 'Autonomous', 'Authority', ComponentBaseName)|indent(20) }} + {{ DefineArchetypePropertyEditReflection(Component, ComponentBaseName)|indent(20) }}; +{% if ComponentDerived %} + + editContext->Class<{{ ComponentName }}>("{{ ComponentName }}", "{{ Component.attrib['Description'] }}") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Category, "Multiplayer") + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game")); +{% endif %} } } } diff --git a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp index 90b590d99d..b57c465df2 100644 --- a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp @@ -94,7 +94,7 @@ namespace Multiplayer if (entityIsMigrating == EntityIsMigrating::True) { m_allowMigrateClientInput = true; - m_serverMigrateFrameId = AZ::Interface::Get()->GetHostFrameId(); + m_serverMigrateFrameId = GetNetworkTime()->GetHostFrameId(); } } @@ -492,8 +492,8 @@ namespace Multiplayer const uint32_t maxClientInputs = inputRate > 0.0 ? static_cast(maxRewindHistory / inputRate) : 0; - INetworkTime* networkTime = AZ::Interface::Get(); - IMultiplayer* multiplayer = AZ::Interface::Get(); + IMultiplayer* multiplayer = GetMultiplayer(); + INetworkTime* networkTime = GetNetworkTime(); while (m_moveAccumulator >= inputRate) { m_moveAccumulator -= inputRate; diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index e6fb77eca7..590faa6bad 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include namespace AZ::ConsoleTypeHelpers { @@ -69,6 +72,7 @@ namespace Multiplayer AZ_CVAR(ProtocolType, sv_protocol, ProtocolType::Udp, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "This flag controls whether we use TCP or UDP for game networking"); AZ_CVAR(bool, sv_isDedicated, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Whether the host command creates an independent or client hosted server"); AZ_CVAR(AZ::TimeMs, cl_defaultNetworkEntityActivationTimeSliceMs, AZ::TimeMs{ 0 }, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Max Ms to use to activate entities coming from the network, 0 means instantiate everything"); + AZ_CVAR(AZ::CVarFixedString, sv_defaultPlayerSpawnAsset, "prefabs/player.network.spawnable", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The default spawnable to use when a new player connects"); void MultiplayerSystemComponent::Reflect(AZ::ReflectContext* context) { @@ -411,6 +415,11 @@ namespace Multiplayer void MultiplayerSystemComponent::OnConnect(AzNetworking::IConnection* connection) { + MultiplayerAgentDatum datum; + datum.m_id = connection->GetConnectionId(); + datum.m_isInvited = false; + datum.m_agentType = MultiplayerAgentType::Client; + if (connection->GetConnectionRole() == ConnectionRole::Connector) { AZLOG_INFO("New outgoing connection to remote address: %s", connection->GetRemoteAddress().GetString().c_str()); @@ -419,36 +428,45 @@ namespace Multiplayer else { AZLOG_INFO("New incoming connection from remote address: %s", connection->GetRemoteAddress().GetString().c_str()); - MultiplayerAgentDatum datum; - datum.m_id = connection->GetConnectionId(); - datum.m_isInvited = false; - datum.m_agentType = MultiplayerAgentType::Client; m_connAcquiredEvent.Signal(datum); } - if (GetAgentType() == MultiplayerAgentType::ClientServer - || GetAgentType() == MultiplayerAgentType::DedicatedServer) + if (m_onConnectFunctor) { - // TODO: This needs to be set to the players autonomous proxy ------------v - NetworkEntityHandle controlledEntity = GetNetworkEntityTracker()->Get(NetEntityId{ 0 }); - if (connection->GetUserData() == nullptr) // Only add user data if the connect event handler has not already done so - { - connection->SetUserData(new ServerToClientConnectionData(connection, *this, controlledEntity)); - } - - AZStd::unique_ptr window = AZStd::make_unique(controlledEntity, connection); - reinterpret_cast(connection->GetUserData())->GetReplicationManager().SetReplicationWindow(AZStd::move(window)); } else { - if (connection->GetUserData() == nullptr) // Only add user data if the connect event handler has not already done so + if (GetAgentType() == MultiplayerAgentType::ClientServer + || GetAgentType() == MultiplayerAgentType::DedicatedServer) { - connection->SetUserData(new ClientToServerConnectionData(connection, *this)); - } + PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast(sv_defaultPlayerSpawnAsset).c_str()), 1); + INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity()); - AZStd::unique_ptr window = AZStd::make_unique(); - reinterpret_cast(connection->GetUserData())->GetReplicationManager().SetEntityActivationTimeSliceMs(cl_defaultNetworkEntityActivationTimeSliceMs); + NetworkEntityHandle controlledEntity; + if (entityList.size() > 0) + { + controlledEntity = entityList[0]; + } + + if (connection->GetUserData() == nullptr) // Only add user data if the connect event handler has not already done so + { + connection->SetUserData(new ServerToClientConnectionData(connection, *this, controlledEntity)); + } + + AZStd::unique_ptr window = AZStd::make_unique(controlledEntity, connection); + reinterpret_cast(connection->GetUserData())->GetReplicationManager().SetReplicationWindow(AZStd::move(window)); + } + else + { + if (connection->GetUserData() == nullptr) // Only add user data if the connect event handler has not already done so + { + connection->SetUserData(new ClientToServerConnectionData(connection, *this)); + } + + AZStd::unique_ptr window = AZStd::make_unique(); + reinterpret_cast(connection->GetUserData())->GetReplicationManager().SetEntityActivationTimeSliceMs(cl_defaultNetworkEntityActivationTimeSliceMs); + } } } @@ -521,6 +539,11 @@ namespace Multiplayer handler.Connect(m_shutdownEvent); } + void MultiplayerSystemComponent::SetOnConnectFunctor(const OnConnectFunctor& functor) + { + m_onConnectFunctor = functor; + } + void MultiplayerSystemComponent::SendReadyForEntityUpdates(bool readyForEntityUpdates) { IConnectionSet& connectionSet = m_networkInterface->GetConnectionSet(); @@ -542,6 +565,16 @@ namespace Multiplayer } } + INetworkTime* MultiplayerSystemComponent::GetNetworkTime() + { + return &m_networkTime; + } + + INetworkEntityManager* MultiplayerSystemComponent::GetNetworkEntityManager() + { + return &m_networkEntityManager; + } + const char* MultiplayerSystemComponent::GetComponentGemName(NetComponentId netComponentId) const { return GetMultiplayerComponentRegistry()->GetComponentGemName(netComponentId); diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index 477745e6b5..1de8fccb50 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -89,8 +89,11 @@ namespace Multiplayer void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) override; void AddSessionInitHandler(SessionInitEvent::Handler& handler) override; void AddSessionShutdownHandler(SessionShutdownEvent::Handler& handler) override; + void SetOnConnectFunctor(const OnConnectFunctor& functor) override; void SendReadyForEntityUpdates(bool readyForEntityUpdates) override; AZ::TimeMs GetCurrentHostTimeMs() const override; + INetworkTime* GetNetworkTime() override; + INetworkEntityManager* GetNetworkEntityManager() override; const char* GetComponentGemName(NetComponentId netComponentId) const override; const char* GetComponentName(NetComponentId netComponentId) const override; const char* GetComponentPropertyName(NetComponentId netComponentId, PropertyIndex propertyIndex) const override; @@ -121,6 +124,8 @@ namespace Multiplayer SessionShutdownEvent m_shutdownEvent; ConnectionAcquiredEvent m_connAcquiredEvent; + OnConnectFunctor m_onConnectFunctor = nullptr; + AZ::TimeMs m_lastReplicatedHostTimeMs = AZ::TimeMs{ 0 }; HostFrameId m_lastReplicatedHostFrameId = InvalidHostFrameId; }; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp index 1e7649f561..65df4f1464 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp @@ -824,7 +824,7 @@ namespace Multiplayer { if (entityReplicator == nullptr) { - IMultiplayer* multiplayer = AZ::Interface::Get(); + IMultiplayer* multiplayer = GetMultiplayer(); AZLOG_INFO ( "EntityReplicationManager: Dropping remote RPC message for component %s of rpc index %s, entityId %u has already been deleted", diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp index 7431b95a22..197d83a48c 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp @@ -448,7 +448,7 @@ namespace Multiplayer void EntityReplicator::DeferRpcMessage(NetworkEntityRpcMessage& entityRpcMessage) { // Received rpc metrics, log rpc sent, number of bytes, and the componentId/rpcId for bandwidth metrics - MultiplayerStats& stats = AZ::Interface::Get()->GetStats(); + MultiplayerStats& stats = GetMultiplayer()->GetStats(); stats.RecordRpcSent(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex(), entityRpcMessage.GetEstimatedSerializeSize()); m_replicationManager.AddDeferredRpcMessage(entityRpcMessage); @@ -631,7 +631,7 @@ namespace Multiplayer bool EntityReplicator::HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcMessage& entityRpcMessage) { // Received rpc metrics, log rpc received, time spent, number of bytes, and the componentId/rpcId for bandwidth metrics - MultiplayerStats& stats = AZ::Interface::Get()->GetStats(); + MultiplayerStats& stats = GetMultiplayer()->GetStats(); stats.RecordRpcReceived(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex(), entityRpcMessage.GetEstimatedSerializeSize()); if (!m_netBindComponent) diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp index 1c7fb5f7af..7ee4d45e93 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp @@ -38,7 +38,6 @@ namespace Multiplayer , m_onSpawnedHandler([this](AZ::Data::Asset spawnable) { this->OnSpawned(spawnable); }) , m_onDespawnedHandler([this](AZ::Data::Asset spawnable) { this->OnDespawned(spawnable); }) { - AZ::Interface::Register(this); AzFramework::RootSpawnableNotificationBus::Handler::BusConnect(); AzFramework::SpawnableEntitiesInterface::Get()->AddOnSpawnedHandler(m_onSpawnedHandler); @@ -48,7 +47,6 @@ namespace Multiplayer NetworkEntityManager::~NetworkEntityManager() { AzFramework::RootSpawnableNotificationBus::Handler::BusDisconnect(); - AZ::Interface::Unregister(this); } void NetworkEntityManager::Initialize(HostId hostId, AZStd::unique_ptr entityDomain) @@ -365,9 +363,24 @@ namespace Multiplayer return returnList; } - INetworkEntityManager::EntityList NetworkEntityManager::CreateEntitiesImmediate( - const PrefabEntityId& prefabEntryId, NetEntityId netEntityId, NetEntityRole netEntityRole, - AutoActivate autoActivate, const AZ::Transform& transform) + INetworkEntityManager::EntityList NetworkEntityManager::CreateEntitiesImmediate + ( + const PrefabEntityId& prefabEntryId, + NetEntityRole netEntityRole, + const AZ::Transform& transform + ) + { + return CreateEntitiesImmediate(prefabEntryId, NextId(), netEntityRole, AutoActivate::Activate, transform); + } + + INetworkEntityManager::EntityList NetworkEntityManager::CreateEntitiesImmediate + ( + const PrefabEntityId& prefabEntryId, + NetEntityId netEntityId, + NetEntityRole netEntityRole, + AutoActivate autoActivate, + const AZ::Transform& transform + ) { INetworkEntityManager::EntityList returnList; @@ -436,7 +449,7 @@ namespace Multiplayer void NetworkEntityManager::OnRootSpawnableAssigned( [[maybe_unused]] AZ::Data::Asset rootSpawnable, [[maybe_unused]] uint32_t generation) { - auto* multiplayer = AZ::Interface::Get(); + auto* multiplayer = GetMultiplayer(); const auto agentType = multiplayer->GetAgentType(); if (agentType == MultiplayerAgentType::Client) @@ -448,7 +461,7 @@ namespace Multiplayer void NetworkEntityManager::OnRootSpawnableReleased([[maybe_unused]] uint32_t generation) { // TODO: Do we need to clear all entities here? - auto* multiplayer = AZ::Interface::Get(); + auto* multiplayer = GetMultiplayer(); const auto agentType = multiplayer->GetAgentType(); if (agentType == MultiplayerAgentType::Client) @@ -494,7 +507,7 @@ namespace Multiplayer return; } - auto* multiplayer = AZ::Interface::Get(); + auto* multiplayer = GetMultiplayer(); const auto agentType = multiplayer->GetAgentType(); const bool spawnImmediately = diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h index ae2cb0dd9e..ba71eaf780 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h @@ -47,10 +47,20 @@ namespace Multiplayer ConstNetworkEntityHandle GetEntity(NetEntityId netEntityId) const override; EntityList CreateEntitiesImmediate(const AzFramework::Spawnable& spawnable, NetEntityRole netEntityRole); - - EntityList CreateEntitiesImmediate( - const PrefabEntityId& prefabEntryId, NetEntityId netEntityId, NetEntityRole netEntityRole, - AutoActivate autoActivate, const AZ::Transform& transform) override; + EntityList CreateEntitiesImmediate + ( + const PrefabEntityId& prefabEntryId, + NetEntityRole netEntityRole, + const AZ::Transform& transform + ) override; + EntityList CreateEntitiesImmediate + ( + const PrefabEntityId& prefabEntryId, + NetEntityId netEntityId, + NetEntityRole netEntityRole, + AutoActivate autoActivate, + const AZ::Transform& transform + ) override; uint32_t GetEntityCount() const override; NetworkEntityHandle AddEntityToEntityMap(NetEntityId netEntityId, AZ::Entity* entity) override; @@ -81,7 +91,6 @@ namespace Multiplayer private: void RemoveEntities(); - NetEntityId NextId(); void OnSpawned(AZ::Data::Asset spawnable); diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.cpp index 8f70f7e1fa..114c3e3b43 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.cpp index dee72156ed..c6eed626a9 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp index 9a0e784d36..c0200c9e6d 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp @@ -11,19 +11,12 @@ */ #include +#include +#include +#include namespace Multiplayer { - NetworkTime::NetworkTime() - { - AZ::Interface::Register(this); - } - - NetworkTime::~NetworkTime() - { - AZ::Interface::Unregister(this); - } - bool NetworkTime::IsTimeRewound() const { return m_rewindingConnectionId != AzNetworking::InvalidConnectionId; @@ -51,11 +44,6 @@ namespace Multiplayer return m_hostTimeMs; } - void NetworkTime::SyncRewindableEntityState() - { - - } - AzNetworking::ConnectionId NetworkTime::GetRewindingConnectionId() const { return m_rewindingConnectionId; @@ -72,4 +60,38 @@ namespace Multiplayer m_hostTimeMs = timeMs; m_rewindingConnectionId = rewindConnectionId; } + + void NetworkTime::SyncEntitiesToRewindState(const AZ::Aabb& rewindVolume) + { + // TODO: extrude rewind volume for initial gather + AZStd::vector gatheredEntries; + AZ::Interface::Get()->GetDefaultVisibilityScene()->Enumerate(rewindVolume, [&gatheredEntries](const AzFramework::IVisibilityScene::NodeData& nodeData) + { + gatheredEntries.reserve(gatheredEntries.size() + nodeData.m_entries.size()); + for (AzFramework::VisibilityEntry* visEntry : nodeData.m_entries) + { + if (visEntry->m_typeFlags & AzFramework::VisibilityEntry::TypeFlags::TYPE_Entity) + { + // TODO: offset aabb for exact rewound position and check against the non-extruded rewind volume + gatheredEntries.push_back(visEntry); + } + } + }); + + for (AzFramework::VisibilityEntry* visEntry : gatheredEntries) + { + AZ::Entity* entity = static_cast(visEntry->m_userData); + [[maybe_unused]] NetBindComponent* entryNetBindComponent = entity->template FindComponent(); + if (entryNetBindComponent != nullptr) + { + // TODO: invoke the sync to rewind event on the netBindComponent and add the entity to the rewound entity set + } + } + } + + void NetworkTime::ClearRewoundEntities() + { + AZ_Assert(!IsTimeRewound(), "Cannot clear rewound entity state while still within scoped rewind"); + // TODO: iterate all rewound entities, signal them to sync rewind state, and clear the rewound entity set + } } diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h index 06e758b349..47f557a11f 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h @@ -23,8 +23,8 @@ namespace Multiplayer : public INetworkTime { public: - NetworkTime(); - virtual ~NetworkTime(); + NetworkTime() = default; + virtual ~NetworkTime() = default; //! INetworkTime overrides. //! @{ @@ -33,10 +33,11 @@ namespace Multiplayer HostFrameId GetUnalteredHostFrameId() const override; void IncrementHostFrameId() override; AZ::TimeMs GetHostTimeMs() const override; - void SyncRewindableEntityState() override; AzNetworking::ConnectionId GetRewindingConnectionId() const override; HostFrameId GetHostFrameIdForRewindingConnection(AzNetworking::ConnectionId rewindConnectionId) const override; void AlterTime(HostFrameId frameId, AZ::TimeMs timeMs, AzNetworking::ConnectionId rewindConnectionId) override; + void SyncEntitiesToRewindState(const AZ::Aabb& rewindVolume) override; + void ClearRewoundEntities() override; //! @} private: diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.inl b/Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.inl index 0835421ebd..2e67d42ede 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.inl +++ b/Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.inl @@ -47,7 +47,7 @@ namespace Multiplayer template inline RewindableObject &RewindableObject::operator =(const RewindableObject& rhs) { - INetworkTime* networkTime = AZ::Interface::Get(); + INetworkTime* networkTime = GetNetworkTime(); SetValueForTime(rhs.GetValueForTime(networkTime->GetHostFrameId()), GetCurrentTimeForProperty()); return *this; } @@ -115,7 +115,7 @@ namespace Multiplayer template inline HostFrameId RewindableObject::GetCurrentTimeForProperty() const { - INetworkTime* networkTime = AZ::Interface::Get(); + INetworkTime* networkTime = GetNetworkTime(); return networkTime->GetHostFrameIdForRewindingConnection(m_owningConnectionId); } diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp index c54a610de2..a51bdc4acc 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp @@ -65,7 +65,7 @@ namespace Multiplayer { AZ::Entity* entity = m_controlledEntity.GetEntity(); AZ_Assert(entity, "Invalid controlled entity provided to replication window"); - m_controlledEntityTransform = entity->GetTransform(); + m_controlledEntityTransform = entity ? entity->GetTransform() : nullptr; AZ_Assert(m_controlledEntityTransform, "Controlled player entity must have a transform"); //// this one is optional diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h index 55a6a4b56e..b4e4427945 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include #include #include From 293e0057f4c0a74642e331dd052b3ae0d0468264 Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 13:58:53 -0700 Subject: [PATCH 160/225] Actually invoke the override OnConnect handler --- Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 590faa6bad..15b6b48631 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -433,7 +433,8 @@ namespace Multiplayer if (m_onConnectFunctor) { - + // Default OnConnect behaviour has been overridden, + m_onConnectFunctor(connection, datum); } else { From 655d71e0ddfd69834537da5e2febd1f8a40fc59f Mon Sep 17 00:00:00 2001 From: greerdv Date: Wed, 12 May 2021 22:16:14 +0100 Subject: [PATCH 161/225] update compatibility of atom components with NonUniformScaleService --- .../Atom/Component/DebugCamera/CameraControllerComponent.h | 3 ++- .../Component/DebugCamera/Code/Source/CameraComponent.cpp | 1 + .../DebugCamera/Code/Source/CameraControllerComponent.cpp | 7 ++++++- .../AtomBridge/Code/Source/FlyCameraInputComponent.cpp | 6 ++++++ .../AtomBridge/Code/Source/FlyCameraInputComponent.h | 1 + .../Code/Source/Animation/AttachmentComponent.h | 1 + .../CoreLights/DirectionalLightComponentController.cpp | 1 + .../DiffuseProbeGridComponentController.cpp | 1 + .../ReflectionProbe/ReflectionProbeComponentController.cpp | 1 + .../Code/Source/SkyBox/HDRiSkyboxComponentController.cpp | 1 + .../Code/Source/SkyBox/PhysicalSkyComponentController.cpp | 1 + 11 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Component/DebugCamera/Code/Include/Atom/Component/DebugCamera/CameraControllerComponent.h b/Gems/Atom/Component/DebugCamera/Code/Include/Atom/Component/DebugCamera/CameraControllerComponent.h index 4b2b19cff0..225952302a 100644 --- a/Gems/Atom/Component/DebugCamera/Code/Include/Atom/Component/DebugCamera/CameraControllerComponent.h +++ b/Gems/Atom/Component/DebugCamera/Code/Include/Atom/Component/DebugCamera/CameraControllerComponent.h @@ -41,7 +41,8 @@ namespace AZ static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + // CameraControllerRequestBus::Handler overrides void Enable(TypeId typeId) override final; void Reset() override final; diff --git a/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp b/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp index fbda0924e6..cbaa70929c 100644 --- a/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp +++ b/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp @@ -69,6 +69,7 @@ namespace AZ void CameraComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("CameraService", 0x1dd1caa4)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void CameraComponent::Activate() diff --git a/Gems/Atom/Component/DebugCamera/Code/Source/CameraControllerComponent.cpp b/Gems/Atom/Component/DebugCamera/Code/Source/CameraControllerComponent.cpp index 69e8469a56..e5a88dd409 100644 --- a/Gems/Atom/Component/DebugCamera/Code/Source/CameraControllerComponent.cpp +++ b/Gems/Atom/Component/DebugCamera/Code/Source/CameraControllerComponent.cpp @@ -32,12 +32,17 @@ namespace AZ required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); required.push_back(AZ_CRC("CameraService", 0x1dd1caa4)); } - + void CameraControllerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC("CameraControllerService", 0xc35788f9)); } + void CameraControllerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + void CameraControllerComponent::Enable(TypeId typeId) { // Enable this controller if type id matches, otherwise disable this controller diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/FlyCameraInputComponent.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/FlyCameraInputComponent.cpp index 54e3a6ce59..3ad8bbae99 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/FlyCameraInputComponent.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/FlyCameraInputComponent.cpp @@ -78,6 +78,12 @@ void FlyCameraInputComponent::GetProvidedServices(AZ::ComponentDescriptor::Depen provided.push_back(AZ_CRC("InputService", 0xd41af40c)); } +////////////////////////////////////////////////////////////////////////////// +void FlyCameraInputComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) +{ + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); +} + ////////////////////////////////////////////////////////////////////////////// void FlyCameraInputComponent::Reflect(AZ::ReflectContext* reflection) { diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/FlyCameraInputComponent.h b/Gems/AtomLyIntegration/AtomBridge/Code/Source/FlyCameraInputComponent.h index 03fb3c421e..6c0232f358 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/FlyCameraInputComponent.h +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/FlyCameraInputComponent.h @@ -30,6 +30,7 @@ namespace AZ public: static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); static void Reflect(AZ::ReflectContext* reflection); AZ_COMPONENT(FlyCameraInputComponent, "{7AE0D6AD-691C-41B6-9DD5-F23F78B1A02E}"); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.h index ac03663f22..855c5494b3 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.h @@ -163,6 +163,7 @@ namespace AZ static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("AttachmentService", 0x5aaa7b63)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentController.cpp index 310e6e6eca..6bff558268 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentController.cpp @@ -121,6 +121,7 @@ namespace AZ void DirectionalLightComponentController::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("DirectionalLightService", 0x5270619f)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleComponent")); } void DirectionalLightComponentController::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/DiffuseProbeGrid/DiffuseProbeGridComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/DiffuseProbeGrid/DiffuseProbeGridComponentController.cpp index 8a0bd86965..0ddace1f87 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/DiffuseProbeGrid/DiffuseProbeGridComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/DiffuseProbeGrid/DiffuseProbeGridComponentController.cpp @@ -73,6 +73,7 @@ namespace AZ void DiffuseProbeGridComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("DiffuseProbeGridService", 0x63d32042)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void DiffuseProbeGridComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp index 91040885f1..9b0ff29bb8 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp @@ -80,6 +80,7 @@ namespace AZ void ReflectionProbeComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("ReflectionProbeService", 0xa5b919ce)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void ReflectionProbeComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/HDRiSkyboxComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/HDRiSkyboxComponentController.cpp index f343a68f79..2c44124564 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/HDRiSkyboxComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/HDRiSkyboxComponentController.cpp @@ -51,6 +51,7 @@ namespace AZ void HDRiSkyboxComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("SkyBoxService", 0x8169a709)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void HDRiSkyboxComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.cpp index 867a81eefe..4a6b1608a4 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.cpp @@ -58,6 +58,7 @@ namespace AZ void PhysicalSkyComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("SkyBoxService", 0x8169a709)); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void PhysicalSkyComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) From 9a4884ff0bc1577a4947d3c835ec144e195d5a53 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 12 May 2021 14:19:18 -0700 Subject: [PATCH 162/225] Exposing Multiplayer integral types (just wrapped ints) to bevahior context so that Network Properties using these type can be Get/Set from Script Canvas --- .../Code/Include/MultiplayerTypes.h | 11 ++++++++++ .../Source/AutoGen/AutoComponent_Source.jinja | 20 +++++++++++++++++++ .../Source/MultiplayerSystemComponent.cpp | 11 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/Gems/Multiplayer/Code/Include/MultiplayerTypes.h b/Gems/Multiplayer/Code/Include/MultiplayerTypes.h index 1bee9867e3..e9f3865563 100644 --- a/Gems/Multiplayer/Code/Include/MultiplayerTypes.h +++ b/Gems/Multiplayer/Code/Include/MultiplayerTypes.h @@ -130,3 +130,14 @@ AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::PropertyIndex); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::RpcIndex); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::ClientInputId); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::HostFrameId); + +namespace AZ +{ + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::HostId, "{D04B3363-8E1B-4193-8B2B-D2140389C9D5}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetEntityId, "{05E4C08B-3A1B-4390-8144-3767D8E56A81}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetComponentId, "{8AF3B382-F187-4323-9014-B380638767E3}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::PropertyIndex, "{F4460210-024D-4B3B-A10A-04B669C34230}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::RpcIndex, "{EBB1C475-FA03-4111-8C84-985377434B9B}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::ClientInputId, "{35BF3504-CEC9-4406-A275-C633A17FBEFB}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::HostFrameId, "{DF17F6F3-48C6-4B4A-BBD9-37DA03162864}"); +} // namespace AZ diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 576978f75c..a3eef99b20 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -707,6 +707,26 @@ enum class NetworkProperties controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }}); }) + ->Method("GetOn{{ UpperFirst(Property.attrib['Name']) }}ChangedEvent", [](AZ::EntityId id) -> AZ::Event<{{ Property.attrib['Type'] }}>* + { + AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); + if (!entity) + { + AZ_Warning("Network Property", false, "{{ ClassName }} GetOn{{ UpperFirst(Property.attrib['Name']) }}ChangedEvent failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + return nullptr; + } + + {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>(); + if (!networkComponent) + { + AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str()) + return nullptr; + } + + return &networkComponent->m_{{ LowerFirst(Property.attrib['Name']) }}Event; + }) + ->Attribute(AZ::Script::Attributes::AzEventDescription, AZ::BehaviorAzEventDescription{ "On {{ UpperFirst(Property.attrib['Name']) }} Changed Event", {"New {{ UpperFirst(Property.attrib['Name']) }}"} }) + {% endif %} {% endcall -%} {% endmacro %} diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index e6fb77eca7..9f45122c1d 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -78,6 +78,17 @@ namespace Multiplayer ->Version(1); } + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("HostId"); + behaviorContext->Class("NetEntityId"); + behaviorContext->Class("NetComponentId"); + behaviorContext->Class("PropertyIndex"); + behaviorContext->Class ("RpcIndex"); + behaviorContext->Class ("ClientInputId"); + behaviorContext->Class ("HostFrameId"); + } + MultiplayerComponent::Reflect(context); } From 50abafbab1bc0033395654c7491bfd3c2720d441 Mon Sep 17 00:00:00 2001 From: Steve Pham <82231385+spham-amzn@users.noreply.github.com> Date: Wed, 12 May 2021 14:31:39 -0700 Subject: [PATCH 163/225] Add orchestrating script to install ubuntu packages for O3DE on Linux (#721) SPEC-3510: Linux environment setup scripts * Add orchestrating script to install ubuntu packages for O3DE on Linux * Fix issue parsing package content file for build-tools --- .../Platform/Linux/install-ubuntu-awscli.sh | 2 +- .../Linux/install-ubuntu-build-tools.sh | 21 ++++---- .../Platform/Linux/install-ubuntu-git.sh | 8 ++-- .../Platform/Linux/install-ubuntu.sh | 48 +++++++++++++++++++ 4 files changed, 64 insertions(+), 15 deletions(-) create mode 100755 scripts/build/build_node/Platform/Linux/install-ubuntu.sh diff --git a/scripts/build/build_node/Platform/Linux/install-ubuntu-awscli.sh b/scripts/build/build_node/Platform/Linux/install-ubuntu-awscli.sh index 4c2f350859..8649f61fd1 100755 --- a/scripts/build/build_node/Platform/Linux/install-ubuntu-awscli.sh +++ b/scripts/build/build_node/Platform/Linux/install-ubuntu-awscli.sh @@ -38,7 +38,7 @@ then ./aws/install rm -rf ./aws else - AWS_CLI_VERSION=`aws --version | awk '{print $1}' | awk -F/ '{print $2}'` + AWS_CLI_VERSION=$(aws --version | awk '{print $1}' | awk -F/ '{print $2}') echo AWS CLI \(version $AWS_CLI_VERSION\) already installed fi diff --git a/scripts/build/build_node/Platform/Linux/install-ubuntu-build-tools.sh b/scripts/build/build_node/Platform/Linux/install-ubuntu-build-tools.sh index fd7b59592a..6fea3b03fa 100755 --- a/scripts/build/build_node/Platform/Linux/install-ubuntu-build-tools.sh +++ b/scripts/build/build_node/Platform/Linux/install-ubuntu-build-tools.sh @@ -26,7 +26,7 @@ then exit 1 fi -UBUNTU_DISTRO="`lsb_release -c | awk '{print $2}'`" +UBUNTU_DISTRO="$(lsb_release -c | awk '{print $2}')" if [ "$UBUNTU_DISTRO" == "bionic" ] then echo "Setup for Ubuntu 18.04 LTS ($UBUNTU_DISTRO)" @@ -53,7 +53,7 @@ fi # will install it from the bionic distro manually into focal. This is needed since Ubuntu 20.04 supports # python 3.8 out of the box, but we are using 3.7 # -LIBFFI6_COUNT=`apt list --installed 2>/dev/null | grep libffi6 | wc -l` +LIBFFI6_COUNT=$(apt list --installed 2>/dev/null | grep libffi6 | wc -l) if [ "$UBUNTU_DISTRO" == "focal" ] && [ $LIBFFI6_COUNT -eq 0 ] then echo "Installing libffi for Ubuntu 20.04" @@ -90,7 +90,7 @@ fi # Add the kitware repository for cmake if necessary # -KITWARE_REPO_COUNT=`cat /etc/apt/sources.list | grep ^deb | grep https://apt.kitware.com/ubuntu/ | wc -l` +KITWARE_REPO_COUNT=$(cat /etc/apt/sources.list | grep ^deb | grep https://apt.kitware.com/ubuntu/ | wc -l) if [ $KITWARE_REPO_COUNT -eq 0 ] then @@ -121,33 +121,34 @@ PACKAGE_FILE_LIST=package-list.ubuntu-$UBUNTU_DISTRO.txt echo Reading package list $PACKAGE_FILE_LIST # Read each line (strip out comment tags) -for LINE in `cat $PACKAGE_FILE_LIST | sed 's/#.*$//g'` +for PREPROC_LINE in $(cat $PACKAGE_FILE_LIST | sed 's/#.*$//g') do - PACKAGE=`echo $LINE | awk -F / '{print $1}'` + LINE=$(echo $PREPROC_LINE | tr -d '\r\n') + PACKAGE=$(echo $LINE | awk -F / '{$1=$1;print $1}') if [ "$PACKAGE" != "" ] # Skip blank lines then - PACKAGE_VER=`echo $LINE | awk -F / '{print $2}'` + PACKAGE_VER=$(echo $LINE | awk -F / '{$2=$2;print $2}') if [ "$PACKAGE_VER" == "" ] then # Process non-versioned packages - INSTALLED_COUNT=`apt list --installed 2>/dev/null | grep ^$PACKAGE/ | wc -l` + INSTALLED_COUNT=$(apt list --installed 2>/dev/null | grep ^$PACKAGE/ | wc -l) if [ $INSTALLED_COUNT -eq 0 ] then echo Installing $PACKAGE apt-get install $PACKAGE -y else - INSTALLED_VERSION=`apt list --installed 2>/dev/null | grep ^$PACKAGE/ | awk '{print $2}'` + INSTALLED_VERSION=$(apt list --installed 2>/dev/null | grep ^$PACKAGE/ | awk '{print $2}') echo $PACKAGE already installed \(version $INSTALLED_VERSION\) fi else # Process versioned packages - INSTALLED_COUNT=`apt list --installed 2>/dev/null | grep ^$PACKAGE/ | wc -l` + INSTALLED_COUNT=$(apt list --installed 2>/dev/null | grep ^$PACKAGE/ | wc -l) if [ $INSTALLED_COUNT -eq 0 ] then echo Installing $PACKAGE \( $PACKAGE_VER \) apt-get install $PACKAGE=$PACKAGE_VER -y else - INSTALLED_VERSION=`apt list --installed 2>/dev/null | grep ^$PACKAGE/ | awk '{print $2}'` + INSTALLED_VERSION=$(apt list --installed 2>/dev/null | grep ^$PACKAGE/ | awk '{print $2}') if [ "$INSTALLED_VERSION" != "$PACKAGE_VER" ] then echo $PACKAGE already installed but with the wrong version. Purging the package diff --git a/scripts/build/build_node/Platform/Linux/install-ubuntu-git.sh b/scripts/build/build_node/Platform/Linux/install-ubuntu-git.sh index 53554f4175..028b0082d7 100755 --- a/scripts/build/build_node/Platform/Linux/install-ubuntu-git.sh +++ b/scripts/build/build_node/Platform/Linux/install-ubuntu-git.sh @@ -26,7 +26,7 @@ then exit 1 fi -UBUNTU_DISTRO="`lsb_release -c | awk '{print $2}'`" +UBUNTU_DISTRO="$(lsb_release -c | awk '{print $2}')" if [ "$UBUNTU_DISTRO" == "bionic" ] then echo "Setup for Ubuntu 18.04 LTS ($UBUNTU_DISTRO)" @@ -49,14 +49,14 @@ then apt-get update apt-get install git -y else - GIT_VERSION=`git --version | awk '{print $3}'` + GIT_VERSION=$(git --version | awk '{print $3}') echo Git $GIT_VERSION already Installed. Skipping Git installation fi # # Setup Git-LFS if needed # -GIT_LFS_PACKAGE_COUNT=`apt list --installed 2>/dev/null | grep git-lfs/ | wc -l` +GIT_LFS_PACKAGE_COUNT=$(apt list --installed 2>/dev/null | grep git-lfs/ | wc -l) if [ $GIT_LFS_PACKAGE_COUNT -eq 0 ] then echo Setting up Git-LFS @@ -87,7 +87,7 @@ then dpkg -i $GCM_PACKAGE_NAME popd else - GCM_VERSION=`git-credential-manager-core --version` + GCM_VERSION=$(git-credential-manager-core --version) echo Git Credential Manager \(GCM\) version $GCM_VERSION already installed. Skipping GCM installation fi diff --git a/scripts/build/build_node/Platform/Linux/install-ubuntu.sh b/scripts/build/build_node/Platform/Linux/install-ubuntu.sh new file mode 100755 index 0000000000..9cdc94fa9e --- /dev/null +++ b/scripts/build/build_node/Platform/Linux/install-ubuntu.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +# This script must be run as root +if [[ $EUID -ne 0 ]] +then + echo "This script must be run as root (sudo)" + exit 1 +fi + +echo Installing packages and tools for O3DE development + +# Install awscli +./install-ubuntu-awscli.sh +if [ $? -ne 0 ] +then + echo Error installing AWSCLI + exit 1 +fi + + +# Install git +./install-ubuntu-git.sh +if [ $? -ne 0 ] +then + echo Error installing Git + exit 1 +fi + +# Install the necessary build tools +./install-ubuntu-build-tools.sh +if [ $? -ne 0 ] +then + echo Error installing ubuntu tools + exit 1 +fi + + +echo Packages and tools for O3DE setup complete +exit 0 From 9b1f4c04e65e8ae29053d1070eacc67a18be7768 Mon Sep 17 00:00:00 2001 From: mriegger Date: Wed, 12 May 2021 14:54:33 -0700 Subject: [PATCH 164/225] Removing the old hack code --- .../Code/Source/Decals/AsyncLoadTracker.h | 18 ++++++++++-------- .../DecalTextureArrayFeatureProcessor.cpp | 18 +++++------------- .../Decals/DecalTextureArrayFeatureProcessor.h | 3 --- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/AsyncLoadTracker.h b/Gems/Atom/Feature/Common/Code/Source/Decals/AsyncLoadTracker.h index ec35c4b51f..a3fff7b91e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/AsyncLoadTracker.h +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/AsyncLoadTracker.h @@ -23,7 +23,9 @@ namespace AZ { public: - void TrackAssetLoad(const FeatureProcessorHandle handle, const AZ::Data::AssetId asset) + using MaterialAssetPtr = AZ::Data::Asset; + + void TrackAssetLoad(const FeatureProcessorHandle handle, const MaterialAssetPtr asset) { if (IsAssetLoading(handle)) { @@ -77,12 +79,12 @@ namespace AZ { const auto asset = EraseFromInFlightHandles(handle); - AZ_Assert(m_inFlightHandlesByAsset.count(asset) > 0, "AsyncLoadTracker in a bad state"); - auto& handleList = m_inFlightHandlesByAsset[asset]; + AZ_Assert(m_inFlightHandlesByAsset.count(asset.GetId()) > 0, "AsyncLoadTracker in a bad state"); + auto& handleList = m_inFlightHandlesByAsset[asset.GetId()]; EraseFromVector(handleList, handle); if (handleList.empty()) { - m_inFlightHandlesByAsset.erase(asset); + m_inFlightHandlesByAsset.erase(asset.GetId()); } } @@ -104,14 +106,14 @@ namespace AZ vec.pop_back(); } - void Add(const FeatureProcessorHandle handle, const AZ::Data::AssetId asset) + void Add(const FeatureProcessorHandle handle, const MaterialAssetPtr asset) { AZ_Assert(m_inFlightHandles.count(handle) == 0, "AsyncLoadTracker::Add() - told to add a handle that was already being tracked."); - m_inFlightHandlesByAsset[asset].push_back(handle); + m_inFlightHandlesByAsset[asset.GetId()].push_back(handle); m_inFlightHandles[handle] = asset; } - AZ::Data::AssetId EraseFromInFlightHandles(const FeatureProcessorHandle handle) + MaterialAssetPtr EraseFromInFlightHandles(const FeatureProcessorHandle handle) { const auto iter = m_inFlightHandles.find(handle); AZ_Assert(iter != m_inFlightHandles.end(), "Told to remove handle that was not present"); @@ -125,7 +127,7 @@ namespace AZ // Hash table that tracks the reverse of the m_inFlightHandlesByAsset hash table. // i.e. for each object, it stores what asset that it needs. - AZStd::unordered_map m_inFlightHandles; + AZStd::unordered_map m_inFlightHandles; }; } } diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp index 4000df646d..24857f8d65 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp @@ -85,7 +85,6 @@ namespace AZ m_decalData.Clear(); m_decalBufferHandler.Release(); - m_materialAssets.clear(); } DecalTextureArrayFeatureProcessor::DecalHandle DecalTextureArrayFeatureProcessor::AcquireDecal() @@ -410,7 +409,7 @@ namespace AZ int iter = m_textureArrayList.begin(); while (iter != -1) { - const auto packedTexture = m_textureArrayList[iter].second.GetPackedTexture(); + const auto& packedTexture = m_textureArrayList[iter].second.GetPackedTexture(); view->GetShaderResourceGroup()->SetImage(m_decalTextureArrayIndices[iter], packedTexture); iter = m_textureArrayList.next(iter); } @@ -482,22 +481,15 @@ namespace AZ return material; } - void DecalTextureArrayFeatureProcessor::QueueMaterialLoadForDecal(const AZ::Data::AssetId material, const DecalHandle handle) + void DecalTextureArrayFeatureProcessor::QueueMaterialLoadForDecal(const AZ::Data::AssetId materialId, const DecalHandle handle) { - // Note that another decal might have already queued this material for loading - if (m_materialLoadTracker.IsAssetLoading(material)) - { - m_materialLoadTracker.TrackAssetLoad(handle, material); - return; - } + const auto materialAsset = QueueMaterialAssetLoad(materialId); - const auto materialAsset = QueueMaterialAssetLoad(material); - m_materialAssets.emplace(material, materialAsset); - m_materialLoadTracker.TrackAssetLoad(handle, material); + m_materialLoadTracker.TrackAssetLoad(handle, materialAsset); if (materialAsset.IsLoading()) { - AZ::Data::AssetBus::MultiHandler::BusConnect(material); + AZ::Data::AssetBus::MultiHandler::BusConnect(materialId); } else if (materialAsset.IsReady()) { diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h index 825e461fc2..5301fcc61b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h @@ -136,11 +136,8 @@ namespace AZ GpuBufferHandler m_decalBufferHandler; AsyncLoadTracker m_materialLoadTracker; - AZStd::unordered_map< AZ::Data::AssetId, DecalLocationAndUseCount> m_materialToTextureArrayLookupTable; - AZStd::unordered_map> m_materialAssets; - bool m_deviceBufferNeedsUpdate = false; }; } // namespace Render From 84216f04793e17c923b744e2531c3e7d0feca27d Mon Sep 17 00:00:00 2001 From: nvsickle Date: Wed, 12 May 2021 15:58:28 -0700 Subject: [PATCH 165/225] Add API for ViewportInfoDisplayState, add some minor RHI integration --- .../Code/CMakeLists.txt | 2 + .../AtomViewportInfoDisplayBus.h | 61 ++++++++++ ...AtomViewportDisplayInfoSystemComponent.cpp | 107 +++++++++++++----- .../AtomViewportDisplayInfoSystemComponent.h | 14 +-- 4 files changed, 150 insertions(+), 34 deletions(-) create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Include/AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt index 395cc22d47..de4ee9b4b5 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt @@ -17,6 +17,8 @@ ly_add_target( INCLUDE_DIRECTORIES PRIVATE Source + PUBLIC + Include BUILD_DEPENDENCIES PRIVATE AZ::AzCore diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Include/AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Include/AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h new file mode 100644 index 0000000000..ae9359d9d3 --- /dev/null +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Include/AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h @@ -0,0 +1,61 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ +#pragma once +#include +#include + +namespace AZ +{ + namespace AtomBridge + { + //! The level of information to display in the viewport info display overlay. + enum class ViewportInfoDisplayState : int + { + NoInfo = 0, + NormalInfo = 1, + FullInfo = 2, + CompactInfo = 3, + Invalid + }; + + //! This bus is used to request changes to the viewport info display overlay. + class AtomViewportInfoDisplayRequests + : public AZ::EBusTraits + { + public: + static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single; + static const AZ::EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single; + + //! Gets the current viewport info overlay state. + virtual ViewportInfoDisplayState GetDisplayState() const = 0; + //! Sets the current viewport info overlay state. + //! The overlay will be drawn to the default viewport context every frame, if enabled. + virtual void SetDisplayState(ViewportInfoDisplayState state) = 0; + }; + + using AtomViewportInfoDisplayRequestBus = AZ::EBus; + + //! This bus is used to listen for state changes in the viewport info display overlay. + class AtomViewportInfoDisplayNotifications + : public AZ::EBusTraits + { + public: + static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single; + + //! Called when the ViewportInfoDisplayState (via the r_displayInfo CVar) has changed. + virtual void OnViewportInfoDisplayStateChanged([[maybe_unused]]ViewportInfoDisplayState state){} + }; + + using AtomViewportInfoDisplayNotificationBus = AZ::EBus; + } +} diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp index 394923071e..c9128c001f 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp @@ -21,21 +21,30 @@ #include #include #include +#include #include #include #include #include -AZ_CVAR(float, r_fpsInterval, 1.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, - "The time period over which to calculate the framerate for r_displayInfo"); - namespace AZ::Render { - static constexpr int DisplayInfoLevelNone = 0; - static constexpr int DisplayInfoLevelNormal = 1; - static constexpr int DisplayInfoLevelFull = 2; - static constexpr int DisplayInfoLevelCompact = 3; + AZ_CVAR(int, r_displayInfo, 1, [](const int& newDisplayInfoVal)->void + { + // Forward this event to the system component so it can update accordingly. + // This callback only gets triggered by console commands, so this will not recurse. + AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast( + &AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, + static_cast(newDisplayInfoVal) + ); + }, AZ::ConsoleFunctorFlags::DontReplicate, + "Toggles debugging information display.\n" + "Usage: r_displayInfo [0=off/1=show/2=enhanced/3=compact]" + ); + AZ_CVAR(float, r_fpsCalcInterval, 1.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, + "The time period over which to calculate the framerate for r_displayInfo." + ); void AtomViewportDisplayInfoSystemComponent::Reflect(AZ::ReflectContext* context) { @@ -47,7 +56,7 @@ namespace AZ::Render if (AZ::EditContext* ec = serialize->GetEditContext()) { - ec->Class("Viewport Display Info", "Manages debug viewport information through r_DisplayInfo") + ec->Class("Viewport Display Info", "Manages debug viewport information through r_displayInfo") ->ClassElement(Edit::ClassElements::EditorData, "") ->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) ->Attribute(Edit::Attributes::AutoExpand, true) @@ -83,15 +92,15 @@ namespace AZ::Render m_rendererDescription = AZStd::string::format("Atom using %s RHI", apiName.GetCStr()); } - CrySystemEventBus::Handler::BusConnect(); AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect( AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContextName()); + AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler::BusConnect(); } void AtomViewportDisplayInfoSystemComponent::Deactivate() { + AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler::BusDisconnect(); AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect(); - CrySystemEventBus::Handler::BusDisconnect(); } AZ::RPI::ViewportContextPtr AtomViewportDisplayInfoSystemComponent::GetViewportContext() const @@ -111,8 +120,13 @@ namespace AZ::Render void AtomViewportDisplayInfoSystemComponent::OnRenderTick() { + auto fontQueryInterface = AZ::Interface::Get(); + if (!fontQueryInterface) + { + return; + } AzFramework::FontDrawInterface* fontDrawInterface = - AZ::Interface::Get()->GetDefaultFontDrawInterface(); + fontQueryInterface->GetDefaultFontDrawInterface(); AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext(); if (!fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene()) @@ -120,18 +134,23 @@ namespace AZ::Render return; } - m_fpsInterval = AZStd::chrono::seconds(r_fpsInterval); + m_fpsInterval = AZStd::chrono::seconds(r_fpsCalcInterval); UpdateFramerate(); - if (!m_displayInfoCVar) + const AtomBridge::ViewportInfoDisplayState displayLevel = GetDisplayState(); + if (displayLevel == AtomBridge::ViewportInfoDisplayState::NoInfo) { return; } - int displayLevel = m_displayInfoCVar->GetIVal(); - if (displayLevel == DisplayInfoLevelNone) + + if (m_updateRootPassQuery) { - return; + if (auto rootPass = AZ::RPI::PassSystemInterface::Get()->GetRootPass()) + { + rootPass->SetPipelineStatisticsQueryEnabled(displayLevel == AtomBridge::ViewportInfoDisplayState::FullInfo); + m_updateRootPassQuery = false; + } } m_drawParams.m_drawViewportId = viewportContext->GetId(); @@ -152,22 +171,30 @@ namespace AZ::Render m_lineSpacing = lineHeight * m_drawParams.m_lineSpacing; DrawRendererInfo(); - if (displayLevel != DisplayInfoLevelCompact) + if (displayLevel == AtomBridge::ViewportInfoDisplayState::FullInfo) { DrawCameraInfo(); + DrawPassInfo(); + } + if (displayLevel != AtomBridge::ViewportInfoDisplayState::CompactInfo) + { DrawMemoryInfo(); } DrawFramerate(); } - void AtomViewportDisplayInfoSystemComponent::OnCrySystemInitialized(ISystem& system, [[maybe_unused]]const SSystemInitParams& initParams) + AtomBridge::ViewportInfoDisplayState AtomViewportDisplayInfoSystemComponent::GetDisplayState() const { - m_displayInfoCVar = system.GetGlobalEnvironment()->pConsole->GetCVar("r_DisplayInfo"); + return static_cast(r_displayInfo.operator int()); } - void AtomViewportDisplayInfoSystemComponent::OnCrySystemShutdown([[maybe_unused]]ISystem& system) + void AtomViewportDisplayInfoSystemComponent::SetDisplayState(AtomBridge::ViewportInfoDisplayState state) { - m_displayInfoCVar = nullptr; + r_displayInfo = static_cast(state); + AtomBridge::AtomViewportInfoDisplayNotificationBus::Broadcast( + &AtomBridge::AtomViewportInfoDisplayNotificationBus::Events::OnViewportInfoDisplayStateChanged, + state); + m_updateRootPassQuery = true; } void AtomViewportDisplayInfoSystemComponent::DrawRendererInfo() @@ -198,6 +225,31 @@ namespace AZ::Render )); } + void AtomViewportDisplayInfoSystemComponent::DrawPassInfo() + { + auto rootPass = AZ::RPI::PassSystemInterface::Get()->GetRootPass(); + const RPI::PipelineStatisticsResult stats = rootPass->GetLatestPipelineStatisticsResult(); + AZStd::function)> containingPassCount = [&containingPassCount](const AZ::RPI::Ptr pass) + { + int count = 1; + if (auto passAsParent = pass->AsParent()) + { + for (const auto child : passAsParent->GetChildren()) + { + count += containingPassCount(child); + } + } + return count; + }; + const int numPasses = containingPassCount(rootPass); + DrawLine(AZStd::string::format( + "Total Passes: %d Vertex Count: %d Primitive Count: %d", + numPasses, + stats.m_vertexCount, + stats.m_primitiveCount + )); + } + void AtomViewportDisplayInfoSystemComponent::DrawMemoryInfo() { static IMemoryManager::SProcessMemInfo processMemInfo; @@ -236,11 +288,16 @@ namespace AZ::Render AZ::ScriptTimePoint currentTime = m_tickRequests->GetTimeAtCurrentTick(); // Only keep as much sampling data is is required by our FPS history. - while (!m_fpsHistory.empty() && (currentTime.Get() - m_fpsHistory.front().Get() > m_fpsInterval)) + while (!m_fpsHistory.empty() && (currentTime.Get() - m_fpsHistory.front().Get()) > m_fpsInterval) { m_fpsHistory.pop_front(); } - m_fpsHistory.push_back(currentTime); + + // Discard entries with a zero time-delta (can happen when we don't have window focus). + if (m_fpsHistory.empty() || (currentTime.Get() - m_fpsHistory.back().Get()) != AZStd::chrono::seconds(0)) + { + m_fpsHistory.push_back(currentTime); + } } void AtomViewportDisplayInfoSystemComponent::DrawFramerate() @@ -254,10 +311,6 @@ namespace AZ::Render if (lastTime.has_value()) { AZStd::chrono::duration deltaTime = time.Get() - lastTime.value().Get(); - if (deltaTime.count() == 0.0) - { - continue; - } double fps = AZStd::chrono::seconds(1) / deltaTime; if (!minFPS.has_value()) { diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h index 5cb6ed3308..ac6c2bab65 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h @@ -19,8 +19,7 @@ #include #include #include - -struct ICVar; +#include namespace AZ { @@ -31,7 +30,7 @@ namespace AZ class AtomViewportDisplayInfoSystemComponent : public AZ::Component , public AZ::RPI::ViewportContextNotificationBus::Handler - , public CrySystemEventBus::Handler + , public AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler { public: AZ_COMPONENT(AtomViewportDisplayInfoSystemComponent, "{AC32F173-E7E2-4943-8E6C-7C3091978221}"); @@ -51,9 +50,9 @@ namespace AZ // AZ::RPI::ViewportContextNotificationBus::Handler overrides... void OnRenderTick() override; - // CrySystemEventBus::Handler overrides... - void OnCrySystemInitialized(ISystem& system, const SSystemInitParams& initParams) override; - void OnCrySystemShutdown(ISystem& system) override; + // AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler overrides... + AtomBridge::ViewportInfoDisplayState GetDisplayState() const override; + void SetDisplayState(AtomBridge::ViewportInfoDisplayState state) override; private: AZ::RPI::ViewportContextPtr GetViewportContext() const; @@ -63,6 +62,7 @@ namespace AZ void DrawRendererInfo(); void DrawCameraInfo(); + void DrawPassInfo(); void DrawMemoryInfo(); void DrawFramerate(); @@ -73,7 +73,7 @@ namespace AZ AZStd::deque m_fpsHistory; AZStd::optional m_lastMemoryUpdate; AZ::TickRequests* m_tickRequests = nullptr; - ICVar* m_displayInfoCVar = nullptr; + bool m_updateRootPassQuery = true; }; } // namespace Render } // namespace AZ From cb09d542d1207e437dfca27b68cd2133776c78f9 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Wed, 12 May 2021 15:59:21 -0700 Subject: [PATCH 166/225] Use the new Atom API instead of the removed r_displayInfo for ViewportTitleDlg --- Code/Sandbox/Editor/CMakeLists.txt | 1 + Code/Sandbox/Editor/ViewportTitleDlg.cpp | 75 ++++++++++++++++++++---- Code/Sandbox/Editor/ViewportTitleDlg.h | 4 +- 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/Code/Sandbox/Editor/CMakeLists.txt b/Code/Sandbox/Editor/CMakeLists.txt index 7d89717391..2be48777d3 100644 --- a/Code/Sandbox/Editor/CMakeLists.txt +++ b/Code/Sandbox/Editor/CMakeLists.txt @@ -124,6 +124,7 @@ ly_add_target( Gem::Atom_RPI.Public Gem::Atom_Feature_Common.Static Gem::AtomToolsFramework.Static + Gem::AtomViewportDisplayInfo ${additional_dependencies} PUBLIC 3rdParty::AWSNativeSDK::Core diff --git a/Code/Sandbox/Editor/ViewportTitleDlg.cpp b/Code/Sandbox/Editor/ViewportTitleDlg.cpp index 95531e117c..159fccfd64 100644 --- a/Code/Sandbox/Editor/ViewportTitleDlg.cpp +++ b/Code/Sandbox/Editor/ViewportTitleDlg.cpp @@ -13,7 +13,7 @@ // Description : CViewportTitleDlg implementation file - +#if !defined(Q_MOC_RUN) #include "EditorDefs.h" #include "ViewportTitleDlg.h" @@ -36,10 +36,13 @@ #include "UsedResources.h" #include "Include/IObjectManager.h" +#include + AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING #include "ui_ViewportTitleDlg.h" AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING +#endif //!defined(Q_MOC_RUN) // CViewportTitleDlg dialog @@ -63,6 +66,32 @@ inline namespace Helpers } } +namespace +{ + class CViewportTitleDlgDisplayInfoHelper + : public QObject + , public AZ::AtomBridge::AtomViewportInfoDisplayNotificationBus::Handler + { + Q_OBJECT + + public: + CViewportTitleDlgDisplayInfoHelper(CViewportTitleDlg* parent) + : QObject(parent) + { + AZ::AtomBridge::AtomViewportInfoDisplayNotificationBus::Handler::BusConnect(); + } + + signals: + void ViewportInfoStatusUpdated(int newIndex); + + private: + void OnViewportInfoDisplayStateChanged(AZ::AtomBridge::ViewportInfoDisplayState state) + { + emit ViewportInfoStatusUpdated(static_cast(state)); + } + }; +} //end anonymous namespace + CViewportTitleDlg::CViewportTitleDlg(QWidget* pParent) : QWidget(pParent) , m_ui(new Ui::ViewportTitleDlg) @@ -115,14 +144,11 @@ void CViewportTitleDlg::OnInitDialog() m_ui->m_toggleHelpersBtn->setChecked(GetIEditor()->GetDisplaySettings()->IsDisplayHelpers()); - ICVar* pDisplayInfo(gEnv->pConsole->GetCVar("r_displayInfo")); - if (pDisplayInfo) - { - SFunctor oFunctor; - oFunctor.Set(OnChangedDisplayInfo, pDisplayInfo, m_ui->m_toggleDisplayInfoBtn); - m_displayInfoCallbackIndex = pDisplayInfo->AddOnChangeFunctor(oFunctor); - OnChangedDisplayInfo(pDisplayInfo, m_ui->m_toggleDisplayInfoBtn); - } + + // Add a child parented to us that listens for r_displayInfo changes. + auto displayInfoHelper = new CViewportTitleDlgDisplayInfoHelper(this); + connect(displayInfoHelper, &CViewportTitleDlgDisplayInfoHelper::ViewportInfoStatusUpdated, this, &CViewportTitleDlg::UpdateDisplayInfo); + UpdateDisplayInfo(); connect(m_ui->m_toggleHelpersBtn, &QToolButton::clicked, this, &CViewportTitleDlg::OnToggleHelpers); connect(m_ui->m_toggleDisplayInfoBtn, &QToolButton::clicked, this, &CViewportTitleDlg::OnToggleDisplayInfo); @@ -156,6 +182,32 @@ void CViewportTitleDlg::OnToggleHelpers() ////////////////////////////////////////////////////////////////////////// void CViewportTitleDlg::OnToggleDisplayInfo() { + AZ::AtomBridge::ViewportInfoDisplayState state = AZ::AtomBridge::ViewportInfoDisplayState::NoInfo; + AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::BroadcastResult( + state, + &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::GetDisplayState + ); + state = static_cast(static_cast(state)+1); + if (state == AZ::AtomBridge::ViewportInfoDisplayState::Invalid) + { + state = AZ::AtomBridge::ViewportInfoDisplayState::NoInfo; + } + // SetDisplayState will fire OnViewportInfoDisplayStateChanged and notify us, no need to call UpdateDisplayInfo. + AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast( + &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, + state + ); +} + +////////////////////////////////////////////////////////////////////////// +void CViewportTitleDlg::UpdateDisplayInfo() +{ + AZ::AtomBridge::ViewportInfoDisplayState state = AZ::AtomBridge::ViewportInfoDisplayState::NoInfo; + AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::BroadcastResult( + state, + &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::GetDisplayState + ); + m_ui->m_toggleDisplayInfoBtn->setChecked(state != AZ::AtomBridge::ViewportInfoDisplayState::NoInfo); } ////////////////////////////////////////////////////////////////////////// @@ -544,10 +596,6 @@ void CViewportTitleDlg::UpdateCustomPresets(const QString& text, QStringList& cu } } -void CViewportTitleDlg::OnChangedDisplayInfo([[maybe_unused]] ICVar* pDisplayInfo, [[maybe_unused]] QAbstractButton* pDisplayInfoButton) -{ -} - bool CViewportTitleDlg::eventFilter(QObject* object, QEvent* event) { bool consumeEvent = false; @@ -609,4 +657,5 @@ namespace AzToolsFramework } } +#include "ViewportTitleDlg.moc" #include diff --git a/Code/Sandbox/Editor/ViewportTitleDlg.h b/Code/Sandbox/Editor/ViewportTitleDlg.h index 55741636b3..ce2f116d97 100644 --- a/Code/Sandbox/Editor/ViewportTitleDlg.h +++ b/Code/Sandbox/Editor/ViewportTitleDlg.h @@ -60,7 +60,6 @@ public: static void LoadCustomPresets(const QString& section, const QString& keyName, QStringList& outCustompresets); static void SaveCustomPresets(const QString& section, const QString& keyName, const QStringList& custompresets); static void UpdateCustomPresets(const QString& text, QStringList& custompresets); - static void OnChangedDisplayInfo(ICVar* pDisplayInfo, QAbstractButton* pDisplayInfoButton); bool eventFilter(QObject* object, QEvent* event) override; @@ -77,6 +76,7 @@ protected: void OnMaximize(); void OnToggleHelpers(); void OnToggleDisplayInfo(); + void UpdateDisplayInfo(); QString m_title; @@ -87,8 +87,6 @@ protected: QStringList m_customFOVPresets; QStringList m_customAspectRatioPresets; - uint64 m_displayInfoCallbackIndex; - void OnMenuFOVCustom(); void CreateFOVMenu(); From 254ad165c15b3d433b852cb05a06f563ccb4fff4 Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 16:01:59 -0700 Subject: [PATCH 167/225] A bunch of work to get external multiplayer components to actually work --- .../{ => Multiplayer}/IConnectionData.h | 2 +- .../Include/{ => Multiplayer}/IEntityDomain.h | 2 +- .../Include/{ => Multiplayer}/IMultiplayer.h | 6 +-- .../IMultiplayerComponentInput.h | 2 +- .../{ => Multiplayer}/INetworkEntityManager.h | 4 +- .../Multiplayer/INetworkPlayerSpawner.h | 0 .../Include/{ => Multiplayer}/INetworkTime.h | 2 +- .../{ => Multiplayer}/IReplicationWindow.h | 4 +- .../Multiplayer}/MultiplayerComponent.h | 6 +-- .../MultiplayerComponentRegistry.h | 2 +- .../Multiplayer}/MultiplayerController.h | 8 +--- .../{ => Multiplayer}/MultiplayerStats.cpp | 2 +- .../{ => Multiplayer}/MultiplayerStats.h | 2 +- .../{ => Multiplayer}/MultiplayerTypes.h | 0 .../Multiplayer}/NetBindComponent.h | 11 ++--- .../{ => Multiplayer}/NetworkEntityHandle.h | 4 +- .../{ => Multiplayer}/NetworkEntityHandle.inl | 0 .../Multiplayer}/NetworkEntityRpcMessage.h | 2 +- .../Multiplayer}/NetworkEntityUpdateMessage.h | 2 +- .../Multiplayer}/NetworkInput.h | 6 +-- .../Multiplayer}/ReplicationRecord.h | 2 +- .../Multiplayer}/RewindableObject.h | 4 +- .../Multiplayer}/RewindableObject.inl | 0 .../AutoGen/AutoComponentTypes_Header.jinja | 2 +- .../AutoGen/AutoComponentTypes_Source.jinja | 8 ++-- .../Source/AutoGen/AutoComponent_Header.jinja | 26 +++++------ .../Source/AutoGen/AutoComponent_Source.jinja | 10 ++-- ...tionPlayerInputComponent.AutoComponent.xml | 4 +- .../AutoGen/Multiplayer.AutoPackets.xml | 8 ++-- ...etworkTransformComponent.AutoComponent.xml | 2 +- .../LocalPredictionPlayerInputComponent.h | 2 +- .../Components/MultiplayerComponent.cpp | 4 +- .../MultiplayerComponentRegistry.cpp | 2 +- .../Components/MultiplayerController.cpp | 6 +-- .../Source/Components/NetBindComponent.cpp | 29 +++--------- .../ClientToServerConnectionData.h | 2 +- .../ServerToClientConnectionData.h | 2 +- .../EntityDomains/FullOwnershipEntityDomain.h | 2 +- .../Code/Source/MultiplayerGem.cpp | 2 +- .../Source/MultiplayerSystemComponent.cpp | 2 +- .../Code/Source/MultiplayerSystemComponent.h | 2 +- .../EntityReplicationManager.cpp | 14 +++--- .../EntityReplicationManager.h | 10 ++-- .../EntityReplication/EntityReplicator.cpp | 6 +-- .../EntityReplication/EntityReplicator.h | 4 +- .../EntityReplication/PropertyPublisher.h | 2 +- .../EntityReplication/PropertySubscriber.cpp | 2 +- .../EntityReplication/ReplicationRecord.cpp | 2 +- .../NetworkEntityAuthorityTracker.cpp | 4 +- .../NetworkEntity/NetworkEntityHandle.cpp | 8 ++-- .../NetworkEntity/NetworkEntityManager.cpp | 5 +- .../NetworkEntity/NetworkEntityManager.h | 8 ++-- .../NetworkEntity/NetworkEntityRpcMessage.cpp | 2 +- .../NetworkEntity/NetworkEntityTracker.cpp | 2 +- .../NetworkEntity/NetworkEntityTracker.h | 4 +- .../NetworkEntityUpdateMessage.cpp | 2 +- .../Code/Source/NetworkInput/NetworkInput.cpp | 4 +- .../Source/NetworkInput/NetworkInputArray.cpp | 2 +- .../Source/NetworkInput/NetworkInputArray.h | 4 +- .../Source/NetworkInput/NetworkInputChild.cpp | 2 +- .../Source/NetworkInput/NetworkInputChild.h | 2 +- .../Source/NetworkInput/NetworkInputHistory.h | 2 +- .../NetworkInputMigrationVector.cpp | 2 +- .../NetworkInputMigrationVector.h | 4 +- .../Code/Source/NetworkTime/NetworkTime.cpp | 4 +- .../Code/Source/NetworkTime/NetworkTime.h | 2 +- .../NullReplicationWindow.h | 2 +- .../ServerToClientReplicationWindow.cpp | 2 +- .../ServerToClientReplicationWindow.h | 6 +-- Gems/Multiplayer/Code/multiplayer_files.cmake | 46 +++++++++---------- 70 files changed, 162 insertions(+), 185 deletions(-) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/IConnectionData.h (97%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/IEntityDomain.h (97%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/IMultiplayer.h (98%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/IMultiplayerComponentInput.h (96%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/INetworkEntityManager.h (98%) create mode 100644 Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/INetworkTime.h (98%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/IReplicationWindow.h (94%) rename Gems/Multiplayer/Code/{Source/Components => Include/Multiplayer}/MultiplayerComponent.h (97%) rename Gems/Multiplayer/Code/{Source/Components => Include/Multiplayer}/MultiplayerComponentRegistry.h (98%) rename Gems/Multiplayer/Code/{Source/Components => Include/Multiplayer}/MultiplayerController.h (90%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/MultiplayerStats.cpp (99%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/MultiplayerStats.h (98%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/MultiplayerTypes.h (100%) rename Gems/Multiplayer/Code/{Source/Components => Include/Multiplayer}/NetBindComponent.h (95%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/NetworkEntityHandle.h (98%) rename Gems/Multiplayer/Code/Include/{ => Multiplayer}/NetworkEntityHandle.inl (100%) rename Gems/Multiplayer/Code/{Source/NetworkEntity => Include/Multiplayer}/NetworkEntityRpcMessage.h (99%) rename Gems/Multiplayer/Code/{Source/NetworkEntity => Include/Multiplayer}/NetworkEntityUpdateMessage.h (99%) rename Gems/Multiplayer/Code/{Source/NetworkInput => Include/Multiplayer}/NetworkInput.h (95%) rename Gems/Multiplayer/Code/{Source/NetworkEntity/EntityReplication => Include/Multiplayer}/ReplicationRecord.h (98%) rename Gems/Multiplayer/Code/{Source/NetworkTime => Include/Multiplayer}/RewindableObject.h (98%) rename Gems/Multiplayer/Code/{Source/NetworkTime => Include/Multiplayer}/RewindableObject.inl (100%) diff --git a/Gems/Multiplayer/Code/Include/IConnectionData.h b/Gems/Multiplayer/Code/Include/Multiplayer/IConnectionData.h similarity index 97% rename from Gems/Multiplayer/Code/Include/IConnectionData.h rename to Gems/Multiplayer/Code/Include/Multiplayer/IConnectionData.h index dcc2c940ef..39fdb61435 100644 --- a/Gems/Multiplayer/Code/Include/IConnectionData.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IConnectionData.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Include/IEntityDomain.h b/Gems/Multiplayer/Code/Include/Multiplayer/IEntityDomain.h similarity index 97% rename from Gems/Multiplayer/Code/Include/IEntityDomain.h rename to Gems/Multiplayer/Code/Include/Multiplayer/IEntityDomain.h index 6571797d05..70215612b0 100644 --- a/Gems/Multiplayer/Code/Include/IEntityDomain.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IEntityDomain.h @@ -12,7 +12,7 @@ #pragma once -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Include/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h similarity index 98% rename from Gems/Multiplayer/Code/Include/IMultiplayer.h rename to Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 80bdaa68eb..665661b55b 100644 --- a/Gems/Multiplayer/Code/Include/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -15,9 +15,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include namespace AzNetworking { diff --git a/Gems/Multiplayer/Code/Include/IMultiplayerComponentInput.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerComponentInput.h similarity index 96% rename from Gems/Multiplayer/Code/Include/IMultiplayerComponentInput.h rename to Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerComponentInput.h index b5df01a1a8..b26feadc4f 100644 --- a/Gems/Multiplayer/Code/Include/IMultiplayerComponentInput.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerComponentInput.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Include/INetworkEntityManager.h b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkEntityManager.h similarity index 98% rename from Gems/Multiplayer/Code/Include/INetworkEntityManager.h rename to Gems/Multiplayer/Code/Include/Multiplayer/INetworkEntityManager.h index ebb95e2281..17224e64cb 100644 --- a/Gems/Multiplayer/Code/Include/INetworkEntityManager.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkEntityManager.h @@ -12,8 +12,8 @@ #pragma once -#include -#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Gems/Multiplayer/Code/Include/INetworkTime.h b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h similarity index 98% rename from Gems/Multiplayer/Code/Include/INetworkTime.h rename to Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h index 1ccf08bbdc..c228e135ee 100644 --- a/Gems/Multiplayer/Code/Include/INetworkTime.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h @@ -14,7 +14,7 @@ #include #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Include/IReplicationWindow.h b/Gems/Multiplayer/Code/Include/Multiplayer/IReplicationWindow.h similarity index 94% rename from Gems/Multiplayer/Code/Include/IReplicationWindow.h rename to Gems/Multiplayer/Code/Include/Multiplayer/IReplicationWindow.h index eb34a2f87d..d0192e8aa4 100644 --- a/Gems/Multiplayer/Code/Include/IReplicationWindow.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IReplicationWindow.h @@ -12,8 +12,8 @@ #pragma once -#include -#include +#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponent.h similarity index 97% rename from Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.h rename to Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponent.h index 0f64221dde..29348a698a 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponent.h @@ -15,9 +15,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include //! Macro to declare bindings for a multiplayer component inheriting from MultiplayerComponent #define AZ_MULTIPLAYER_COMPONENT(ComponentClass, Guid, Base) \ diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.h b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponentRegistry.h similarity index 98% rename from Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.h rename to Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponentRegistry.h index e16f942100..d06362ed4b 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponentRegistry.h @@ -14,7 +14,7 @@ #include #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerController.h b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerController.h similarity index 90% rename from Gems/Multiplayer/Code/Source/Components/MultiplayerController.h rename to Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerController.h index de07e39e66..89c47c40d4 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerController.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerController.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer @@ -84,12 +84,6 @@ namespace Multiplayer //! Returns the input priority ordering for determining the order of ProcessInput or CreateInput functions. virtual InputPriorityOrder GetInputOrder() const = 0; - //! Queries the rewind system to determine what volume is relevent for a given input, this is very important for performance at scale. - //! @param networkInput input structure to process - //! @param deltaTime amount of time the provided input would be integrated over - //! @return a world-space aabb representing the volume relevent to the provided input - virtual AZ::Aabb GetRewindBoundsForInput(const NetworkInput& networkInput, float deltaTime) const = 0; - //! Base execution for ProcessInput packet, do not call directly. //! @param networkInput input structure to process //! @param deltaTime amount of time to integrate the provided inputs over diff --git a/Gems/Multiplayer/Code/Include/MultiplayerStats.cpp b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.cpp similarity index 99% rename from Gems/Multiplayer/Code/Include/MultiplayerStats.cpp rename to Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.cpp index 7672997ad5..1f063b749d 100644 --- a/Gems/Multiplayer/Code/Include/MultiplayerStats.cpp +++ b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.cpp @@ -10,7 +10,7 @@ * */ -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Include/MultiplayerStats.h b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.h similarity index 98% rename from Gems/Multiplayer/Code/Include/MultiplayerStats.h rename to Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.h index dc266a14bf..5d00c4d205 100644 --- a/Gems/Multiplayer/Code/Include/MultiplayerStats.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include namespace AzNetworking { diff --git a/Gems/Multiplayer/Code/Include/MultiplayerTypes.h b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerTypes.h similarity index 100% rename from Gems/Multiplayer/Code/Include/MultiplayerTypes.h rename to Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerTypes.h diff --git a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetBindComponent.h similarity index 95% rename from Gems/Multiplayer/Code/Source/Components/NetBindComponent.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetBindComponent.h index 0885e44aa4..464333e3b2 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetBindComponent.h @@ -20,11 +20,11 @@ #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include namespace Multiplayer @@ -73,7 +73,6 @@ namespace Multiplayer bool IsProcessingInput() const; void CreateInput(NetworkInput& networkInput, float deltaTime); void ProcessInput(NetworkInput& networkInput, float deltaTime); - AZ::Aabb GetRewindBoundsForInput(const NetworkInput& networkInput, float deltaTime) const; bool HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetEntityRole remoteRole, NetworkEntityRpcMessage& message); bool HandlePropertyChangeMessage(AzNetworking::ISerializer& serializer, bool notifyChanges = true); diff --git a/Gems/Multiplayer/Code/Include/NetworkEntityHandle.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.h similarity index 98% rename from Gems/Multiplayer/Code/Include/NetworkEntityHandle.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.h index 9b8546ef2c..813589fac6 100644 --- a/Gems/Multiplayer/Code/Include/NetworkEntityHandle.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.h @@ -13,7 +13,7 @@ #pragma once #include -#include +#include namespace Multiplayer { @@ -138,4 +138,4 @@ namespace Multiplayer }; } -#include +#include diff --git a/Gems/Multiplayer/Code/Include/NetworkEntityHandle.inl b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.inl similarity index 100% rename from Gems/Multiplayer/Code/Include/NetworkEntityHandle.inl rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.inl diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityRpcMessage.h similarity index 99% rename from Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityRpcMessage.h index 08b1960172..f6a7ff2c65 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityRpcMessage.h @@ -14,7 +14,7 @@ #include #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityUpdateMessage.h similarity index 99% rename from Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityUpdateMessage.h index 9ca539d75d..e96191262a 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityUpdateMessage.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput.h similarity index 95% rename from Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput.h index b2b0fa12c6..9c6d2ce66a 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput.h @@ -12,9 +12,9 @@ #pragma once -#include -#include -#include +#include +#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.h b/Gems/Multiplayer/Code/Include/Multiplayer/ReplicationRecord.h similarity index 98% rename from Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.h rename to Gems/Multiplayer/Code/Include/Multiplayer/ReplicationRecord.h index 83721a5539..f6eb93c4ba 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/ReplicationRecord.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.h b/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.h similarity index 98% rename from Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.h rename to Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.h index 4e830d4480..9e1655aec7 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include #include #include @@ -115,4 +115,4 @@ namespace AZ AZ_TYPE_INFO_TEMPLATE(Multiplayer::RewindableObject, "{B2937B44-FEE1-4277-B1E0-863DE76D363F}", AZ_TYPE_INFO_TYPENAME, AZ_TYPE_INFO_AUTO); } -#include +#include diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.inl b/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.inl similarity index 100% rename from Gems/Multiplayer/Code/Source/NetworkTime/RewindableObject.inl rename to Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.inl diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Header.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Header.jinja index fc2860ebe7..849b4245e2 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Header.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Header.jinja @@ -1,7 +1,7 @@ #pragma once #include -#include +#include namespace AZ { diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja index 2acc252729..453d74c907 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include {% for Component in dataFiles %} {% set ComponentDerived = Component.attrib['OverrideComponent']|booleanTrue %} {% set ControllerDerived = Component.attrib['OverrideController']|booleanTrue %} @@ -21,8 +21,8 @@ namespace {{ Namespace }} { void RegisterMultiplayerComponents() { - Multiplayer::MultiplayerComponentRegistry* multiplayerComponentRegistry = GetMultiplayerComponentRegistry(); - Multiplayer::MultiplayerStats& stats = GetMultiplayer()->GetStats(); + Multiplayer::MultiplayerComponentRegistry* multiplayerComponentRegistry = Multiplayer::GetMultiplayerComponentRegistry(); + Multiplayer::MultiplayerStats& stats = Multiplayer::GetMultiplayer()->GetStats(); {% for Component in dataFiles %} {% set ComponentName = Component.attrib['Name'] %} {% set ComponentBaseName = ComponentName %} diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja index faaa009e34..c22945c983 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja @@ -221,13 +221,14 @@ AZStd::fixed_vector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] } #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include {% call(Include) AutoComponentMacros.ParseIncludes(Component) %} #include <{{ Include.attrib['File'] }}> {% endcall %} @@ -359,7 +360,6 @@ namespace {{ Component.attrib['Namespace'] }} //! MultiplayerController interface //! @{ Multiplayer::MultiplayerController::InputPriorityOrder GetInputOrder() const override { return Multiplayer::MultiplayerController::InputPriorityOrder::Default; } - AZ::Aabb GetRewindBoundsForInput([[maybe_unused]] const NetworkInput& networkInput, [[maybe_unused]] float deltaTime) const override { return AZ::Aabb::CreateNull(); } void CreateInput([[maybe_unused]] Multiplayer::NetworkInput& input, [[maybe_unused]] float deltaTime) override {} void ProcessInput([[maybe_unused]] Multiplayer::NetworkInput& input, [[maybe_unused]] float deltaTime) override {} //! @} @@ -434,12 +434,12 @@ namespace {{ Component.attrib['Namespace'] }} //! MultiplayerComponent interface //! @{ - NetComponentId GetNetComponentId() const override; + Multiplayer::NetComponentId GetNetComponentId() const override; bool HandleRpcMessage(AzNetworking::IConnection* invokingConnection, Multiplayer::NetEntityRole remoteRole, Multiplayer::NetworkEntityRpcMessage& rpcMessage) override; bool SerializeStateDeltaMessage(Multiplayer::ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer) override; void NotifyStateDeltaChanges(Multiplayer::ReplicationRecord& replicationRecord) override; bool HasController() const override; - MultiplayerController* GetController() override; + Multiplayer::MultiplayerController* GetController() override; protected: void ConstructController() override; @@ -484,8 +484,8 @@ namespace {{ Component.attrib['Namespace'] }} void NotifyChangesAutonomousToAuthorityProperties(const {{ RecordName }}& replicationRecord) const; //! Debug name helpers - static const char* GetNetworkPropertyName(PropertyIndex propertyIndex); - static const char* GetRpcName(RpcIndex rpcIndex); + static const char* GetNetworkPropertyName(Multiplayer::PropertyIndex propertyIndex); + static const char* GetRpcName(Multiplayer::RpcIndex rpcIndex); AZStd::unique_ptr<{{ RecordName }}> m_currentRecord; AZStd::unique_ptr<{{ ControllerName }}> m_controller; @@ -517,7 +517,7 @@ namespace {{ Component.attrib['Namespace'] }} {{ Type }}* {{ Name }} = nullptr; {% endcall %} - static NetComponentId s_netComponentId; + static Multiplayer::NetComponentId s_netComponentId; friend void RegisterMultiplayerComponents(); }; } diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index d719cbe47b..1bc6dc3994 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -902,8 +902,8 @@ m_{{ LowerFirst(Property.attrib['Name']) }} = m_{{ LowerFirst(Property.attrib['N #include #include #include -#include -#include +#include +#include {% if ComponentDerived or ControllerDerived %} #include <{{ Component.attrib['OverrideInclude'] }}> {% endif %} @@ -915,7 +915,7 @@ m_{{ LowerFirst(Property.attrib['Name']) }} = m_{{ LowerFirst(Property.attrib['N namespace {{ Component.attrib['Namespace'] }} { - NetComponentId {{ UpperFirst(ComponentBaseName) }}::s_netComponentId = InvalidNetComponentId; + Multiplayer::NetComponentId {{ UpperFirst(ComponentBaseName) }}::s_netComponentId = Multiplayer::InvalidNetComponentId; namespace {{ UpperFirst(Component.attrib['Name']) }}Internal { @@ -1408,7 +1408,7 @@ namespace {{ Component.attrib['Namespace'] }} } {% endif %} - const char* {{ ComponentBaseName }}::GetNetworkPropertyName([[maybe_unused]] PropertyIndex propertyIndex) + const char* {{ ComponentBaseName }}::GetNetworkPropertyName([[maybe_unused]] Multiplayer::PropertyIndex propertyIndex) { {% if NetworkPropertyCount > 0 %} const {{ UpperFirst(Component.attrib['Name']) }}Internal::NetworkProperties propertyId = static_cast<{{ UpperFirst(Component.attrib['Name']) }}Internal::NetworkProperties>(propertyIndex); @@ -1423,7 +1423,7 @@ namespace {{ Component.attrib['Namespace'] }} return "Unknown network property"; } - const char* {{ ComponentBaseName }}::GetRpcName([[maybe_unused]] RpcIndex rpcIndex) + const char* {{ ComponentBaseName }}::GetRpcName([[maybe_unused]] Multiplayer::RpcIndex rpcIndex) { {% if RpcCount > 0 %} const {{ UpperFirst(Component.attrib['Name']) }}Internal::RemoteProcedure rpcId = static_cast<{{ UpperFirst(Component.attrib['Name']) }}Internal::RemoteProcedure>(rpcIndex); diff --git a/Gems/Multiplayer/Code/Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.xml b/Gems/Multiplayer/Code/Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.xml index 44edcaf505..a5a7e8decd 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.xml +++ b/Gems/Multiplayer/Code/Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.xml @@ -10,8 +10,8 @@ - - + + diff --git a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml index daf55c3d92..1260075cba 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml +++ b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml @@ -2,10 +2,10 @@ - - - - + + + + diff --git a/Gems/Multiplayer/Code/Source/AutoGen/NetworkTransformComponent.AutoComponent.xml b/Gems/Multiplayer/Code/Source/AutoGen/NetworkTransformComponent.AutoComponent.xml index 46065b386f..e76ac75edc 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/NetworkTransformComponent.AutoComponent.xml +++ b/Gems/Multiplayer/Code/Source/AutoGen/NetworkTransformComponent.AutoComponent.xml @@ -10,7 +10,7 @@ - + diff --git a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.h b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.h index 15a4f3a048..924fd78391 100644 --- a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.h +++ b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.h @@ -13,7 +13,7 @@ #pragma once #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp index fcdad87416..ae6fc50f5a 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp @@ -10,8 +10,8 @@ * */ -#include -#include +#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.cpp b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.cpp index de1782cc59..648b28633e 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.cpp +++ b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.cpp @@ -10,7 +10,7 @@ * */ -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp b/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp index 737ecc10cc..9b8f41d5bc 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp +++ b/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp @@ -10,9 +10,9 @@ * */ -#include -#include -#include +#include +#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp index eba09734a9..6dc661415e 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp @@ -10,13 +10,13 @@ * */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -177,21 +177,6 @@ namespace Multiplayer } } - AZ::Aabb NetBindComponent::GetRewindBoundsForInput(const NetworkInput& networkInput, float deltaTime) const - { - AZ_Assert(m_netEntityRole == NetEntityRole::Authority, "Incorrect network role for computing rewind bounds"); - AZ::Aabb bounds = AZ::Aabb::CreateNull(); - for (MultiplayerComponent* multiplayerComponent : m_multiplayerInputComponentVector) - { - const AZ::Aabb componentBounds = multiplayerComponent->GetController()->GetRewindBoundsForInput(networkInput, deltaTime); - if (componentBounds.IsValid()) - { - bounds.AddAabb(componentBounds); - } - } - return bounds; - } - bool NetBindComponent::HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetEntityRole remoteRole, NetworkEntityRpcMessage& message) { auto findIt = m_multiplayerComponentMap.find(message.GetComponentId()); diff --git a/Gems/Multiplayer/Code/Source/ConnectionData/ClientToServerConnectionData.h b/Gems/Multiplayer/Code/Source/ConnectionData/ClientToServerConnectionData.h index b72a6aad2b..449ffafe45 100644 --- a/Gems/Multiplayer/Code/Source/ConnectionData/ClientToServerConnectionData.h +++ b/Gems/Multiplayer/Code/Source/ConnectionData/ClientToServerConnectionData.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h b/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h index b02e6de9aa..6274a6ba31 100644 --- a/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h +++ b/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/EntityDomains/FullOwnershipEntityDomain.h b/Gems/Multiplayer/Code/Source/EntityDomains/FullOwnershipEntityDomain.h index c1abbe74cd..3bf6eb554f 100644 --- a/Gems/Multiplayer/Code/Source/EntityDomains/FullOwnershipEntityDomain.h +++ b/Gems/Multiplayer/Code/Source/EntityDomains/FullOwnershipEntityDomain.h @@ -12,7 +12,7 @@ #pragma once -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/MultiplayerGem.cpp b/Gems/Multiplayer/Code/Source/MultiplayerGem.cpp index cafdbf2a09..aef3e546ad 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerGem.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerGem.cpp @@ -13,10 +13,10 @@ #include #include #include -#include #include #include #include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 15b6b48631..715d9a8527 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -11,13 +11,13 @@ */ #include -#include #include #include #include #include #include #include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index 1de8fccb50..ba59a82eae 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp index 65df4f1464..6eefeaf5fe 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp @@ -14,14 +14,14 @@ #include #include #include -#include -#include -#include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.h b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.h index 4fc14e210f..50a4ad43d4 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.h @@ -13,11 +13,11 @@ #pragma once #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp index 197d83a48c..15293d518d 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp @@ -16,11 +16,11 @@ #include #include #include -#include -#include #include #include -#include +#include +#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.h b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.h index 93494ab07c..3587c28975 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.h @@ -18,8 +18,8 @@ #include #include #include -#include -#include +#include +#include namespace AzNetworking { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.h b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.h index 238e665a00..be8ac1b65b 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace AzNetworking diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp index 7b8c3e6094..4994884364 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp index 5f8dae8ff4..6aa6c10b11 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp @@ -10,7 +10,7 @@ * */ -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp index 797d67e3ef..ecfd416380 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp @@ -11,8 +11,8 @@ */ #include -#include -#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp index ca0275d20b..0dd7292d25 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp @@ -10,11 +10,11 @@ * */ -#include +#include +#include +#include +#include #include -#include -#include -#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp index 7ee4d45e93..28b72abf25 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp @@ -11,7 +11,6 @@ */ #include - #include #include #include @@ -22,9 +21,9 @@ #include #include #include -#include +#include +#include #include -#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h index ba71eaf780..e763e7ebca 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h @@ -17,11 +17,11 @@ #include #include #include -#include -#include -#include #include -#include +#include +#include +#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp index 4bfc753f75..d58c192162 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.cpp index 69f715317a..42104e79fd 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.h index 4cfb242154..34f5d03f2f 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.h @@ -12,8 +12,8 @@ #pragma once -#include -#include +#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp index 27c39ea135..5ece0c7157 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp index 0ab1d5ffcc..eafd4375e7 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp @@ -10,8 +10,8 @@ * */ -#include -#include +#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp index 0f5a0d7c0c..82e5cea0c4 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h index 504992fecb..d5cbcbbed3 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h @@ -12,8 +12,8 @@ #pragma once -#include -#include +#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.cpp index 114c3e3b43..c6b8e8d7ef 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.h index 18b518f19f..fa4ab1e4e9 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.h @@ -12,7 +12,7 @@ #pragma once -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputHistory.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputHistory.h index ad406ffd8b..c5f0a70fd3 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputHistory.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputHistory.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.cpp index c6eed626a9..4395ff5b7d 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.h index c6ea425fec..454cef4e0a 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.h @@ -12,8 +12,8 @@ #pragma once -#include -#include +#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp index c0200c9e6d..ab5988444b 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp @@ -11,8 +11,8 @@ */ #include -#include -#include +#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h index 47f557a11f..18adc00140 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/NullReplicationWindow.h b/Gems/Multiplayer/Code/Source/ReplicationWindows/NullReplicationWindow.h index 1922e65941..5cb9c0de70 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/NullReplicationWindow.h +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/NullReplicationWindow.h @@ -12,7 +12,7 @@ #pragma once -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp index a51bdc4acc..bf370c1952 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h index b4e4427945..25fbfd481d 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h @@ -12,9 +12,9 @@ #pragma once -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/multiplayer_files.cmake b/Gems/Multiplayer/Code/multiplayer_files.cmake index 1f4e57ae43..bea88af10c 100644 --- a/Gems/Multiplayer/Code/multiplayer_files.cmake +++ b/Gems/Multiplayer/Code/multiplayer_files.cmake @@ -10,18 +10,28 @@ # set(FILES - Include/IConnectionData.h - Include/IEntityDomain.h - Include/IMultiplayer.h - Include/IMultiplayerComponentInput.h - Include/INetworkEntityManager.h - Include/INetworkTime.h - Include/IReplicationWindow.h - Include/MultiplayerStats.cpp - Include/MultiplayerStats.h - Include/MultiplayerTypes.h - Include/NetworkEntityHandle.h - Include/NetworkEntityHandle.inl + Include/Multiplayer/IConnectionData.h + Include/Multiplayer/IEntityDomain.h + Include/Multiplayer/IMultiplayer.h + Include/Multiplayer/IMultiplayerComponentInput.h + Include/Multiplayer/INetworkEntityManager.h + Include/Multiplayer/INetworkTime.h + Include/Multiplayer/IReplicationWindow.h + Include/Multiplayer/MultiplayerComponent.h + Include/Multiplayer/MultiplayerController.h + Include/Multiplayer/MultiplayerComponentRegistry.h + Include/Multiplayer/MultiplayerStats.cpp + Include/Multiplayer/MultiplayerStats.h + Include/Multiplayer/MultiplayerTypes.h + Include/Multiplayer/NetBindComponent.h + Include/Multiplayer/NetworkEntityRpcMessage.h + Include/Multiplayer/NetworkEntityUpdateMessage.h + Include/Multiplayer/NetworkEntityHandle.h + Include/Multiplayer/NetworkEntityHandle.inl + Include/Multiplayer/NetworkInput.h + Include/Multiplayer/ReplicationRecord.h + Include/Multiplayer/RewindableObject.h + Include/Multiplayer/RewindableObject.inl Source/Multiplayer_precompiled.cpp Source/Multiplayer_precompiled.h Source/MultiplayerSystemComponent.cpp @@ -36,14 +46,10 @@ set(FILES Source/AutoGen/NetworkTransformComponent.AutoComponent.xml Source/Components/LocalPredictionPlayerInputComponent.cpp Source/Components/LocalPredictionPlayerInputComponent.h - Source/Components/MultiplayerComponentRegistry.cpp - Source/Components/MultiplayerComponentRegistry.h Source/Components/MultiplayerComponent.cpp - Source/Components/MultiplayerComponent.h Source/Components/MultiplayerController.cpp - Source/Components/MultiplayerController.h + Source/Components/MultiplayerComponentRegistry.cpp Source/Components/NetBindComponent.cpp - Source/Components/NetBindComponent.h Source/Components/NetworkTransformComponent.cpp Source/Components/NetworkTransformComponent.h Source/ConnectionData/ClientToServerConnectionData.cpp @@ -64,7 +70,6 @@ set(FILES Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp Source/NetworkEntity/EntityReplication/PropertySubscriber.h Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp - Source/NetworkEntity/EntityReplication/ReplicationRecord.h Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp Source/NetworkEntity/NetworkEntityAuthorityTracker.h Source/NetworkEntity/NetworkEntityHandle.cpp @@ -73,14 +78,11 @@ set(FILES Source/NetworkEntity/NetworkSpawnableLibrary.cpp Source/NetworkEntity/NetworkSpawnableLibrary.h Source/NetworkEntity/NetworkEntityRpcMessage.cpp - Source/NetworkEntity/NetworkEntityRpcMessage.h Source/NetworkEntity/NetworkEntityTracker.cpp Source/NetworkEntity/NetworkEntityTracker.h Source/NetworkEntity/NetworkEntityTracker.inl Source/NetworkEntity/NetworkEntityUpdateMessage.cpp - Source/NetworkEntity/NetworkEntityUpdateMessage.h Source/NetworkInput/NetworkInput.cpp - Source/NetworkInput/NetworkInput.h Source/NetworkInput/NetworkInputArray.cpp Source/NetworkInput/NetworkInputArray.h Source/NetworkInput/NetworkInputChild.cpp @@ -91,8 +93,6 @@ set(FILES Source/NetworkInput/NetworkInputMigrationVector.h Source/NetworkTime/NetworkTime.cpp Source/NetworkTime/NetworkTime.h - Source/NetworkTime/RewindableObject.h - Source/NetworkTime/RewindableObject.inl Source/Pipeline/NetBindMarkerComponent.cpp Source/Pipeline/NetBindMarkerComponent.h Source/Pipeline/NetworkSpawnableHolderComponent.cpp From 8bb425709b38d2f574de0eafe842f3a0cffea8dc Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 16:04:44 -0700 Subject: [PATCH 168/225] unit test fix --- Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp b/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp index 367b7ee0de..9f1b879856 100644 --- a/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp +++ b/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp @@ -10,7 +10,8 @@ * */ -#include +#include +#include #include #include #include From 67c3801d73fbcf67e93f9d42c3548923a580bf5d Mon Sep 17 00:00:00 2001 From: SSpalding <57235700+AMZN-scspaldi@users.noreply.github.com> Date: Wed, 12 May 2021 16:15:18 -0700 Subject: [PATCH 169/225] Log monitor encoding fix (#729) Fixed log monitor encoding bug. --- Tools/LyTestTools/ly_test_tools/log/log_monitor.py | 4 ++-- Tools/LyTestTools/tests/unit/test_log_monitor.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/log/log_monitor.py b/Tools/LyTestTools/ly_test_tools/log/log_monitor.py index ca3cd24303..ea3991342a 100755 --- a/Tools/LyTestTools/ly_test_tools/log/log_monitor.py +++ b/Tools/LyTestTools/ly_test_tools/log/log_monitor.py @@ -44,7 +44,7 @@ def check_exact_match(line, expected_line): # Look for either start of line or whitespace, then the expected_line, then either end of the line or whitespace. # This way we don't partial match inside of a string. So for example, 'foo' matches 'foo bar' but not 'foobar' - regex_pattern = re.compile("(^|\\s){}($|\\s)".format(re.escape(expected_line))) + regex_pattern = re.compile("(^|\\s){}($|\\s)".format(re.escape(expected_line)), re.UNICODE) if regex_pattern.search(line) is not None: return expected_line @@ -125,7 +125,7 @@ class LogMonitor(object): self.py_log = "" try: logger.debug("Monitoring log file in '{}' ".format(self.log_file_path)) - with open(self.log_file_path, mode='r') as log: + with open(self.log_file_path, mode='r', encoding='utf-8') as log: logger.info( "Monitoring log file '{}' for '{}' seconds".format(self.log_file_path, timeout)) diff --git a/Tools/LyTestTools/tests/unit/test_log_monitor.py b/Tools/LyTestTools/tests/unit/test_log_monitor.py index 5be2b48d8b..2dd588f9ff 100755 --- a/Tools/LyTestTools/tests/unit/test_log_monitor.py +++ b/Tools/LyTestTools/tests/unit/test_log_monitor.py @@ -98,6 +98,16 @@ class TestLogMonitor(object): under_test = ly_test_tools.log.log_monitor.check_exact_match(line, expected_line) assert under_test == expected_line + @mock.patch('os.path.exists', mock.MagicMock(return_value=True)) + def test_Monitor_UTF8StringsPresentAndExpected_Success(self): + mock_file = io.StringIO('gr\xc3\xb6\xc3\x9feren pr\xc3\xbcfung \xd1\x82\xd0\xb5\xd1\x81\xd1\x82\xd1\x83\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xbd\xd1\x8f\n\xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99\n\xc3\x85lpha\xc3\x9fravo\xc3\xa7harlie\n') + mock_launcher.is_alive.side_effect = [True, True, True, False] + + with mock.patch('ly_test_tools.log.log_monitor.open', return_value=mock_file, create=True): + mock_log_monitor().monitor_log_for_lines(['gr\xc3\xb6\xc3\x9feren pr\xc3\xbcfung \xd1\x82\xd0\xb5\xd1\x81\xd1\x82\xd1\x83\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xbd\xd1\x8f', + '\xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99', + '\xc3\x85lpha\xc3\x9fravo\xc3\xa7harlie']) + @mock.patch('os.path.exists', mock.MagicMock(return_value=True)) def test_Monitor_AllLinesFound_Success(self): mock_file = io.StringIO(u'a\nb\nc\n') From 7633ec9a83035d9bc543070f055840a086180d02 Mon Sep 17 00:00:00 2001 From: catdo Date: Wed, 12 May 2021 16:27:51 -0700 Subject: [PATCH 170/225] removed spacings in CMakeList and removed the tags.txt file in the prefab level --- .../Gem/PythonTests/CMakeLists.txt | 26 +++++++++---------- .../tags.txt | 12 --------- 2 files changed, 13 insertions(+), 25 deletions(-) delete mode 100644 AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/tags.txt diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 86bcb967ab..3f0827f995 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -124,19 +124,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) endif() ## Prefab ## - if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_pytest( - NAME AutomatedTesting::PrefabTests - TEST_SUITE main - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/prefab/TestSuite_Main.py - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - ) - endif() +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::PrefabTests + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/prefab/TestSuite_Main.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + ) +endif() ## Editor Python Bindings ## if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) diff --git a/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/tags.txt b/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/tags.txt deleted file mode 100644 index 0d6c1880e7..0000000000 --- a/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/tags.txt +++ /dev/null @@ -1,12 +0,0 @@ -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 -0,0,0,0,0,0 From 8fd5c30e136e62887842916b26491c691a625e26 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Wed, 12 May 2021 17:47:10 -0700 Subject: [PATCH 171/225] Address some build/review feedback --- Code/Sandbox/Editor/ViewportTitleDlg.cpp | 7 ++-- .../AtomFont/Code/Source/FFont.cpp | 1 - ...AtomViewportDisplayInfoSystemComponent.cpp | 32 +++++++++---------- .../AtomViewportDisplayInfoSystemComponent.h | 1 + 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/Code/Sandbox/Editor/ViewportTitleDlg.cpp b/Code/Sandbox/Editor/ViewportTitleDlg.cpp index 159fccfd64..d7c8929540 100644 --- a/Code/Sandbox/Editor/ViewportTitleDlg.cpp +++ b/Code/Sandbox/Editor/ViewportTitleDlg.cpp @@ -187,11 +187,8 @@ void CViewportTitleDlg::OnToggleDisplayInfo() state, &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::GetDisplayState ); - state = static_cast(static_cast(state)+1); - if (state == AZ::AtomBridge::ViewportInfoDisplayState::Invalid) - { - state = AZ::AtomBridge::ViewportInfoDisplayState::NoInfo; - } + state = static_cast( + (static_cast(state)+1) % static_cast(AZ::AtomBridge::ViewportInfoDisplayState::Invalid)); // SetDisplayState will fire OnViewportInfoDisplayStateChanged and notify us, no need to call UpdateDisplayInfo. AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast( &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp index be0f87100a..cc14014e48 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp @@ -1684,7 +1684,6 @@ AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::Te return internalParams; } - //Code mostly duplicated from CRenderer::Draw2dTextWithDepth float posX = params.m_position.GetX(); float posY = params.m_position.GetY(); internalParams.m_viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId); diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp index c9128c001f..ed6b910b76 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp @@ -111,25 +111,26 @@ namespace AZ::Render void AtomViewportDisplayInfoSystemComponent::DrawLine(AZStd::string_view line, AZ::Color color) { m_drawParams.m_color = color; - AzFramework::FontDrawInterface* fontDrawInterface = - AZ::Interface::Get()->GetDefaultFontDrawInterface(); - AZ::Vector2 textSize = fontDrawInterface->GetTextSize(m_drawParams, line); - fontDrawInterface->DrawScreenAlignedText2d(m_drawParams, line); + AZ::Vector2 textSize = m_fontDrawInterface->GetTextSize(m_drawParams, line); + m_fontDrawInterface->DrawScreenAlignedText2d(m_drawParams, line); m_drawParams.m_position.SetY(m_drawParams.m_position.GetY() + textSize.GetY() + m_lineSpacing); } void AtomViewportDisplayInfoSystemComponent::OnRenderTick() { - auto fontQueryInterface = AZ::Interface::Get(); - if (!fontQueryInterface) + if (!m_fontDrawInterface) { - return; + auto fontQueryInterface = AZ::Interface::Get(); + if (!fontQueryInterface) + { + return; + } + m_fontDrawInterface = + fontQueryInterface->GetDefaultFontDrawInterface(); } - AzFramework::FontDrawInterface* fontDrawInterface = - fontQueryInterface->GetDefaultFontDrawInterface(); AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext(); - if (!fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene()) + if (!m_fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene()) { return; } @@ -167,7 +168,7 @@ namespace AZ::Render m_drawParams.m_lineSpacing = 0.5f; // Calculate line spacing based on the font's actual line height - const float lineHeight = fontDrawInterface->GetTextSize(m_drawParams, " ").GetY(); + const float lineHeight = m_fontDrawInterface->GetTextSize(m_drawParams, " ").GetY(); m_lineSpacing = lineHeight * m_drawParams.m_lineSpacing; DrawRendererInfo(); @@ -234,7 +235,7 @@ namespace AZ::Render int count = 1; if (auto passAsParent = pass->AsParent()) { - for (const auto child : passAsParent->GetChildren()) + for (const auto& child : passAsParent->GetChildren()) { count += containingPassCount(child); } @@ -243,10 +244,10 @@ namespace AZ::Render }; const int numPasses = containingPassCount(rootPass); DrawLine(AZStd::string::format( - "Total Passes: %d Vertex Count: %d Primitive Count: %d", + "Total Passes: %d Vertex Count: %lld Primitive Count: %lld", numPasses, - stats.m_vertexCount, - stats.m_primitiveCount + aznumeric_cast(stats.m_vertexCount), + aznumeric_cast(stats.m_primitiveCount) )); } @@ -269,7 +270,6 @@ namespace AZ::Render } m_lastMemoryUpdate = currentTime; - int peakUsageMB = aznumeric_cast(processMemInfo.PeakPagefileUsage >> 20); int currentUsageMB = aznumeric_cast(processMemInfo.PagefileUsage >> 20); DrawLine(AZStd::string::format("Mem=%d Peak=%d", currentUsageMB, peakUsageMB)); diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h index ac6c2bab65..08bec4a1d2 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h @@ -68,6 +68,7 @@ namespace AZ AZStd::string m_rendererDescription; AzFramework::TextDrawParameters m_drawParams; + AzFramework::FontDrawInterface* m_fontDrawInterface = nullptr; float m_lineSpacing; AZStd::chrono::duration m_fpsInterval = AZStd::chrono::seconds(1); AZStd::deque m_fpsHistory; From 1fe81c1533c9e1bbf15f5a6ffff1afb9468759f4 Mon Sep 17 00:00:00 2001 From: Peng Date: Wed, 12 May 2021 17:51:30 -0700 Subject: [PATCH 172/225] ATOM-15266 added location in the assert message where the descriptor set will be re-created --- Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp index 8769aaa1f9..634f5a51ac 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/DescriptorSet.cpp @@ -241,8 +241,8 @@ namespace AZ VkResult result = vkAllocateDescriptorSets(descriptor.m_device->GetNativeDevice(), &allocInfo, &m_nativeDescriptorSet); if (result == VK_ERROR_FRAGMENTED_POOL) { - // fragmented pool will be re-created subsequently, so warning only - AZ_Warning("Vulkan RHI", false, "Fragmented pool"); + // fragmented pool will be re-created subsequently in DescriptorSetAllocator, so warning only + AZ_Warning("Vulkan RHI", false, "Fragmented pool, will be recreated in DescriptorSetAllocator afterward"); } else { From e7722658718b4c705b688ca88c54cb17c603b417 Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 20:09:27 -0700 Subject: [PATCH 173/225] Build fixes for gem reorganization --- .../Code/Source/Debug/MultiplayerDebugSystemComponent.cpp | 2 +- .../Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp index aec8d8520e..1ae4bffd07 100644 --- a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp index 4962d16fb4..805a982506 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include From eea0660d2140c1e84f63b484f2e89e87a9ec4930 Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 20:26:08 -0700 Subject: [PATCH 174/225] A couple more fixes --- .../Code/Include/Multiplayer/RewindableObject.inl | 4 ++-- .../Code/Source/AutoGen/AutoComponent_Source.jinja | 4 ++-- Gems/Multiplayer/Code/multiplayer_files.cmake | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.inl b/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.inl index 2e67d42ede..20f52ffcb0 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.inl +++ b/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.inl @@ -47,7 +47,7 @@ namespace Multiplayer template inline RewindableObject &RewindableObject::operator =(const RewindableObject& rhs) { - INetworkTime* networkTime = GetNetworkTime(); + INetworkTime* networkTime = Multiplayer::GetNetworkTime(); SetValueForTime(rhs.GetValueForTime(networkTime->GetHostFrameId()), GetCurrentTimeForProperty()); return *this; } @@ -115,7 +115,7 @@ namespace Multiplayer template inline HostFrameId RewindableObject::GetCurrentTimeForProperty() const { - INetworkTime* networkTime = GetNetworkTime(); + INetworkTime* networkTime = Multiplayer::GetNetworkTime(); return networkTime->GetHostFrameIdForRewindingConnection(m_owningConnectionId); } diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 1bc6dc3994..200d38910b 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -1143,7 +1143,7 @@ namespace {{ Component.attrib['Namespace'] }} { editContext->Class<{{ ComponentBaseName }}>("{{ ComponentBaseName }}", "{{ Component.attrib['Description'] }}") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Multiplayer") + ->Attribute(AZ::Edit::Attributes::Category, "{{ Component.attrib['Namespace'] }}") ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game")) {{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Authority', ComponentBaseName)|indent(20) -}} {{ DefineNetworkPropertyEditReflection(Component, 'Authority', 'Server', ComponentBaseName)|indent(20) -}} @@ -1155,7 +1155,7 @@ namespace {{ Component.attrib['Namespace'] }} editContext->Class<{{ ComponentName }}>("{{ ComponentName }}", "{{ Component.attrib['Description'] }}") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Multiplayer") + ->Attribute(AZ::Edit::Attributes::Category, "{{ Component.attrib['Namespace'] }}") ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game")); {% endif %} } diff --git a/Gems/Multiplayer/Code/multiplayer_files.cmake b/Gems/Multiplayer/Code/multiplayer_files.cmake index bea88af10c..5eba7dd144 100644 --- a/Gems/Multiplayer/Code/multiplayer_files.cmake +++ b/Gems/Multiplayer/Code/multiplayer_files.cmake @@ -24,12 +24,12 @@ set(FILES Include/Multiplayer/MultiplayerStats.h Include/Multiplayer/MultiplayerTypes.h Include/Multiplayer/NetBindComponent.h - Include/Multiplayer/NetworkEntityRpcMessage.h + Include/Multiplayer/NetworkEntityRpcMessage.h Include/Multiplayer/NetworkEntityUpdateMessage.h Include/Multiplayer/NetworkEntityHandle.h Include/Multiplayer/NetworkEntityHandle.inl Include/Multiplayer/NetworkInput.h - Include/Multiplayer/ReplicationRecord.h + Include/Multiplayer/ReplicationRecord.h Include/Multiplayer/RewindableObject.h Include/Multiplayer/RewindableObject.inl Source/Multiplayer_precompiled.cpp @@ -48,7 +48,7 @@ set(FILES Source/Components/LocalPredictionPlayerInputComponent.h Source/Components/MultiplayerComponent.cpp Source/Components/MultiplayerController.cpp - Source/Components/MultiplayerComponentRegistry.cpp + Source/Components/MultiplayerComponentRegistry.cpp Source/Components/NetBindComponent.cpp Source/Components/NetworkTransformComponent.cpp Source/Components/NetworkTransformComponent.h From 601dd30452f9f052bf93fc48413e831259e2297d Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 20:41:53 -0700 Subject: [PATCH 175/225] Various build and test fixes --- .../Code/Include/Multiplayer/IMultiplayer.h | 14 +++++++++----- .../EntityReplication/EntityReplicationManager.cpp | 6 +++++- .../Code/Source/NetworkTime/NetworkTime.cpp | 10 ++++++++++ .../Code/Source/NetworkTime/NetworkTime.h | 4 ++-- .../Code/Tests/RewindableObjectTests.cpp | 6 +++--- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 665661b55b..eda5b71b52 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -139,27 +139,31 @@ namespace Multiplayer inline INetworkTime* GetNetworkTime() { - return GetMultiplayer()->GetNetworkTime(); + return AZ::Interface::Get(); } inline INetworkEntityManager* GetNetworkEntityManager() { - return GetMultiplayer()->GetNetworkEntityManager(); + IMultiplayer* multiplayer = GetMultiplayer(); + return (multiplayer != nullptr) ? multiplayer->GetNetworkEntityManager() : nullptr; } inline NetworkEntityTracker* GetNetworkEntityTracker() { - return GetNetworkEntityManager()->GetNetworkEntityTracker(); + INetworkEntityManager* networkEntityManager = GetNetworkEntityManager(); + return (networkEntityManager != nullptr) ? networkEntityManager->GetNetworkEntityTracker() : nullptr; } inline NetworkEntityAuthorityTracker* GetNetworkEntityAuthorityTracker() { - return GetNetworkEntityManager()->GetNetworkEntityAuthorityTracker(); + INetworkEntityManager* networkEntityManager = GetNetworkEntityManager(); + return (networkEntityManager != nullptr) ? networkEntityManager->GetNetworkEntityAuthorityTracker() : nullptr; } inline MultiplayerComponentRegistry* GetMultiplayerComponentRegistry() { - return GetNetworkEntityManager()->GetMultiplayerComponentRegistry(); + INetworkEntityManager* networkEntityManager = GetNetworkEntityManager(); + return (networkEntityManager != nullptr) ? networkEntityManager->GetMultiplayerComponentRegistry() : nullptr; } //! @class ScopedAlterTime diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp index 6eefeaf5fe..286090ca74 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp @@ -60,7 +60,11 @@ namespace Multiplayer // Start window update events m_updateWindow.Enqueue(AZ::TimeMs{ 0 }, true); - GetNetworkEntityManager()->AddEntityExitDomainHandler(m_entityExitDomainEventHandler); + INetworkEntityManager* networkEntityManager = GetNetworkEntityManager(); + if (networkEntityManager != nullptr) + { + networkEntityManager->AddEntityExitDomainHandler(m_entityExitDomainEventHandler); + } } void EntityReplicationManager::SetRemoteHostId(HostId hostId) diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp index ab5988444b..d991e59d05 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp @@ -17,6 +17,16 @@ namespace Multiplayer { + NetworkTime::NetworkTime() + { + AZ::Interface::Register(this); + } + + NetworkTime::~NetworkTime() + { + AZ::Interface::Unregister(this); + } + bool NetworkTime::IsTimeRewound() const { return m_rewindingConnectionId != AzNetworking::InvalidConnectionId; diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h index 18adc00140..ff2da0f759 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h @@ -23,8 +23,8 @@ namespace Multiplayer : public INetworkTime { public: - NetworkTime() = default; - virtual ~NetworkTime() = default; + NetworkTime(); + virtual ~NetworkTime(); //! INetworkTime overrides. //! @{ diff --git a/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp b/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp index 9f1b879856..f614dc2690 100644 --- a/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp +++ b/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp @@ -38,7 +38,7 @@ namespace UnitTest { test = i; EXPECT_EQ(i, test); - AZ::Interface::Get()->IncrementHostFrameId(); + Multiplayer::GetNetworkTime()->IncrementHostFrameId(); } for (uint32_t i = 0; i < 16; ++i) @@ -51,7 +51,7 @@ namespace UnitTest { test = i; EXPECT_EQ(i, test); - AZ::Interface::Get()->IncrementHostFrameId(); + Multiplayer::GetNetworkTime()->IncrementHostFrameId(); } for (uint32_t i = 16; i < 48; ++i) @@ -69,7 +69,7 @@ namespace UnitTest { test = i; EXPECT_EQ(i, test); - AZ::Interface::Get()->IncrementHostFrameId(); + Multiplayer::GetNetworkTime()->IncrementHostFrameId(); } { From 77899c5d96c4119d6b855648282752ee0e05e342 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 12 May 2021 20:45:58 -0700 Subject: [PATCH 176/225] Updated network property behavior context category so they are grouped nicer in the Script Canvas palette --- .../Code/Source/AutoGen/AutoComponent_Source.jinja | 4 +++- .../Code/Source/MultiplayerSystemComponent.cpp | 14 +++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index a3eef99b20..5b53145024 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -725,7 +725,7 @@ enum class NetworkProperties return &networkComponent->m_{{ LowerFirst(Property.attrib['Name']) }}Event; }) - ->Attribute(AZ::Script::Attributes::AzEventDescription, AZ::BehaviorAzEventDescription{ "On {{ UpperFirst(Property.attrib['Name']) }} Changed Event", {"New {{ UpperFirst(Property.attrib['Name']) }}"} }) + ->Attribute(AZ::Script::Attributes::AzEventDescription, AZ::BehaviorAzEventDescription{ "On {{ UpperFirst(Property.attrib['Name']) }} Changed Event", {"New {{ Property.attrib['Type'] }}"} }) {% endif %} {% endcall -%} @@ -1217,6 +1217,8 @@ namespace {{ Component.attrib['Namespace'] }} if (behaviorContext) { behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}") + ->Attribute(AZ::Script::Attributes::Module, "{{ LowerFirst(Component.attrib['Namespace']) }}") + ->Attribute(AZ::Script::Attributes::Category, "{{ UpperFirst(Component.attrib['Namespace']) }}") {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}} {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Server', ComponentName)|indent(16) -}} {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Client', ComponentName)|indent(16) -}} diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 9f45122c1d..7d74f5e071 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -80,13 +80,13 @@ namespace Multiplayer if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { - behaviorContext->Class("HostId"); - behaviorContext->Class("NetEntityId"); - behaviorContext->Class("NetComponentId"); - behaviorContext->Class("PropertyIndex"); - behaviorContext->Class ("RpcIndex"); - behaviorContext->Class ("ClientInputId"); - behaviorContext->Class ("HostFrameId"); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); } MultiplayerComponent::Reflect(context); From cb8016bde5f7c63c3054b4992705b9011fce502e Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 20:52:02 -0700 Subject: [PATCH 177/225] Fix for validator failing on empty files --- .../Multiplayer/INetworkPlayerSpawner.h | 18 ++++++++++++++++++ .../Code/Source/MultiplayerSystemComponent.cpp | 2 +- Gems/Multiplayer/Code/multiplayer_files.cmake | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h index e69de29bb2..f50d60e82d 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h @@ -0,0 +1,18 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +namespace Multiplayer +{ + +} diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 715d9a8527..80a09d7d48 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -433,7 +433,7 @@ namespace Multiplayer if (m_onConnectFunctor) { - // Default OnConnect behaviour has been overridden, + // Default OnConnect behaviour has been overridden m_onConnectFunctor(connection, datum); } else diff --git a/Gems/Multiplayer/Code/multiplayer_files.cmake b/Gems/Multiplayer/Code/multiplayer_files.cmake index 5eba7dd144..26909cbfd3 100644 --- a/Gems/Multiplayer/Code/multiplayer_files.cmake +++ b/Gems/Multiplayer/Code/multiplayer_files.cmake @@ -15,6 +15,7 @@ set(FILES Include/Multiplayer/IMultiplayer.h Include/Multiplayer/IMultiplayerComponentInput.h Include/Multiplayer/INetworkEntityManager.h + Include/Multiplayer/INetworkPlayerSpawner.h Include/Multiplayer/INetworkTime.h Include/Multiplayer/IReplicationWindow.h Include/Multiplayer/MultiplayerComponent.h From c0d9a3c423b61747656842a931f9c127dceba8d7 Mon Sep 17 00:00:00 2001 From: karlberg Date: Wed, 12 May 2021 20:55:03 -0700 Subject: [PATCH 178/225] Fix for clang not being lazy about template expansion --- Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h | 5 ----- Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index eda5b71b52..4931fb167f 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -137,11 +137,6 @@ namespace Multiplayer return AZ::Interface::Get(); } - inline INetworkTime* GetNetworkTime() - { - return AZ::Interface::Get(); - } - inline INetworkEntityManager* GetNetworkEntityManager() { IMultiplayer* multiplayer = GetMultiplayer(); diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h index c228e135ee..240eed270a 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h @@ -83,4 +83,10 @@ namespace Multiplayer static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; }; using INetworkTimeRequestBus = AZ::EBus; + + // Convenience helpers + inline INetworkTime* GetNetworkTime() + { + return AZ::Interface::Get(); + } } From d85e0500d5d33c215dc96898b0269a9c1138c884 Mon Sep 17 00:00:00 2001 From: guthadam Date: Thu, 13 May 2021 00:55:29 -0500 Subject: [PATCH 179/225] PR feedback --- .../Common/Code/Source/Material/MaterialAssignmentId.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentId.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentId.cpp index 0fe89d49b8..59de229445 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentId.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentId.cpp @@ -110,7 +110,7 @@ namespace AZ bool MaterialAssignmentId::operator!=(const MaterialAssignmentId& rhs) const { - return m_lodIndex != rhs.m_lodIndex || m_materialAssetId.m_subId != rhs.m_materialAssetId.m_subId; + return !(*this == rhs); } } // namespace Render } // namespace AZ From d690c3fee4810a49da588a71da4a95ab603918c9 Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Thu, 13 May 2021 11:59:22 +0100 Subject: [PATCH 180/225] static rigid body and rigid body component use Handles instead of pointers (#662) --- .../Configuration/RigidBodyConfiguration.cpp | 8 +- .../Configuration/RigidBodyConfiguration.h | 1 - .../Physics/SimulatedBodies/RigidBody.h | 2 +- .../Code/Source/Family/BlastFamilyImpl.cpp | 2 +- Gems/Blast/Code/Tests/Mocks/BlastMocks.h | 2 +- .../Code/Source/EditorRigidBodyComponent.cpp | 98 +++--- .../Code/Source/EditorRigidBodyComponent.h | 7 +- Gems/PhysX/Code/Source/RigidBody.cpp | 8 +- Gems/PhysX/Code/Source/RigidBody.h | 2 +- Gems/PhysX/Code/Source/RigidBodyComponent.cpp | 278 ++++++++++++++---- Gems/PhysX/Code/Source/RigidBodyComponent.h | 3 +- Gems/PhysX/Code/Source/Scene/PhysXScene.cpp | 18 +- .../Code/Source/StaticRigidBodyComponent.cpp | 42 ++- .../Code/Source/StaticRigidBodyComponent.h | 1 - Gems/PhysX/Code/Source/System/PhysXSystem.cpp | 3 + Gems/PhysX/Code/Tests/PhysXTestCommon.cpp | 12 + 16 files changed, 358 insertions(+), 129 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp index 80434e5dee..0d5d5ca841 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp @@ -99,6 +99,11 @@ namespace AzPhysics classElement.RemoveElementByName(AZ_CRC_CE("Property Visibility Flags")); } + if (classElement.GetVersion() <= 4) + { + classElement.RemoveElementByName(AZ_CRC_CE("Simulated")); + } + return true; } } @@ -110,7 +115,7 @@ namespace AzPhysics if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(4, &Internal::RigidBodyVersionConverter) + ->Version(5, &Internal::RigidBodyVersionConverter) ->Field("Initial linear velocity", &RigidBodyConfiguration::m_initialLinearVelocity) ->Field("Initial angular velocity", &RigidBodyConfiguration::m_initialAngularVelocity) ->Field("Linear damping", &RigidBodyConfiguration::m_linearDamping) @@ -119,7 +124,6 @@ namespace AzPhysics ->Field("Start Asleep", &RigidBodyConfiguration::m_startAsleep) ->Field("Interpolate Motion", &RigidBodyConfiguration::m_interpolateMotion) ->Field("Gravity Enabled", &RigidBodyConfiguration::m_gravityEnabled) - ->Field("Simulated", &RigidBodyConfiguration::m_simulated) ->Field("Kinematic", &RigidBodyConfiguration::m_kinematic) ->Field("CCD Enabled", &RigidBodyConfiguration::m_ccdEnabled) ->Field("Compute Mass", &RigidBodyConfiguration::m_computeMass) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h index 5c43118f3d..ecf7e023c5 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h @@ -57,7 +57,6 @@ namespace AzPhysics bool m_startAsleep = false; bool m_interpolateMotion = false; bool m_gravityEnabled = true; - bool m_simulated = true; bool m_kinematic = false; bool m_ccdEnabled = false; //!< Whether continuous collision detection is enabled. float m_ccdMinAdvanceCoefficient = 0.15f; //!< Coefficient affecting how granularly time is subdivided in CCD. diff --git a/Code/Framework/AzFramework/AzFramework/Physics/SimulatedBodies/RigidBody.h b/Code/Framework/AzFramework/AzFramework/Physics/SimulatedBodies/RigidBody.h index 5b18887d43..0f43aaaf4a 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/SimulatedBodies/RigidBody.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/SimulatedBodies/RigidBody.h @@ -62,7 +62,7 @@ namespace AzPhysics virtual void SetLinearVelocity(const AZ::Vector3& velocity) = 0; virtual AZ::Vector3 GetAngularVelocity() const = 0; virtual void SetAngularVelocity(const AZ::Vector3& angularVelocity) = 0; - virtual AZ::Vector3 GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) = 0; + virtual AZ::Vector3 GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) const = 0; virtual void ApplyLinearImpulse(const AZ::Vector3& impulse) = 0; virtual void ApplyLinearImpulseAtWorldPoint(const AZ::Vector3& impulse, const AZ::Vector3& worldPoint) = 0; virtual void ApplyAngularImpulse(const AZ::Vector3& angularImpulse) = 0; diff --git a/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp b/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp index d276486548..87865d0e08 100644 --- a/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp +++ b/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp @@ -241,7 +241,7 @@ namespace Blast configuration.m_orientation = transform.GetRotation(); configuration.m_scale = transform.GetScale(); configuration.m_ccdEnabled = m_actorConfiguration.m_isCcdEnabled; - configuration.m_simulated = m_actorConfiguration.m_isSimulated; + configuration.m_startSimulationEnabled = m_actorConfiguration.m_isSimulated; configuration.m_initialAngularVelocity = AZ::Vector3::CreateZero(); BlastActorDesc actorDesc; diff --git a/Gems/Blast/Code/Tests/Mocks/BlastMocks.h b/Gems/Blast/Code/Tests/Mocks/BlastMocks.h index a1e57a6917..1ae87e2282 100644 --- a/Gems/Blast/Code/Tests/Mocks/BlastMocks.h +++ b/Gems/Blast/Code/Tests/Mocks/BlastMocks.h @@ -424,7 +424,7 @@ namespace Blast void SetAngularVelocity([[maybe_unused]] const AZ::Vector3& angularVelocity) override {} - AZ::Vector3 GetLinearVelocityAtWorldPoint([[maybe_unused]] const AZ::Vector3& worldPoint) override + AZ::Vector3 GetLinearVelocityAtWorldPoint([[maybe_unused]] const AZ::Vector3& worldPoint) const override { return {}; } diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp index b6517b0499..f97e7c6cbd 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp @@ -282,9 +282,8 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { - sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_rigidBodyHandle); - m_rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; - m_editorBody = nullptr; + sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorRigidBodyHandle); + m_editorRigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } } @@ -342,12 +341,15 @@ namespace PhysX [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { - if (m_editorBody && m_config.m_centerOfMassDebugDraw) + if (m_config.m_centerOfMassDebugDraw) { - debugDisplay.DepthTestOff(); - debugDisplay.SetColor(m_centerOfMassDebugColor); - debugDisplay.DrawBall(m_editorBody->GetCenterOfMassWorld(), m_centerOfMassDebugSize); - debugDisplay.DepthTestOn(); + if (const AzPhysics::RigidBody* body = GetRigidBody()) + { + debugDisplay.DepthTestOff(); + debugDisplay.SetColor(m_centerOfMassDebugColor); + debugDisplay.DrawBall(body->GetCenterOfMassWorld(), m_centerOfMassDebugSize); + debugDisplay.DepthTestOn(); + } } } @@ -366,29 +368,30 @@ namespace PhysX AZ::Transform colliderTransform = GetWorldTM(); colliderTransform.ExtractScale(); - AzPhysics::RigidBodyConfiguration configuration; + AzPhysics::RigidBodyConfiguration configuration = m_config; configuration.m_orientation = colliderTransform.GetRotation(); configuration.m_position = colliderTransform.GetTranslation(); configuration.m_entityId = GetEntityId(); configuration.m_debugName = GetEntity()->GetName(); - configuration.m_centerOfMassOffset = m_config.m_centerOfMassOffset; - configuration.m_computeCenterOfMass = m_config.m_computeCenterOfMass; - configuration.m_computeInertiaTensor = m_config.m_computeInertiaTensor; - configuration.m_inertiaTensor = m_config.m_inertiaTensor; - configuration.m_simulated = false; - configuration.m_kinematic = m_config.m_kinematic; + configuration.m_startSimulationEnabled = false; configuration.m_colliderAndShapeData = Internal::GetCollisionShapes(GetEntity()); + if (auto* sceneInterface = AZ::Interface::Get()) { - m_rigidBodyHandle = sceneInterface->AddSimulatedBody(m_editorSceneHandle, &configuration); - m_editorBody = azdynamic_cast(sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_rigidBodyHandle)); + m_editorRigidBodyHandle = sceneInterface->AddSimulatedBody(m_editorSceneHandle, &configuration); + if (auto* body = azdynamic_cast( + sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorRigidBodyHandle) + )) + { + // AddSimulatedBody may update mass / CoM / Inertia tensor based on the config, so grab the updated values. + m_config.m_mass = body->GetMass(); + m_config.m_centerOfMassOffset = body->GetCenterOfMassLocal(); + m_config.m_inertiaTensor = body->GetInverseInertiaLocal(); + } } - - m_editorBody->UpdateMassProperties(m_config.GetMassComputeFlags(), &m_config.m_centerOfMassOffset, &m_config.m_inertiaTensor, &m_config.m_mass); - m_config.m_mass = m_editorBody->GetMass(); - m_config.m_centerOfMassOffset = m_editorBody->GetCenterOfMassLocal(); - m_config.m_inertiaTensor = m_editorBody->GetInverseInertiaLocal(); + AZ_Error("EditorRigidBodyComponent", + m_editorRigidBodyHandle != AzPhysics::InvalidSimulatedBodyHandle, "Failed to create editor rigid body"); } void EditorRigidBodyComponent::OnColliderChanged() @@ -424,9 +427,8 @@ namespace PhysX { if (auto* sceneInterface = AZ::Interface::Get()) { - sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_rigidBodyHandle); - m_rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; - m_editorBody = nullptr; + sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorRigidBodyHandle); + m_editorRigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; CreateEditorWorldRigidBody(); } @@ -436,46 +438,65 @@ namespace PhysX void EditorRigidBodyComponent::EnablePhysics() { - if (!IsPhysicsEnabled()) + if (auto* sceneInterface = AZ::Interface::Get()) { - m_editorBody->SetSimulationEnabled(true); + sceneInterface->EnableSimulationOfBody(m_editorSceneHandle, m_editorRigidBodyHandle); } } void EditorRigidBodyComponent::DisablePhysics() { - m_editorBody->SetSimulationEnabled(false); + if (auto* sceneInterface = AZ::Interface::Get()) + { + sceneInterface->DisableSimulationOfBody(m_editorSceneHandle, m_editorRigidBodyHandle); + } } bool EditorRigidBodyComponent::IsPhysicsEnabled() const { - return m_editorBody && m_editorBody->m_simulating; + if (auto* sceneInterface = AZ::Interface::Get()) + { + if (AzPhysics::SimulatedBody* body = + sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorRigidBodyHandle)) + { + return body->m_simulating; + } + } + return false; } AZ::Aabb EditorRigidBodyComponent::GetAabb() const { - if (m_editorBody) + if (auto* sceneInterface = AZ::Interface::Get()) { - return m_editorBody->GetAabb(); + if (AzPhysics::SimulatedBody* body = + sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorRigidBodyHandle)) + { + return body->GetAabb(); + } } return AZ::Aabb::CreateNull(); } AzPhysics::SimulatedBody* EditorRigidBodyComponent::GetSimulatedBody() { - return m_editorBody; + if (auto* sceneInterface = AZ::Interface::Get()) + { + return sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorRigidBodyHandle); + } + return nullptr; } AzPhysics::SimulatedBodyHandle EditorRigidBodyComponent::GetSimulatedBodyHandle() const { - return m_rigidBodyHandle; + return m_editorRigidBodyHandle; } AzPhysics::SceneQueryHit EditorRigidBodyComponent::RayCast(const AzPhysics::RayCastRequest& request) { - if (m_editorBody) + if (AzPhysics::SimulatedBody* body = GetSimulatedBody()) { - return m_editorBody->RayCast(request); + return body->RayCast(request); } return AzPhysics::SceneQueryHit(); } @@ -488,7 +509,12 @@ namespace PhysX const AzPhysics::RigidBody* EditorRigidBodyComponent::GetRigidBody() const { - return m_editorBody; + if (auto* sceneInterface = AZ::Interface::Get()) + { + return azdynamic_cast( + sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorRigidBodyHandle)); + } + return nullptr; } void EditorRigidBodyComponent::SetShouldBeRecreated() diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.h b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.h index b2b199e6be..72d34bb0d0 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.h +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.h @@ -33,8 +33,8 @@ namespace PhysX struct EditorRigidBodyConfiguration : public AzPhysics::RigidBodyConfiguration { - AZ_CLASS_ALLOCATOR(EditorRigidBodyConfiguration, AZ::SystemAllocator, 0); - AZ_RTTI(EditorRigidBodyConfiguration, "{27297024-5A99-4C58-8614-4EF18137CE69}", AzPhysics::RigidBodyConfiguration); + AZ_CLASS_ALLOCATOR(PhysX::EditorRigidBodyConfiguration, AZ::SystemAllocator, 0); + AZ_RTTI(PhysX::EditorRigidBodyConfiguration, "{27297024-5A99-4C58-8614-4EF18137CE69}", AzPhysics::RigidBodyConfiguration); static void Reflect(AZ::ReflectContext* context); @@ -127,8 +127,7 @@ namespace PhysX Debug::DebugDisplayDataChangedEvent::Handler m_debugDisplayDataChangeHandler; EditorRigidBodyConfiguration m_config; - AzPhysics::SimulatedBodyHandle m_rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; - AzPhysics::RigidBody* m_editorBody = nullptr; + AzPhysics::SimulatedBodyHandle m_editorRigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; AzPhysics::SceneHandle m_editorSceneHandle = AzPhysics::InvalidSceneHandle; AZ::Color m_centerOfMassDebugColor = AZ::Colors::White; diff --git a/Gems/PhysX/Code/Source/RigidBody.cpp b/Gems/PhysX/Code/Source/RigidBody.cpp index 6d1ece6a82..7fda0a1912 100644 --- a/Gems/PhysX/Code/Source/RigidBody.cpp +++ b/Gems/PhysX/Code/Source/RigidBody.cpp @@ -82,12 +82,8 @@ namespace PhysX SetName(configuration.m_debugName); SetGravityEnabled(configuration.m_gravityEnabled); - SetSimulationEnabled(configuration.m_simulated); SetCCDEnabled(configuration.m_ccdEnabled); - - AzPhysics::MassComputeFlags flags = configuration.GetMassComputeFlags(); - UpdateMassProperties(flags, &configuration.m_centerOfMassOffset, &configuration.m_inertiaTensor, - &configuration.m_mass); + SetKinematic(configuration.m_kinematic); if (configuration.m_customUserData) { @@ -459,7 +455,7 @@ namespace PhysX } } - AZ::Vector3 RigidBody::GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) + AZ::Vector3 RigidBody::GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) const { return m_pxRigidActor ? GetLinearVelocity() + GetAngularVelocity().Cross(worldPoint - GetCenterOfMassWorld()) : diff --git a/Gems/PhysX/Code/Source/RigidBody.h b/Gems/PhysX/Code/Source/RigidBody.h index c9f171b261..07df60d649 100644 --- a/Gems/PhysX/Code/Source/RigidBody.h +++ b/Gems/PhysX/Code/Source/RigidBody.h @@ -63,7 +63,7 @@ namespace PhysX void SetLinearVelocity(const AZ::Vector3& velocity) override; AZ::Vector3 GetAngularVelocity() const override; void SetAngularVelocity(const AZ::Vector3& angularVelocity) override; - AZ::Vector3 GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) override; + AZ::Vector3 GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) const override; void ApplyLinearImpulse(const AZ::Vector3& impulse) override; void ApplyLinearImpulseAtWorldPoint(const AZ::Vector3& impulse, const AZ::Vector3& worldPoint) override; void ApplyAngularImpulse(const AZ::Vector3& angularImpulse) override; diff --git a/Gems/PhysX/Code/Source/RigidBodyComponent.cpp b/Gems/PhysX/Code/Source/RigidBodyComponent.cpp index cf2e306cc7..58b0749d0f 100644 --- a/Gems/PhysX/Code/Source/RigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/RigidBodyComponent.cpp @@ -185,7 +185,6 @@ namespace PhysX { sceneInterface->RemoveSimulatedBody(m_attachedSceneHandle, m_rigidBodyHandle); m_rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; - m_rigidBody = nullptr; } Physics::RigidBodyRequestBus::Handler::BusDisconnect(); @@ -232,20 +231,33 @@ namespace PhysX // User sets kinematic Target ---> Update transform // User sets transform ---> Update kinematic target - if (!IsPhysicsEnabled() || (m_rigidBody->IsKinematic() && !m_isLastMovementFromKinematicSource)) + if (!IsPhysicsEnabled() || (IsKinematic() && !m_isLastMovementFromKinematicSource)) { return; } + auto* sceneInterface = AZ::Interface::Get(); + if (sceneInterface == nullptr) + { + AZ_Error("RigidBodyComponent", false, "PostPhysicsTick, SceneInterface is null"); + return; + } + + AzPhysics::SimulatedBody* rigidBody = + sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_rigidBodyHandle); + if (rigidBody == nullptr) + { + AZ_Error("RigidBodyComponent", false, "Unable to retrieve simulated rigid body"); + return; + } + + AZ::Transform transform = rigidBody->GetTransform(); if (m_configuration.m_interpolateMotion) { - AZ::Transform transform = m_rigidBody->GetTransform(); - m_interpolator->SetTarget(transform.GetTranslation(), m_rigidBody->GetOrientation(), fixedDeltaTime); + m_interpolator->SetTarget(transform.GetTranslation(), rigidBody->GetOrientation(), fixedDeltaTime); } else { - AZ::Transform transform = m_rigidBody->GetTransform(); - // Maintain scale (this must be precise). AZ::Transform entityTransform = AZ::Transform::Identity(); AZ::TransformBus::EventResult(entityTransform, GetEntityId(), &AZ::TransformInterface::GetWorldTM); @@ -261,13 +273,17 @@ namespace PhysX // Note: OnTransformChanged is not safe at the moment due to TransformComponent design flaw. // It is called when the parent entity is activated after the children causing rigid body // to move through the level instantly. - if (IsPhysicsEnabled() && (m_rigidBody->IsKinematic() && !m_isLastMovementFromKinematicSource)) + if (AzPhysics::RigidBody* body = GetRigidBody()) { - m_rigidBody->SetKinematicTarget(world); - } - else if (!IsPhysicsEnabled()) - { - m_rigidBodyTransformNeedsUpdateOnPhysReEnable = true; + if (body->m_simulating && + (body->IsKinematic() && !m_isLastMovementFromKinematicSource)) + { + body->SetKinematicTarget(world); + } + else if (!body->m_simulating) + { + m_rigidBodyTransformNeedsUpdateOnPhysReEnable = true; + } } } @@ -290,16 +306,9 @@ namespace PhysX auto* sceneInterface = AZ::Interface::Get(); if (sceneInterface != nullptr) { + m_configuration.m_startSimulationEnabled = false; //enable physics will enable this when called. m_rigidBodyHandle = sceneInterface->AddSimulatedBody(m_attachedSceneHandle, &m_configuration); - m_rigidBody = azdynamic_cast(sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_rigidBodyHandle)); - //disable simulating the body until EnablePhysics is called. - sceneInterface->DisableSimulationOfBody(m_attachedSceneHandle, m_rigidBodyHandle); } - m_rigidBody->SetKinematic(m_configuration.m_kinematic); - - AzPhysics::MassComputeFlags flags = m_configuration.GetMassComputeFlags(); - m_rigidBody->UpdateMassProperties(flags, &m_configuration.m_centerOfMassOffset, &m_configuration.m_inertiaTensor, - &m_configuration.m_mass); // Listen to the PhysX system for events concerning this entity. if (sceneInterface != nullptr) @@ -319,16 +328,23 @@ namespace PhysX return; } - if (auto* sceneInterface = AZ::Interface::Get()) + auto* sceneInterface = AZ::Interface::Get(); + if (sceneInterface == nullptr) { - sceneInterface->EnableSimulationOfBody(m_attachedSceneHandle, m_rigidBodyHandle); + AZ_Error("RigidBodyComponent", false, "Unable to enable physics, SceneInterface is null"); + return; } + SetSimulationEnabled(true); AZ::Transform transform = AZ::Transform::CreateIdentity(); AZ::TransformBus::EventResult(transform, GetEntityId(), &AZ::TransformInterface::GetWorldTM); if (m_rigidBodyTransformNeedsUpdateOnPhysReEnable) { - m_rigidBody->SetTransform(transform); + if (AzPhysics::SimulatedBody* body = + sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_rigidBodyHandle)) + { + body->SetTransform(transform); + } m_rigidBodyTransformNeedsUpdateOnPhysReEnable = false; } @@ -345,188 +361,322 @@ namespace PhysX void RigidBodyComponent::DisablePhysics() { - if (auto* sceneInterface = AZ::Interface::Get()) - { - sceneInterface->DisableSimulationOfBody(m_attachedSceneHandle, m_rigidBodyHandle); - } + SetSimulationEnabled(false); Physics::RigidBodyNotificationBus::Event(GetEntityId(), &Physics::RigidBodyNotificationBus::Events::OnPhysicsDisabled); } bool RigidBodyComponent::IsPhysicsEnabled() const { - return m_rigidBody != nullptr && m_rigidBody->m_simulating; + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->m_simulating; + } + return false; } void RigidBodyComponent::ApplyLinearImpulse(const AZ::Vector3& impulse) { - m_rigidBody->ApplyLinearImpulse(impulse); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->ApplyLinearImpulse(impulse); + } } void RigidBodyComponent::ApplyLinearImpulseAtWorldPoint(const AZ::Vector3& impulse, const AZ::Vector3& worldSpacePoint) { - m_rigidBody->ApplyLinearImpulseAtWorldPoint(impulse, worldSpacePoint); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->ApplyLinearImpulseAtWorldPoint(impulse, worldSpacePoint); + } } void RigidBodyComponent::ApplyAngularImpulse(const AZ::Vector3& impulse) { - m_rigidBody->ApplyAngularImpulse(impulse); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->ApplyAngularImpulse(impulse); + } } AZ::Vector3 RigidBodyComponent::GetLinearVelocity() const { - return m_rigidBody->GetLinearVelocity(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetLinearVelocity(); + } + return AZ::Vector3::CreateZero(); } void RigidBodyComponent::SetLinearVelocity(const AZ::Vector3& velocity) { - m_rigidBody->SetLinearVelocity(velocity); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetLinearVelocity(velocity); + } } AZ::Vector3 RigidBodyComponent::GetAngularVelocity() const { - return m_rigidBody->GetAngularVelocity(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetAngularVelocity(); + } + return AZ::Vector3::CreateZero(); } void RigidBodyComponent::SetAngularVelocity(const AZ::Vector3& angularVelocity) { - m_rigidBody->SetAngularVelocity(angularVelocity); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetAngularVelocity(angularVelocity); + } } AZ::Vector3 RigidBodyComponent::GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) const { - return m_rigidBody->GetLinearVelocityAtWorldPoint(worldPoint); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetLinearVelocityAtWorldPoint(worldPoint); + } + return AZ::Vector3::CreateZero(); } AZ::Vector3 RigidBodyComponent::GetCenterOfMassWorld() const { - return m_rigidBody->GetCenterOfMassWorld(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetCenterOfMassWorld(); + } + return AZ::Vector3::CreateZero(); } AZ::Vector3 RigidBodyComponent::GetCenterOfMassLocal() const { - return m_rigidBody->GetCenterOfMassLocal(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetCenterOfMassLocal(); + } + return AZ::Vector3::CreateZero(); } AZ::Matrix3x3 RigidBodyComponent::GetInverseInertiaWorld() const { - return m_rigidBody->GetInverseInertiaWorld(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetInverseInertiaWorld(); + } + return AZ::Matrix3x3::CreateZero(); } AZ::Matrix3x3 RigidBodyComponent::GetInverseInertiaLocal() const { - return m_rigidBody->GetInverseInertiaLocal(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetInverseInertiaLocal(); + } + return AZ::Matrix3x3::CreateZero(); } float RigidBodyComponent::GetMass() const { - return m_rigidBody->GetMass(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetMass(); + } + return 0.0f; } float RigidBodyComponent::GetInverseMass() const { - return m_rigidBody->GetInverseMass(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetInverseMass(); + } + return 0.0f; } void RigidBodyComponent::SetMass(float mass) { - m_rigidBody->SetMass(mass); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetMass(mass); + } } void RigidBodyComponent::SetCenterOfMassOffset(const AZ::Vector3& comOffset) { - m_rigidBody->SetCenterOfMassOffset(comOffset); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetCenterOfMassOffset(comOffset); + } } float RigidBodyComponent::GetLinearDamping() const { - return m_rigidBody->GetLinearDamping(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetLinearDamping(); + } + return 0.0f; } void RigidBodyComponent::SetLinearDamping(float damping) { - m_rigidBody->SetLinearDamping(damping); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetLinearDamping(damping); + } } float RigidBodyComponent::GetAngularDamping() const { - return m_rigidBody->GetAngularDamping(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetAngularDamping(); + } + return 0.0f; } void RigidBodyComponent::SetAngularDamping(float damping) { - m_rigidBody->SetAngularDamping(damping); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetAngularDamping(damping); + } } bool RigidBodyComponent::IsAwake() const { - return m_rigidBody->IsAwake(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->IsAwake(); + } + return false; } void RigidBodyComponent::ForceAsleep() { - m_rigidBody->ForceAsleep(); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->ForceAsleep(); + } } void RigidBodyComponent::ForceAwake() { - m_rigidBody->ForceAwake(); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->ForceAwake(); + } } bool RigidBodyComponent::IsKinematic() const { - return m_rigidBody->IsKinematic(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->IsKinematic(); + } + return false; } void RigidBodyComponent::SetKinematic(bool kinematic) { - m_rigidBody->SetKinematic(kinematic); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetKinematic(kinematic); + } } void RigidBodyComponent::SetKinematicTarget(const AZ::Transform& targetPosition) { m_isLastMovementFromKinematicSource = true; - m_rigidBody->SetKinematicTarget(targetPosition); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetKinematicTarget(targetPosition); + } } bool RigidBodyComponent::IsGravityEnabled() const { - return m_rigidBody->IsGravityEnabled(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->IsGravityEnabled(); + } + return false; } void RigidBodyComponent::SetGravityEnabled(bool enabled) { - m_rigidBody->SetGravityEnabled(enabled); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetGravityEnabled(enabled); + } } void RigidBodyComponent::SetSimulationEnabled(bool enabled) { - m_rigidBody->SetSimulationEnabled(enabled); + if (auto* sceneInterface = AZ::Interface::Get()) + { + if (enabled) + { + sceneInterface->EnableSimulationOfBody(m_attachedSceneHandle, m_rigidBodyHandle); + } + else + { + sceneInterface->DisableSimulationOfBody(m_attachedSceneHandle, m_rigidBodyHandle); + } + } } float RigidBodyComponent::GetSleepThreshold() const { - return m_rigidBody->GetSleepThreshold(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetSleepThreshold(); + } + return 0.0f; } void RigidBodyComponent::SetSleepThreshold(float threshold) { - m_rigidBody->SetSleepThreshold(threshold); + if (AzPhysics::RigidBody* body = GetRigidBody()) + { + body->SetSleepThreshold(threshold); + } } AZ::Aabb RigidBodyComponent::GetAabb() const { - return m_rigidBody->GetAabb(); + if (const AzPhysics::RigidBody* body = GetRigidBodyConst()) + { + return body->GetAabb(); + } + return AZ::Aabb::CreateNull(); } AzPhysics::RigidBody* RigidBodyComponent::GetRigidBody() { - return m_rigidBody; + return azdynamic_cast(GetSimulatedBody()); } AzPhysics::SimulatedBody* RigidBodyComponent::GetSimulatedBody() { - return m_rigidBody; + if (auto* sceneInterface = AZ::Interface::Get()) + { + return sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_rigidBodyHandle); + } + return nullptr; + } + + const AzPhysics::RigidBody* RigidBodyComponent::GetRigidBodyConst() const + { + if (auto* sceneInterface = AZ::Interface::Get()) + { + return azdynamic_cast( + sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_rigidBodyHandle)); + } + return nullptr; } AzPhysics::SimulatedBodyHandle RigidBodyComponent::GetSimulatedBodyHandle() const @@ -536,9 +686,9 @@ namespace PhysX AzPhysics::SceneQueryHit RigidBodyComponent::RayCast(const AzPhysics::RayCastRequest& request) { - if (m_rigidBody) + if (AzPhysics::RigidBody* body = GetRigidBody()) { - return m_rigidBody->RayCast(request); + return body->RayCast(request); } return AzPhysics::SceneQueryHit(); } diff --git a/Gems/PhysX/Code/Source/RigidBodyComponent.h b/Gems/PhysX/Code/Source/RigidBodyComponent.h index 12c4d3f5ff..7b2a34cf37 100644 --- a/Gems/PhysX/Code/Source/RigidBodyComponent.h +++ b/Gems/PhysX/Code/Source/RigidBodyComponent.h @@ -153,11 +153,12 @@ namespace PhysX void InitPhysicsTickHandler(); void PostPhysicsTick(float fixedDeltaTime); + const AzPhysics::RigidBody* GetRigidBodyConst() const; + std::unique_ptr m_interpolator; AzPhysics::RigidBodyConfiguration m_configuration; AzPhysics::SimulatedBodyHandle m_rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; - AzPhysics::RigidBody* m_rigidBody = nullptr; AzPhysics::SceneHandle m_attachedSceneHandle = AzPhysics::InvalidSceneHandle; AZ::Vector3 m_initialScale = AZ::Vector3::CreateOne(); diff --git a/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp b/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp index 03bbac9fd4..96e2d8a9bb 100644 --- a/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp +++ b/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp @@ -189,6 +189,22 @@ namespace PhysX return newBody; } + AzPhysics::SimulatedBody* CreateRigidBody(const AzPhysics::RigidBodyConfiguration* configuration, AZ::Crc32& crc) + { + RigidBody* newBody = aznew RigidBody(*configuration); + if (!AZStd::holds_alternative(configuration->m_colliderAndShapeData)) + { + const bool shapeAdded = AddShape(newBody, configuration->m_colliderAndShapeData); + AZ_Warning("PhysXScene", shapeAdded, "No Collider or Shape information found when creating Rigid body [%s]", configuration->m_debugName.c_str()); + } + const AzPhysics::MassComputeFlags& flags = configuration->GetMassComputeFlags(); + newBody->UpdateMassProperties(flags, &configuration->m_centerOfMassOffset, + &configuration->m_inertiaTensor, &configuration->m_mass); + + crc = AZ::Crc32(newBody, sizeof(*newBody)); + return newBody; + } + AzPhysics::SimulatedBody* CreateCharacterBody(PhysXScene* scene, const Physics::CharacterConfiguration* characterConfig) { @@ -617,7 +633,7 @@ namespace PhysX AZ::Crc32 newBodyCrc; if (azrtti_istypeof(simulatedBodyConfig)) { - newBody = Internal::CreateSimulatedBody( + newBody = Internal::CreateRigidBody( azdynamic_cast(simulatedBodyConfig), newBodyCrc); } else if (azrtti_istypeof(simulatedBodyConfig)) diff --git a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp index 79e5ea8204..881fb29750 100644 --- a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp @@ -100,7 +100,6 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { m_staticRigidBodyHandle = sceneInterface->AddSimulatedBody(m_attachedSceneHandle, &configuration); - m_staticRigidBody = azdynamic_cast(sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_staticRigidBodyHandle)); } } @@ -119,16 +118,18 @@ namespace PhysX { sceneInterface->RemoveSimulatedBody(m_attachedSceneHandle, m_staticRigidBodyHandle); m_staticRigidBodyHandle = AzPhysics::InvalidSceneHandle; - m_staticRigidBody = nullptr; } AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); AZ::TransformNotificationBus::Handler::BusDisconnect(); } - void StaticRigidBodyComponent::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) + void StaticRigidBodyComponent::OnTransformChanged([[maybe_unused]] const AZ::Transform& local, const AZ::Transform& world) { - m_staticRigidBody->SetTransform(world); + if (AzPhysics::SimulatedBody* body = GetSimulatedBody()) + { + body->SetTransform(world); + } } void StaticRigidBodyComponent::EnablePhysics() @@ -153,12 +154,31 @@ namespace PhysX bool StaticRigidBodyComponent::IsPhysicsEnabled() const { - return m_staticRigidBody != nullptr && m_staticRigidBody->m_simulating; + if (m_staticRigidBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) + { + if (auto* sceneInterface = AZ::Interface::Get(); + sceneInterface != nullptr && + sceneInterface->IsEnabled(m_attachedSceneHandle))//check if the scene is enabled + { + if (AzPhysics::SimulatedBody* body = sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_staticRigidBodyHandle)) + { + return body->m_simulating; + } + } + } + return false; } AZ::Aabb StaticRigidBodyComponent::GetAabb() const { - return m_staticRigidBody->GetAabb(); + if (auto* sceneInterface = AZ::Interface::Get()) + { + if (AzPhysics::SimulatedBody* body = sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_staticRigidBodyHandle)) + { + return body->GetAabb(); + } + } + return AZ::Aabb::CreateNull(); } AzPhysics::SimulatedBodyHandle StaticRigidBodyComponent::GetSimulatedBodyHandle() const @@ -168,14 +188,18 @@ namespace PhysX AzPhysics::SimulatedBody* StaticRigidBodyComponent::GetSimulatedBody() { - return m_staticRigidBody; + if (auto* sceneInterface = AZ::Interface::Get()) + { + return sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_staticRigidBodyHandle); + } + return nullptr; } AzPhysics::SceneQueryHit StaticRigidBodyComponent::RayCast(const AzPhysics::RayCastRequest& request) { - if (m_staticRigidBody) + if (auto* body = azdynamic_cast(GetSimulatedBody())) { - return m_staticRigidBody->RayCast(request); + return body->RayCast(request); } return AzPhysics::SceneQueryHit(); } diff --git a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.h b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.h index 660521ab7a..0f5bf1a4b2 100644 --- a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.h +++ b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.h @@ -65,7 +65,6 @@ namespace PhysX void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; AzPhysics::SimulatedBodyHandle m_staticRigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; - PhysX::StaticRigidBody* m_staticRigidBody = nullptr; AzPhysics::SceneHandle m_attachedSceneHandle = AzPhysics::InvalidSceneHandle; }; } // namespace PhysX diff --git a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp index 1d925570c5..1622d04aae 100644 --- a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp +++ b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp @@ -140,6 +140,9 @@ namespace PhysX } }; + AZ_Warning("PhysXSystem", deltaTime <= m_systemConfig.m_maxTimestep, + "Frame delta time of [%.6f seconds] exceeds Physics max frame timestep, physics timestep will be clamped to [%.6f seconds].", + deltaTime, m_systemConfig.m_maxTimestep); deltaTime = AZ::GetClamp(deltaTime, 0.0f, m_systemConfig.m_maxTimestep); AZ_Assert(m_systemConfig.m_fixedTimestep >= 0.0f, "PhysXSystem - fixed timestep is negitive."); diff --git a/Gems/PhysX/Code/Tests/PhysXTestCommon.cpp b/Gems/PhysX/Code/Tests/PhysXTestCommon.cpp index 2404a60e0d..93ad7704c9 100644 --- a/Gems/PhysX/Code/Tests/PhysXTestCommon.cpp +++ b/Gems/PhysX/Code/Tests/PhysXTestCommon.cpp @@ -415,6 +415,10 @@ namespace PhysX Physics::SphereShapeConfiguration shapeConfiguration; shapeConfiguration.m_radius = radius; AzPhysics::RigidBodyConfiguration rigidBodySettings; + rigidBodySettings.m_computeMass = false; + rigidBodySettings.m_computeInertiaTensor = false; + rigidBodySettings.m_computeCenterOfMass = false; + rigidBodySettings.m_mass = 1.0f; rigidBodySettings.m_position = position; rigidBodySettings.m_linearDamping = 0.0f; rigidBodySettings.m_colliderAndShapeData = AZStd::make_pair(&colliderConfig, &shapeConfiguration); @@ -437,6 +441,10 @@ namespace PhysX Physics::CapsuleShapeConfiguration shapeConfig(height, radius); rigidBodySettings.m_colliderAndShapeData = AZStd::make_pair(&colliderConfig, &shapeConfig); rigidBodySettings.m_position = position; + rigidBodySettings.m_computeMass = false; + rigidBodySettings.m_computeInertiaTensor = false; + rigidBodySettings.m_computeCenterOfMass = false; + rigidBodySettings.m_mass = 1.0f; if (auto* sceneInterface = AZ::Interface::Get()) { @@ -455,6 +463,10 @@ namespace PhysX shapeConfiguration.m_dimensions = dimensions; AzPhysics::RigidBodyConfiguration rigidBodySettings; + rigidBodySettings.m_computeMass = false; + rigidBodySettings.m_computeInertiaTensor = false; + rigidBodySettings.m_computeCenterOfMass = false; + rigidBodySettings.m_mass = 1.0f; rigidBodySettings.m_position = position; rigidBodySettings.m_linearDamping = 0.0f; rigidBodySettings.m_colliderAndShapeData = AZStd::make_pair(&colliderConfig, &shapeConfiguration); From a13c9e8d531c25d2c490e127f63d2964b3ba9c08 Mon Sep 17 00:00:00 2001 From: Hasareej <82398396+Hasareej@users.noreply.github.com> Date: Thu, 13 May 2021 14:23:31 +0100 Subject: [PATCH 181/225] Hasareej lyn 2301 cluster space (#717) ViewportUi widget anchoring & alignment update. --- .../EditorTransformComponentSelection.cpp | 2 +- .../ViewportUi/ViewportUiDisplay.cpp | 30 ++++++++++++++++--- .../ViewportUi/ViewportUiDisplay.h | 4 +-- .../ViewportUi/ViewportUiManager.cpp | 8 ++--- .../ViewportUi/ViewportUiManager.h | 4 +-- .../ViewportUi/ViewportUiRequestBus.h | 15 ++++++++-- .../Tests/Viewport/ViewportUiDisplayTests.cpp | 10 +++---- .../Tests/Viewport/ViewportUiManagerTests.cpp | 12 ++++---- .../Code/Editor/ColliderComponentMode.cpp | 2 +- .../Source/EditorWhiteBoxComponentMode.cpp | 2 +- 10 files changed, 61 insertions(+), 28 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index c6450d03c7..1766e65276 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -2526,7 +2526,7 @@ namespace AzToolsFramework // create the cluster for changing transform mode ViewportUi::ViewportUiRequestBus::EventResult( m_transformModeClusterId, ViewportUi::DefaultViewportId, - &ViewportUi::ViewportUiRequestBus::Events::CreateCluster); + &ViewportUi::ViewportUiRequestBus::Events::CreateCluster, ViewportUi::Alignment::TopLeft); // create and register the buttons (strings correspond to icons even if the values appear different) m_translateButtonId = RegisterClusterButton(m_transformModeClusterId, "Move"); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp index e67ac46f62..e9e7dcc1cc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp @@ -41,6 +41,28 @@ namespace AzToolsFramework::ViewportUi::Internal } } + static Qt::Alignment GetQtAlignment(Alignment align) + { + switch (align) + { + case Alignment::TopRight: + return Qt::AlignTop | Qt::AlignRight; + case Alignment::TopLeft: + return Qt::AlignTop | Qt::AlignLeft; + case Alignment::BottomRight: + return Qt::AlignBottom | Qt::AlignRight; + case Alignment::BottomLeft: + return Qt::AlignBottom | Qt::AlignLeft; + case Alignment::Top: + return Qt::AlignTop; + case Alignment::Bottom: + return Qt::AlignBottom; + } + + AZ_Assert(false, "ViewportUI", "Unhandled ViewportUI Alignment %d", static_cast(align)); + return Qt::AlignTop; + } + ViewportUiDisplay::ViewportUiDisplay(QWidget* parent, QWidget* renderOverlay) : m_renderOverlay(renderOverlay) , m_uiMainWindow(parent) @@ -56,7 +78,7 @@ namespace AzToolsFramework::ViewportUi::Internal UnparentWidgets(m_viewportUiElements); } - void ViewportUiDisplay::AddCluster(AZStd::shared_ptr buttonGroup) + void ViewportUiDisplay::AddCluster(AZStd::shared_ptr buttonGroup, const Alignment align) { if (!buttonGroup.get()) { @@ -66,7 +88,7 @@ namespace AzToolsFramework::ViewportUi::Internal auto viewportUiCluster = AZStd::make_shared(buttonGroup); auto id = AddViewportUiElement(viewportUiCluster); buttonGroup->SetViewportUiElementId(id); - PositionViewportUiElementAnchored(id, Qt::AlignTop | Qt::AlignLeft); + PositionViewportUiElementAnchored(id, GetQtAlignment(align)); } void ViewportUiDisplay::AddClusterButton( @@ -94,7 +116,7 @@ namespace AzToolsFramework::ViewportUi::Internal } } - void ViewportUiDisplay::AddSwitcher(AZStd::shared_ptr buttonGroup) + void ViewportUiDisplay::AddSwitcher(AZStd::shared_ptr buttonGroup, const Alignment align) { if (!buttonGroup.get()) { @@ -104,7 +126,7 @@ namespace AzToolsFramework::ViewportUi::Internal auto viewportUiSwitcher = AZStd::make_shared(buttonGroup); auto id = AddViewportUiElement(viewportUiSwitcher); buttonGroup->SetViewportUiElementId(id); - PositionViewportUiElementAnchored(id, Qt::AlignTop | Qt::AlignLeft); + PositionViewportUiElementAnchored(id, GetQtAlignment(align)); } void ViewportUiDisplay::AddSwitcherButton(const ViewportUiElementId clusterId, Button* button) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h index 7ef81986c0..d46e01c978 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h @@ -56,12 +56,12 @@ namespace AzToolsFramework::ViewportUi::Internal ViewportUiDisplay(QWidget* parent, QWidget* renderOverlay); ~ViewportUiDisplay(); - void AddCluster(AZStd::shared_ptr buttonGroup); + void AddCluster(AZStd::shared_ptr buttonGroup, Alignment align); void AddClusterButton(ViewportUiElementId clusterId, Button* button); void RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId); void UpdateCluster(const ViewportUiElementId clusterId); - void AddSwitcher(AZStd::shared_ptr buttonGroup); + void AddSwitcher(AZStd::shared_ptr buttonGroup, Alignment align); void AddSwitcherButton(ViewportUiElementId switcherId, Button* button); void RemoveSwitcherButton(ViewportUiElementId switcherId, ButtonId buttonId); void UpdateSwitcher(ViewportUiElementId switcherId); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp index 6eb97adb93..12c3b5c9bb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp @@ -30,18 +30,18 @@ namespace AzToolsFramework::ViewportUi ViewportUiRequestBus::Handler::BusDisconnect(); } - const ClusterId ViewportUiManager::CreateCluster() + const ClusterId ViewportUiManager::CreateCluster(const Alignment align) { auto buttonGroup = AZStd::make_shared(); - m_viewportUi->AddCluster(buttonGroup); + m_viewportUi->AddCluster(buttonGroup, align); return RegisterNewCluster(buttonGroup); } - const SwitcherId ViewportUiManager::CreateSwitcher() + const SwitcherId ViewportUiManager::CreateSwitcher(const Alignment align) { auto buttonGroup = AZStd::make_shared(); - m_viewportUi->AddSwitcher(buttonGroup); + m_viewportUi->AddSwitcher(buttonGroup, align); return RegisterNewSwitcher(buttonGroup); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h index 1b350bbd64..04a58cef65 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h @@ -31,8 +31,8 @@ namespace AzToolsFramework::ViewportUi ~ViewportUiManager() = default; // ViewportUiRequestBus ... - const ClusterId CreateCluster() override; - const SwitcherId CreateSwitcher() override; + const ClusterId CreateCluster(Alignment align) override; + const SwitcherId CreateSwitcher(Alignment align) override; void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) override; void SetSwitcherActiveButton(SwitcherId switcherId, ButtonId buttonId) override; const ButtonId CreateClusterButton(ClusterId clusterId, const AZStd::string& icon) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h index 5041f28656..3879817ccb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h @@ -41,15 +41,26 @@ namespace AzToolsFramework::ViewportUi String }; + //! Used to anchor widgets to a specific side of the viewport. + enum class Alignment + { + TopRight, + TopLeft, + BottomRight, + BottomLeft, + Top, + Bottom + }; + //! Viewport requests to interact with the Viewport UI. Viewport UI refers to the entire UI overlay (one per viewport). //! Each widget on the Viewport UI is referred to as an element. class ViewportUiRequests { public: //! Creates and registers a cluster with the Viewport UI system. - virtual const ClusterId CreateCluster() = 0; + virtual const ClusterId CreateCluster(Alignment align) = 0; //! Creates and registers a switcher with the Viewport UI system. - virtual const SwitcherId CreateSwitcher() = 0; + virtual const SwitcherId CreateSwitcher(Alignment align) = 0; //! Sets the active button of the cluster. This is the button which will display as highlighted. virtual void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) = 0; //! Sets the active button of the switcher. This is the button which has a text label. diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiDisplayTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiDisplayTests.cpp index a1ce868569..5fd102b450 100644 --- a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiDisplayTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiDisplayTests.cpp @@ -72,7 +72,7 @@ namespace UnitTest TEST_F(ViewportUiDisplayTestFixture, RemoveViewportUiElementRemovesElementFromViewportUi) { ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay); - viewportUi.AddCluster(m_buttonGroup); + viewportUi.AddCluster(m_buttonGroup, AzToolsFramework::ViewportUi::Alignment::TopLeft); auto widget = viewportUi.GetViewportUiElement(m_buttonGroup->GetViewportUiElementId()); EXPECT_TRUE(widget.get() != nullptr); @@ -89,7 +89,7 @@ namespace UnitTest ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay); viewportUi.InitializeUiOverlay(); - viewportUi.AddCluster(m_buttonGroup); + viewportUi.AddCluster(m_buttonGroup, AzToolsFramework::ViewportUi::Alignment::TopLeft); viewportUi.Update(); viewportUi.ShowViewportUiElement(m_buttonGroup->GetViewportUiElementId()); @@ -102,7 +102,7 @@ namespace UnitTest ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay); viewportUi.InitializeUiOverlay(); - viewportUi.AddCluster(m_buttonGroup); + viewportUi.AddCluster(m_buttonGroup, AzToolsFramework::ViewportUi::Alignment::TopLeft); viewportUi.HideViewportUiElement(m_buttonGroup->GetViewportUiElementId()); EXPECT_FALSE(viewportUi.IsViewportUiElementVisible(m_buttonGroup->GetViewportUiElementId())); @@ -112,7 +112,7 @@ namespace UnitTest { ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay); viewportUi.InitializeUiOverlay(); - viewportUi.AddCluster(m_buttonGroup); + viewportUi.AddCluster(m_buttonGroup, AzToolsFramework::ViewportUi::Alignment::TopLeft); viewportUi.Update(); auto widget = viewportUi.GetViewportUiElement(m_buttonGroup->GetViewportUiElementId()); @@ -129,7 +129,7 @@ namespace UnitTest auto buttonGroup = AZStd::make_shared(); buttonGroup->AddButton(""); - viewportUi.AddCluster(buttonGroup); + viewportUi.AddCluster(buttonGroup, AzToolsFramework::ViewportUi::Alignment::TopLeft); viewportUi.Update(); EXPECT_TRUE(viewportUi.GetUiMainWindow()->isVisible()); diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiManagerTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiManagerTests.cpp index 396bde3fdd..9babd0fe6d 100644 --- a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiManagerTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiManagerTests.cpp @@ -101,7 +101,7 @@ namespace UnitTest TEST_F(ViewportUiManagerTestFixture, CreateClusterAddsNewClusterAndReturnsId) { - auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(); + auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(AzToolsFramework::ViewportUi::Alignment::TopLeft); auto clusterEntry = m_viewportManagerWrapper.GetViewportManager()->GetClusterMap().find(clusterId); EXPECT_TRUE(clusterEntry != m_viewportManagerWrapper.GetViewportManager()->GetClusterMap().end()); @@ -110,7 +110,7 @@ namespace UnitTest TEST_F(ViewportUiManagerTestFixture, CreateClusterButtonAddsNewButtonAndReturnsId) { - auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(); + auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(AzToolsFramework::ViewportUi::Alignment::TopLeft); auto buttonId = m_viewportManagerWrapper.GetViewportManager()->CreateClusterButton(clusterId, ""); auto clusterEntry = m_viewportManagerWrapper.GetViewportManager()->GetClusterMap().find(clusterId); @@ -120,7 +120,7 @@ namespace UnitTest TEST_F(ViewportUiManagerTestFixture, SetClusterActiveButtonSetsButtonStateToActive) { - auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(); + auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(AzToolsFramework::ViewportUi::Alignment::TopLeft); auto buttonId = m_viewportManagerWrapper.GetViewportManager()->CreateClusterButton(clusterId, ""); auto clusterEntry = m_viewportManagerWrapper.GetViewportManager()->GetClusterMap().find(clusterId); @@ -133,7 +133,7 @@ namespace UnitTest TEST_F(ViewportUiManagerTestFixture, RegisterClusterEventHandlerConnectsHandlerToClusterEvent) { - auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(); + auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(AzToolsFramework::ViewportUi::Alignment::TopLeft); auto buttonId = m_viewportManagerWrapper.GetViewportManager()->CreateClusterButton(clusterId, ""); // create a handler which will be triggered by the cluster @@ -159,7 +159,7 @@ namespace UnitTest TEST_F(ViewportUiManagerTestFixture, RemoveClusterRemovesClusterFromViewportUi) { - auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(); + auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(AzToolsFramework::ViewportUi::Alignment::TopLeft); m_viewportManagerWrapper.GetViewportManager()->RemoveCluster(clusterId); auto clusterEntry = m_viewportManagerWrapper.GetViewportManager()->GetClusterMap().find(clusterId); @@ -171,7 +171,7 @@ namespace UnitTest { m_viewportManagerWrapper.GetMockRenderOverlay()->setVisible(true); - auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(); + auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(AzToolsFramework::ViewportUi::Alignment::TopLeft); auto buttonId = m_viewportManagerWrapper.GetViewportManager()->CreateClusterButton(clusterId, ""); m_viewportManagerWrapper.GetViewportManager()->Update(); diff --git a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp index 9aece90d90..7caa497344 100644 --- a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp +++ b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp @@ -240,7 +240,7 @@ namespace PhysX // create the cluster for changing transform mode AzToolsFramework::ViewportUi::ViewportUiRequestBus::EventResult( m_modeSelectionClusterId, AzToolsFramework::ViewportUi::DefaultViewportId, - &AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::CreateCluster); + &AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::CreateCluster, AzToolsFramework::ViewportUi::Alignment::TopLeft); // create and register the buttons m_dimensionsModeButtonId = RegisterClusterButton(m_modeSelectionClusterId, "Scale"); diff --git a/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponentMode.cpp b/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponentMode.cpp index 7677ee69f4..0772851cba 100644 --- a/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponentMode.cpp +++ b/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponentMode.cpp @@ -482,7 +482,7 @@ namespace WhiteBox // create the cluster for changing transform mode AzToolsFramework::ViewportUi::ViewportUiRequestBus::EventResult( m_modeSelectionClusterId, AzToolsFramework::ViewportUi::DefaultViewportId, - &AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::CreateCluster); + &AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::CreateCluster, AzToolsFramework::ViewportUi::Alignment::TopLeft); // create and register the buttons m_defaultModeButtonId = RegisterClusterButton(m_modeSelectionClusterId, "SketchMode"); From 7f79cc879698118c05dba138270e5e36955c94c2 Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Thu, 13 May 2021 15:04:00 +0100 Subject: [PATCH 182/225] RemoveSimulatedBody automatically updates the requested handle to be invalid once removed. (#740) --- .../AzFramework/Physics/PhysicsScene.h | 16 ++++++++-------- Gems/EMotionFX/Code/Tests/Mocks/PhysicsSystem.h | 4 ++-- .../Code/Source/EditorColliderComponent.cpp | 4 ---- .../Code/Source/EditorRigidBodyComponent.cpp | 2 -- .../Code/Source/EditorShapeColliderComponent.cpp | 2 -- .../PhysXCharacters/API/CharacterController.cpp | 1 - .../Source/PhysXCharacters/API/RagdollNode.cpp | 1 - Gems/PhysX/Code/Source/RigidBodyComponent.cpp | 1 - Gems/PhysX/Code/Source/Scene/PhysXScene.cpp | 6 ++++-- Gems/PhysX/Code/Source/Scene/PhysXScene.h | 4 ++-- .../Code/Source/Scene/PhysXSceneInterface.cpp | 4 ++-- .../Code/Source/Scene/PhysXSceneInterface.h | 4 ++-- .../Code/Source/StaticRigidBodyComponent.cpp | 1 - .../Benchmarks/PhysXBenchmarkWashingMachine.cpp | 2 -- .../Tests/Benchmarks/PhysXJointBenchmarks.cpp | 5 +---- .../Benchmarks/PhysXRigidBodyBenchmarks.cpp | 15 +++------------ Gems/PhysX/Code/Tests/PhysXSceneTests.cpp | 9 +++++++-- Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp | 1 - .../Code/Tests/ScriptCanvasPhysicsTest.cpp | 4 ++-- .../EditorWhiteBoxColliderComponent.cpp | 1 - .../Components/WhiteBoxColliderComponent.cpp | 1 - 21 files changed, 33 insertions(+), 55 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.h b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.h index db3ec15c83..58e53b0b0d 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.h @@ -88,13 +88,13 @@ namespace AzPhysics //! Remove a simulated body from the Scene.z //! @param sceneHandle A handle to the scene to remove the requested simulated body. - //! @param bodyHandle A handle to the simulated body being removed. - virtual void RemoveSimulatedBody(SceneHandle sceneHandle, SimulatedBodyHandle bodyHandle) = 0; + //! @param bodyHandle A handle to the simulated body being removed. This will be set to AzPhysics::InvalidSimulatedBodyHandle as they're no longer valid. + virtual void RemoveSimulatedBody(SceneHandle sceneHandle, SimulatedBodyHandle& bodyHandle) = 0; //! Remove a list of simulated bodies from the Scene. //! @param sceneHandle A handle to the scene to remove the simulated bodies from. - //! @param bodyHandles A list of simulated body handles to be removed. - virtual void RemoveSimulatedBodies(SceneHandle sceneHandle, const SimulatedBodyHandleList& bodyHandles) = 0; + //! @param bodyHandles A list of simulated body handles to be removed. All handles will be set to AzPhysics::InvalidSimulatedBodyHandle as they're no longer valid. + virtual void RemoveSimulatedBodies(SceneHandle sceneHandle, SimulatedBodyHandleList& bodyHandles) = 0; //! Enable / Disable simulation of the requested body. By default all bodies added are enabled. //! Disabling simulation the body will no longer be affected by any forces, collisions, or found with scene queries. @@ -286,12 +286,12 @@ namespace AzPhysics virtual SimulatedBodyList GetSimulatedBodiesFromHandle(const SimulatedBodyHandleList& bodyHandles) = 0; //! Remove a simulated body from the Scene. - //! @param bodyHandle A handle to the simulated body being removed. - virtual void RemoveSimulatedBody(SimulatedBodyHandle bodyHandle) = 0; + //! @param bodyHandle A handle to the simulated body being removed. This will be set to AzPhysics::InvalidSimulatedBodyHandle as they're no longer valid. + virtual void RemoveSimulatedBody(SimulatedBodyHandle& bodyHandle) = 0; //! Remove a list of simulated bodies from the Scene. - //! @param bodyHandles A list of simulated body handles to be removed. - virtual void RemoveSimulatedBodies(const SimulatedBodyHandleList& bodyHandles) = 0; + //! @param bodyHandles A list of simulated body handles to be removed. All handles will be set to AzPhysics::InvalidSimulatedBodyHandle as they're no longer valid. + virtual void RemoveSimulatedBodies(SimulatedBodyHandleList& bodyHandles) = 0; //! Enable / Disable simulation of the requested body. By default all bodies added are enabled. //! Disabling simulation the body will no longer be affected by any forces, collisions, or found with scene queries. diff --git a/Gems/EMotionFX/Code/Tests/Mocks/PhysicsSystem.h b/Gems/EMotionFX/Code/Tests/Mocks/PhysicsSystem.h index 1219e34448..22102fd38a 100644 --- a/Gems/EMotionFX/Code/Tests/Mocks/PhysicsSystem.h +++ b/Gems/EMotionFX/Code/Tests/Mocks/PhysicsSystem.h @@ -92,10 +92,10 @@ namespace Physics [[maybe_unused]] bool enable) override {} void RemoveSimulatedBody( [[maybe_unused]] AzPhysics::SceneHandle sceneHandle, - [[maybe_unused]] AzPhysics::SimulatedBodyHandle bodyHandle) override {} + [[maybe_unused]] AzPhysics::SimulatedBodyHandle& bodyHandle) override {} void RemoveSimulatedBodies( [[maybe_unused]] AzPhysics::SceneHandle sceneHandle, - [[maybe_unused]] const AzPhysics::SimulatedBodyHandleList& bodyHandles) override {} + [[maybe_unused]] AzPhysics::SimulatedBodyHandleList& bodyHandles) override {} void EnableSimulationOfBody( [[maybe_unused]] AzPhysics::SceneHandle sceneHandle, [[maybe_unused]] AzPhysics::SimulatedBodyHandle bodyHandle) override {} diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp index 2cf5835a1f..18bb06ba74 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp @@ -405,7 +405,6 @@ namespace PhysX if (m_sceneInterface) { m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorBodyHandle); - m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } } @@ -579,7 +578,6 @@ namespace PhysX if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorBodyHandle); - m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } return; } @@ -634,7 +632,6 @@ namespace PhysX if (m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorBodyHandle); - m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } m_editorBodyHandle = m_sceneInterface->AddSimulatedBody(m_editorSceneHandle, &configuration); @@ -1051,7 +1048,6 @@ namespace PhysX if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorBodyHandle); - m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } } diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp index f97e7c6cbd..efd65181da 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp @@ -283,7 +283,6 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorRigidBodyHandle); - m_editorRigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } } @@ -428,7 +427,6 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorRigidBodyHandle); - m_editorRigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; CreateEditorWorldRigidBody(); } diff --git a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp index b71bd47288..58b8995281 100644 --- a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp @@ -271,7 +271,6 @@ namespace PhysX if (m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorBodyHandle); - m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } m_editorBodyHandle = m_sceneInterface->AddSimulatedBody(m_editorSceneHandle, &configuration); @@ -681,7 +680,6 @@ namespace PhysX if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_editorBodyHandle); - m_editorBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } } diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterController.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterController.cpp index 9e5f92aa72..08df8c0601 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterController.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/API/CharacterController.cpp @@ -343,7 +343,6 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->RemoveSimulatedBody(m_sceneOwner, m_shadowBodyHandle); - m_shadowBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; m_shadowBody = nullptr; } } diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/API/RagdollNode.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/API/RagdollNode.cpp index 6e3b97212b..0f9c7644cd 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/API/RagdollNode.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/API/RagdollNode.cpp @@ -163,7 +163,6 @@ namespace PhysX sceneInterface->RemoveSimulatedBody(m_sceneOwner, m_rigidBodyHandle); } m_rigidBody = nullptr; - m_rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; m_sceneOwner = AzPhysics::InvalidSceneHandle; } } diff --git a/Gems/PhysX/Code/Source/RigidBodyComponent.cpp b/Gems/PhysX/Code/Source/RigidBodyComponent.cpp index 58b0749d0f..f770f8408c 100644 --- a/Gems/PhysX/Code/Source/RigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/RigidBodyComponent.cpp @@ -184,7 +184,6 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->RemoveSimulatedBody(m_attachedSceneHandle, m_rigidBodyHandle); - m_rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } Physics::RigidBodyRequestBus::Handler::BusDisconnect(); diff --git a/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp b/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp index 96e2d8a9bb..79aa767959 100644 --- a/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp +++ b/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp @@ -729,7 +729,7 @@ namespace PhysX return results; } - void PhysXScene::RemoveSimulatedBody(AzPhysics::SimulatedBodyHandle bodyHandle) + void PhysXScene::RemoveSimulatedBody(AzPhysics::SimulatedBodyHandle& bodyHandle) { if (bodyHandle == AzPhysics::InvalidSimulatedBodyHandle) { @@ -751,10 +751,12 @@ namespace PhysX m_deferredDeletions.push_back(m_simulatedBodies[index].second); m_simulatedBodies[index] = AZStd::make_pair(AZ::Crc32(), nullptr); m_freeSceneSlots.push(index); + + bodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } } - void PhysXScene::RemoveSimulatedBodies(const AzPhysics::SimulatedBodyHandleList& bodyHandles) + void PhysXScene::RemoveSimulatedBodies(AzPhysics::SimulatedBodyHandleList& bodyHandles) { for (auto& handle: bodyHandles) { diff --git a/Gems/PhysX/Code/Source/Scene/PhysXScene.h b/Gems/PhysX/Code/Source/Scene/PhysXScene.h index 8bf20fca55..2e257283f0 100644 --- a/Gems/PhysX/Code/Source/Scene/PhysXScene.h +++ b/Gems/PhysX/Code/Source/Scene/PhysXScene.h @@ -48,8 +48,8 @@ namespace PhysX AzPhysics::SimulatedBodyHandleList AddSimulatedBodies(const AzPhysics::SimulatedBodyConfigurationList& simulatedBodyConfigs) override; AzPhysics::SimulatedBody* GetSimulatedBodyFromHandle(AzPhysics::SimulatedBodyHandle bodyHandle) override; AzPhysics::SimulatedBodyList GetSimulatedBodiesFromHandle(const AzPhysics::SimulatedBodyHandleList& bodyHandles) override; - void RemoveSimulatedBody(AzPhysics::SimulatedBodyHandle bodyHandle) override; - void RemoveSimulatedBodies(const AzPhysics::SimulatedBodyHandleList& bodyHandles) override; + void RemoveSimulatedBody(AzPhysics::SimulatedBodyHandle& bodyHandle) override; + void RemoveSimulatedBodies(AzPhysics::SimulatedBodyHandleList& bodyHandles) override; void EnableSimulationOfBody(AzPhysics::SimulatedBodyHandle bodyHandle) override; void DisableSimulationOfBody(AzPhysics::SimulatedBodyHandle bodyHandle) override; AzPhysics::SceneQueryHits QueryScene(const AzPhysics::SceneQueryRequest* request) override; diff --git a/Gems/PhysX/Code/Source/Scene/PhysXSceneInterface.cpp b/Gems/PhysX/Code/Source/Scene/PhysXSceneInterface.cpp index 948529a5c8..3b3ab2f0f8 100644 --- a/Gems/PhysX/Code/Source/Scene/PhysXSceneInterface.cpp +++ b/Gems/PhysX/Code/Source/Scene/PhysXSceneInterface.cpp @@ -112,7 +112,7 @@ namespace PhysX return {}; //return an empty list } - void PhysXSceneInterface::RemoveSimulatedBody(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle bodyHandle) + void PhysXSceneInterface::RemoveSimulatedBody(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle& bodyHandle) { if (AzPhysics::Scene* scene = m_physxSystem->GetScene(sceneHandle)) { @@ -120,7 +120,7 @@ namespace PhysX } } - void PhysXSceneInterface::RemoveSimulatedBodies(AzPhysics::SceneHandle sceneHandle, const AzPhysics::SimulatedBodyHandleList& bodyHandles) + void PhysXSceneInterface::RemoveSimulatedBodies(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandleList& bodyHandles) { if (AzPhysics::Scene* scene = m_physxSystem->GetScene(sceneHandle)) { diff --git a/Gems/PhysX/Code/Source/Scene/PhysXSceneInterface.h b/Gems/PhysX/Code/Source/Scene/PhysXSceneInterface.h index 3bc08d641c..2edfbd8457 100644 --- a/Gems/PhysX/Code/Source/Scene/PhysXSceneInterface.h +++ b/Gems/PhysX/Code/Source/Scene/PhysXSceneInterface.h @@ -40,8 +40,8 @@ namespace PhysX AzPhysics::SimulatedBodyHandleList AddSimulatedBodies(AzPhysics::SceneHandle sceneHandle, const AzPhysics::SimulatedBodyConfigurationList& simulatedBodyConfigs) override; AzPhysics::SimulatedBody* GetSimulatedBodyFromHandle(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle bodyHandle) override; AzPhysics::SimulatedBodyList GetSimulatedBodiesFromHandle(AzPhysics::SceneHandle sceneHandle, const AzPhysics::SimulatedBodyHandleList& bodyHandles) override; - void RemoveSimulatedBody(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle bodyHandle) override; - void RemoveSimulatedBodies(AzPhysics::SceneHandle sceneHandle, const AzPhysics::SimulatedBodyHandleList& bodyHandles) override; + void RemoveSimulatedBody(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle& bodyHandle) override; + void RemoveSimulatedBodies(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandleList& bodyHandles) override; void EnableSimulationOfBody(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle bodyHandle) override; void DisableSimulationOfBody(AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle bodyHandle) override; AzPhysics::SceneQueryHits QueryScene(AzPhysics::SceneHandle sceneHandle, const AzPhysics::SceneQueryRequest* request) override; diff --git a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp index 881fb29750..bb1dfc4293 100644 --- a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp @@ -117,7 +117,6 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->RemoveSimulatedBody(m_attachedSceneHandle, m_staticRigidBodyHandle); - m_staticRigidBodyHandle = AzPhysics::InvalidSceneHandle; } AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXBenchmarkWashingMachine.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXBenchmarkWashingMachine.cpp index 463aea2f71..adc910e8c8 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXBenchmarkWashingMachine.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXBenchmarkWashingMachine.cpp @@ -129,10 +129,8 @@ namespace PhysX::Benchmarks for (int i = 0; i < NumCylinderSide; i++) { sceneInterface->RemoveSimulatedBody(m_sceneHandle, m_cylinder[i]); - m_cylinder[i] = AzPhysics::InvalidSimulatedBodyHandle; } sceneInterface->RemoveSimulatedBody(m_sceneHandle, m_blade); - m_blade = AzPhysics::InvalidSimulatedBodyHandle; } m_sceneHandle = AzPhysics::InvalidSceneHandle; } diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXJointBenchmarks.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXJointBenchmarks.cpp index 7143f08626..7d650d6bef 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXJointBenchmarks.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXJointBenchmarks.cpp @@ -404,10 +404,7 @@ namespace PhysX::Benchmarks } subTickTracker.Stop(); - for (auto handle : snakeRigidBodyHandles) - { - m_defaultScene->RemoveSimulatedBody(handle); - } + m_defaultScene->RemoveSimulatedBodies(snakeRigidBodyHandles); snakeRigidBodyHandles.clear(); //sort the frame times and get the P50, P90, P99 percentiles diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXRigidBodyBenchmarks.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXRigidBodyBenchmarks.cpp index 54f7d2219c..e295916554 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXRigidBodyBenchmarks.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXRigidBodyBenchmarks.cpp @@ -233,10 +233,7 @@ namespace PhysX::Benchmarks subTickTracker.Stop(); //object clean up - for (auto handle : rigidBodies) - { - m_defaultScene->RemoveSimulatedBody(handle); - } + m_defaultScene->RemoveSimulatedBodies(rigidBodies); rigidBodies.clear(); //sort the frame times and get the P50, P90, P99 percentiles @@ -310,10 +307,7 @@ namespace PhysX::Benchmarks //object clean up washingMachine.TearDownWashingMachine(); - for (auto handle : rigidBodies) - { - m_defaultScene->RemoveSimulatedBody(handle); - } + m_defaultScene->RemoveSimulatedBodies(rigidBodies); rigidBodies.clear(); //sort the frame times and get the P50, P90, P99 percentiles @@ -465,10 +459,7 @@ namespace PhysX::Benchmarks //object clean up collisionHandlers.clear(); washingMachine.TearDownWashingMachine(); - for (auto handle : rigidBodies) - { - m_defaultScene->RemoveSimulatedBody(handle); - } + m_defaultScene->RemoveSimulatedBodies(rigidBodies); rigidBodies.clear(); //sort the frame times and get the P50, P90, P99 percentiles diff --git a/Gems/PhysX/Code/Tests/PhysXSceneTests.cpp b/Gems/PhysX/Code/Tests/PhysXSceneTests.cpp index 2a30fad32d..2a38e1b867 100644 --- a/Gems/PhysX/Code/Tests/PhysXSceneTests.cpp +++ b/Gems/PhysX/Code/Tests/PhysXSceneTests.cpp @@ -237,13 +237,17 @@ namespace PhysX //select 1 to remove AzPhysics::SimulatedBodyHandle removedSelection = simBodyHandles[simBodyHandles.size() / 2]; + const AzPhysics::SimulatedBodyIndex removedIndex = AZStd::get(removedSelection); sceneInterface->RemoveSimulatedBody(m_testSceneHandle, removedSelection); + // The removedSelection handle should be set to invalid in RemoveSimulatedBody + EXPECT_EQ(removedSelection, AzPhysics::InvalidSimulatedBodyHandle); + //add a new one. AzPhysics::SimulatedBodyHandle newSimBodyHandle = sceneInterface->AddSimulatedBody(m_testSceneHandle, &config); //The old and new handle should share an index as the freed slot will be used - EXPECT_EQ(AZStd::get(removedSelection), + EXPECT_EQ(removedIndex, AZStd::get(newSimBodyHandle)); } @@ -287,9 +291,10 @@ namespace PhysX EXPECT_EQ(simBodyHandle, addEventSimBodyHandle); //remove the body + const AzPhysics::SimulatedBodyHandle removedHandle = simBodyHandle; //copy the handle as RemoveSimulatedBody will mark it invalid. sceneInterface->RemoveSimulatedBody(m_testSceneHandle, simBodyHandle); EXPECT_TRUE(removedTriggered); - EXPECT_EQ(simBodyHandle, removeEventSimBodyHandle); + EXPECT_EQ(removedHandle, removeEventSimBodyHandle); } TEST_F(PhysXSceneFixture, StartFinishSimulationEvents_triggerAsExpected) diff --git a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp index 8e4da0fe4b..74c88d0b46 100644 --- a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp +++ b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp @@ -882,7 +882,6 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->RemoveSimulatedBody(m_testSceneHandle, rigidBodyHandle); - rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } rigidBody = nullptr; } diff --git a/Gems/ScriptCanvasPhysics/Code/Tests/ScriptCanvasPhysicsTest.cpp b/Gems/ScriptCanvasPhysics/Code/Tests/ScriptCanvasPhysicsTest.cpp index c74030d6df..4b04434e13 100644 --- a/Gems/ScriptCanvasPhysics/Code/Tests/ScriptCanvasPhysicsTest.cpp +++ b/Gems/ScriptCanvasPhysics/Code/Tests/ScriptCanvasPhysicsTest.cpp @@ -90,10 +90,10 @@ namespace ScriptCanvasPhysicsTests [[maybe_unused]] bool enable) override {} void RemoveSimulatedBody( [[maybe_unused]] AzPhysics::SceneHandle sceneHandle, - [[maybe_unused]] AzPhysics::SimulatedBodyHandle bodyHandle) override {} + [[maybe_unused]] AzPhysics::SimulatedBodyHandle& bodyHandle) override {} void RemoveSimulatedBodies( [[maybe_unused]] AzPhysics::SceneHandle sceneHandle, - [[maybe_unused]] const AzPhysics::SimulatedBodyHandleList& bodyHandles) override {} + [[maybe_unused]] AzPhysics::SimulatedBodyHandleList& bodyHandles) override {} void EnableSimulationOfBody( [[maybe_unused]] AzPhysics::SceneHandle sceneHandle, [[maybe_unused]] AzPhysics::SimulatedBodyHandle bodyHandle) override {} diff --git a/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.cpp b/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.cpp index 97bce7631d..c8b189942e 100644 --- a/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.cpp +++ b/Gems/WhiteBox/Code/Source/Components/EditorWhiteBoxColliderComponent.cpp @@ -163,7 +163,6 @@ namespace WhiteBox if (m_sceneInterface) { m_sceneInterface->RemoveSimulatedBody(m_editorSceneHandle, m_rigidBodyHandle); - m_rigidBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } } diff --git a/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.cpp b/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.cpp index 117b175cda..41d0a4c5e3 100644 --- a/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.cpp +++ b/Gems/WhiteBox/Code/Source/Components/WhiteBoxColliderComponent.cpp @@ -132,7 +132,6 @@ namespace WhiteBox sceneInterface->RemoveSimulatedBody(defaultScene, m_simulatedBodyHandle); } } - m_simulatedBodyHandle = AzPhysics::InvalidSimulatedBodyHandle; } void WhiteBoxColliderComponent::OnTransformChanged( From 4aff32e719c604b59ccdef7e21ce3dcd9923a8dc Mon Sep 17 00:00:00 2001 From: bosnichd Date: Thu, 13 May 2021 08:55:36 -0600 Subject: [PATCH 183/225] More red code (#732) Remove: - Code/CryEngine/CryCommon/Platform - Some unused Code/CryEngine/CryCommon/Mock files - Code/Tools/CryXML and almost all of Code/Tools/CryCommonTools - Code/Tools/TestBed/ResourceCompilerImage - Tools/DeepBandwidthToExcel - Various .p4ignore files --- Code/.p4ignore | 6 - Code/CryEngine/CryCommon/CMakeLists.txt | 8 - .../CryCommon/Mocks/IMemoryManagerMock.h | 43 - Code/CryEngine/CryCommon/Mocks/INetworkMock.h | 47 - .../CryCommon/Mocks/MockCGFContent.h | 29 - .../Platform/Android/crycommon_android.cmake | 11 - .../Android/crycommon_android_files.cmake | 14 - ...ycommon_enginesettings_android_files.cmake | 13 - .../Platform/AppleTV/crycommon_appletv.cmake | 11 - ...crycommon_enginesettings_linux_files.cmake | 13 - .../Platform/Linux/crycommon_linux.cmake | 11 - .../Linux/crycommon_linux_files.cmake | 14 - .../Platform/Mac/crycommon_mac.cmake | 11 - .../Platform/Mac/crycommon_mac_files.cmake | 14 - .../Platform/Windows/crycommon_windows.cmake | 11 - .../Windows/crycommon_windows_files.cmake | 13 - .../crycommon_enginesettings_ios_files.cmake | 13 - .../Platform/iOS/crycommon_ios.cmake | 11 - .../Platform/iOS/crycommon_ios_files.cmake | 14 - .../CryCommon/Terrain/Bus/HeightmapDataBus.h | 102 - .../CryCommon/Terrain/Bus/TerrainBus.h | 56 - .../Terrain/Bus/TerrainProviderBus.h | 82 - .../Terrain/Bus/TerrainRendererBus.h | 37 - .../Terrain/Bus/WorldMaterialRequestsBus.h | 122 - Code/CryEngine/CryCommon/WinBase.cpp | 3 + .../CryEngine/CryCommon/crycommon_files.cmake | 7 +- .../CryCommon/crycommon_linux_files.cmake | 13 - .../CryCommon/crycommon_testing_files.cmake | 2 - .../CryEngine/CryCommon/stl/STLAlignedAlloc.h | 115 - .../CrySystem/Tests/Test_CryPrimitives.cpp | 16 - Code/Framework/AtomCore/.p4ignore | 1 - Code/Framework/AzCore/.p4ignore | 1 - Code/Sandbox/.p4ignore | 5 - Code/Tools/CMakeLists.txt | 1 - Code/Tools/CryCommonTools/CMakeLists.txt | 26 - Code/Tools/CryCommonTools/ColladaShared.h | 18 - Code/Tools/CryCommonTools/Decompose.cpp | 514 ---- Code/Tools/CryCommonTools/Decompose.h | 30 - Code/Tools/CryCommonTools/Exceptions.h | 43 - Code/Tools/CryCommonTools/FileUtil.cpp | 175 -- Code/Tools/CryCommonTools/FileUtil.h | 311 --- .../CryCommonTools/FileXmlBufferSource.h | 48 - Code/Tools/CryCommonTools/ILogger.h | 53 - Code/Tools/CryCommonTools/IPakSystem.h | 49 - Code/Tools/CryCommonTools/ISettings.h | 57 - Code/Tools/CryCommonTools/LocaleChanger.cpp | 27 - Code/Tools/CryCommonTools/LocaleChanger.h | 30 - Code/Tools/CryCommonTools/LogFile.cpp | 79 - Code/Tools/CryCommonTools/LogFile.h | 40 - Code/Tools/CryCommonTools/MathHelpers.h | 72 - Code/Tools/CryCommonTools/ModuleHelpers.cpp | 44 - Code/Tools/CryCommonTools/ModuleHelpers.h | 31 - Code/Tools/CryCommonTools/PakSystem.cpp | 380 --- Code/Tools/CryCommonTools/PakSystem.h | 69 - .../CryCommonTools/PakXmlFileBufferSource.h | 74 - Code/Tools/CryCommonTools/PathHelpers.cpp | 621 ----- Code/Tools/CryCommonTools/PathHelpers.h | 110 - .../UnixLike/ZipDir/ZipDir_Traits_UnixLike.h | 15 - .../Linux/ZipDir/ZipDir_Traits_Linux.h | 16 - .../Linux/ZipDir/ZipDir_Traits_Platform.h | 15 - .../Platform/Linux/platform_linux_files.cmake | 16 - .../Platform/Mac/ZipDir/ZipDir_Traits_Mac.h | 16 - .../Mac/ZipDir/ZipDir_Traits_Platform.h | 14 - .../Platform/Mac/platform_mac_files.cmake | 16 - .../Windows/ZipDir/ZipDir_Traits_Platform.h | 14 - .../Windows/ZipDir/ZipDir_Traits_Windows.h | 16 - .../Windows/platform_windows_files.cmake | 15 - Code/Tools/CryCommonTools/ProgressRange.h | 89 - Code/Tools/CryCommonTools/PropertyHelpers.cpp | 125 - Code/Tools/CryCommonTools/PropertyHelpers.h | 28 - Code/Tools/CryCommonTools/STLHelpers.cpp | 14 - Code/Tools/CryCommonTools/STLHelpers.h | 54 - Code/Tools/CryCommonTools/SimpleBitmap.h | 508 ---- Code/Tools/CryCommonTools/SimpleStringPool.h | 249 -- .../CryCommonTools/StealingThreadPool.cpp | 580 ----- .../Tools/CryCommonTools/StealingThreadPool.h | 123 - Code/Tools/CryCommonTools/SuffixUtil.h | 59 - .../CryCommonTools/SummedAreaFilterKernel.cpp | 442 ---- .../CryCommonTools/SummedAreaFilterKernel.h | 112 - .../CryCommonTools/TempFilePakExtraction.cpp | 129 - .../CryCommonTools/TempFilePakExtraction.h | 50 - Code/Tools/CryCommonTools/ThreadUtils.cpp | 171 -- Code/Tools/CryCommonTools/ThreadUtils.h | 288 --- Code/Tools/CryCommonTools/UI/log_icons.bmp | 3 - .../UnitTests/PathHelpersUnitTests.cpp | 807 ------- .../UnitTests/StringHelpersUnitTests.cpp | 1056 --------- Code/Tools/CryCommonTools/WeightFilterSet.cpp | 36 - Code/Tools/CryCommonTools/WeightFilterSet.h | 96 - Code/Tools/CryCommonTools/XMLPakFileSink.cpp | 55 - Code/Tools/CryCommonTools/XMLPakFileSink.h | 39 - Code/Tools/CryCommonTools/XMLWriter.cpp | 261 -- Code/Tools/CryCommonTools/XMLWriter.h | 185 -- Code/Tools/CryCommonTools/ZipDir/ZipDir.h | 30 - .../CryCommonTools/ZipDir/ZipDirCache.cpp | 298 --- .../Tools/CryCommonTools/ZipDir/ZipDirCache.h | 140 -- .../ZipDir/ZipDirCacheFactory.cpp | 804 ------- .../ZipDir/ZipDirCacheFactory.h | 143 -- .../CryCommonTools/ZipDir/ZipDirCacheRW.cpp | 2100 ----------------- .../CryCommonTools/ZipDir/ZipDirCacheRW.h | 283 --- .../CryCommonTools/ZipDir/ZipDirFind.cpp | 246 -- Code/Tools/CryCommonTools/ZipDir/ZipDirFind.h | 109 - .../CryCommonTools/ZipDir/ZipDirFindRW.cpp | 253 -- .../CryCommonTools/ZipDir/ZipDirFindRW.h | 110 - .../CryCommonTools/ZipDir/ZipDirList.cpp | 174 -- Code/Tools/CryCommonTools/ZipDir/ZipDirList.h | 138 -- .../ZipDir/ZipDirStructures.cpp | 670 ------ .../CryCommonTools/ZipDir/ZipDirTree.cpp | 356 --- Code/Tools/CryCommonTools/ZipDir/ZipDirTree.h | 103 - Code/Tools/CryCommonTools/ZipDir/ZipFile.h | 19 - .../CryCommonTools/ZipDir/ZipFileFormat.h | 388 --- .../ZipDir/ZipFileFormat_info.h | 112 - .../CryCommonTools/ZipDir/zipdirstructures.h | 426 ---- .../CryCommonTools/crycommontools_files.cmake | 39 - .../crycommontools_tests_files.cmake | 15 - Code/Tools/CryCommonTools/zlibstatd64.lib | 3 - Code/Tools/CryXML/CMakeLists.txt | 32 - Code/Tools/CryXML/CryXML.cpp | 105 - Code/Tools/CryXML/CryXML.def | 3 - Code/Tools/CryXML/CryXML_precompiled.cpp | 14 - Code/Tools/CryXML/CryXML_precompiled.h | 32 - Code/Tools/CryXML/ICryXML.h | 34 - Code/Tools/CryXML/IXMLSerializer.h | 68 - Code/Tools/CryXML/XML/xml.cpp | 1400 ----------- Code/Tools/CryXML/XML/xml.h | 471 ---- Code/Tools/CryXML/XMLSerializer.cpp | 40 - Code/Tools/CryXML/XMLSerializer.h | 31 - Code/Tools/CryXML/cryxml_files.cmake | 22 - .../Input/Bump2NormalHighQ.tif.exportsettings | 1 - ...usehighQWithAlpha256512.tif.exportsettings | 1 - ...usehighQWithAlpha512256.tif.exportsettings | 1 - .../Input/LuminanceOnly.tif.exportsettings | 1 - .../Input/NoPreset3DC_ddn.tif.exportsettings | 1 - .../Input/NoPresetX8R8G8B8.tif.exportsettings | 1 - ...PresetX8R8G8B8WithAlpha.tif.exportsettings | 1 - .../NoPresetX8R8G8B8_bump.tif.exportsettings | 1 - .../NoPresetX8R8G8B8_ddn.tif.exportsettings | 1 - .../Input/NoTIFSettings.tif.exportsettings | 1 - .../NoTIFSettings300400.tif.exportsettings | 1 - ...oTIFSettingsGrey_DDNDIF.tif.exportsettings | 1 - .../NoTIFSettings_DDNDIF.tif.exportsettings | 1 - .../Input/NormalmapLowQ.tif.exportsettings | 1 - ...ormalmapLowQReduce1_ddn.tif.exportsettings | 1 - .../NormalmapLowQ_ddn.tif.exportsettings | 1 - .../TestColorChart_cch.tif.exportsettings | 1 - .../diamand_plate_ddn.tif.exportsettings | 1 - Gems/Blast/Assets/.p4ignore | 1 - Tools/AnimationTest/assetImportTest.bat | 31 - Tools/DeepBandwidthToExcel/7z.exe | 3 - .../DeepBandwidthToExcel.exe | 3 - .../Template/[Content_Types].xml | 2 - .../DeepBandwidthToExcel/Template/_rels/.rels | 2 - .../Template/docProps/app.xml | 2 - .../Template/docProps/core.xml | 2 - .../Template/xl/_rels/workbook.xml.rels | 2 - .../Template/xl/calcChain.xml | 2 - .../Template/xl/charts/chart1.xml | 2 - .../Template/xl/charts/chart2.xml | 2 - .../Template/xl/charts/chart3.xml | 2 - .../Template/xl/charts/chart4.xml | 2 - .../Template/xl/charts/chart5.xml | 93 - .../Template/xl/charts/chart6.xml | 78 - .../Template/xl/charts/chart7.xml | 84 - .../Template/xl/charts/chart8.xml | 83 - .../xl/drawings/_rels/drawing1.xml.rels | 2 - .../xl/drawings/_rels/drawing2.xml.rels | 2 - .../xl/drawings/_rels/drawing3.xml.rels | 2 - .../xl/drawings/_rels/drawing4.xml.rels | 2 - .../xl/drawings/_rels/drawing5.xml.rels | 2 - .../xl/drawings/_rels/drawing6.xml.rels | 2 - .../xl/drawings/_rels/drawing7.xml.rels | 2 - .../xl/drawings/_rels/drawing8.xml.rels | 2 - .../Template/xl/drawings/drawing1.xml | 2 - .../Template/xl/drawings/drawing2.xml | 2 - .../Template/xl/drawings/drawing3.xml | 2 - .../Template/xl/drawings/drawing4.xml | 2 - .../Template/xl/drawings/drawing5.xml | 2 - .../Template/xl/drawings/drawing6.xml | 2 - .../Template/xl/drawings/drawing7.xml | 2 - .../Template/xl/drawings/drawing8.xml | 2 - .../Template/xl/sharedStrings.xml | 2 - .../Template/xl/styles.xml | 2 - .../Template/xl/theme/theme1.xml | 2 - .../Template/xl/workbook.xml | 2 - .../xl/worksheets/_rels/sheet1.xml.rels | 2 - .../xl/worksheets/_rels/sheet2.xml.rels | 2 - .../xl/worksheets/_rels/sheet3.xml.rels | 2 - .../xl/worksheets/_rels/sheet4.xml.rels | 2 - .../xl/worksheets/_rels/sheet5.xml.rels | 2 - .../xl/worksheets/_rels/sheet6.xml.rels | 2 - .../xl/worksheets/_rels/sheet7.xml.rels | 2 - .../xl/worksheets/_rels/sheet8.xml.rels | 2 - .../Template/xl/worksheets/sheet1.xml | 2 - .../Template/xl/worksheets/sheet2.xml | 2 - .../Template/xl/worksheets/sheet3.xml | 2 - .../Template/xl/worksheets/sheet4.xml | 19 - .../Template/xl/worksheets/sheet5.xml | 17 - .../Template/xl/worksheets/sheet6.xml | 18 - .../Template/xl/worksheets/sheet7.xml | 18 - .../Template/xl/worksheets/sheet8.xml | 18 - .../Template/xl/worksheets/sheet9.xml | 16 - .../Windows/package_filelists/atom.json | 11 - 201 files changed, 4 insertions(+), 19283 deletions(-) delete mode 100644 Code/.p4ignore delete mode 100644 Code/CryEngine/CryCommon/Mocks/IMemoryManagerMock.h delete mode 100644 Code/CryEngine/CryCommon/Mocks/INetworkMock.h delete mode 100644 Code/CryEngine/CryCommon/Mocks/MockCGFContent.h delete mode 100644 Code/CryEngine/CryCommon/Platform/Android/crycommon_android.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Android/crycommon_android_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Android/crycommon_enginesettings_android_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/AppleTV/crycommon_appletv.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Linux/crycommon_enginesettings_linux_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/iOS/crycommon_enginesettings_ios_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios.cmake delete mode 100644 Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios_files.cmake delete mode 100644 Code/CryEngine/CryCommon/Terrain/Bus/HeightmapDataBus.h delete mode 100644 Code/CryEngine/CryCommon/Terrain/Bus/TerrainBus.h delete mode 100644 Code/CryEngine/CryCommon/Terrain/Bus/TerrainProviderBus.h delete mode 100644 Code/CryEngine/CryCommon/Terrain/Bus/TerrainRendererBus.h delete mode 100644 Code/CryEngine/CryCommon/Terrain/Bus/WorldMaterialRequestsBus.h delete mode 100644 Code/CryEngine/CryCommon/crycommon_linux_files.cmake delete mode 100644 Code/CryEngine/CryCommon/stl/STLAlignedAlloc.h delete mode 100644 Code/Framework/AtomCore/.p4ignore delete mode 100644 Code/Framework/AzCore/.p4ignore delete mode 100644 Code/Sandbox/.p4ignore delete mode 100644 Code/Tools/CryCommonTools/ColladaShared.h delete mode 100644 Code/Tools/CryCommonTools/Decompose.cpp delete mode 100644 Code/Tools/CryCommonTools/Decompose.h delete mode 100644 Code/Tools/CryCommonTools/Exceptions.h delete mode 100644 Code/Tools/CryCommonTools/FileUtil.cpp delete mode 100644 Code/Tools/CryCommonTools/FileUtil.h delete mode 100644 Code/Tools/CryCommonTools/FileXmlBufferSource.h delete mode 100644 Code/Tools/CryCommonTools/ILogger.h delete mode 100644 Code/Tools/CryCommonTools/IPakSystem.h delete mode 100644 Code/Tools/CryCommonTools/ISettings.h delete mode 100644 Code/Tools/CryCommonTools/LocaleChanger.cpp delete mode 100644 Code/Tools/CryCommonTools/LocaleChanger.h delete mode 100644 Code/Tools/CryCommonTools/LogFile.cpp delete mode 100644 Code/Tools/CryCommonTools/LogFile.h delete mode 100644 Code/Tools/CryCommonTools/MathHelpers.h delete mode 100644 Code/Tools/CryCommonTools/ModuleHelpers.cpp delete mode 100644 Code/Tools/CryCommonTools/ModuleHelpers.h delete mode 100644 Code/Tools/CryCommonTools/PakSystem.cpp delete mode 100644 Code/Tools/CryCommonTools/PakSystem.h delete mode 100644 Code/Tools/CryCommonTools/PakXmlFileBufferSource.h delete mode 100644 Code/Tools/CryCommonTools/PathHelpers.cpp delete mode 100644 Code/Tools/CryCommonTools/PathHelpers.h delete mode 100644 Code/Tools/CryCommonTools/Platform/Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h delete mode 100644 Code/Tools/CryCommonTools/Platform/Linux/ZipDir/ZipDir_Traits_Linux.h delete mode 100644 Code/Tools/CryCommonTools/Platform/Linux/ZipDir/ZipDir_Traits_Platform.h delete mode 100644 Code/Tools/CryCommonTools/Platform/Linux/platform_linux_files.cmake delete mode 100644 Code/Tools/CryCommonTools/Platform/Mac/ZipDir/ZipDir_Traits_Mac.h delete mode 100644 Code/Tools/CryCommonTools/Platform/Mac/ZipDir/ZipDir_Traits_Platform.h delete mode 100644 Code/Tools/CryCommonTools/Platform/Mac/platform_mac_files.cmake delete mode 100644 Code/Tools/CryCommonTools/Platform/Windows/ZipDir/ZipDir_Traits_Platform.h delete mode 100644 Code/Tools/CryCommonTools/Platform/Windows/ZipDir/ZipDir_Traits_Windows.h delete mode 100644 Code/Tools/CryCommonTools/Platform/Windows/platform_windows_files.cmake delete mode 100644 Code/Tools/CryCommonTools/ProgressRange.h delete mode 100644 Code/Tools/CryCommonTools/PropertyHelpers.cpp delete mode 100644 Code/Tools/CryCommonTools/PropertyHelpers.h delete mode 100644 Code/Tools/CryCommonTools/STLHelpers.cpp delete mode 100644 Code/Tools/CryCommonTools/STLHelpers.h delete mode 100644 Code/Tools/CryCommonTools/SimpleBitmap.h delete mode 100644 Code/Tools/CryCommonTools/SimpleStringPool.h delete mode 100644 Code/Tools/CryCommonTools/StealingThreadPool.cpp delete mode 100644 Code/Tools/CryCommonTools/StealingThreadPool.h delete mode 100644 Code/Tools/CryCommonTools/SuffixUtil.h delete mode 100644 Code/Tools/CryCommonTools/SummedAreaFilterKernel.cpp delete mode 100644 Code/Tools/CryCommonTools/SummedAreaFilterKernel.h delete mode 100644 Code/Tools/CryCommonTools/TempFilePakExtraction.cpp delete mode 100644 Code/Tools/CryCommonTools/TempFilePakExtraction.h delete mode 100644 Code/Tools/CryCommonTools/ThreadUtils.cpp delete mode 100644 Code/Tools/CryCommonTools/ThreadUtils.h delete mode 100644 Code/Tools/CryCommonTools/UI/log_icons.bmp delete mode 100644 Code/Tools/CryCommonTools/UnitTests/PathHelpersUnitTests.cpp delete mode 100644 Code/Tools/CryCommonTools/UnitTests/StringHelpersUnitTests.cpp delete mode 100644 Code/Tools/CryCommonTools/WeightFilterSet.cpp delete mode 100644 Code/Tools/CryCommonTools/WeightFilterSet.h delete mode 100644 Code/Tools/CryCommonTools/XMLPakFileSink.cpp delete mode 100644 Code/Tools/CryCommonTools/XMLPakFileSink.h delete mode 100644 Code/Tools/CryCommonTools/XMLWriter.cpp delete mode 100644 Code/Tools/CryCommonTools/XMLWriter.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDir.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirCache.cpp delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirCache.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirCacheFactory.cpp delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirCacheFactory.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirCacheRW.cpp delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirCacheRW.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirFind.cpp delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirFind.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirFindRW.cpp delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirFindRW.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirList.cpp delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirList.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirStructures.cpp delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirTree.cpp delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipDirTree.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipFile.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipFileFormat.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/ZipFileFormat_info.h delete mode 100644 Code/Tools/CryCommonTools/ZipDir/zipdirstructures.h delete mode 100644 Code/Tools/CryCommonTools/crycommontools_tests_files.cmake delete mode 100644 Code/Tools/CryCommonTools/zlibstatd64.lib delete mode 100644 Code/Tools/CryXML/CMakeLists.txt delete mode 100644 Code/Tools/CryXML/CryXML.cpp delete mode 100644 Code/Tools/CryXML/CryXML.def delete mode 100644 Code/Tools/CryXML/CryXML_precompiled.cpp delete mode 100644 Code/Tools/CryXML/CryXML_precompiled.h delete mode 100644 Code/Tools/CryXML/ICryXML.h delete mode 100644 Code/Tools/CryXML/IXMLSerializer.h delete mode 100644 Code/Tools/CryXML/XML/xml.cpp delete mode 100644 Code/Tools/CryXML/XML/xml.h delete mode 100644 Code/Tools/CryXML/XMLSerializer.cpp delete mode 100644 Code/Tools/CryXML/XMLSerializer.h delete mode 100644 Code/Tools/CryXML/cryxml_files.cmake delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/Bump2NormalHighQ.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/DiffusehighQWithAlpha256512.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/DiffusehighQWithAlpha512256.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/LuminanceOnly.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoPreset3DC_ddn.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8WithAlpha.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8_bump.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8_ddn.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings300400.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettingsGrey_DDNDIF.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings_DDNDIF.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQ.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQReduce1_ddn.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQ_ddn.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/TestColorChart_cch.tif.exportsettings delete mode 100644 Code/Tools/TestBed/ResourceCompilerImage/Input/diamand_plate_ddn.tif.exportsettings delete mode 100644 Gems/Blast/Assets/.p4ignore delete mode 100644 Tools/AnimationTest/assetImportTest.bat delete mode 100644 Tools/DeepBandwidthToExcel/7z.exe delete mode 100644 Tools/DeepBandwidthToExcel/DeepBandwidthToExcel.exe delete mode 100644 Tools/DeepBandwidthToExcel/Template/[Content_Types].xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/_rels/.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/docProps/app.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/docProps/core.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/_rels/workbook.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/calcChain.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/charts/chart1.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/charts/chart2.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/charts/chart3.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/charts/chart4.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/charts/chart5.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/charts/chart6.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/charts/chart7.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/charts/chart8.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing1.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing2.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing3.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing4.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing5.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing6.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing7.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing8.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing1.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing2.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing3.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing4.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing5.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing6.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing7.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing8.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/sharedStrings.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/styles.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/theme/theme1.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/workbook.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet1.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet2.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet3.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet4.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet5.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet6.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet7.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet8.xml.rels delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet1.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet2.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet3.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet4.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet5.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet6.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet7.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet8.xml delete mode 100644 Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet9.xml diff --git a/Code/.p4ignore b/Code/.p4ignore deleted file mode 100644 index f0b9f1ea6b..0000000000 --- a/Code/.p4ignore +++ /dev/null @@ -1,6 +0,0 @@ -#Ignore these directories -SDKs - -#ColinB (8/26)- I know there are depot files that this will ignore... But these files should not be -#here, they should all be in 3rdParty... so we will ignore them until I can move them, it should -#be OK for now because they shouldn't change at all anyway. diff --git a/Code/CryEngine/CryCommon/CMakeLists.txt b/Code/CryEngine/CryCommon/CMakeLists.txt index 5105ff1a5b..3a1eb90d9d 100644 --- a/Code/CryEngine/CryCommon/CMakeLists.txt +++ b/Code/CryEngine/CryCommon/CMakeLists.txt @@ -9,23 +9,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_pal_tool_dirs(pal_tool_dirs ${CMAKE_CURRENT_LIST_DIR}/Platform) - ly_add_target( NAME CryCommon STATIC NAMESPACE Legacy FILES_CMAKE crycommon_files.cmake - ${pal_dir}/crycommon_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/crycommon_${PAL_PLATFORM_NAME_LOWERCASE}.cmake INCLUDE_DIRECTORIES PUBLIC . # Lots of code without CryCommon/ .. # Dangerous since exports CryEngine's path (client code can do CrySystem/ without depending on that target) - ${pal_dir} - ${pal_tool_dirs} BUILD_DEPENDENCIES PUBLIC AZ::AzCore diff --git a/Code/CryEngine/CryCommon/Mocks/IMemoryManagerMock.h b/Code/CryEngine/CryCommon/Mocks/IMemoryManagerMock.h deleted file mode 100644 index 63df006e14..0000000000 --- a/Code/CryEngine/CryCommon/Mocks/IMemoryManagerMock.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once -#include - -class MemoryManagerMock - : public IMemoryManager -{ -public: - MOCK_METHOD1(GetProcessMemInfo, - bool(SProcessMemInfo& minfo)); - MOCK_METHOD3(TraceDefineHeap, - HeapHandle(const char* heapName, size_t size, const void* pBase)); - MOCK_METHOD6(TraceHeapAlloc, - void(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint)); - MOCK_METHOD3(TraceHeapFree, - void(HeapHandle heap, void* mem, size_t blockSize)); - MOCK_METHOD1(TraceHeapSetColor, - void(uint32 color)); - MOCK_METHOD0(TraceHeapGetColor, - uint32()); - MOCK_METHOD1(TraceHeapSetLabel, - void(const char* sLabel)); - MOCK_METHOD1(CreateCustomMemoryHeapInstance, - ICustomMemoryHeap* const (EAllocPolicy const eAllocPolicy)); - MOCK_METHOD3(CreateGeneralExpandingMemoryHeap, - IGeneralMemoryHeap* (size_t upperLimit, size_t reserveSize, const char* sUsage)); - MOCK_METHOD3(CreateGeneralMemoryHeap, - IGeneralMemoryHeap* (void* base, size_t sz, const char* sUsage)); - MOCK_METHOD2(ReserveAddressRange, - IMemoryAddressRange* (size_t capacity, const char* sName)); - MOCK_METHOD2(CreatePageMappingHeap, - IPageMappingHeap* (size_t addressSpace, const char* sName)); -}; diff --git a/Code/CryEngine/CryCommon/Mocks/INetworkMock.h b/Code/CryEngine/CryCommon/Mocks/INetworkMock.h deleted file mode 100644 index b627f927bc..0000000000 --- a/Code/CryEngine/CryCommon/Mocks/INetworkMock.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -struct NetworkMock : public INetwork -{ - NetworkMock() : m_gridMate(nullptr) - { - } - GridMate::IGridMate* m_gridMate; - - void Release() override {} - void GetMemoryStatistics([[maybe_unused]] ICrySizer* pSizer) override {} - void GetBandwidthStatistics([[maybe_unused]] SBandwidthStats* const pStats) override {} - void GetPerformanceStatistics([[maybe_unused]] SNetworkPerformance* pSizer) override {} - void GetProfilingStatistics([[maybe_unused]] SNetworkProfilingStats* const pStats) override {} - void SyncWithGame([[maybe_unused]] ENetworkGameSync syncType) override {} - const char* GetHostName() override { return "testhostname"; } - GridMate::IGridMate* GetGridMate() override - { - return m_gridMate; - } - ChannelId GetChannelIdForSessionMember([[maybe_unused]] GridMate::GridMember* member) const override { return ChannelId(); } - ChannelId GetServerChannelId() const override { return ChannelId(); } - ChannelId GetLocalChannelId() const override { return ChannelId(); } - CTimeValue GetSessionTime() override { return CTimeValue(); } - void ChangedAspects([[maybe_unused]] EntityId id, [[maybe_unused]] NetworkAspectType aspectBits) override {} - void SetDelegatableAspectMask([[maybe_unused]] NetworkAspectType aspectBits) override {} - void SetObjectDelegatedAspectMask([[maybe_unused]] EntityId entityId, [[maybe_unused]] NetworkAspectType aspects, [[maybe_unused]] bool set) override {} - void DelegateAuthorityToClient([[maybe_unused]] EntityId entityId, [[maybe_unused]] ChannelId clientChannelId) override {} - void InvokeActorRMI([[maybe_unused]] EntityId entityId, [[maybe_unused]] uint8 actorExtensionId, [[maybe_unused]] ChannelId targetChannelFilter, [[maybe_unused]] IActorRMIRep& rep) override {} - void InvokeScriptRMI([[maybe_unused]] ISerializable* serializable, [[maybe_unused]] bool isServerRMI, [[maybe_unused]] ChannelId toChannelId = kInvalidChannelId, [[maybe_unused]] ChannelId avoidChannelId = kInvalidChannelId) override {} - void RegisterActorRMI([[maybe_unused]] IActorRMIRep* rep) override {} - void UnregisterActorRMI([[maybe_unused]] IActorRMIRep* rep) override {} - EntityId LocalEntityIdToServerEntityId([[maybe_unused]] EntityId localId) const override { return EntityId(); } - EntityId ServerEntityIdToLocalEntityId([[maybe_unused]] EntityId serverId, [[maybe_unused]] bool allowForcedEstablishment = false) const override { return EntityId(); } -}; diff --git a/Code/CryEngine/CryCommon/Mocks/MockCGFContent.h b/Code/CryEngine/CryCommon/Mocks/MockCGFContent.h deleted file mode 100644 index 8047a863f6..0000000000 --- a/Code/CryEngine/CryCommon/Mocks/MockCGFContent.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include - -#include - -class MockIAssetWriter - : public IAssetWriter -{ -public: - ~MockIAssetWriter() override = default; - MOCK_METHOD1(WriteCGF, - bool(CContentCGF* content)); - MOCK_METHOD2(WriteCHR, - bool(CContentCGF* content, IConvertContext* convertContext)); - MOCK_METHOD3(WriteSKIN, - bool(CContentCGF* content, IConvertContext* convertContext, bool exportMorphTargets)); -}; diff --git a/Code/CryEngine/CryCommon/Platform/Android/crycommon_android.cmake b/Code/CryEngine/CryCommon/Platform/Android/crycommon_android.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Android/crycommon_android.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Android/crycommon_android_files.cmake b/Code/CryEngine/CryCommon/Platform/Android/crycommon_android_files.cmake deleted file mode 100644 index 7b9245ae92..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Android/crycommon_android_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../WinBase.cpp -) diff --git a/Code/CryEngine/CryCommon/Platform/Android/crycommon_enginesettings_android_files.cmake b/Code/CryEngine/CryCommon/Platform/Android/crycommon_enginesettings_android_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Android/crycommon_enginesettings_android_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/Platform/AppleTV/crycommon_appletv.cmake b/Code/CryEngine/CryCommon/Platform/AppleTV/crycommon_appletv.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/AppleTV/crycommon_appletv.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_enginesettings_linux_files.cmake b/Code/CryEngine/CryCommon/Platform/Linux/crycommon_enginesettings_linux_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_enginesettings_linux_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux.cmake b/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux_files.cmake b/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux_files.cmake deleted file mode 100644 index 7b9245ae92..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../WinBase.cpp -) diff --git a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac.cmake b/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac_files.cmake b/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac_files.cmake deleted file mode 100644 index 7b9245ae92..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../WinBase.cpp -) diff --git a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows.cmake b/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows_files.cmake b/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_enginesettings_ios_files.cmake b/Code/CryEngine/CryCommon/Platform/iOS/crycommon_enginesettings_ios_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_enginesettings_ios_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios.cmake b/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - diff --git a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios_files.cmake b/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios_files.cmake deleted file mode 100644 index 7b9245ae92..0000000000 --- a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../WinBase.cpp -) diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/HeightmapDataBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/HeightmapDataBus.h deleted file mode 100644 index 93065e1196..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/HeightmapDataBus.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace Terrain -{ - class Viewport2D - { - public: - int m_topLeftX = 0; - int m_topLeftY = 0; - int m_width = 0; - int m_height = 0; - - Viewport2D() = default; - Viewport2D(const Viewport2D&) = default; - Viewport2D& operator=(const Viewport2D&) = default; - - Viewport2D(int topLeftX, int topLeftY, int width, int height) - : m_topLeftX(topLeftX) - , m_topLeftY(topLeftY) - , m_width(width) - , m_height(height) - { - } - }; - - // External height map data requests - class HeightmapDataRequestInfo - { - public: - HeightmapDataRequestInfo() = default; - HeightmapDataRequestInfo(const HeightmapDataRequestInfo& rhs) = default; - HeightmapDataRequestInfo& operator=(const HeightmapDataRequestInfo& rhs) = default; - - HeightmapDataRequestInfo(int viewportTopLeftX, int viewportTopLeftY, int viewportWidth, int viewportHeight, float metersPerPixel, AZ::Vector2 worldMin, AZ::Vector2 worldMax) - : m_viewport(viewportTopLeftX, viewportTopLeftY, viewportWidth, viewportHeight) - , m_metersPerPixel(metersPerPixel) - , m_worldMin(worldMin) - , m_worldMax(worldMax) - { - } - - float GetMetersPerPixel() const - { - return m_metersPerPixel; - } - - AZ::Vector2 GetWorldMin() const - { - return m_worldMin; - } - - AZ::Vector2 GetWorldMax() const - { - return m_worldMax; - } - - AZ::Vector2 GetWorldWidth() const - { - return (m_worldMax - m_worldMin); - } - - Viewport2D GetViewport() const - { - return m_viewport; - } - - private: - Viewport2D m_viewport; - AZ::Vector2 m_worldMin = AZ::Vector2(0.0f, 0.0f); - AZ::Vector2 m_worldMax = AZ::Vector2(0.0f, 0.0f); - float m_metersPerPixel = 1.0f; - }; - - class HeightmapDataNotifications - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - virtual void OnTerrainHeightDataChanged(const AZ::Aabb& dirtyRegion) = 0; - }; - using HeightmapDataNotificationBus = AZ::EBus; -} diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/TerrainBus.h deleted file mode 100644 index 2cfb5134c9..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainBus.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -class CShader; - -namespace Terrain -{ - class TerrainDataRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - virtual float GetHeightSynchronous(float x, float y) = 0; - virtual AZ::Vector3 GetNormalSynchronous(float x, float y) = 0; - - virtual CShader* GetTerrainHeightGeneratorShader() const = 0; - virtual CShader* GetTerrainMaterialCompositingShader() const = 0; - }; - using TerrainDataRequestBus = AZ::EBus; - - class TerrainShaderRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - virtual void RefreshShader(const AZStd::string_view name, CShader* shader) = 0; - virtual void ReleaseShader(CShader* shader) const = 0; - }; - using TerrainShaderRequestBus = AZ::EBus; -} diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainProviderBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/TerrainProviderBus.h deleted file mode 100644 index 6c1aca6ea7..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainProviderBus.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -#include - -#include "HeightmapDataBus.h" - -class CShader; - -namespace Terrain -{ - // This interface defines how the renderer can access the terrain system to set up state and gather information before rendering height maps - class TerrainProviderRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - //! allows multiple threads to call - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - // world properties - virtual AZ::Vector3 GetWorldSize() = 0; - virtual AZ::Vector3 GetRegionSize() = 0; - virtual AZ::Vector3 GetWorldOrigin() = 0; - virtual AZ::Vector2 GetHeightRange() = 0; - - // utility - virtual void GetRegionIndex(const AZ::Vector2& worldMin, const AZ::Vector2& worldMax, int& regionIndexX, int& regionIndexY) = 0; - - virtual float GetHeightAtIndexedPosition([[maybe_unused]] int ix, [[maybe_unused]] int iy) { return 64.0f; } - virtual float GetHeightAtWorldPosition([[maybe_unused]] float fx, [[maybe_unused]] float fy) { return 64.0f; } - virtual unsigned char GetSurfaceTypeAtIndexedPosition([[maybe_unused]] int ix, [[maybe_unused]] int iy) { return 0; } - }; - using TerrainProviderRequestBus = AZ::EBus; - - // This class exists for the terrain system to inject data into the renderer for generating the GPU-side terrain height map - struct CRETerrainContext - { - // Tract map - virtual void OnTractVersionUpdate() = 0; - - CShader* m_currentShader = nullptr; - }; - - class TerrainProviderNotifications - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - //! allows multiple threads to call - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - // interface to be implemented by the game, invoked by the terrain render element - - // pull settings from the world cache, so the next accessors are accurate - virtual void SynchronizeSettings(CRETerrainContext* context) = 0; - }; - using TerrainProviderNotificationBus = AZ::EBus; -} diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainRendererBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/TerrainRendererBus.h deleted file mode 100644 index ea644f5653..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainRendererBus.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace Terrain -{ - class TerrainRendererRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - //! allows multiple threads to call - using MutexType = AZStd::recursive_mutex; - - // Query state of the terrain renderer - // Returns true once the terrain renderer has fulfilled most data requests and is ready for rendering - virtual bool IsReady() = 0; - }; - using TerrainRendererRequestBus = AZ::EBus; -} diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/WorldMaterialRequestsBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/WorldMaterialRequestsBus.h deleted file mode 100644 index 3fb80f5f11..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/WorldMaterialRequestsBus.h +++ /dev/null @@ -1,122 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -struct IMaterial; -class ITexture; - -namespace Terrain -{ - struct MacroMaterial - { - // Textures - _smart_ptr m_macroColorMap = nullptr; - _smart_ptr m_macroGlossMap = nullptr; - _smart_ptr m_macroNormalMap = nullptr; - - // Material Params - AZ::Color m_macroColorMapColor; - float m_macroGlossMapScale = 1.0f; - float m_macroNormalMapScale = 1.0f; - float m_macroSpecReflectance = 0.03f; - - void Clear() - { - m_macroColorMap = nullptr; - m_macroGlossMap = nullptr; - m_macroNormalMap = nullptr; - - m_macroColorMapColor = AZ::Color(1.0f); - m_macroGlossMapScale = 1.0f; - m_macroNormalMapScale = 1.0f; - m_macroSpecReflectance = 0.03f; - } - }; - - struct TerrainMaterialLayer - { - _smart_ptr m_material = nullptr; - _smart_ptr m_splatTexture = nullptr; - - TerrainMaterialLayer(_smart_ptr material, _smart_ptr splatTexture) - : m_material(material) - , m_splatTexture(splatTexture) - { - } - }; - - struct RegionMaterials - { - MacroMaterial m_macroMaterial; - - AZStd::vector m_materialLayers; - _smart_ptr m_defaultMaterial = nullptr; - - RegionMaterials& operator=(const RegionMaterials& rhs) = default; - - void Clear() - { - m_materialLayers.clear(); - m_defaultMaterial = nullptr; - m_macroMaterial.Clear(); - } - }; - - const AZ::u32 kMaxRegionsPerTerrainMaterialRequest = 16; - typedef AZStd::pair RegionIndex; - typedef AZStd::fixed_vector RegionIndexVector; - typedef AZStd::fixed_vector RegionMaterialVector; - - enum class RequestResult - { - NoAssetsForRegion, - Loading, - Success - }; - - class WorldMaterialRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - //! allows multiple threads to call - using MutexType = AZStd::recursive_mutex; - - virtual void LoadWorld(const AZStd::string& worldName, int regionSize) = 0; - - virtual RequestResult RequestRegionMaterials(const RegionIndexVector& regions, RegionMaterialVector& outRegionMaterials) = 0; - - // Parameters: - // int tileX, tileY : Region tile indices - // Returns: - // bool : If true, region material data is loaded and exists. outMacroMaterial will be modified with the respective macro material data - // If false, no region material data has been loaded or exists for the given tile (may still have invalid material layers). - virtual RequestResult GetMacroMaterial(int tileX, int tileY, MacroMaterial& outMacroMaterial) = 0; - - virtual void GetTerrainPOMParameters(float& pomHeightBias, float& pomDisplacement, float& selfShadowStrength) = 0; - - //Get the surface type at a given position. If not loaded yet, returns "loadingMaterial". - virtual AZStd::string_view GetSurfaceTypeAtPosition(AZ::Vector2 position) = 0; - }; - using WorldMaterialRequestBus = AZ::EBus; -} // namespace Terrain - diff --git a/Code/CryEngine/CryCommon/WinBase.cpp b/Code/CryEngine/CryCommon/WinBase.cpp index e6ea1cd4a8..47cb943240 100644 --- a/Code/CryEngine/CryCommon/WinBase.cpp +++ b/Code/CryEngine/CryCommon/WinBase.cpp @@ -12,6 +12,7 @@ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Linux/Mac port support for Win32API calls +#if !defined(WIN32) #include "platform.h" // Note: This should be first to get consistent debugging definitions @@ -1667,3 +1668,5 @@ __finddata64_t::~__finddata64_t() } } #endif //defined(APPLE) || defined(LINUX) + +#endif // !defined(WIN32) diff --git a/Code/CryEngine/CryCommon/crycommon_files.cmake b/Code/CryEngine/CryCommon/crycommon_files.cmake index 77b51825f1..dff4ca66e7 100644 --- a/Code/CryEngine/CryCommon/crycommon_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_files.cmake @@ -249,7 +249,6 @@ set(FILES platform_impl.cpp Win32specific.h Win64specific.h - stl/STLAlignedAlloc.h LyShine/IDraw2d.h LyShine/ILyShine.h LyShine/ISprite.h @@ -341,11 +340,7 @@ set(FILES Maestro/Types/AssetBlendKey.h Maestro/Types/AssetBlends.h Maestro/Types/SequenceType.h - Terrain/Bus/WorldMaterialRequestsBus.h - Terrain/Bus/TerrainBus.h - Terrain/Bus/TerrainRendererBus.h - Terrain/Bus/HeightmapDataBus.h - Terrain/Bus/TerrainProviderBus.h StaticInstance.h Pak/CryPakUtils.h + WinBase.cpp ) diff --git a/Code/CryEngine/CryCommon/crycommon_linux_files.cmake b/Code/CryEngine/CryCommon/crycommon_linux_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/crycommon_linux_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/crycommon_testing_files.cmake b/Code/CryEngine/CryCommon/crycommon_testing_files.cmake index d20a33f791..b94be27c3b 100644 --- a/Code/CryEngine/CryCommon/crycommon_testing_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_testing_files.cmake @@ -14,12 +14,10 @@ set(FILES Mocks/IConsoleMock.h Mocks/ICryPakMock.h Mocks/ILogMock.h - Mocks/IMemoryManagerMock.h Mocks/ISystemMock.h Mocks/ITimerMock.h Mocks/ICVarMock.h Mocks/IRendererMock.h Mocks/ITextureMock.h Mocks/IRemoteConsoleMock.h - Mocks/MockCGFContent.h ) diff --git a/Code/CryEngine/CryCommon/stl/STLAlignedAlloc.h b/Code/CryEngine/CryCommon/stl/STLAlignedAlloc.h deleted file mode 100644 index dc21cead81..0000000000 --- a/Code/CryEngine/CryCommon/stl/STLAlignedAlloc.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implements an aligned allocator for STL -// based on the Mallocator (http://blogs.msdn.com/b/vcblog/archive/2008/08/28/the-mallocator.aspx) - -#pragma once - -#include // Required for size_t and ptrdiff_t and NULL - -#include - -namespace stl -{ - template - class AlignedAllocator - : public AZ::SimpleSchemaAllocator> - { - public: - AZ_TYPE_INFO(AlignedAllocator, "{DF152D8A-36ED-4A2A-9FA6-734F212716C6}"); - using Base = AZ::SimpleSchemaAllocator>; - using Descriptor = Base::Descriptor; - using Schema = AZ::ChildAllocatorSchema; - - AlignedAllocator() - : Base("AlignedAllocator", "Legacy Cry Aligned Allocator") - { - } - - pointer_type Allocate(size_type byteSize, size_type /*alignment*/, int flags /* = 0 */, const char* name /* = 0 */, const char* fileName /* = 0 */, int lineNum /* = 0 */, unsigned int suppressStackRecord /* = 0 */) override - { - return Base::Allocate(byteSize, Alignment, flags, name, fileName, lineNum, suppressStackRecord); - } - - void DeAllocate(pointer_type ptr, size_type byteSize, [[maybe_unused]] size_type alignment) override - { - return Base::DeAllocate(ptr, byteSize, Alignment); - } - - pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type /*newAlignment*/) override - { - return Base::ReAllocate(ptr, newSize, Alignment); - } - }; - - template - using aligned_alloc = AZ::AZStdAlloc>; - - ////////////////////////////////////////////////////////////////////////// - // Defines aligned vector type - ////////////////////////////////////////////////////////////////////////// - template - class aligned_vector - : public AZStd::vector > - { - public: - typedef aligned_alloc MyAlloc; - typedef AZStd::vector MySuperClass; - typedef aligned_vector MySelf; - typedef size_t size_type; - - aligned_vector() {} - explicit aligned_vector(const MyAlloc& _Al) - : MySuperClass(_Al) {} - explicit aligned_vector(size_type _Count) - : MySuperClass(_Count) {}; - aligned_vector(size_type _Count, const T& _Val) - : MySuperClass(_Count, _Val) {} - aligned_vector(size_type _Count, const T& _Val, const MyAlloc& _Al) - : MySuperClass(_Count, _Val) {} - aligned_vector(const MySelf& _Right) - : MySuperClass(_Right) {}; - - - template - aligned_vector(_Iter _First, _Iter _Last) - : MySuperClass(_First, _Last) {}; - - template - aligned_vector(_Iter _First, _Iter _Last, const MyAlloc& _Al) - : MySuperClass(_First, _Last, _Al) {}; - }; - - template - inline size_t size_of_aligned_vector(const Vec& c) - { - if (!c.empty()) - { - // Not really correct as not taking alignment into the account - return c.capacity() * sizeof(typename Vec::value_type); - } - return 0; - } -} // namespace stl - -// Specialize for the AlignedAllocator to provide one per module that does not use the -// environment for its storage. Since this allocator just uses LegacyAllocator -// to do the real work, it's fine if there is one of these per cry module -namespace AZ -{ - template - class AllocatorInstance> : public Internal::AllocatorInstanceBase, AllocatorStorage::ModuleStoragePolicy>> - { - }; -} diff --git a/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp b/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp index 2e6e646548..26d12ffd8c 100644 --- a/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp +++ b/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp @@ -12,7 +12,6 @@ #include "CrySystem_precompiled.h" #include #include -#include TEST(StringTests, CUT_Strings) { @@ -424,21 +423,6 @@ TEST_F(CryPrimitives, CUT_FixedString) EXPECT_EQ("0123", str5); } -////////////////////////////////////////////////////////////////////////// -// Unit Testing of aligned_vector -////////////////////////////////////////////////////////////////////////// -TEST_F(CryPrimitives, CUT_AlignedVector) -{ - stl::aligned_vector vec; - - vec.push_back(1); - vec.push_back(2); - vec.push_back(3); - - EXPECT_TRUE(vec.size() == 3); - EXPECT_TRUE(((INT_PTR)(&vec[0]) % 16) == 0); -} - TEST_F(CryPrimitives, CUT_DynArray) { LegacyDynArray a; diff --git a/Code/Framework/AtomCore/.p4ignore b/Code/Framework/AtomCore/.p4ignore deleted file mode 100644 index 6722cd96e7..0000000000 --- a/Code/Framework/AtomCore/.p4ignore +++ /dev/null @@ -1 +0,0 @@ -*.xml diff --git a/Code/Framework/AzCore/.p4ignore b/Code/Framework/AzCore/.p4ignore deleted file mode 100644 index 6722cd96e7..0000000000 --- a/Code/Framework/AzCore/.p4ignore +++ /dev/null @@ -1 +0,0 @@ -*.xml diff --git a/Code/Sandbox/.p4ignore b/Code/Sandbox/.p4ignore deleted file mode 100644 index 9c6b6fcd91..0000000000 --- a/Code/Sandbox/.p4ignore +++ /dev/null @@ -1,5 +0,0 @@ -#Ignore these directories -SDKs - -#ignore these files -*.user diff --git a/Code/Tools/CMakeLists.txt b/Code/Tools/CMakeLists.txt index db5476756b..278474819c 100644 --- a/Code/Tools/CMakeLists.txt +++ b/Code/Tools/CMakeLists.txt @@ -15,7 +15,6 @@ add_subdirectory(AWSNativeSDKInit) add_subdirectory(AzTestRunner) add_subdirectory(CrashHandler) add_subdirectory(CryCommonTools) -add_subdirectory(CryXML) add_subdirectory(News) add_subdirectory(PythonBindingsExample) add_subdirectory(RemoteConsole) diff --git a/Code/Tools/CryCommonTools/CMakeLists.txt b/Code/Tools/CryCommonTools/CMakeLists.txt index 0188506e97..63f535b1af 100644 --- a/Code/Tools/CryCommonTools/CMakeLists.txt +++ b/Code/Tools/CryCommonTools/CMakeLists.txt @@ -13,44 +13,18 @@ if (NOT PAL_TRAIT_BUILD_HOST_TOOLS) return() endif() -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - ly_add_target( NAME CryCommonTools STATIC NAMESPACE Legacy FILES_CMAKE crycommontools_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PUBLIC . - ${pal_dir} BUILD_DEPENDENCIES PRIVATE - 3rdParty::lz4 - 3rdParty::zlib - 3rdParty::zstd AZ::AzCore PUBLIC Legacy::CryCommon AZ::AzFramework ) - -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - ly_add_target( - NAME CryCommonTools.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Legacy - FILES_CMAKE - crycommontools_tests_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - UnitTests - BUILD_DEPENDENCIES - PRIVATE - Legacy::CryCommonTools - AZ::AzTest - ) - ly_add_googletest( - NAME Legacy::CryCommonTools.Tests - ) -endif() diff --git a/Code/Tools/CryCommonTools/ColladaShared.h b/Code/Tools/CryCommonTools/ColladaShared.h deleted file mode 100644 index edc8341fe1..0000000000 --- a/Code/Tools/CryCommonTools/ColladaShared.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_COLLADASHARED_H -#define CRYINCLUDE_CRYCOMMONTOOLS_COLLADASHARED_H -#pragma once - -static const char* g_LumberyardExportNodeTag = "LumberyardExportNode"; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_COLLADASHARED_H diff --git a/Code/Tools/CryCommonTools/Decompose.cpp b/Code/Tools/CryCommonTools/Decompose.cpp deleted file mode 100644 index 3cf88db251..0000000000 --- a/Code/Tools/CryCommonTools/Decompose.cpp +++ /dev/null @@ -1,514 +0,0 @@ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -#include - -// Taken from http://tog.acm.org/GraphicsGems/gemsiv/polar_decomp/Decompose.c - -/**** Decompose.c ****/ -/* Ken Shoemake, 1993 */ -#include -#include "Decompose.h" - -#pragma warning(disable:4244) // conversion from 'double' to 'float', possible loss of data -#pragma warning(disable:4305) // 'initializing' : truncation from 'double' to 'float' - -namespace decomp { - - /******* Matrix Preliminaries *******/ - - /** Fill out 3x3 matrix to 4x4 **/ -#define mat_pad(A) (A[W][X]=A[X][W]=A[W][Y]=A[Y][W]=A[W][Z]=A[Z][W]=0,A[W][W]=1) - -/** Copy nxn matrix A to C using "gets" for assignment **/ -#define mat_copy(C,gets,A,n) {int i,j; for(i=0;i= 0.0) { - s = sqrt(tr + mat[W][W]); - qu.w = s * 0.5; - s = 0.5 / s; - qu.x = (mat[Z][Y] - mat[Y][Z]) * s; - qu.y = (mat[X][Z] - mat[Z][X]) * s; - qu.z = (mat[Y][X] - mat[X][Y]) * s; - } else { - int h = X; - if (mat[Y][Y] > mat[X][X]) h = Y; - if (mat[Z][Z] > mat[h][h]) h = Z; - switch (h) { -#define caseMacro(i,j,k,I,J,K) \ - case I:\ - s = sqrt( (mat[I][I] - (mat[J][J]+mat[K][K])) + mat[W][W] );\ - qu.i = s*0.5;\ - s = 0.5 / s;\ - qu.j = (mat[I][J] + mat[J][I]) * s;\ - qu.k = (mat[K][I] + mat[I][K]) * s;\ - qu.w = (mat[K][J] - mat[J][K]) * s;\ - break - caseMacro(x, y, z, X, Y, Z); - caseMacro(y, z, x, Y, Z, X); - caseMacro(z, x, y, Z, X, Y); - } - } - if (mat[W][W] != 1.0) qu = Qt_Scale(qu, 1 / sqrt(mat[W][W])); - return (qu); - } - /******* Decomp Auxiliaries *******/ - - static HMatrix mat_id = { {1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1} }; - - /** Compute either the 1 or infinity norm of M, depending on tpose **/ - float mat_norm(HMatrix M, int tpose) - { - int i; - float sum, max; - max = 0.0; - for (i = 0; i < 3; i++) { - if (tpose) sum = fabs(M[0][i]) + fabs(M[1][i]) + fabs(M[2][i]); - else sum = fabs(M[i][0]) + fabs(M[i][1]) + fabs(M[i][2]); - if (max < sum) max = sum; - } - return max; - } - - float norm_inf(HMatrix M) { return mat_norm(M, 0); } - float norm_one(HMatrix M) { return mat_norm(M, 1); } - - /** Return index of column of M containing maximum abs entry, or -1 if M=0 **/ - int find_max_col(HMatrix M) - { - float abs, max; - int i, j, col; - max = 0.0; col = -1; - for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) { - abs = M[i][j]; if (abs < 0.0) abs = -abs; - if (abs > max) { max = abs; col = j; } - } - return col; - } - - /** Setup u for Household reflection to zero all v components but first **/ - void make_reflector(float* v, float* u) - { - float s = sqrt(vdot(v, v)); - u[0] = v[0]; u[1] = v[1]; - u[2] = v[2] + ((v[2] < 0.0) ? -s : s); - s = sqrt(2.0 / vdot(u, u)); - u[0] = u[0] * s; u[1] = u[1] * s; u[2] = u[2] * s; - } - - /** Apply Householder reflection represented by u to column vectors of M **/ - void reflect_cols(HMatrix M, float* u) - { - int i, j; - for (i = 0; i < 3; i++) { - float s = u[0] * M[0][i] + u[1] * M[1][i] + u[2] * M[2][i]; - for (j = 0; j < 3; j++) M[j][i] -= u[j] * s; - } - } - /** Apply Householder reflection represented by u to row vectors of M **/ - void reflect_rows(HMatrix M, float* u) - { - int i, j; - for (i = 0; i < 3; i++) { - float s = vdot(u, M[i]); - for (j = 0; j < 3; j++) M[i][j] -= u[j] * s; - } - } - - /** Find orthogonal factor Q of rank 1 (or less) M **/ - void do_rank1(HMatrix M, HMatrix Q) - { - float v1[3], v2[3], s; - int col; - mat_copy(Q, =, mat_id, 4); - /* If rank(M) is 1, we should find a non-zero column in M */ - col = find_max_col(M); - if (col < 0) return; /* Rank is 0 */ - v1[0] = M[0][col]; v1[1] = M[1][col]; v1[2] = M[2][col]; - make_reflector(v1, v1); reflect_cols(M, v1); - v2[0] = M[2][0]; v2[1] = M[2][1]; v2[2] = M[2][2]; - make_reflector(v2, v2); reflect_rows(M, v2); - s = M[2][2]; - if (s < 0.0) Q[2][2] = -1.0; - reflect_cols(Q, v1); reflect_rows(Q, v2); - } - - /** Find orthogonal factor Q of rank 2 (or less) M using adjoint transpose **/ - void do_rank2(HMatrix M, HMatrix MadjT, HMatrix Q) - { - float v1[3], v2[3]; - float w, x, y, z, c, s, d; - int col; - /* If rank(M) is 2, we should find a non-zero column in MadjT */ - col = find_max_col(MadjT); - if (col < 0) { do_rank1(M, Q); return; } /* Rank<2 */ - v1[0] = MadjT[0][col]; v1[1] = MadjT[1][col]; v1[2] = MadjT[2][col]; - make_reflector(v1, v1); reflect_cols(M, v1); - vcross(M[0], M[1], v2); - make_reflector(v2, v2); reflect_rows(M, v2); - w = M[0][0]; x = M[0][1]; y = M[1][0]; z = M[1][1]; - if (w * z > x* y) { - c = z + w; s = y - x; d = sqrt(c * c + s * s); c = c / d; s = s / d; - Q[0][0] = Q[1][1] = c; Q[0][1] = -(Q[1][0] = s); - } else { - c = z - w; s = y + x; d = sqrt(c * c + s * s); c = c / d; s = s / d; - Q[0][0] = -(Q[1][1] = c); Q[0][1] = Q[1][0] = s; - } - Q[0][2] = Q[2][0] = Q[1][2] = Q[2][1] = 0.0; Q[2][2] = 1.0; - reflect_cols(Q, v1); reflect_rows(Q, v2); - } - - - /******* Polar Decomposition *******/ - - /* Polar Decomposition of 3x3 matrix in 4x4, - * M = QS. See Nicholas Higham and Robert S. Schreiber, - * Fast Polar Decomposition of An Arbitrary Matrix, - * Technical Report 88-942, October 1988, - * Department of Computer Science, Cornell University. - */ - float polar_decomp(HMatrix M, HMatrix Q, HMatrix S) - { -#define TOL 1.0e-6 - HMatrix Mk, MadjTk, Ek; - float det, M_one, M_inf, MadjT_one, MadjT_inf, E_one, gamma, g1, g2; - int i, j; - mat_tpose(Mk, =, M, 3); - M_one = norm_one(Mk); M_inf = norm_inf(Mk); - do { - adjoint_transpose(Mk, MadjTk); - det = vdot(Mk[0], MadjTk[0]); - if (det == 0.0) { do_rank2(Mk, MadjTk, Mk); break; } - MadjT_one = norm_one(MadjTk); MadjT_inf = norm_inf(MadjTk); - gamma = sqrt(sqrt((MadjT_one * MadjT_inf) / (M_one * M_inf)) / fabs(det)); - g1 = gamma * 0.5; - g2 = 0.5 / (gamma * det); - mat_copy(Ek, =, Mk, 3); - mat_binop(Mk, =, g1 * Mk, +, g2 * MadjTk, 3); - mat_copy(Ek, -=, Mk, 3); - E_one = norm_one(Ek); - M_one = norm_one(Mk); M_inf = norm_inf(Mk); - } while (E_one > (M_one * TOL)); - mat_tpose(Q, =, Mk, 3); mat_pad(Q); - mat_mult(Mk, M, S); mat_pad(S); - for (i = 0; i < 3; i++) for (j = i; j < 3; j++) - S[i][j] = S[j][i] = 0.5 * (S[i][j] + S[j][i]); - return (det); - } - - - - - - - - - - - - - - - - - - /******* Spectral Decomposition *******/ - - /* Compute the spectral decomposition of symmetric positive semi-definite S. - * Returns rotation in U and scale factors in result, so that if K is a diagonal - * matrix of the scale factors, then S = U K (U transpose). Uses Jacobi method. - * See Gene H. Golub and Charles F. Van Loan. Matrix Computations. Hopkins 1983. - */ - HVect spect_decomp(HMatrix S, HMatrix U) - { - HVect kv; - double Diag[3], OffD[3]; /* OffD is off-diag (by omitted index) */ - double g, h, fabsh, fabsOffDi, t, theta, c, s, tau, ta, OffDq, a, b; - static char nxt[] = { Y,Z,X }; - int sweep, i, j; - mat_copy(U, =, mat_id, 4); - Diag[X] = S[X][X]; Diag[Y] = S[Y][Y]; Diag[Z] = S[Z][Z]; - OffD[X] = S[Y][Z]; OffD[Y] = S[Z][X]; OffD[Z] = S[X][Y]; - for (sweep = 20; sweep > 0; sweep--) { - float sm = fabs(OffD[X]) + fabs(OffD[Y]) + fabs(OffD[Z]); - if (sm == 0.0) break; - for (i = Z; i >= X; i--) { - int p = nxt[i]; int q = nxt[p]; - fabsOffDi = fabs(OffD[i]); - g = 100.0 * fabsOffDi; - if (fabsOffDi > 0.0) { - h = Diag[q] - Diag[p]; - fabsh = fabs(h); - if (fabsh + g == fabsh) { - t = OffD[i] / h; - } else { - theta = 0.5 * h / OffD[i]; - t = 1.0 / (fabs(theta) + sqrt(theta * theta + 1.0)); - if (theta < 0.0) t = -t; - } - c = 1.0 / sqrt(t * t + 1.0); s = t * c; - tau = s / (c + 1.0); - ta = t * OffD[i]; OffD[i] = 0.0; - Diag[p] -= ta; Diag[q] += ta; - OffDq = OffD[q]; - OffD[q] -= s * (OffD[p] + tau * OffD[q]); - OffD[p] += s * (OffDq - tau * OffD[p]); - for (j = Z; j >= X; j--) { - a = U[j][p]; b = U[j][q]; - U[j][p] -= s * (b + tau * a); - U[j][q] += s * (a - tau * b); - } - } - } - } - kv.x = Diag[X]; kv.y = Diag[Y]; kv.z = Diag[Z]; kv.w = 1.0; - return (kv); - } - - /******* Spectral Axis Adjustment *******/ - - /* Given a unit quaternion, q, and a scale vector, k, find a unit quaternion, p, - * which permutes the axes and turns freely in the plane of duplicate scale - * factors, such that q p has the largest possible w component, i.e. the - * smallest possible angle. Permutes k's components to go with q p instead of q. - * See Ken Shoemake and Tom Duff. Matrix Animation and Polar Decomposition. - * Proceedings of Graphics Interface 1992. Details on p. 262-263. - */ - Quat snuggle(Quat q, HVect* k) - { -#define SQRTHALF (0.7071067811865475244f) -#define sgn(n,v) ((n)?-(v):(v)) -#define swap(a,i,j) {a[3]=a[i]; a[i]=a[j]; a[j]=a[3];} -#define cycle(a,p) if (p) {a[3]=a[0]; a[0]=a[1]; a[1]=a[2]; a[2]=a[3];}\ - else {a[3]=a[2]; a[2]=a[1]; a[1]=a[0]; a[0]=a[3];} - Quat p; - float ka[4]; - int i, turn = -1; - ka[X] = k->x; ka[Y] = k->y; ka[Z] = k->z; - if (ka[X] == ka[Y]) { if (ka[X] == ka[Z]) turn = W; else turn = Z; } - else { if (ka[X] == ka[Z]) turn = Y; else if (ka[Y] == ka[Z]) turn = X; } - if (turn >= 0) { - Quat qtoz, qp; - unsigned neg[3], win; - double mag[3], t; - static Quat qxtoz = { 0,SQRTHALF,0,SQRTHALF }; - static Quat qytoz = { SQRTHALF,0,0,SQRTHALF }; - static Quat qppmm = { 0.5, 0.5,-0.5,-0.5 }; - static Quat qpppp = { 0.5, 0.5, 0.5, 0.5 }; - static Quat qmpmm = { -0.5, 0.5,-0.5,-0.5 }; - static Quat qpppm = { 0.5, 0.5, 0.5,-0.5 }; - static Quat q0001 = { 0.0, 0.0, 0.0, 1.0 }; - static Quat q1000 = { 1.0, 0.0, 0.0, 0.0 }; - switch (turn) { - default: return (Qt_Conj(q)); - case X: q = Qt_Mul(q, qtoz = qxtoz); swap(ka, X, Z) break; - case Y: q = Qt_Mul(q, qtoz = qytoz); swap(ka, Y, Z) break; - case Z: qtoz = q0001; break; - } - q = Qt_Conj(q); - mag[0] = (double)q.z * q.z + (double)q.w * q.w - 0.5; - mag[1] = (double)q.x * q.z - (double)q.y * q.w; - mag[2] = (double)q.y * q.z + (double)q.x * q.w; - for (i = 0; i < 3; i++) if (neg[i] = (mag[i] < 0.0)) mag[i] = -mag[i]; - if (mag[0] > mag[1]) { if (mag[0] > mag[2]) win = 0; else win = 2; } - else { if (mag[1] > mag[2]) win = 1; else win = 2; } - switch (win) { - case 0: if (neg[0]) p = q1000; else p = q0001; break; - case 1: if (neg[1]) p = qppmm; else p = qpppp; cycle(ka, 0) break; - case 2: if (neg[2]) p = qmpmm; else p = qpppm; cycle(ka, 1) break; - } - qp = Qt_Mul(q, p); - t = sqrt(mag[win] + 0.5); - p = Qt_Mul(p, Qt_(0.0, 0.0, -qp.z / t, qp.w / t)); - p = Qt_Mul(qtoz, Qt_Conj(p)); - } else { - float qa[4], pa[4]; - unsigned lo, hi, neg[4], par = 0; - double all, big, two; - qa[0] = q.x; qa[1] = q.y; qa[2] = q.z; qa[3] = q.w; - for (i = 0; i < 4; i++) { - pa[i] = 0.0; - if (neg[i] = (qa[i] < 0.0)) qa[i] = -qa[i]; - par ^= neg[i]; - } - /* Find two largest components, indices in hi and lo */ - if (qa[0] > qa[1]) lo = 0; else lo = 1; - if (qa[2] > qa[3]) hi = 2; else hi = 3; - if (qa[lo] > qa[hi]) { - if (qa[lo ^ 1] > qa[hi]) { hi = lo; lo ^= 1; } - else { hi ^= lo; lo ^= hi; hi ^= lo; } - } else {if (qa[hi^1]>qa[lo]) lo = hi^1;} - all = (qa[0] + qa[1] + qa[2] + qa[3]) * 0.5; - two = (qa[hi] + qa[lo]) * SQRTHALF; - big = qa[hi]; - if (all > two) { - if (all > big) {/*all*/ - {int i; for (i = 0; i < 4; i++) pa[i] = sgn(neg[i], 0.5); } - cycle(ka, par) - } else {/*big*/ pa[hi] = sgn(neg[hi],1.0);} - } else { - if (two > big) {/*two*/ - pa[hi] = sgn(neg[hi], SQRTHALF); pa[lo] = sgn(neg[lo], SQRTHALF); - if (lo > hi) { hi ^= lo; lo ^= hi; hi ^= lo; } - if (hi == W) { hi = "\001\002\000"[lo]; lo = 3 - hi - lo; } - swap(ka, hi, lo) - } else {/*big*/ pa[hi] = sgn(neg[hi],1.0);} - } - p.x = -pa[0]; p.y = -pa[1]; p.z = -pa[2]; p.w = pa[3]; - } - k->x = ka[X]; k->y = ka[Y]; k->z = ka[Z]; - return (p); - } - - - - - - - - - - - - /******* Decompose Affine Matrix *******/ - - /* Decompose 4x4 affine matrix A as TFRUK(U transpose), where t contains the - * translation components, q contains the rotation R, u contains U, k contains - * scale factors, and f contains the sign of the determinant. - * Assumes A transforms column vectors in right-handed coordinates. - * See Ken Shoemake and Tom Duff. Matrix Animation and Polar Decomposition. - * Proceedings of Graphics Interface 1992. - */ - void decomp_affine(HMatrix A, AffineParts* parts) - { - HMatrix Q, S, U; - Quat p; - float det; - parts->t = Qt_(A[X][W], A[Y][W], A[Z][W], 0); - det = polar_decomp(A, Q, S); - if (det < 0.0) { - mat_copy(Q, =, -Q, 3); - parts->f = -1; - } else parts->f = 1; - parts->q = Qt_FromMatrix(Q); - parts->k = spect_decomp(S, U); - parts->u = Qt_FromMatrix(U); - p = snuggle(parts->u, &parts->k); - parts->u = Qt_Mul(parts->u, p); - } - - /******* Invert Affine Decomposition *******/ - - /* Compute inverse of affine decomposition. - */ - void invert_affine(AffineParts* parts, AffineParts* inverse) - { - Quat t, p; - inverse->f = parts->f; - inverse->q = Qt_Conj(parts->q); - inverse->u = Qt_Mul(parts->q, parts->u); - inverse->k.x = (parts->k.x == 0.0) ? 0.0 : 1.0 / parts->k.x; - inverse->k.y = (parts->k.y == 0.0) ? 0.0 : 1.0 / parts->k.y; - inverse->k.z = (parts->k.z == 0.0) ? 0.0 : 1.0 / parts->k.z; - inverse->k.w = parts->k.w; - t = Qt_(-parts->t.x, -parts->t.y, -parts->t.z, 0); - t = Qt_Mul(Qt_Conj(inverse->u), Qt_Mul(t, inverse->u)); - t = Qt_(inverse->k.x * t.x, inverse->k.y * t.y, inverse->k.z * t.z, 0); - p = Qt_Mul(inverse->q, inverse->u); - t = Qt_Mul(p, Qt_Mul(t, Qt_Conj(p))); - inverse->t = (inverse->f > 0.0) ? t : Qt_(-t.x, -t.y, -t.z, 0); - } - -} diff --git a/Code/Tools/CryCommonTools/Decompose.h b/Code/Tools/CryCommonTools/Decompose.h deleted file mode 100644 index 88e04737b6..0000000000 --- a/Code/Tools/CryCommonTools/Decompose.h +++ /dev/null @@ -1,30 +0,0 @@ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -namespace decomp { -// Taken from http://tog.acm.org/GraphicsGems/gemsiv/polar_decomp/Decompose.h - -/**** Decompose.h - Basic declarations ****/ -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_DECOMPOSE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_DECOMPOSE_H -#pragma once - -typedef struct {float x, y, z, w;} Quat; /* Quaternion */ -enum QuatPart {X, Y, Z, W}; -typedef Quat HVect; /* Homogeneous 3D vector */ -typedef float HMatrix[4][4]; /* Right-handed, for column vectors */ -typedef struct { - HVect t; /* Translation components */ - Quat q; /* Essential rotation */ - Quat u; /* Stretch rotation */ - HVect k; /* Stretch factors */ - float f; /* Sign of determinant */ -} AffineParts; -float polar_decomp(HMatrix M, HMatrix Q, HMatrix S); -HVect spect_decomp(HMatrix S, HMatrix U); -Quat snuggle(Quat q, HVect *k); -void decomp_affine(HMatrix A, AffineParts *parts); -void invert_affine(AffineParts *parts, AffineParts *inverse); - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_DECOMPOSE_H - -} diff --git a/Code/Tools/CryCommonTools/Exceptions.h b/Code/Tools/CryCommonTools/Exceptions.h deleted file mode 100644 index cc8830f0dd..0000000000 --- a/Code/Tools/CryCommonTools/Exceptions.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_EXCEPTIONS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_EXCEPTIONS_H -#pragma once - - -#include -#include - -class BaseException - : public std::exception -{ -public: - BaseException(const string& msg) - : msg(msg) {} - virtual const char* what() const throw () {return msg.c_str(); } - -private: - string msg; -}; - -template -class Exception - : public BaseException -{ -public: - Exception(const string& msg) - : BaseException(msg) {} -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_EXCEPTIONS_H diff --git a/Code/Tools/CryCommonTools/FileUtil.cpp b/Code/Tools/CryCommonTools/FileUtil.cpp deleted file mode 100644 index d42a60bcc2..0000000000 --- a/Code/Tools/CryCommonTools/FileUtil.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "FileUtil.h" -#include "PathHelpers.h" -#include "StringHelpers.h" - -#include -#include - - -////////////////////////////////////////////////////////////////////////// -// returns true if 'dir' is a subdirectory of 'baseDir' or same directory as 'baseDir' -// note: returns false in case of wrong names passed -static bool IsSubdirOrSameDir(const char* dir, const char* baseDir) -{ - - AZ::IO::LocalFileIO localFileIO; - - char szFullPathDir[AZ_MAX_PATH_LEN]; - if(!localFileIO.ConvertToAbsolutePath(dir, szFullPathDir, sizeof(szFullPathDir))) - { - return false; - } - - char szFullPathBaseDir[2 * 1024]; - if(!localFileIO.ConvertToAbsolutePath(baseDir, szFullPathBaseDir, sizeof(szFullPathBaseDir))) - { - return false; - } - - const char* p = szFullPathDir; - const char* q = szFullPathBaseDir; - for (;; ++p, ++q) - { - if (tolower(*p) == tolower(*q)) - { - if (*p == 0) - { - // dir is exactly same as baseDir - return true; - } - continue; - } - - if ((*p == '/' || *p == '\\') && (*q == '/' || *q == '\\')) - { - continue; - } - - if (*p == 0) - { - // dir length is shorter than baseDir length. so it's not a subdir - return false; - } - - if (*q == 0) - { - // baseDir is shorter than dir. so may be it's a subdir. - const bool isSubdir = (*p == '/' || *p == '\\'); - return isSubdir; - } - - return false; - } -} - -////////////////////////////////////////////////////////////////////////// -// the paths must have trailing slash -static bool ScanDirectoryRecursive(const string& root, const string& path, const string& file, std::vector& files, bool recursive, const string& dirToIgnore) -{ - bool anyFound = false; - if (!dirToIgnore.empty()) - { - if (IsSubdirOrSameDir(root.c_str(), dirToIgnore.c_str())) - { - return anyFound; - } - } - - AZ::IO::LocalFileIO localFileIO; - localFileIO.FindFiles(root.c_str(), file.c_str(), [&](const char* filePath) -> bool - { - bool isDir = localFileIO.IsDirectory(filePath); - if (!isDir) - { - const string foundFilename(filePath); - if (StringHelpers::MatchesWildcardsIgnoreCase(foundFilename, file)) - { - anyFound = true; - files.push_back(PathHelpers::Join(path, PathHelpers::GetFilename(filePath))); - } - } - - return true; // Keep iterating - }); - - if (recursive) - { - localFileIO.FindFiles(root.c_str(), "*", [&](const char* filePath) -> bool - { - bool isDir = localFileIO.IsDirectory(filePath); - // If recursive. - if (isDir && strcmp(filePath, ".") && strcmp(filePath, "..")) - { - if (ScanDirectoryRecursive(filePath, PathHelpers::Join(path, PathHelpers::GetFilename(filePath)), file, files, recursive, dirToIgnore)) - { - anyFound = true; - } - } - return true; // Keep iterating - }); - } - - return anyFound; -} - -////////////////////////////////////////////////////////////////////////// - -bool FileUtil::ScanDirectory(const string& path, const string& file, std::vector& files, bool recursive, const string& dirToIgnore) -{ - return ScanDirectoryRecursive(path, "", file, files, recursive, dirToIgnore); -} - - -bool FileUtil::EnsureDirectoryExists(const char* szPathIn) -{ - if (!szPathIn || !szPathIn[0]) - { - return true; - } - - if (DirectoryExists(szPathIn)) - { - return true; - } - - std::vector path(szPathIn, szPathIn + strlen(szPathIn) + 1); - char* p = &path[0]; - - // Skip '/' and '//' in the beginning - while (*p == '/' || *p == '\\') - { - ++p; - } - - for (;; ) - { - while (*p != '/' && *p != '\\' && *p) - { - ++p; - } - const char saved = *p; - *p = 0; - AZ::IO::LocalFileIO().CreatePath(&path[0]); - *p++ = saved; - if (saved == 0) - { - break; - } - } - - return DirectoryExists(szPathIn); -} diff --git a/Code/Tools/CryCommonTools/FileUtil.h b/Code/Tools/CryCommonTools/FileUtil.h deleted file mode 100644 index cf258c074b..0000000000 --- a/Code/Tools/CryCommonTools/FileUtil.h +++ /dev/null @@ -1,311 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_FILEUTIL_H -#define CRYINCLUDE_CRYCOMMONTOOLS_FILEUTIL_H -#pragma once - -#include -#include - -#include - -#if AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) -#include -#endif -#if defined(AZ_PLATFORM_LINUX) -#include "Linux64Specific.h" -#endif // defined(AZ_PLATFORM_LINUX) - -#include -#include - -namespace FileUtil -{ - // Magic number explanation: - // Both epochs are Gregorian. 1970 - 1601 = 369. Assuming a leap - // year every four years, 369 / 4 = 92. However, 1700, 1800, and 1900 - // were NOT leap years, so 89 leap years, 280 non-leap years. - // 89 * 366 + 280 * 365 = 134744 days between epochs. Of course - // 60 * 60 * 24 = 86400 seconds per day, so 134744 * 86400 = - // 11644473600 = SECS_BETWEEN_EPOCHS. - // - // This result is also confirmed in the MSDN documentation on how - // to convert a time_t value to a win32 FILETIME. - #define SECS_BETWEEN_EPOCHS 11644473600ll - /* 10^7 */ - #define SECS_TO_100NS 10000000ll - - // Find all files matching filespec. - bool ScanDirectory(const string& path, const string& filespec, std::vector& files, bool recursive, const string& dirToIgnore); - - // Ensures that directory specified by szPathIn exists by creating all needed (sub-)directories. - // Returns false in case of a failure. - // Example: "c:\temp\test" ("c:\temp\test\" also works) - ensures that "c:\temp\test" exists. - bool EnsureDirectoryExists(const char* szPathIn); - - // converts the FILETIME to the C Timestamp (compatible with dbghelp.dll) - inline DWORD FiletimeToUnixTime(const FILETIME& ft) - { - return (DWORD)((((int64&)ft) / SECS_TO_100NS) - SECS_BETWEEN_EPOCHS); - } - - // converts the FILETIME to 64bit C timestamp - inline AZ::u64 FiletimeTo64BitUnixTime(const FILETIME& fileTime) - { - const AZ::u64 time = static_cast(fileTime.dwHighDateTime) << 32 | fileTime.dwLowDateTime; - return ((time / SECS_TO_100NS) - SECS_BETWEEN_EPOCHS); - } - - // converts the C Timestamp (compatible with dbghelp.dll) to FILETIME - inline FILETIME UnixTimeToFiletime(DWORD nCTime) - { - const int64 time = (nCTime + SECS_BETWEEN_EPOCHS) * SECS_TO_100NS; - return (FILETIME&)time; - } - - //converts the 64 bit C Timestamp to FILETIME - inline void UnixTime64BitToFiletime(AZ::u64 nCTime, FILETIME& fileTime) - { - const AZ::u64 time = (nCTime + SECS_BETWEEN_EPOCHS) * SECS_TO_100NS; - fileTime.dwLowDateTime = static_cast(time); - fileTime.dwHighDateTime = static_cast(time >> 32); - } - - inline FILETIME GetInvalidFileTime() - { - FILETIME fileTime; - fileTime.dwLowDateTime = 0; - fileTime.dwHighDateTime = 0; - return fileTime; - } - - // returns file time stamps -#if defined(AZ_PLATFORM_WINDOWS) - inline bool GetFileTimes(const char* filename, FILETIME* ftimeCreate = nullptr, FILETIME* ftimeAccess = nullptr, FILETIME* ftimeModify = nullptr) - { - WIN32_FIND_DATAA FindFileData; - const HANDLE hFind = FindFirstFileA(filename, &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) - { - return false; - } - - if (ftimeModify == nullptr && ftimeCreate == nullptr && ftimeAccess == nullptr) - { - FindClose(hFind); - return true; - } - - FindClose(hFind); - if (ftimeCreate) - { - ftimeCreate->dwLowDateTime = FindFileData.ftCreationTime.dwLowDateTime; - ftimeCreate->dwHighDateTime = FindFileData.ftCreationTime.dwHighDateTime; - } - if (ftimeModify) - { - ftimeModify->dwLowDateTime = FindFileData.ftLastWriteTime.dwLowDateTime; - ftimeModify->dwHighDateTime = FindFileData.ftLastWriteTime.dwHighDateTime; - } - if (ftimeAccess) - { - ftimeAccess->dwLowDateTime = FindFileData.ftLastAccessTime.dwLowDateTime; - ftimeAccess->dwHighDateTime = FindFileData.ftCreationTime.dwHighDateTime; - } - return true; - } -#else - inline bool GetFileTimes(const char* filename, AZ::u64* timeCreate = nullptr, AZ::u64* timeAccess = nullptr, AZ::u64* timeModify = nullptr) - { - - struct stat statResult; - if (stat(filename, &statResult) != 0) - { - return false; - } - - if (timeCreate) - { - *timeCreate =static_cast(statResult.st_ctime); - } - if (timeModify) - { - *timeModify =static_cast(statResult.st_mtime); - } - if (timeAccess) - { - *timeAccess =static_cast(statResult.st_atime); - } - return true; - } -#endif - - - - inline FILETIME GetLastWriteFileTime(const char* filename) - { - FILETIME timeModify = GetInvalidFileTime(); -#if defined(AZ_PLATFORM_WINDOWS) - GetFileTimes(filename, nullptr, nullptr, &timeModify); -#else - AZ::u64 modTime = 0; - GetFileTimes(filename, nullptr, nullptr, &modTime); - if(modTime != 0) - { - UnixTime64BitToFiletime(modTime, timeModify); - } -#endif - return timeModify; - } - - inline bool FileTimesAreEqual(const FILETIME& fileTime0, const FILETIME& fileTime1) - { - return - (fileTime0.dwLowDateTime == fileTime1.dwLowDateTime) && - (fileTime0.dwHighDateTime == fileTime1.dwHighDateTime); - } - - inline bool FileTimesAreEqual(const char* const srcfilename, const char* const targetfilename) - { - FILETIME ftSource = FileUtil::GetLastWriteFileTime(srcfilename); - FILETIME ftTarget = FileUtil::GetLastWriteFileTime(targetfilename); - return FileTimesAreEqual(ftSource, ftTarget); - } - - inline bool FileTimeIsValid(const FILETIME& fileTime) - { - return !FileTimesAreEqual(GetInvalidFileTime(), fileTime); - } - - inline bool SetFileTimes(const char* const filename, const FILETIME& creationFileTime, const FILETIME& accessFileTime, const FILETIME& modifcationFileTime) - { -#if defined(AZ_PLATFORM_WINDOWS) - const HANDLE hf = CreateFileA(filename, FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (hf != INVALID_HANDLE_VALUE) - { - if (SetFileTime(hf, &creationFileTime, &accessFileTime, &modifcationFileTime)) - { - if (CloseHandle(hf)) - { - return true; - } - } - - CloseHandle(hf); - } -#else - AZ::u64 creationTime = FiletimeTo64BitUnixTime(creationFileTime); - AZ::u64 modificationTime = FiletimeTo64BitUnixTime(modifcationFileTime); - - struct utimbuf puttime; - puttime.modtime = modificationTime; - puttime.actime = creationTime; - - if (utime(filename, &puttime) == 0) - { - return true; - } - -#endif - return false; - } - - inline bool SetFileTimes(const char* const filename, const FILETIME& fileTime) - { -#if defined(AZ_PLATFORM_WINDOWS) - const HANDLE hf = CreateFileA(filename, FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (hf != INVALID_HANDLE_VALUE) - { - if (SetFileTime(hf, &fileTime, &fileTime, &fileTime)) - { - if (CloseHandle(hf)) - { - return true; - } - } - - CloseHandle(hf); - } -#else - - AZ::u64 newTime = FiletimeTo64BitUnixTime(fileTime); - - struct utimbuf puttime; - puttime.modtime = newTime; - puttime.actime = newTime; - - if (utime(filename, &puttime) == 0) - { - return true; - } -#endif - return false; - } - - inline bool SetFileTimes(const char* const srcfilename, const char* const targetfilename) - { -#if defined(AZ_PLATFORM_WINDOWS) - FILETIME creationFileTime, accessFileTime, modifcationFileTime; - if (GetFileTimes(srcfilename, &creationFileTime, &accessFileTime, &modifcationFileTime)) - { - const HANDLE hf = CreateFileA(targetfilename, FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (hf != INVALID_HANDLE_VALUE) - { - if (SetFileTime(hf, &creationFileTime, &accessFileTime, &modifcationFileTime)) - { - if (CloseHandle(hf)) - { - return true; - } - } - - CloseHandle(hf); - } - } -#else - AZ::u64 creationFileTime, accessFileTime, modifcationFileTime; - if (GetFileTimes(srcfilename, &creationFileTime, &accessFileTime, &modifcationFileTime)) - { - struct utimbuf puttime; - puttime.modtime = modifcationFileTime; - puttime.actime = accessFileTime; - - if (utime(targetfilename, &puttime) == 0) - { - return true; - } - } -#endif - return false; - } - - inline uint64 GetFileSize(const char* const filename) - { - AZ::u64 fileSize = AZ::IO::SystemFile::Length(filename); - return fileSize >= 0? fileSize : -1; - - } - - inline bool FileExists(const char* szPath) - { - return AZ::IO::LocalFileIO().Exists(szPath); - } - - inline bool DirectoryExists(const char* szPath) - { - return AZ::IO::LocalFileIO().IsDirectory(szPath); - } -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_FILEUTIL_H diff --git a/Code/Tools/CryCommonTools/FileXmlBufferSource.h b/Code/Tools/CryCommonTools/FileXmlBufferSource.h deleted file mode 100644 index de802a3311..0000000000 --- a/Code/Tools/CryCommonTools/FileXmlBufferSource.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_FILEXMLBUFFERSOURCE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_FILEXMLBUFFERSOURCE_H -#pragma once - - -class FileXmlBufferSource - : public IXmlBufferSource -{ -public: - FileXmlBufferSource(const char* path) - { - file = std::fopen(path, "r"); - } - ~FileXmlBufferSource() - { - if (file) - { - std::fclose(file); - } - } - - virtual int Read(void* buffer, int size) const - { - if (!file) - { - return 0; - } - return std::fread(buffer, 1, size, file); - } - -private: - mutable std::FILE* file; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_FILEXMLBUFFERSOURCE_H diff --git a/Code/Tools/CryCommonTools/ILogger.h b/Code/Tools/CryCommonTools/ILogger.h deleted file mode 100644 index cbcbae3094..0000000000 --- a/Code/Tools/CryCommonTools/ILogger.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ILOGGER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ILOGGER_H -#pragma once - - -#include -#include - -class ILogger -{ -public: - enum ESeverity - { - eSeverity_Debug, - eSeverity_Info, - eSeverity_Warning, - eSeverity_Error - }; - - virtual ~ILogger() - { - } - - void Log(ESeverity eSeverity, const char* const format, ...) - { - char buffer[2048]; - { - va_list args; - va_start(args, format); - _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, format, args); - va_end(args); - } - LogImpl(eSeverity, buffer); - } - -protected: - virtual void LogImpl(ESeverity eSeverity, const char* text) = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ILOGGER_H diff --git a/Code/Tools/CryCommonTools/IPakSystem.h b/Code/Tools/CryCommonTools/IPakSystem.h deleted file mode 100644 index d8646c3a2c..0000000000 --- a/Code/Tools/CryCommonTools/IPakSystem.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_IPAKSYSTEM_H -#define CRYINCLUDE_CRYCOMMONTOOLS_IPAKSYSTEM_H -#pragma once - -#include - -struct PakSystemFile; -struct PakSystemArchive; -struct IPakSystem -{ - virtual PakSystemFile* Open(const char* filename, const char* mode) = 0; - virtual bool ExtractNoOverwrite(const char* filename, const char* extractToFile = 0) = 0; - virtual void Close(PakSystemFile* file) = 0; - virtual int GetLength(PakSystemFile* file) const = 0; - virtual int Read(PakSystemFile* file, void* buffer, int size) = 0; - virtual bool EoF(PakSystemFile* file) = 0; - - virtual PakSystemArchive* OpenArchive(const char* path, size_t fileAlignment = 1, bool encrypted = false, const uint32 encryptionKey[4] = 0) = 0; - virtual void CloseArchive(PakSystemArchive* archive) = 0; - - // Summary: - // Adds a new file to the pak or update an existing one. - // Adds a directory (creates several nested directories if needed) - // Arguments: - // path - relative path inside archive - // data, size - file content - // modTime - modification timestamp of the file - // compressionLevel - level of compression (correnponds to zlib-levels): - // -1 or [0-9] where -1=default compression, 0=no compression, 9=best compression - virtual void AddToArchive(PakSystemArchive* archive, const char* path, void* data, int size, int64 modTime, int compressionLevel = -1) = 0; - - virtual bool DeleteFromArchive(PakSystemArchive* archive, const char* path) = 0; - virtual bool CheckIfFileExist(PakSystemArchive* archive, const char* path, int64 modTime) = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_IPAKSYSTEM_H diff --git a/Code/Tools/CryCommonTools/ISettings.h b/Code/Tools/CryCommonTools/ISettings.h deleted file mode 100644 index bba3100215..0000000000 --- a/Code/Tools/CryCommonTools/ISettings.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ISETTINGS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ISETTINGS_H -#pragma once - - -class ISettings -{ -public: - virtual bool GetSettingString(char* buffer, int bufferSizeInBytes, const char* key) = 0; - virtual bool GetSettingInt(int& value, const char* key) = 0; -}; - -inline bool GetSettingByRef(ISettings* settings, const string& key, string& value) -{ - char buffer[1024]; - bool success = false; - if (settings) - { - success = settings->GetSettingString(buffer, sizeof(buffer), key.c_str()); - } - if (success) - { - value = buffer; - } - return success; -} - -inline bool GetSettingByRef(ISettings* settings, const string& key, int& value) -{ - return settings->GetSettingInt(value, key.c_str()); -} - -template -inline T GetSetting(ISettings* settings, const string& key, const T& dflt) -{ - T value; - if (!GetSettingByRef(settings, key, value)) - { - value = dflt; - } - return value; -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ISETTINGS_H diff --git a/Code/Tools/CryCommonTools/LocaleChanger.cpp b/Code/Tools/CryCommonTools/LocaleChanger.cpp deleted file mode 100644 index 3a9edee30a..0000000000 --- a/Code/Tools/CryCommonTools/LocaleChanger.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "LocaleChanger.h" -#include - -LocaleChanger::LocaleChanger(int category, const char* newLocale) -{ - m_category = category; - m_oldLocale = setlocale(category, newLocale); -} - -LocaleChanger::~LocaleChanger() -{ - setlocale(m_category, m_oldLocale.c_str()); -} diff --git a/Code/Tools/CryCommonTools/LocaleChanger.h b/Code/Tools/CryCommonTools/LocaleChanger.h deleted file mode 100644 index 3b85c462a2..0000000000 --- a/Code/Tools/CryCommonTools/LocaleChanger.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_LOCALECHANGER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_LOCALECHANGER_H -#pragma once - - -class LocaleChanger -{ -public: - LocaleChanger(int category, const char* newLocale); - ~LocaleChanger(); - -private: - int m_category; - string m_oldLocale; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_LOCALECHANGER_H diff --git a/Code/Tools/CryCommonTools/LogFile.cpp b/Code/Tools/CryCommonTools/LogFile.cpp deleted file mode 100644 index ef98be776b..0000000000 --- a/Code/Tools/CryCommonTools/LogFile.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "LogFile.h" - -LogFile::LogFile(const char* const filename) - : m_file(0) - , m_hasWarnings(false) - , m_hasErrors(false) -{ - m_file = std::fopen(filename, "w"); -} - -LogFile::~LogFile() -{ - if (m_file) - { - fclose(m_file); - } -} - -bool LogFile::IsOpen() const -{ - return m_file != 0; -} - -bool LogFile::HasWarningsOrErrors() const -{ - return m_hasWarnings || m_hasErrors; -} - -void LogFile::LogImpl(ESeverity eSeverity, const char* const text) -{ - const char* severityMessage = 0; - switch (eSeverity) - { - case eSeverity_Debug: - severityMessage = " "; - break; - case eSeverity_Info: - severityMessage = " "; - break; - case eSeverity_Warning: - severityMessage = "W: "; - break; - case eSeverity_Error: - severityMessage = "E: "; - break; - default: - severityMessage = "?: "; - break; - } - - if (eSeverity == eSeverity_Warning) - { - m_hasWarnings = true; - } - if (eSeverity == eSeverity_Error) - { - m_hasErrors = true; - } - - if (m_file) - { - fprintf(m_file, "%s%s\n", severityMessage, text); - fflush(m_file); - } -} diff --git a/Code/Tools/CryCommonTools/LogFile.h b/Code/Tools/CryCommonTools/LogFile.h deleted file mode 100644 index d26c457165..0000000000 --- a/Code/Tools/CryCommonTools/LogFile.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_LOGFILE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_LOGFILE_H -#pragma once - - -#include "ILogger.h" - -class LogFile - : public ILogger -{ -public: - LogFile(const char* filename); - ~LogFile(); - - bool IsOpen() const; - bool HasWarningsOrErrors() const; - - // ILogger - virtual void LogImpl(ESeverity eSeverity, const char* message); - -private: - std::FILE* m_file; - bool m_hasWarnings; - bool m_hasErrors; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_LOGFILE_H diff --git a/Code/Tools/CryCommonTools/MathHelpers.h b/Code/Tools/CryCommonTools/MathHelpers.h deleted file mode 100644 index d21c14aa6c..0000000000 --- a/Code/Tools/CryCommonTools/MathHelpers.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_MATHHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_MATHHELPERS_H -#pragma once - - -#include -#if (_M_IX86_FP > 0) -#include -#endif - -namespace MathHelpers -{ -#if (_M_IX86_FP > 0) - inline int FastRoundFloatTowardZero(float f) - { - return _mm_cvtt_ss2si(_mm_set_ss(f)); - } -#else - inline int FastRoundFloatTowardZero(float f) - { - return int(f); - } -#endif - -#if defined(AZ_PLATFORM_WINDOWS) - - inline unsigned int EnableFloatingPointExceptions(unsigned int mask) - { - _clearfp(); - unsigned int oldMask; - _controlfp_s(&oldMask, 0, 0); - unsigned int newMask; - _controlfp_s(&newMask, ~mask, _MCW_EM); - return ~oldMask; - } - - class AutoFloatingPointExceptions - { - public: - AutoFloatingPointExceptions(const unsigned int mask) - : m_mask(EnableFloatingPointExceptions(mask)) - { - } - - ~AutoFloatingPointExceptions() - { - EnableFloatingPointExceptions(m_mask); - } - - private: - unsigned int m_mask; - }; - -#endif //AZ_PLATFORM_WINDOWS -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_MATHHELPERS_H - - diff --git a/Code/Tools/CryCommonTools/ModuleHelpers.cpp b/Code/Tools/CryCommonTools/ModuleHelpers.cpp deleted file mode 100644 index 2ce5c2639a..0000000000 --- a/Code/Tools/CryCommonTools/ModuleHelpers.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "ModuleHelpers.h" - -HMODULE ModuleHelpers::GetCurrentModule(CurrentModuleSpecifier moduleSpecifier) -{ - switch (moduleSpecifier) - { - case CurrentModuleSpecifier_Executable: - return GetModuleHandle(0); - - case CurrentModuleSpecifier_Library: - MEMORY_BASIC_INFORMATION mbi; - static int dummy; - VirtualQuery(&dummy, &mbi, sizeof(mbi)); - HMODULE instance = reinterpret_cast(mbi.AllocationBase); - return instance; - } - - return 0; -} - -std::basic_string ModuleHelpers::GetCurrentModulePath(CurrentModuleSpecifier moduleSpecifier) -{ - // Here's a trick that will get you the handle of the module - // you're running in without any a-priori knowledge: - // http://www.dotnet247.com/247reference/msgs/13/65259.aspx - HMODULE instance = GetCurrentModule(moduleSpecifier); - TCHAR moduleNameBuffer[MAX_PATH]; - GetModuleFileName(instance, moduleNameBuffer, sizeof(moduleNameBuffer) / sizeof(moduleNameBuffer[0])); - return moduleNameBuffer; -} diff --git a/Code/Tools/CryCommonTools/ModuleHelpers.h b/Code/Tools/CryCommonTools/ModuleHelpers.h deleted file mode 100644 index cb9049e89b..0000000000 --- a/Code/Tools/CryCommonTools/ModuleHelpers.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_MODULEHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_MODULEHELPERS_H -#pragma once - - -namespace ModuleHelpers -{ - enum CurrentModuleSpecifier - { - CurrentModuleSpecifier_Executable, - CurrentModuleSpecifier_Library - }; - - HMODULE GetCurrentModule(CurrentModuleSpecifier moduleSpecifier); - std::basic_string GetCurrentModulePath(CurrentModuleSpecifier moduleSpecifier); -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_MODULEHELPERS_H diff --git a/Code/Tools/CryCommonTools/PakSystem.cpp b/Code/Tools/CryCommonTools/PakSystem.cpp deleted file mode 100644 index 42a129c5e6..0000000000 --- a/Code/Tools/CryCommonTools/PakSystem.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "PakSystem.h" -#include "PathHelpers.h" -#include "StringHelpers.h" -#include "ZipDir/ZipDir.h" - -#include -#include -#include - - - -PakSystemFile::PakSystemFile() -{ - type = PakSystemFileType_Unknown; - file = NULL; - zip = NULL; - fileEntry = NULL; - data = NULL; - dataPosition = 0; -} - -PakSystem::PakSystem() -{ -} - -PakSystemFile* PakSystem::Open(const char* a_path, const char* a_mode) -{ - string normalPath = a_path; - - string const zipExt = ".zip"; - bool bZip = StringHelpers::EndsWithIgnoreCase(normalPath, zipExt); - - if (bZip) - { - // If it's a .zip file, then we'll try to look for a file without .zip extension inside of the .zip file - normalPath.erase(normalPath.length() - zipExt.length(), zipExt.length()); - } - - string zipPath = normalPath + zipExt; - string filename = PathHelpers::GetFilename(normalPath); - - if (!normalPath.empty() && normalPath[0] == '@') - { - // File is inside pak file. - int splitter = normalPath.find_first_of("|;,"); - if (splitter >= 0) - { - zipPath = normalPath.substr(1, splitter - 1); - filename = StringHelpers::MakeLowerCase(normalPath.substr(splitter + 1)); - bZip = true; - } - else - { - return 0; - } - } - - if (!bZip) - { - // Try to open the file. - FILE* f = nullptr; - azfopen(&f, normalPath.c_str(), a_mode); - if (f) - { - std::unique_ptr file(new PakSystemFile()); - file->type = PakSystemFileType_File; - file->file = f; - - return file.release(); - } - } - - // if it's simple and read-only, it's assumed it's read-only - unsigned const nFactoryFlags = ZipDir::CacheFactory::FLAGS_DONT_COMPACT | ZipDir::CacheFactory::FLAGS_READ_ONLY; - - bool bFileExists = false; - const uint32* decryptionKey = 0; // use default one - - if (bZip) - { - // a caller asked to open a .zip file. check if the .zip file on disk exist - FILE* f = nullptr; - azfopen(&f, zipPath.c_str(), "rb"); - if (f) - { - fclose(f); - bFileExists = true; - } - } - else - { - // a caller specified normal file. we already failed to find it on disk, - // so the file could be within a .pak file. let's find all 'potential' - // pak files and look within these for a matching file - - std::vector foundFileCountainer; // pak files found - - for (string dirToSearch = normalPath;; ) - { - dirToSearch = PathHelpers::GetDirectory(dirToSearch); - - AZ::IO::LocalFileIO localFileIO; - localFileIO.FindFiles(dirToSearch.c_str(), "*.pak", [&](const char* filePath) -> bool - { - const string foundFilename(filePath); - if (StringHelpers::EqualsIgnoreCase(PathHelpers::FindExtension(foundFilename), "pak")) - { - foundFileCountainer.push_back(foundFilename); - } - return true; // continue iterating - }); - - if (PathHelpers::GetFilename(dirToSearch).empty()) - { - // We've reached the top of the path - break; - } - } - - // iterate through found containers and look for relevant files within them - for (int iFile = 0; iFile < foundFileCountainer.size(); ++iFile) - { - zipPath = foundFileCountainer[ iFile ]; - string pathToZip = PathHelpers::GetDirectory(zipPath); - - // construct filename by removing path to zip from path to filename - string pathToFile = PathHelpers::GetDirectory(string(normalPath)); - string pureFileName = PathHelpers::GetFilename(string(normalPath)); - if (pathToFile.length() != pathToZip.length() && pathToZip.length() > 0) - { - pathToFile = pathToFile.substr(pathToZip.length() + 1); - } - filename = pathToFile.empty() - ? pureFileName - : pathToFile + "\\" + pureFileName; - - ZipDir::CacheFactory factory(ZipDir::ZD_INIT_FAST, nFactoryFlags); - ZipDir::CachePtr testZip = factory.New(zipPath.c_str(), decryptionKey); - ZipDir::FileEntry* testFileEntry = (testZip ? testZip->FindFile(filename.c_str()) : 0); - - // break out if we have a testFileEntry, as we've found our first (and best) candidate. - if (testFileEntry) - { - bFileExists = true; - break; - } - } - } - - { - ZipDir::CacheFactory factory(ZipDir::ZD_INIT_FAST, nFactoryFlags); - ZipDir::CachePtr zip = (bFileExists ? factory.New(zipPath.c_str(), decryptionKey) : 0); - ZipDir::FileEntry* fileEntry = (zip ? zip->FindFile(filename.c_str()) : 0); - - if (fileEntry) - { - std::unique_ptr file(new PakSystemFile()); - file->type = PakSystemFileType_PakFile; - file->zip = zip; - file->fileEntry = fileEntry; - file->data = zip->AllocAndReadFile(file->fileEntry); - file->dataPosition = 0; - return file.release(); - } - } - - return 0; -} - - -//Extracts archived file to disk without overwriting any files -//returns true on success, false on failure (due to potential overwrite or no file -//in archive -bool PakSystem::ExtractNoOverwrite(const char* fileToExtract, const char* extractToFile) -{ - if (0 == extractToFile) - { - extractToFile = fileToExtract; - } - - //open file using pak system - PakSystemFile* fileZip = Open(fileToExtract, "r"); - if (!fileZip) - { - return false; - } - - // Try to open a writable file - FILE* fFileOnDisk = nullptr; - azfopen(&fFileOnDisk, extractToFile, "wb"); - if (!fFileOnDisk) - { - Close(fileZip); - return false; - } - - fwrite(fileZip->data, fileZip->fileEntry->desc.lSizeUncompressed, 1, fFileOnDisk); - fclose(fFileOnDisk); - - Close(fileZip); - - return true; -} - - -void PakSystem::Close(PakSystemFile* file) -{ - if (file) - { - switch (file->type) - { - case PakSystemFileType_File: - fclose(file->file); - break; - - case PakSystemFileType_PakFile: - file->zip->Free(file->data); - break; - } - delete file; - } -} - - -int PakSystem::GetLength(PakSystemFile* file) const -{ - if (file) - { - switch (file->type) - { - case PakSystemFileType_File: - { - if (file->file) - { - long pos = ftell(file->file); - fseek(file->file, 0, SEEK_END); - int result = ftell(file->file); - fseek(file->file, pos, SEEK_SET); - return result; - } - break; - } - case PakSystemFileType_PakFile: - { - if (file->fileEntry) - { - return file->fileEntry->desc.lSizeUncompressed; - } - break; - } - default: - { - break; - } - } - } - return 0; -} - - -int PakSystem::Read(PakSystemFile* file, void* buffer, int size) -{ - int readBytes = 0; - - if (file) - { - switch (file->type) - { - case PakSystemFileType_File: - { - readBytes = fread(buffer, 1, size, file->file); - } - break; - - case PakSystemFileType_PakFile: - { - int fileSize = file->fileEntry->desc.lSizeUncompressed; - readBytes = (fileSize - file->dataPosition > size ? size : fileSize - file->dataPosition); - memcpy(buffer, static_cast(file->data) + file->dataPosition, readBytes); - file->dataPosition += readBytes; - } - break; - } - } - - return readBytes; -} - -bool PakSystem::EoF(PakSystemFile* file) -{ - bool EoF = true; - if (file) - { - switch (file->type) - { - case PakSystemFileType_File: - { - EoF = (0 != feof(file->file)); - } - break; - - case PakSystemFileType_PakFile: - { - int fileSize = file->fileEntry->desc.lSizeUncompressed; - EoF = (file->dataPosition >= fileSize); - } - break; - } - } - - return EoF; -} - -PakSystemArchive* PakSystem::OpenArchive(const char* path, size_t fileAlignment, bool encrypted, const uint32 encryptionKey[4]) -{ - //unsigned nFactoryFlags = ZipDir::CacheFactory::FLAGS_DONT_COMPACT | ZipDir::CacheFactory::FLAGS_CREATE_NEW; - unsigned nFactoryFlags = 0; - ZipDir::CacheFactory factory(ZipDir::ZD_INIT_FAST, nFactoryFlags); - ZipDir::CacheRWPtr cache = factory.NewRW(path, fileAlignment, encrypted, encryptionKey); - PakSystemArchive* archive = (cache ? new PakSystemArchive() : 0); - if (archive) - { - archive->zip = cache; - } - return archive; -} - -void PakSystem::CloseArchive(PakSystemArchive* archive) -{ - if (archive) - { - archive->zip->Close(); - delete archive; - } -} - -void PakSystem::AddToArchive(PakSystemArchive* archive, const char* path, void* data, int size, int64 modTime, int compressionLevel) -{ - int compressionMethod = ZipFile::METHOD_DEFLATE; - if (compressionLevel == 0) - { - compressionMethod = ZipFile::METHOD_STORE; - } - archive->zip->UpdateFile(path, data, size, compressionMethod, compressionLevel, modTime); -} - -////////////////////////////////////////////////////////////////////////// -bool PakSystem::CheckIfFileExist(PakSystemArchive* archive, const char* path, int64 modTime) -{ - assert(archive); - - ZipDir::FileEntry* pFileEntry = archive->zip->FindFile(path); - if (pFileEntry) - { - return pFileEntry->CompareFileTimeNTFS(modTime); - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool PakSystem::DeleteFromArchive(PakSystemArchive* archive, const char* path) -{ - ZipDir::ErrorEnum err = archive->zip->RemoveFile(path); - return ZipDir::ZD_ERROR_SUCCESS == err; -} diff --git a/Code/Tools/CryCommonTools/PakSystem.h b/Code/Tools/CryCommonTools/PakSystem.h deleted file mode 100644 index ba57f26d4d..0000000000 --- a/Code/Tools/CryCommonTools/PakSystem.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_PAKSYSTEM_H -#define CRYINCLUDE_CRYCOMMONTOOLS_PAKSYSTEM_H -#pragma once - - -#include "IPakSystem.h" -#include "ZipDir/ZipDir.h" // TODO: get rid of thid include - -enum PakSystemFileType -{ - PakSystemFileType_Unknown, - PakSystemFileType_File, - PakSystemFileType_PakFile -}; -struct PakSystemFile -{ - PakSystemFile(); - PakSystemFileType type; - - // PakSystemFileType_File - FILE* file; - - // PakSystemFileType_PakFile - ZipDir::CachePtr zip; - ZipDir::FileEntry* fileEntry; - void* data; - int dataPosition; -}; - -struct PakSystemArchive -{ - ZipDir::CacheRWPtr zip; -}; - -class PakSystem - : public IPakSystem -{ -public: - PakSystem(); - - // IPakSystem - virtual PakSystemFile* Open(const char* filename, const char* mode); - virtual bool ExtractNoOverwrite(const char* filename, const char* extractToFile = 0); - virtual void Close(PakSystemFile* file); - virtual int GetLength(PakSystemFile* file) const; - virtual int Read(PakSystemFile* file, void* buffer, int size); - virtual bool EoF(PakSystemFile* file); - - virtual PakSystemArchive* OpenArchive(const char* path, size_t fileAlignment, bool encrypted, const uint32 encryptionKey[4]); - virtual void CloseArchive(PakSystemArchive* archive); - virtual void AddToArchive(PakSystemArchive* archive, const char* path, void* data, int size, int64 modTime, int compressionLevel); - virtual bool DeleteFromArchive(PakSystemArchive* archive, const char* path); - virtual bool CheckIfFileExist(PakSystemArchive* archive, const char* path, int64 modTime); -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_PAKSYSTEM_H diff --git a/Code/Tools/CryCommonTools/PakXmlFileBufferSource.h b/Code/Tools/CryCommonTools/PakXmlFileBufferSource.h deleted file mode 100644 index cd9aa9d211..0000000000 --- a/Code/Tools/CryCommonTools/PakXmlFileBufferSource.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_PAKXMLFILEBUFFERSOURCE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_PAKXMLFILEBUFFERSOURCE_H -#pragma once - - -#include "../CryXML/IXMLSerializer.h" -#include "IPakSystem.h" - -class PakXmlFileBufferSource - : public IXmlBufferSource -{ -public: - PakXmlFileBufferSource(IPakSystem* pakSystem, const char* path) - : pakSystem(pakSystem) - { - file = pakSystem->Open(path, "r"); - } - ~PakXmlFileBufferSource() - { - if (file) - { - pakSystem->Close(file); - } - } - - virtual int Read(void* buffer, int size) const - { - return pakSystem->Read(file, buffer, size); - }; - - IPakSystem* pakSystem; - PakSystemFile* file; -}; - -class PakXmlBufferSource - : public IXmlBufferSource -{ -public: - PakXmlBufferSource(const char* buffer, size_t length) - : position(buffer) - , end(buffer + length) - { - } - - virtual int Read(void* output, int size) const - { - size_t bytesLeft = end - position; - size_t bytesToCopy = size < bytesLeft ? size : bytesLeft; - if (bytesToCopy > 0) - { - memcpy(output, position, bytesToCopy); - position += bytesToCopy; - } - return bytesToCopy; - }; - - mutable const char* position; - const char* end; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_PAKXMLFILEBUFFERSOURCE_H diff --git a/Code/Tools/CryCommonTools/PathHelpers.cpp b/Code/Tools/CryCommonTools/PathHelpers.cpp deleted file mode 100644 index 4abd28183e..0000000000 --- a/Code/Tools/CryCommonTools/PathHelpers.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "PathHelpers.h" -#include "StringHelpers.h" -#include "Util.h" - -#include -#include -#include -#include -#include - - -// Returns position of last extension in last name (string::npos if not found) -// note: returns string::npos for names starting from '.' and having no -// '.' later (for example 'aaa/.ccc', 'a:.abc', '.rc') -template -static inline size_t findExtensionPosition_Tpl(const TS& path) -{ - const size_t dotPos = path.rfind('.'); - if (dotPos == TS::npos) - { - return TS::npos; - } - - static const typename TS::value_type separators[] = { '\\', '/', ':', 0 }; - const size_t separatorPos = path.find_last_of(separators); - if (separatorPos != TS::npos) - { - if (separatorPos + 1 >= dotPos) - { - return TS::npos; - } - } - else if (dotPos == 0) - { - return TS::npos; - } - - return dotPos + 1; -} - -static size_t findExtensionPosition(const string& path) -{ - return findExtensionPosition_Tpl(path); -} - -static size_t findExtensionPosition(const wstring& path) -{ - return findExtensionPosition_Tpl(path); -} - - -string PathHelpers::FindExtension(const string& path) -{ - const size_t extPos = findExtensionPosition(path); - return (extPos == string::npos) ? string() : path.substr(extPos, string::npos); -} - -wstring PathHelpers::FindExtension(const wstring& path) -{ - const size_t extPos = findExtensionPosition(path); - return (extPos == wstring::npos) ? wstring() : path.substr(extPos, wstring::npos); -} - - -template -static inline TS ReplaceExtension_Tpl(const TS& path, const TS& newExtension) -{ - if (path.empty()) - { - return TS(); - } - - if (newExtension.empty()) - { - return PathHelpers::RemoveExtension(path); - } - - const typename TS::value_type last = path[path.length() - 1]; - if ((last == '\\') || (last == '/') || (last == ':') || (last == '.')) - { - return path; - } - - const size_t extPos = findExtensionPosition(path); - static const typename TS::value_type dot[] = { '.', 0 }; - return ((extPos == TS::npos) ? path + dot : path.substr(0, extPos)) + newExtension; -} - -string PathHelpers::ReplaceExtension(const string& path, const string& newExtension) -{ - return ReplaceExtension_Tpl(path, newExtension); -} - -wstring PathHelpers::ReplaceExtension(const wstring& path, const wstring& newExtension) -{ - return ReplaceExtension_Tpl(path, newExtension); -} - - -string PathHelpers::RemoveExtension(const string& path) -{ - const size_t extPos = findExtensionPosition(path); - return (extPos == string::npos) ? path : path.substr(0, extPos - 1); -} - -wstring PathHelpers::RemoveExtension(const wstring& path) -{ - const size_t extPos = findExtensionPosition(path); - return (extPos == wstring::npos) ? path : path.substr(0, extPos - 1); -} - - -template -static inline TS GetDirectory_Tpl(const TS& path) -{ - static const typename TS::value_type separators[] = { '/', '\\', ':', 0 }; - const size_t pos = path.find_last_of(separators); - - if (pos == TS::npos) - { - return TS(); - } - - if (path[pos] == ':' || pos == 0 || path[pos - 1] == ':') - { - return path.substr(0, pos + 1); - } - - // Handle paths like "\\machine" - if (pos == 1 && (path[0] == '/' || path[0] == '\\')) - { - return path; - } - - return path.substr(0, pos); -} - -string PathHelpers::GetDirectory(const string& path) -{ - return GetDirectory_Tpl(path); -} - -wstring PathHelpers::GetDirectory(const wstring& path) -{ - return GetDirectory_Tpl(path); -} - - -template -static inline TS GetFilename_Tpl(const TS& path) -{ - static const typename TS::value_type separators[] = { '/', '\\', ':', 0 }; - const size_t pos = path.find_last_of(separators); - - if (pos == TS::npos) - { - return path; - } - - // Handle paths like "\\machine" - if (pos == 1 && (path[0] == '/' || path[0] == '\\')) - { - return TS(); - } - - return path.substr(pos + 1, TS::npos); -} - -string PathHelpers::GetFilename(const string& path) -{ - return GetFilename_Tpl(path); -} - -wstring PathHelpers::GetFilename(const wstring& path) -{ - return GetFilename_Tpl(path); -} - - -template -static inline TS AddSeparator_Tpl(const TS& path) -{ - if (path.empty()) - { - return TS(); - } - const typename TS::value_type last = path[path.length() - 1]; - if (last == '/' || last == '\\' || last == ':') - { - return path; - } -#if defined(AZ_PLATFORM_WINDOWS) - static const typename TS::value_type separator[] = { '\\', 0 }; -#else - static const typename TS::value_type separator[] = { '/', 0 }; -#endif - return path + separator; -} - -string PathHelpers::AddSeparator(const string& path) -{ - return AddSeparator_Tpl(path); -} - -wstring PathHelpers::AddSeparator(const wstring& path) -{ - return AddSeparator_Tpl(path); -} - - -template -static inline TS RemoveSeparator_Tpl(const TS& path) -{ - if (path.empty()) - { - return TS(); - } - const typename TS::value_type last = path[path.length() - 1]; - if ((last == '/' || last == '\\') && path.length() > 1 && path[path.length() - 2] != ':') - { - return path.substr(0, path.length() - 1); - } - return path; -} - -string PathHelpers::RemoveSeparator(const string& path) -{ - return RemoveSeparator_Tpl(path); -} - -wstring PathHelpers::RemoveSeparator(const wstring& path) -{ - return RemoveSeparator_Tpl(path); -} - - -template -static inline TS RemoveDuplicateSeparators_Tpl(const TS& path) -{ - if (path.length() <= 1) - { - return path; - } - - TS ret; - ret.reserve(path.length()); - - const typename TS::value_type* p = path.c_str(); - - // We start from the second char just to avoid damaging UNC paths with double backslash at the beginning (e.g. "\\Server04\file.txt") - ret += *p++; - - while (*p) - { - ret += *p++; - if (p[-1] == '\\' || p[-1] == '/') - { - while (*p == '\\' || *p == '/') - { - ++p; - } - } - } - - return ret; -} - -string PathHelpers::RemoveDuplicateSeparators(const string& path) -{ - return RemoveDuplicateSeparators_Tpl(path); -} - -wstring PathHelpers::RemoveDuplicateSeparators(const wstring& path) -{ - return RemoveDuplicateSeparators_Tpl(path); -} - - -template -static inline TS Join_Tpl(const TS& path1, const TS& path2) -{ - if (path1.empty()) - { - return path2; - } - if (path2.empty()) - { - return path1; - } - - if (!PathHelpers::IsRelative(path2)) - { - assert(0 && "Join(): path2 is not relative"); - return TS(); - } - - const typename TS::value_type last = path1[path1.length() - 1]; - if (last == '/' || last == '\\' || last == ':') - { - return path1 + path2; - } -#if defined(AZ_PLATFORM_WINDOWS) - static const typename TS::value_type separator[] = { '\\', 0 }; -#else - static const typename TS::value_type separator[] = { '/', 0 }; -#endif - return path1 + separator + path2; -} - - -string PathHelpers::Join(const string& path1, const string& path2) -{ - return Join_Tpl(path1, path2); -} - -wstring PathHelpers::Join(const wstring& path1, const wstring& path2) -{ - return Join_Tpl(path1, path2); -} - - -template -static inline bool IsRelative_Tpl(const TS& path) -{ - if (path.empty()) - { - return true; - } - return path[0] != '/' && path[0] != '\\' && path.find(':') == TS::npos; -} - -bool PathHelpers::IsRelative(const string& path) -{ - return IsRelative_Tpl(path); -} - -bool PathHelpers::IsRelative(const wstring& path) -{ - return IsRelative_Tpl(path); -} - - -string PathHelpers::ToUnixPath(const string& path) -{ - return StringHelpers::Replace(path, '\\', '/'); -} - -wstring PathHelpers::ToUnixPath(const wstring& path) -{ - wstring s(path); - std::replace(s.begin(), s.end(), L'\\', L'/'); - return s; -} - - -string PathHelpers::ToDosPath(const string& path) -{ - return StringHelpers::Replace(path, '/', '\\'); -} - -wstring PathHelpers::ToDosPath(const wstring& path) -{ - wstring s(path); - std::replace(s.begin(), s.end(), L'/', L'\\'); - return s; -} - -string PathHelpers::ToPlatformPath(const string& path) -{ -#if defined(AZ_PLATFORM_WINDOWS) - return ToDosPath(path); -#else - return ToUnixPath(path); -#endif -} - -wstring PathHelpers::ToPlatformPath(const wstring& path) -{ -#if defined(AZ_PLATFORM_WINDOWS) - return ToDosPath(path); -#else - return ToUnixPath(path); -#endif -} - - -string PathHelpers::GetAsciiPath(const char* pPath) -{ - AZStd::wstring wstr; - AZStd::to_wstring(wstr, pPath); - return GetAsciiPath(wstr.c_str()); -} - -string PathHelpers::GetAsciiPath(const wchar_t* pPath) -{ - if (!pPath[0]) - { - return string(); - } - - wstring w = ToPlatformPath(RemoveSeparator(wstring(pPath))); - - if (StringHelpers::Utf16ContainsAsciiOnly(w.c_str())) - { - return StringHelpers::ConvertAsciiUtf16ToAscii(w.c_str()); - } - - // The path is non-ASCII, so let's resort to using short - // filenames where needed (short names are always ASCII-only) - - // Long names components - std::vector p0; - StringHelpers::Split(w, wstring(L"\\"), true, p0); - - // find last component that is not in ASCII char set - int lastNonAscii; - for (lastNonAscii = (int)p0.size() - 1; lastNonAscii >= 0; --lastNonAscii) - { - if (!StringHelpers::Utf16ContainsAsciiOnly(p0[lastNonAscii].c_str())) - { - break; - } - } - assert(lastNonAscii >= 0); - - string res; - res.reserve(w.length()); - - w.clear(); - for (int i = 0; i <= lastNonAscii; ++i) - { - w.append(p0[i]); - if (i < lastNonAscii) - { - w.push_back('\\'); - } - } - - enum - { - kBufferLen = AZ_MAX_PATH_LEN - }; - wchar_t bufferWchars[kBufferLen]; - -#if defined(AZ_PLATFORM_WINDOWS) - const int charCount = GetShortPathNameW(w.c_str(), bufferWchars, kBufferLen); -#else - const int charCount = w.length(); - wcsncpy(bufferWchars, w.c_str(), kBufferLen); -#endif - if (charCount <= 0 || charCount >= kBufferLen) - { - return string(); - } -#if defined(AZ_PLATFORM_WINDOWS) - // Paranoid - if (!StringHelpers::Utf16ContainsAsciiOnly(bufferWchars)) - { - assert(0); - return string(); - } -#endif - - // Short names components - std::vector p1; - StringHelpers::Split(wstring(bufferWchars), wstring(L"\\"), true, p1); - - for (size_t i = 0; i < (int)p0.size(); ++i) - { - if (!p0[i].empty()) - { - const wstring& p = - (i > lastNonAscii || StringHelpers::Utf16ContainsAsciiOnly(p0[i].c_str())) - ? p0[i] - : p1[i]; - res.append(StringHelpers::ConvertAsciiUtf16ToAscii(p.c_str())); - } - if (i + 1 < (int)p0.size()) - { - res.push_back('\\'); - } - } - - return res; -} - - -string PathHelpers::GetAbsoluteAsciiPath(const char* pPath) -{ - char fullPath[AZ_MAX_PATH_LEN]; - AZ::IO::LocalFileIO localFileIO; - - AZStd::string normalizedPath(pPath); - AzFramework::StringFunc::Path::Normalize(normalizedPath); - - localFileIO.ConvertToAbsolutePath(normalizedPath.c_str(), fullPath, AZ_MAX_PATH_LEN); - fullPath[sizeof(fullPath) - 1] = '\0'; - - AZStd::wstring wstr; - AZStd::to_wstring(wstr, fullPath); - return GetAsciiPath(wstr.c_str()); -} - -string PathHelpers::GetAbsoluteAsciiPath(const wchar_t* pPath) -{ - AZStd::string str; - AZStd::to_string(str, pPath); - - AzFramework::StringFunc::Path::Normalize(str); - - char fullPath[AZ_MAX_PATH_LEN]; - AZ::IO::LocalFileIO localFileIO; - localFileIO.ConvertToAbsolutePath(str.c_str(), fullPath, AZ_MAX_PATH_LEN); - fullPath[sizeof(fullPath) - 1] = '\0'; - - AZStd::wstring wstr; - AZStd::to_wstring(wstr, fullPath); - return GetAsciiPath(wstr.c_str()); -} - - -string PathHelpers::GetShortestRelativeAsciiPath(const string& baseFolder, const string& dependentPath) -{ - const string d = GetAbsoluteAsciiPath(dependentPath.c_str()); - if (d.empty()) - { - return PathHelpers::CanonicalizePath(dependentPath); - } - - const string b = GetAbsoluteAsciiPath(baseFolder.c_str()); - if (b.empty()) - { - return PathHelpers::CanonicalizePath(dependentPath); - } - - const string b2 = AddSeparator(b); - if (StringHelpers::StartsWithIgnoreCase(d, b2)) - { - const size_t len = d.length() - b2.length(); - // note: len == 0 is possible in case of "C:\" and "C:\". - return (len == 0) ? string(".") : d.substr(b2.length(), len); - } - - std::vector p0; - StringHelpers::Split(b2, string("\\"), true, p0); - std::vector p1; - StringHelpers::Split(d, string("\\"), true, p1); - - if (!StringHelpers::EqualsIgnoreCase(p0[0], p1[0])) - { - // got different drive letters - return PathHelpers::CanonicalizePath(dependentPath); - } - - if (StringHelpers::EqualsIgnoreCase(d, b)) - { - // exactly same path - return string("."); - } - - // Search for first non-matching component - for (int i = 1; i < (int)p0.size(); ++i) - { - if (StringHelpers::EqualsIgnoreCase(p0[i], p1[i])) - { - continue; - } - - string s; - s.reserve(Util::getMax(d.length(), b.length())); - for (int j = i; j < (int)p0.size(); ++j) - { - if (!p0[j].empty()) - { - s.append("..\\"); - } - } - for (int j = i; j < (int)p1.size(); ++j) - { - s.append(p1[j]); - if (j + 1 < (int)p1.size()) - { - s.push_back('\\'); - } - } - return s; - } - - assert(0); - return string(); -} - - -string PathHelpers::CanonicalizePath(const string& path) -{ - string result = RemoveSeparator(path); - // remove .\ or ./ at the path beginning. - if (result.length() > 2) - { - if (result[0] == '.' && (result[1] == '\\' || result[1] == '/')) - { - result = result.substr(2); - } - } - - return result; -} diff --git a/Code/Tools/CryCommonTools/PathHelpers.h b/Code/Tools/CryCommonTools/PathHelpers.h deleted file mode 100644 index 4cf509d876..0000000000 --- a/Code/Tools/CryCommonTools/PathHelpers.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_PATHHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_PATHHELPERS_H -#pragma once - -#include - -namespace PathHelpers -{ - // checks to see what the extension is in a string path - // returns the extension if found or an empty string if not found - string FindExtension(const string& path); - wstring FindExtension(const wstring& path); - - // replace an extension of a string path with a new specified extension - // returns a string with the replaced extension or the original string if unable to replace the extension - string ReplaceExtension(const string& path, const string& newExtension); - wstring ReplaceExtension(const wstring& path, const wstring& newExtension); - - // removes the extension of a specified string path - // returns a string with the extension removed or the original string if no extension was found - string RemoveExtension(const string& path); - wstring RemoveExtension(const wstring& path); - - // "abc/def/ghi" -> "abc/def" - // "abc/def/ghi/" -> "abc/def/ghi" - // "/" -> "/" - // gets the directory path out of a specified string path - // returns a string of the directory path - string GetDirectory(const string& path); - wstring GetDirectory(const wstring& path); - - // gets the file name out of a specified string path - // returns a string of the file name - string GetFilename(const string& path); - wstring GetFilename(const wstring& path); - - // add a backslash to a specified path if it doesn't already have a separator - // returns a path with the appended backslash unless there was already a separator - string AddSeparator(const string& path); - wstring AddSeparator(const wstring& path); - - // removes a forward slash or backslash from the end of a specified string path if found - // returns a string with the separator removed - string RemoveSeparator(const string& path); - wstring RemoveSeparator(const wstring& path); - - // removes extra forward slashes and backslashes if they're contained within the string path - // returns a string with the extra forward slashes and backslashes removed - string RemoveDuplicateSeparators(const string& path); - wstring RemoveDuplicateSeparators(const wstring& path); - - // It's not allowed to pass an absolute path in path2. - // Join(GetDirectory(fname), GetFilename(fname)) returns fname. - // merges two string paths together into one - // returns the merged string paths - string Join(const string& path1, const string& path2); - wstring Join(const wstring& path1, const wstring& path2); - - // checks to see if the path is a relative path - // returns true if it is or false if it is not - bool IsRelative(const string& path); - bool IsRelative(const wstring& path); - - // converts a string path to a unix path format - // returns the path in unix format - string ToUnixPath(const string& path); - wstring ToUnixPath(const wstring& path); - - // converts a string path to a dos path format - // returns the path in dos format - string ToDosPath(const string& path); - wstring ToDosPath(const wstring& path); - - // converts a string to the platform's path format. - // returns the path in the platform's path format. - string ToPlatformPath(const string& path); - wstring ToPlatformPath(const wstring& path); - - // char* pPath: in ASCII or UTF-8 encoding - // wchar_t* pPath: in UTF-16 encoding - // Non-ASCII components of pPath (everything from &pPath[0] to last non-ASCII - // part, inclusively) should exist on disk, otherwise an empty string is returned. - string GetAsciiPath(const char* pPath); - string GetAsciiPath(const wchar_t* pPath); - - // pPath passed should be in ASCII or UTF-8 encoding - string GetAbsoluteAsciiPath(const char* pPath); - // pPath passed should be in UTF-16 encoding - string GetAbsoluteAsciiPath(const wchar_t* pPath); - - // baseFolder and dependentPath passed should be in ASCII or UTF-8 encoding - string GetShortestRelativeAsciiPath(const string& baseFolder, const string& dependentPath); - - string CanonicalizePath(const string& path); -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_PATHHELPERS_H diff --git a/Code/Tools/CryCommonTools/Platform/Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h b/Code/Tools/CryCommonTools/Platform/Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h deleted file mode 100644 index 03a0b4ff38..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h +++ /dev/null @@ -1,15 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_CRYCOMMONTOOLS_FSEEK(file, offset, s) fseek(file, offset, s) -#define AZ_TRAIT_CRYCOMMONTOOLS_FTELL(file) ftell(file) diff --git a/Code/Tools/CryCommonTools/Platform/Linux/ZipDir/ZipDir_Traits_Linux.h b/Code/Tools/CryCommonTools/Platform/Linux/ZipDir/ZipDir_Traits_Linux.h deleted file mode 100644 index 81a38177c2..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Linux/ZipDir/ZipDir_Traits_Linux.h +++ /dev/null @@ -1,16 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include <../Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h> - -#define AZ_TRAIT_CRYCOMMONTOOLS_PACK_1 0 diff --git a/Code/Tools/CryCommonTools/Platform/Linux/ZipDir/ZipDir_Traits_Platform.h b/Code/Tools/CryCommonTools/Platform/Linux/ZipDir/ZipDir_Traits_Platform.h deleted file mode 100644 index 6232c6462b..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Linux/ZipDir/ZipDir_Traits_Platform.h +++ /dev/null @@ -1,15 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include <../Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h> -#include diff --git a/Code/Tools/CryCommonTools/Platform/Linux/platform_linux_files.cmake b/Code/Tools/CryCommonTools/Platform/Linux/platform_linux_files.cmake deleted file mode 100644 index 9c71b39bf1..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Linux/platform_linux_files.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ZipDir/ZipDir_Traits_Platform.h - ZipDir/ZipDir_Traits_Linux.h - ../Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h -) diff --git a/Code/Tools/CryCommonTools/Platform/Mac/ZipDir/ZipDir_Traits_Mac.h b/Code/Tools/CryCommonTools/Platform/Mac/ZipDir/ZipDir_Traits_Mac.h deleted file mode 100644 index 111a31dc55..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Mac/ZipDir/ZipDir_Traits_Mac.h +++ /dev/null @@ -1,16 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include <../Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h> - -#define AZ_TRAIT_CRYCOMMONTOOLS_PACK_1 1 diff --git a/Code/Tools/CryCommonTools/Platform/Mac/ZipDir/ZipDir_Traits_Platform.h b/Code/Tools/CryCommonTools/Platform/Mac/ZipDir/ZipDir_Traits_Platform.h deleted file mode 100644 index e601614c59..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Mac/ZipDir/ZipDir_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Code/Tools/CryCommonTools/Platform/Mac/platform_mac_files.cmake b/Code/Tools/CryCommonTools/Platform/Mac/platform_mac_files.cmake deleted file mode 100644 index b1fb3fa9a1..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Mac/platform_mac_files.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ZipDir/ZipDir_Traits_Platform.h - ZipDir/ZipDir_Traits_Mac.h - ../Common/UnixLike/ZipDir/ZipDir_Traits_UnixLike.h -) diff --git a/Code/Tools/CryCommonTools/Platform/Windows/ZipDir/ZipDir_Traits_Platform.h b/Code/Tools/CryCommonTools/Platform/Windows/ZipDir/ZipDir_Traits_Platform.h deleted file mode 100644 index 1d177a5c8c..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Windows/ZipDir/ZipDir_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Code/Tools/CryCommonTools/Platform/Windows/ZipDir/ZipDir_Traits_Windows.h b/Code/Tools/CryCommonTools/Platform/Windows/ZipDir/ZipDir_Traits_Windows.h deleted file mode 100644 index 6d9c5314e4..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Windows/ZipDir/ZipDir_Traits_Windows.h +++ /dev/null @@ -1,16 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_CRYCOMMONTOOLS_FSEEK(file, offset, s) _fseeki64(file, (__int64)offset, s) -#define AZ_TRAIT_CRYCOMMONTOOLS_FTELL(file) (size_t)_ftelli64(file) -#define AZ_TRAIT_CRYCOMMONTOOLS_PACK_1 1 diff --git a/Code/Tools/CryCommonTools/Platform/Windows/platform_windows_files.cmake b/Code/Tools/CryCommonTools/Platform/Windows/platform_windows_files.cmake deleted file mode 100644 index 252842e917..0000000000 --- a/Code/Tools/CryCommonTools/Platform/Windows/platform_windows_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ZipDir/ZipDir_Traits_Platform.h - ZipDir/ZipDir_Traits_Windows.h -) diff --git a/Code/Tools/CryCommonTools/ProgressRange.h b/Code/Tools/CryCommonTools/ProgressRange.h deleted file mode 100644 index 297d862980..0000000000 --- a/Code/Tools/CryCommonTools/ProgressRange.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_PROGRESSRANGE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_PROGRESSRANGE_H -#pragma once - - -class ProgressRange -{ -public: - template - ProgressRange(T* object, void (T::* setter)(float progress)) - : m_target(new MethodTarget(object, setter)) - , m_progress(0.0f) - , m_start(0.0f) - , m_scale(1.0f) - { - m_target->Set(m_start); - } - - ProgressRange(ProgressRange& parent, float scale) - : m_target(new ParentRangeTarget(parent)) - , m_progress(0.0f) - , m_start(parent.m_progress) - , m_scale(scale) - { - m_target->Set(m_start); - } - - ~ProgressRange() - { - m_target->Set(m_start + m_scale); - delete m_target; - } - - void SetProgress(float progress) - { - assert(progress > -0.01f && progress < 1.1f); - m_progress = progress; - m_target->Set(m_start + m_scale * progress); - } - -private: - struct ITarget - { - virtual ~ITarget() {} - virtual void Set(float progress) = 0; - }; - - struct ParentRangeTarget - : public ITarget - { - ParentRangeTarget(ProgressRange& range) - : range(range) {} - virtual void Set(float progress) {range.SetProgress(progress); } - ProgressRange& range; - }; - - template - struct MethodTarget - : public ITarget - { - typedef void (T::* Setter)(float progress); - MethodTarget(T* object, Setter setter) - : object(object) - , setter(setter) {} - virtual void Set(float progress) {(object->*setter)(progress); } - T* object; - Setter setter; - }; - - ITarget* m_target; - float m_progress; - float m_start; - float m_scale; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_PROGRESSRANGE_H diff --git a/Code/Tools/CryCommonTools/PropertyHelpers.cpp b/Code/Tools/CryCommonTools/PropertyHelpers.cpp deleted file mode 100644 index aaaa1df309..0000000000 --- a/Code/Tools/CryCommonTools/PropertyHelpers.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "PropertyHelpers.h" -#include "StringHelpers.h" - - -bool PropertyHelpers::GetPropertyValue(const string& a_propertiesString, const char* a_propertyName, string& a_value) -{ - if ((a_propertyName == 0) || (a_propertyName[0] == 0)) - { - return false; - } - - const char* lineStart = a_propertiesString.c_str(); - - while (*lineStart) - { - string key; - string value; - - const size_t lineEndPosition = strcspn(lineStart, "\n"); - const size_t equalPosition = strcspn(lineStart, "="); - - if (equalPosition < lineEndPosition) - { - key = string(lineStart, equalPosition); - value = string(lineStart + equalPosition + 1, lineEndPosition - equalPosition - 1); - } - else - { - key = string(lineStart, lineEndPosition); - value = ""; - } - - key = StringHelpers::Trim(key); - - if (_stricmp(key.c_str(), a_propertyName) == 0) - { - a_value = StringHelpers::Trim(value); - return true; - } - - lineStart += lineEndPosition; - if (*lineStart) - { - ++lineStart; - } - } - - return false; -} - -void PropertyHelpers::SetPropertyValue(string& a_propertiesString, const char* a_propertyName, const char* a_value) -{ - if ((a_propertyName == 0) || (a_propertyName[0] == 0)) - { - return; - } - - const string newValue = StringHelpers::Trim(string(a_value)); - - const char* lineStart = a_propertiesString.c_str(); - - while (*lineStart) - { - const size_t lineEndPosition = strcspn(lineStart, "\n"); - const size_t equalPosition = strcspn(lineStart, "="); - - const string key = StringHelpers::Trim(string(lineStart, ((equalPosition < lineEndPosition) ? equalPosition : lineEndPosition))); - - if (_stricmp(key.c_str(), a_propertyName) == 0) - { - const size_t prefixSz = lineStart - a_propertiesString.c_str(); - const size_t expressionSz = lineEndPosition; - - if (newValue.empty()) - { - a_propertiesString = a_propertiesString.substr(0, prefixSz) + string(a_propertyName) + a_propertiesString.substr(prefixSz + expressionSz, string::npos); - } - else - { - a_propertiesString = a_propertiesString.substr(0, prefixSz) + string(a_propertyName) + string("=") + newValue + a_propertiesString.substr(prefixSz + expressionSz, string::npos); - } - return; - } - - lineStart += lineEndPosition; - if (*lineStart) - { - ++lineStart; - } - } - - if (a_propertiesString.empty() || (a_propertiesString[a_propertiesString.size() - 1] != '\n')) - { - a_propertiesString += string("\r\n"); - } - - if (newValue.empty()) - { - a_propertiesString += string(a_propertyName); - } - else - { - a_propertiesString += string(a_propertyName) + string("=") + newValue; - } -} - -bool PropertyHelpers::HasProperty(const string& a_propertiesString, const char* a_propertyName) -{ - string value; - return PropertyHelpers::GetPropertyValue(a_propertiesString, a_propertyName, value); -} diff --git a/Code/Tools/CryCommonTools/PropertyHelpers.h b/Code/Tools/CryCommonTools/PropertyHelpers.h deleted file mode 100644 index 0a2f428cc8..0000000000 --- a/Code/Tools/CryCommonTools/PropertyHelpers.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_PROPERTYHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_PROPERTYHELPERS_H -#pragma once - - -namespace PropertyHelpers -{ - bool GetPropertyValue(const string& propertiesString, const char* propertyName, string& value); - void SetPropertyValue(string& a_propertiesString, const char* propertyName, const char* value); - bool HasProperty(const string& propertiesString, const char* propertyName); -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_PROPERTYHELPERS_H - - diff --git a/Code/Tools/CryCommonTools/STLHelpers.cpp b/Code/Tools/CryCommonTools/STLHelpers.cpp deleted file mode 100644 index c1b65f25b2..0000000000 --- a/Code/Tools/CryCommonTools/STLHelpers.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include diff --git a/Code/Tools/CryCommonTools/STLHelpers.h b/Code/Tools/CryCommonTools/STLHelpers.h deleted file mode 100644 index 6fbf0c7d11..0000000000 --- a/Code/Tools/CryCommonTools/STLHelpers.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_STLHELPERS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_STLHELPERS_H -#pragma once - - -#include - -namespace STLHelpers -{ - template - inline const char* constchar_cast(const Type& type) - { - return type; - } - - template <> - inline const char* constchar_cast(const std::string& type) - { - return type.c_str(); - } - - template - struct less_strcmp - { - bool operator()(const Type& left, const Type& right) const - { - return strcmp(constchar_cast(left), constchar_cast(right)) < 0; - } - }; - - template - struct less_stricmp - { - bool operator()(const Type& left, const Type& right) const - { - return _stricmp(constchar_cast(left), constchar_cast(right)) < 0; - } - }; -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_STLHELPERS_H diff --git a/Code/Tools/CryCommonTools/SimpleBitmap.h b/Code/Tools/CryCommonTools/SimpleBitmap.h deleted file mode 100644 index ce4e93c626..0000000000 --- a/Code/Tools/CryCommonTools/SimpleBitmap.h +++ /dev/null @@ -1,508 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_SIMPLEBITMAP_H -#define CRYINCLUDE_CRYCOMMONTOOLS_SIMPLEBITMAP_H - -#include -#include // STL vector -#include "platform.h" // uint32 -#include "Cry_Math.h" // uint32 -#include "Util.h" // getMin() - -enum EImageFilteringMode -{ - eifm2DBorder = 0, - eifmCubemapFilter = 1, -}; - -namespace -{ - enum ECubeFace - { - ecfPosX = 0, - ecfNegX = 1, - ecfPosY = 2, - ecfNegY = 3, - ecfPosZ = 4, - ecfNegZ = 5, - ecfUnknown = -1, - }; - - struct JumpEntry - { - ECubeFace face; - int rot; - }; - - static const JumpEntry XJmpTable[] = - { - {ecfNegZ, 0}, {ecfPosZ, 2}, // ecfPosXa - {ecfPosZ, 0}, {ecfNegZ, 2}, // ecfNegXa - {ecfPosX, 1}, {ecfNegX, 3}, // ecfPosYa - {ecfPosX, 3}, {ecfNegX, 1}, // ecfNegYa - {ecfPosX, 0}, {ecfNegX, 0}, // ecfPosZa - {ecfPosX, 2}, {ecfNegX, 2} // ecfNegZa - }; - - static const JumpEntry YJmpTable[] = - { - {ecfPosY, 3}, {ecfNegY, 1}, // ecfPosXa - {ecfPosY, 1}, {ecfNegY, 3}, // ecfNegXa - {ecfNegZ, 2}, {ecfPosZ, 0}, // ecfPosYa - {ecfPosZ, 0}, {ecfNegZ, 2}, // ecfNegYa - {ecfNegY, 0}, {ecfPosY, 2}, // ecfPosZa - {ecfNegY, 2}, {ecfPosY, 0} // ecfNegZa - }; -} - -//! memory block used as bitmap -//! if you might need mipmaps please consider using ImageObject instead -template -class CSimpleBitmap -{ -public: - - CSimpleBitmap() - : m_dwWidth(0) - , m_dwHeight(0) - { - } - - ~CSimpleBitmap() - { - } - - // copy constructor - CSimpleBitmap(const CSimpleBitmap& rhs) - : m_dwWidth(0) - , m_dwHeight(0) - { - *this = rhs; // call assignment operator - } - - // assignment operator - CSimpleBitmap& operator=(const CSimpleBitmap& rhs) - { - if (&rhs != this) - { - m_data = rhs.m_data; - m_dwWidth = rhs.m_dwWidth; - m_dwHeight = rhs.m_dwHeight; - } - return *this; - } - - //! free all the memory resources - void FreeData() - { - m_data = std::vector(); - m_dwWidth = 0; - m_dwHeight = 0; - } - - //! /return true=success, false=failed because of low memory - bool SetSize(const uint32 indwWidth, const uint32 indwHeight) - { - if (m_dwWidth * m_dwHeight != indwWidth * indwHeight) - { - FreeData(); - m_data.resize(indwWidth * indwHeight); - m_dwWidth = indwWidth; - m_dwHeight = indwHeight; - } - return true; - } - -private: - ECubeFace JumpX(const ECubeFace srcFace, const bool isdXPos, int* rotCoords) const - { - int index = (int)srcFace * 2 + (isdXPos ? 0 : 1); - assert(index < sizeof(XJmpTable)); - const JumpEntry& jmp = XJmpTable[index]; - (*rotCoords) += jmp.rot; - return jmp.face; - } - - ECubeFace JumpY(const ECubeFace srcFace, const bool isdYPos, int* rotCoords) const - { - int index = (int)srcFace * 2 + (isdYPos ? 0 : 1); - assert(index < sizeof(YJmpTable)); - const JumpEntry& jmp = YJmpTable[index]; - (*rotCoords) += jmp.rot; - return jmp.face; - } - - // table that shows to which face we jump - ECubeFace JumpTable(const ECubeFace srcFace, int isdXPos, int isdYPos, int* rotCoords) const - { - if (isdXPos != 0) // recursive jump until dx==0 - { - int newSwap = 0; - ECubeFace newFace = JumpX(srcFace, isdXPos > 0, &newSwap); - (*rotCoords) += newSwap; - isdXPos -= ((isdXPos > 0) ? 1 : -1); - RotateCoord(&isdXPos, &isdYPos, newSwap); - return JumpTable(newFace, isdXPos, isdYPos, rotCoords); - } - if (isdYPos != 0) // recursive jump until dy==0 - { - int newSwap = 0; - ECubeFace newFace = JumpY(srcFace, isdYPos > 0, &newSwap); - (*rotCoords) += newSwap; - isdYPos -= ((isdYPos > 0) ? 1 : -1); - RotateCoord(&isdXPos, &isdYPos, newSwap); - return JumpTable(newFace, isdXPos, isdYPos, rotCoords); - } - assert(isdXPos == 0 && isdYPos == 0); - return srcFace; - } - - void RotateCoord(int* x, int* y, int mode) const - { - if (mode != 0) - { - if (mode == 2) // 180 degrees - { - (*x) = -(*x); - (*y) = -(*y); - } - else - { - if (mode == 1) // 90 dergees - { - int tmp = (*y); - (*y) = (*x); - (*x) = -tmp; - } - else // 270 degrees - { - assert(mode == 3); - int tmp = (*y); - (*y) = -(*x); - (*x) = tmp; - } - } - } - } - -public: - //! works only within the Bitmap for filter kernels - //! /param inX 0..m_dwWidth-1 or the method returns false - //! /param inY 0..m_dwHeight-1 or the method returns false - //! /param outValue - //! /return pointer to the raster element value if position was in the bitmap, NULL otherwise - const RasterElement* GetForFiltering_2D(const int inX, const int inY) const - { - return Get(inX, inY); - } - - //! works only within the Bitmap for filter kernels - //! /param inX 0..m_dwWidth-1 or the method returns false - //! /param inY 0..m_dwHeight-1 or the method returns false - //! /param outValue - //! /return pointer to the raster element value if position was in the bitmap, NULL otherwise - const RasterElement* GetForFiltering_Cubemap(const int inX, const int inY, const int srcX, const int srcY) const - { - if (m_data.empty()) - { - return false; - } - - assert(m_dwWidth == m_dwHeight * 6); - assert(srcX >= 0 && srcX < m_dwWidth); - assert(srcY >= 0 && srcY < m_dwHeight); - - const int sideSize = m_dwHeight; - - ECubeFace srcFace = (ECubeFace)(srcX / sideSize); - - if (inX >= 0 && inX < m_dwWidth && inY >= 0 && inY < m_dwHeight) // if we're inside the cubemap - { - ECubeFace destFace = (ECubeFace)(inX / sideSize); - if (destFace == srcFace) // we have the same face as src texel - { - return &m_data[inY * m_dwWidth + inX]; - } - } - const int halfSideSize = Util::getMax(1, sideSize / 2); - - // ternary logic - const int isdXPositive = int(floorf((float)inX / sideSize) - floorf((float)srcX / sideSize)); - const int isdYPositive = int(floorf((float)inY / sideSize) - floorf((float)srcY / sideSize)); - //if(isdXPositive==0&&isdYPositive<0&&srcFace==ecfPosY) - //{ - // int tmp = 0; - //} - assert(isdXPositive != 0 || isdYPositive != 0); - int rotCoords = 0; // quadrants to rotate coords - ECubeFace destFace = JumpTable(srcFace, isdXPositive, isdYPositive, &rotCoords); - rotCoords = ((rotCoords % 4) + 4) % 4; - int destX = inX - srcFace * sideSize; - int destY = inY; - - // rotate coords - destX -= halfSideSize; // center coords - destY -= halfSideSize; - RotateCoord(&destX, &destY, rotCoords); - destX += halfSideSize; // shift back - destY += halfSideSize; - - destX = ((destX + sideSize) % sideSize + sideSize) % sideSize; // tile in the face - destY = ((destY + sideSize) % sideSize + sideSize) % sideSize; - - destX = Util::getMin(destX, sideSize - 1); - destY = Util::getMin(destY, sideSize - 1); - destX += sideSize * destFace; - - assert(destX < m_dwWidth); - assert((ECubeFace)(destX / sideSize) == destFace); - - return &m_data[destY * m_dwWidth + destX]; - } - - const RasterElement* GetForFiltering(const Vec3& inDir) const - { - Vec3 vcAbsDir(fabsf(inDir.x), fabsf(inDir.y), fabsf(inDir.z)); - ECubeFace face; - int rotQuadrant = 0; - Vec2 texCoord; - if (vcAbsDir.x > vcAbsDir.y && vcAbsDir.x > vcAbsDir.z) - { - if (inDir.x > 0) - { - rotQuadrant = 3; - face = ecfPosX; - } - else - { - rotQuadrant = 1; - face = ecfNegX; - } - texCoord = Vec2(inDir.y, inDir.z) / vcAbsDir.x; - } - else if (vcAbsDir.y > vcAbsDir.x && vcAbsDir.y > vcAbsDir.z) - { - if (inDir.y > 0) - { - rotQuadrant = 2; - face = ecfPosY; - } - else - { - rotQuadrant = 0; - face = ecfNegY; - } - texCoord = Vec2(inDir.x, inDir.z) / vcAbsDir.y; - } - else - { - assert(vcAbsDir.z >= vcAbsDir.x && vcAbsDir.z >= vcAbsDir.y); - if (inDir.z > 0) - { - rotQuadrant = 1; - face = ecfPosZ; - } - else - { - rotQuadrant = 3; - face = ecfNegZ; - } - texCoord = Vec2(inDir.x, inDir.y) / vcAbsDir.z; - } - - texCoord = texCoord * .5f + Vec2(.5f, .5f); - assert(texCoord.x <= 1.f && texCoord.x >= 0); - assert(texCoord.y <= 1.f && texCoord.y >= 0); - - Vec2i texelPos(texCoord.x * (m_dwHeight - 1), texCoord.y * (m_dwHeight - 1)); - - texelPos.x += face * m_dwHeight; // plus face - return &m_data[texelPos.y * m_dwWidth + texelPos.x]; - } - - //! works only within the Bitmap - //! /param inX 0..m_dwWidth-1 or the method returns false - //! /param inY 0..m_dwHeight-1 or the method returns false - //! /param outValue - //! /return pointer to raster element value if position was in the bitmap, NULL otherwise - const RasterElement* Get(const uint32 inX, const uint32 inY) const - { - if (m_data.empty()) - { - return 0; - } - if (inX >= m_dwWidth || inY >= m_dwHeight) - { - return 0; - } - return &m_data[inY * m_dwWidth + inX]; - } - - - //! bilinear, works only well within 0..1 - bool GetFiltered(const float infX, const float infY, RasterElement& outValue) const - { - float fIX = floorf(infX), fIY = floorf(infY); - float fFX = infX - fIX, fFY = infY - fIY; - int iXa = (int)fIX, iYa = (int)fIY; - int iXb = iXa + 1, iYb = iYa + 1; - - if (iXb == m_dwWidth) - { - iXb = 0; - } - - if (iYb == m_dwHeight) - { - iYb = 0; - } - - const RasterElement* p[4]; - - if ((p[0] = Get(iXa, iYa)) && (p[1] = Get(iXb, iYa)) && (p[2] = Get(iXa, iYb)) && (p[3] = Get(iXb, iYb))) - { - outValue = - (*p[0]) * ((1.0f - fFX) * (1.0f - fFY)) + // left top - (*p[1]) * ((fFX) * (1.0f - fFY)) + // right top - (*p[2]) * ((1.0f - fFX) * (fFY)) + // left bottom - (*p[3]) * ((fFX) * (fFY)); // right bottom - - return true; - } - - return false; - } - - //! works only within the Bitmap - //! /param inX 0..m_dwWidth-1 or the method returns false - //! /param inY 0..m_dwHeight-1 or the method returns false - const RasterElement& GetRef(const uint32 inX, const uint32 inY) const - { - assert(!m_data.empty()); - assert(inX < m_dwWidth && inY < m_dwHeight); - return m_data[inY * m_dwWidth + inX]; - } - - //! works only within the Bitmap - //! /param inX 0..m_dwWidth-1 or the method returns false - //! /param inY 0..m_dwHeight-1 or the method returns false - RasterElement& GetRef(const uint32 inX, const uint32 inY) - { - assert(!m_data.empty()); - assert(inX < m_dwWidth && inY < m_dwHeight); - return m_data[inY * m_dwWidth + inX]; - } - - //! works even outside of the Bitmap (tiled) - //! /param inX 0..m_dwWidth-1 or the method returns false - //! /param inY 0..m_dwHeight-1 or the method returns false - RasterElement& GetTiledRef(const uint32 inX, const uint32 inY) - { - assert(!m_data.empty()); - const uint32 x = inX % m_dwWidth; - const uint32 y = inY % m_dwHeight; - return m_data[y * m_dwWidth + x]; - } - - //! works only within the Bitmap - //! /param inX 0..m_dwWidth-1 or the method returns false - //! /param inY 0..m_dwHeight-1 or the method returns false - //! /param inValue - bool Set(const uint32 inX, const uint32 inY, const RasterElement& inValue) - { - if (m_data.empty()) - { - assert(!m_data.empty()); - return false; - } - - if (inX >= m_dwWidth || inY >= m_dwHeight) - { - return false; - } - - m_data[inY * m_dwWidth + inX] = inValue; - - return true; - } - - uint32 GetWidth() const - { - return m_dwWidth; - } - - uint32 GetHeight() const - { - return m_dwHeight; - } - - // Returns size of one line in bytes - size_t GetPitch() const - { - return m_dwWidth * sizeof(RasterElement); - } - - uint32 GetBitmapSizeInBytes() const - { - return m_dwWidth * m_dwHeight * sizeof(RasterElement); - } - - //! /return could be 0 if the pixel is outside the bitmap - const RasterElement* GetPointer(const uint32 inX = 0, const uint32 inY = 0) const - { - if (inX >= m_dwWidth || inY >= m_dwHeight) - { - return 0; - } - return &m_data[inY * m_dwWidth + inX]; - } - - //! /return could be 0 if the pixel is outside the bitmap - RasterElement* GetPointer(const uint32 inX = 0, const uint32 inY = 0) - { - if (inX >= m_dwWidth || inY >= m_dwHeight) - { - return 0; - } - return &m_data[inY * m_dwWidth + inX]; - } - - void Fill(const RasterElement& inValue) - { - const uint32 n = m_dwHeight * m_dwWidth; - for (uint32 i = 0; i < n; ++i) - { - m_data[i] = inValue; - } - } - - bool IsValid() const - { - return !m_data.empty(); - } - -protected: // ------------------------------------------------------ - - std::vector m_data; //!< [m_dwWidth * m_dwHeight] - - uint32 m_dwWidth; - uint32 m_dwHeight; -}; - - - - - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_SIMPLEBITMAP_H diff --git a/Code/Tools/CryCommonTools/SimpleStringPool.h b/Code/Tools/CryCommonTools/SimpleStringPool.h deleted file mode 100644 index 4e65ce1be6..0000000000 --- a/Code/Tools/CryCommonTools/SimpleStringPool.h +++ /dev/null @@ -1,249 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_SIMPLESTRINGPOOL_H -#define CRYINCLUDE_CRYCOMMONTOOLS_SIMPLESTRINGPOOL_H -#pragma once - -#include - -///////////////////////////////////////////////////////////////////// -// String pool implementation. -// Inspired by expat implementation. -///////////////////////////////////////////////////////////////////// -class CSimpleStringPool -{ -public: - enum - { - STD_BLOCK_SIZE = 4096 - }; - struct BLOCK - { - BLOCK* next; - int size; - char s[1]; - }; - unsigned int m_blockSize; - BLOCK* m_blocks; - BLOCK* m_free_blocks; - const char* m_end; - char* m_ptr; - char* m_start; - int nUsedSpace; - int nUsedBlocks; - - CSimpleStringPool() - { - m_blockSize = STD_BLOCK_SIZE; - m_blocks = 0; - m_start = 0; - m_ptr = 0; - m_end = 0; - nUsedSpace = 0; - nUsedBlocks = 0; - m_free_blocks = 0; - } - ~CSimpleStringPool() - { - BLOCK* pBlock = m_blocks; - while (pBlock) - { - BLOCK* temp = pBlock->next; - //nFree++; - free(pBlock); - pBlock = temp; - } - pBlock = m_free_blocks; - while (pBlock) - { - BLOCK* temp = pBlock->next; - //nFree++; - free(pBlock); - pBlock = temp; - } - m_blocks = 0; - m_ptr = 0; - m_start = 0; - m_end = 0; - } - void SetBlockSize(unsigned int nBlockSize) - { - if (nBlockSize > 1024 * 1024) - { - nBlockSize = 1024 * 1024; - } - unsigned int size = 512; - while (size < nBlockSize) - { - size *= 2; - } - - m_blockSize = size - offsetof(BLOCK, s); - } - void Clear() - { - if (m_free_blocks) - { - BLOCK* pLast = m_blocks; - while (pLast) - { - BLOCK* temp = pLast->next; - if (!temp) - { - break; - } - pLast = temp; - } - if (pLast) - { - pLast->next = m_free_blocks; - } - } - m_free_blocks = m_blocks; - m_blocks = 0; - m_start = 0; - m_ptr = 0; - m_end = 0; - nUsedSpace = 0; - } - char* Append(const char* ptr, int nStrLen) - { - char* ret = m_ptr; - if (m_ptr && nStrLen + 1 < (m_end - m_ptr)) - { - memcpy(m_ptr, ptr, nStrLen); - m_ptr = m_ptr + nStrLen; - *m_ptr++ = 0; // add null termination. - } - else - { - int nNewBlockSize = (std::max)(nStrLen + 1, (int)m_blockSize); - AllocBlock(nNewBlockSize, nStrLen + 1); - memcpy(m_ptr, ptr, nStrLen); - m_ptr = m_ptr + nStrLen; - *m_ptr++ = 0; // add null termination. - ret = m_start; - } - nUsedSpace += nStrLen; - return ret; - } - char* ReplaceString(const char* str1, const char* str2) - { - int nStrLen1 = check_cast(strlen(str1)); - int nStrLen2 = check_cast(strlen(str2)); - - // undo ptr1 add. - if (m_ptr != m_start) - { - m_ptr = m_ptr - nStrLen1 - 1; - } - - assert(m_ptr == str1); - - int nStrLen = nStrLen1 + nStrLen2; - - char* ret = m_ptr; - if (m_ptr && nStrLen + 1 < (m_end - m_ptr)) - { - memcpy(m_ptr, str1, nStrLen1); - memcpy(m_ptr + nStrLen1, str2, nStrLen2); - m_ptr = m_ptr + nStrLen; - *m_ptr++ = 0; // add null termination. - } - else - { - int nNewBlockSize = (std::max)(nStrLen + 1, check_cast(m_blockSize)); - if (m_ptr == m_start) - { - ReallocBlock(nNewBlockSize * 2); // Reallocate current block. - memcpy(m_ptr + nStrLen1, str2, nStrLen2); - } - else - { - AllocBlock(nNewBlockSize, nStrLen + 1); - memcpy(m_ptr, str1, nStrLen1); - memcpy(m_ptr + nStrLen1, str2, nStrLen2); - } - - m_ptr = m_ptr + nStrLen; - *m_ptr++ = 0; // add null termination. - ret = m_start; - } - nUsedSpace += nStrLen; - return ret; - } -private: - void AllocBlock(int blockSize, int nMinBlockSize) - { - if (m_free_blocks) - { - BLOCK* pBlock = m_free_blocks; - BLOCK* pPrev = 0; - while (pBlock) - { - if (pBlock->size >= nMinBlockSize) - { - // Reuse free block - if (pPrev) - { - pPrev->next = pBlock->next; - } - else - { - m_free_blocks = pBlock->next; - } - - pBlock->next = m_blocks; - m_blocks = pBlock; - m_ptr = pBlock->s; - m_start = pBlock->s; - m_end = pBlock->s + pBlock->size; - return; - } - pPrev = pBlock; - pBlock = pBlock->next; - } - } - size_t nMallocSize = offsetof(BLOCK, s) + blockSize * sizeof(char); - //nMallocs++; - BLOCK* pBlock = (BLOCK*)malloc(nMallocSize); - pBlock->size = blockSize; - pBlock->next = m_blocks; - m_blocks = pBlock; - m_ptr = pBlock->s; - m_start = pBlock->s; - m_end = pBlock->s + blockSize; - nUsedBlocks++; - } - void ReallocBlock(int blockSize) - { - BLOCK* pThisBlock = m_blocks; - BLOCK* pPrevBlock = m_blocks->next; - m_blocks = pPrevBlock; - - size_t nMallocSize = offsetof(BLOCK, s) + blockSize * sizeof(char); - - //nMallocs++; - BLOCK* pBlock = (BLOCK*)realloc(pThisBlock, nMallocSize); - pBlock->size = blockSize; - pBlock->next = m_blocks; - m_blocks = pBlock; - m_ptr = pBlock->s; - m_start = pBlock->s; - m_end = pBlock->s + blockSize; - } -}; - - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_SIMPLESTRINGPOOL_H diff --git a/Code/Tools/CryCommonTools/StealingThreadPool.cpp b/Code/Tools/CryCommonTools/StealingThreadPool.cpp deleted file mode 100644 index e4a6f87243..0000000000 --- a/Code/Tools/CryCommonTools/StealingThreadPool.cpp +++ /dev/null @@ -1,580 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "StealingThreadPool.h" -#include "ThreadUtils.h" -#include -#include -#include - -namespace ThreadUtils { - class StealingWorker - { - public: - StealingWorker(StealingThreadPool* pool, int index, bool trace, AZStd::condition_variable& jobsCV) - : m_pool(pool) - , m_index(index) - , m_tracingEnabled(trace) - , m_lastStartTime(0) - , m_exitFlag(0) - , m_jobsCV(jobsCV) - { - } - - static unsigned int __stdcall ThreadFunc(void* param) - { - StealingWorker* self = (StealingWorker*)(param); - self->Work(); - return 0; - } - - void Start(int startTime) - { - m_lastStartTime = startTime; - - string threadName; - threadName.Format("StealingWorker %d", m_index); - - AZStd::thread_desc threadDesc; - threadDesc.m_name = threadName.c_str(); - m_thread = AZStd::thread(AZStd::bind(StealingWorker::ThreadFunc, (void*)this), &threadDesc); - - } - - bool GetJobLockless(Job& job) - { - if (m_jobs.empty()) - { - return false; - } - job = m_jobs.front(); - m_jobs.pop_front(); - - return true; - } - - bool GetJob(Job& job) - { - AZStd::lock_guard lock(m_lockJobs); - return GetJobLockless(job); - } - - void ExecuteJob(Job& job) - { - --m_pool->m_numJobsWaitingForExecution; - job.Run(); - - if (m_tracingEnabled) - { - int time = (int)GetTickCount(); - - JobTrace trace; - trace.m_job = job; - trace.m_duration = time - m_lastStartTime; - m_traces.push_back(trace); - - m_lastStartTime = time; - } - - --m_pool->m_numJobs; - m_pool->m_jobFinishedCV.notify_all(); - } - - bool TryToStealJob(Job& job) - { - while (true) - { - StealingWorker* victim = m_pool->FindBestVictim(m_index); - if (!victim) - { - return false; - } - if (StealJobs(job, victim)) - { - return true; - } - } - } - - void Work() - { - Job job; - - while (true) - { - AZStd::mutex loadMutex; - AZStd::unique_lock loadLock(loadMutex, AZStd::defer_lock_t()); - - while (m_pool->m_numJobsWaitingForExecution == 0) - { - - m_jobsCV.wait(loadLock); - - if (m_exitFlag == 1) - { - return; - } - } - - if (GetJob(job)) - { - ExecuteJob(job); - } - else if (TryToStealJob(job)) - { - ExecuteJob(job); - } - } - } - - // Called from different worker thread - bool StealJobs(Job& job, StealingWorker* victim) - { - if (victim == this) - { - assert(0 && "Trying to steal own jobs"); - return false; - } - - bool order = m_index < victim->m_index; - AZStd::lock_guard lock1(order ? m_lockJobs : victim->m_lockJobs); - AZStd::lock_guard lock2(order ? victim->m_lockJobs : m_lockJobs); - - if (victim->m_jobs.empty()) - { - return false; - } - - int numJobs = (int)victim->m_jobs.size(); - size_t stealUntil = numJobs - numJobs / 2; - Jobs::iterator begin = victim->m_jobs.begin(); - Jobs::iterator end = victim->m_jobs.begin() + stealUntil; - - m_jobs.insert(m_jobs.end(), begin, end); - victim->m_jobs.erase(begin, end); - - return GetJobLockless(job); - } - - // Called from any thread - void Submit(const Job& job) - { - AZStd::lock_guard lock(m_lockJobs); - - m_jobs.push_back(job); - m_jobs.back().m_debugInitialThread = m_index; - - m_jobsCV.notify_one(); - } - - // Called from any thread - void Submit(const Jobs& jobs) - { - const size_t numJobs = jobs.size(); - - AZStd::lock_guard lock(m_lockJobs); - - m_jobs.insert(m_jobs.begin(), jobs.begin(), jobs.end()); - for (size_t i = 0; i < numJobs; ++i) - { - m_jobs[i].m_debugInitialThread = m_index; - } - - m_jobsCV.notify_one(); - } - - long NumJobsPending() const - { - AZStd::lock_guard lock(m_lockJobs); - return m_jobs.size(); - } - - // Called from main thread - void SignalExit() - { - CryInterlockedCompareExchange(&m_exitFlag, 1, 0); - } - - void GetTraces(JobTraces& traces) - { - if (m_tracingEnabled) - { - m_traces.swap(traces); - } - } - - private: - StealingThreadPool* m_pool; - AZStd::thread m_thread; - int m_index; - bool m_tracingEnabled; - int m_lastStartTime; - JobTraces m_traces; - - Jobs m_jobs; - mutable AZStd::mutex m_lockJobs; - AZStd::condition_variable& m_jobsCV; - - LONG m_exitFlag; - friend class StealingThreadPool; - }; - - // --------------------------------------------------------------------------- - - StealingThreadPool::StealingThreadPool(int numThreads, bool enableTracing) - : m_numThreads(numThreads) - , m_numJobs(0) - , m_numJobsWaitingForExecution(0) - , m_enableTracing(enableTracing) - { - m_workers.resize(numThreads); - for (int i = 0; i < numThreads; ++i) - { - m_workers[i] = new StealingWorker(this, i, m_enableTracing, m_jobsCV); - } - } - - StealingThreadPool::~StealingThreadPool() - { - WaitAllJobs(); - - size_t numThreads = m_workers.size(); - for (size_t i = 0; i < numThreads; ++i) - { - m_workers[i]->SignalExit(); - } - m_jobsCV.notify_all(); - - m_threadTraces.resize(numThreads); - for (size_t i = 0; i < numThreads; ++i) - { - m_workers[i]->GetTraces(m_threadTraces[i]); - } - } - - void StealingThreadPool::Start() - { - int startTime = (int)GetTickCount(); - size_t numThreads = m_workers.size(); - for (int i = 0; i < numThreads; ++i) - { - m_workers[i]->Start(startTime); - } - } - - void StealingThreadPool::WaitAllJobs() - { - AZStd::mutex loadMutex; - AZStd::unique_lock loadLock(loadMutex, AZStd::defer_lock_t()); - - while (m_numJobs > 0) - { - m_jobsCV.wait(loadLock); - } - } - - // Called from any thread - void StealingThreadPool::Submit(const Job& job) - { - ++m_numJobs; - ++m_numJobsWaitingForExecution; - - if (StealingWorker* worker = FindWorstWorker()) - { - worker->Submit(job); - } - } - - // Called from any thread - void StealingThreadPool::Submit(const Jobs& jobs) - { - m_numJobs += jobs.size(); - m_numJobsWaitingForExecution += jobs.size(); - if (StealingWorker* worker = FindWorstWorker()) - { - worker->Submit(jobs); - } - } - - JobGroup* StealingThreadPool::CreateJobGroup(JobFunc func, void* data) - { - return new JobGroup(this, func, data); - } - - StealingWorker* StealingThreadPool::FindBestVictim(int exceptFor) const - { - int maxJobs = 0; - StealingWorker* bestVictim = 0; - for (size_t i = 0; i < m_workers.size(); ++i) - { - if (i == exceptFor) - { - continue; - } - StealingWorker* worker = m_workers[i]; - long numJobs = worker->NumJobsPending(); - if (numJobs > maxJobs) - { - maxJobs = numJobs; - bestVictim = worker; - } - } - return bestVictim; - } - - StealingWorker* StealingThreadPool::FindWorstWorker() const - { - if (m_workers.empty()) - { - return 0; - } - - int minJobs = INT_MAX; - StealingWorker* worstWorker = m_workers[0]; - for (size_t i = 0; i < m_workers.size(); ++i) - { - StealingWorker* worker = m_workers[i]; - long numJobs = worker->NumJobsPending(); - if (numJobs < minJobs) - { - minJobs = numJobs; - worstWorker = worker; - } - } - return worstWorker; - } - - static bool WriteString(FILE* f, const char* str) - { - return fwrite(str, strlen(str), 1, f) == 1; - } - - static int Interpolate(int a, int b, float phase) - { - return int(float(a) + float(b - a) * phase); - } - - static int InterpolateColor(int c1, int c2, float phase) - { - const int r1 = (c1 & 0x0000ff); - const int g1 = (c1 & 0x00ff00) >> 8; - const int b1 = (c1 & 0xff0000) >> 16; - const int r2 = (c2 & 0x0000ff); - const int g2 = (c2 & 0x00ff00) >> 8; - const int b2 = (c2 & 0xff0000) >> 16; - - const int r = min(255, max(0, Interpolate(r1, r2, phase))); - const int g = min(255, max(0, Interpolate(g1, g2, phase))); - const int b = min(255, max(0, Interpolate(b1, b2, phase))); - - return r + (g << 8) + (b << 16); - } - - static const int g_animColors[] = { - 0xff0000, 0x0000ff, 0x00ff00, - 0xffff00, 0xff00ff, 0x00ffff, - 0xff8080, 0x8080ff, 0x80ff80, - 0xffff80, 0xff80ff, 0x80ffff - }; - - static int ColorizeJobTrace(const ThreadUtils::JobTrace& trace) - { - const int numColors = sizeof(g_animColors) / sizeof(g_animColors[0]); - const int initialThread = trace.m_job.m_debugInitialThread; - const int index = initialThread % numColors; - const float brightness = aznumeric_cast(pow(0.5f, initialThread / numColors)); - return InterpolateColor(0, InterpolateColor(g_animColors[index], 0xffffff, 0.5f), brightness); - } - - bool StealingThreadPool::SaveTracesGraph(const char* filename) - { - if (!m_enableTracing) - { - return false; - } - - const float screenWidth = 1240.0f; - - float duration = 0; - for (size_t t = 0; t < m_threadTraces.size(); ++t) - { - float threadDuration = 0; - const JobTraces& traces = m_threadTraces[t]; - for (int i = 0; i < traces.size(); ++i) - { - threadDuration += traces[i].m_duration; - } - duration = max(threadDuration, duration); - } - - const float padding = 10.0f; - const float rowHeight = 60.0f; - const float xScale = fabsf(duration) > FLT_EPSILON ? (screenWidth - padding * 2.0f) / duration : 1.0f; - - const float width = screenWidth; - const float height = (m_threadTraces.size() + 0.5f) * rowHeight; - - FILE* f = nullptr; - azfopen(&f, filename, "wt"); - if (!f) - { - return false; - } - - char buf[4096]; - azsnprintf(buf, sizeof(buf), - "\n" - "\n", - width, height - ); - - if (!WriteString(f, buf)) - { - return false; - } - - for (size_t t = 0; t < m_threadTraces.size(); ++t) - { - float x = padding; - float y = rowHeight * 0.5f + rowHeight * t; - - azsnprintf(buf, sizeof(buf), - " Thread %i\n", - x, y, x, y, static_cast(t + 1)); - - if (!WriteString(f, buf)) - { - return false; - } - - - y += padding; - - const ThreadUtils::JobTraces& traces = m_threadTraces[t]; - for (int i = 0; i < traces.size(); ++i) - { - const float width2 = traces[i].m_duration * xScale; - const float height2 = rowHeight * 0.5f; - - const int color = ColorizeJobTrace(traces[i]); - const int strokeColor = 0; - azsnprintf(buf, sizeof(buf), - " \n", - color, strokeColor, width2, height2, x, y); - - if (!WriteString(f, buf)) - { - return false; - } - - x += width2; - } - - y += rowHeight; - } - - if (!WriteString(f, "\n\n")) - { - return false; - } - - fclose(f); - return true; - } - - // --------------------------------------------------------------------------- - - void JobGroup::Process(JobGroup::GroupInfo* info) - { - info->m_job.Run(); - - long jobsLeft = --info->m_group->m_numJobsRunning; - assert(jobsLeft >= 0); - if (jobsLeft == 0) - { - info->m_group->m_finishJob.Run(); - delete info->m_group; - } - } - - JobGroup::JobGroup(StealingThreadPool* pool, JobFunc func, void* data) - : m_pool(pool) - , m_numJobsRunning(0) - , m_finishJob(func, data) - , m_submited(false) - { - } - - void JobGroup::Submit() - { - if (m_submited) - { - assert(0); - return; - } - - if (m_numJobsRunning == 0) - { - m_pool->Submit(m_finishJob); - return; - } - - Jobs jobs; - jobs.resize(m_infos.size()); - for (size_t i = 0; i < m_infos.size(); ++i) - { - jobs[i] = Job((JobFunc) & JobGroup::Process, &m_infos[i]); - } - - m_pool->Submit(jobs); - } - - void JobGroup::Add(JobFunc func, void* data) - { - if (m_submited) - { - assert(0); - return; - } - - GroupInfo info; - info.m_job = Job(func, data); - info.m_group = this; - - m_infos.push_back(info); - ++m_numJobsRunning; - } -} diff --git a/Code/Tools/CryCommonTools/StealingThreadPool.h b/Code/Tools/CryCommonTools/StealingThreadPool.h deleted file mode 100644 index 8576ed0416..0000000000 --- a/Code/Tools/CryCommonTools/StealingThreadPool.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_STEALINGTHREADPOOL_H -#define CRYINCLUDE_CRYCOMMONTOOLS_STEALINGTHREADPOOL_H -#pragma once - - -#include "ThreadUtils.h" -#include -#include -#include -#include -#if AZ_TRAIT_OS_PLATFORM_APPLE -#include "AppleSpecific.h" -#endif - -namespace ThreadUtils { - class StealingWorker; - class JobGroup; - - // Simple stealing thread pool - class StealingThreadPool - { - public: - explicit StealingThreadPool(int numThreads, bool enableTracing = false); - ~StealingThreadPool(); - - void Start(); - void WaitAllJobs(); - - const std::vector& Traces() const{ return m_threadTraces; } - bool SaveTracesGraph(const char* filename); - - // Submits single independent job - template - void Submit(void(* jobFunc)(T*), T* data) - { - Submit(Job((JobFunc)jobFunc, data)); - } - - // Create a group of jobs. A group of jobs can be followed by one "finishing" job. - // It is a way to express dependencies between jobs. - template - JobGroup* CreateJobGroup(void(* jobFunc)(T*), T* data) - { - return CreateJobGroup((JobFunc)jobFunc, (void*)data); - } - - uint GetNumThreads() const { return aznumeric_cast(m_numThreads); } - - private: - StealingWorker* FindBestVictim(int exceptFor) const; - StealingWorker* FindWorstWorker() const; - - void Submit(const Job& job); - void Submit(const Jobs& jobs); - JobGroup* CreateJobGroup(JobFunc, void* data); - - size_t m_numThreads; - typedef std::vector ThreadWorkers; - ThreadWorkers m_workers; - - bool m_enableTracing; - std::vector m_threadTraces; - - AZStd::atomic_long m_numJobsWaitingForExecution; - AZStd::atomic_long m_numJobs; - AZStd::condition_variable m_jobsCV; - AZStd::condition_variable m_jobFinishedCV; - - - friend class JobGroup; - friend class StealingWorker; - }; - - - // JobGroup represents a group of jobs that can be followed by one "finishing" - // job. This is a way to express dependencies between jobs. - class JobGroup - { - public: - template - void Add(void(* jobFunc)(T*), T* data) - { - Add((JobFunc)jobFunc, data); - } - - // Submits group to thread pool - void Submit(); - private: - struct GroupInfo - { - Job m_job; - JobGroup* m_group; - }; - typedef std::vector GroupInfos; - - JobGroup(StealingThreadPool* pool, JobFunc func, void* data); - - static void Process(JobGroup::GroupInfo* job); - void Add(JobFunc func, void* data); - - volatile LONG m_numJobsRunning; - StealingThreadPool* m_pool; - GroupInfos m_infos; - Job m_finishJob; - bool m_submited; - friend class StealingThreadPool; - }; -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_STEALINGTHREADPOOL_H diff --git a/Code/Tools/CryCommonTools/SuffixUtil.h b/Code/Tools/CryCommonTools/SuffixUtil.h deleted file mode 100644 index 632e86525f..0000000000 --- a/Code/Tools/CryCommonTools/SuffixUtil.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_SUFFIXUTIL_H -#define CRYINCLUDE_CRYCOMMONTOOLS_SUFFIXUTIL_H -#pragma once - - -// convenience class to work with suffixes in filenames, like in like dirt_ddn.dds -class SuffixUtil -{ -public: - - // filename allowed to have many suffixes (e.g. "test_ddn_bump.dds" has "bump" and "ddn" - // as suffixes (assuming that suffixSeparator is '_'). - // suffixes in file extension are also considered (e.g. "test_abc.my_data" has "abc" and "data" as suffixes) - // suffixes in path part are also considered. if it's not what you want - remove path before calling this function. - // comparison is case insensitive - static bool HasSuffix(const char* const filename, const char suffixSeparator, const char* const suffix) - { - assert(filename); - assert(suffix && suffix[0]); - - const size_t suffixLen = strlen(suffix); - - for (const char* p = filename; *p; ++p) - { - if (p[0] != suffixSeparator) - { - continue; - } - - if (azmemicmp(&p[1], suffix, suffixLen) != 0) - { - continue; - } - - const char c = p[1 + suffixLen]; - if ((c == 0) || (c == suffixSeparator) || (c == '.')) - { - return true; - } - } - - return false; - } -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_SUFFIXUTIL_H diff --git a/Code/Tools/CryCommonTools/SummedAreaFilterKernel.cpp b/Code/Tools/CryCommonTools/SummedAreaFilterKernel.cpp deleted file mode 100644 index 3ee26df3bd..0000000000 --- a/Code/Tools/CryCommonTools/SummedAreaFilterKernel.cpp +++ /dev/null @@ -1,442 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include -#include // assert() -#include // floorf() -#include "SummedAreaFilterKernel.h" // CSummedAreaFilterKernel - -CSummedAreaFilterKernel::CSummedAreaFilterKernel() -{ - m_eFilterType = eEmpty; - m_fCorrectionFactor = 0.0f; -} - -// http://www.sixsigma.de/english/sixsigma/6s_e_gauss.htm -bool CSummedAreaFilterKernel::CreateFromGauss(const unsigned long indwSize) -{ - assert(indwSize > 2); - - int iInit = 0; - - if (!Alloc(indwSize, indwSize, &iInit)) - { - return false; - } - - for (unsigned long y = 0; y < indwSize; y++) - { - for (unsigned long x = 0; x < indwSize; x++) - { - float fX = (float)(x) - (float)(indwSize) * 0.5f; - float fY = (float)(y) - (float)(indwSize) * 0.5f; - - double r1 = sqrt(fX * fX + fY * fY) / (indwSize * 0.5 - 2.0); - - if (r1 > 1) - { - m_pData[y * indwSize + x] = 0; - } - else - { - double fSigma = 1.0 / 3.0; // we aim for 6*sigma = 99,99996 of all values - - double fWeight = exp(-r1 * r1 / (2 * fSigma * fSigma)); - - fWeight -= (1.0 - 0.9999996); - - m_pData[y * indwSize + x] = (int)(255.0f * fWeight); - } - } - } - - m_eFilterType = eGaussBlur; - _SumUpTableAndNormalize(); - return true; -} - - -// create summed area table -void CSummedAreaFilterKernel::_SumUpTableAndNormalize() -{ - for (unsigned long y = 0; y < m_dwHeight; y++) - { - int iFromLeft = 0; - - for (unsigned long x = 0; x < m_dwWidth; x++) - { - iFromLeft += m_pData[y * m_dwWidth + x]; - - if (y != 0) - { - m_pData[y * m_dwWidth + x] = iFromLeft + m_pData[(y - 1) * m_dwWidth + x]; - } - else - { - m_pData[y * m_dwWidth + x] = iFromLeft; - } - } - } - - m_fCorrectionFactor = 1.0f / ((float)m_pData[m_dwHeight * m_dwWidth - 1]); -} - - -// windows size 16x16 = radius 8 -bool CSummedAreaFilterKernel::CreateFromSincCalc(const unsigned long indwSize) -{ - assert(indwSize > 2); - - int iInit = 0; - - if (!Alloc(indwSize, indwSize, &iInit)) - { - return false; - } - - for (unsigned long y = 0; y < indwSize; y++) - { - for (unsigned long x = 0; x < indwSize; x++) - { - float fX = (float)(x - indwSize * 0.5f); - float fY = (float)(y - indwSize * 0.5f); - - float r1 = sqrtf(fX * fX + fY * fY) / (indwSize * 0.5f - 2.0f); - - if (r1 > 1.0f) - { - m_pData[y * indwSize + x] = 0; - } - else - { - r1 *= 3.1415926535897932384626433832795f; - - float r2 = r1 * 8.0f; - - // http://home.no.net/dmaurer/~dersch/interpolator/interpolator.html - // weight = [ sin(x*pi) / (x*pi) ] * [ sin(x*pi / 8) / (x*pi/8) ] - - // http://www.binbooks.com/books/photo/i/l/57186AF8DE - // sinc(x) = sin(pi * x) / (pi * x) - // L8interp(x) = sinc(x) * sinc(x/8) if abs(x) <= 8 - // = 0 if abs(x) > 8 - - float fWeight = (sinf(r1) * sinf(r2)) / (r1 * r2); - - m_pData[y * indwSize + x] = (int)(255.0f * fWeight); - } - } - } - - m_eFilterType = eSinc; - _SumUpTableAndNormalize(); - - return true; -} - - - - - -bool CSummedAreaFilterKernel::CreateFromRAWFile(const char* filename, const unsigned long indwSize, const int iniMidValue) -{ - assert(iniMidValue >= 0 && iniMidValue < 255); - - int iInit = 0; - - if (!Alloc(indwSize, indwSize, &iInit)) - { - return false; - } - - FILE* in = fopen(filename, "rb"); - if (!in) - { - return false; - } - - for (unsigned long y = 0; y < m_dwHeight; y++) - { - for (unsigned long x = 0; x < m_dwWidth; x++) - { - unsigned char val; - - if (fread(&val, 1, 1, in) != 1) - { - fclose(in); - return false; - } - - m_pData[y * m_dwWidth + x] = (int)val - iniMidValue; - } - } - - fclose(in); - - m_eFilterType = eRAW; - _SumUpTableAndNormalize(); - - return true; -} - - -std::string CSummedAreaFilterKernel::GetInfoString(void) const -{ - std::string sRet = "FilterKernel("; - - switch (m_eFilterType) - { - case eEmpty: - sRet += "Empty"; - break; - case eSinc: - sRet += "Sinc16x16"; - break; - case eRAW: - sRet += "RAW"; - break; - case eGaussBlur: - sRet += "GaussBlur"; - break; - case eGaussSharp: - sRet += "GaussSharp"; - break; - default: - assert(0); - } - - sRet += ")"; - - return(sRet); -} - -float CSummedAreaFilterKernel::GetAreaNonAA(float infAx, float infAy, float infDx, float infDy) const -{ - assert(m_eFilterType != eEmpty); - - int ax = (int)floorf(infAx * 127.5f + 127.5f); - int ay = (int)floorf(infAy * 127.5f + 127.5f); - int dx = (int)floorf(infDx * 127.5f + 127.5f); - int dy = (int)floorf(infDy * 127.5f + 127.5f); - - if (ax < 0) - { - ax = 0; - } - else if (ax > 255) - { - ax = 255; - } - if (dx < 0) - { - dx = 0; - } - else if (dx > 255) - { - dx = 255; - } - if (ay < 0) - { - ay = 0; - } - else if (ay > 255) - { - ay = 255; - } - if (dy < 0) - { - dy = 0; - } - else if (dy > 255) - { - dy = 255; - } - - unsigned long area = m_pData[dy * m_dwWidth + dx] - m_pData[dy * m_dwWidth + ax] - m_pData[ay * m_dwWidth + dx] + m_pData[ay * m_dwWidth + ax]; - - return(m_fCorrectionFactor * (float)area); -} - - - -// optimizable -float CSummedAreaFilterKernel::GetAreaAA(float infAx, float infAy, float infDx, float infDy) const -{ - assert(m_eFilterType != eEmpty); - - infAx = infAx * 127.5f + 127.5f; - infAy = infAy * 127.5f + 127.5f; - infDx = infDx * 127.5f + 127.5f; - infDy = infDy * 127.5f + 127.5f; - - float fSum = _GetBilinearFiltered(infDx, infDy) - - _GetBilinearFiltered(infAx, infDy) - - _GetBilinearFiltered(infDx, infAy) - + _GetBilinearFiltered(infAx, infAy); - - return(fSum * m_fCorrectionFactor); -} - - -float CSummedAreaFilterKernel::_GetBilinearFiltered(const float infX, const float infY) const -{ - float fIX = floorf(infX), fIY = floorf(infY); - float fFX = infX - fIX, fFY = infY - fIY; - int iX = (int)fIX, iY = (int)fIY; - - if (iX < 0) - { - iX = 0; - } - else if (iX > 254) - { - iX = 254; - } - if (iY < 0) - { - iY = 0; - } - else if (iY > 254) - { - iY = 254; - } - - float fArea = m_pData[ iY * m_dwWidth + iX ] * ((1.0f - fFX) * (1.0f - fFY)) // left top - + m_pData[ iY * m_dwWidth + iX + 1 ] * ((fFX) * (1.0f - fFY)) // right top - + m_pData[(iY + 1) * m_dwWidth + iX ] * ((1.0f - fFX) * (fFY)) // left bottom - + m_pData[ iY * m_dwWidth + iX + 257] * ((fFX) * (fFY)); // right bottom - - return(fArea); -} - - - -bool CSummedAreaFilterKernel::CreateWeightFilter(CSimpleBitmap& outFilter, const float infX, const float infY, - const float infWeight, const float infR) const -{ - assert(infX >= 0.0f); - assert(infX < 1.0f); - assert(infY >= 0.0f); - assert(infY < 1.0f); - assert(infWeight >= 0.0f); - assert(infR > 0.0f); - - float fLeftTop = ceilf(infR); - int iSide = 2 * (int)fLeftTop + 1; - - float fInit = 0.0f; - - if (!outFilter.Alloc(iSide, iSide, &fInit)) - { - return false; - } - - AddWeights(outFilter, infX + fLeftTop, infY + fLeftTop, infWeight, infR); - - return true; -} - - -bool CSummedAreaFilterKernel::CreateWeightFilterBlock(CSimpleBitmap& outFilter, const unsigned long indwSideLength, - const float infR) const -{ - assert(indwSideLength >= 0); - assert(infR > 0.0f); - - float fLeftTop = ceilf(infR); - int iSide = 2 * (int)fLeftTop + 1; - - float fInit = 0.0f; - - if (!outFilter.Alloc(iSide, iSide, &fInit)) - { - return false; - } - - float fStep = 1.0f / (float)indwSideLength; - float fHalf = fStep * 0.5f; - - float fWeight = fStep * fStep; - - for (float y = fHalf; y < 1.0f; y += fStep) - { - for (float x = fHalf; x < 1.0f; x += fStep) - { - AddWeights(outFilter, x + fLeftTop, y + fLeftTop, fWeight, infR); - } - } - - // check -#ifdef _DEBUG - float fSum = 0.0f; - for (int y = 0; y < iSide; y++) - { - for (int x = 0; x < iSide; x++) - { - float f; - - outFilter.Get(x, y, f); - fSum += f; - } - } - assert(fSum >= 0.98f); - assert(fSum <= 1.02f); -#endif - - return true; -} - - -void CSummedAreaFilterKernel::AddWeights(CSimpleBitmap& inoutFilter, const float infX, const float infY, - const float infWeight, const float infR) const -{ - assert(infWeight >= 0.0f); - assert(infR > 0.0f); - - if (infWeight <= 0.0f) - { - return; - } - - float fInvR = 1.0f / infR; - float sx = floorf(infX - infR); - float sy = floorf(infY - infR); - - int iax = (int)sx; - int iay = (int)sy; - int iex = (int)ceilf(infX + infR); - int iey = (int)ceilf(infY + infR); - - float x, y; - int ix, iy; - - for (iy = iay, y = (sy - infY) * fInvR; iy <= iey; iy++, y += fInvR) - { - for (ix = iax, x = (sx - infX) * fInvR; ix <= iex; ix++, x += fInvR) - { - float fArea = GetAreaAA(x, y, x + fInvR, y + fInvR); // better quality - // float fArea=m_Filter.GetAreaNonAA(x,y,x+fInvR,y+fInvR); // faster - - // assert(fArea<=1.0f); // may be wrong if we use sharpening filter - - float fOldVal; - - inoutFilter.Get(ix, iy, fOldVal); - inoutFilter.Set(ix, iy, fOldVal + fArea * infWeight); - } - } -} - - - diff --git a/Code/Tools/CryCommonTools/SummedAreaFilterKernel.h b/Code/Tools/CryCommonTools/SummedAreaFilterKernel.h deleted file mode 100644 index 55af94f12c..0000000000 --- a/Code/Tools/CryCommonTools/SummedAreaFilterKernel.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_SUMMEDAREAFILTERKERNEL_H -#define CRYINCLUDE_CRYCOMMONTOOLS_SUMMEDAREAFILTERKERNEL_H - -#include // STL string -#include "SimpleBitmap.h" // SimpleBitmap<> - -// squared of any size (summed area tables limit the size and/or values) -// normalized(sum=1) - -// optimized for high quality, not speed -// for faster filter kernels extract the neccessary size and use this 1:1 - -// based on summed area tables - -class CSummedAreaFilterKernel - : public CSimpleBitmap -{ -public: - - //! constructor init is eEmpty - CSummedAreaFilterKernel(); - - //! load 8 bit photoshop 256x256 raw image - slow - //! typical filtersize for a gaussian filter kernel is 1.44 - //! /param iniMidValue [0..255[ this enables sharpening - sharpening may expand the result range - bool CreateFromRAWFile(const char* filename, const unsigned long indwSize = 256, const int iniMidValue = 0); - - //! sharpest possible result - filter diameter size has to be 16*pixelsize (256 samples per pixel) - //! theory: http://home.no.net/dmaurer/~dersch/interpolator/interpolator.html - //! /param indwSize >2 - bool CreateFromSincCalc(const unsigned long indwSize = 256); - - //! shttp://www.sixsigma.de/english/sixsigma/6s_e_gauss.htm - //! /param indwSize >2 - bool CreateFromGauss(const unsigned long indwSize = 256); - - //! optimizable O(k*1) with high k - //! bokeh is in the range ([-1..1],[-1..1]) - //! return normalized result - float GetAreaAA(float infAx, float infAy, float infDx, float infDy) const; - - //! O(k*1) with low k - //! bokeh is in the range ([-1..1],[-1..1]) - //! return normalized result - float GetAreaNonAA(float infAx, float infAy, float infDx, float infDy) const; - - //! - //! /return e.g. "FilterKernel(Sinc16x16)" - std::string GetInfoString(void) const; - - //! /param infX [0..1[ - //! /param infY [0..1[ - //! /param infWeight [0..[ - //! /param infR >0, radius - bool CreateWeightFilter(CSimpleBitmap& outFilter, const float infX, const float infY, - const float infWeight, const float infR) const; - - //! weight for the whole block is 1.0 - //! /param indwSideLength [1,..[ e.g. 3 for 3x3 block - //! /param infR >0, radius - bool CreateWeightFilterBlock(CSimpleBitmap& outFilter, const unsigned long indwSideLength, const float infR) const; - - //! with user filter kernel - //! /param infX - //! /param infY - //! /param infWeight [0..[ - //! /param infR >0, radius - void AddWeights(CSimpleBitmap& inoutFilter, const float infX, const float infY, - const float infWeight, const float infR) const; - -private: // -------------------------------------------------------------------- - - enum EFilterState - { - eEmpty, //!< after calling constructor - eSinc, //!< from CreateFromSincCalc - eRAW, //!< from CreateFromRAWFile - eGaussBlur, //!< from CreateFromGauss - eDisc, //!< not implemented - eGaussSharp //!< not implemented - }; - - EFilterState m_eFilterType; //!< for error checks and GetInfoString() - float m_fCorrectionFactor; //!< to get the normalized (whole kernel has sum of 1) result - - //! optimizable - //! bokeh is in the range ([0..255],[0..255]) - //! /param infX - //! /param infY - //! /return not normalized result - float _GetBilinearFiltered(const float infX, const float infY) const; - - //! sum the stored values in the bitmap together - //! calculate m_fCorrectionFactor - void _SumUpTableAndNormalize(void); -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_SUMMEDAREAFILTERKERNEL_H diff --git a/Code/Tools/CryCommonTools/TempFilePakExtraction.cpp b/Code/Tools/CryCommonTools/TempFilePakExtraction.cpp deleted file mode 100644 index 52aa6896d6..0000000000 --- a/Code/Tools/CryCommonTools/TempFilePakExtraction.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Opens a temporary file for read only access, where the file could be -// located in a zip or pak file. Note that if the file specified -// already exists it does not delete it when finished. - - -#include "TempFilePakExtraction.h" -#include "FileUtil.h" -#include "PathHelpers.h" -#include "IPakSystem.h" - - -TempFilePakExtraction::TempFilePakExtraction(const char* filename, const char* tempPath, IPakSystem* pPakSystem) - : m_strOriginalFileName(filename) - , m_strTempFileName(filename) -{ - if (!pPakSystem || !tempPath) - { - return; - } - - { - FILE* fileOnDisk = nullptr; - azfopen(&fileOnDisk, m_strOriginalFileName.c_str(), "rb"); - if (fileOnDisk) - { - fclose(fileOnDisk); - return; - } - } - - // Choose the name for the temporary file. - string tempFullFileName; - { - uint32 tempNumber = 0; - { - LARGE_INTEGER performanceCount; - if (QueryPerformanceCounter(&performanceCount)) - { - tempNumber = performanceCount.u.LowPart; - } - } - - string tempName; - { - // CryEngine's pak system supports filenames in format "@pakFilename|fileInPak", - // so let's handle such cases by using fileInPak part of the filename. - const size_t pos = m_strOriginalFileName.find_last_of('|'); - if (pos != string::npos) - { - tempName = m_strOriginalFileName.substr(pos + 1, string::npos); - if (tempName.empty()) - { - tempName = "BadFilenameSyntax"; - } - } - else - { - tempName = m_strOriginalFileName; - } - tempName = PathHelpers::GetFilename(tempName); - } - - int tryCount = 2000; - while (--tryCount >= 0) - { - tempFullFileName.Format("%sRC%04x_%s", tempPath, (tempNumber & 0xFFFF), tempName.c_str()); - - if (!FileUtil::FileExists(tempFullFileName.c_str())) - { - FILE* f = nullptr; - azfopen(&f, tempFullFileName.c_str(), "wb"); - if (f) - { - fclose(f); - break; - } - } - - tempFullFileName.clear(); - ++tempNumber; - } - - if (tempFullFileName.empty()) - { - return; - } - } - - if (pPakSystem->ExtractNoOverwrite(m_strOriginalFileName.c_str(), tempFullFileName.c_str())) - { - m_strTempFileName = tempFullFileName; - AZ::IO::SystemFile::SetWritable(m_strTempFileName.c_str(), false); - } - else - { - AZ::IO::LocalFileIO().Remove(tempFullFileName.c_str()); - } -} - - -TempFilePakExtraction::~TempFilePakExtraction() -{ - if (HasTempFile()) - { -#if defined(AZ_PLATFORM_WINDOWS) - SetFileAttributesA(m_strTempFileName.c_str(), FILE_ATTRIBUTE_ARCHIVE); -#endif - AZ::IO::LocalFileIO().Remove(m_strTempFileName.c_str()); - } -} - - -bool TempFilePakExtraction::HasTempFile() const -{ - return (m_strOriginalFileName != m_strTempFileName); -} diff --git a/Code/Tools/CryCommonTools/TempFilePakExtraction.h b/Code/Tools/CryCommonTools/TempFilePakExtraction.h deleted file mode 100644 index c0fbb44b8a..0000000000 --- a/Code/Tools/CryCommonTools/TempFilePakExtraction.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Opens a temporary file for read only access, where the file could be -// located in a zip or pak file. Note that if the file specified -// already exists it does not delete it when finished. - - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_TEMPFILEPAKEXTRACTION_H -#define CRYINCLUDE_CRYCOMMONTOOLS_TEMPFILEPAKEXTRACTION_H -#pragma once - -#include - -struct IPakSystem; - -class TempFilePakExtraction -{ -public: - TempFilePakExtraction(const char* filename, const char* tempPath, IPakSystem* pPakSystem); - ~TempFilePakExtraction(); - - const string& GetTempName() const - { - return m_strTempFileName; - } - - const string& GetOriginalName() const - { - return m_strOriginalFileName; - } - - bool HasTempFile() const; - -private: - string m_strTempFileName; - string m_strOriginalFileName; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_TEMPFILEPAKEXTRACTION_H diff --git a/Code/Tools/CryCommonTools/ThreadUtils.cpp b/Code/Tools/CryCommonTools/ThreadUtils.cpp deleted file mode 100644 index b3dfcd6117..0000000000 --- a/Code/Tools/CryCommonTools/ThreadUtils.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "ThreadUtils.h" -#include -#include -#include -#include - -namespace ThreadUtils -{ - class SimpleWorker - { - public: - SimpleWorker(SimpleThreadPool* pool, int index, bool trace) - : m_pool(pool) - , m_index(index) - , m_trace(trace) - { - } - - void Start(int startTime) - { - m_lastStartTime = startTime; - m_handle = AZStd::thread(AZStd::bind(SimpleWorker::ThreadFunc, (void*)this)); - } - - static unsigned int __stdcall ThreadFunc(void* param) - { - SimpleWorker* self = (SimpleWorker*)(param); - self->Work(); - return 0; - } - - void ExecuteJob(Job& job) - { - job.Run(); - if (m_trace) - { - int time = (int)GetTickCount(); - - JobTrace trace; - trace.m_job = job; - trace.m_duration = time - m_lastStartTime; - m_traces.push_back(trace); - - m_lastStartTime = time; - } - } - - void Work() - { - Job job; - for (;; ) - { - if (m_pool->GetJob(job, m_index)) - { - ExecuteJob(job); - } - else - { - return; - } - } - } - - // Called from main thread - void Join(JobTraces& traces) - { - if(m_handle.joinable()) - { - m_handle.join(); - } - - if (m_trace) - { - m_traces.swap(traces); - } - } - - private: - SimpleThreadPool* m_pool; - AZStd::thread m_handle; - int m_index; - bool m_trace; - int m_lastStartTime; - JobTraces m_traces; - friend SimpleThreadPool; - }; - - // --------------------------------------------------------------------------- - - SimpleThreadPool::SimpleThreadPool(bool trace) - : m_trace(trace) - , m_started(false) - , m_numProcessedJobs(0) - { - } - - SimpleThreadPool::~SimpleThreadPool() - { - WaitAllJobs(); - } - - void SimpleThreadPool::Start(int numThreads) - { - m_workers.resize(numThreads); - for (int i = 0; i < numThreads; ++i) - { - m_workers[i] = new SimpleWorker(this, i, m_trace); - } - - m_started = true; - - int startTime = (int)GetTickCount(); - for (int i = 0; i < numThreads; ++i) - { - m_workers[i]->Start(startTime); - } - } - - - void SimpleThreadPool::WaitAllJobs() - { - size_t numThreads = m_workers.size(); - m_threadTraces.resize(numThreads); - for (size_t i = 0; i < numThreads; ++i) - { - m_workers[i]->Join(m_threadTraces[i]); - } - - for (size_t i = 0; i < numThreads; ++i) - { - delete m_workers[i]; - } - m_workers.clear(); - - m_started = false; - } - - void SimpleThreadPool::Submit(const Job& job) - { - assert(!m_started); - m_jobs.push_back(job); - } - - bool SimpleThreadPool::GetJob(Job& job, [[maybe_unused]] int threadIndex) - { - AZStd::lock_guard lock(m_lockJobs); - - if (m_numProcessedJobs >= m_jobs.size()) - { - return false; - } - - job = m_jobs[m_numProcessedJobs]; - ++m_numProcessedJobs; - return true; - } -} diff --git a/Code/Tools/CryCommonTools/ThreadUtils.h b/Code/Tools/CryCommonTools/ThreadUtils.h deleted file mode 100644 index ac60a8420e..0000000000 --- a/Code/Tools/CryCommonTools/ThreadUtils.h +++ /dev/null @@ -1,288 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_THREADUTILS_H -#define CRYINCLUDE_CRYCOMMONTOOLS_THREADUTILS_H -#pragma once - -#include - -#if defined(AZ_PLATFORM_WINDOWS) -#define WIN32_LEAN_AND_MEAN -#include // CRITICAL_SECTION -#endif - -#include -#include - -namespace ThreadUtils -{ -#if defined(AZ_PLATFORM_WINDOWS) - class CriticalSection - { - friend class ConditionVariable; - - public: - CriticalSection() - { - memset(&m_cs, 0, sizeof(m_cs)); - InitializeCriticalSection(&m_cs); - } - - ~CriticalSection() - { - DeleteCriticalSection(&m_cs); - } - - void Lock() - { - EnterCriticalSection(&m_cs); - } - void Unlock() - { - LeaveCriticalSection(&m_cs); - } - bool TryLock() - { - return TryEnterCriticalSection(&m_cs) != FALSE; - } - -#if defined(AZ_DEBUG_BUILD) - bool IsLocked() - { - return m_cs.RecursionCount > 0 && m_cs.OwningThread == GetCurrentThread(); - } -#endif - - private: - // You are not allowed to copy or move a CRITICAL_SECTION - // handle, so make this class non-copyable - CriticalSection(const CriticalSection& cs); - CriticalSection& operator=(const CriticalSection& cs); - - CRITICAL_SECTION m_cs; - }; - - class ConditionVariable - { - public: - ConditionVariable() - { - InitializeConditionVariable(&m_cv); - } - - void Wake() - { - WakeConditionVariable(&m_cv); - } - - void WakeAll() - { - WakeAllConditionVariable(&m_cv); - } - - void Sleep(CriticalSection& cs, DWORD milliseconds = INFINITE) - { - SleepConditionVariableCS(&m_cv, &cs.m_cs, milliseconds); - } - - private: - // You are not allowed to copy or move a CONDITION_VARIABLE - // handle, so make this class non-copyable - ConditionVariable(const ConditionVariable& cs); - ConditionVariable& operator=(const ConditionVariable& cs); - - CONDITION_VARIABLE m_cv; - }; -#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) - class CriticalSection - { - public: - CriticalSection() - : m_locked(false) - { - } - - ~CriticalSection() - { - } - - void Lock() - { - m_cs.lock(); - m_locked = true; - } - void Unlock() - { - m_cs.unlock(); - m_locked = false; - } - bool TryLock() - { - m_locked = m_cs.try_lock(); - return m_locked; - } - -#if defined (AZ_DEBUG_BUILD) - bool IsLocked() - { - return m_locked; - } -#endif - - private: - // You are not allowed to copy or move a CRITICAL_SECTION - // handle, so make this class non-copyable - CriticalSection(const CriticalSection& cs); - CriticalSection& operator=(const CriticalSection& cs); - - bool m_locked; - AZStd::recursive_mutex m_cs; - }; -#endif - - class AutoLock - { - private: - CriticalSection& m_lock; - - AutoLock(); - AutoLock(const AutoLock&); - AutoLock& operator = (const AutoLock&); - - public: - AutoLock(CriticalSection& lock) - : m_lock(lock) - { - m_lock.Lock(); - } - ~AutoLock() - { - m_lock.Unlock(); - } - }; - - typedef void(* JobFunc)(void*); - - struct Job - { - JobFunc m_func; - void* m_data; - int m_debugInitialThread; - - Job() - : m_func(0) - , m_data(0) - , m_debugInitialThread(0) - { - } - - Job(JobFunc func, void* data) - : m_func(func) - , m_data(data) - , m_debugInitialThread(0) - { - } - - void Run() - { - m_func(m_data); - } - }; - typedef std::deque Jobs; - - struct JobTrace - { - Job m_job; - bool m_stolen; - int m_duration; - - JobTrace() - : m_duration(0) - , m_stolen(false) - { - } - }; - typedef std::vector JobTraces; - - class SimpleWorker; - - class SimpleThreadPool - { - public: - SimpleThreadPool(bool trace); - ~SimpleThreadPool(); - - bool GetJob(Job& job, int threadIndex); - - // Submits single independent job - template - void Submit(void(* jobFunc)(T*), T* data) - { - Submit(Job((JobFunc)jobFunc, data)); - } - - void Start(int numThreads); - void WaitAllJobs(); - - private: - void Submit(const Job& job); - - bool m_started; - bool m_trace; - - std::vector m_workers; - - std::vector m_threadTraces; - - int m_numProcessedJobs; - AZStd::mutex m_lockJobs; - std::vector m_jobs; - }; - -#if defined(AZ_PLATFORM_WINDOWS) -#pragma pack(push, 8) - struct ThreadNameInfo - { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. - }; -#pragma pack(pop) - - // Usage: SetThreadName (-1, "MainThread"); - // From http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx - inline void SetThreadName([[maybe_unused]] DWORD dwThreadID, [[maybe_unused]] const char* threadName) - { -#ifdef _DEBUG - ThreadNameInfo info; - info.dwType = 0x1000; - info.szName = threadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - const DWORD exceptionCode = 0x406D1388; - RaiseException(exceptionCode, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } -#endif - } -#endif -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_THREADUTILS_H diff --git a/Code/Tools/CryCommonTools/UI/log_icons.bmp b/Code/Tools/CryCommonTools/UI/log_icons.bmp deleted file mode 100644 index 4080bb98ea..0000000000 --- a/Code/Tools/CryCommonTools/UI/log_icons.bmp +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1fb280a5c873225c5f2b0518964c9b7947e81c6fdb4ec19374e02043a12dd295 -size 2358 diff --git a/Code/Tools/CryCommonTools/UnitTests/PathHelpersUnitTests.cpp b/Code/Tools/CryCommonTools/UnitTests/PathHelpersUnitTests.cpp deleted file mode 100644 index 0c44aabb86..0000000000 --- a/Code/Tools/CryCommonTools/UnitTests/PathHelpersUnitTests.cpp +++ /dev/null @@ -1,807 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ - - -#include -#include "PathHelpers.h" -#include -#include -#include - -namespace PathHelpersTest -{ - class CryCommonToolsPathHelpersTest - : public UnitTest::AllocatorsTestFixture - { - public: - void SetUp() override - { - UnitTest::AllocatorsTestFixture::SetUp(); - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - } - - void TearDown() - { - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - UnitTest::AllocatorsTestFixture::TearDown(); - } - }; - - TEST_F(CryCommonToolsPathHelpersTest, FindExtension_StringPathNoExtension_ReturnsEmptyString) - { - const char* filePath = "ext"; - string result = PathHelpers::FindExtension(filePath); - EXPECT_STREQ("", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, FindExtension_StringPath_ReturnsStringExtension) - { - const char* extension = "ext"; - const char* filePath = "foo.ext"; - string result = PathHelpers::FindExtension(filePath); - EXPECT_STREQ(extension, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, FindExtension_WStringPathNoExtension_ReturnsEmptyString) - { - const wchar_t filePath[] = L"ext"; - const wchar_t expectedResult[] = L""; - const wstring result = PathHelpers::FindExtension(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, FindExtension_WStringPath_ReturnsStringExtension) - { - const wchar_t extension[] = L"ext"; - const wchar_t filePath[] = L"foo.ext"; - const wstring result = PathHelpers::FindExtension(filePath); - EXPECT_TRUE(result == extension); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_EmptyStringPath_ReturnsEmptyString) - { - const char* filePath = ""; - const char* newExtension = "new"; - string result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_STREQ(filePath, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_StringNoExtension_ReturnsStringNoExtension) - { - const char* filePath = "foo.ext"; - const char* newExtension = ""; - string result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_STREQ("foo", result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_StringPathWithDoubleBackSlash_ReturnsUnalteredString) - { - const char* filePath = "foo.ext\\"; - const char* newExtension = "new"; - string result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_STREQ(filePath, result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_StringPathWithForwardSlash_ReturnsUnalteredString) - { - const char* filePath = "foo.ext/"; - const char* newExtension = "new"; - string result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_STREQ(filePath, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_StringPathWithColon_ReturnsUnalteredString) - { - const char* filePath = "foo.ext:"; - const char* newExtension = "new"; - string result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_STREQ(filePath, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_StringPathEndsWithPeriod_ReturnsUnalteredString) - { - const char* filePath = "foo.ext."; - const char* newExtension = "new"; - string result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_STREQ(filePath, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_StringNewExtension_ReturnsStringWithNewExtension) - { - const char* filePath = "foo.ext"; - const char* newExtension = "new"; - string result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_STREQ("foo.new", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_EmptyWStringPath_ReturnsEmptyWString) - { - const wchar_t filePath[] = L""; - const wchar_t newExtension[] = L"new"; - wstring result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_TRUE(result == filePath); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_WStringNoExtension_ReturnsWStringNoExtension) - { - const wchar_t filePath[] = L"foo.ext"; - const wchar_t newExtension[] = L""; - const wchar_t expectedResult[] = L"foo"; - wstring result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_TRUE(result == expectedResult); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_WStringPathWithDoubleBackSlash_ReturnsUnalteredWString) - { - const wchar_t filePath[] = L"foo.ext\\"; - const wchar_t newExtension[] = L"new"; - wstring result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_TRUE(result == filePath); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_WStringPathWithForwardSlash_ReturnsUnalteredWString) - { - const wchar_t filePath[] = L"foo.ext/"; - const wchar_t newExtension[] = L"new"; - wstring result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_TRUE(result == filePath); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_WStringPathWithColon_ReturnsUnalteredWString) - { - const wchar_t filePath[] = L"foo.ext:"; - const wchar_t newExtension[] = L"new"; - wstring result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_TRUE(result == filePath); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_WStringPathEndsWithPeriod_ReturnsUnalteredWString) - { - const wchar_t filePath[] = L"foo.ext."; - const wchar_t newExtension[] = L"new"; - wstring result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_TRUE(result == filePath); - } - - TEST_F(CryCommonToolsPathHelpersTest, ReplaceExtension_WStringNewExtension_ReturnsWStringWithNewExtension) - { - const wchar_t filePath[] = L"foo.ext"; - const wchar_t newExtension[] = L"new"; - const wchar_t expectedResult[] = L"foo.new"; - wstring result = PathHelpers::ReplaceExtension(filePath, newExtension); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveExtension_StringPathNoExtension_ReturnsUnalteredString) - { - const char* filePath = "foo"; - string result = PathHelpers::RemoveExtension(filePath); - EXPECT_STREQ(filePath, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveExtension_StringPath_ReturnsStringWithoutExtension) - { - const char* filePath = "foo.bar"; - string result = PathHelpers::RemoveExtension(filePath); - EXPECT_STREQ("foo", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveExtension_WStringPathNoExtension_ReturnsUnalteredWString) - { - const wchar_t filePath[] = L"foo"; - wstring result = PathHelpers::RemoveExtension(filePath); - EXPECT_TRUE(result == filePath); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveExtension_WStringPath_ReturnsWStringWithoutExtension) - { - const wchar_t filePath[] = L"foo.bar"; - const wchar_t expectedResult[] = L"foo"; - wstring result = PathHelpers::RemoveExtension(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_StringPathWithColon_RemovesCharactersAfterColon) - { - const char* filePath = "foo:bar"; - string result = PathHelpers::GetDirectory(filePath); - EXPECT_STREQ("foo:", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_StringPathWithColonAsCharacterBeforeLastSeparator_RemovesCharactersAfterLastSeparator) - { - const char* filePath = "foo:/bar"; - string result = PathHelpers::GetDirectory(filePath); - EXPECT_STREQ("foo:/", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_StringPathWithLastSeparatorAsFirstCharacter_ReturnsStringColon) - { - const char* filePath = ":foo"; - string result = PathHelpers::GetDirectory(filePath); - EXPECT_STREQ(":", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_StringPathStartsWithForwardSlash_ReturnsFullString) - { - const char* filePath = "//foo"; - string result = PathHelpers::GetDirectory(filePath); - EXPECT_STREQ(filePath, result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_StringPathStartsWithDoubleBackSlash_ReturnsFullString) - { - const char* filePath = "\\\\foo"; - string result = PathHelpers::GetDirectory(filePath); - EXPECT_STREQ(filePath, result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_StringPath_ReturnsOnlyStringPath) - { - const char* filePath = "foobar/"; - string result = PathHelpers::GetDirectory(filePath); - EXPECT_STREQ("foobar", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_WStringPathWithColon_RemovesCharactersAfterColon) - { - const wchar_t filePath[] = L"foo:bar"; - const wchar_t expectedResult[] = L"foo:"; - wstring result = PathHelpers::GetDirectory(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_WStringPathWithColonAsCharacterBeforeLastSeparator_RemovesCharactersAfterLastSeparator) - { - const wchar_t filePath[] = L"foo:/bar"; - const wchar_t expectedResult[] = L"foo:/"; - wstring result = PathHelpers::GetDirectory(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_WStringPathWithLastSeparatorAsFirstCharacter_ReturnsWStringColon) - { - const wchar_t filePath[] = L":foo"; - const wchar_t expectedResult[] = L":"; - wstring result = PathHelpers::GetDirectory(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_WStringPathStartsWithForwardSlash_ReturnsFullWString) - { - const wchar_t filePath[] = L"//foo"; - wstring result = PathHelpers::GetDirectory(filePath); - EXPECT_TRUE(result == filePath); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_WStringPathStartsWithDoubleBackSlash_ReturnsFullWString) - { - const wchar_t filePath[] = L"\\\\foo"; - wstring result = PathHelpers::GetDirectory(filePath); - EXPECT_TRUE(result == filePath); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, GetDirectory_WStringPath_ReturnsOnlyWStringPath) - { - const wchar_t filePath[] = L"foobar/"; - const wchar_t expectedResult[] = L"foobar"; - wstring result = PathHelpers::GetDirectory(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetFilename_StringPathStartsWithForwardSlash_ReturnsEmptyString) - { - const char* filePath = "/:foobar"; - string result = PathHelpers::GetFilename(filePath); - EXPECT_STREQ("", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetFilename_StringPathStartsWithDoubleBackSlash_ReturnsEmptyString) - { - const char* filePath = "\\:foobar"; - string result = PathHelpers::GetFilename(filePath); - EXPECT_STREQ("", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetFilename_StringPath_ReturnsStringFilename) - { - const char* filePath = "/foo/foo/foobar"; - string result = PathHelpers::GetFilename(filePath); - EXPECT_STREQ("foobar", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetFilename_WStringPathStartsWithForwardSlash_ReturnsEmptyWString) - { - const wchar_t filePath[] = L"/:foobar"; - const wchar_t expectedResult[] = L""; - wstring result = PathHelpers::GetFilename(filePath); - EXPECT_TRUE(result == expectedResult); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, GetFilename_WStringPathStartsWithDoubleBackSlash_ReturnsEmptyWString) - { - const wchar_t filePath[] = L"\\:foobar"; - const wchar_t expectedResult[] = L""; - wstring result = PathHelpers::GetFilename(filePath); - EXPECT_TRUE(result == expectedResult); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, GetFilename_WStringPath_ReturnsWStringFilename) - { - const wchar_t filePath[] = L"/foo/foo/foobar"; - const wchar_t expectedResult[] = L"foobar"; - wstring result = PathHelpers::GetFilename(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_EmptyPath_ReturnsEmptyString) - { - const char* filePath = ""; - string result = PathHelpers::AddSeparator(filePath); - EXPECT_STREQ(filePath, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_StringPathEndsWithForwardSlash_ReturnsStringPath) - { - const char* filePath = "foo/"; - string result = PathHelpers::AddSeparator(filePath); - EXPECT_STREQ(filePath, result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_StringPathEndsWithDoubleBackSlash_ReturnsStringPath) - { - const char* filePath = "foo\\"; - string result = PathHelpers::AddSeparator(filePath); - EXPECT_STREQ(filePath, result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_StringPathEndsWithColon_ReturnsStringPath) - { - const char* filePath = "foo:"; - string result = PathHelpers::AddSeparator(filePath); - EXPECT_STREQ(filePath, result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_StringPath_ReturnsStringWithDoubleBackSlashAdded) - { - const char* filePath = "foo"; - string result = PathHelpers::AddSeparator(filePath); - EXPECT_STREQ("foo\\", result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_EmptyPath_ReturnsEmptyWString) - { - const wchar_t filePath[] = L""; - wstring result = PathHelpers::AddSeparator(filePath); - EXPECT_TRUE(result == filePath); - } - - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_WStringPathEndsWithForwardSlash_ReturnsWStringPath) - { - const wchar_t filePath[] = L"foo/"; - wstring result = PathHelpers::AddSeparator(filePath); - EXPECT_TRUE(result == filePath); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_WStringPathEndsWithDoubleBackSlash_ReturnsWStringPath) - { - const wchar_t filePath[] = L"foo\\"; - wstring result = PathHelpers::AddSeparator(filePath); - EXPECT_TRUE(result == filePath); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_WStringPathEndsWithColon_ReturnsWStringPath) - { - const wchar_t filePath[] = L"foo:"; - wstring result = PathHelpers::AddSeparator(filePath); - EXPECT_TRUE(result == filePath); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, AddSeparator_WStringPath_ReturnsWStringWithDoubleBackSlashAdded) - { - const wchar_t filePath[] = L"foo"; - const wchar_t expectedResult[] = L"foo\\"; - wstring result = PathHelpers::AddSeparator(filePath); - EXPECT_TRUE(result == expectedResult); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, RemoveSeparator_EmptyStringPath_ReturnsEmptyString) - { - const char* filePath = ""; - string result = PathHelpers::RemoveSeparator(filePath); - EXPECT_STREQ(filePath, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveSeparator_StringPathEndsWithForwardSlash_ReturnsStringWithoutForwardSlash) - { - const char* filePath = "foo/"; - string result = PathHelpers::RemoveSeparator(filePath); - EXPECT_STREQ("foo", result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, RemoveSeparator_StringPathEndsWithDoubleBackSlash_ReturnsStringWithoutDoubleBackSlash) - { - const char* filePath = "foo\\"; - string result = PathHelpers::RemoveSeparator(filePath); - EXPECT_STREQ("foo", result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, RemoveSeparator_StringPath_ReturnsStringPath) - { - const char* filePath = "foo"; - string result = PathHelpers::RemoveSeparator(filePath); - EXPECT_STREQ(filePath, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveSeparator_EmptyWStringPath_ReturnsEmptyWString) - { - const wchar_t filePath[] = L""; - wstring result = PathHelpers::RemoveSeparator(filePath); - EXPECT_TRUE(result == filePath); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveSeparator_WStringPathEndsWithForwardSlash_ReturnsWStringWithoutForwardSlash) - { - const wchar_t filePath[] = L"foo/"; - const wchar_t expectedResult[] = L"foo"; - wstring result = PathHelpers::RemoveSeparator(filePath); - EXPECT_TRUE(result == expectedResult); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, RemoveSeparator_WStringPathEndsWithDoubleBackSlash_ReturnsWStringWithoutDoubleBackSlash) - { - const wchar_t filePath[] = L"foo\\"; - const wchar_t expectedResult[] = L"foo"; - wstring result = PathHelpers::RemoveSeparator(filePath); - EXPECT_TRUE(result == expectedResult); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, RemoveSeparator_WStringPath_ReturnsWStringPath) - { - const wchar_t filePath[] = L"foo"; - wstring result = PathHelpers::RemoveSeparator(filePath); - EXPECT_TRUE(result == filePath); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveDuplicateSeparators_StringPathLengthEqualOne_ReturnsStringPath) - { - const char* filePath = "f"; - string result = PathHelpers::RemoveDuplicateSeparators(filePath); - EXPECT_STREQ(filePath, result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, RemoveDuplicateSeparators_StringPathWithDuplicateBackSlashes_ReturnsStringWithoutDoubleBackSlashes) - { - const char* filePath = "foo\\\\bar"; - string result = PathHelpers::RemoveDuplicateSeparators(filePath); - EXPECT_STREQ("foo\\bar", result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, RemoveDuplicateSeparators_StringPathWithDuplicateForwardSlashes_ReturnsStringWithoutForwardSlashes) - { - const char* filePath = "foo//bar"; - string result = PathHelpers::RemoveDuplicateSeparators(filePath); - EXPECT_STREQ("foo/bar", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, RemoveDuplicateSeparators_WStringPathLengthEqualOne_ReturnsWStringPath) - { - const wchar_t filePath[] = L"f"; - wstring result = PathHelpers::RemoveDuplicateSeparators(filePath); - EXPECT_TRUE(result == filePath); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, RemoveDuplicateSeparators_WStringPathWithDuplicateBackSlashes_ReturnsWStringWithoutDoubleBackSlashes) - { - const wchar_t filePath[] = L"foo\\\\bar"; - const wchar_t expectedResult[] = L"foo\\bar"; - wstring result = PathHelpers::RemoveDuplicateSeparators(filePath); - EXPECT_TRUE(result == expectedResult); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, RemoveDuplicateSeparators_WStringPathWithDuplicateForwardSlashes_ReturnsWStringWithoutForwardSlashes) - { - const wchar_t filePath[] = L"foo//bar"; - const wchar_t expectedResult[] = L"foo/bar"; - wstring result = PathHelpers::RemoveDuplicateSeparators(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, Join_EmptySecondStringPath_ReturnsFirstString) - { - const char* filePath1 = "foo"; - const char* filePath2 = ""; - string result = PathHelpers::Join(filePath1, filePath2); - EXPECT_STREQ(filePath1, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, Join_EmptyFirstStringPath_ReturnsSecondString) - { - const char* filePath1 = ""; - const char* filePath2 = "bar"; - string result = PathHelpers::Join(filePath1, filePath2); - EXPECT_STREQ(filePath2, result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, Join_StringPath_ReturnsStringAppendedWithDoubleBackSlashDivider) - { - const char* filePath1 = "foo"; - const char* filePath2 = "bar"; - string result = PathHelpers::Join(filePath1, filePath2); - EXPECT_STREQ("foo\\bar", result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, Join_FirstStringPathEndsWithForwardSlash_ReturnsAppendedString) - { - const char* filePath1 = "foo/"; - const char* filePath2 = "bar"; - string result = PathHelpers::Join(filePath1, filePath2); - EXPECT_STREQ("foo/bar", result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, Join_FirstStringPathEndsWithDoubleBackSlash_ReturnsAppendedString) - { - const char* filePath1 = "foo\\"; - const char* filePath2 = "bar"; - string result = PathHelpers::Join(filePath1, filePath2); - EXPECT_STREQ("foo\\bar", result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, Join_FirstStringPathEndsWithColon_ReturnsAppendedString) - { - const char* filePath1 = "foo:"; - const char* filePath2 = "bar"; - string result = PathHelpers::Join(filePath1, filePath2); - EXPECT_STREQ("foo:bar", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, Join_EmptySecondWStringPath_ReturnsFirstWString) - { - const wchar_t filePath1[] = L"foo"; - const wchar_t filePath2[] = L""; - wstring result = PathHelpers::Join(filePath1, filePath2); - EXPECT_TRUE(result == filePath1); - } - - TEST_F(CryCommonToolsPathHelpersTest, Join_EmptyFirstWStringPath_ReturnsSecondWString) - { - const wchar_t filePath1[] = L""; - const wchar_t filePath2[] = L"bar"; - wstring result = PathHelpers::Join(filePath1, filePath2); - EXPECT_TRUE(result == filePath2); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, Join_WStringPath_ReturnsWStringAppendedWithDoubleBackSlashDivider) - { - const wchar_t filePath1[] = L"foo"; - const wchar_t filePath2[] = L"bar"; - const wchar_t expectedResult[] = L"foo\\bar"; - wstring result = PathHelpers::Join(filePath1, filePath2); - EXPECT_TRUE(result == expectedResult); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, Join_FirstWStringPathEndsWithForwardSlash_ReturnsAppendedWString) - { - const wchar_t filePath1[] = L"foo/"; - const wchar_t filePath2[] = L"bar"; - const wchar_t expectedResult[] = L"foo/bar"; - wstring result = PathHelpers::Join(filePath1, filePath2); - EXPECT_TRUE(result == expectedResult); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, Join_FirstWStringPathEndsWithDoubleBackSlash_ReturnsAppendedWString) - { - const wchar_t filePath1[] = L"foo\\"; - const wchar_t filePath2[] = L"bar"; - const wchar_t expectedResult[] = L"foo\\bar"; - wstring result = PathHelpers::Join(filePath1, filePath2); - EXPECT_TRUE(result == expectedResult); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, Join_FirstWStringPathEndsWithColon_ReturnsAppendedWString) - { - const wchar_t filePath1[] = L"foo:"; - const wchar_t filePath2[] = L"bar"; - const wchar_t expectedResult[] = L"foo:bar"; - wstring result = PathHelpers::Join(filePath1, filePath2); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_EmptyStringPath_ReturnsTrue) - { - const char* filePath = ""; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_StringPath_ReturnsTrue) - { - const char* filePath = "foo"; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_StringPathBeginsWithForwardSlash_ReturnsFalse) - { - const char* filePath = "/foo"; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_FALSE(result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_StringPathBeginsWithDoubleBackSlash_ReturnsFalse) - { - const char* filePath = "\\foo"; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_FALSE (result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_StringPathBeginsWithColon_ReturnsFalse) - { - const char* filePath = ":foo"; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_EmptyWStringPath_ReturnsTrue) - { - const wchar_t filePath[] = L""; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_WStringPath_ReturnsTrue) - { - const wchar_t filePath[] = L"foo"; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_WStringPathBeginsWithForwardSlash_ReturnsFalse) - { - const wchar_t filePath[] = L"/foo"; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_FALSE(result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_WStringPathBeginsWithDoubleBackSlash_ReturnsFalse) - { - const wchar_t filePath[] = L"\\foo"; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_FALSE(result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, IsRelative_WStringPathBeginsWithColon_ReturnsFalse) - { - const wchar_t filePath[] = L":foo"; - bool result = PathHelpers::IsRelative(filePath); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsPathHelpersTest, ToUnixPath_StringPath_ReturnsStringWithForwardSlashes) - { - const char* filePath = "foo\\foo\\foo"; - string result = PathHelpers::ToUnixPath(filePath); - EXPECT_STREQ("foo/foo/foo", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, ToUnixPath_WStringPath_ReturnsWStringWithForwardSlashes) - { - const wchar_t filePath[] = L"foo\\foo\\foo"; - const wchar_t expectedResult[] = L"foo/foo/foo"; - wstring result = PathHelpers::ToUnixPath(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, ToDosPath_StringPath_ReturnsStringWithDoubleBackSlashes) - { - const char* filePath = "foo/foo/foo"; - string result = PathHelpers::ToDosPath(filePath); - EXPECT_STREQ("foo\\foo\\foo", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, ToDosPath_WStringPath_ReturnsStringWithDoubleBackSlashes) - { - const wchar_t filePath[] = L"foo/foo/foo"; - const wchar_t expectedResult[] = L"foo\\foo\\foo"; - wstring result = PathHelpers::ToDosPath(filePath); - EXPECT_TRUE(result == expectedResult); - } - - TEST_F(CryCommonToolsPathHelpersTest, GetAsciiPath_EmptyStringPath_ReturnsEmpty) - { - const char* filePath = ""; - string result = PathHelpers::GetAsciiPath(filePath); - EXPECT_STREQ(filePath, result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, GetAsciiPath_StringPath_ReturnsStringWithoutForwardSlash) - { - const char* filePath = "foo/bar/"; - string result = PathHelpers::GetAsciiPath(filePath); - EXPECT_STREQ("foo\\bar", result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - - TEST_F(CryCommonToolsPathHelpersTest, GetAsciiPath_EmptyWStringPath_ReturnsEmpty) - { - const wchar_t filePath[] = L""; - string expectedResult = ""; - string result = PathHelpers::GetAsciiPath(filePath); - EXPECT_STREQ(expectedResult, result); - } - - TEST_F(CryCommonToolsPathHelpersTest, CanonicalizePath_StringPathLengthLessThanThree_ReturnsStringWithoutForwardSlash) - { - const char* filePath = "./"; - string result = PathHelpers::CanonicalizePath(filePath); - EXPECT_STREQ(".", result); - } - - TEST_F(CryCommonToolsPathHelpersTest, CanonicalizePath_StringPathStartsWithPeriodForwardSlash_ReturnsStringWithoutPeriodAndForwardSlash) - { - const char* filePath = "./foo"; - string result = PathHelpers::CanonicalizePath(filePath); - EXPECT_STREQ("foo", result); - } - -#if AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS - TEST_F(CryCommonToolsPathHelpersTest, CanonicalizePath_StringPathStartsWithPeriodDoubleBackSlash_ReturnsStringWithoutPeriodAndDoubleBackSlash) - { - const char* filePath = ".\\foo"; - string result = PathHelpers::CanonicalizePath(filePath); - EXPECT_STREQ("foo", result); - } -#endif // AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS -} - -AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); diff --git a/Code/Tools/CryCommonTools/UnitTests/StringHelpersUnitTests.cpp b/Code/Tools/CryCommonTools/UnitTests/StringHelpersUnitTests.cpp deleted file mode 100644 index 013f077528..0000000000 --- a/Code/Tools/CryCommonTools/UnitTests/StringHelpersUnitTests.cpp +++ /dev/null @@ -1,1056 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ - -#include -#include "StringHelpers.h" -#include -#include -#include - -namespace StringHelpersTest -{ - class CryCommonToolsStringHelpersTest - : public UnitTest::AllocatorsTestFixture - { - public: - void SetUp() override - { - UnitTest::AllocatorsTestFixture::SetUp(); - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - } - - void TearDown() - { - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - UnitTest::AllocatorsTestFixture::TearDown(); - } - }; - - TEST_F(CryCommonToolsStringHelpersTest, Compare_TwoMatchingStrings_ReturnsZero) - { - const char* string1 = "foo"; - const char* string2 = "foo"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_EQ(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_SecondStringLonger_ReturnsGreaterThanZero) - { - const char* string1 = "foo"; - const char* string2 = "foobar"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_GT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_FirstStringLonger_ReturnsLessThanZero) - { - const char* string1 = "foobar"; - const char* string2 = "foo"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_LT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_FirstStringCapitalized_ReturnsGreaterThanZero) - { - const char* string1 = "FOO"; - const char* string2 = "foo"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_GT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_SecondStringCapitalized_ReturnsLessThanZero) - { - const char* string1 = "foo"; - const char* string2 = "FOO"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_LT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_TwoMatchingWStrings_ReturnsZero) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"foo"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_EQ(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_SecondWStringLonger_ReturnsGreaterThanZero) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"foobar"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_GT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_FirstWStringLonger_ReturnsLessThanZero) - { - const wchar_t string1[] = L"foobar"; - const wchar_t string2[] = L"foo"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_LT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_FirstWStringCapitalized_ReturnsGreaterThanZero) - { - const wchar_t string1[] = L"FOO"; - const wchar_t string2[] = L"foo"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_GT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Compare_SecondWStringCapitalized_ReturnsLessThanZero) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"FOO"; - int result = StringHelpers::Compare(string1, string2); - EXPECT_LT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_TwoMatchingStrings_ReturnsZero) - { - const char* string1 = "foo"; - const char* string2 = "foo"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_EQ(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_FirstStringCapitalized_ReturnsZero) - { - const char* string1 = "FOO"; - const char* string2 = "foo"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_EQ(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_SecondStringCapitalized_ReturnsZero) - { - const char* string1 = "foo"; - const char* string2 = "FOO"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_EQ(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_SecondStringLonger_ReturnsGreaterThanZero) - { - const char* string1 = "foo"; - const char* string2 = "foobar"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_GT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_FirstStringLonger_ReturnsLessThanZero) - { - const char* string1 = "foobar"; - const char* string2 = "foo"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_LT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_TwoMatchingWStrings_ReturnsZero) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"foo"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_EQ(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_FirstWStringCapitalized_ReturnsZero) - { - const wchar_t string1[] = L"FOO"; - const wchar_t string2[] = L"foo"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_EQ(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_SecondWStringCapitalized_ReturnsZero) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"FOO"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_EQ(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_SecondWStringLonger_ReturnsGreaterThanZero) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"foobar"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_GT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, CompareIgnoreCase_FirstWStringLonger_ReturnsLessThanZero) - { - const wchar_t string1[] = L"foobar"; - const wchar_t string2[] = L"foo"; - int result = StringHelpers::CompareIgnoreCase(string1, string2); - EXPECT_LT(0, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Equals_SameTwoStrings_ReturnsTrue) - { - const char* string1 = "foo"; - const char* string2 = "foo"; - bool result = StringHelpers::Equals(string1, string2); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Equals_SecondStringUpperCase_ReturnsFalse) - { - const char* string1 = "foo"; - const char* string2 = "FOO"; - bool result = StringHelpers::Equals(string1, string2); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Equals_FirstStringUpperCase_ReturnsFalse) - { - const char* string1 = "FOO"; - const char* string2 = "foo"; - bool result = StringHelpers::Equals(string1, string2); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Equals_DifferentStrings_ReturnsFalse) - { - const char* string1 = "foo"; - const char* string2 = "foobar"; - bool result = StringHelpers::Equals(string1, string2); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Equals_SameTwoWStrings_ReturnsTrue) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"foo"; - bool result = StringHelpers::Equals(string1, string2); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Equals_SecondWStringUpperCase_ReturnsFalse) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"FOO"; - bool result = StringHelpers::Equals(string1, string2); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Equals_FirstWStringUpperCase_ReturnsFalse) - { - const wchar_t string1[] = L"FOO"; - const wchar_t string2[] = L"foo"; - bool result = StringHelpers::Equals(string1, string2); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Equals_DifferentWStrings_ReturnsFalse) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"foobar"; - bool result = StringHelpers::Equals(string1, string2); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EqualsIgnoreCase_SameTwoStrings_ReturnsTrue) - { - const char* string1 = "foo"; - const char* string2 = "foo"; - bool result = StringHelpers::EqualsIgnoreCase(string1, string2); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EqualsIgnoreCase_SecondStringUpperCase_ReturnsFalse) - { - const char* string1 = "foo"; - const char* string2 = "FOO"; - bool result = StringHelpers::EqualsIgnoreCase(string1, string2); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EqualsIgnoreCase_FirstStringUpperCase_ReturnsFalse) - { - const char* string1 = "FOO"; - const char* string2 = "foo"; - bool result = StringHelpers::EqualsIgnoreCase(string1, string2); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EqualsIgnoreCase_DifferentStrings_ReturnsFalse) - { - const char* string1 = "foo"; - const char* string2 = "foobar"; - bool result = StringHelpers::EqualsIgnoreCase(string1, string2); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EqualsIgnoreCase_SameTwoWStrings_ReturnsTrue) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"foo"; - bool result = StringHelpers::EqualsIgnoreCase(string1, string2); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EqualsIgnoreCase_SecondWStringUpperCase_ReturnsFalse) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"FOO"; - bool result = StringHelpers::EqualsIgnoreCase(string1, string2); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EqualsIgnoreCase_FirstWStringUpperCase_ReturnsFalse) - { - const wchar_t string1[] = L"FOO"; - const wchar_t string2[] = L"foo"; - bool result = StringHelpers::EqualsIgnoreCase(string1, string2); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EqualsIgnoreCase_DifferentWStrings_ReturnsFalse) - { - const wchar_t string1[] = L"foo"; - const wchar_t string2[] = L"foobar"; - bool result = StringHelpers::EqualsIgnoreCase(string1, string2); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_StringPathsWithLongerPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "foobar"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_StringPathAndPattern_ReturnsTrue) - { - const char* string = "foobar"; - const char* pattern = "foo"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_StringPathCapitalized_ReturnsFalse) - { - const char* string = "FOOBAR"; - const char* pattern = "foo"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_PatternStringCapitalized_ReturnsFalse) - { - const char* string = "foobar"; - const char* pattern = "FOO"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_StringPathAndNoMatchingPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "bar"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_WStringPathsWithLongerPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"foobar"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_WStringPathAndPattern_ReturnsTrue) - { - const wchar_t string[] = L"foobar"; - const wchar_t pattern[] = L"foo"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_WStringPathCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"FOOBAR"; - const wchar_t pattern[] = L"foo"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_PatternWstringCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"foobar"; - const wchar_t pattern[] = L"FOO"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWith_WStringPathAndNoMatchingPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::StartsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_StringPathsWithLongerPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "foobar"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_StringPathAndPattern_ReturnsTrue) - { - const char* string = "foobar"; - const char* pattern = "foo"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_StringPathCapitalized_ReturnsFalse) - { - const char* string = "FOOBAR"; - const char* pattern = "foo"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_PatternStringCapitalized_ReturnsFalse) - { - const char* string = "foobar"; - const char* pattern = "FOO"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_StringPathAndNoMatchingPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "bar"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_WStringPathsWithLongerPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"foobar"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_WStringPathAndPattern_ReturnsTrue) - { - const wchar_t string[] = L"foobar"; - const wchar_t pattern[] = L"foo"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_WStringPathCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"FOOBAR"; - const wchar_t pattern[] = L"foo"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_PatternWStringCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"foobar"; - const wchar_t pattern[] = L"FOO"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, StartsWithIgnoreCase_WStringPathAndNoMatchingPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::StartsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_StringPathWithLongerPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "foobar"; - bool result = StringHelpers::EndsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_StringPathAndPattern_ReturnsTrue) - { - const char* string = "foobar"; - const char* pattern = "bar"; - bool result = StringHelpers::EndsWith(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_StringPathCapitalized_ReturnsFalse) - { - const char* string = "FOOBAR"; - const char* pattern = "bar"; - bool result = StringHelpers::EndsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_PatternStringCapitalized_ReturnsFalse) - { - const char* string = "foobar"; - const char* pattern = "BAR"; - bool result = StringHelpers::EndsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_StringPathAndNoMatchingPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "bar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_WStringPathWithLongerPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"foobar"; - bool result = StringHelpers::EndsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_WStringPathAndPattern_ReturnsTrue) - { - const wchar_t string[] = L"foobar"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::EndsWith(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_WStringPathCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"FOOBAR"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::EndsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_PatternWStringCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"foobar"; - const wchar_t pattern[] = L"BAR"; - bool result = StringHelpers::EndsWith(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWith_WStringPathAndNoMatchingPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_StringPathWithLongerPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "foobar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_StringPathAndPattern_ReturnsTrue) - { - const char* string = "foobar"; - const char* pattern = "bar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_StringPathCapitalized_ReturnsTrue) - { - const char* string = "FOOBAR"; - const char* pattern = "bar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_PatternStringCapitalized_ReturnsTrue) - { - const char* string = "foobar"; - const char* pattern = "BAR"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_StringPathAndNoMatchingPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "bar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_WStringPathWithLongerPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"foobar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_WStringPathAndPattern_ReturnsTrue) - { - const wchar_t string[] = L"foobar"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_WStringPathCapitalized_ReturnsTrue) - { - const wchar_t string[] = L"FOOBAR"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_PatternWStringCapitalized_ReturnsTrue) - { - const wchar_t string[] = L"foobar"; - const wchar_t pattern[] = L"BAR"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, EndsWithIgnoreCase_WStringPathAndNoMatchingPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::EndsWithIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_StringPathWithLongerPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "barbar"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_StringPathAndPattern_ReturnsTrue) - { - const char* string = "foobarfoo"; - const char* pattern = "bar"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_PatternStringCapitalized_ReturnsFalse) - { - const char* string = "foobarfoo"; - const char* pattern = "BAR"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_StringPathCapitalized_ReturnsFalse) - { - const char* string = "FOOBARFOO"; - const char* pattern = "bar"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_StringPathNoMatchingPattern_ReturnsFalse) - { - const char* string = "foofoofoo"; - const char* pattern = "bar"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_WStringPathWithLongerPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"barbar"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_WStringPathAndPattern_ReturnsTrue) - { - const wchar_t string[] = L"foobarfoo"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_PatternWStringCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"foobarfoo"; - const wchar_t pattern[] = L"BAR"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_WStringPathCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"FOOBARFOO"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Contains_WStringPathNoMatchingPattern_ReturnsFalse) - { - const wchar_t string[] = L"foofoofoo"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::Contains(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_StringPathWithLongerPattern_ReturnsFalse) - { - const char* string = "foo"; - const char* pattern = "barbar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_StringPathAndPattern_ReturnsTrue) - { - const char* string = "foobarfoo"; - const char* pattern = "bar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_PatternStringCapitalized_ReturnsTrue) - { - const char* string = "foobarfoo"; - const char* pattern = "BAR"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_StringPathCapitalized_ReturnsTrue) - { - const char* string = "FOOBARFOO"; - const char* pattern = "bar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_StringPathNoMatchingPattern_ReturnsFalse) - { - const char* string = "foofoofoo"; - const char* pattern = "bar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_WStringPathWithLongerPattern_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t pattern[] = L"barbar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_WStringPathAndPattern_ReturnsTrue) - { - const wchar_t string[] = L"foobarfoo"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_WStringPathAndPattern2_ReturnsTrue) - { - const wchar_t string[] = L"foobfobaro"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_PatternWStringCapitalized_ReturnsTrue) - { - const wchar_t string[] = L"foobarfoo"; - const wchar_t pattern[] = L"BAR"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_WStringPathCapitalized_ReturnsTrue) - { - const wchar_t string[] = L"FOOBARFOO"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, ContainsIgnoreCase_WStringPathNoMatchingPattern_ReturnsFalse) - { - const wchar_t string[] = L"foofoofoo"; - const wchar_t pattern[] = L"bar"; - bool result = StringHelpers::ContainsIgnoreCase(string, pattern); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_StringMatchingPattern_ReturnsTrue) - { - const char* string = "foo"; - const char* wildcard = "f*o"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_PatternStringCapitalized_ReturnsFalse) - { - const char* string = "foo"; - const char* wildcard = "F*O"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_StringCapitalized_ReturnsFalse) - { - const char* string = "FOO"; - const char* wildcard = "f*o"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_StringNoMatchingPatternWithAsterisk_ReturnsFalse) - { - const char* string = "foo"; - const char* wildcard = "f*r"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_StringNoMatchingPattern_ReturnsFalse) - { - const char* string = "foobar"; - const char* wildcard = "foo"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_WStringMatchingPattern_ReturnsTrue) - { - const wchar_t string[] = L"foo"; - const wchar_t wildcard[] = L"f*o"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_WPatternStringCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t wildcard[] = L"F*O"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_WStringCapitalized_ReturnsFalse) - { - const wchar_t string[] = L"FOO"; - const wchar_t wildcard[] = L"f*o"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_WStringNoMatchingPatternWithAsterisk_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t wildcard[] = L"f*r"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcards_WStringNoMatchingPattern_ReturnsFalse) - { - const wchar_t string[] = L"foobar"; - const wchar_t wildcard[] = L"foo"; - bool result = StringHelpers::MatchesWildcards(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_StringMatchingPattern_ReturnsTrue) - { - const char* string = "foo"; - const char* wildcard = "f*o"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_PatternStringCapitalized_ReturnsTrue) - { - const char* string = "foo"; - const char* wildcard = "F*O"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_StringCapitalized_ReturnsTrue) - { - const char* string = "FOO"; - const char* wildcard = "f*o"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_StringNoMatchingPatternWithAsterisk_ReturnsFalse) - { - const char* string = "foo"; - const char* wildcard = "f*r"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_StringNoMatchingPattern_ReturnsFalse) - { - const char* string = "foobar"; - const char* wildcard = "foo"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_WStringMatchingPattern_ReturnsTrue) - { - const wchar_t string[] = L"foo"; - const wchar_t wildcard[] = L"f*o"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_PatternWStringCapitalized_ReturnsTrue) - { - const wchar_t string[] = L"foo"; - const wchar_t wildcard[] = L"F*O"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_WStringCapitalized_ReturnsTrue) - { - const wchar_t string[] = L"FOO"; - const wchar_t wildcard[] = L"f*o"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_TRUE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_WStringNoMatchingPatternWithAsterisk_ReturnsFalse) - { - const wchar_t string[] = L"foo"; - const wchar_t wildcard[] = L"f*r"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MatchesWildcardsIgnoreCase_WStringNoMatchingPattern_ReturnsFalse) - { - const wchar_t string[] = L"foobar"; - const wchar_t wildcard[] = L"foo"; - bool result = StringHelpers::MatchesWildcardsIgnoreCase(string, wildcard); - EXPECT_FALSE(result); - } - - TEST_F(CryCommonToolsStringHelpersTest, TrimLeft_StringWithoutReturnOrTab_ReturnsString) - { - const char* stringInput = "foo"; - string result = StringHelpers::TrimLeft(stringInput); - EXPECT_STREQ(stringInput, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, TrimRight_StringWithoutReturnOrTab_ReturnsString) - { - const char* stringInput = "foo"; - string result = StringHelpers::TrimRight(stringInput); - EXPECT_STREQ(stringInput, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MakeLowerCase_UpperCaseString_ReturnsLowerCaseString) - { - const char* stringInput = "FOO"; - string result = StringHelpers::MakeLowerCase(stringInput); - EXPECT_STREQ("foo", result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MakeLowerCase_UpperCaseWString_ReturnsLowerCaseString) - { - const wchar_t stringInput[] = L"FOO"; - const wchar_t expectedString[] = L"foo"; - wstring result = StringHelpers::MakeLowerCase(stringInput); - EXPECT_TRUE(result == expectedString); - } - - TEST_F(CryCommonToolsStringHelpersTest, MakeUpperCase_LowerCaseString_ReturnsUpperCaseString) - { - const char* stringInput = "foo"; - string result = StringHelpers::MakeUpperCase(stringInput); - EXPECT_STREQ("FOO", result); - } - - TEST_F(CryCommonToolsStringHelpersTest, MakeUpperCase_LowerCaseWString_ReturnsUpperCaseString) - { - const wchar_t stringInput[] = L"foo"; - const wchar_t expectedString[] = L"FOO"; - wstring result = StringHelpers::MakeUpperCase(stringInput); - EXPECT_TRUE(result == expectedString); - } - - TEST_F(CryCommonToolsStringHelpersTest, Replace_CharacterToReplace_ReturnsStringWithReplacedCharacters) - { - const char* stringInput = "foo"; - char oldChar = 'o'; - char newChar = 'i'; - string result = StringHelpers::Replace(stringInput, oldChar, newChar); - EXPECT_STREQ("fii", result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Replace_CharacterToReplace_ReturnsWStringWithReplacedCharacters) - { - const wchar_t stringInput[] = L"foo"; - wchar_t oldChar = 'o'; - wchar_t newChar = 'i'; - const wchar_t expectedString[] = L"fii"; - wstring result = StringHelpers::Replace(stringInput, oldChar, newChar); - EXPECT_TRUE(result == expectedString); - } - - TEST_F(CryCommonToolsStringHelpersTest, Replace_CharacterToReplaceNotInString_ReturnsOriginalString) - { - const char* stringInput = "foo"; - char oldChar = 'a'; - char newChar = 'i'; - string result = StringHelpers::Replace(stringInput, oldChar, newChar); - EXPECT_STREQ(stringInput, result); - } - - TEST_F(CryCommonToolsStringHelpersTest, Replace_CharacterToReplaceNotInWString_ReturnsOriginalWString) - { - const wchar_t stringInput[] = L"foo"; - wchar_t oldChar = 'a'; - wchar_t newChar = 'i'; - wstring result = StringHelpers::Replace(stringInput, oldChar, newChar); - EXPECT_TRUE(result == stringInput); - } -} diff --git a/Code/Tools/CryCommonTools/WeightFilterSet.cpp b/Code/Tools/CryCommonTools/WeightFilterSet.cpp deleted file mode 100644 index dfc5ff24d0..0000000000 --- a/Code/Tools/CryCommonTools/WeightFilterSet.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include // assert() -#include "WeightFilterSet.h" // CWeightFilterSet - - - -void CWeightFilterSet::FreeData() -{ - m_FilterKernelBlock.FreeData(); -} - - -bool CWeightFilterSet::Create(const unsigned long indwSideLength, const CSummedAreaFilterKernel& inFilter, const float infR) -{ - assert(indwSideLength >= 1); - - FreeData(); - - // 32 Baustelle - inFilter.CreateWeightFilterBlock(m_FilterKernelBlock, 1, infR * indwSideLength); - return(true); -} - diff --git a/Code/Tools/CryCommonTools/WeightFilterSet.h b/Code/Tools/CryCommonTools/WeightFilterSet.h deleted file mode 100644 index 16c8c79acd..0000000000 --- a/Code/Tools/CryCommonTools/WeightFilterSet.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_WEIGHTFILTERSET_H -#define CRYINCLUDE_CRYCOMMONTOOLS_WEIGHTFILTERSET_H - - -#include "SimpleBitmap.h" // SimpleBitmap<> -#include // STL vector<> -#include "SummedAreaFilterKernel.h" // CSummedAreaFilterKernel - -class CWeightFilterSet -{ -public: - - //! /param indwSideLength [1,..[ e.g. 3 for 3x3 block - bool Create(const unsigned long indwSideLength, const CSummedAreaFilterKernel& inFilter, const float infR); - - //! - void FreeData(); - - //! optimizable - //! weight is 1.0 - //! /param iniX x position in inoutDest - //! /param iniY y position in inoutDest - //! /param TInputImage typically CSimpleBitmap - //! /return weight - template - float GetBlockWithFilter(const TInputImage& inSrc, const int iniX, const int iniY, TElement& outResult) - { - float fWeightSum = 0.0f; - CSimpleBitmap& rBitmap = m_FilterKernelBlock; - - int W = (int)rBitmap.GetWidth(); - int H = (int)rBitmap.GetHeight(); - - int iSrcW = (int)inSrc.GetWidth(); - int iSrcH = (int)inSrc.GetHeight(); - - float* pfWeights = rBitmap.GetPointer(0, 0); - - for (int y = 0; y < H; y++) - { - int iDestY = y + iniY - H / 2; - - // optimizable (don't use the bottom border) - // if(iDestY==iSrcH){ pfWeights+=H;continue; } - - for (int x = 0; x < W; x++, pfWeights++) - { - int iDestX = x + iniX - W / 2; - - // optimizable (don't use the right border) - // if(iDestX==iSrcW) - // continue; - - TElement Value; - - // if(inSrc.Get(iDestX,iDestY,Value)) - if (inSrc.Get((iDestX + iSrcW * 2) % iSrcW, (iDestY + iSrcH * 2) % iSrcH, Value)) // tiled - { - float fWeight = *pfWeights; - - outResult += Value * fWeight; - fWeightSum += fWeight; - } - } - } - - return fWeightSum; - } - - int GetBorderSize() - { - int W = (int)m_FilterKernelBlock.GetWidth(); - - return (W - 1) / 2; - } - -private: // ------------------------------------------------------------- - - CSimpleBitmap m_FilterKernelBlock; //!< weight = 1 -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_WEIGHTFILTERSET_H diff --git a/Code/Tools/CryCommonTools/XMLPakFileSink.cpp b/Code/Tools/CryCommonTools/XMLPakFileSink.cpp deleted file mode 100644 index 9a9590687f..0000000000 --- a/Code/Tools/CryCommonTools/XMLPakFileSink.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "XMLPakFileSink.h" -#include "StringHelpers.h" - -XMLPakFileSink::XMLPakFileSink(IPakSystem* pakSystem, const string& archivePath, const string& filePath) - : pakSystem(pakSystem) - , filePath(filePath) -{ - archive = pakSystem->OpenArchive(archivePath.c_str()); -} - -XMLPakFileSink::~XMLPakFileSink() -{ - if (archive && pakSystem) - { - SYSTEMTIME st; - GetSystemTime(&st); - - FILETIME ft; - ZeroStruct(ft); - const BOOL ok = SystemTimeToFileTime(&st, &ft); - - LARGE_INTEGER lt; - lt.HighPart = ft.dwHighDateTime; - lt.LowPart = ft.dwLowDateTime; - - const __int64 modTime = lt.QuadPart; - ; - - pakSystem->AddToArchive(archive, filePath.c_str(), &data[0], int(data.size()), modTime); - pakSystem->CloseArchive(archive); - } -} - -void XMLPakFileSink::Write(const char* text) -{ - string asciiText = text; - int len = int(asciiText.size()); - int start = int(data.size()); - data.resize(data.size() + len); - memcpy(&data[start], asciiText.c_str(), len); -} diff --git a/Code/Tools/CryCommonTools/XMLPakFileSink.h b/Code/Tools/CryCommonTools/XMLPakFileSink.h deleted file mode 100644 index 973f9a05ca..0000000000 --- a/Code/Tools/CryCommonTools/XMLPakFileSink.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_XMLPAKFILESINK_H -#define CRYINCLUDE_CRYCOMMONTOOLS_XMLPAKFILESINK_H -#pragma once - - -#include "XMLWriter.h" -#include "IPakSystem.h" - -class XMLPakFileSink - : public IXMLSink -{ -public: - XMLPakFileSink(IPakSystem* pakSystem, const string& archivePath, const string& filePath); - ~XMLPakFileSink(); - - // IXMLSink - virtual void Write(const char* text); - -private: - IPakSystem* pakSystem; - PakSystemArchive* archive; - string filePath; - std::vector data; -}; - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_XMLPAKFILESINK_H diff --git a/Code/Tools/CryCommonTools/XMLWriter.cpp b/Code/Tools/CryCommonTools/XMLWriter.cpp deleted file mode 100644 index bfaf9df429..0000000000 --- a/Code/Tools/CryCommonTools/XMLWriter.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "XMLWriter.h" -#include "StringHelpers.h" -#include - -XMLWriter::XMLWriter(IXMLSink* sink) -{ - m_indentationSize = -1; - m_sink = sink; - - WriteText("\n"); -} - -void XMLWriter::BeginElement(const string& name) -{ - // Write the indentation. - if (m_newLine) - { - for (int i = 0; i < m_indentationSize; ++i) - { - WriteText(" "); - } - } - - WriteText("<%s", name.c_str()); - m_newLine = false; -} - -void XMLWriter::EndElement(const string& name) -{ - // Write the indentation. - if (m_newLine) - { - for (int i = 0; i < m_indentationSize; ++i) - { - WriteText(" "); - } - } - - WriteText("\n", name.c_str()); - m_newLine = true; -} - -void XMLWriter::CloseElement(const string& name, bool newLine) -{ - if (newLine) - { - WriteText(">\n"); - } - else - { - WriteText(">"); - } - m_newLine = newLine; -} - -void XMLWriter::CloseLeafElement(const string& name) -{ - WriteText(" />\n"); - m_newLine = true; -} - -void XMLWriter::IncreaseIndentation() -{ - ++m_indentationSize; -} - -void XMLWriter::DecreaseIndentation() -{ - --m_indentationSize; -} - -void XMLWriter::WriteAttribute(const string& name, const string& value) -{ - WriteText(" %s=\"%s\"", name.c_str(), value.c_str()); -} - -void XMLWriter::SerializeAttribute(char* buffer, size_t bufferSize, const string& value) -{ - // TODO: Escape string. - strcpy_s(buffer, bufferSize, value.c_str()); -} - -void XMLWriter::SerializeAttribute(char* buffer, size_t bufferSize, float value) -{ - sprintf_s(buffer, bufferSize, "%.10e", value); -} - -void XMLWriter::SerializeAttribute(char* buffer, size_t bufferSize, int value) -{ - sprintf_s(buffer, bufferSize, "%d", value); -} - -void XMLWriter::SerializeArrayElement(char* buffer, size_t bufferSize, float value) -{ - sprintf_s(buffer, bufferSize, "%.10e", value); -} - -void XMLWriter::SerializeArrayElement(char* buffer, size_t bufferSize, const string& value) -{ - strcpy(buffer, value.c_str()); -} - -void XMLWriter::SerializeArrayElement(char* buffer, size_t bufferSize, int value) -{ - sprintf_s(buffer, bufferSize, "%d", value); -} - -void XMLWriter::WriteContent(const string& text) -{ - WriteText("%s", text.c_str()); -} - -void XMLWriter::WriteContentLine(const string& text) -{ - // Write the indentation. - if (m_newLine) - { - for (int i = 0; i < m_indentationSize; ++i) - { - WriteText(" "); - } - } - - WriteText("%s\n", text.c_str()); - m_newLine = true; -} - -void XMLWriter::WriteText(const char* format, ...) -{ - va_list args; - va_start(args, format); - char buffer[40000]; - azvsnprintf(buffer, sizeof(buffer), format, args); - m_sink->Write(buffer); - va_end(args); -} - -XMLWriter::Element::Element(XMLWriter& writer, const string& name, bool output) - : m_writer(writer) - , m_name(name) - , m_output(output) - , isParent(false) -{ - if (!m_writer.m_elements.empty()) - { - Element* parent = m_writer.m_elements.back(); - if (!parent->isParent) - { - parent->isParent = true; - if (parent->m_output) - { - m_writer.CloseElement(m_name, true); - } - } - } - m_writer.m_elements.push_back(this); - if (m_output) - { - m_writer.IncreaseIndentation(); - } - if (m_output) - { - m_writer.BeginElement(m_name); - } -} - -XMLWriter::Element::~Element() -{ - if (m_output) - { - if (isParent) - { - m_writer.EndElement(m_name); - } - else - { - m_writer.CloseLeafElement(m_name); - } - } - m_writer.m_elements.pop_back(); - if (m_output) - { - m_writer.DecreaseIndentation(); - } -} - -void XMLWriter::Element::Child(const string& name, const string& value) -{ - Element child(m_writer, name); - child.Content(value); -} - -void XMLWriter::Element::Content(const string& text) -{ - if (m_output) - { - assert(!isParent); - if (!isParent) - { - isParent = true; - m_writer.CloseElement(m_name, false); - } - m_writer.WriteContent(text); - } -} - -void XMLWriter::Element::ContentLine(const string& text) -{ - if (!isParent) - { - isParent = true; - if (m_output) - { - m_writer.CloseElement(m_name, true); - } - } - if (m_output) - { - m_writer.WriteContentLine(text); - } -} - -XMLFileSink::XMLFileSink(const string& filename) -{ - m_file = std::fopen(filename.c_str(), "w"); - if (!m_file) - { - throw OpenFailedError("Unable to open file."); - } -} - -XMLFileSink::~XMLFileSink() -{ - if (m_file) - { - fclose(m_file); - } -} - -void XMLFileSink::Write(const char* text) -{ - if (m_file) - { - string asciiText = StringHelpers::ConvertString(text); - fwrite(asciiText.c_str(), 1, asciiText.size(), m_file); - } -} diff --git a/Code/Tools/CryCommonTools/XMLWriter.h b/Code/Tools/CryCommonTools/XMLWriter.h deleted file mode 100644 index d98b9f3d56..0000000000 --- a/Code/Tools/CryCommonTools/XMLWriter.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_XMLWRITER_H -#define CRYINCLUDE_CRYCOMMONTOOLS_XMLWRITER_H -#pragma once - - -#include "Exceptions.h" - -#include -#include -#include - -class IXMLSink -{ -public: - // Define an exception type to throw when file opening fails. - struct OpenFailedErrorTag {}; - typedef Exception OpenFailedError; - - virtual void Write(const char* text) = 0; -}; - -class XMLFileSink - : public IXMLSink -{ -public: - XMLFileSink(const string& name); - ~XMLFileSink(); - - virtual void Write(const char* text); - -private: - FILE* m_file; -}; - -class XMLWriter -{ -public: - XMLWriter(IXMLSink* sink); - - class Element - { - public: - Element(XMLWriter& writer, const string& name, bool output = true); - ~Element(); - - template - void Attribute(const string& name, const T& value); - void Child(const string& name, const string& value); - void Content(const string& text); - void ContentLine(const string& text); - template - void ContentArrayElement(const T& value); - void ContentArrayFloat24(const float floatBuffer[24], const int entryCount); - - void WriteDirectText(const char* text) - { - if (!isParent) - { - isParent = true; - if (m_output) - { - m_writer.CloseElement(m_name, false); - } - } - m_writer.WriteDirectText(text); - } - - private: - XMLWriter& m_writer; - string m_name; - bool isParent; - bool m_output; - }; - - void WriteDirectText(const char* text) - { - m_sink->Write(text); - } - -private: - void IncreaseIndentation(); - void DecreaseIndentation(); - - void BeginElement(const string& name); - void EndElement(const string& name); - void CloseElement(const string& name, bool newLine); - void CloseLeafElement(const string& name); - - void WriteAttribute(const string& name, const string& value); - static void SerializeAttribute(char* buffer, size_t bufferSize, const string& value); - static void SerializeAttribute(char* buffer, size_t bufferSize, float value); - static void SerializeAttribute(char* buffer, size_t bufferSize, int value); - static void SerializeArrayElement(char* buffer, size_t bufferSize, float value); - static void SerializeArrayElement(char* buffer, size_t bufferSize, const string& value); - static void SerializeArrayElement(char* buffer, size_t bufferSize, int value); - void WriteContent(const string& text); - void WriteContentLine(const string& text); - - void WriteText(const char* format, ...); - - IXMLSink* m_sink; - int m_indentationSize; - - std::vector m_elements; - bool m_newLine; -}; - -template -void XMLWriter::Element::Attribute(const string& name, const T& value) -{ - assert(!isParent); - char buffer[1024]; - XMLWriter::SerializeAttribute(buffer, sizeof(buffer), value); - if (m_output) - { - m_writer.WriteAttribute(name, buffer); - } -} - -template -void XMLWriter::Element::ContentArrayElement(const T& value) -{ - if (!m_output) - { - return; - } - - if (!isParent) - { - isParent = true; - m_writer.CloseElement(m_name, false); - } - - char buffer[1024] = {' ', 0}; - XMLWriter::SerializeArrayElement(buffer + 1, sizeof(buffer) - 1, value); - - m_writer.WriteDirectText(buffer); -} - -inline void XMLWriter::Element::ContentArrayFloat24(const float floatBuffer[24], const int entryCount) -{ - if (!m_output) - { - return; - } - if (!isParent) - { - isParent = true; - m_writer.CloseElement(m_name, false); - } - - char buffer[2048]; - if (entryCount == 24) - { - sprintf_s(buffer, " %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e", - floatBuffer[0], floatBuffer[1], floatBuffer[2], floatBuffer[3], floatBuffer[4], floatBuffer[5], floatBuffer[6], floatBuffer[7], - floatBuffer[8], floatBuffer[9], floatBuffer[10], floatBuffer[11], floatBuffer[12], floatBuffer[13], floatBuffer[14], floatBuffer[15], - floatBuffer[16], floatBuffer[17], floatBuffer[18], floatBuffer[19], floatBuffer[20], floatBuffer[21], floatBuffer[22], floatBuffer[23]); - m_writer.WriteDirectText(buffer); - } - else - { - for (int i = 0; i < entryCount; i++) - { - char buffer[1024]; - sprintf_s(buffer, " %.10e", floatBuffer[i]); - m_writer.WriteDirectText(buffer); - } - } -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_XMLWRITER_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDir.h b/Code/Tools/CryCommonTools/ZipDir/ZipDir.h deleted file mode 100644 index c9954ce5dc..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDir.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIR_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIR_H -#pragma once - -#include "smartptr.h" -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include "smartptr.h" -#include "ZipDirTree.h" -#include "ZipDirList.h" -#include "ZipDirCache.h" -#include "ZipDirCacheRW.h" -#include "ZipDirCacheFactory.h" -#include "ZipDirFind.h" -#include "ZipDirFindRW.h" - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIR_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirCache.cpp b/Code/Tools/CryCommonTools/ZipDir/ZipDirCache.cpp deleted file mode 100644 index 1f5d4a9286..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirCache.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include -#include "FileUtil.h" -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include "ZipDirTree.h" -#include "ZipDirCache.h" -#include "ZipDirFind.h" -#include "ZipDirCacheFactory.h" -#include -#include -#include "PathHelpers.h" -#include - -using namespace ZipFile; - -// initializes the instance structure -void ZipDir::Cache::Construct(FILE* fNew, size_t nDataSizeIn, const EncryptionKey& key) -{ - m_nRefCount = 0; - m_pFile = fNew; - m_nDataSize = nDataSizeIn; - m_nZipPathOffset = nDataSizeIn; - m_bEncryptHeaders = false; - m_encryptionKey = key; -} - -// self-destruct when ref count drops to 0 -void ZipDir::Cache::Delete() -{ - if (m_pFile) - { - fclose (m_pFile); - } - free(this); -} - -// looks for the given file record in the Central Directory. If there's none, returns NULL. -// if there is some, returns the pointer to it. -// the Path must be the relative path to the file inside the Zip -// if the file handle is passed, it will be used to find the file data offset, if one hasn't been initialized yet -ZipDir::FileEntry* ZipDir::Cache::FindFile (const char* szPath, [[maybe_unused]] bool bRefresh) -{ - ZipDir::FindFile fd (this); - if (!fd.FindExact(szPath)) - { - assert (!fd.GetFileEntry()); - return NULL; - } - assert (fd.GetFileEntry()); - return fd.GetFileEntry(); -} - -// loads the given file into the pCompressed buffer (the actual compressed data) -// if the pUncompressed buffer is supplied, uncompresses the data there -// buffers must have enough memory allocated, according to the info in the FileEntry -// NOTE: there's no need to decompress if the method is 0 (store) -// returns 0 if successful or error code if couldn't do something -ZipDir::ErrorEnum ZipDir::Cache::ReadFile (FileEntry* pFileEntry, void* pCompressed, void* pUncompressed) -{ - if (!pFileEntry) - { - return ZD_ERROR_INVALID_CALL; - } - - if (pFileEntry->desc.lSizeUncompressed == 0) - { - assert (pFileEntry->desc.lSizeCompressed == 0); - return ZD_ERROR_SUCCESS; - } - - assert (pFileEntry->desc.lSizeCompressed > 0); - - ErrorEnum nError = Refresh(pFileEntry); - if (nError != ZD_ERROR_SUCCESS) - { - return nError; - } - - if (AZ_TRAIT_CRYCOMMONTOOLS_FSEEK(m_pFile, pFileEntry->nFileDataOffset, SEEK_SET)) - { - return ZD_ERROR_IO_FAILED; - } - - SmartPtr pBufferDestroyer; - - void* pBuffer = pCompressed; // the buffer where the compressed data will go - - if (pFileEntry->nMethod == 0 && pUncompressed) - { - // we can directly read into the uncompress buffer - pBuffer = pUncompressed; - } - - if (!pBuffer) - { - if (!pUncompressed) - { - // what's the sense of it - no buffers at all? - return ZD_ERROR_INVALID_CALL; - } - - pBuffer = malloc(pFileEntry->desc.lSizeCompressed); - pBufferDestroyer.Attach(pBuffer); // we want it auto-freed once we return - } - - - if (fread (pBuffer, pFileEntry->desc.lSizeCompressed, 1, m_pFile) != 1) - { - return ZD_ERROR_IO_FAILED; - } - - if (pFileEntry->nMethod == METHOD_DEFLATE_AND_ENCRYPT) - { - ZipDir::Decrypt((char*)pBuffer, pFileEntry->desc.lSizeCompressed, m_encryptionKey); - } - - // if there's a buffer for uncompressed data, uncompress it to that buffer - if (pUncompressed) - { - if (pFileEntry->nMethod == 0) - { - assert (pBuffer == pUncompressed); - //assert (pFileEntry->desc.lSizeCompressed == pFileEntry->nSizeUncompressed); - //memcpy (pUncompressed, pBuffer, pFileEntry->desc.lSizeCompressed); - } - else - { - unsigned long nSizeUncompressed = pFileEntry->desc.lSizeUncompressed; - if (Z_OK != ZipRawUncompress(pUncompressed, &nSizeUncompressed, pBuffer, pFileEntry->desc.lSizeCompressed)) - { - return ZD_ERROR_CORRUPTED_DATA; - } - } - } - - return ZD_ERROR_SUCCESS; -} - -// loads and unpacks the file into a newly created buffer (that must be subsequently freed with -// Free()) Returns NULL if failed -void* ZipDir::Cache::AllocAndReadFile (FileEntry* pFileEntry) -{ - if (!pFileEntry) - { - return NULL; - } - - void* pData = malloc(pFileEntry->desc.lSizeUncompressed); - if (pData) - { - if (ZD_ERROR_SUCCESS != ReadFile (pFileEntry, NULL, pData)) - { - free(pData); - pData = NULL; - } - } - return pData; -} - -// frees the memory block that was previously allocated by AllocAndReadFile -void ZipDir::Cache::Free (void* pData) -{ - free(pData); -} - -// refreshes information about the given file entry into this file entry -ZipDir::ErrorEnum ZipDir::Cache::Refresh (FileEntry* pFileEntry) -{ - if (!pFileEntry) - { - return ZD_ERROR_INVALID_CALL; - } - - if (pFileEntry->nFileDataOffset != pFileEntry->INVALID_DATA_OFFSET) - { - return ZD_ERROR_SUCCESS; // the data offset has been successfully read.. - } - - return ZipDir::Refresh(m_pFile, pFileEntry, m_bEncryptHeaders); -} - -////////////////////////////////////////////////////////////////////////// -uint32 ZipDir::Cache::GetFileDataOffset(FileEntry* pFileEntry) -{ - if (pFileEntry->nFileDataOffset == pFileEntry->INVALID_DATA_OFFSET) - { - ZipDir::Refresh (m_pFile, pFileEntry, m_bEncryptHeaders); - } - return pFileEntry->nFileDataOffset; -} - -// returns the size of memory occupied by the instance referred to by this cache -// must be exact, because it's used by CacheRW to reallocate this cache -size_t ZipDir::Cache::GetSize() const -{ - return m_nDataSize + sizeof(Cache) + strlen(GetFilePath()); -} - - -// QUICK check to determine whether the file entry belongs to this object -bool ZipDir::Cache::IsOwnerOf (const FileEntry* pFileEntry) const -{ - // just check whether the pointer is within the memory block of this cache instance - return ((ULONG_PTR)pFileEntry >= (ULONG_PTR)(GetRoot() + 1) - && (ULONG_PTR)pFileEntry <= ((ULONG_PTR)GetRoot()) + m_nDataSize - sizeof(FileEntry)); -} - -bool ZipDir::Cache::UnpakToDisk(const string& destFolder) -{ - return UnpakToDiskInternal(GetRoot(), destFolder); -} - -bool ZipDir::Cache::UnpakToDiskInternal(ZipDir::DirHeader* folder, const string& destFolder) -{ - if (!folder) - { - return false; - } - - if (!FileUtil::EnsureDirectoryExists(destFolder.c_str())) - { - return false; - } - - bool result = true; - for (ZipFile::ushort fileNum = 0; fileNum < folder->numFiles; ++fileNum) - { - ZipDir::FileEntry* fileEntry = folder->GetFileEntry(fileNum); - if (!fileEntry) - { - result = false; - continue; - } - - string filePath = PathHelpers::Join(destFolder, fileEntry->GetName(folder->GetNamePool())); - AZ::IO::SystemFile file; - if (!file.Open(filePath.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_WRITE | AZ::IO::SystemFile::SF_OPEN_CREATE)) - { - result = false; - continue; - } - - if (!fileEntry->desc.lSizeUncompressed) - { - // Nothing to write. Just close the file. - file.Close(); - continue; - } - - AZStd::vector buffer(fileEntry->desc.lSizeUncompressed); - if (ReadFile(fileEntry, nullptr, buffer.data()) == ZD_ERROR_SUCCESS) - { - file.Write(buffer.data(), buffer.size()); - file.Close(); - } - else - { - file.Close(); - AZ::IO::SystemFile::Delete(filePath.c_str()); - result = false; - continue; - } - } - - for (ZipFile::ushort dirNum = 0; dirNum < folder->numDirs; ++dirNum) - { - ZipDir::DirEntry* entry = folder->GetSubdirEntry(dirNum); - if (!entry) - { - result = false; - continue; - } - - string newPath = PathHelpers::Join(destFolder, entry->GetName(folder->GetNamePool())); - if (!UnpakToDiskInternal(entry->GetDirectory(), newPath)) - { - result = false; - continue; - } - } - - return result; -} - diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirCache.h b/Code/Tools/CryCommonTools/ZipDir/ZipDirCache.h deleted file mode 100644 index 958c77efc3..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirCache.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Declarations of the class used to parse and cache Zipped directory. -// This class is actually an auto-pointer to the instance of the cache, so it can -// be easily passed by value. -// The cache instance contains the optimized for memory usage and fast search tree -// of the files/directories inside the zip; each file has a descriptor with the -// info about where its compressed data lies within the file - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHE_H -#pragma once - - - -///////////////////////////////////////////////////////////// -// THe Zip Dir uses a special memory layout for keeping the structure of zip file. -// This layout is optimized for small memory footprint (for big zip files) -// and quick binary-search access to the individual files. -// -// The serialized layout consists of a number of directory records. -// Each directory record starts with the DirHeader structure, then -// it has an array of DirEntry structures (sorted by name), -// array of FileEntry structures (sorted by name) and then -// the pool of names, followed by pad bytes to align the whole directory -// record on 4-byte boundray. - -namespace ZipDir -{ - // this is the header of the instance data allocated dynamically - // it contains the FILE* : it owns it and closes upon destruction - struct Cache - { - void AddRef() { ++m_nRefCount; } - void Release() - { - if (--m_nRefCount <= 0) - { - Delete(); - } - } - int NumRefs() const { return m_nRefCount; } - - // looks for the given file record in the Central Directory. If there's none, returns NULL. - // if there is some, returns the pointer to it. - // the Path must be the relative path to the file inside the Zip - // if the file handle is passed, it will be used to find the file data offset, if one hasn't been initialized yet - // if bFull is true, then the full information about the file is returned (the offset to the data may be unknown at this point)- - // if needed, the file is accessed and the information is loaded - FileEntry* FindFile (const char* szPath, bool bFullInfo = false); - - // loads the given file into the pCompressed buffer (the actual compressed data) - // if the pUncompressed buffer is supplied, uncompresses the data there - // buffers must have enough memory allocated, according to the info in the FileEntry - // NOTE: there's no need to decompress if the method is 0 (store) - // returns 0 if successful or error code if couldn't do something - ErrorEnum ReadFile (FileEntry* pFileEntry, void* pCompressed, void* pUncompressed); - - // loads and unpacks the file into a newly created buffer (that must be subsequently freed with - // Free()) Returns NULL if failed - void* AllocAndReadFile (FileEntry* pFileEntry); - - // frees the memory block that was previously allocated by AllocAndReadFile - void Free (void*); - - // refreshes information about the given file entry into this file entry - ErrorEnum Refresh (FileEntry* pFileEntry); - - // Return FileEntity data offset inside zip file. - uint32 GetFileDataOffset(FileEntry* pFileEntry); - - - // returns the root directory record; - // through this directory record, user can traverse the whole tree - DirHeader* GetRoot() const - { - return (DirHeader*)(this + 1); - } - - // returns the size of memory occupied by the instance referred to by this cache - // must be exact, because it's used by CacheRW to reallocate this cache - size_t GetSize() const; - - // QUICK check to determine whether the file entry belongs to this object - bool IsOwnerOf (const FileEntry* pFileEntry) const; - - // returns the string - path to the zip file from which this object was constructed. - // this will be "" if the object was constructed with a factory that wasn't created with FLAGS_MEMORIZE_ZIP_PATH - const char* GetFilePath() const - { - return ((const char*)(this + 1)) + m_nZipPathOffset; - } - - // Unpak the file into a destination folder - bool UnpakToDisk(const string& destFolder); - - friend class CacheFactory; // the factory class creates instances of this class - friend class CacheRW; // the Read-Write 2-way cache can modify this cache directly during write operations - protected: - volatile signed int m_nRefCount; // the reference count - FILE* m_pFile; // the opened file - - // the size of the serialized data following this instance (not including the extra fields after the serialized tree data) - size_t m_nDataSize; - // the offset to the path/name of the zip file relative to (char*)(this+1) pointer in bytes - size_t m_nZipPathOffset; - - // tells if encryption used for zip-file - EncryptionKey m_encryptionKey; - bool m_bEncryptHeaders; - public: - // initializes the instance structure - void Construct(FILE* fNew, size_t nDataSize, const EncryptionKey& key); - void Delete(); - private: - bool ReadCompressedData(char* data, size_t size); - bool UnpakToDiskInternal(ZipDir::DirHeader* dirHeader, const string& destFolder); - - // the constructor/destructor cannot be called at all - everything will go through the factory class - Cache() { m_nRefCount = 0; } - ~Cache(){} - }; - - TYPEDEF_AUTOPTR(Cache); - - typedef Cache_AutoPtr CachePtr; -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHE_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheFactory.cpp b/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheFactory.cpp deleted file mode 100644 index 9d64f60b63..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheFactory.cpp +++ /dev/null @@ -1,804 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "smartptr.h" -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include "ZipDirTree.h" -#include "ZipDirCache.h" -#include "ZipDirCacheRW.h" -#include "ZipDirCacheFactory.h" -#include "ZipDirList.h" -#include - -static uint32 g_defaultEncryptionKey[4] = { 0xc968fb67, 0x8f9b4267, 0x85399e84, 0xf9b99dc4 }; - -ZipDir::CacheFactory::CacheFactory (InitMethodEnum nInitMethod, unsigned nFlags) -{ - m_nCDREndPos = 0; - m_f = NULL; - m_bBuildFileEntryMap = false; // we only need it for validation/debugging - m_bBuildFileEntryTree = true; // we need it to actually build the optimized structure of directories - m_bEncryptedHeaders = false; - - m_nInitMethod = nInitMethod; - m_nFlags = nFlags; -} - -ZipDir::CacheFactory::~CacheFactory() -{ - Clear(); -} - -ZipDir::CachePtr ZipDir::CacheFactory::New (const char* szFile, const uint32 key[4]) -{ - m_encryptionKey = EncryptionKey(g_defaultEncryptionKey); - if (key) - { - m_encryptionKey = EncryptionKey(key); - } - - Clear(); - m_f = nullptr; - azfopen(&m_f, szFile, "rb"); - if (m_f) - { - return MakeCache (szFile); - } - Clear(); - THROW_ZIPDIR_ERROR(ZD_ERROR_IO_FAILED, "Cannot open file in binary mode for reading, probably missing file"); - return 0; - /* - if (!m_f) - THROW_ZIPDIR_ERROR(ZD_ERROR_IO_FAILED,"Cannot open file in binary mode for reading, probably missing file"); - try - { - return MakeCache (szFile); - } - catch(Error) - { - Clear(); - throw; - } - */ -} - - -ZipDir::CacheRWPtr ZipDir::CacheFactory::NewRW(const char* szFileName, size_t fileAlignment, bool encrypted, const uint32* key) -{ - m_encryptionKey = EncryptionKey(g_defaultEncryptionKey); - if (key) - { - m_encryptionKey = EncryptionKey(key); - } - - CacheRWPtr pCache = new CacheRW(encrypted, m_encryptionKey); - - // opens the given zip file and connects to it. Creates a new file if no such file exists - // if successful, returns true. - if (!(m_nFlags & FLAGS_DONT_MEMORIZE_ZIP_PATH)) - { - pCache->m_strFilePath = szFileName; - } - - if (m_nFlags & FLAGS_DONT_COMPACT) - { - pCache->m_nFlags |= CacheRW::FLAGS_DONT_COMPACT; - } - - // first, try to open the file for reading or reading/writing - if (m_nFlags & FLAGS_READ_ONLY) - { - m_f = nullptr; - azfopen(&m_f, szFileName, "rb"); - pCache->m_nFlags |= CacheRW::FLAGS_CDR_DIRTY | CacheRW::FLAGS_READ_ONLY; - - if (!m_f) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_IO_FAILED, "Could not open file in binary mode for reading"); - return 0; - } - } - else - { - m_f = NULL; - if (!(m_nFlags & FLAGS_CREATE_NEW)) - { - m_f = nullptr; - azfopen(&m_f, szFileName, "r+b"); - } - - bool bOpenForWriting = true; - - if (m_f) - { - // get file size - fseek(m_f, 0, SEEK_END); - size_t nFileSize = AZ_TRAIT_CRYCOMMONTOOLS_FTELL(m_f); - fseek(m_f, 0, SEEK_SET); - - if (nFileSize) - { - if (!ReadCacheRW(*pCache)) - { - fclose(m_f); - m_f = NULL; - - THROW_ZIPDIR_ERROR(ZD_ERROR_IO_FAILED, "Could not read archive"); - return 0; - } - bOpenForWriting = false; - } - else - { - // if file has 0 bytes (e.g. crash during saving) we don't want to open it - assert(0); // you can ignore, the system shold handle this gracefully - } - } - - if (bOpenForWriting) - { - m_f = nullptr; - azfopen(&m_f, szFileName, "w+b"); - if (m_f) - { - // there's no such file, but we'll create one. We'll need to write out the CDR here - pCache->m_lCDROffset = 0; - pCache->m_nFlags |= CacheRW::FLAGS_CDR_DIRTY; - } - pCache->m_fileAlignment = fileAlignment; - } - - if (!m_f) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_IO_FAILED, "Could not open file in binary mode for appending (read/write)"); - return 0; - } - } - - - // give the cache the file handle: - pCache->m_pFile = m_f; - // the factory doesn't own it after that - m_f = NULL; - - return pCache; -} - -bool ZipDir::CacheFactory::ReadCacheRW (CacheRW& rwCache) -{ - m_bBuildFileEntryTree = true; - if (!Prepare()) - { - return false; - } - - // since it's open for R/W, we need to know exactly how much space - // we have for each file to use the gaps efficiently - FileEntryList Adjuster (&m_treeFileEntries, m_CDREnd.lCDROffset); - Adjuster.RefreshEOFOffsets(); - - m_treeFileEntries.Swap(rwCache.m_treeDir); - m_CDR_buffer.swap(rwCache.m_CDR_buffer); // CDR Buffer contain actually the string pool for the tree directory. - m_unifiedNameBuffer.swap(rwCache.m_unifiedNameBuffer); // string pool for unified names - - // very important: we need this offset to be able to add to the zip file - rwCache.m_lCDROffset = m_CDREnd.lCDROffset; - - if (m_bEncryptedHeaders != rwCache.m_bEncryptedHeaders) - { - // force to relink and update all headers on close - rwCache.m_nFlags |= ZipDir::CacheRW::FLAGS_UNCOMPACTED; - rwCache.m_bHeadersEncryptedOnClose = rwCache.m_bEncryptedHeaders; - rwCache.m_bEncryptedHeaders = m_bEncryptedHeaders; - } - return true; -} - -// reads everything and prepares the maps -bool ZipDir::CacheFactory::Prepare () -{ - if (!FindCDREnd()) - { - return false; - } - - m_bEncryptedHeaders = (m_CDREnd.nDisk & (1 << 15)) != 0; - m_CDREnd.nDisk = m_CDREnd.nDisk & 0x7fff; - - // we don't support multivolume archives - if (m_CDREnd.nDisk != 0 - || m_CDREnd.nCDRStartDisk != 0 - || m_CDREnd.numEntriesOnDisk != m_CDREnd.numEntriesTotal) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_UNSUPPORTED, "Multivolume archive detected. Current version of ZipDir does not support multivolume archives"); - return false; - } - - // if the central directory offset or size are out of range, - // the CDREnd record is probably corrupt - if (m_CDREnd.lCDROffset > m_nCDREndPos - || m_CDREnd.lCDRSize > m_nCDREndPos - || m_CDREnd.lCDROffset + m_CDREnd.lCDRSize > m_nCDREndPos) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_DATA_IS_CORRUPT, "The central directory offset or size are out of range, the pak is probably corrupt, try to repair or delete the file"); - return false; - } - - if (!BuildFileEntryMap()) - { - return false; - } - - // the number of parsed files MUST be the declared number of entries - // in the central directory - if (m_bBuildFileEntryMap && m_CDREnd.numEntriesTotal != m_mapFileEntries.size()) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_CDR_IS_CORRUPT, "The number of parsed files does not match the declared number of entries in the central directory, the pak is probably corrupt, try to repair or delete the file"); - } - - const size_t numFilesFound = m_treeFileEntries.NumFilesTotal(); - if (m_bBuildFileEntryTree && m_CDREnd.numEntriesTotal != numFilesFound) - { - const size_t numDirsFound = m_treeFileEntries.NumDirsTotal(); - - // Other zip tools create entries for directories. - // These entires don't have representation in our tree. - // FIXME: Proper calculation of entry count should be implemented. - if (m_CDREnd.numEntriesTotal != numFilesFound + numDirsFound) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_CDR_IS_CORRUPT, "The number of parsed files does not match the declared number of entries in the central directory. The pak does not appear to be corrupt, but perhaps there are some duplicated or missing file entries, try to repair the file"); - } - } - - return true; -} - -ZipDir::CachePtr ZipDir::CacheFactory::MakeCache (const char* szFile) -{ - if (!Prepare()) - { - return CachePtr(); - } - - // initializes this object from the given tree, which is a convenient representation of the file tree - size_t nSizeRequired = m_treeFileEntries.GetSizeSerialized(); - size_t nSizeZipPath = 1; // we need to remember the terminating 0 - if (!(m_nFlags & FLAGS_DONT_MEMORIZE_ZIP_PATH)) - { - nSizeZipPath += strlen(szFile); - } - // allocate and initialize the memory that'll be the root now - size_t nCacheInstanceSize = sizeof(Cache) + nSizeRequired + nSizeZipPath; - - Cache* pCacheInstance = (Cache*)malloc(nCacheInstanceSize); // Do not use pools for this allocation - pCacheInstance->Construct(m_f, nSizeRequired, m_encryptionKey); - CachePtr cache = pCacheInstance; - m_f = NULL; // we don't own the file anymore - it's in possession of the cache instance - - // try to serialize into the memory -#if !defined(NDEBUG) - size_t nSizeSerialized = -#endif - m_treeFileEntries.Serialize (cache->GetRoot()); - - assert (nSizeSerialized == nSizeRequired); - - char* pZipPath = ((char*)(pCacheInstance + 1)) + nSizeRequired; - - if (!(m_nFlags & FLAGS_DONT_MEMORIZE_ZIP_PATH)) - { - memcpy (pZipPath, szFile, nSizeZipPath); - } - else - { - pZipPath[0] = '\0'; - } - - Clear(); - - return cache; -} - -void ZipDir::CacheFactory::Clear() -{ - if (m_f) - { - fclose (m_f); - } - m_nCDREndPos = 0; - memset (&m_CDREnd, 0, sizeof(m_CDREnd)); - m_mapFileEntries.clear(); - m_treeFileEntries.Clear(); - m_bEncryptedHeaders = false; -} - - -////////////////////////////////////////////////////////////////////////// -// searches for CDREnd record in the given file -bool ZipDir::CacheFactory::FindCDREnd() -{ - // this buffer will be used to find the CDR End record - // the additional bytes are required to store the potential tail of the CDREnd structure - // when moving the window to the next position in the file - char pReservedBuffer[g_nCDRSearchWindowSize + sizeof(ZipFile::CDREnd) - 1]; - - Seek (0, SEEK_END); - unsigned long nFileSize = Tell(); - - if (nFileSize < sizeof(ZipFile::CDREnd)) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_NO_CDR, "The file is too small, it doesn't even contain the CDREnd structure. Please check and delete the file. Truncated files are not deleted automatically"); - return false; - } - - // this will point to the place where the buffer was loaded - unsigned int nOldBufPos = nFileSize; - // start scanning well before the end of the file to avoid reading beyond the end - - unsigned int nScanPos = nFileSize - sizeof(ZipFile::CDREnd); - - m_CDREnd.lSignature = 0; // invalid signature as the flag of not-found CDR End structure - while (true) - { - unsigned int nNewBufPos; // the new buf pos - char* pWindow = pReservedBuffer; // the window pointer into which data will be read (takes into account the possible tail-of-CDREnd) - if (nOldBufPos <= g_nCDRSearchWindowSize) - { - // the old buffer position doesn't let us read the full search window size - // therefore the new buffer pos will be 0 (instead of negative beyond the start of the file) - // and the window pointer will be closer tot he end of the buffer because the end of the buffer - // contains the data from the previous iteration (possibly) - nNewBufPos = 0; - pWindow = pReservedBuffer + g_nCDRSearchWindowSize - (nOldBufPos - nNewBufPos); - } - else - { - nNewBufPos = nOldBufPos - g_nCDRSearchWindowSize; - assert (nNewBufPos > 0); - } - - // since dealing with 32bit unsigned, check that filesize is bigger than - // CDREnd plus comment before the following check occurs. - if (nFileSize > (sizeof(ZipFile::CDREnd) + 0xFFFF)) - { - // if the new buffer pos is beyond 64k limit for the comment size - if (nNewBufPos < (unsigned int)(nFileSize - sizeof(ZipFile::CDREnd) - 0xFFFF)) - { - nNewBufPos = nFileSize - sizeof(ZipFile::CDREnd) - 0xFFFF; - } - } - - // if there's nothing to search - if (nNewBufPos >= nOldBufPos) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_NO_CDR, "Cannot find Central Directory Record in pak. This is either not a pak file, or a pak file without Central Directory. It does not mean that the data is permanently lost, but it may be severely damaged. Please repair the file with external tools, there may be enough information left to recover the file completely"); // we didn't find anything - return false; - } - - // seek to the start of the new window and read it - Seek (nNewBufPos); - Read (pWindow, nOldBufPos - nNewBufPos); - - while (nScanPos >= nNewBufPos) - { - ZipFile::CDREnd* pEnd = (ZipFile::CDREnd*)(pWindow + nScanPos - nNewBufPos); - if (pEnd->lSignature == pEnd->SIGNATURE) - { - if (pEnd->nCommentLength == nFileSize - nScanPos - sizeof(ZipFile::CDREnd)) - { - // the comment length is exactly what we expected - m_CDREnd = *pEnd; - m_nCDREndPos = nScanPos; - break; - } - else - { - THROW_ZIPDIR_ERROR (ZD_ERROR_DATA_IS_CORRUPT, "Central Directory Record is followed by a comment of inconsistent length. This might be a minor misconsistency, please try to repair the file. However, it is dangerous to open the file because I will have to guess some structure offsets, which can lead to permanent unrecoverable damage of the archive content"); - return false; - } - } - if (nScanPos == 0) - { - break; - } - --nScanPos; - } - - if (m_CDREnd.lSignature == m_CDREnd.SIGNATURE) - { - return true; // we've found it - } - - nOldBufPos = nNewBufPos; - memmove (pReservedBuffer + g_nCDRSearchWindowSize, pWindow, sizeof(ZipFile::CDREnd) - 1); - } - THROW_ZIPDIR_ERROR (ZD_ERROR_UNEXPECTED, "The program flow may not have possibly lead here. This error is unexplainable"); // we shouldn't be here - return false; -} - - -////////////////////////////////////////////////////////////////////////// -// uses the found CDREnd to scan the CDR and probably the Zip file itself -// builds up the m_mapFileEntries -bool ZipDir::CacheFactory::BuildFileEntryMap() -{ - Seek (m_CDREnd.lCDROffset); - - if (m_CDREnd.lCDRSize == 0) - { - return true; - } - - DynArray& pBuffer = m_CDR_buffer; // Use persistent buffer. - - pBuffer.resize(m_CDREnd.lCDRSize + 1); // Allocate one more because we use this memory as a strings pool. - - if (pBuffer.empty()) // couldn't allocate enough memory for temporary copy of CDR - { - THROW_ZIPDIR_ERROR (ZD_ERROR_NO_MEMORY, "Not enough memory to cache Central Directory record for fast initialization. This error may not happen on non-console systems"); - return false; - } - - // Calculate buffer size for unified filenames - const size_t headersSize = sizeof(ZipFile::CDRFileHeader) * m_CDREnd.numEntriesTotal; - const size_t terminatingZeros = m_CDREnd.numEntriesTotal; - if (headersSize > m_CDREnd.lCDRSize + terminatingZeros) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_CORRUPTED_DATA, "Number of entries in Central Directory seems to be wrong"); - return false; - } - const size_t nameBufferSize = m_CDREnd.lCDRSize + terminatingZeros - headersSize; // numEntriesTotal for terminating zeroes - - // Allocate buffer for unified filenames - m_unifiedNameBuffer.resize(nameBufferSize); - if (m_unifiedNameBuffer.empty() && nameBufferSize != 0) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_NO_MEMORY, "Not enough memory to allocate unified names buffer"); - return false; - } - char* pUnifiedName = m_unifiedNameBuffer.empty() ? 0 : &m_unifiedNameBuffer[0]; - const char* const pUnifiedNameEnd = pUnifiedName + m_unifiedNameBuffer.size(); - - ReadHeaderData(&pBuffer[0], m_CDREnd.lCDRSize); - - // now we've read the complete CDR - parse it. - ZipFile::CDRFileHeader* pFile = (ZipFile::CDRFileHeader*)(&pBuffer[0]); - const char* const pEndOfData = &pBuffer[0] + m_CDREnd.lCDRSize; - const char* const pEndOfBuffer = &pBuffer[0] + pBuffer.size(); - char* pFileName; - - // check signature of first entry - if ((const char*)(pFile + 1) <= pEndOfData) - { - if (pFile->lSignature != pFile->SIGNATURE) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_CDR_IS_CORRUPT, m_bEncryptedHeaders - ? "Signature of CDR entry is corrupt. Wrong decryption key was used or archive is corrupt." - : "Signature of CDR entry is corrupt. Archive is corrupt."); - return false; - } - } - - while ((pFileName = (char*)(pFile + 1)) <= pEndOfData) - { - // Hacky way to use CDR memory block as a string pool. - pFile->lSignature = 0; // Force signature to always be 0 (First byte of signature maybe a zero termination of the previous file filename). - - if (pFile->nVersionNeeded > 20) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_UNSUPPORTED, "Reading file header with unsupported version (nVersionNeeded > 20)."); - return false; - } - //if (pFile->lSignature != pFile->SIGNATURE) // Timur, Dont compare signatures as signatue in memory can be overwritten by the code below - //break; - // the end of this file record - const char* pEndOfRecord = (pFileName + pFile->nFileNameLength + pFile->nExtraFieldLength + pFile->nFileCommentLength); - // if the record overlaps with the End Of CDR structure, something is wrong - if (pEndOfRecord > pEndOfData) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_CDR_IS_CORRUPT, "Central Directory record is either corrupt, or truncated, or missing. Cannot read the archive directory"); - return false; - } - - ////////////////////////////////////////////////////////////////////////// - // Analyze advanced section. - ////////////////////////////////////////////////////////////////////////// - SExtraZipFileData extra; - const char* pExtraField = (pFileName + pFile->nFileNameLength); - const char* pExtraEnd = pExtraField + pFile->nExtraFieldLength; - while (pExtraField < pExtraEnd) - { - const char* pAttrData = pExtraField + sizeof(ZipFile::ExtraFieldHeader); - ZipFile::ExtraFieldHeader& hdr = *(ZipFile::ExtraFieldHeader*)pExtraField; - switch (hdr.headerID) - { - case ZipFile::EXTRA_NTFS: - { - extra.nLastModifyTime = *(uint64*)(pAttrData + sizeof(ZipFile::ExtraNTFSHeader)); - //uint64 accTime = *(uint64*)(pAttrData + sizeof(ZipFile::ExtraNTFSHeader) + 8); - //uint64 crtTime = *(uint64*)(pAttrData + sizeof(ZipFile::ExtraNTFSHeader) + 16); - } - break; - } - pExtraField += sizeof(ZipFile::ExtraFieldHeader) + hdr.dataSize; - } - - bool bDirectory = false; - if (pFile->nFileNameLength > 0 && (pFileName[pFile->nFileNameLength - 1] == '/' || pFileName[pFile->nFileNameLength - 1] == '\\')) - { - bDirectory = true; - } - - if (!bDirectory) - { - const size_t fileNameLen = pFile->nFileNameLength; - pFileName[fileNameLen] = 0; // Not standard!, may overwrite signature of the next memory record data in zip. - - // generate unified name - if (pFileName + fileNameLen + 1 > pEndOfBuffer || - pUnifiedName + fileNameLen + 1 > pUnifiedNameEnd) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_CORRUPTED_DATA, "Filename length exceeds estimated size. Try to repair the archive."); - return false; - } - - for (int i = 0; i < fileNameLen + 1; i++) - { - pUnifiedName[i] = ::tolower(pFileName[i]); - } - - // put this entry into the map - AddFileEntry (pFileName, pUnifiedName, pFile, extra); - - pUnifiedName += fileNameLen + 1; - } - - // move to the next file - pFile = (ZipFile::CDRFileHeader*)pEndOfRecord; - } - - // finished reading CDR - return true; -} - - -////////////////////////////////////////////////////////////////////////// -// give the CDR File Header entry, reads the local file header to validate -// and determine where the actual file lies -void ZipDir::CacheFactory::AddFileEntry (char* strFilePath, char* strUnifiedPath, const ZipFile::CDRFileHeader* pFileHeader, const SExtraZipFileData& extra) -{ - if (pFileHeader->lLocalHeaderOffset > m_CDREnd.lCDROffset) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_CDR_IS_CORRUPT, "Central Directory contains file descriptors pointing outside the archive file boundaries. The archive file is either truncated or damaged. Please try to repair the file"); // the file offset is beyond the CDR: impossible - return; - } - - if (pFileHeader->nMethod == ZipFile::METHOD_STORE && pFileHeader->desc.lSizeUncompressed != pFileHeader->desc.lSizeCompressed) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_VALIDATION_FAILED, "File with STORE compression method declares its compressed size not matching its uncompressed size. File descriptor is inconsistent, archive content may be damaged, please try to repair the archive"); - return; - } - - FileEntry fileEntry (*pFileHeader, extra); - - if ((m_bEncryptedHeaders || m_nInitMethod >= ZD_INIT_FULL) && pFileHeader->desc.lSizeCompressed) - { - InitDataOffset(fileEntry, pFileHeader); - } - - if (m_bBuildFileEntryMap) - { - m_mapFileEntries.insert (FileEntryMap::value_type(strFilePath, fileEntry)); - } - - if (m_bBuildFileEntryTree) - { - m_treeFileEntries.Add(strFilePath, strUnifiedPath, fileEntry); - } -} - - -////////////////////////////////////////////////////////////////////////// -// initializes the actual data offset in the file in the fileEntry structure -// searches to the local file header, reads it and calculates the actual offset in the file -void ZipDir::CacheFactory::InitDataOffset (FileEntry& fileEntry, const ZipFile::CDRFileHeader* pFileHeader) -{ - // make sure it's the same file and the fileEntry structure is properly initialized - assert (fileEntry.nFileHeaderOffset == pFileHeader->lLocalHeaderOffset); - - /* - // without validation, it would be like this: - ErrorEnum nError = Refresh(&fileEntry); - if (nError != ZD_ERROR_SUCCESS) - THROW_ZIPDIR_ERROR(nError,"Cannot refresh file entry. Probably corrupted file header inside zip file"); - */ - - - if (m_bEncryptedHeaders) - { - // ignore local header - fileEntry.nFileDataOffset = pFileHeader->lLocalHeaderOffset + sizeof(ZipFile::LocalFileHeader) + pFileHeader->nFileNameLength + pFileHeader->nExtraFieldLength; - } - else - { - Seek(pFileHeader->lLocalHeaderOffset); - // read the local file header and the name (for validation) into the buffer - DynArraypBuffer; - unsigned nBufferLength = sizeof(ZipFile::LocalFileHeader) + pFileHeader->nFileNameLength; - pBuffer.resize(nBufferLength); - Read (&pBuffer[0], nBufferLength); - - // validate the local file header (compare with the CDR file header - they should contain basically the same information) - const ZipFile::LocalFileHeader* pLocalFileHeader = (const ZipFile::LocalFileHeader*)&pBuffer[0]; - if (pFileHeader->desc != pLocalFileHeader->desc - || pFileHeader->nMethod != pLocalFileHeader->nMethod - || pFileHeader->nFileNameLength != pLocalFileHeader->nFileNameLength - // for a tough validation, we can compare the timestamps of the local and central directory entries - // but we won't do that for backward compatibility with ZipDir - //|| pFileHeader->nLastModDate != pLocalFileHeader->nLastModDate - //|| pFileHeader->nLastModTime != pLocalFileHeader->nLastModTime - ) - { - THROW_ZIPDIR_ERROR (ZD_ERROR_VALIDATION_FAILED, "The local file header descriptor doesn't match the basic parameters declared in the global file header in the file. The archive content is misconsistent and may be damaged. Please try to repair the archive"); - return; - } - - // now compare the local file name with the one recorded in CDR: they must match. - if (azmemicmp((const char*)&pBuffer[sizeof(ZipFile::LocalFileHeader)], (const char*)pFileHeader + 1, pFileHeader->nFileNameLength)) - { - // either file name, or the extra field do not match - THROW_ZIPDIR_ERROR(ZD_ERROR_VALIDATION_FAILED, "The local file header contains file name which does not match the file name of the global file header. The archive content is misconsistent with its directory. Please repair the archive"); - return; - } - - fileEntry.nFileDataOffset = pFileHeader->lLocalHeaderOffset + sizeof(ZipFile::LocalFileHeader) + pLocalFileHeader->nFileNameLength + pLocalFileHeader->nExtraFieldLength; - } - - if (fileEntry.nFileDataOffset >= m_nCDREndPos) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_VALIDATION_FAILED, "The global file header declares the file which crosses the boundaries of the archive. The archive is either corrupted or truncated, please try to repair it"); - return; - } - - if (m_nInitMethod >= ZD_INIT_VALIDATE) - { - Validate (fileEntry); - } -} - -////////////////////////////////////////////////////////////////////////// -// reads the file pointed by the given header and entry (they must be coherent) -// and decompresses it; then calculates and validates its CRC32 -void ZipDir::CacheFactory::Validate(const FileEntry& fileEntry) -{ - DynArray pBuffer; - // validate the file contents - // allocate memory for both the compressed data and uncompressed data - pBuffer.resize(fileEntry.desc.lSizeCompressed + fileEntry.desc.lSizeUncompressed); - char* pUncompressed = &pBuffer[fileEntry.desc.lSizeCompressed]; - char* pCompressed = &pBuffer[0]; - - assert (fileEntry.nFileDataOffset != FileEntry::INVALID_DATA_OFFSET); - Seek(fileEntry.nFileDataOffset); - - Read(pCompressed, fileEntry.desc.lSizeCompressed); - - if (fileEntry.nMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT) - { - ZipDir::Decrypt(pCompressed, fileEntry.desc.lSizeCompressed, m_encryptionKey); - } - - unsigned long nDestSize = fileEntry.desc.lSizeUncompressed; - int nError = Z_OK; - if (fileEntry.nMethod) - { - nError = ZipRawUncompress (pUncompressed, &nDestSize, pCompressed, fileEntry.desc.lSizeCompressed); - } - else - { - assert (fileEntry.desc.lSizeCompressed == fileEntry.desc.lSizeUncompressed); - memcpy (pUncompressed, pCompressed, fileEntry.desc.lSizeUncompressed); - } - switch (nError) - { - case Z_OK: - break; - case Z_MEM_ERROR: - THROW_ZIPDIR_ERROR(ZD_ERROR_ZLIB_NO_MEMORY, "ZLib reported out-of-memory error"); - return; - case Z_BUF_ERROR: - THROW_ZIPDIR_ERROR(ZD_ERROR_ZLIB_CORRUPTED_DATA, "ZLib reported compressed stream buffer error"); - return; - case Z_DATA_ERROR: - THROW_ZIPDIR_ERROR(ZD_ERROR_ZLIB_CORRUPTED_DATA, "ZLib reported compressed stream data error"); - return; - default: - THROW_ZIPDIR_ERROR(ZD_ERROR_ZLIB_FAILED, "ZLib reported an unexpected unknown error"); - return; - } - - if (nDestSize != fileEntry.desc.lSizeUncompressed) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_CORRUPTED_DATA, "Uncompressed stream doesn't match the size of uncompressed file stored in the archive file headers"); - return; - } - - uLong uCRC32 = crc32(0L, Z_NULL, 0); - uCRC32 = crc32(uCRC32, (Bytef*)pUncompressed, nDestSize); - if (uCRC32 != fileEntry.desc.lCRC32) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_CRC32_CHECK, "Uncompressed stream CRC32 check failed"); - return; - } -} - - -////////////////////////////////////////////////////////////////////////// -// extracts the file path from the file header with subsequent information -// may, or may not, put all letters to lower-case (depending on whether the system is to be case-sensitive or not) -// it's the responsibility of the caller to ensure that the file name is in readable valid memory -char* ZipDir::CacheFactory::GetFilePath (const char* pFileName, ZipFile::ushort nFileNameLength) -{ - static char strResult[_MAX_PATH]; - assert(nFileNameLength < _MAX_PATH); - memcpy(strResult, pFileName, nFileNameLength); - strResult[nFileNameLength] = 0; - for (int i = 0; i < nFileNameLength; i++) - { - strResult[i] = ::tolower(strResult[i]); - } - - return strResult; -} - -// seeks in the file relative to the starting position -void ZipDir::CacheFactory::Seek (ZipFile::ulong nPos, int nOrigin) // throw -{ - if (AZ_TRAIT_CRYCOMMONTOOLS_FSEEK(m_f, nPos, nOrigin)) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_IO_FAILED, "Cannot fseek() to the new position in the file. This is unexpected error and should not happen under any circumstances. Perhaps some network or disk failure error has caused this"); - return; - } -} - -unsigned long ZipDir::CacheFactory::Tell () // throw -{ - AZ::s64 nPos = AZ_TRAIT_CRYCOMMONTOOLS_FTELL(m_f); - if (nPos == -1) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_IO_FAILED, "Cannot ftell() position in the archive. This is unexpected error and should not happen under any circumstances. Perhaps some network or disk failure error has caused this"); - return 0; - } - return (unsigned long)nPos; -} - -void ZipDir::CacheFactory::Read (void* pDest, unsigned nSize) // throw -{ - if (fread (pDest, nSize, 1, m_f) != 1) - { - THROW_ZIPDIR_ERROR(ZD_ERROR_IO_FAILED, "Cannot fread() a portion of data from archive"); - } -} - -void ZipDir::CacheFactory::ReadHeaderData (void* pDest, unsigned nSize) // throw -{ - Read(pDest, nSize); - - if (m_bEncryptedHeaders) - { - ZipDir::Decrypt((char*)pDest, nSize, m_encryptionKey); - } -} - diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheFactory.h b/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheFactory.h deleted file mode 100644 index caf947e1af..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheFactory.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// This is the class that can read the directory from Zip file, -// and store it into the directory cache - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHEFACTORY_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHEFACTORY_H -#pragma once - - -namespace ZipDir -{ - class CacheRW; - TYPEDEF_AUTOPTR(CacheRW); - typedef CacheRW_AutoPtr CacheRWPtr; - - // an instance of this class is temporarily created on stack to initialize the CZipFile instance - class CacheFactory - { - public: - enum - { - // open RW cache in read-only mode - FLAGS_READ_ONLY = 1, - // do not compact RW-cached zip upon destruction - FLAGS_DONT_COMPACT = 1 << 1, - // if this is set, then the zip paths won't be memorized in the cache objects - FLAGS_DONT_MEMORIZE_ZIP_PATH = 1 << 2, - // if this is set, the archive will be created anew (the existing file will be overwritten) - FLAGS_CREATE_NEW = 1 << 3 - }; - - // initializes the internal structures - // nFlags can have FLAGS_READ_ONLY flag, in this case the object will be opened only for reading - CacheFactory (InitMethodEnum nInitMethod, unsigned nFlags = 0); - ~CacheFactory(); - - // the new function creates a new cache - CachePtr New(const char* szFileName, const uint32 decryptionKey[4]);// throw (ErrorEnum); - - CacheRWPtr NewRW(const char* szFileName, size_t fileAlignment, bool encrypted, const uint32 encryptionKey[4]); - - protected: - // reads the zip file into the file entry tree. - bool ReadCacheRW (CacheRW& rwCache); - - // creates from the m_f file - // reserves the given number of bytes for future expansion of the object - // upon return, pReserve contains the actual number of bytes that were allocated (more might have been allocated) - CachePtr MakeCache (const char* szFile); - - // this sets the window size of the blocks of data read from the end of the file to find the Central Directory Record - // since normally there are no - enum - { - g_nCDRSearchWindowSize = 0x100 - }; - - void Clear(); - - // reads everything and prepares the maps - bool Prepare(); - - // searches for CDREnd record in the given file - bool FindCDREnd();// throw(ErrorEnum); - - // uses the found CDREnd to scan the CDR and probably the Zip file itself - // builds up the m_mapFileEntries - bool BuildFileEntryMap();// throw (ErrorEnum); - - // give the CDR File Header entry, reads the local file header to validate and determine where - // the actual file lies - // This function can actually modify strFilePath and strUnifiedPath variables, make sure you use copies of real paths. - void AddFileEntry (char* strFilePath, char* strUnifiedPath, const ZipFile::CDRFileHeader* pFileHeader, const SExtraZipFileData& extra);// throw (ErrorEnum); - - // extracts the file path from the file header with subsequent information - // may, or may not, put all letters to lower-case (depending on whether the system is to be case-sensitive or not) - // it's the responsibility of the caller to ensure that the file name is in readable valid memory - char* GetFilePath (const ZipFile::CDRFileHeader* pFileHeader) - { - return GetFilePath((const char*)(pFileHeader + 1), pFileHeader->nFileNameLength); - } - // extracts the file path from the file header with subsequent information - // may, or may not, put all letters to lower-case (depending on whether the system is to be case-sensitive or not) - // it's the responsibility of the caller to ensure that the file name is in readable valid memory - char* GetFilePath (const ZipFile::LocalFileHeader* pFileHeader) - { - return GetFilePath((const char*)(pFileHeader + 1), pFileHeader->nFileNameLength); - } - // extracts the file path from the file header with subsequent information - // may, or may not, put all letters to lower-case (depending on whether the system is to be case-sensitive or not) - // it's the responsibility of the caller to ensure that the file name is in readable valid memory - char* GetFilePath (const char* pFileName, ZipFile::ushort nFileNameLength); - - // validates (if the init method has the corresponding value) the given file/header - void Validate(const FileEntry& fileEntry); - - // initializes the actual data offset in the file in the fileEntry structure - // searches to the local file header, reads it and calculates the actual offset in the file - void InitDataOffset (FileEntry& fileEntry, const ZipFile::CDRFileHeader* pFileHeader); - - // seeks in the file relative to the starting position - void Seek (ZipFile::ulong nPos, int nOrigin = SEEK_SET); // throw - unsigned long Tell (); // throw - void Read (void* pDest, unsigned nSize); // throw - void ReadHeaderData (void* pDest, unsigned nSize);// throw - protected: - - FILE* m_f; - InitMethodEnum m_nInitMethod; - unsigned m_nFlags; - ZipFile::CDREnd m_CDREnd; - - unsigned m_nCDREndPos; // position of the CDR End in the file - - // Map: Relative file path => file entry info - typedef std::map FileEntryMap; - FileEntryMap m_mapFileEntries; - - FileEntryTree m_treeFileEntries; - - DynArray m_CDR_buffer; - DynArray m_unifiedNameBuffer; - - EncryptionKey m_encryptionKey; - bool m_bEncryptedHeaders; - bool m_bBuildFileEntryMap; - bool m_bBuildFileEntryTree; - }; -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRCACHEFACTORY_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheRW.cpp b/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheRW.cpp deleted file mode 100644 index 6e47aec5d4..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheRW.cpp +++ /dev/null @@ -1,2100 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "Util.h" -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include "ZipDirTree.h" -#include "ZipDirList.h" -#include "ZipDirCache.h" -#include "ZipDirCacheRW.h" -#include "ZipDirCacheFactory.h" -#include "ZipDirFindRW.h" - -#include "ThreadUtils.h" - -#include // declaration of Z_OK for ZipRawDecompress -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum PackFileStatus -{ - PACKFILE_COMPRESSED, - - PACKFILE_ADDED, - PACKFILE_UPTODATE, - PACKFILE_SKIPPED, - PACKFILE_MISSING, - PACKFILE_FAILED -}; - -enum PackFileCompressionPolicy -{ - PACKFILE_USE_REQUESTED_COMPRESSOR, - PACKFILE_USE_FASTEST_DECOMPRESSING_CODEC -}; - -class PackFilePool; -struct PackFileBatch -{ - PackFilePool* pool; - - int zipMaxSize; - int sourceMinSize; - int sourceMaxSize; - int compressionMethod; - int compressionLevel; - - PackFileBatch() - : pool(0) - , sourceMinSize(0) - , sourceMaxSize(0) - , zipMaxSize(0) - , compressionMethod(0) - , compressionLevel(0) - { - } -}; - -class PackFilePool; -struct PackFileJob -{ - int index; - int key; - PackFileBatch* batch; - const char* relativePathSrc; - const char* realFilename; - - unsigned int existingCRC; - - void* compressedData; - unsigned long compressedSize; - unsigned long compressedSizePreviously; - - void* uncompressedData; - unsigned long uncompressedSize; - unsigned long uncompressedSizePreviously; - - int64 modTime; - ZipDir::ErrorEnum zdError; - PackFileStatus status; - PackFileCompressionPolicy compressionPolicy; - - PackFileJob() - : index(0) - , key(0) - , batch(0) - , realFilename(0) - , relativePathSrc(0) - , existingCRC(0) - , compressedData(0) - , compressedSize(0) - , compressedSizePreviously(0) - , uncompressedData(0) - , uncompressedSize(0) - , uncompressedSizePreviously(0) - , modTime(0) - , zdError(ZipDir::ZD_ERROR_NOT_IMPLEMENTED) - , status(PACKFILE_FAILED) - , compressionPolicy(PACKFILE_USE_REQUESTED_COMPRESSOR) - { - } - - void DetachUncompressedData() - { - if (uncompressedData && uncompressedData == compressedData) - { - compressedData = 0; - compressedSize = 0; - } - - uncompressedData = 0; - uncompressedSize = 0; - } - - ~PackFileJob() - { - if (compressedData && compressedData != uncompressedData) - { - azfree(compressedData); - compressedData = 0; - } - - if (uncompressedData) - { - azfree(uncompressedData); - uncompressedData = 0; - } - } -}; - - -// --------------------------------------------------------------------------- -static void PackFileFromDisc(PackFileJob* job); -class PackFilePool -{ -public: - PackFilePool(int numFiles, size_t memoryLimit) - : m_pool(false) - , m_skip(false) - , m_awaitedFile(0) - , m_memoryLimit(memoryLimit) - , m_allocatedMemory(0) - { - m_files.reserve(numFiles); - } - - ~PackFilePool() - { - } - - void Submit(int key, const PackFileJob& job) - { - PackFileJob* newJob = new PackFileJob(job); - - // index in queue, and custom key for identification - newJob->index = int(m_files.size()); - newJob->key = key; - - m_files.push_back(newJob); - } - - PackFileJob* WaitForFile(int index) - { - while (true) - { - { - AZStd::lock_guard lock(m_filesLock); - m_awaitedFile = index; - if (size_t(index) >= m_files.size()) - { - return 0; - } - if (m_files[index]) - { - return m_files[index]; - } - } - Sleep(0); - } - - assert(0); - return 0; - } - - void Start(unsigned numExtraThreads) - { - if (numExtraThreads == 0) - { - for (PackFileJob* job : m_files) - { - PackFileFromDisc(job); - } - } - else - { - for (size_t i = 0; i < m_files.size(); ++i) - { - PackFileJob* job = m_files[i]; - m_files[i] = 0; - m_pool.Submit(&ProcessFile, job); - } - - m_pool.Start(numExtraThreads); - } - } - - size_t GetJobCount() const - { - return m_files.size(); - } - - void SkipPendingFiles() - { - m_skip = true; - } - - void ReleaseFile(int index) - { - assert(m_files[index] != 0); - if (m_files[index]) - { - if (m_memoryLimit != 0) - { - AZStd::lock_guard lock(m_filesLock); - - m_allocatedMemory -= m_files[index]->uncompressedSize; - m_allocatedMemory -= m_files[index]->compressedSize; - } - - delete m_files[index]; - m_files[index] = 0; - } - } - -private: - - // called from non-main thread - static void ProcessFile(PackFileJob* job) - { - PackFilePool* self = job->batch->pool; - - if (!self->m_skip) - { - if (self->m_memoryLimit != 0) - { - while (true) - { - size_t allocatedMemory = 0; - int awaitedFile = 0; - { - AZStd::lock_guard lock(self->m_filesLock); - allocatedMemory = self->m_allocatedMemory; - awaitedFile = self->m_awaitedFile; - } - - if (allocatedMemory > self->m_memoryLimit && job->index > awaitedFile + 1) - { - Sleep(10); // give time to main thread to write data to file - } - else - { - break; - } - } - } - - PackFileFromDisc(job); - } - - self->FileCompleted(job); - } - - // called from non-main thread - void FileCompleted(PackFileJob* job) - { - AZStd::lock_guard lock(m_filesLock); - - assert(job); - assert(job->index < m_files.size()); - assert(m_files[job->index] == 0); - m_files[job->index] = job; - - if (m_memoryLimit != 0) - { - m_allocatedMemory += job->uncompressedSize; - m_allocatedMemory += job->compressedSize; - } - } - - size_t m_memoryLimit; - - AZStd::mutex m_filesLock; - std::vector m_files; - int m_awaitedFile; - size_t m_allocatedMemory; - bool m_skip; - - ThreadUtils::SimpleThreadPool m_pool; -}; - -////////////////////////////////////////////////////////////////////////// -static size_t AlignTo(size_t offset, size_t alignment) -{ - const size_t remainder = offset % alignment; - return remainder ? offset + alignment - remainder : offset; -} -////////////////////////////////////////////////////////////////////////// -// Calculates new offset of the header to make sure that following data are -// aligned properly -static size_t CalculateAlignedHeaderOffset(const char* fileName, size_t currentOffset, size_t alignment) -{ - // Since file should start from header - if (currentOffset == 0) - { - return 0; - } - - // Local header is followed by filename - const size_t totalHeaderSize = sizeof(ZipFile::LocalFileHeader) + strlen(fileName); - - // Align end of the header - const size_t dataOffset = AlignTo(currentOffset + totalHeaderSize, alignment); - - return dataOffset - totalHeaderSize; -} - -////////////////////////////////////////////////////////////////////////// -ZipDir::CacheRW::CacheRW(bool encryptHeaders, const EncryptionKey& encryptionKey) - : m_pFile (NULL) - , m_nFlags (0) - , m_lCDROffset (0) - , m_fileAlignment (1) - , m_bEncryptedHeaders(encryptHeaders) - , m_bHeadersEncryptedOnClose(encryptHeaders) - , m_encryptionKey(encryptionKey) -{ - m_nRefCount = 0; -} -////////////////////////////////////////////////////////////////////////// -ZipDir::CacheRW::~CacheRW() -{ - Close(); -} -////////////////////////////////////////////////////////////////////////// -void ZipDir::CacheRW::AddRef() -{ - ++m_nRefCount; -} - -////////////////////////////////////////////////////////////////////////// -void ZipDir::CacheRW::Release() -{ - if (--m_nRefCount <= 0) - { - delete this; - } -} - -void ZipDir::CacheRW::Close() -{ - if (m_pFile) - { - if (!(m_nFlags & FLAGS_READ_ONLY)) - { - if ((m_nFlags & FLAGS_UNCOMPACTED) && !(m_nFlags & FLAGS_DONT_COMPACT)) - { - if (!RelinkZip()) - { - WriteCDR(); - } - } - else - if (m_nFlags & FLAGS_CDR_DIRTY) - { - WriteCDR(); - } - } - - if (m_pFile) // RelinkZip() might have closed the file - { - fclose (m_pFile); - } - - m_pFile = NULL; - } - m_treeDir.Clear(); -} - -////////////////////////////////////////////////////////////////////////// -char* ZipDir::CacheRW::UnifyPath(char* const str, const char* pPath) -{ - assert(str); - const char* src = pPath; - char* trg = str; - while (*src) - { - if (*src != '/') - { - *trg++ = ::tolower(*src++); - } - else - { - *trg++ = '\\'; - src++; - } - } - *trg = 0; - return str; -} - -////////////////////////////////////////////////////////////////////////// -char* ZipDir::CacheRW::ToUnixPath(char* const str, const char* pPath) -{ - assert(str); - const char* src = pPath; - char* trg = str; - while (*src) - { - if (*src != '/') - { - *trg++ = *src++; - } - else - { - *trg++ = '\\'; - src++; - } - } - *trg = 0; - return str; -} - -////////////////////////////////////////////////////////////////////////// -char* ZipDir::CacheRW::AllocPath(const char* pPath) -{ - char str[_MAX_PATH]; - char* temp = ToUnixPath(str, pPath); - temp = m_tempStringPool.Append(temp, strlen(temp)); - return temp; -} - -static bool UseZlibForFileType(const char* filename) -{ - AZStd::string f(filename); - - //some files types are forced to use zlib - bool found = AzFramework::StringFunc::Path::IsExtension(filename, ".dds") || f.find("cover.ctc") != string::npos || AzFramework::StringFunc::Path::IsExtension(filename, ".uicanvas"); - - return found; -} - -#ifdef AZ_DEBUG_BUILD -static const char* CodecAsString(CompressionCodec::Codec codec) -{ - switch (codec) - { - case CompressionCodec::Codec::ZLIB: - return "ZLIB"; - case CompressionCodec::Codec::ZSTD: - return "ZSTD"; - case CompressionCodec::Codec::LZ4: - return "LZ4"; - } - return "ERROR"; -} -#endif - -static bool CompressData(PackFileJob *job) -{ - bool bUseZlib = UseZlibForFileType(job->relativePathSrc) || (job->compressionPolicy == PACKFILE_USE_REQUESTED_COMPRESSOR); - - bool compressionSuccessful = true; - - if (bUseZlib) - { - job->compressedSize = ZipDir::GetCompressedSizeEstimate(job->uncompressedSize,CompressionCodec::Codec::ZLIB); - job->compressedData = azmalloc(job->compressedSize); - int error = ZipDir::ZipRawCompress(job->uncompressedData, &job->compressedSize, job->compressedData, job->uncompressedSize, job->batch->compressionLevel); - if (error == Z_OK) - { - job->status = PACKFILE_COMPRESSED; - job->zdError = ZipDir::ZD_ERROR_SUCCESS; - } - else - { - compressionSuccessful = false; - } - } - else - { - unsigned long compressedSize[static_cast(CompressionCodec::Codec::NUM_CODECS)]; - void* compressedData[static_cast(CompressionCodec::Codec::NUM_CODECS)]; - std::chrono::milliseconds decompressionTime[static_cast(CompressionCodec::Codec::NUM_CODECS)]; - bool compressionCodecWasSuccessful[static_cast(CompressionCodec::Codec::NUM_CODECS)]; - - std::chrono::time_point start; - - //do compression - for (CompressionCodec::Codec codec : CompressionCodec::s_AllCodecs) - { - unsigned int index = static_cast(codec); - compressedSize[index] = ZipDir::GetCompressedSizeEstimate(job->uncompressedSize, codec); - compressedData[index] = azmalloc(compressedSize[index]); - AZStd::unique_ptr tempBuffer; - unsigned long tempSize = 0; - - //some files decompress so fast they are beyond our ability to measure so we need to do it a few times to get a reading - int numTimesToDecompress = 1 + ZipDir::TARGET_MIN_TEST_COMPRESS_BYTES / job->uncompressedSize; - - auto testDecompressionTime = [&tempSize, job, &tempBuffer, &start, &compressionCodecWasSuccessful, index, numTimesToDecompress, &compressedData, &compressedSize, &decompressionTime]() { - tempSize = job->uncompressedSize; - tempBuffer = AZStd::make_unique(tempSize); - start = std::chrono::high_resolution_clock::now(); - - //start by assuming the decompression test is never going to result in an error - compressionCodecWasSuccessful[index] = true; - - for (int i = 0; i < numTimesToDecompress; i++) - { - int zerror = ZipDir::ZipRawUncompress(tempBuffer.get(), &tempSize, compressedData[index], compressedSize[index]); - if (zerror != Z_OK) - { - compressionCodecWasSuccessful[index] = false; - break; - } - } - decompressionTime[index] = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); - }; - - switch (codec) - { - case CompressionCodec::Codec::ZLIB: - if (ZipDir::ZipRawCompress(job->uncompressedData, &compressedSize[index], compressedData[index], job->uncompressedSize, job->batch->compressionLevel) == Z_OK) - { - testDecompressionTime(); - } - else - { - compressionCodecWasSuccessful[index] = false; - } - break; - - case CompressionCodec::Codec::ZSTD: - if (ZipDir::ZipRawCompressZSTD(job->uncompressedData, &compressedSize[index], compressedData[index], job->uncompressedSize, 1) == Z_OK) - { - testDecompressionTime(); - } - else - { - compressionCodecWasSuccessful[index] = false; - } - break; - - case CompressionCodec::Codec::LZ4: - if (ZipDir::ZipRawCompressLZ4(job->uncompressedData, &compressedSize[index], compressedData[index], job->uncompressedSize, job->batch->compressionLevel) == Z_OK) - { - testDecompressionTime(); - } - else - { - compressionCodecWasSuccessful[index] = false; - } - - break; - - default: - break; - } - } - - //check decompression speed - int bestTimeIndex = -1; - int numberOfSuccessfulCodecs = 0; - for (CompressionCodec::Codec codec : CompressionCodec::s_AllCodecs) - { - int index = static_cast(codec); - if (compressionCodecWasSuccessful[index]) - { - numberOfSuccessfulCodecs++; - if (bestTimeIndex == -1) - { - bestTimeIndex = index; - continue; - } - if ((decompressionTime[index] < decompressionTime[bestTimeIndex])) - { - bestTimeIndex = index; - } - } - } - - if (!numberOfSuccessfulCodecs) - { - AZ_Error("ZipDirCacheRW", false, "None of the available codecs were able to compress the file: %s", job->relativePathSrc); - compressionSuccessful = false; - } - else - { -#ifdef AZ_DEBUG_BUILD - AZ_Printf("ZipDirCacheRW", "Winner for %s is %s with: %d ms ", job->realFilename, CodecAsString(static_cast(bestTimeIndex)), decompressionTime[bestTimeIndex]); -#endif - } - - //get rid of losing data - for (CompressionCodec::Codec codec : CompressionCodec::s_AllCodecs) - { - int index = static_cast(codec); - if (index != bestTimeIndex) - { - azfree(compressedData[index]); - compressedData[index] = nullptr; - } - } - - if (compressionSuccessful) - { - job->compressedSize = compressedSize[bestTimeIndex]; - job->compressedData = compressedData[bestTimeIndex]; - } - } - - //if there was a problem with the compression so just store the file - if (!compressionSuccessful) - { - azfree(job->compressedData); - job->compressedData = job->uncompressedData; - job->compressedSize = job->uncompressedSize; - } - job->status = PACKFILE_COMPRESSED; - job->zdError = ZipDir::ZD_ERROR_SUCCESS; - return true; -} - -static void PackFileFromMemory(PackFileJob* job) -{ - if (job->existingCRC != 0) - { - unsigned int crcCode = (unsigned int)crc32(0, (unsigned char*)job->uncompressedData, job->uncompressedSize); - if (crcCode == job->existingCRC) - { - job->compressedData = 0; - job->compressedSize = 0; - job->status = PACKFILE_UPTODATE; - job->zdError = ZipDir::ZD_ERROR_SUCCESS; - // This file with same data already in pak, skip it. - return; - } - } - - switch (job->batch->compressionMethod) - { - case ZipFile::METHOD_DEFLATE_AND_ENCRYPT: - case ZipFile::METHOD_DEFLATE: - { - // allocate memory for compression. Min is nSize * 1.001 + 12 - if (job->uncompressedSize > 0) - { - CompressData(job); - } - else - { - job->status = PACKFILE_COMPRESSED; - job->zdError = ZipDir::ZD_ERROR_SUCCESS; - - job->compressedSize = 0; - job->compressedData = 0; - } - break; - } - case ZipFile::METHOD_STORE: - job->compressedData = job->uncompressedData; - job->compressedSize = job->uncompressedSize; - job->status = PACKFILE_COMPRESSED; - job->zdError = ZipDir::ZD_ERROR_SUCCESS; - break; - - default: - job->status = PACKFILE_FAILED; - job->zdError = ZipDir::ZD_ERROR_UNSUPPORTED; - break; - } -} - -bool ZipDir::CacheRW::WriteCompressedData(const char* data, size_t size, bool encrypt, FILE* file) -{ - if (size <= 0) - { - return true; - } - - std::vector buffer; - if (encrypt) - { - buffer.resize(size); - memcpy(&buffer[0], data, size); - ZipDir::Encrypt(&buffer[0], size, m_encryptionKey); - data = &buffer[0]; - } - - // Danny - writing a single large chunk (more than 6MB?) causes - // Windows fwrite to (silently?!) fail. So we're writing data - // in small chunks. - while (size > 0) - { - const size_t sizeToWrite = Util::getMin(size, size_t(1024 * 1024)); - if (fwrite(data, sizeToWrite, 1, file) != 1) - { - return false; - } - data += sizeToWrite; - size -= sizeToWrite; - } - - return true; -} - -static bool WriteRandomData(FILE* file, size_t size) -{ - if (size <= 0) - { - return true; - } - - const size_t bufferSize = Util::getMin(size, size_t(1024 * 1024)); - std::vector buffer(bufferSize); - - while (size > 0) - { - const size_t sizeToWrite = Util::getMin(size, bufferSize); - - for (size_t i = 0; i < sizeToWrite; ++i) - { - buffer[i] = rand() & 0xff; - } - - if (fwrite(&buffer[0], sizeToWrite, 1, file) != 1) - { - return false; - } - - size -= sizeToWrite; - } - - return true; -} - -bool ZipDir::CacheRW::WriteNullData(size_t size) -{ - if (size <= 0) - { - return true; - } - - const size_t bufferSize = Util::getMin(size, size_t(1024 * 1024)); - std::vector buffer(bufferSize, 0); - - while (size > 0) - { - const size_t sizeToWrite = Util::getMin(size, bufferSize); - - if (fwrite(&buffer[0], sizeToWrite, 1, m_pFile) != 1) - { - return false; - } - - size -= sizeToWrite; - } - - return true; -} - -void ZipDir::CacheRW::StorePackedFile(PackFileJob* job) -{ - if (job->batch->zipMaxSize > 0 && GetTotalFileSize() > job->batch->zipMaxSize) - { - job->status = PACKFILE_SKIPPED; - job->zdError = ZipDir::ZD_ERROR_SUCCESS; - return; - } - - job->status = PACKFILE_FAILED; - - char str[_MAX_PATH]; - char* relativePath = UnifyPath(str, job->relativePathSrc); - - // create or find the file entry.. this object will rollback (delete the object - // if the operation fails) if needed. - FileEntryTransactionAdd pFileEntry(this, AllocPath(job->relativePathSrc), AllocPath(relativePath)); - - if (!pFileEntry) - { - job->zdError = ZipDir::ZD_ERROR_INVALID_PATH; - return; - } - - pFileEntry->OnNewFileData(job->uncompressedData, job->uncompressedSize, - job->compressedSize, job->batch->compressionMethod, false); - pFileEntry->SetFromFileTimeNTFS(job->modTime); - - // since we changed the time, we'll have to update CDR - m_nFlags |= FLAGS_CDR_DIRTY; - - // the new CDR position, if the operation completes successfully - unsigned lNewCDROffset = m_lCDROffset; - - if (pFileEntry->IsInitialized()) - { - // this file entry is already allocated in CDR - - // check if the new compressed data fits into the old place - unsigned nFreeSpace = pFileEntry->nEOFOffset - pFileEntry->nFileHeaderOffset - (unsigned)sizeof(ZipFile::LocalFileHeader) - (unsigned)strlen(relativePath); - - if (nFreeSpace != job->compressedSize) - { - m_nFlags |= FLAGS_UNCOMPACTED; - } - - if (nFreeSpace >= job->compressedSize) - { - // and we can just override the compressed data in the file - ErrorEnum e = WriteLocalHeader(m_pFile, pFileEntry, job->relativePathSrc, m_bEncryptedHeaders); - if (e != ZipDir::ZD_ERROR_SUCCESS) - { - job->zdError = e; - return; - } - } - else - { - // we need to write the file anew - in place of current CDR - pFileEntry->nFileHeaderOffset = CalculateAlignedHeaderOffset(job->relativePathSrc, m_lCDROffset, m_fileAlignment); - ErrorEnum e = WriteLocalHeader(m_pFile, pFileEntry, job->relativePathSrc, m_bEncryptedHeaders); - lNewCDROffset = pFileEntry->nEOFOffset; - if (e != ZipDir::ZD_ERROR_SUCCESS) - { - job->zdError = e; - return; - } - } - } - else - { - pFileEntry->nFileHeaderOffset = CalculateAlignedHeaderOffset(job->relativePathSrc, m_lCDROffset, m_fileAlignment); - ErrorEnum e = WriteLocalHeader(m_pFile, pFileEntry, job->relativePathSrc, m_bEncryptedHeaders); - if (e != ZipDir::ZD_ERROR_SUCCESS) - { - job->zdError = e; - return; - } - - lNewCDROffset = pFileEntry->nFileDataOffset + job->compressedSize; - - m_nFlags |= FLAGS_CDR_DIRTY; - } - - // now we have the fresh local header and data offset - -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)pFileEntry->nFileDataOffset, SEEK_SET) != 0) -#else - if (fseek (m_pFile, pFileEntry->nFileDataOffset, SEEK_SET) != 0) -#endif - { - job->zdError = ZD_ERROR_IO_FAILED; - return; - } - - const bool encrypt = pFileEntry->nMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT; - - if (!WriteCompressedData((char*)job->compressedData, job->compressedSize, encrypt, m_pFile)) - { - job->zdError = ZD_ERROR_IO_FAILED; - return; - } - - // since we wrote the file successfully, update the new CDR position - m_lCDROffset = lNewCDROffset; - pFileEntry.Commit(); - - job->status = PACKFILE_ADDED; - job->zdError = ZD_ERROR_SUCCESS; -} - -// Adds a new file to the zip or update an existing one -// adds a directory (creates several nested directories if needed) -ZipDir::ErrorEnum ZipDir::CacheRW::UpdateFile (const char* szRelativePathSrc, void* pUncompressed, unsigned nSize, - unsigned nCompressionMethod, int nCompressionLevel, int64 modTime) -{ - char str[_MAX_PATH]; - char* szRelativePath = UnifyPath(str, szRelativePathSrc); - - - PackFileBatch batch; - batch.compressionMethod = nCompressionMethod; - batch.compressionLevel = nCompressionLevel; - - PackFileJob job; - job.relativePathSrc = szRelativePathSrc; - job.modTime = modTime; - job.uncompressedData = pUncompressed; - job.uncompressedSize = nSize; - job.batch = &batch; - - // crc will be used to check if this file need to be updated at all - ZipDir::FileEntry* entry = FindFile(szRelativePath); - if (entry) - { - job.existingCRC = entry->desc.lCRC32; - } - - PackFileFromMemory(&job); - - switch (job.status) - { - case PACKFILE_SKIPPED: - case PACKFILE_MISSING: - case PACKFILE_FAILED: - return ZD_ERROR_IO_FAILED; - } - - StorePackedFile(&job); - job.DetachUncompressedData(); - return job.zdError; -} - -static FILETIME GetFileWriteTimeAndSize(uint64* fileSize, const char* filename) -{ - // Warning: FindFirstFile on NTFS may report file size that - // is not up-to-date with the actual file content. - // http://blogs.msdn.com/b/oldnewthing/archive/2011/12/26/10251026.aspx - - FILETIME fileTime; - -#if defined(AZ_PLATFORM_WINDOWS) - WIN32_FIND_DATAA FindFileData; - HANDLE hFind = FindFirstFileA(filename, &FindFileData); - - if (hFind == INVALID_HANDLE_VALUE) - { - fileTime.dwLowDateTime = 0; - fileTime.dwHighDateTime = 0; - if (fileSize) - { - *fileSize = 0; - } - } - else - { - fileTime.dwLowDateTime = FindFileData.ftLastWriteTime.dwLowDateTime; - fileTime.dwHighDateTime = FindFileData.ftLastWriteTime.dwHighDateTime; - if (fileSize) - { - *fileSize = (uint64(FindFileData.nFileSizeHigh) << 32) + FindFileData.nFileSizeLow; - } - FindClose(hFind); - } -#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) - //We cant use this implmentation for the windows version because ModificationTime - //returns the time filename was changed(ChangeTime) not last written into(LastWriteTime). - //If LocalFileIO ever adds support for LastWriteTime we can have a common implementation. - AZ::IO::LocalFileIO localFileIO; - AZ::u64 modTime = 0; - modTime = localFileIO.ModificationTime(filename); - if(modTime != 0) - { - fileTime.dwHighDateTime = modTime >> 32; - fileTime.dwLowDateTime = modTime & 0xFFFFFFFF; - if (fileSize) - { - localFileIO.Size(filename, *fileSize); - } - } -#else -#error Needs implmentation! -#endif - return fileTime; -} -static void PackFileFromDisc(PackFileJob* job) -{ - const FILETIME ft = GetFileWriteTimeAndSize(0, job->realFilename); - LARGE_INTEGER lt; - lt.HighPart = ft.dwHighDateTime; - lt.LowPart = ft.dwLowDateTime; - job->modTime = lt.QuadPart; - - FILE* f = nullptr; - azfopen(&f, job->realFilename, "rb"); - if (!f) - { - job->status = PACKFILE_FAILED; - job->zdError = ZipDir::ZD_ERROR_FILE_NOT_FOUND; - return; - } - - fseek(f, 0, SEEK_END); - size_t fileSize = (size_t)ftell(f); - - if ((fileSize < job->batch->sourceMinSize) || (job->batch->sourceMaxSize > 0 && fileSize > job->batch->sourceMaxSize)) - { - fclose(f); - - job->status = PACKFILE_SKIPPED; - job->zdError = ZipDir::ZD_ERROR_SUCCESS; - return; - } - - if (!fileSize) - { - //Allow 0-Bytes long files. - job->uncompressedData = nullptr; - } - else - { - job->uncompressedData = azmalloc(fileSize); - - fseek(f, 0, SEEK_SET); - if (fread(job->uncompressedData, 1, fileSize, f) != fileSize) - { - azfree(job->uncompressedData); - job->uncompressedData = 0; - fclose(f); - - job->status = PACKFILE_FAILED; - job->zdError = ZipDir::ZD_ERROR_IO_FAILED; - return; - } - } - fclose(f); - job->uncompressedSize = fileSize; - - PackFileFromMemory(job); -} - -bool ZipDir::CacheRW::UpdateMultipleFiles(const char** realFilenames, const char** filenamesInZip, size_t fileCount, - int compressionLevel, bool encryptContent, size_t zipMaxSize, int sourceMinSize, int sourceMaxSize, - unsigned numExtraThreads, ZipDir::IReporter* reporter, ZipDir::ISplitter* splitter, bool useFastestDecompressionCodec) -{ - int compressionMethod = ZipFile::METHOD_DEFLATE; - if (encryptContent) - { - compressionMethod = ZipFile::METHOD_DEFLATE_AND_ENCRYPT; - } - else if (compressionLevel == 0) - { - compressionMethod = ZipFile::METHOD_STORE; - } - - uint64 totalSize = 0; - - clock_t startTime = clock(); - - PackFileBatch batch; - batch.compressionLevel = compressionLevel; - batch.compressionMethod = compressionMethod; - batch.sourceMinSize = sourceMinSize; - batch.sourceMaxSize = sourceMaxSize; - batch.zipMaxSize = zipMaxSize; - - const size_t memoryLimit = 1024 * 1024 * 1024; // prevents threads from generating more than 1GB of data - PackFilePool pool(fileCount, memoryLimit); - batch.pool = &pool; - - for (int i = 0; i < fileCount; ++i) - { - const char* realFilename = realFilenames[i]; - const char* filenameInZip = filenamesInZip[i]; - - PackFileJob job; - - job.relativePathSrc = filenameInZip; - job.realFilename = realFilename; - job.batch = &batch; - job.compressionPolicy = useFastestDecompressionCodec ? PACKFILE_USE_FASTEST_DECOMPRESSING_CODEC : PACKFILE_USE_REQUESTED_COMPRESSOR; - - { - // crc will be used to check if this file need to be updated at all - ZipDir::FileEntry* entry = FindFile(filenameInZip); - if (entry) - { - uint64 fileSize = 0; - - const FILETIME ft = GetFileWriteTimeAndSize(&fileSize, realFilename); - LARGE_INTEGER lt; - - lt.HighPart = ft.dwHighDateTime; - lt.LowPart = ft.dwLowDateTime; - job.modTime = lt.QuadPart; - job.existingCRC = entry->desc.lCRC32; - job.compressedSizePreviously = entry->desc.lSizeCompressed; - job.uncompressedSizePreviously = entry->desc.lSizeUncompressed; - - // Check if file with the same name, timestamp and size already exists in pak. - if (entry->CompareFileTimeNTFS(job.modTime) && fileSize == entry->desc.lSizeUncompressed) - { - if (reporter) - { - reporter->ReportUpToDate(filenameInZip); - } - continue; - } - } - } - - pool.Submit(i, job); - } - - // Get the number of submitted jobs, which is at most - // as large as the largest successfully submitted file-index. - // Any number of files can be skipped for submission. - const int jobCount = pool.GetJobCount(); - if (jobCount == 0) - { - return true; - } - - pool.Start(numExtraThreads); - - for (int i = 0; i < jobCount; ++i) - { - PackFileJob* job = pool.WaitForFile(i); - if (!job) - { - assert(job); - continue; - } - - if (job->status == PACKFILE_COMPRESSED) - { - if (splitter) - { - size_t dsk = GetTotalFileSizeOnDiskSoFar(); - size_t bse = 0; - size_t add = 0; - size_t sub = 0; - - bse += sizeof(ZipFile::CDRFileHeader) + strlen(job->relativePathSrc); - bse += sizeof(ZipFile::LocalFileHeader) + strlen(job->relativePathSrc); - - if (job->compressedSize) - { - add += bse + job->compressedSize; - } - if (job->compressedSizePreviously) - { - sub += bse + job->compressedSizePreviously; - } - - if (splitter->CheckWriteLimit(dsk, add, sub)) - { - splitter->SetLastFile(dsk, add, sub, job->key - 1); - - // deplete the pool before leaving the loop - pool.SkipPendingFiles(); - for (; i < jobCount; ++i) - { - pool.WaitForFile(i); - pool.ReleaseFile(i); - } - - break; - } - } - - StorePackedFile(job); - } - - switch (job->status) - { - case PACKFILE_ADDED: - if (reporter) - { - reporter->ReportAdded(job->relativePathSrc); - } - - totalSize += job->uncompressedSize; - break; - case PACKFILE_MISSING: - if (reporter) - { - reporter->ReportMissing(job->realFilename); - } - break; - case PACKFILE_UPTODATE: - if (reporter) - { - reporter->ReportUpToDate(job->realFilename); - } - break; - case PACKFILE_SKIPPED: - if (reporter) - { - reporter->ReportSkipped(job->realFilename); - } - break; - default: - if (reporter) - { - reporter->ReportFailed(job->realFilename, ""); // TODO reason - } - break; - } - - pool.ReleaseFile(i); - } - - clock_t endTime = clock(); - double timeSeconds = double(endTime - startTime) / CLOCKS_PER_SEC; - double speed = (endTime - startTime) == 0 ? 0.0 : double(totalSize) / timeSeconds; - - if (reporter) - { - reporter->ReportSpeed(speed); - } - - return true; -} - - -// Adds a new file to the zip or update an existing one if it is not compressed - just stored - start a big file -ZipDir::ErrorEnum ZipDir::CacheRW::StartContinuousFileUpdate(const char* szRelativePathSrc, unsigned nSize) -{ - char str[_MAX_PATH]; - char* szRelativePath = UnifyPath(str, szRelativePathSrc); - - SmartPtr pBufferDestroyer; - - // create or find the file entry.. this object will rollback (delete the object - // if the operation fails) if needed. - FileEntryTransactionAdd pFileEntry(this, AllocPath(szRelativePathSrc), AllocPath(szRelativePath)); - - if (!pFileEntry) - { - return ZD_ERROR_INVALID_PATH; - } - - pFileEntry->OnNewFileData (NULL, nSize, nSize, ZipFile::METHOD_STORE, false); - // since we changed the time, we'll have to update CDR - m_nFlags |= FLAGS_CDR_DIRTY; - - // the new CDR position, if the operation completes successfully - unsigned lNewCDROffset = m_lCDROffset; - if (pFileEntry->IsInitialized()) - { - // check if the new compressed data fits into the old place - unsigned nFreeSpace = pFileEntry->nEOFOffset - pFileEntry->nFileHeaderOffset - (unsigned)sizeof(ZipFile::LocalFileHeader) - (unsigned)strlen(szRelativePath); - - if (nFreeSpace != nSize) - { - m_nFlags |= FLAGS_UNCOMPACTED; - } - - if (nFreeSpace >= nSize) - { - // and we can just override the compressed data in the file - ErrorEnum e = WriteLocalHeader(m_pFile, pFileEntry, szRelativePathSrc, m_bEncryptedHeaders); - if (e != ZD_ERROR_SUCCESS) - { - return e; - } - } - else - { - // we need to write the file anew - in place of current CDR - pFileEntry->nFileHeaderOffset = CalculateAlignedHeaderOffset(szRelativePathSrc, m_lCDROffset, m_fileAlignment); - ErrorEnum e = WriteLocalHeader(m_pFile, pFileEntry, szRelativePathSrc, m_bEncryptedHeaders); - lNewCDROffset = pFileEntry->nEOFOffset; - if (e != ZD_ERROR_SUCCESS) - { - return e; - } - } - } - else - { - pFileEntry->nFileHeaderOffset = CalculateAlignedHeaderOffset(szRelativePathSrc, m_lCDROffset, m_fileAlignment); - ErrorEnum e = WriteLocalHeader(m_pFile, pFileEntry, szRelativePathSrc, m_bEncryptedHeaders); - if (e != ZD_ERROR_SUCCESS) - { - return e; - } - - lNewCDROffset = pFileEntry->nFileDataOffset + nSize; - - m_nFlags |= FLAGS_CDR_DIRTY; - } - -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)pFileEntry->nFileDataOffset, SEEK_SET) != 0) -#else - if (fseek (m_pFile, pFileEntry->nFileDataOffset, SEEK_SET) != 0) -#endif - { - return ZD_ERROR_IO_FAILED; - } - - if (!WriteNullData(nSize)) - { - return ZD_ERROR_IO_FAILED; - } - - pFileEntry->nEOFOffset = pFileEntry->nFileDataOffset; - - // since we wrote the file successfully, update the new CDR position - m_lCDROffset = lNewCDROffset; - pFileEntry.Commit(); - - return ZD_ERROR_SUCCESS; -} - -// Adds a new file to the zip or update an existing's segment if it is not compressed - just stored -// adds a directory (creates several nested directories if needed) -ZipDir::ErrorEnum ZipDir::CacheRW::UpdateFileContinuousSegment (const char* szRelativePathSrc, [[maybe_unused]] unsigned nSize, void* pUncompressed, unsigned nSegmentSize, unsigned nOverwriteSeekPos) -{ - char str[_MAX_PATH]; - char* szRelativePath = UnifyPath(str, szRelativePathSrc); - - SmartPtr pBufferDestroyer; - - // create or find the file entry.. this object will rollback (delete the object - // if the operation fails) if needed. - FileEntryTransactionAdd pFileEntry(this, AllocPath(szRelativePathSrc), AllocPath(szRelativePath)); - - if (!pFileEntry) - { - return ZD_ERROR_INVALID_PATH; - } - - pFileEntry->OnNewFileData (pUncompressed, nSegmentSize, nSegmentSize, ZipFile::METHOD_STORE, true); - // since we changed the time, we'll have to update CDR - m_nFlags |= FLAGS_CDR_DIRTY; - - // this file entry is already allocated in CDR - unsigned lSegmentOffset = pFileEntry->nEOFOffset; - -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)pFileEntry->nFileHeaderOffset, SEEK_SET) != 0) -#else - if (fseek (m_pFile, pFileEntry->nFileHeaderOffset, SEEK_SET) != 0) -#endif - { - return ZD_ERROR_IO_FAILED; - } - - // and we can just override the compressed data in the file - ErrorEnum e = WriteLocalHeader(m_pFile, pFileEntry, szRelativePath, m_bEncryptedHeaders); - if (e != ZD_ERROR_SUCCESS) - { - return e; - } - - if (nOverwriteSeekPos != 0xffffffff) - { - lSegmentOffset = pFileEntry->nFileDataOffset + nOverwriteSeekPos; - } - - // now we have the fresh local header and data offset -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)lSegmentOffset, SEEK_SET) != 0) -#else - if (fseek (m_pFile, lSegmentOffset, SEEK_SET) != 0) -#endif - { - return ZD_ERROR_IO_FAILED; - } - - const bool encrypt = false; // encryption is not supported for continous updates - if (!WriteCompressedData((char*)pUncompressed, nSegmentSize, encrypt, m_pFile)) - { - return ZD_ERROR_IO_FAILED; - } - - if (nOverwriteSeekPos == 0xffffffff) - { - pFileEntry->nEOFOffset = lSegmentOffset + nSegmentSize; - } - - // since we wrote the file successfully, update CDR - pFileEntry.Commit(); - return ZD_ERROR_SUCCESS; -} - - -ZipDir::ErrorEnum ZipDir::CacheRW::UpdateFileCRC (const char* szRelativePathSrc, unsigned dwCRC32) -{ - char str[_MAX_PATH]; - char* szRelativePath = UnifyPath(str, szRelativePathSrc); - - SmartPtr pBufferDestroyer; - - // create or find the file entry.. this object will rollback (delete the object - // if the operation fails) if needed. - FileEntryTransactionAdd pFileEntry(this, AllocPath(szRelativePathSrc), AllocPath(szRelativePath)); - - if (!pFileEntry) - { - return ZD_ERROR_INVALID_PATH; - } - - // since we changed the time, we'll have to update CDR - m_nFlags |= FLAGS_CDR_DIRTY; - - pFileEntry->desc.lCRC32 = dwCRC32; - -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)pFileEntry->nFileHeaderOffset, SEEK_SET) != 0) -#else - if (fseek (m_pFile, pFileEntry->nFileHeaderOffset, SEEK_SET) != 0) -#endif - { - return ZD_ERROR_IO_FAILED; - } - - // and we can just override the compressed data in the file - ErrorEnum e = WriteLocalHeader(m_pFile, pFileEntry, szRelativePath, m_bEncryptedHeaders); - if (e != ZD_ERROR_SUCCESS) - { - return e; - } - - // since we wrote the file successfully, update - pFileEntry.Commit(); - return ZD_ERROR_SUCCESS; -} - - -// deletes the file from the archive -ZipDir::ErrorEnum ZipDir::CacheRW::RemoveFile (const char* szRelativePathSrc) -{ - char str[_MAX_PATH]; - char* szRelativePath = UnifyPath(str, szRelativePathSrc); - - // find the last slash in the path - const char* pSlash = (std::max)(strrchr(szRelativePath, '/'), strrchr(szRelativePath, '\\')); - - const char* pFileName; // the name of the file to delete - - FileEntryTree* pDir; // the dir from which the subdir will be deleted - - if (pSlash) - { - FindDirRW fd (GetRoot()); - // the directory to remove - pDir = fd.FindExact(string (szRelativePath, pSlash - szRelativePath).c_str()); - if (!pDir) - { - return ZD_ERROR_DIR_NOT_FOUND;// there is no such directory - } - pFileName = pSlash + 1; - } - else - { - pDir = GetRoot(); - pFileName = szRelativePath; - } - - ErrorEnum e = pDir->RemoveFile (pFileName); - if (e == ZD_ERROR_SUCCESS) - { - m_nFlags |= FLAGS_UNCOMPACTED | FLAGS_CDR_DIRTY; - } - return e; -} - - -// deletes the directory, with all its descendants (files and subdirs) -ZipDir::ErrorEnum ZipDir::CacheRW::RemoveDir (const char* szRelativePathSrc) -{ - char str[_MAX_PATH]; - char* szRelativePath = UnifyPath(str, szRelativePathSrc); - - // find the last slash in the path - const char* pSlash = (std::max)(strrchr(szRelativePath, '/'), strrchr(szRelativePath, '\\')); - - const char* pDirName; // the name of the dir to delete - - FileEntryTree* pDir; // the dir from which the subdir will be deleted - - if (pSlash) - { - FindDirRW fd (GetRoot()); - // the directory to remove - pDir = fd.FindExact(string (szRelativePath, pSlash - szRelativePath).c_str()); - if (!pDir) - { - return ZD_ERROR_DIR_NOT_FOUND;// there is no such directory - } - pDirName = pSlash + 1; - } - else - { - pDir = GetRoot(); - pDirName = szRelativePath; - } - - ErrorEnum e = pDir->RemoveDir (pDirName); - if (e == ZD_ERROR_SUCCESS) - { - m_nFlags |= FLAGS_UNCOMPACTED | FLAGS_CDR_DIRTY; - } - return e; -} - -// deletes all files and directories in this archive -ZipDir::ErrorEnum ZipDir::CacheRW::RemoveAll() -{ - ErrorEnum e = m_treeDir.RemoveAll(); - if (e == ZD_ERROR_SUCCESS) - { - m_nFlags |= FLAGS_UNCOMPACTED | FLAGS_CDR_DIRTY; - } - return e; -} - -ZipDir::ErrorEnum ZipDir::CacheRW::ReadFile (FileEntry* pFileEntry, void* pCompressed, void* pUncompressed) -{ - if (!pFileEntry) - { - return ZD_ERROR_INVALID_CALL; - } - - if (pFileEntry->desc.lSizeUncompressed == 0) - { - assert (pFileEntry->desc.lSizeCompressed == 0); - return ZD_ERROR_SUCCESS; - } - - assert (pFileEntry->desc.lSizeCompressed > 0); - - ErrorEnum nError = Refresh(pFileEntry); - if (nError != ZD_ERROR_SUCCESS) - { - return nError; - } - -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)pFileEntry->nFileDataOffset, SEEK_SET)) -#else - if (fseek (m_pFile, pFileEntry->nFileDataOffset, SEEK_SET)) -#endif - { - return ZD_ERROR_IO_FAILED; - } - - SmartPtr pBufferDestroyer; - - void* pBuffer = pCompressed; // the buffer where the compressed data will go - - if (pFileEntry->nMethod == 0 && pUncompressed) - { - // we can directly read into the uncompress buffer - pBuffer = pUncompressed; - } - - if (!pBuffer) - { - if (!pUncompressed) - { - // what's the sense of it - no buffers at all? - return ZD_ERROR_INVALID_CALL; - } - - pBuffer = azmalloc(pFileEntry->desc.lSizeCompressed); - pBufferDestroyer.Attach(pBuffer); // we want it auto-freed once we return - } - - if (fread((char*)pBuffer, pFileEntry->desc.lSizeCompressed, 1, m_pFile) != 1) - { - return ZD_ERROR_IO_FAILED; - } - - if (pFileEntry->nMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT) - { - ZipDir::Decrypt((char*)pBuffer, pFileEntry->desc.lSizeCompressed, m_encryptionKey); - } - - // if there's a buffer for uncompressed data, uncompress it to that buffer - if (pUncompressed) - { - if (pFileEntry->nMethod == 0) - { - assert (pBuffer == pUncompressed); - //assert (pFileEntry->nSizeCompressed == pFileEntry->nSizeUncompressed); - //memcpy (pUncompressed, pBuffer, pFileEntry->nSizeCompressed); - } - else - { - unsigned long nSizeUncompressed = pFileEntry->desc.lSizeUncompressed; - if (nSizeUncompressed > 0) - { - if (Z_OK != ZipRawUncompress(pUncompressed, &nSizeUncompressed, pBuffer, pFileEntry->desc.lSizeCompressed)) - { - return ZD_ERROR_CORRUPTED_DATA; - } - } - } - } - - return ZD_ERROR_SUCCESS; -} - - -////////////////////////////////////////////////////////////////////////// -// finds the file by exact path -ZipDir::FileEntry* ZipDir::CacheRW::FindFile (const char* szPathSrc, [[maybe_unused]] bool bFullInfo) -{ - char str[_MAX_PATH]; - char* szPath = UnifyPath(str, szPathSrc); - - ZipDir::FindFileRW fd (GetRoot()); - if (!fd.FindExact(szPath)) - { - assert (!fd.GetFileEntry()); - return NULL; - } - assert (fd.GetFileEntry()); - return fd.GetFileEntry(); -} - -// returns the size of memory occupied by the instance referred to by this cache -size_t ZipDir::CacheRW::GetSize() const -{ - return sizeof(*this) + m_strFilePath.capacity() + m_treeDir.GetSize() - sizeof(m_treeDir); -} - -// returns the compressed size of all the entries -size_t ZipDir::CacheRW::GetCompressedSize() const -{ - return m_treeDir.GetCompressedFileSize(); -} - -// returns the total size of memory occupied by the instance of this cache and all the compressed files -size_t ZipDir::CacheRW::GetTotalFileSize() const -{ - return GetSize() + GetCompressedSize(); -} - -// returns the total size of space occupied on disk by the instance of this cache and all the compressed files -size_t ZipDir::CacheRW::GetTotalFileSizeOnDiskSoFar() -{ - FileRecordList arrFiles(GetRoot()); - FileRecordList::ZipStats statFiles = arrFiles.GetStats(); - - return m_lCDROffset + statFiles.nSizeCDR; -} - -// refreshes information about the given file entry into this file entry -ZipDir::ErrorEnum ZipDir::CacheRW::Refresh (FileEntry* pFileEntry) -{ - if (!pFileEntry) - { - return ZD_ERROR_INVALID_CALL; - } - - if (pFileEntry->nFileDataOffset != pFileEntry->INVALID_DATA_OFFSET) - { - return ZD_ERROR_SUCCESS; // the data offset has been successfully read.. - } - - return ZipDir::Refresh(m_pFile, pFileEntry, m_bEncryptedHeaders); -} - - -// writes the CDR to the disk -bool ZipDir::CacheRW::WriteCDR(FILE* fTarget, bool encryptCDR) -{ - if (!fTarget) - { - return false; - } - -#ifdef WIN32 - if (_fseeki64(fTarget, (__int64)m_lCDROffset, SEEK_SET)) -#else - if (fseek(fTarget, m_lCDROffset, SEEK_SET)) -#endif - { - return false; - } - - FileRecordList arrFiles(GetRoot()); - //arrFiles.SortByFileOffset(); - size_t nSizeCDR = arrFiles.GetStats().nSizeCDR; - void* pCDR = malloc(nSizeCDR); -#if !defined(NDEBUG) - size_t nSizeCDRSerialized = -#endif - arrFiles.MakeZipCDR(m_lCDROffset, pCDR, encryptCDR); - assert (nSizeCDRSerialized == nSizeCDR); - - if (encryptCDR) - { - // We do not encrypt CDREnd, so we could find it by signature - ZipDir::Encrypt((char*)pCDR, nSizeCDR - sizeof(ZipFile::CDREnd), m_encryptionKey); - } - - size_t nWriteRes = fwrite (pCDR, nSizeCDR, 1, fTarget); - free(pCDR); - return nWriteRes == 1; -} - -// generates random file name -string ZipDir::CacheRW::GetRandomName(int nAttempt) -{ - if (nAttempt) - { - char szBuf[8]; - int i; - for (i = 0; i < sizeof(szBuf) - 1; ++i) - { - int r = rand() % (10 + 'z' - 'a' + 1); - szBuf[i] = r > 9 ? (r - 10) + 'a' : '0' + r; - } - szBuf[i] = '\0'; - return szBuf; - } - else - { - return string(); - } -} - -bool ZipDir::CacheRW::RelinkZip() -{ - AZ::IO::LocalFileIO localFileIO; - for (int nAttempt = 0; nAttempt < 32; ++nAttempt) - { - string strNewFilePath = m_strFilePath + "$" + GetRandomName(nAttempt); - - FILE* f = nullptr; - azfopen(&f, strNewFilePath.c_str(), "wb"); - if (f) - { - bool bOk = RelinkZip(f); - fclose (f); // we don't need the temporary file handle anyway - - if (!bOk) - { - // we don't need the temporary file - localFileIO.Remove(strNewFilePath.c_str()); - return false; - } - - // we successfully relinked, now copy the temporary file to the original file - fclose (m_pFile); - m_pFile = NULL; - - localFileIO.Remove(m_strFilePath.c_str()); - if (localFileIO.Rename(strNewFilePath.c_str(), m_strFilePath.c_str()) == 0) - { - // successfully renamed - reopen - m_pFile = nullptr; - azfopen(&m_pFile, m_strFilePath.c_str(), "r+b"); - return m_pFile == NULL; - } - else - { - // could not rename - - //m_pFile = fopen (strNewFilePath.c_str(), "r+b"); - return false; - } - } - } - - // couldn't open temp file - return false; -} - -bool ZipDir::CacheRW::RelinkZip(FILE* fTmp) -{ - FileRecordList arrFiles(GetRoot()); - arrFiles.SortByFileOffset(); - FileRecordList::ZipStats Stats = arrFiles.GetStats(); - - // we back up our file entries, because we'll need to restore them - // in case the operation fails - std::vector arrFileEntryBackup; - arrFiles.Backup (arrFileEntryBackup); - - // this is the set of files that are to be written out - compressed data and the file record iterator - std::vector queFiles; - queFiles.reserve (g_nMaxItemsRelinkBuffer); - - // the total size of data in the queue - unsigned nQueueSize = 0; - - for (FileRecordList::iterator it = arrFiles.begin(); it != arrFiles.end(); ++it) - { - FileEntry* entry = it->pFileEntry; - // find the file data offset - if (ZD_ERROR_SUCCESS != Refresh(entry)) - { - return false; - } - - // go to the file data -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)entry->nFileDataOffset, SEEK_SET) != 0) -#else - if (fseek (m_pFile, entry->nFileDataOffset, SEEK_SET) != 0) -#endif - { - return false; - } - - // allocate memory for the file compressed data - FileDataRecordPtr pFile = FileDataRecord::New (*it); - - if (!pFile) - { - return false; - } - - // read the compressed data - if (entry->desc.lSizeCompressed && fread (pFile->GetData(), entry->desc.lSizeCompressed, 1, m_pFile) != 1) - { - return false; - } - - if (entry->nMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT) - { - ZipDir::Decrypt((char*)pFile->GetData(), entry->desc.lSizeCompressed, m_encryptionKey); - } - - // put the file into the queue for copying (writing) - queFiles.push_back(pFile); - nQueueSize += entry->desc.lSizeCompressed; - - // if the queue is big enough, write it out - if (nQueueSize > g_nSizeRelinkBuffer || queFiles.size() >= g_nMaxItemsRelinkBuffer) - { - nQueueSize = 0; - if (!WriteZipFiles(queFiles, fTmp)) - { - return false; - } - } - } - - if (!WriteZipFiles(queFiles, fTmp)) - { - return false; - } - - ZipFile::ulong lOldCDROffset = m_lCDROffset; - // the file data has now been written out. Now write the CDR -#ifdef WIN32 - m_lCDROffset = (ZipFile::ulong)_ftelli64(fTmp); -#else - m_lCDROffset = ftell(fTmp); -#endif - if (m_lCDROffset >= 0 && WriteCDR(fTmp, m_bHeadersEncryptedOnClose) && 0 == fflush (fTmp)) - { - // the new file positions are already there - just discard the backup and return - return true; - } - // recover from backup - arrFiles.Restore (arrFileEntryBackup); - m_lCDROffset = lOldCDROffset; - m_bEncryptedHeaders = m_bHeadersEncryptedOnClose; - return false; -} - -// writes out the file data in the queue into the given file. Empties the queue -bool ZipDir::CacheRW::WriteZipFiles(std::vector& queFiles, FILE* fTmp) -{ - for (std::vector::iterator it = queFiles.begin(); it != queFiles.end(); ++it) - { - // set the new header offset to the file entry - we won't need it -#ifdef WIN32 - const unsigned long currentPos = (unsigned long)_ftelli64 (fTmp); -#else - const unsigned long currentPos = ftell (fTmp); -#endif - (*it)->pFileEntry->nFileHeaderOffset = CalculateAlignedHeaderOffset((*it)->strPath.c_str(), currentPos, m_fileAlignment); - - // while writing the local header, the data offset will also be calculated - if (ZD_ERROR_SUCCESS != WriteLocalHeader(fTmp, (*it)->pFileEntry, (*it)->strPath.c_str(), m_bHeadersEncryptedOnClose)) - { - return false; - } - ; - - // write the compressed file data - const bool encrypt = (*it)->pFileEntry->nMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT; - if (!WriteCompressedData((char*)(*it)->GetData(), (*it)->pFileEntry->desc.lSizeCompressed, encrypt, fTmp)) - { - return false; - } - -#ifdef WIN32 - assert ((*it)->pFileEntry->nEOFOffset == (unsigned long)_ftelli64 (fTmp)); -#else - assert ((*it)->pFileEntry->nEOFOffset == ftell (fTmp)); -#endif - } - queFiles.clear(); - queFiles.reserve (g_nMaxItemsRelinkBuffer); - return true; -} - -void TruncateFile(FILE* file, size_t newLength) -{ -#if defined(AZ_PLATFORM_WINDOWS) - int filedes = _fileno(file); - _chsize_s(filedes, newLength); -#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) - ftruncate(fileno(file), newLength); -#else -#error Not implemented! -#endif -} - -bool ZipDir::CacheRW::EncryptArchive(EncryptionChange change, IEncryptPredicate* encryptContentPredicate, int* numChanged, int* numSkipped) -{ - FileRecordList arrFiles(GetRoot()); - arrFiles.SortByFileOffset(); - - size_t unusedSpace = 0; - size_t lastDataEnd = 0; - - for (FileRecordList::iterator it = arrFiles.begin(); it != arrFiles.end(); ++it) - { - FileEntry* entry = it->pFileEntry; - - if (entry->nFileHeaderOffset > lastDataEnd) - { - fseek(m_pFile, lastDataEnd, SEEK_SET); - size_t gapLength = entry->nFileHeaderOffset - lastDataEnd; - unusedSpace += gapLength; - if (change == ENCRYPT) - { - if (!WriteRandomData(m_pFile, gapLength)) - { - return false; - } - } - else - { - if (!WriteNullData(gapLength)) - { - return false; - } - } - } - lastDataEnd = entry->nEOFOffset; - - if (numSkipped) - { - ++(*numSkipped); - } - - // find the file data offset - if (ZD_ERROR_SUCCESS != Refresh (entry)) - { - return false; - } - - ZipFile::ushort oldMethod = entry->nMethod; - ZipFile::ushort newMethod = oldMethod; - if (change == ENCRYPT) - { - if (entry->nMethod == ZipFile::METHOD_DEFLATE) - { - newMethod = ZipFile::METHOD_DEFLATE_AND_ENCRYPT; - } - } - else - { - if (entry->nMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT) - { - newMethod = ZipFile::METHOD_DEFLATE; - } - } - - // allow encryption only for matching files - if (newMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT && - (!encryptContentPredicate || !encryptContentPredicate->Match(it->strPath.c_str()))) - { - newMethod = ZipFile::METHOD_DEFLATE; - } - - entry->nMethod = newMethod; - - const bool encryptHeaders = change == ENCRYPT; - // encryption is toggled or compression method changed... - if (newMethod != oldMethod || encryptHeaders != m_bEncryptedHeaders) - { - // ... update header - if (ZipDir::WriteLocalHeader(m_pFile, entry, it->strPath.c_str(), encryptHeaders) != ZD_ERROR_SUCCESS) - { - return false; - } - } - - if (newMethod == oldMethod) - { - // no need to update file content - continue; - } - - // go to the file data -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)entry->nFileDataOffset, SEEK_SET) != 0) -#else - if (fseek (m_pFile, entry->nFileDataOffset, SEEK_SET) != 0) -#endif - { - return false; - } - - // allocate memory for the file compressed data - FileDataRecordPtr pFile = FileDataRecord::New(*it); - if (!pFile) - { - return false; - } - - // read the compressed data - if (entry->desc.lSizeCompressed && fread (pFile->GetData(), entry->desc.lSizeCompressed, 1, m_pFile) != 1) - { - return false; - } - - if (oldMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT) - { - ZipDir::Decrypt((char*)pFile->GetData(), entry->desc.lSizeCompressed, m_encryptionKey); - } - -#ifdef WIN32 - if (_fseeki64 (m_pFile, (__int64)entry->nFileDataOffset, SEEK_SET) != 0) -#else - if (fseek (m_pFile, entry->nFileDataOffset, SEEK_SET) != 0) -#endif - { - return false; - } - - const bool encryptContent = newMethod == ZipFile::METHOD_DEFLATE_AND_ENCRYPT; - if (!WriteCompressedData((const char*)pFile->GetData(), entry->desc.lSizeCompressed, encryptContent, m_pFile)) - { - return false; - } - - if (numSkipped) - { - --(*numSkipped); - } - if (numChanged) - { - ++(*numChanged); - } - } - - m_bEncryptedHeaders = change == ENCRYPT; - m_bHeadersEncryptedOnClose = m_bEncryptedHeaders; - - if (!WriteCDR(m_pFile, m_bEncryptedHeaders)) - { - return false; - } - - if (fflush (m_pFile) != 0) - { - return false; - } - - size_t endOfCDR = (size_t)ftell(m_pFile); - - fseek(m_pFile, 0, SEEK_END); - size_t fileSize = (size_t)ftell(m_pFile); - - if (fileSize != endOfCDR) - { - TruncateFile(m_pFile, endOfCDR); - } - - fclose(m_pFile); - m_pFile = 0; - m_treeDir.Clear(); - return true; -} diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheRW.h b/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheRW.h deleted file mode 100644 index 6c02d34bf3..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirCacheRW.h +++ /dev/null @@ -1,283 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -////////////////////////////////////////////////////////////////////////// -// Declaration of the class that will keep the ZipDir Cache object -// and will provide all its services to access Zip file, plus it will -// provide services to write to the zip file efficiently -// Time to time, the contained Cache object will be recreated during -// an archive add operation - -#pragma once - -#include "SimpleStringPool.h" -#include "StringUtils.h" - -struct PackFileJob; -namespace ZipDir -{ - struct FileDataRecord; - TYPEDEF_AUTOPTR(FileDataRecord); - typedef FileDataRecord_AutoPtr FileDataRecordPtr; - - static constexpr int TARGET_MIN_TEST_COMPRESS_BYTES = 128 * 1024; - - struct IReporter - { - virtual void ReportAdded(const char* filename) = 0; - virtual void ReportMissing(const char* filename) = 0; - virtual void ReportUpToDate(const char* filename) = 0; - virtual void ReportSkipped(const char* filename) = 0; - virtual void ReportFailed(const char* filename, const char* error) = 0; - virtual void ReportSpeed(double bytesPerSecond) = 0; - }; - - struct ISplitter - { - // Arguments: - // total - the current size of the pak - // add - the size of the file to add - // sub - the size of the old version of the file which will be removed from the pak - // Return: - // true if adding the current file to the current pak is still permitted. - virtual bool CheckWriteLimit(size_t total, size_t add, size_t sub) const = 0; - - // Arguments: - // total - the current size of the pak - // add - the size of the file to add - // sub - the size of the old version of the file which will be removed from the pak - // offset - the position of the first file which has not been added to the pak - // in the array passed to "UpdateMultipleFiles()" - virtual void SetLastFile(size_t total, size_t add, size_t sub, int offset) = 0; - }; - - struct IEncryptPredicate - { - virtual ~IEncryptPredicate() = default; - virtual bool Match(const char* filename) = 0; - }; - - class CacheRW - { - public: - enum EncryptionChange - { - ENCRYPT, - DECRYPT - }; - // the size of the buffer that's using during re-linking the zip file - enum - { - g_nSizeRelinkBuffer = 128 * 1024 * 1024, // 128 Mbytes - g_nMaxItemsRelinkBuffer = 1024 // max number of files to read before (without) writing - }; - - void AddRef(); - void Release(); - - - CacheRW(bool encryptHeaders, const EncryptionKey& encryptionKey); - ~CacheRW(); - - bool IsValid () const - { - return m_pFile != NULL; - } - - static char* UnifyPath(char* const str, const char* pPath); - static char* ToUnixPath(char* const str, const char* pPath); - char* AllocPath(const char* pPath); - - // opens the given zip file and connects to it. Creates a new file if no such file exists - // if successful, returns true. - //ErrorEnum Open (CMTSafeHeap* pHeap, InitMethodEnum nInitMethod, unsigned nFlags, const char* szFile); - - // Adds a new file to the zip or update an existing one - // adds a directory (creates several nested directories if needed) - ErrorEnum UpdateFile(const char* szRelativePath, void* pUncompressed, unsigned nSize, unsigned nCompressionMethod, int nCompressionLevel, int64 modTime); - - // Sets if Archive should be encrypted or decrypted on close. - bool EncryptArchive(EncryptionChange change, IEncryptPredicate* encryptContentPredicate, int* numChanged, int* numSkipped); - - // Adds or updates a bunch of files. Creates directories if needed. Multithreaded when numExtraThreads > 0 - bool UpdateMultipleFiles(const char** realFilenames, const char** filenamesInZip, size_t fileCount, - int compressionLevel, bool encryptContent, size_t zipMaxSize, int sourceMinSize, int sourceMaxSize, - unsigned numExtraThreads, ZipDir::IReporter* reporter, ZipDir::ISplitter* splitter = nullptr, bool useFastestDecompressionCodec = false); - - // Adds a new file to the zip or update an existing one if it is not compressed - just stored - start a big file - ErrorEnum StartContinuousFileUpdate(const char* szRelativePath, unsigned nSize); - - // Adds a new file to the zip or update an existing's segment if it is not compressed - just stored - // adds a directory (creates several nested directories if needed) - // Arguments: - // nOverwriteSeekPos - 0xffffffff means the seek pos should not be overwritten - ErrorEnum UpdateFileContinuousSegment (const char* szRelativePath, unsigned nSize, void* pUncompressed, unsigned nSegmentSize, unsigned nOverwriteSeekPos); - - ErrorEnum UpdateFileCRC(const char* szRelativePath, unsigned dwCRC32); - - // deletes the file from the archive - ErrorEnum RemoveFile(const char* szRelativePath); - - // deletes the directory, with all its descendants (files and subdirs) - ErrorEnum RemoveDir(const char* szRelativePath); - - // deletes all files and directories in this archive - ErrorEnum RemoveAll(); - - // closes the current zip file - void Close(); - - FileEntry* FindFile(const char* szPath, bool bFullInfo = false); - - ErrorEnum ReadFile(FileEntry* pFileEntry, void* pCompressed, void* pUncompressed); - - void* AllocAndReadFile (FileEntry* pFileEntry); - - void Free (void* p) - { - free(p); - } - - // refreshes information about the given file entry into this file entry - ErrorEnum Refresh (FileEntry* pFileEntry); - - // returns the size of memory occupied by the instance of this cache - size_t GetSize() const; - - // returns the compressed size of all the entries - size_t GetCompressedSize() const; - - // returns the total size of memory occupied by the instance of this cache and all the compressed files - size_t GetTotalFileSize() const; - - // returns the total size of space occupied on disk by the instance of this cache and all the compressed files - size_t GetTotalFileSizeOnDiskSoFar(); - - // QUICK check to determine whether the file entry belongs to this object - bool IsOwnerOf (const FileEntry* pFileEntry) const - { - return m_treeDir.IsOwnerOf(pFileEntry); - } - - // returns the string - path to the zip file from which this object was constructed. - // this will be "" if the object was constructed with a factory that wasn't created with FLAGS_MEMORIZE_ZIP_PATH - const char* GetFilePath() const - { - return m_strFilePath.c_str(); - } - - FileEntryTree* GetRoot() - { - return &m_treeDir; - } - - const FileEntryTree* GetRoot() const - { - return &m_treeDir; - } - - // writes the CDR to the disk - bool WriteCDR() {return WriteCDR(m_pFile, m_bEncryptedHeaders); } - bool WriteCDR(FILE* fTarget, bool encryptHeaders); - - bool RelinkZip(); - protected: - bool RelinkZip(FILE* fTmp); - // writes out the file data in the queue into the given file. Empties the queue - bool WriteZipFiles(std::vector& queFiles, FILE* fTmp); - // generates random file name - string GetRandomName(int nAttempt); - - bool ReadCompressedData(char* data, size_t size); - bool WriteCompressedData(const char* data, size_t size, bool encrypt, FILE* file); - bool WriteNullData(size_t size); - - void StorePackedFile(PackFileJob* job); - protected: - - friend class CacheFactory; - volatile signed int m_nRefCount; // the reference count - FileEntryTree m_treeDir; - FILE* m_pFile; - string m_strFilePath; - - // offset to the start of CDR in the file,even if there's no CDR there currently - // when a new file is added, it can start from here, but this value will need to be updated then - ZipFile::ulong m_lCDROffset; - - CSimpleStringPool m_tempStringPool; - - enum - { - // if this is set, the file needs to be compacted before it can be used by - // all standard zip tools, because gaps between file datas can be present - FLAGS_UNCOMPACTED = 1 << 0, - // if this is set, the CDR needs to be written to the file - FLAGS_CDR_DIRTY = 1 << 1, - // if this is set, the file is opened in read-only mode. no write operations are to be performed - FLAGS_READ_ONLY = 1 << 2, - // when this is set, compact operation is not performed - FLAGS_DONT_COMPACT = 1 << 3 - }; - unsigned m_nFlags; - size_t m_fileAlignment; - - // CDR buffer. - DynArray m_CDR_buffer; - // unified names buffer - DynArray m_unifiedNameBuffer; - - EncryptionKey m_encryptionKey; - bool m_bEncryptedHeaders; - bool m_bHeadersEncryptedOnClose; - }; - - TYPEDEF_AUTOPTR(CacheRW); - typedef CacheRW_AutoPtr CacheRWPtr; - - // creates and if needed automatically destroys the file entry - class FileEntryTransactionAdd - { - class CacheRW* m_pCache; - char m_szPath[_MAX_PATH]; - FileEntry* m_pFileEntry; - bool m_bComitted; - public: - operator FileEntry* () { - return m_pFileEntry; - } - operator bool() const{ - return m_pFileEntry != NULL; - } - FileEntry* operator -> () {return m_pFileEntry; } - FileEntryTransactionAdd(class CacheRW* pCache, char* szPath, char* szUnifiedPath) - : m_pCache(pCache) - , m_bComitted (false) - { - // we need to copy path, because original one will be destroyed by FileEntryTree::Add call - cry_strcpy(m_szPath, szUnifiedPath); - m_pFileEntry = m_pCache->GetRoot()->Add(szPath, szUnifiedPath); - } - ~FileEntryTransactionAdd() - { - if (m_pFileEntry && !m_bComitted) - { - m_pCache->RemoveFile(m_szPath); - } - } - void Commit() - { - m_bComitted = true; - } - }; -} diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirFind.cpp b/Code/Tools/CryCommonTools/ZipDir/ZipDirFind.cpp deleted file mode 100644 index c62428f0b1..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirFind.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include "smartptr.h" -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include "ZipDirCache.h" -#include "ZipDirFind.h" -#include "StringHelpers.h" - -bool ZipDir::FindFile::FindFirst (const char* szWildcard) -{ - if (!PreFind (szWildcard)) - { - return false; - } - - // finally, this is the name of the file - m_nFileEntry = 0; - return SkipNonMatchingFiles(); -} - -bool ZipDir::FindDir::FindFirst (const char* szWildcard) -{ - if (!PreFind (szWildcard)) - { - return false; - } - - // finally, this is the name of the file - m_nDirEntry = 0; - return SkipNonMatchingDirs(); -} - -// matches the file wilcard in the m_szWildcard to the given file/dir name -// this takes into account the fact that xxx. is the alias name for xxx -bool ZipDir::FindData::MatchWildcard(const char* szName) -{ - if (StringHelpers::MatchesWildcards(szName, m_szWildcard)) - { - return true; - } - - // check if the file object name contains extension sign (.) - const char* p; - for (p = szName; *p && *p != '.'; ++p) - { - continue; - } - - if (*p) - { - // there's an extension sign in the object, but it wasn't matched.. - assert (*p == '.'); - return false; - } - - // no extension sign - add it - char szAlias[_MAX_PATH + 2]; - size_t nLength = p - szName; - if (nLength > _MAX_PATH) - { - nLength = _MAX_PATH; - } - memcpy (szAlias, szName, nLength); - szAlias[nLength] = '.'; // add the alias - szAlias[nLength + 1] = '\0'; // terminate the string - return StringHelpers::MatchesWildcards(szAlias, m_szWildcard); -} - - -ZipDir::FileEntry* ZipDir::FindFile::FindExact (const char* szPath) -{ - if (!PreFind (szPath)) - { - return NULL; - } - - FileEntry* pFileEntry = m_pDirHeader->FindFileEntry(m_szWildcard); - if (pFileEntry) - { - m_nFileEntry = (unsigned)(pFileEntry - m_pDirHeader->GetFileEntry(0)); - } - else - { - m_pDirHeader = NULL; // we didn't find it, fail the search - } - return pFileEntry; -} - -////////////////////////////////////////////////////////////////////////// -// after this call returns successfully (with true returned), the m_szWildcard -// contains the file name/wildcard and m_pDirHeader contains the directory where -// the file (s) are to be found -bool ZipDir::FindData::PreFind (const char* szWildcard) -{ - if (!m_pRoot) - { - return false; - } - - // start the search from the root - m_pDirHeader = m_pRoot; - - // for each path dir name, copy it into the buffer and try to find the subdirectory - const char* pPath = szWildcard; - for (;; ) - { - char* pName = m_szWildcard; - - // at first we'll use the wildcard memory to save the directory names - for (; *pPath && *pPath != '/' && *pPath != '\\' && pName < m_szWildcard + sizeof(m_szWildcard) - 1; ++pPath, ++pName) - { - *pName = ::tolower(*pPath); - } - *pName = '\0'; - - if (*pPath) - { - if (*pPath != '/' && *pPath != '\\') - { - return false;//ZD_ERROR_NAME_TOO_LONG; - } - // this is the name of the directory - DirEntry* pDirEntry = m_pDirHeader->FindSubdirEntry(m_szWildcard); - if (!pDirEntry) - { - m_pDirHeader = NULL; // finish the search - return false; - } - m_pDirHeader = pDirEntry->GetDirectory(); - ++pPath; - assert(m_pDirHeader); - } - else - { - // finally, this is the name of the file (or directory) - return true; - } - } -} - -// goes on to the next entry -bool ZipDir::FindFile::FindNext () -{ - if (m_pDirHeader && m_nFileEntry < m_pDirHeader->numFiles) - { - ++m_nFileEntry; - return SkipNonMatchingFiles(); - } - else - { - return false; - } -} - -// goes on to the next entry -bool ZipDir::FindDir::FindNext () -{ - if (m_pDirHeader && m_nDirEntry < m_pDirHeader->numDirs) - { - ++m_nDirEntry; - return SkipNonMatchingDirs(); - } - else - { - return false; - } -} - -bool ZipDir::FindFile::SkipNonMatchingFiles() -{ - assert(m_pDirHeader && m_nFileEntry <= m_pDirHeader->numFiles); - - for (; m_nFileEntry < m_pDirHeader->numFiles; ++m_nFileEntry) - { - if (MatchWildcard(GetFileName())) - { - return true; - } - } - // we didn't find anything other file else - return false; -} - -bool ZipDir::FindDir::SkipNonMatchingDirs() -{ - assert(m_pDirHeader && m_nDirEntry <= m_pDirHeader->numDirs); - - for (; m_nDirEntry < m_pDirHeader->numDirs; ++m_nDirEntry) - { - if (MatchWildcard(GetDirName())) - { - return true; - } - } - // we didn't find anything other file else - return false; -} - - -ZipDir::FileEntry* ZipDir::FindFile::GetFileEntry() -{ - return m_pDirHeader && m_nFileEntry < m_pDirHeader->numFiles ? m_pDirHeader->GetFileEntry(m_nFileEntry) : NULL; -} -ZipDir::DirEntry* ZipDir::FindDir::GetDirEntry() -{ - return m_pDirHeader && m_nDirEntry < m_pDirHeader->numDirs ? m_pDirHeader->GetSubdirEntry(m_nDirEntry) : NULL; -} - -const char* ZipDir::FindFile::GetFileName () -{ - if (m_pDirHeader && m_nFileEntry < m_pDirHeader->numFiles) - { - const char* pNamePool = m_pDirHeader->GetNamePool(); - return m_pDirHeader->GetFileEntry(m_nFileEntry)->GetName(pNamePool); - } - else - { - return ""; // default name - } -} - -const char* ZipDir::FindDir::GetDirName () -{ - if (m_pDirHeader && m_nDirEntry < m_pDirHeader->numDirs) - { - const char* pNamePool = m_pDirHeader->GetNamePool(); - return m_pDirHeader->GetSubdirEntry(m_nDirEntry)->GetName(pNamePool); - } - else - { - return ""; // default name - } -} diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirFind.h b/Code/Tools/CryCommonTools/ZipDir/ZipDirFind.h deleted file mode 100644 index 99e95607c1..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirFind.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRFIND_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRFIND_H -#pragma once - - -namespace ZipDir -{ - // create this structure and loop: - // FindData fd (pZip); - // for (fd.FindFirst("*.cgf"); fd.GetFileEntry(); fd.FindNext()) - // {} // inside the loop, use GetFileEntry() and GetFileName() to get the file entry and name records - class FindData - { - public: - - FindData (DirHeader* pRoot) - : m_pRoot (pRoot) - , m_pDirHeader (NULL) - { - } - - protected: - // initializes everything until the point where the file must be searched for - // after this call returns successfully (with true returned), the m_szWildcard - // contains the file name/wildcard and m_pDirHeader contains the directory where - // the file (s) are to be found - bool PreFind (const char* szWildcard); - - // matches the file wilcard in the m_szWildcard to the given file/dir name - // this takes into account the fact that xxx. is the alias name for xxx - bool MatchWildcard(const char* szName); - - DirHeader* m_pRoot; // the zip file inwhich the search is performed - DirHeader* m_pDirHeader; // the header of the directory in which the files reside - //unsigned m_nDirEntry; // the current directory entry inside the parent directory - - // the actual wildcard being used in the current scan - the file name wildcard only! - char m_szWildcard[_MAX_PATH]; - }; - - class FindFile - : public FindData - { - public: - FindFile (Cache* pCache) - : FindData(pCache->GetRoot()) - { - } - FindFile (DirHeader* pRoot) - : FindData(pRoot) - { - } - // if bExactFile is passed, only the file is searched, and besides with the exact name as passed (no wildcards) - bool FindFirst (const char* szWildcard); - - FileEntry* FindExact (const char* szPath); - - // goes on to the next file entry - bool FindNext (); - - FileEntry* GetFileEntry(); - const char* GetFileName (); - - protected: - bool SkipNonMatchingFiles(); - unsigned m_nFileEntry; // the current file index inside the parent directory - }; - - class FindDir - : public FindData - { - public: - FindDir (Cache* pCache) - : FindData(pCache->GetRoot()) - { - } - FindDir (DirHeader* pRoot) - : FindData(pRoot) - { - } - // if bExactFile is passed, only the file is searched, and besides with the exact name as passed (no wildcards) - bool FindFirst (const char* szWildcard); - - // goes on to the next file entry - bool FindNext (); - - DirEntry* GetDirEntry(); - const char* GetDirName (); - - protected: - bool SkipNonMatchingDirs(); - unsigned m_nDirEntry; // the current dir index inside the parent directory - }; -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRFIND_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirFindRW.cpp b/Code/Tools/CryCommonTools/ZipDir/ZipDirFindRW.cpp deleted file mode 100644 index a44f8dd45e..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirFindRW.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include "smartptr.h" -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include "ZipDirTree.h" -#include "ZipDirCacheRW.h" -#include "ZipDirFindRW.h" -#include "StringHelpers.h" - -bool ZipDir::FindFileRW::FindFirst (const char* szWildcard) -{ - if (!PreFind (szWildcard)) - { - return false; - } - - // finally, this is the name of the file - m_itFile = m_pDirHeader->GetFileBegin(); - return SkipNonMatchingFiles(); -} - -bool ZipDir::FindDirRW::FindFirst (const char* szWildcard) -{ - if (!PreFind (szWildcard)) - { - return false; - } - - // finally, this is the name of the file - m_itDir = m_pDirHeader->GetDirBegin(); - return SkipNonMatchingDirs(); -} - -// matches the file wilcard in the m_szWildcard to the given file/dir name -// this takes into account the fact that xxx. is the alias name for xxx -bool ZipDir::FindDataRW::MatchWildcard(const char* szName) -{ - if (StringHelpers::MatchesWildcards(szName, m_szWildcard)) - { - return true; - } - - // check if the file object name contains extension sign (.) - const char* p; - for (p = szName; *p && *p != '.'; ++p) - { - continue; - } - - if (*p) - { - // there's an extension sign in the object, but it wasn't matched.. - assert (*p == '.'); - return false; - } - - // no extension sign - add it - char szAlias[_MAX_PATH + 2]; - size_t nLength = p - szName; - if (nLength > _MAX_PATH) - { - nLength = _MAX_PATH; - } - memcpy (szAlias, szName, nLength); - szAlias[nLength] = '.'; // add the alias - szAlias[nLength + 1] = '\0'; // terminate the string - return StringHelpers::MatchesWildcards(szAlias, m_szWildcard); -} - - -ZipDir::FileEntry* ZipDir::FindFileRW::FindExact (const char* szPath) -{ - if (!PreFind (szPath)) - { - return NULL; - } - - FileEntryTree::FileMap::iterator itFile = m_pDirHeader->FindFile(m_szWildcard); - if (itFile != m_pDirHeader->GetFileEnd()) - { - m_itFile = itFile; - } - else - { - m_pDirHeader = NULL; // we didn't find it, fail the search - } - return m_pDirHeader ? m_pDirHeader->GetFileEntry(itFile) : NULL; -} - -ZipDir::FileEntryTree* ZipDir::FindDirRW::FindExact (const char* szPath) -{ - if (!PreFind(szPath)) - { - return NULL; - } - - // the wildcard will contain the target directory name - return m_pDirHeader->FindDir(m_szWildcard); -} - -////////////////////////////////////////////////////////////////////////// -// initializes everything until the point where the file must be searched for -// after this call returns successfully (with true returned), the m_szWildcard -// contains the file name/wildcard and m_pDirHeader contains the directory where -// the file (s) are to be found -bool ZipDir::FindDataRW::PreFind (const char* szWildcard) -{ - if (!m_pRoot) - { - return false; - } - - // start the search from the root - m_pDirHeader = m_pRoot; - - // for each path dir name, copy it into the buffer and try to find the subdirectory - const char* pPath = szWildcard; - for (;; ) - { - char* pName = m_szWildcard; - - // at first we'll use the wildcard memory to save the directory names - for (; *pPath && *pPath != '/' && *pPath != '\\' && pName < m_szWildcard + sizeof(m_szWildcard) - 1; ++pPath, ++pName) - { - *pName = ::tolower(*pPath); - } - *pName = '\0'; - - if (*pPath) - { - // this is the name of the directory - FileEntryTree* pDirEntry = m_pDirHeader->FindDir(m_szWildcard); - if (!pDirEntry) - { - m_pDirHeader = NULL; // finish the search - return false; - } - m_pDirHeader = pDirEntry->GetDirectory(); - ++pPath; - assert(m_pDirHeader); - } - else - { - // finally, this is the name of the file (or directory) - return true; - } - } -} - -// goes on to the next entry -bool ZipDir::FindFileRW::FindNext () -{ - if (m_pDirHeader && m_itFile != m_pDirHeader->GetFileEnd()) - { - ++m_itFile; - return SkipNonMatchingFiles(); - } - else - { - return false; - } -} - -// goes on to the next entry -bool ZipDir::FindDirRW::FindNext () -{ - if (m_pDirHeader && m_itDir != m_pDirHeader->GetDirEnd()) - { - ++m_itDir; - return SkipNonMatchingDirs(); - } - else - { - return false; - } -} - -bool ZipDir::FindFileRW::SkipNonMatchingFiles() -{ - assert(m_pDirHeader); - - for (; m_itFile != m_pDirHeader->GetFileEnd(); ++m_itFile) - { - if (MatchWildcard(GetFileName())) - { - return true; - } - } - // we didn't find anything other file else - return false; -} - -bool ZipDir::FindDirRW::SkipNonMatchingDirs() -{ - assert(m_pDirHeader); - - for (; m_itDir != m_pDirHeader->GetDirEnd(); ++m_itDir) - { - if (MatchWildcard(GetDirName())) - { - return true; - } - } - // we didn't find anything other file else - return false; -} - - -ZipDir::FileEntry* ZipDir::FindFileRW::GetFileEntry() -{ - return m_pDirHeader && m_itFile != m_pDirHeader->GetFileEnd() ? m_pDirHeader->GetFileEntry(m_itFile) : NULL; -} -ZipDir::FileEntryTree* ZipDir::FindDirRW::GetDirEntry() -{ - return m_pDirHeader && m_itDir != m_pDirHeader->GetDirEnd() ? m_pDirHeader->GetDirEntry(m_itDir) : NULL; -} - -const char* ZipDir::FindFileRW::GetFileName () -{ - if (m_pDirHeader && m_itFile != m_pDirHeader->GetFileEnd()) - { - return m_pDirHeader->GetFileName(m_itFile); - } - else - { - return ""; // default name - } -} - -const char* ZipDir::FindDirRW::GetDirName () -{ - if (m_pDirHeader && m_itDir != m_pDirHeader->GetDirEnd()) - { - return m_pDirHeader->GetDirName(m_itDir); - } - else - { - return ""; // default name - } -} diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirFindRW.h b/Code/Tools/CryCommonTools/ZipDir/ZipDirFindRW.h deleted file mode 100644 index 3085b5f8ba..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirFindRW.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Declaration of the class that can be used to search for the entries -// in a zip dir cache - - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRFINDRW_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRFINDRW_H -#pragma once - - -namespace ZipDir -{ - // create this structure and loop: - // FindData fd (pZip); - // for (fd.FindFirst("*.cgf"); fd.GetFileEntry(); fd.FindNext()) - // {} // inside the loop, use GetFileEntry() and GetFileName() to get the file entry and name records - class FindDataRW - { - public: - FindDataRW (FileEntryTree* pRoot) - : m_pRoot (pRoot) - , m_pDirHeader (NULL) - { - } - - // returns the directory to which the current object belongs - FileEntryTree* GetParentDir() {return m_pDirHeader; } - protected: - // initializes everything until the point where the file must be searched for - // after this call returns successfully (with true returned), the m_szWildcard - // contains the file name/wildcard and m_pDirHeader contains the directory where - // the file (s) are to be found - bool PreFind (const char* szWildcard); - - // matches the file wilcard in the m_szWildcard to the given file/dir name - // this takes into account the fact that xxx. is the alias name for xxx - bool MatchWildcard(const char* szName); - - // the directory inside which the current object (file or directory) is being searched - FileEntryTree* m_pDirHeader; - - FileEntryTree* m_pRoot; // the root of the zip file in which to search - - // the actual wildcard being used in the current scan - the file name wildcard only! - char m_szWildcard[_MAX_PATH]; - }; - - - class FindFileRW - : public FindDataRW - { - public: - FindFileRW (FileEntryTree* pRoot) - : FindDataRW(pRoot) - { - } - // if bExactFile is passed, only the file is searched, and besides with the exact name as passed (no wildcards) - bool FindFirst (const char* szWildcard); - - FileEntry* FindExact (const char* szPath); - - // goes on to the next file entry - bool FindNext (); - - FileEntry* GetFileEntry(); - const char* GetFileName (); - - protected: - bool SkipNonMatchingFiles(); - FileEntryTree::FileMap::iterator m_itFile; // the current file iterator inside the parent directory - }; - - class FindDirRW - : public FindDataRW - { - public: - FindDirRW (FileEntryTree* pRoot) - : FindDataRW(pRoot) - { - } - // if bExactFile is passed, only the file is searched, and besides with the exact name as passed (no wildcards) - bool FindFirst (const char* szWildcard); - - FileEntryTree* FindExact (const char* szPath); - - // goes on to the next file entry - bool FindNext (); - - FileEntryTree* GetDirEntry(); - const char* GetDirName (); - - protected: - bool SkipNonMatchingDirs(); - FileEntryTree::SubdirMap::iterator m_itDir; // the current dir index inside the parent directory - }; -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRFINDRW_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirList.cpp b/Code/Tools/CryCommonTools/ZipDir/ZipDirList.cpp deleted file mode 100644 index 36b0dd6ba8..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirList.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#undef max -#include -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include "ZipDirList.h" -#include "ZipDirTree.h" - -ZipDir::FileRecordList::FileRecordList(FileEntryTree* pTree) -{ - clear(); - reserve(pTree->NumFilesTotal()); - AddAllFiles(pTree); -} - -//recursively adds the files from this directory and subdirectories -// the strRoot contains the trailing slash -void ZipDir::FileRecordList::AddAllFiles(FileEntryTree* pTree, string strRoot) -{ - for (FileEntryTree::SubdirMap::iterator it = pTree->GetDirBegin(); it != pTree->GetDirEnd(); ++it) - { - AddAllFiles (it->second, strRoot + it->second->GetOriginalName() + "/"); - } - - for (FileEntryTree::FileMap::iterator it = pTree->GetFileBegin(); it != pTree->GetFileEnd(); ++it) - { - FileRecord rec; - rec.pFileEntry = pTree->GetFileEntry(it); - const char* filename = rec.pFileEntry->szOriginalFileName ? rec.pFileEntry->szOriginalFileName : it->first; - rec.strPath = strRoot + filename; - push_back(rec); - } -} - - -// sorts the files by the physical offset in the zip file -void ZipDir::FileRecordList::SortByFileOffset() -{ - std::sort (begin(), end(), FileRecordFileOffsetOrder()); -} - -// returns the size of CDR in the zip file -ZipDir::FileRecordList::ZipStats ZipDir::FileRecordList::GetStats() const -{ - ZipStats Stats; - Stats.nSizeCDR = sizeof(ZipFile::CDREnd); - Stats.nSizeCompactData = 0; - // for each file, we'll need to store only its CDR header and the name - for (const_iterator it = begin(); it != end(); ++it) - { - Stats.nSizeCDR += sizeof(ZipFile::CDRFileHeader) + it->strPath.length(); - Stats.nSizeCompactData += sizeof(ZipFile::LocalFileHeader) + it->strPath.length() + it->pFileEntry->desc.lSizeCompressed; - } - - return Stats; -} - -// puts the CDR into the given block of mem -size_t ZipDir::FileRecordList::MakeZipCDR(ZipFile::ulong lCDROffset, void* pBuffer, bool encryptedFlag) const -{ - const ZipFile::ushort nBaseVersion = std::max(encryptedFlag ? ZipFile::VERSION_ENCRYPTION_PKWARE : ZipFile::VERSION_DEFAULT, ZipFile::VERSION_COMPRESSION_DEFLATE); - - char* pCur = (char*)pBuffer; - for (const_iterator it = begin(); it != end(); ++it) - { - ZipFile::CDRFileHeader& h = *(ZipFile::CDRFileHeader*)pCur; - pCur = (char*)(&h + 1); - h.lSignature = h.SIGNATURE; - h.nVersionMadeBy = nBaseVersion + (ZipFile::CREATOR_MSDOS << 8); - h.nVersionNeeded = nBaseVersion; - h.nFlags = 0; - h.nMethod = it->pFileEntry->nMethod; - h.nLastModTime = it->pFileEntry->nLastModTime; - h.nLastModDate = it->pFileEntry->nLastModDate; - h.desc = it->pFileEntry->desc; - h.nFileNameLength = (ZipFile::ushort)it->strPath.length(); - h.nExtraFieldLength = 0; - h.nFileCommentLength = 0; - h.nDiskNumberStart = 0; - h.nAttrInternal = 0; - h.lAttrExternal = 0; - h.lLocalHeaderOffset = it->pFileEntry->nFileHeaderOffset; - - memcpy (pCur, it->strPath.c_str(), it->strPath.length()); - pCur += it->strPath.length(); - } - - ZipFile::CDREnd& e = *(ZipFile::CDREnd*)pCur; - e.lSignature = e.SIGNATURE; - e.nDisk = encryptedFlag ? (1 << 15) : 0; - e.nCDRStartDisk = 0; - e.numEntriesOnDisk = (ZipFile::ushort)this->size(); - e.numEntriesTotal = (ZipFile::ushort)this->size(); - e.lCDRSize = (ZipFile::ulong)(pCur - (char*)pBuffer); - e.lCDROffset = lCDROffset; - e.nCommentLength = 0; - - pCur = (char*)(&e + 1); - - return pCur - (char*)pBuffer; -} - - -ZipDir::FileEntryList::FileEntryList (FileEntryTree* pTree, unsigned lCDROffset) - : m_lCDROffset (lCDROffset) -{ - Add (pTree); -} - -void ZipDir::FileEntryList::Add(FileEntryTree* pTree) -{ - for (FileEntryTree::SubdirMap::iterator itDir = pTree->GetDirBegin(); itDir != pTree->GetDirEnd(); ++itDir) - { - Add(pTree->GetDirEntry(itDir)); - } - for (FileEntryTree::FileMap::iterator itFile = pTree->GetFileBegin(); itFile != pTree->GetFileEnd(); ++itFile) - { - insert(pTree->GetFileEntry(itFile)); - } -} - -// updates each file entry's info about the next file entry -void ZipDir::FileEntryList::RefreshEOFOffsets() -{ - iterator it, itNext = begin(); - - if (itNext != end()) - { - while ((it = itNext, ++itNext) != end()) - { - // start scan - (*it)->nEOFOffset = (*itNext)->nFileHeaderOffset; - } - // it is the last one.. - (*it)->nEOFOffset = m_lCDROffset; - } -} - - -void ZipDir::FileRecordList::Backup(std::vector& arrFiles) const -{ - arrFiles.resize (size()); - std::vector::iterator itTgt = arrFiles.begin(); - - for (const_iterator it = begin(); it != end(); ++it, ++itTgt) - { - *itTgt = *it->pFileEntry; - } -} - -void ZipDir::FileRecordList::Restore(const std::vector& arrFiles) -{ - if (arrFiles.size() == size()) - { - std::vector::const_iterator itTgt = arrFiles.begin(); - for (iterator it = begin(); it != end(); ++it, ++itTgt) - { - *it->pFileEntry = *itTgt; - } - } -} diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirList.h b/Code/Tools/CryCommonTools/ZipDir/ZipDirList.h deleted file mode 100644 index 58ce7312ae..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirList.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRLIST_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRLIST_H -#pragma once - -#include - -namespace ZipDir -{ - // this is the array of file entries that's convenient to use to construct CDR - struct FileRecord - { - string strPath; // relative path to the file inside zip - FileEntry* pFileEntry; // the file entry itself - - void ConstructFileRecord() - { - new (&strPath)string(); - } - }; - - struct FileDataRecord - : public FileRecord - { - FileDataRecord() { m_nRefCount = 0; } - void AddRef() { ++m_nRefCount; } - void Release() - { - if (--m_nRefCount <= 0) - { - Delete(); - } - } - - void Delete() - { - free (this); - } - - static FileDataRecord* New(const FileRecord& rThat) - { - FileDataRecord* pThis = (FileDataRecord*)malloc(sizeof(FileDataRecord) + rThat.pFileEntry->desc.lSizeCompressed); - - if (pThis) - { - pThis->m_nRefCount = 0; - pThis->ConstructFileRecord(); - *static_cast(pThis) = rThat; - } - return pThis; - } - - void* GetData() {return this + 1; } - - volatile signed int m_nRefCount; // the reference count - }; - - TYPEDEF_AUTOPTR(FileDataRecord); - typedef FileDataRecord_AutoPtr FileDataRecordPtr; - - struct FileRecordFileOffsetOrder - { - bool operator () (const FileRecord& left, const FileRecord& right) - { - return left.pFileEntry->nFileHeaderOffset < right.pFileEntry->nFileHeaderOffset; - } - }; - - // this is used for construction of CDR - class FileRecordList - : public std::vector - { - public: - FileRecordList(class FileEntryTree* pTree); - - struct ZipStats - { - // the size of the CDR in the file - size_t nSizeCDR; - // the size of the file data part (local file descriptors and file datas) - // if it's compacted - size_t nSizeCompactData; - }; - - // sorts the files by the physical offset in the zip file - void SortByFileOffset (); - - // returns the size of CDR in the zip file - ZipStats GetStats() const; - - // puts the CDR into the given block of mem - size_t MakeZipCDR(ZipFile::ulong lCDROffset, void* p, bool encryptedFlag) const; - - void Backup(std::vector& arrFiles) const; - void Restore(const std::vector& arrFiles); - - protected: - // recursively adds the files from this directory and subdirectories - // the strRoot contains the trailing slash - void AddAllFiles(class FileEntryTree* pTree, string strRoot = string()); - }; - - - struct FileEntryFileOffsetOrder - { - bool operator () (FileEntry* pLeft, FileEntry* pRight) const - { - return pLeft->nFileHeaderOffset < pRight->nFileHeaderOffset; - } - }; - - // this is used for refreshing EOFOffsets - class FileEntryList - : public std::set - { - public: - FileEntryList (class FileEntryTree* pTree, unsigned lCDROffset); - // updates each file entry's info about the next file entry - void RefreshEOFOffsets(); - protected: - void Add (class FileEntryTree* pTree); - unsigned m_lCDROffset; - }; -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRLIST_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirStructures.cpp b/Code/Tools/CryCommonTools/ZipDir/ZipDirStructures.cpp deleted file mode 100644 index 3d404ad62b..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirStructures.cpp +++ /dev/null @@ -1,670 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "smartptr.h" -#include -#include -#include -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include -#include -#include -#include - -using namespace ZipFile; - -ZipDir::FileEntry::FileEntry(const CDRFileHeader& header, const SExtraZipFileData& extra) -{ - this->desc = header.desc; - this->nFileHeaderOffset = header.lLocalHeaderOffset; - this->nFileDataOffset = INVALID_DATA_OFFSET; // we don't know yet - this->nMethod = header.nMethod; - this->nNameOffset = 0; // we don't know yet -#if defined(AZ_PLATFORM_WINDOWS) - this->nLastModTime = header.nLastModTime; - this->nLastModDate = header.nLastModDate; -#endif - this->nNTFS_LastModifyTime = extra.nLastModifyTime; - this->szOriginalFileName = 0; - - // make an estimation (at least this offset should be there), but we don't actually know yet - this->nEOFOffset = header.lLocalHeaderOffset + sizeof (ZipFile::LocalFileHeader) + header.nFileNameLength + header.desc.lSizeCompressed; -} - - - -// Uncompresses raw (without wrapping) data that is compressed with method 8 (deflated) in the Zip file -// returns one of the Z_* errors (Z_OK upon success) -// This function just mimics the standard uncompress (with modification taken from unzReadCurrentFile) -// with 2 differences: there are no 16-bit checks, and -// it initializes the inflation to start without waiting for compression method byte, as this is the -// way it's stored into zip file -int ZipDir::ZipRawUncompress (void* pUncompressed, unsigned long* pDestSize, const void* pCompressed, unsigned long nSrcSize) -{ - int nReturnCode = Z_OK; - - //check first 4 bytes to see what compression codec was used - if (CompressionCodec::TestForZSTDMagic(pCompressed)) - { - - size_t result = ZSTD_decompress(pUncompressed, *pDestSize, pCompressed, nSrcSize); - - if (ZSTD_isError(result)) - { - AZ_Error("ZipDirStructures", false, "Error decompressing using zstd: %s", ZSTD_getErrorName(result)); - nReturnCode = Z_BUF_ERROR; - } - else - { - *pDestSize = result; - } - return nReturnCode; - } - else if (CompressionCodec::TestForLZ4Magic(pCompressed)) - { - size_t result; - LZ4F_decompressionContext_t dctx; - result = LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION); - if (LZ4F_isError(result)) - { - AZ_Error("ZipDirStructures", false, "Error creating lz4 decompression context: %s", LZ4F_getErrorName(result)); - return Z_BUF_ERROR; - } - - size_t dstSize = (size_t)*pDestSize; - size_t srcSize = (size_t)nSrcSize; - result = LZ4F_decompress(dctx, pUncompressed, &dstSize, pCompressed, &srcSize, nullptr); - if (LZ4F_isError(result)) - { - AZ_Error("ZipDirStructures", false, "Error decompressing using lz4: %s", LZ4F_getErrorName(result)); - nReturnCode = Z_BUF_ERROR; - } - else - { - *pDestSize = (long)dstSize; - } - - size_t freeCode = LZ4F_freeDecompressionContext(dctx); - if (LZ4F_isError(freeCode)) - { - //We are not changing the return code in this case, but it is good to record that releasing the - //decompression context failed. - AZ_Error("ZipDirStructures", false, "Error releasing lz4 decompression context: %s", LZ4F_getErrorName(freeCode)); - } - - return nReturnCode; - } - - - //Default to Zlib - z_stream stream; - stream.next_in = (Bytef*)pCompressed; - stream.avail_in = (uInt)nSrcSize; - - int err; - - stream.next_out = (Bytef*)pUncompressed; - stream.avail_out = (uInt) * pDestSize; - - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - err = inflateInit2(&stream, -MAX_WBITS); - if (err != Z_OK) - { - return err; - } - - // for some strange reason, passing Z_FINISH doesn't work - - // it seems the stream isn't finished for some files and - // inflate returns an error due to stream-end-not-reached (though expected) problem - err = inflate(&stream, Z_SYNC_FLUSH); - if (err != Z_STREAM_END && err != Z_OK) - { - inflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - - *pDestSize = stream.total_out; - - err = inflateEnd(&stream); - return err; - -} - -// compresses the raw data into raw data. The buffer for compressed data itself with the heap passed. Uses method 8 (deflate) -// returns one of the Z_* errors (Z_OK upon success) -int ZipDir::ZipRawCompress(const void* pUncompressed, unsigned long* pDestSize, void* pCompressed, unsigned long nSrcSize, int nLevel) -{ - z_stream stream; - int err; - - stream.next_out = reinterpret_cast(pCompressed); - - stream.next_in = const_cast(static_cast(pUncompressed)); - stream.avail_in = static_cast(nSrcSize); - - stream.avail_out = static_cast(*pDestSize); - - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - err = deflateInit2 (&stream, nLevel, Z_DEFLATED, -MAX_WBITS, 9, Z_DEFAULT_STRATEGY); - if (err != Z_OK) - { - return err; - } - - err = deflate (&stream, Z_FINISH); - if (err != Z_STREAM_END) - { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *pDestSize = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -int ZipDir::ZipRawCompressZSTD(const void* pUncompressed, unsigned long* pDestSize, void* pCompressed, unsigned long nSrcSize, int nLevel) -{ - size_t result = ZSTD_compress(pCompressed, *pDestSize, pUncompressed, nSrcSize, nLevel); - - int err = Z_OK; - - if (ZSTD_isError(result)) - { - err = Z_BUF_ERROR; - } - else - { - *pDestSize = static_cast(result); - } - return err; -} - -int ZipDir::ZipRawCompressLZ4(const void* pUncompressed, unsigned long* pDestSize, void* pCompressed, unsigned long nSrcSize, [[maybe_unused]] int nLevel) -{ - int returnCode = Z_OK; - const size_t compressedBufferMaxSize = aznumeric_caster(*pDestSize); - size_t lz4_code = LZ4F_compressFrame(pCompressed, compressedBufferMaxSize, pUncompressed, aznumeric_caster(nSrcSize), nullptr); - - if (LZ4F_isError(lz4_code)) - { - returnCode = Z_BUF_ERROR; - } - else - { - *pDestSize = aznumeric_caster(lz4_code); - } - - return returnCode; -} - -int ZipDir::GetCompressedSizeEstimate(unsigned long uncompressedSize, CompressionCodec::Codec codec) -{ - switch (codec) - { - case CompressionCodec::Codec::ZLIB: - return (uncompressedSize + (uncompressedSize >> 3) + 32); - case CompressionCodec::Codec::ZSTD: - return ZSTD_compressBound(uncompressedSize); - case CompressionCodec::Codec::LZ4: - return LZ4F_compressFrameBound(uncompressedSize, nullptr); - default: - break; - } - return 0; -} - -ZipDir::ValidationResult ZipDir::ValidateZSTDCompressedDataWithOriginalData(const void* pUncompressed, unsigned long uncompressedSize, const void* pCompressed, unsigned long compressedSize) -{ - auto decompressedSize = ZSTD_getDecompressedSize(pCompressed, compressedSize); - ZipDir::ValidationResult testResult = ValidationResult::OK; - - if (decompressedSize != uncompressedSize) - { - testResult = ValidationResult::SIZE_MISMATCH; - } - else - { - void* decompressionBuffer = azmalloc(decompressedSize); - - size_t result = ZSTD_decompress(decompressionBuffer, decompressedSize, pCompressed, compressedSize); - - if (ZSTD_isError(result)) - { - AZ_Warning("Debug", false, "Error decompressing data with zstd: %s", ZSTD_getErrorName(result)); - testResult = ValidationResult::DATA_CORRUPTED; - } - else - { - if (memcmp(decompressionBuffer, pUncompressed, decompressedSize) != 0) - { - testResult = ValidationResult::DATA_NO_MATCH; - } - } - azfree(decompressionBuffer); - } - return testResult; -} - -// finds the subdirectory entry by the name, using the names from the name pool -// assumes: all directories are sorted in alphabetical order. -// case-sensitive (must be lower-case if case-insensitive search in Win32 is performed) -ZipDir::DirEntry* ZipDir::DirHeader::FindSubdirEntry(const char* szName) -{ - if (this->numDirs) - { - const char* pNamePool = GetNamePool(); - DirEntrySortPred pred(pNamePool); - DirEntry* pBegin = GetSubdirEntry(0); - DirEntry* pEnd = pBegin + this->numDirs; - DirEntry* pEntry = std::lower_bound(pBegin, pEnd, szName, pred); -#if defined(LINUX) - if (pEntry != pEnd && !strcasecmp(szName, pEntry->GetName(pNamePool))) -#else - if (pEntry != pEnd && !strcmp(szName, pEntry->GetName(pNamePool))) -#endif - { - return pEntry; - } - } - return NULL; -} - -// finds the file entry by the name, using the names from the name pool -// assumes: all directories are sorted in alphabetical order. -// case-sensitive (must be lower-case if case-insensitive search in Win32 is performed) -ZipDir::FileEntry* ZipDir::DirHeader::FindFileEntry(const char* szName) -{ - if (this->numFiles) - { - const char* pNamePool = GetNamePool(); - DirEntrySortPred pred(pNamePool); - FileEntry* pBegin = GetFileEntry(0); - FileEntry* pEnd = pBegin + this->numFiles; - FileEntry* pEntry = std::lower_bound(pBegin, pEnd, szName, pred); -#if defined(LINUX) - if (pEntry != pEnd && !strcasecmp(szName, pEntry->GetName(pNamePool))) -#else - if (pEntry != pEnd && !strcmp(szName, pEntry->GetName(pNamePool))) -#endif - { - return pEntry; - } - } - return NULL; -} - - -// tries to refresh the file entry from the given file (reads fromthere if needed) -// returns the error code if the operation was impossible to complete -ZipDir::ErrorEnum ZipDir::Refresh(FILE* f, FileEntry* pFileEntry, bool encryptedHeaders) -{ - if (pFileEntry->nFileDataOffset != pFileEntry->INVALID_DATA_OFFSET) - { - return ZD_ERROR_SUCCESS; - } - - if (pFileEntry->desc.lSizeCompressed == 0) - { - return ZD_ERROR_SUCCESS; - } - -#ifdef WIN32 - if (_fseeki64(f, (__int64)pFileEntry->nFileHeaderOffset, SEEK_SET)) -#else - if (fseek(f, pFileEntry->nFileHeaderOffset, SEEK_SET)) -#endif - { - return ZD_ERROR_IO_FAILED; - } - - if (encryptedHeaders) - { - // with encrypted headers FileEntries should always be initialized from CDR. - return ZD_ERROR_IO_FAILED; - } - - // read the local file header and the name (for validation) into the buffer - LocalFileHeader fileHeader; - if (1 != fread (&fileHeader, sizeof(fileHeader), 1, f)) - { - return ZD_ERROR_IO_FAILED; - } - - if (fileHeader.desc != pFileEntry->desc - || fileHeader.nMethod != pFileEntry->nMethod) - { - return ZD_ERROR_IO_FAILED; - } - - pFileEntry->nFileDataOffset = pFileEntry->nFileHeaderOffset + sizeof(LocalFileHeader) + fileHeader.nFileNameLength + fileHeader.nExtraFieldLength; - pFileEntry->nEOFOffset = pFileEntry->nFileDataOffset + pFileEntry->desc.lSizeCompressed; - return ZD_ERROR_SUCCESS; -} - -// writes into the file local header - without Extra data -// puts the new offset to the file data to the file entry -// in case of error can put INVALID_DATA_OFFSET into the data offset field of file entry -ZipDir::ErrorEnum ZipDir::WriteLocalHeader (FILE* f, FileEntry* pFileEntry, const char* szRelativePath, bool encrypt) -{ - size_t nFileNameLength = strlen(szRelativePath); - size_t nHeaderSize = sizeof(LocalFileHeader) + nFileNameLength; - - pFileEntry->nFileDataOffset = pFileEntry->nFileHeaderOffset + nHeaderSize; - pFileEntry->nEOFOffset = pFileEntry->nFileDataOffset + pFileEntry->desc.lSizeCompressed; - -#ifdef WIN32 - if (_fseeki64 (f, (__int64)pFileEntry->nFileHeaderOffset, SEEK_SET)) -#else - if (fseek (f, pFileEntry->nFileHeaderOffset, SEEK_SET)) -#endif - { - return ZD_ERROR_IO_FAILED; - } - - if (encrypt) - { - std::vector garbage; - garbage.resize(nHeaderSize); - for (size_t i = 0; i < nHeaderSize; ++i) - { - garbage[i] = rand() & 0xff; - } - - if (fwrite(&garbage[0], nHeaderSize, 1, f) != 1) - { - return ZD_ERROR_IO_FAILED; - } - } - else - { - LocalFileHeader h; - memset(&h, 0, sizeof(h)); - - h.lSignature = h.SIGNATURE; - h.nVersionNeeded = 10; - h.nFlags = 0; - h.nMethod = pFileEntry->nMethod; -#if defined(AZ_PLATFORM_WINDOWS) - h.nLastModDate = pFileEntry->nLastModDate; - h.nLastModTime = pFileEntry->nLastModTime; -#endif - h.desc = pFileEntry->desc; - h.nFileNameLength = (unsigned short)nFileNameLength; - h.nExtraFieldLength = 0; - - if (1 != fwrite(&h, sizeof(h), 1, f)) - { - return ZD_ERROR_IO_FAILED; - } - - if (nFileNameLength > 0) - { - if (1 != fwrite (szRelativePath, nFileNameLength, 1, f)) - { - return ZD_ERROR_IO_FAILED; - } - } - } - - return ZD_ERROR_SUCCESS; -} - - -// conversion routines for the date/time fields used in Zip -ZipFile::ushort ZipDir::DOSDate(tm* t) -{ - return - ((t->tm_year - 80) << 9) - | (t->tm_mon << 5) - | t->tm_mday; -} - -ZipFile::ushort ZipDir::DOSTime(tm* t) -{ - return - ((t->tm_hour) << 11) - | ((t->tm_min) << 5) - | ((t->tm_sec) >> 1); -} - - - -// sets the current time to modification time -// calculates CRC32 for the new data -void ZipDir::FileEntry::OnNewFileData(void* pUncompressed, unsigned nSize, unsigned nCompressedSize, unsigned nCompressionMethod, bool bContinuous) -{ - time_t nTime; - time(&nTime); -#if defined(AZ_PLATFORM_WINDOWS) - tm t; - localtime_s(&t, &nTime); - this->nLastModTime = DOSTime(&t); - this->nLastModDate = DOSDate(&t); -#else - -#endif - this->nNTFS_LastModifyTime = AZStd::GetTimeUTCMilliSecond(); - - if (!bContinuous) - { - this->desc.lCRC32 = crc32(0L, Z_NULL, 0); - this->desc.lSizeCompressed = nCompressedSize; - this->desc.lSizeUncompressed = nSize; - } - - // we'll need CRC32 of the file to pack it - this->desc.lCRC32 = crc32(this->desc.lCRC32, (Bytef*)pUncompressed, nSize); - - this->nMethod = nCompressionMethod; -} - - -const char* ZipDir::DOSTimeCStr(ZipFile::ushort nTime) -{ - static char szBuf[16]; - azsprintf(szBuf, "%02d:%02d.%02d", (nTime >> 11), ((nTime & ((1 << 11) - 1)) >> 5), ((nTime & ((1 << 5) - 1)) << 1)); - return szBuf; -} - -const char* ZipDir::DOSDateCStr(ZipFile::ushort nTime) -{ - static char szBuf[32]; - azsprintf(szBuf, "%02d.%02d.%04d", (nTime & 0x1F), (nTime >> 5) & 0xF, (nTime >> 9) + 1980); - return szBuf; -} - -uint64 ZipDir::FileEntry::GetModificationTime() -{ - if (nNTFS_LastModifyTime != 0) - { - return nNTFS_LastModifyTime; - } - -#if defined(AZ_PLATFORM_WINDOWS) - // TODO/TIME: check and test - SYSTEMTIME st; - st.wYear = (nLastModDate >> 9) + 1980; - st.wMonth = ((nLastModDate >> 5) & 0xF); - st.wDay = (nLastModDate & 0x1F); - st.wHour = (nLastModTime >> 11); - st.wMinute = (nLastModTime >> 5) & 0x3F; - st.wSecond = (nLastModTime << 1) & 0x3F; - st.wMilliseconds = 0; - FILETIME ft; - SystemTimeToFileTime(&st, &ft); - LARGE_INTEGER lt; - lt.HighPart = ft.dwHighDateTime; - lt.LowPart = ft.dwLowDateTime; - return lt.QuadPart; -#else - return 0; -#endif -} - - -void ZipDir::FileEntry::SetFromFileTimeNTFS(int64 timestamp) -{ -#if defined(AZ_PLATFORM_WINDOWS) - FILETIME ft; - ft.dwHighDateTime = timestamp >> 32; - ft.dwLowDateTime = timestamp & 0xFFFFFFFF; - - WORD dosTime, dosDate; - FileTimeToDosDateTime(&ft, &dosDate, &dosTime); - - nLastModDate = dosDate; - nLastModTime = dosTime; -#endif - nNTFS_LastModifyTime = timestamp; -} - -bool ZipDir::FileEntry::CompareFileTimeNTFS(int64 timestamp) -{ -#if defined(AZ_PLATFORM_WINDOWS) - FILETIME ft; - ft.dwHighDateTime = timestamp >> 32; - ft.dwLowDateTime = timestamp & 0xFFFFFFFF; - - WORD dosTime, dosDate; - FileTimeToDosDateTime(&ft, &dosDate, &dosTime); - - return (nLastModTime == dosTime && nLastModDate == dosDate); -#else - return (nNTFS_LastModifyTime == timestamp); -#endif -} - -const char* ZipDir::Error::getError() -{ - switch (this->nError) - { -#define DECLARE_ERROR(x) case ZD_ERROR_##x: \ - return #x; - DECLARE_ERROR(SUCCESS); - DECLARE_ERROR(IO_FAILED); - DECLARE_ERROR(UNEXPECTED); - DECLARE_ERROR(UNSUPPORTED); - DECLARE_ERROR(INVALID_SIGNATURE); - DECLARE_ERROR(ZIP_FILE_IS_CORRUPT); - DECLARE_ERROR(DATA_IS_CORRUPT); - DECLARE_ERROR(NO_CDR); - DECLARE_ERROR(CDR_IS_CORRUPT); - DECLARE_ERROR(NO_MEMORY); - DECLARE_ERROR(VALIDATION_FAILED); - DECLARE_ERROR(CRC32_CHECK); - DECLARE_ERROR(ZLIB_FAILED); - DECLARE_ERROR(ZLIB_CORRUPTED_DATA); - DECLARE_ERROR(ZLIB_NO_MEMORY); - DECLARE_ERROR(CORRUPTED_DATA); - DECLARE_ERROR(INVALID_CALL); - DECLARE_ERROR(NOT_IMPLEMENTED); - DECLARE_ERROR(FILE_NOT_FOUND); - DECLARE_ERROR(DIR_NOT_FOUND); - DECLARE_ERROR(NAME_TOO_LONG); - DECLARE_ERROR(INVALID_PATH); - DECLARE_ERROR(FILE_ALREADY_EXISTS); -#undef DECLARE_ERROR - default: - return "Unknown ZD_ERROR code"; - } -} - - -inline void btea(uint32* v, int n, uint32 const k[4]) -{ -#define TEA_DELTA 0x9e3779b9 -#define TEA_MX (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (k[(p & 3) ^ e] ^ z))) - uint32 y, z, sum; - unsigned p, rounds, e; - if (n > 1) /* Coding Part */ - { - rounds = 6 + 52 / n; - sum = 0; - z = v[n - 1]; - do - { - sum += TEA_DELTA; - e = (sum >> 2) & 3; - for (p = 0; p < n - 1; p++) - { - y = v[p + 1]; - z = v[p] += TEA_MX; - } - y = v[0]; - z = v[n - 1] += TEA_MX; - } while (--rounds); - } - else if (n < -1) /* Decoding Part */ - { - n = -n; - rounds = 6 + 52 / n; - sum = rounds * TEA_DELTA; - y = v[0]; - do - { - e = (sum >> 2) & 3; - for (p = n - 1; p > 0; p--) - { - z = v[p - 1]; - y = v[p] -= TEA_MX; - } - z = v[n - 1]; - y = v[0] -= TEA_MX; - } while ((sum -= TEA_DELTA) != 0); - } -#undef TEA_DELTA -#undef TEA_MX -} - -static inline void SwapByteOrder(uint32* values, size_t count) -{ - for (uint32* w = values, * e = values + count; w != e; ++w) - { - *w = (*w >> 24) + ((*w >> 8) & 0xff00) + ((*w & 0xff00) << 8) + (*w << 24); - } -} - -////////////////////////////////////////////////////////////////////////// -void ZipDir::Encrypt(char* buffer, size_t size, const EncryptionKey& key) -{ - uint32* intBuffer = (uint32*)buffer; - const int encryptedLen = size >> 2; - - SwapByteOrder(intBuffer, encryptedLen); - - btea(intBuffer, encryptedLen, key.key); - - SwapByteOrder(intBuffer, encryptedLen); -} - -////////////////////////////////////////////////////////////////////////// -void ZipDir::Decrypt(char* buffer, size_t size, const EncryptionKey& key) -{ - uint32* intBuffer = (uint32*)buffer; - const int encryptedLen = size >> 2; - - SwapByteOrder(intBuffer, encryptedLen); - - btea(intBuffer, -encryptedLen, key.key); - - SwapByteOrder(intBuffer, encryptedLen); -} - diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirTree.cpp b/Code/Tools/CryCommonTools/ZipDir/ZipDirTree.cpp deleted file mode 100644 index b35ae48b2a..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirTree.cpp +++ /dev/null @@ -1,356 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "ZipFileFormat.h" -#include "zipdirstructures.h" -#include "ZipDirTree.h" - - -// Adds or finds the file. Returns non-initialized structure if it was added, -// or an IsInitialized() structure if it was found -ZipDir::FileEntry* ZipDir::FileEntryTree::Add(char* szPath, char* szUnifiedPath) -{ - // find the slash; if we found it, it's a subdirectory - add a subdirectory and - // add the file to it. - // if we didn't find it, it's a file - add the file to this dir - - char* pSlash; - for (pSlash = szPath; *pSlash && *pSlash != '/' && *pSlash != '\\'; ++pSlash) - { - continue; // find the next slash - } - char* pUnifiedSlash = szUnifiedPath + (pSlash - szPath); - assert(*pUnifiedSlash == '\0' || *pUnifiedSlash == '\\' || *pUnifiedSlash == '/'); - - if (*pUnifiedSlash) - { - FileEntryTree* pSubdir; - // we have a subdirectory here - create the file in it - { - char* unifiedDir = szUnifiedPath; - *pUnifiedSlash = '\0'; - - char* dir = szPath; - *pSlash = '\0'; - - SubdirMap::iterator it = m_mapDirs.find (unifiedDir); - if (it == m_mapDirs.end()) - { - pSubdir = new FileEntryTree(dir); - m_mapDirs.insert (SubdirMap::value_type(unifiedDir, pSubdir)); - } - else - { - pSubdir = it->second; - } - } - - return pSubdir->Add(pSlash + 1, pUnifiedSlash + 1); - } - else - { - ZipDir::FileEntry* result = &m_mapFiles[szUnifiedPath]; - result->szOriginalFileName = szPath; - return result; - } -} - -// adds a file to this directory -ZipDir::ErrorEnum ZipDir::FileEntryTree::Add (char* szPath, char* szUnifiedPath, const FileEntry& file) -{ - FileEntry* pFile = Add (szPath, szUnifiedPath); - if (!pFile) - { - return ZD_ERROR_INVALID_PATH; - } - if (pFile->IsInitialized()) - { - return ZD_ERROR_FILE_ALREADY_EXISTS; - } - // preserve original filename - const char* szOriginalFileName = pFile->szOriginalFileName; - *pFile = file; - pFile->szOriginalFileName = szOriginalFileName; - return ZD_ERROR_SUCCESS; -} - -// returns the number of files in this tree, including this and sublevels -unsigned ZipDir::FileEntryTree::NumFilesTotal() const -{ - unsigned numFiles = (unsigned)m_mapFiles.size(); - for (SubdirMap::const_iterator it = m_mapDirs.begin(); it != m_mapDirs.end(); ++it) - { - numFiles += it->second->NumFilesTotal(); - } - return numFiles; -} - -#ifdef _TEST_ -size_t g_nSF = 0, g_nSS = 0, g_nSN = 0, g_nSNa = 0, g_nSH; -size_t g_nGF = 0, g_nGS = 0, g_nGN = 0, g_nGNa = 0, g_nGH; -#endif - -// returns the size required to serialize the tree -size_t ZipDir::FileEntryTree::GetSizeSerialized() const -{ - // the total size of name pool gets aligned on 4-byte boundary - size_t nSizeOfNamePool = 0; - size_t nSizeOfFileEntries = 0, nSizeOfDirEntries = 0; - size_t nSizeOfSubdirs = 0; - - for (SubdirMap::const_iterator itDir = m_mapDirs.begin(); itDir != m_mapDirs.end(); ++itDir) - { - nSizeOfDirEntries += sizeof(DirEntry); - const char* dirname = itDir->first; - nSizeOfNamePool += strlen(dirname) + 1; - nSizeOfSubdirs += itDir->second->GetSizeSerialized(); - } - - // for each file, we need to have an entry in the name pool and in the file list - for (FileMap::const_iterator itFile = m_mapFiles.begin(); itFile != m_mapFiles.end(); ++itFile) - { - nSizeOfFileEntries += sizeof(FileEntry); - const char* fname = itFile->first; - nSizeOfNamePool += strlen(fname) + 1; - } - - if (nSizeOfNamePool > 0xFFFF) - { - // we don't support so long names/directories - THROW_ZIPDIR_ERROR(ZD_ERROR_UNSUPPORTED, "Name pool larger then 65536 bytes"); - } - -#ifdef _TEST_ - g_nGF += nSizeOfFileEntries; - g_nGS += nSizeOfDirEntries; - g_nGN += nSizeOfNamePool; - g_nGNa += ((nSizeOfNamePool + 3) & ~3); - g_nGH += sizeof(DirHeader); -#endif - - return sizeof(DirHeader) + ((nSizeOfNamePool + 3) & ~3) + nSizeOfDirEntries + nSizeOfFileEntries + nSizeOfSubdirs; -} - -// serializes into the memory -size_t ZipDir::FileEntryTree::Serialize (DirHeader* pDirHeader) const -{ - pDirHeader->numDirs = (ZipFile::ushort)m_mapDirs.size(); - pDirHeader->numFiles = (ZipFile::ushort)m_mapFiles.size(); - DirEntry* pDirEntries = (DirEntry*)(pDirHeader + 1); - FileEntry* pFileEntries = (FileEntry*)(pDirEntries + pDirHeader->numDirs); - char* pNamePool = (char*)(pFileEntries + pDirHeader->numFiles); - - char* pName = pNamePool; - DirEntry* pDirEntry = pDirEntries; - FileEntry* pFileEntry = pFileEntries; - - SubdirMap::const_iterator itDir; - for (itDir = m_mapDirs.begin(); itDir != m_mapDirs.end(); ++itDir) - { - pDirEntry->nNameOffset = (ZipFile::ulong)(pName - pNamePool); - size_t nNameLen = strlen(itDir->first); - memcpy (pName, itDir->first, nNameLen + 1); - pName += nNameLen + 1; - ++pDirEntry; - } - - assert ((FileEntry*)pDirEntry == pFileEntry); - - // for each file, we need to have an entry in the name pool and in the file list - for (FileMap::const_iterator itFile = m_mapFiles.begin(); itFile != m_mapFiles.end(); ++itFile) - { - *pFileEntry = itFile->second; - const char* filename = itFile->first; - pFileEntry->nNameOffset = (ZipFile::ushort)(pName - pNamePool); - size_t nNameLen = strlen(filename); - memcpy (pName, filename, nNameLen + 1); - pName += nNameLen + 1; - ++pFileEntry; - } - assert ((const char*)pFileEntry == pNamePool); - - // now the name pool is full. Go on and fill the other directories - const char* pSubdirHeader = (const char*)(((UINT_PTR)(pName + 3)) & ~3); - -#ifdef _TEST_ - g_nSF += pDirHeader->numFiles * sizeof(FileEntry); - g_nSS += pDirHeader->numDirs * sizeof(DirEntry); - g_nSN += pName - pNamePool; - g_nSNa += pSubdirHeader - pNamePool; - g_nSH += sizeof(DirHeader); -#endif - - pDirEntry = pDirEntries; - for (itDir = m_mapDirs.begin(); itDir != m_mapDirs.end(); ++itDir) - { - pDirEntry->nDirHeaderOffset = (ZipFile::ulong)(pSubdirHeader - (const char*)pDirEntry); - pSubdirHeader += itDir->second->Serialize ((DirHeader*)pSubdirHeader); - ++pDirEntry; - } - - - return pSubdirHeader - (const char*)pDirHeader; -} - - - -void ZipDir::FileEntryTree::Clear() -{ - for (SubdirMap::iterator it = m_mapDirs.begin(); it != m_mapDirs.end(); ++it) - { - delete it->second; - } - m_mapDirs.clear(); - m_mapFiles.clear(); -} - - -size_t ZipDir::FileEntryTree::GetSize() const -{ - size_t nSize = sizeof(*this); - for (SubdirMap::const_iterator itDir = m_mapDirs.begin(); itDir != m_mapDirs.end(); ++itDir) - { - nSize += strlen(itDir->first) + sizeof(*itDir) + itDir->second->GetSize(); - } - - for (FileMap::const_iterator itFile = m_mapFiles.begin(); itFile != m_mapFiles.end(); ++itFile) - { - nSize += strlen(itFile->first) + sizeof(*itFile); - } - return nSize; -} - -size_t ZipDir::FileEntryTree::GetCompressedFileSize() const -{ - size_t nSize = 0; - for (SubdirMap::const_iterator itDir = m_mapDirs.begin(); itDir != m_mapDirs.end(); ++itDir) - { - nSize += itDir->second->GetCompressedFileSize(); - } - - for (FileMap::const_iterator itFile = m_mapFiles.begin(); itFile != m_mapFiles.end(); ++itFile) - { - nSize += itFile->second.desc.lSizeCompressed; - } - return nSize; -} - -size_t ZipDir::FileEntryTree::GetUncompressedFileSize() const -{ - size_t nSize = 0; - for (SubdirMap::const_iterator itDir = m_mapDirs.begin(); itDir != m_mapDirs.end(); ++itDir) - { - nSize += itDir->second->GetUncompressedFileSize(); - } - - for (FileMap::const_iterator itFile = m_mapFiles.begin(); itFile != m_mapFiles.end(); ++itFile) - { - nSize += itFile->second.desc.lSizeUncompressed; - } - return nSize; -} - -bool ZipDir::FileEntryTree::IsOwnerOf (const FileEntry* pFileEntry) const -{ - for (FileMap::const_iterator itFile = m_mapFiles.begin(); itFile != m_mapFiles.end(); ++itFile) - { - if (pFileEntry == &itFile->second) - { - return true; - } - } - - for (SubdirMap::const_iterator itDir = m_mapDirs.begin(); itDir != m_mapDirs.end(); ++itDir) - { - if (itDir->second->IsOwnerOf (pFileEntry)) - { - return true; - } - } - - return false; -} - -ZipDir::FileEntryTree* ZipDir::FileEntryTree::FindDir(const char* szDirName) -{ - SubdirMap::iterator it = m_mapDirs.find (szDirName); - if (it == m_mapDirs.end()) - { - return NULL; - } - else - { - return it->second; - } -} - -ZipDir::FileEntryTree::FileMap::iterator ZipDir::FileEntryTree::FindFile (const char* szFileName) -{ - return m_mapFiles.find (szFileName); -} - -ZipDir::FileEntry* ZipDir::FileEntryTree::GetFileEntry(FileMap::iterator it) -{ - return it == GetFileEnd() ? NULL : &it->second; -} - -ZipDir::FileEntryTree* ZipDir::FileEntryTree::GetDirEntry(SubdirMap::iterator it) -{ - return it == GetDirEnd() ? NULL : it->second; -} - -const ZipDir::FileEntry* ZipDir::FileEntryTree::GetFileEntry(FileMap::const_iterator it) const -{ - return it == GetFileEnd() ? NULL : &it->second; -} - -const ZipDir::FileEntryTree* ZipDir::FileEntryTree::GetDirEntry(SubdirMap::const_iterator it) const -{ - return it == GetDirEnd() ? NULL : it->second; -} - -ZipDir::ErrorEnum ZipDir::FileEntryTree::RemoveDir (const char* szDirName) -{ - SubdirMap::iterator itRemove = m_mapDirs.find (szDirName); - if (itRemove == m_mapDirs.end()) - { - return ZD_ERROR_FILE_NOT_FOUND; - } - - delete itRemove->second; - m_mapDirs.erase (itRemove); - return ZD_ERROR_SUCCESS; -} - -ZipDir::ErrorEnum ZipDir::FileEntryTree::RemoveFile (const char* szFileName) -{ - FileMap::iterator itRemove = m_mapFiles.find (szFileName); - if (itRemove == m_mapFiles.end()) - { - return ZD_ERROR_FILE_NOT_FOUND; - } - - m_mapFiles.erase (itRemove); - return ZD_ERROR_SUCCESS; -} - -size_t ZipDir::FileEntryTree::NumDirsTotal() const -{ - size_t result = m_mapDirs.size(); - SubdirMap::const_iterator it; - for (it = m_mapDirs.begin(); it != m_mapDirs.end(); ++it) - { - result += it->second->NumDirsTotal(); - } - return result; -} diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipDirTree.h b/Code/Tools/CryCommonTools/ZipDir/ZipDirTree.h deleted file mode 100644 index 0e8af76142..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipDirTree.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRTREE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRTREE_H -#pragma once - - -namespace ZipDir -{ - class FileEntryTree - { - public: - FileEntryTree() - : m_originalName(0) {} - FileEntryTree(const char* originalName) - : m_originalName(originalName) {} - ~FileEntryTree () {Clear(); } - - // adds a file to this directory - // Function can modify szPath input - ErrorEnum Add (char* szPath, char* szUnifiedPath, const FileEntry& file); - - // Adds or finds the file. Returns non-initialized structure if it was added, - // or an IsInitialized() structure if it was found - // Function can modify szPath input - FileEntry* Add (char* szPath, char* szUnifiedPath); - - // returns the number of files in this tree, including this and sublevels - unsigned NumFilesTotal() const; - - // returns the size required to serialize the tree - size_t GetSizeSerialized() const; - - // serializes into the memory - size_t Serialize (DirHeader* pDir) const; - - void Clear(); - - void Swap (FileEntryTree& rThat) - { - m_mapDirs.swap (rThat.m_mapDirs); - m_mapFiles.swap (rThat.m_mapFiles); - } - - size_t GetSize() const; - - size_t GetCompressedFileSize() const; - size_t GetUncompressedFileSize() const; - - bool IsOwnerOf (const FileEntry* pFileEntry) const; - - // subdirectories - typedef std::map > SubdirMap; - // file entries - typedef std::map > FileMap; - - FileEntryTree* FindDir(const char* szDirName); - ErrorEnum RemoveDir (const char* szDirName); - ErrorEnum RemoveAll (){Clear(); return ZD_ERROR_SUCCESS; } - FileEntry* FindFileEntry (const char* szFileName); - FileMap::iterator FindFile (const char* szFileName); - ErrorEnum RemoveFile (const char* szFileName); - FileEntryTree* GetDirectory(){return this; } // the FileENtryTree is simultaneously an entry in the dir list AND the directory header - - FileMap::iterator GetFileBegin() {return m_mapFiles.begin(); } - FileMap::iterator GetFileEnd() {return m_mapFiles.end(); } - FileMap::const_iterator GetFileBegin() const {return m_mapFiles.begin(); } - FileMap::const_iterator GetFileEnd() const {return m_mapFiles.end(); } - unsigned NumFiles() const {return (unsigned)m_mapFiles.size(); } - - SubdirMap::iterator GetDirBegin() {return m_mapDirs.begin(); } - SubdirMap::iterator GetDirEnd() {return m_mapDirs.end(); } - SubdirMap::const_iterator GetDirBegin() const {return m_mapDirs.begin(); } - SubdirMap::const_iterator GetDirEnd() const {return m_mapDirs.end(); } - size_t NumDirsTotal() const; - - const char* GetFileName(FileMap::iterator it) {return it->first; } - const char* GetDirName(SubdirMap::iterator it) {return it->first; } - const char* GetOriginalName() const{ return m_originalName; } - - FileEntry* GetFileEntry(FileMap::iterator it); - FileEntryTree* GetDirEntry(SubdirMap::iterator it); - const FileEntry* GetFileEntry(FileMap::const_iterator it) const; - const FileEntryTree* GetDirEntry(SubdirMap::const_iterator it) const; - - protected: - SubdirMap m_mapDirs; - FileMap m_mapFiles; - const char* m_originalName; - }; -} -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRTREE_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipFile.h b/Code/Tools/CryCommonTools/ZipDir/ZipFile.h deleted file mode 100644 index 5e1f78050c..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipFile.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILE_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILE_H -#pragma once - - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILE_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipFileFormat.h b/Code/Tools/CryCommonTools/ZipDir/ZipFileFormat.h deleted file mode 100644 index 3f2083de0f..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipFileFormat.h +++ /dev/null @@ -1,388 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_H -#pragma once - -#include -#include - -#if AZ_TRAIT_CRYCOMMONTOOLS_PACK_1 -#pragma pack(push) -#pragma pack(1) -#define PACK_GCC -#else -#define PACK_GCC __PACKED -#endif - -namespace ZipFile -{ - typedef unsigned int ulong; - typedef unsigned short ushort; - - // General-purpose bit field flags - enum - { - GPF_ENCRYPTED = 1 << 0, // If set, indicates that the file is encrypted. - GPF_DATA_DESCRIPTOR = 1 << 3, // if set, the CRC32 and sizes aren't set in the file header, but only in the data descriptor following compressed data - GPF_RESERVED_8_ENHANCED_DEFLATING = 1 << 4, // Reserved for use with method 8, for enhanced deflating. - GPF_COMPRESSED_PATCHED = 1 << 5, // the file is compressed patched data - }; - - // compression methods - enum - { - METHOD_STORE = 0, // The file is stored (no compression) - METHOD_SHRINK = 1, // The file is Shrunk - METHOD_REDUCE_1 = 2, // The file is Reduced with compression factor 1 - METHOD_REDUCE_2 = 3, // The file is Reduced with compression factor 2 - METHOD_REDUCE_3 = 4, // The file is Reduced with compression factor 3 - METHOD_REDUCE_4 = 5, // The file is Reduced with compression factor 4 - METHOD_IMPLODE = 6, // The file is Imploded - METHOD_TOKENIZE = 7, // Reserved for Tokenizing compression algorithm - METHOD_DEFLATE = 8, // The file is Deflated - METHOD_DEFLATE64 = 9, // Enhanced Deflating using Deflate64(tm) - METHOD_IMPLODE_PKWARE = 10, // PKWARE Date Compression Library Imploding - METHOD_DEFLATE_AND_ENCRYPT = 11 // Deflate + Custom encryption - }; - - // version numbers - enum - { - VERSION_DEFAULT = 10, // Default value - - VERSION_TYPE_VOLUMELABEL = 11, // File is a volume label - VERSION_TYPE_FOLDER = 20, // File is a folder (directory) - VERSION_TYPE_PATCHDATASET = 27, // File is a patch data set - VERSION_TYPE_ZIP64 = 45, // File uses ZIP64 format extensions - - VERSION_COMPRESSION_DEFLATE = 20, // File is compressed using Deflate compression - VERSION_COMPRESSION_DEFLATE64 = 21, // File is compressed using Deflate64(tm) - VERSION_COMPRESSION_DCLIMPLODE = 25, // File is compressed using PKWARE DCL Implode - VERSION_COMPRESSION_BZIP2 = 46, // File is compressed using BZIP2 compression* - VERSION_COMPRESSION_LZMA = 63, // File is compressed using LZMA - VERSION_COMPRESSION_PPMD = 63, // File is compressed using PPMd+ - - VERSION_ENCRYPTION_PKWARE = 20, // File is encrypted using traditional PKWARE encryption - VERSION_ENCRYPTION_DES = 50, // File is encrypted using DES - VERSION_ENCRYPTION_3DES = 50, // File is encrypted using 3DES - VERSION_ENCRYPTION_RC2 = 50, // File is encrypted using original RC2 encryption - VERSION_ENCRYPTION_RC4 = 50, // File is encrypted using RC4 encryption - VERSION_ENCRYPTION_AES = 51, // File is encrypted using AES encryption - VERSION_ENCRYPTION_RC2C = 51, // File is encrypted using corrected RC2 encryption** - VERSION_ENCRYPTION_RC4C = 52, // File is encrypted using corrected RC2-64 encryption** - VERSION_ENCRYPTION_NOOAEP = 61, // File is encrypted using non-OAEP key wrapping*** - VERSION_ENCRYPTION_CDR = 62, // Central directory encryption - VERSION_ENCRYPTION_BLOWFISH = 63, // File is encrypted using Blowfish - VERSION_ENCRYPTION_TWOFISH = 63, // File is encrypted using Twofish - }; - - // creator numbers - enum - { - CREATOR_MSDOS = 0, // MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems) - CREATOR_AMIGA = 1, // Amiga - CREATOR_OpenVMS = 2, // OpenVMS - CREATOR_UNIX = 3, // UNIX - CREATOR_VM = 4, // VM/CMS - CREATOR_ATARI = 5, // Atari ST - CREATOR_OS2 = 6, // OS/2 H.P.F.S. - CREATOR_MACINTOSH = 7, // Macintosh - CREATOR_ZSYSTEM = 8, // Z-System - CREATOR_CPM = 9, // CP/M - CREATOR_WINDOWS = 10, // Windows NTFS - CREATOR_MVS = 11, // MVS (OS/390 - Z/OS) - CREATOR_VSE = 12, // VSE - CREATOR_ACORN = 13, // Acorn Risc - CREATOR_VFAT = 14, // VFAT - CREATOR_AMVS = 15, // alternate MVS - CREATOR_BEOS = 16, // BeOS - CREATOR_TANDEM = 17, // Tandem - CREATOR_OS400 = 18, // OS/400 - CREATOR_OSX = 19, // OS X (Darwin) - - CREATOR_UNUSED = 20, // 20 thru 255 - unused - }; - - enum - { - ZIP64_SEE_EXTENSION = -1 // If an archive is in ZIP64 format - // and a value in a field is 0xFFFFFFFF (or 0xFFFF), the size will be - // in the corresponding 8 byte (or 4 byte) ZIP64 extended information. - }; - - // end of Central Directory Record - // followed by the .zip file comment (variable size, can be empty, obtained from nCommentLength) - struct CDREnd - { - enum - { - SIGNATURE = 0x06054b50 - }; - ulong lSignature; // end of central dir signature 4 bytes (0x06054b50) - ushort nDisk; // number of this disk 2 bytes - ushort nCDRStartDisk; // number of the disk with the start of the central directory 2 bytes - ushort numEntriesOnDisk; // total number of entries in the central directory on this disk 2 bytes - ushort numEntriesTotal; // total number of entries in the central directory 2 bytes - ulong lCDRSize; // size of the central directory 4 bytes - ulong lCDROffset; // offset of start of central directory with respect to the starting disk number 4 bytes - ushort nCommentLength; // .ZIP file comment length 2 bytes - - AUTO_STRUCT_INFO - - // .ZIP file comment (variable size, can be empty) follows - } PACK_GCC; - - // end of Central Directory Record - // followed by the zip64 extensible data sector (variable size, can be empty, obtained from nExtDataLength) - struct CDREnd_ZIP64 - { - enum - { - SIGNATURE = 0x06064b50 - }; - ulong lSignature; // end of central dir signature 4 bytes (0x06064b50) - uint64 nExtDataLength; // The value stored into the "size of zip64 end of central directory record" should be the size of the remaining record and should not include the leading 12 bytes. 8 bytes - ushort nVersionMadeBy; // version made by 2 bytes - ushort nVersionNeeded; // version needed to extract 2 bytes - ulong nDisk; // number of this disk 4 bytes - ulong nCDRStartDisk; // number of the disk with the start of the central directory 4 bytes - uint64 numEntriesOnDisk; // total number of entries in the central directory on this disk 8 bytes - uint64 numEntriesTotal; // total number of entries in the central directory 8 bytes - uint64 lCDRSize; // size of the central directory 8 bytes - uint64 lCDROffset; // offset of start of central directory with respect to the starting disk number 8 bytes - - AUTO_STRUCT_INFO - - // zip64 extensible data sector (variable size, can be empty) follows - } PACK_GCC; - - // end of Central Directory Locator - struct CDRLocator_ZIP64 - { - enum - { - SIGNATURE = 0x07064b50 - }; - ulong lSignature; // end of central loc signature 4 bytes (0x07064b50) - ulong nCDR64StartDisk; // number of the disk with the start of the zip64 end of central directory 4 bytes - uint64 lCDR64EndOffset; // relative offset of the zip64 end of central directory record 8 bytes - ulong nDisks; // number of disks 4 bytes - - AUTO_STRUCT_INFO - } PACK_GCC; - - // This descriptor exists only if bit 3 of the general - // purpose bit flag is set (see below). It is byte aligned - // and immediately follows the last byte of compressed data. - // This descriptor is used only when it was not possible to - // seek in the output .ZIP file, e.g., when the output .ZIP file - // was standard output or a non seekable device. For Zip64 format - // archives, the compressed and uncompressed sizes are 8 bytes each. - struct DataDescriptor - { - ulong lCRC32; // crc-32 4 bytes - ulong lSizeCompressed; // compressed size 4 bytes - ulong lSizeUncompressed; // uncompressed size 4 bytes - - bool operator == (const DataDescriptor& d) const - { - return lCRC32 == d.lCRC32 && lSizeCompressed == d.lSizeCompressed && lSizeUncompressed == d.lSizeUncompressed; - } - bool operator != (const DataDescriptor& d) const - { - return lCRC32 != d.lCRC32 || lSizeCompressed != d.lSizeCompressed || lSizeUncompressed != d.lSizeUncompressed; - } - - bool IsZIP64([[maybe_unused]] const DataDescriptor& d) const - { - return lSizeCompressed == (ulong)ZIP64_SEE_EXTENSION || lSizeUncompressed == (ulong)ZIP64_SEE_EXTENSION; - } - - AUTO_STRUCT_INFO - } PACK_GCC; - - // When compressing files, compressed and uncompressed sizes - // should be stored in ZIP64 format (as 8 byte values) when a - // file's size exceeds 0xFFFFFFFF. However ZIP64 format may be - // used regardless of the size of a file. When extracting, if - // the zip64 extended information extra field is present for - // the file the compressed and uncompressed sizes will be 8 - // byte values. - struct DataDescriptor_ZIP64 - { - ulong lCRC32; // crc-32 4 bytes - uint64 lSizeCompressed; // compressed size 8 bytes - uint64 lSizeUncompressed; // uncompressed size 8 bytes - - bool operator == (const DataDescriptor& d) const - { - return lCRC32 == d.lCRC32 && lSizeCompressed == d.lSizeCompressed && lSizeUncompressed == d.lSizeUncompressed; - } - bool operator != (const DataDescriptor& d) const - { - return lCRC32 != d.lCRC32 || lSizeCompressed != d.lSizeCompressed || lSizeUncompressed != d.lSizeUncompressed; - } - - AUTO_STRUCT_INFO - } PACK_GCC; - - // the File Header as it appears in the CDR - // followed by: - // file name (variable size) - // extra field (variable size) - // file comment (variable size) - struct CDRFileHeader - { - enum - { - SIGNATURE = 0x02014b50 - }; - ulong lSignature; // central file header signature 4 bytes (0x02014b50) - ushort nVersionMadeBy; // version made by 2 bytes - ushort nVersionNeeded; // version needed to extract 2 bytes - ushort nFlags; // general purpose bit flag 2 bytes - ushort nMethod; // compression method 2 bytes - ushort nLastModTime; // last mod file time 2 bytes - ushort nLastModDate; // last mod file date 2 bytes - DataDescriptor desc; - ushort nFileNameLength; // file name length 2 bytes - ushort nExtraFieldLength; // extra field length 2 bytes - ushort nFileCommentLength; // file comment length 2 bytes - ushort nDiskNumberStart; // disk number start 2 bytes - ushort nAttrInternal; // internal file attributes 2 bytes - ulong lAttrExternal; // external file attributes 4 bytes - - // This is the offset from the start of the first disk on - // which this file appears, to where the local header should - // be found. If an archive is in zip64 format and the value - // in this field is 0xFFFFFFFF, the size will be in the - // corresponding 8 byte zip64 extended information extra field. - enum - { - ZIP64_LOCAL_HEADER_OFFSET = 0xFFFFFFFF - }; - ulong lLocalHeaderOffset; // relative offset of local header 4 bytes - - bool IsZIP64([[maybe_unused]] const CDRFileHeader& d) const - { - return desc.IsZIP64(desc) || nDiskNumberStart == (ushort)ZIP64_SEE_EXTENSION || lLocalHeaderOffset == (ulong)ZIP64_SEE_EXTENSION; - } - - AUTO_STRUCT_INFO - } PACK_GCC; - - - // this is the local file header that appears before the compressed data - // followed by: - // file name (variable size) - // extra field (variable size) - struct LocalFileHeader - { - enum - { - SIGNATURE = 0x04034b50 - }; - ulong lSignature; // local file header signature 4 bytes (0x04034b50) - ushort nVersionNeeded; // version needed to extract 2 bytes - ushort nFlags; // general purpose bit flag 2 bytes - ushort nMethod; // compression method 2 bytes - ushort nLastModTime; // last mod file time 2 bytes - ushort nLastModDate; // last mod file date 2 bytes - DataDescriptor desc; - ushort nFileNameLength; // file name length 2 bytes - ushort nExtraFieldLength; // extra field length 2 bytes - - bool IsZIP64([[maybe_unused]] const LocalFileHeader& d) const - { - return desc.IsZIP64(desc); - } - - AUTO_STRUCT_INFO - } PACK_GCC; - - // compression methods - enum EExtraHeaderID - { - EXTRA_ZIP64 = 0x0001, // ZIP64 extended information extra field - EXTRA_NTFS = 0x000a, // NTFS - EXTRA_UNIX = 0x000d, // UNIX - EXTRA_PATCH = 0x000f, // Patch Descriptor - }; - - ////////////////////////////////////////////////////////////////////////// - // header1+data1 + header2+data2 . . . - // Each header should consist of: - // Header ID - 2 bytes - // Data Size - 2 bytes - struct ExtraFieldHeader - { - ushort headerID; - ushort dataSize; - - AUTO_STRUCT_INFO - } PACK_GCC; - - struct ExtraNTFSHeader - { - ulong reserved; // 4 bytes. - ushort attrTag; // 2 bytes. - ushort attrSize; // 2 bytes. - - AUTO_STRUCT_INFO - } PACK_GCC; - - ////////////////////////////////////////////////////////////////////////// - // The following is the layout of the zip64 extended - // information "extra" block. If one of the size or - // offset fields in the Local or Central directory - // record is too small to hold the required data, - // a Zip64 extended information record is created. - // The order of the fields in the zip64 extended - // information record is fixed, but the fields MUST - // only appear if the corresponding Local or Central - // directory record field is set to 0xFFFF or 0xFFFFFFFF. - // - // The extended information in the Local header MUST include - // BOTH original and compressed file size fields. - - struct ExtraZIP64LocalFileHeader - { - // LocalFileHeader overrides - uint64 lSizeUncompressed; // uncompressed size 4->8 bytes - uint64 lSizeCompressed; // compressed size 4->8 bytes - - AUTO_STRUCT_INFO - } PACK_GCC; - - struct ExtraZIP64CDRFileHeader - { - // CDRFileHeader overrides - uint64 lSizeUncompressed; // uncompressed size 4->8 bytes - uint64 lSizeCompressed; // compressed size 4->8 bytes - - uint64 lLocalHeaderOffset; // relative offset of local header 4->8 bytes - ulong nDiskNumberStart; // Number of the disk on which this file starts 2->4 bytes - - AUTO_STRUCT_INFO - } PACK_GCC; -} - -#undef PACK_GCC - -#if AZ_TRAIT_CRYCOMMONTOOLS_PACK_1 -#pragma pack(pop) -#endif - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_H diff --git a/Code/Tools/CryCommonTools/ZipDir/ZipFileFormat_info.h b/Code/Tools/CryCommonTools/ZipDir/ZipFileFormat_info.h deleted file mode 100644 index 9f91eec49b..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/ZipFileFormat_info.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_INFO_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_INFO_H -#pragma once - -#include "ZipFileFormat.h" - -STRUCT_INFO_BEGIN(ZipFile::CDREnd) -STRUCT_VAR_INFO(lSignature, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(nDisk, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nCDRStartDisk, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(numEntriesOnDisk, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(numEntriesTotal, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(lCDRSize, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(lCDROffset, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(nCommentLength, TYPE_INFO(ZipFile::ushort)) -STRUCT_INFO_END(ZipFile::CDREnd) - -STRUCT_INFO_BEGIN(ZipFile::CDREnd_ZIP64) -STRUCT_VAR_INFO(lSignature, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(nExtDataLength, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(nVersionMadeBy, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nVersionNeeded, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nDisk, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(nCDRStartDisk, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(numEntriesOnDisk, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(numEntriesTotal, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(lCDRSize, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(lCDROffset, TYPE_INFO(ZipFile::uint64)) -STRUCT_INFO_END(ZipFile::CDREnd_ZIP64) - -STRUCT_INFO_BEGIN(ZipFile::CDRLocator_ZIP64) -STRUCT_VAR_INFO(lSignature, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(nCDR64StartDisk, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(lCDR64EndOffset, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(nDisks, TYPE_INFO(ZipFile::ulong)) -STRUCT_INFO_END(ZipFile::CDRLocator_ZIP64) - -STRUCT_INFO_BEGIN(ZipFile::DataDescriptor) -STRUCT_VAR_INFO(lCRC32, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(lSizeCompressed, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(lSizeUncompressed, TYPE_INFO(ZipFile::ulong)) -STRUCT_INFO_END(ZipFile::DataDescriptor) - -STRUCT_INFO_BEGIN(ZipFile::DataDescriptor_ZIP64) -STRUCT_VAR_INFO(lCRC32, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(lSizeCompressed, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(lSizeUncompressed, TYPE_INFO(ZipFile::uint64)) -STRUCT_INFO_END(ZipFile::DataDescriptor_ZIP64) - -STRUCT_INFO_BEGIN(ZipFile::CDRFileHeader) -STRUCT_VAR_INFO(lSignature, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(nVersionMadeBy, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nVersionNeeded, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nFlags, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nMethod, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nLastModTime, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nLastModDate, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(desc, TYPE_INFO(ZipFile::DataDescriptor)) -STRUCT_VAR_INFO(nFileNameLength, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nExtraFieldLength, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nFileCommentLength, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nDiskNumberStart, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nAttrInternal, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(lAttrExternal, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(lLocalHeaderOffset, TYPE_INFO(ZipFile::ulong)) -STRUCT_INFO_END(ZipFile::CDRFileHeader) - -STRUCT_INFO_BEGIN(ZipFile::LocalFileHeader) -STRUCT_VAR_INFO(lSignature, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(nVersionNeeded, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nFlags, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nMethod, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nLastModTime, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nLastModDate, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(desc, TYPE_INFO(ZipFile::DataDescriptor)) -STRUCT_VAR_INFO(nFileNameLength, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(nExtraFieldLength, TYPE_INFO(ZipFile::ushort)) -STRUCT_INFO_END(ZipFile::LocalFileHeader) - -STRUCT_INFO_BEGIN(ZipFile::ExtraFieldHeader) -STRUCT_VAR_INFO(headerID, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(dataSize, TYPE_INFO(ZipFile::ushort)) -STRUCT_INFO_END(ZipFile::ExtraFieldHeader) - -STRUCT_INFO_BEGIN(ZipFile::ExtraNTFSHeader) -STRUCT_VAR_INFO(reserved, TYPE_INFO(ZipFile::ulong)) -STRUCT_VAR_INFO(attrTag, TYPE_INFO(ZipFile::ushort)) -STRUCT_VAR_INFO(attrSize, TYPE_INFO(ZipFile::ushort)) -STRUCT_INFO_END(ZipFile::ExtraNTFSHeader) - -STRUCT_INFO_BEGIN(ZipFile::ExtraZIP64Data) -STRUCT_VAR_INFO(lSizeUncompressed, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(lSizeCompressed, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(lLocalHeaderOffset, TYPE_INFO(ZipFile::uint64)) -STRUCT_VAR_INFO(nDiskNumberStart, TYPE_INFO(ZipFile::ulong)) -STRUCT_INFO_END(ZipFile::ExtraZIP64Data) - - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_INFO_H diff --git a/Code/Tools/CryCommonTools/ZipDir/zipdirstructures.h b/Code/Tools/CryCommonTools/ZipDir/zipdirstructures.h deleted file mode 100644 index dac298c90c..0000000000 --- a/Code/Tools/CryCommonTools/ZipDir/zipdirstructures.h +++ /dev/null @@ -1,426 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// This file contains only the support definitions for CZipDir class -// implementation. This it to unload the ZipDir.h from secondary stuff. - -#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRSTRUCTURES_H -#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRSTRUCTURES_H -#pragma once - -#include - -namespace ZipDir -{ - // possible errors occuring during the method execution - // to avoid clushing with the global Windows defines, we prefix these with ZD_ - enum ErrorEnum - { - ZD_ERROR_SUCCESS = 0, - ZD_ERROR_IO_FAILED, - ZD_ERROR_UNEXPECTED, - ZD_ERROR_UNSUPPORTED, - ZD_ERROR_INVALID_SIGNATURE, - ZD_ERROR_ZIP_FILE_IS_CORRUPT, - ZD_ERROR_DATA_IS_CORRUPT, - ZD_ERROR_NO_CDR, - ZD_ERROR_CDR_IS_CORRUPT, - ZD_ERROR_NO_MEMORY, - ZD_ERROR_VALIDATION_FAILED, - ZD_ERROR_CRC32_CHECK, - ZD_ERROR_ZLIB_FAILED, - ZD_ERROR_ZLIB_CORRUPTED_DATA, - ZD_ERROR_ZLIB_NO_MEMORY, - ZD_ERROR_CORRUPTED_DATA, - ZD_ERROR_INVALID_CALL, - ZD_ERROR_NOT_IMPLEMENTED, - ZD_ERROR_FILE_NOT_FOUND, - ZD_ERROR_DIR_NOT_FOUND, - ZD_ERROR_NAME_TOO_LONG, - ZD_ERROR_INVALID_PATH, - ZD_ERROR_FILE_ALREADY_EXISTS - }; - - // the error describes the reason of the error, as well as the error code, line of code where it happened etc. - struct Error - { - Error(ErrorEnum _nError, const char* _szDescription, const char* _szFunction, const char* _szFile, unsigned _nLine) - : nError(_nError) - , m_szDescription(_szDescription) - , szFunction(_szFunction) - , szFile(_szFile) - , nLine(_nLine) - { - } - - ErrorEnum nError; - const char* getError(); - - const char* getDescription() {return m_szDescription; } - const char* szFunction, * szFile; - unsigned nLine; - protected: - // the description of the error; if needed, will be made as a dynamic string - const char* m_szDescription; - }; - - //#define THROW_ZIPDIR_ERROR(ZD_ERR,DESC) throw Error (ZD_ERR, DESC, __FUNCTION__, __FILE__, __LINE__) - //#define THROW_ZIPDIR_ERROR(ZD_ERR,DESC) CryWarning( VALIDATOR_MODULE_SYSTEM,VALIDATOR_WARNING,DESC ) - -#define THROW_ZIPDIR_ERROR(ZD_ERR, DESC) - - struct EncryptionKey - { - uint32 key[4]; - - explicit EncryptionKey(const uint32 data[4]) - { - memcpy(key, data, sizeof(key)); - } - - EncryptionKey() - { - memset(key, 0, sizeof(key)); - } - }; - - // possible initialization methods - enum InitMethodEnum - { - // initialize as fast as possible, with minimal validation - ZD_INIT_FAST, - // after initialization, scan through all file headers, precache the actual file data offset values and validate the headers - ZD_INIT_FULL, - // scan all file headers and try to decompress the data, searching for corrupted files - ZD_INIT_VALIDATE, - // maximum level of validation, checks for integrity of the archive - ZD_INIT_VALIDATE_MAX = ZD_INIT_VALIDATE - }; - - typedef void* (* FnAlloc) (void* pUserData, unsigned nItems, unsigned nSize); - typedef void (* FnFree) (void* pUserData, void* pAddress); - - ////////////////////////////////////////////////////////////////////////// - // This structure contains the pointers to functions for memory management - // by default, it's initialized to default malloc/free -#if 0 - struct Allocator - { - FnAlloc fnAlloc; - FnFree fnFree; - void* pOpaque; - - static void* DefaultAlloc (void*, unsigned nItems, unsigned nSize) - { - return malloc (nItems * nSize); - } - - static void DefaultFree (void*, void* pAddress) - { - free (pAddress); - } - - void* Alloc (unsigned nItems, unsigned nSize) - { - return this->fnAlloc(this->pOpaque, nItems, nSize); - } - - void Free (void* pAddress) - { - this->fnFree (this->pOpaque, pAddress); - } - - // constructs the allocator object; by default, the stdlib functions are used - Allocator (FnAlloc fnAllocIn = DefaultAlloc, FnFree fnFreeIn = DefaultFree, void* pOpaqueIn = NULL) - : fnAlloc(fnAllocIn) - , fnFree (fnFreeIn) - , pOpaque(pOpaqueIn) - { - } - }; -#endif - // instance of this class just releases the memory when it's destructed - struct SmartHeapPtr - { - SmartHeapPtr() - : m_pAddress(NULL) - { - } - ~SmartHeapPtr() - { - Release(); - } - - void Attach (void* p) - { - Release(); - m_pAddress = p; - } - - void* Detach() - { - void* p = m_pAddress; - m_pAddress = NULL; - return p; - } - - void Release() - { - if (m_pAddress) - { - free(m_pAddress); - m_pAddress = NULL; - } - } - protected: - // the pointer to free - void* m_pAddress; - }; - - typedef SmartHeapPtr SmartPtr; - - // Uncompresses raw (without wrapping) data that is compressed with method 8 (deflated) in the Zip file - // returns one of the Z_* errors (Z_OK upon success) - extern int ZipRawUncompress (void* pUncompressed, unsigned long* pDestSize, const void* pCompressed, unsigned long nSrcSize); - - // compresses the raw data into raw data. The buffer for compressed data itself with the heap passed. Uses method 8 (deflate) - // returns one of the Z_* errors (Z_OK upon success), and the size in *pDestSize. the pCompressed buffer must be at least nSrcSize*1.001+12 size - - extern int ZipRawCompress (const void* pUncompressed, unsigned long* pDestSize, void* pCompressed, unsigned long nSrcSize, int nLevel); - extern int ZipRawCompressZSTD(const void* pUncompressed, unsigned long* pDestSize, void* pCompressed, unsigned long nSrcSize, int nLevel); - extern int ZipRawCompressLZ4(const void* pUncompressed, unsigned long* pDestSize, void* pCompressed, unsigned long nSrcSize, int nLevel); - - //returns an estimate of the size of the data when compressed - extern int GetCompressedSizeEstimate(unsigned long uncompressedSize, CompressionCodec::Codec codec = CompressionCodec::Codec::ZLIB); - - enum class ValidationResult - { - OK = 0, - SIZE_MISMATCH, - DATA_CORRUPTED, - DATA_NO_MATCH - }; - //decompresses a zstd blob and compares with the original - returns true if original and uncompressed data match - ValidationResult ValidateZSTDCompressedDataWithOriginalData(const void* pUncompressed, unsigned long uncompressedSize, const void* pCompressed, unsigned long compressedSize); - - ////////////////////////////////////////////////////////////////////////// - struct SExtraZipFileData - { - SExtraZipFileData() - : nLastModifyTime(0) {} - - uint64 nLastModifyTime; - }; - - // this is the record about the file in the Zip file. - struct FileEntry - { - enum - { - INVALID_DATA_OFFSET = 0xFFFFFFFF - }; - - ZipFile::DataDescriptor desc; - ZipFile::ulong nFileHeaderOffset; // offset of the local file header - ZipFile::ulong nFileDataOffset; // offset of the packed info inside the file; NOTE: this can be INVALID_DATA_OFFSET, if not calculated yet! - ZipFile::ushort nMethod; // the method of compression (0 if no compression/store) - ZipFile::ushort nNameOffset; // offset of the file name in the name pool for the directory - - // the file modification times - ZipFile::ushort nLastModTime; - ZipFile::ushort nLastModDate; - - uint64 nNTFS_LastModifyTime; - - // the offset to the start of the next file's header - this - // can be used to calculate the available space in zip file - ZipFile::ulong nEOFOffset; - const char* szOriginalFileName; // original filename (for CacheRW) - - FileEntry() - : nFileHeaderOffset(INVALID_DATA_OFFSET) - , szOriginalFileName(0){} - FileEntry(const ZipFile::CDRFileHeader& header, const SExtraZipFileData& extra); - - bool IsInitialized () - { - // structure marked as non-initialized should have nFileHeaderOffset == INVALID_DATA_OFFSET - return nFileHeaderOffset != INVALID_DATA_OFFSET; - } - // returns the name of this file, given the pointer to the name pool - const char* GetName(const char* pNamePool) const - { - return pNamePool + nNameOffset; - } - - // sets the current time to modification time - // calculates CRC32 for the new data - void OnNewFileData(void* pUncompressed, unsigned nSize, unsigned nCompressedSize, unsigned nCompressionMethod, bool bContinuous); - - uint64 GetModificationTime(); - void SetFromFileTimeNTFS(int64 timestamp); - bool CompareFileTimeNTFS(int64 timestamp); - }; - - // tries to refresh the file entry from the given file (reads fromthere if needed) - // returns the error code if the operation was impossible to complete - extern ErrorEnum Refresh (FILE* f, FileEntry* pFileEntry, bool encrpytedHeaders); - - // writes into the file local header - without Extra data - // puts the new offset to the file data to the file entry - // in case of error can put INVALID_DATA_OFFSET into the data offset field of file entry - extern ErrorEnum WriteLocalHeader (FILE* f, FileEntry* pFileEntry, const char* szRelativePath, bool encrypt); - - // conversion routines for the date/time fields used in Zip - extern ZipFile::ushort DOSDate(tm*); - extern ZipFile::ushort DOSTime(tm*); - - extern const char* DOSTimeCStr(ZipFile::ushort nTime); - extern const char* DOSDateCStr(ZipFile::ushort nTime); - - struct DirHeader; - // this structure represents a subdirectory descriptor in the directory record. - // it points to the actual directory info (list of its subdirs and files), as well - // as on its name - struct DirEntry - { - ZipFile::ulong nDirHeaderOffset;// offset, in bytes, relative to this object, of the actual directory record header - ZipFile::ulong nNameOffset; // offset of the dir name in the name pool of the parent directory - // returns the name of this directory, given the pointer to the name pool of hte parent directory - const char* GetName(const char* pNamePool) const - { - return pNamePool + nNameOffset; - } - - // returns the pointer to the actual directory record. - // call this function only for the actual structure instance contained in a directory record and - // followed by the other directory records - const DirHeader* GetDirectory () const - { - return (const DirHeader*)(((const char*)this) + nDirHeaderOffset); - } - DirHeader* GetDirectory () - { - return (DirHeader*)(((char*)this) + nDirHeaderOffset); - } - }; - - // this is the head of the directory record - // the name pool follows straight the directory and file entries. - struct DirHeader - { - ZipFile::ushort numDirs; // number of directory entries - DirEntry structures - ZipFile::ushort numFiles; // number of file entries - FileEntry structures - - // returns the pointer to the name pool that follows this object - // you can only call this method for the structure instance actually followed by the dir record - const char* GetNamePool() const - { - return ((char*)(this + 1)) + (size_t)this->numDirs * sizeof(DirEntry) + (size_t)this->numFiles * sizeof(FileEntry); - } - char* GetNamePool() - { - return ((char*)(this + 1)) + (size_t)this->numDirs * sizeof(DirEntry) + (size_t)this->numFiles * sizeof(FileEntry); - } - - // returns the pointer to the i-th directory - // call this only for the actual instance of the structure at the head of dir record - const DirEntry* GetSubdirEntry(unsigned i) const - { - assert (i < numDirs); - return ((const DirEntry*)(this + 1)) + i; - } - DirEntry* GetSubdirEntry(unsigned i) - { - assert (i < numDirs); - return ((DirEntry*)(this + 1)) + i; - } - - // returns the pointer to the i-th file - // call this only for the actual instance of the structure at the head of dir record - const FileEntry* GetFileEntry (unsigned i) const - { - assert (i < numFiles); - return (const FileEntry*)(((const DirEntry*)(this + 1)) + numDirs) + i; - } - FileEntry* GetFileEntry (unsigned i) - { - assert (i < numFiles); - return (FileEntry*)(((DirEntry*)(this + 1)) + numDirs) + i; - } - - // finds the subdirectory entry by the name, using the names from the name pool - // assumes: all directories are sorted in alphabetical order. - // case-sensitive (must be lower-case if case-insensitive search in Win32 is performed) - DirEntry* FindSubdirEntry(const char* szName); - - // finds the file entry by the name, using the names from the name pool - // assumes: all directories are sorted in alphabetical order. - // case-sensitive (must be lower-case if case-insensitive search in Win32 is performed) - FileEntry* FindFileEntry(const char* szName); - }; - - // this is the sorting predicate for directory entries - struct DirEntrySortPred - { - DirEntrySortPred (const char* pNamePool) - : m_pNamePool (pNamePool) - { - } - - bool operator () (const FileEntry& left, const FileEntry& right) const - { - return strcmp(left.GetName(m_pNamePool), right.GetName(m_pNamePool)) < 0; - } - - bool operator () (const FileEntry& left, const char* szRight) const - { - return strcmp(left.GetName(m_pNamePool), szRight) < 0; - } - - bool operator () (const char* szLeft, const FileEntry& right) const - { - return strcmp(szLeft, right.GetName(m_pNamePool)) < 0; - } - - bool operator () (const DirEntry& left, const DirEntry& right) const - { - return strcmp(left.GetName(m_pNamePool), right.GetName(m_pNamePool)) < 0; - } - - bool operator () (const DirEntry& left, const char* szName) const - { - return strcmp(left.GetName(m_pNamePool), szName) < 0; - } - - bool operator () (const char* szLeft, const DirEntry& right) const - { - return strcmp(szLeft, right.GetName(m_pNamePool)) < 0; - } - - const char* m_pNamePool; - }; - - inline void tolower (string& str) - { - for (size_t i = 0; i < str.length(); ++i) - { - const_cast(str[i]) = ::tolower(str[i]); - } - } - - void Encrypt(char* buffer, size_t size, const EncryptionKey& key); - void Decrypt(char* buffer, size_t size, const EncryptionKey& key); -} - -#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPDIRSTRUCTURES_H diff --git a/Code/Tools/CryCommonTools/crycommontools_files.cmake b/Code/Tools/CryCommonTools/crycommontools_files.cmake index d68c49836a..204a65f907 100644 --- a/Code/Tools/CryCommonTools/crycommontools_files.cmake +++ b/Code/Tools/CryCommonTools/crycommontools_files.cmake @@ -10,45 +10,6 @@ # set(FILES - PakSystem.cpp - TempFilePakExtraction.cpp - IPakSystem.h - PakSystem.h - PakXmlFileBufferSource.h - TempFilePakExtraction.h - FileUtil.cpp - PathHelpers.cpp StringHelpers.cpp - FileUtil.h - MathHelpers.h - PathHelpers.h - PropertyHelpers.h - PropertyHelpers.cpp - SimpleStringPool.h - StealingThreadPool.cpp - StealingThreadPool.h StringHelpers.h - ThreadUtils.cpp - ZipDir/ZipDirCache.cpp - ZipDir/ZipDirCacheFactory.cpp - ZipDir/ZipDirCacheRW.cpp - ZipDir/ZipDirFind.cpp - ZipDir/ZipDirFindRW.cpp - ZipDir/ZipDirList.cpp - ZipDir/ZipDirStructures.cpp - ZipDir/ZipDirTree.cpp - ThreadUtils.h - ZipDir/ZipDir.h - ZipDir/ZipDirCache.h - ZipDir/ZipDirCacheFactory.h - ZipDir/ZipDirCacheRW.h - ZipDir/ZipDirFind.h - ZipDir/ZipDirFindRW.h - ZipDir/ZipDirList.h - ZipDir/zipdirstructures.h - ZipDir/ZipDirTree.h - ZipDir/ZipFile.h - ZipDir/ZipFileFormat.h - ZipDir/ZipFileFormat_info.h - SuffixUtil.h ) diff --git a/Code/Tools/CryCommonTools/crycommontools_tests_files.cmake b/Code/Tools/CryCommonTools/crycommontools_tests_files.cmake deleted file mode 100644 index 13f6d90d3c..0000000000 --- a/Code/Tools/CryCommonTools/crycommontools_tests_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - UnitTests/PathHelpersUnitTests.cpp - UnitTests/StringHelpersUnitTests.cpp -) diff --git a/Code/Tools/CryCommonTools/zlibstatd64.lib b/Code/Tools/CryCommonTools/zlibstatd64.lib deleted file mode 100644 index 779712e946..0000000000 --- a/Code/Tools/CryCommonTools/zlibstatd64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9d9f51c3e75a4e80f45ba176511a84257146d6bc7c61f0cd582343544fd30e7c -size 277480 diff --git a/Code/Tools/CryXML/CMakeLists.txt b/Code/Tools/CryXML/CMakeLists.txt deleted file mode 100644 index a154fb6bd5..0000000000 --- a/Code/Tools/CryXML/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -if (NOT PAL_TRAIT_BUILD_HOST_TOOLS) - return() -endif() -ly_add_target( - NAME CryXML MODULE - NAMESPACE Legacy - FILES_CMAKE - cryxml_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - COMPILE_DEFINITIONS - PRIVATE - CRYTOOLS - RESOURCE_COMPILER - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::expat - Legacy::CryCommon - Legacy::CryCommonTools -) diff --git a/Code/Tools/CryXML/CryXML.cpp b/Code/Tools/CryXML/CryXML.cpp deleted file mode 100644 index 597c751b0d..0000000000 --- a/Code/Tools/CryXML/CryXML.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Defines the entry point for the DLL application. - - -#include "CryXML_precompiled.h" -#include "CryAssert_impl.h" -#include "ICryXML.h" -#include "XMLSerializer.h" -#include -#include - -class CryXML - : public ICryXML -{ -public: - CryXML(); - virtual void AddRef(); - virtual void Release(); - virtual IXMLSerializer* GetXMLSerializer(); - -private: - int nRefCount; - XMLSerializer serializer; -}; - -static CryXML* s_pCryXML = nullptr; - -#if defined(AZ_PLATFORM_WINDOWS) && !defined(AZ_MONOLITHIC_BUILD) -BOOL APIENTRY DllMain([[maybe_unused]] HANDLE hModule, [[maybe_unused]] DWORD ul_reason_for_call, [[maybe_unused]] LPVOID lpReserved) -{ - return TRUE; -} -#endif - -extern "C" DLL_EXPORT ICryXML * __stdcall GetICryXML() -{ - PREVENT_MODULE_AND_ENVIRONMENT_SYMBOL_STRIPPING - - if (!s_pCryXML) - { - s_pCryXML = new CryXML; - } - return s_pCryXML; -} - -CryXML::CryXML() - : nRefCount(0) -{ -} - -void CryXML::AddRef() -{ - ++this->nRefCount; -} - -void CryXML::Release() -{ - --this->nRefCount; - if (this->nRefCount == 0) - { - if (this == s_pCryXML) - { - s_pCryXML = nullptr; - } - delete this; - } -} - -IXMLSerializer* CryXML::GetXMLSerializer() -{ - return &this->serializer; -} - - -// STLPort requires folowing functions defined: - -// when using STL Port _STLP_DEBUG and _STLP_DEBUG_TERMINATE - avoid actually -// crashing (default terminator seems to kill the thread, which isn't nice). -#ifdef _STLP_DEBUG_TERMINATE -void __stl_debug_terminate(void) -{ - assert(0 && "STL Debug Error"); -} -#endif -#ifdef _STLP_DEBUG_MESSAGE -void __stl_debug_message(const char* format_str, ...) -{ - va_list __args; - va_start(__args, format_str); - vprintf(format_str, __args); - va_end(__args); -} -#endif //_STLP_DEBUG_MESSAGE diff --git a/Code/Tools/CryXML/CryXML.def b/Code/Tools/CryXML/CryXML.def deleted file mode 100644 index 6275474eab..0000000000 --- a/Code/Tools/CryXML/CryXML.def +++ /dev/null @@ -1,3 +0,0 @@ -LIBRARY CryXML -EXPORTS - GetICryXML @1 diff --git a/Code/Tools/CryXML/CryXML_precompiled.cpp b/Code/Tools/CryXML/CryXML_precompiled.cpp deleted file mode 100644 index 8bb231ffd1..0000000000 --- a/Code/Tools/CryXML/CryXML_precompiled.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CryXML_precompiled.h" diff --git a/Code/Tools/CryXML/CryXML_precompiled.h b/Code/Tools/CryXML/CryXML_precompiled.h deleted file mode 100644 index b7f48067b1..0000000000 --- a/Code/Tools/CryXML/CryXML_precompiled.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// -#pragma once - -#include - -#define CRY_ASSERT(condition) assert(condition) -#define CRY_ASSERT_TRACE(condition, message) assert(condition) -#define CRY_ASSERT_MESSAGE(condition, message) assert(condition) - -// Define this to prevent including CryAssert (there is no proper hook for turning this off, like the above). -#define CRYINCLUDE_CRYCOMMON_CRYASSERT_H - -#define CRY_STRING -#include - -#include "Cry_Math.h" diff --git a/Code/Tools/CryXML/ICryXML.h b/Code/Tools/CryXML/ICryXML.h deleted file mode 100644 index fddc95e60e..0000000000 --- a/Code/Tools/CryXML/ICryXML.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYXML_ICRYXML_H -#define CRYINCLUDE_CRYXML_ICRYXML_H -#pragma once - - -class IXMLSerializer; - -class ICryXML -{ -public: - virtual ~ICryXML() = default; - virtual void AddRef() = 0; - virtual void Release() = 0; - virtual IXMLSerializer* GetXMLSerializer() = 0; -}; - -// Prototype for the function that is exported by the DLL - use this function to -// get a pointer to an ICryXML object. The function is exported by name as GetICryXML(). -typedef ICryXML* (* FnGetICryXML)(); - -#endif // CRYINCLUDE_CRYXML_ICRYXML_H diff --git a/Code/Tools/CryXML/IXMLSerializer.h b/Code/Tools/CryXML/IXMLSerializer.h deleted file mode 100644 index 44347beb5b..0000000000 --- a/Code/Tools/CryXML/IXMLSerializer.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYXML_IXMLSERIALIZER_H -#define CRYINCLUDE_CRYXML_IXMLSERIALIZER_H -#pragma once - - -#include "IXml.h" -#include -class IXMLDataSink; -class IXMLDataSource; - -struct IXmlBufferSource -{ - virtual int Read(void* buffer, int size) const = 0; -}; - -class FileXmlBufferSource - : public IXmlBufferSource -{ -public: - FileXmlBufferSource(const char* path) - { - file = nullptr; - azfopen(&file, path, "r"); - } - ~FileXmlBufferSource() - { - if (file) - { - std::fclose(file); - } - } - - virtual int Read(void* buffer, int size) const - { - if (!file) - { - return 0; - } - return check_cast(std::fread(buffer, 1, size, file)); - } - -private: - mutable std::FILE* file; -}; - -class IXMLSerializer -{ -public: - virtual XmlNodeRef CreateNode(const char* tag) = 0; - virtual bool Write(XmlNodeRef root, const char* szFileName) = 0; - - virtual XmlNodeRef Read(const IXmlBufferSource& source, bool bRemoveNonessentialSpacesFromContent, int nErrorBufferSize, char* szErrorBuffer) = 0; -}; - -#endif // CRYINCLUDE_CRYXML_IXMLSERIALIZER_H diff --git a/Code/Tools/CryXML/XML/xml.cpp b/Code/Tools/CryXML/XML/xml.cpp deleted file mode 100644 index 4c117b54c7..0000000000 --- a/Code/Tools/CryXML/XML/xml.cpp +++ /dev/null @@ -1,1400 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CryXML_precompiled.h" - -//#define _CRT_SECURE_NO_DEPRECATE 1 -//#define _CRT_NONSTDC_NO_DEPRECATE -#include - -#define XML_STATIC -#include -#include "xml.h" -#include "../IXMLSerializer.h" -#include "Util.h" -#include -#include -#include - -#include -#include -#include -#include - -///////////////////////////////////////////////////////////////////// -// String pool implementation (from expat). -///////////////////////////////////////////////////////////////////// -class CSimpleStringPool -{ -public: - enum - { - STD_BLOCK_SIZE = 4096 - }; - struct BLOCK - { - BLOCK* next; - int size; - char s[1]; - }; - unsigned int m_blockSize; - BLOCK* m_blocks; - const char* m_end; - char* m_ptr; - char* m_start; - int nUsedSpace; - int nUsedBlocks; - - CSimpleStringPool() - { - m_blockSize = STD_BLOCK_SIZE; - m_blocks = 0; - m_start = 0; - m_ptr = 0; - m_end = 0; - nUsedSpace = 0; - nUsedBlocks = 0; - } - ~CSimpleStringPool() - { - BLOCK* p = m_blocks; - while (p) - { - BLOCK* temp = p->next; - //nFree++; - CryModuleFree(p); - p = temp; - } - m_blocks = 0; - m_ptr = 0; - m_start = 0; - m_end = 0; - } - void SetBlockSize(unsigned int nBlockSize) - { - if (nBlockSize > 1024 * 1024) - { - nBlockSize = 1024 * 1024; - } - unsigned int size = 512; - while (size < nBlockSize) - { - size *= 2; - } - - m_blockSize = size; - } - char* Append(const char* ptr, int nStrLen) - { - char* ret = m_ptr; - if (m_ptr && nStrLen + 1 < (m_end - m_ptr)) - { - memcpy(m_ptr, ptr, nStrLen); - m_ptr = m_ptr + nStrLen; - *m_ptr++ = 0; // add null termination. - } - else - { - int nNewBlockSize = Util::getMax(nStrLen + 1, (int)m_blockSize); - AllocBlock(nNewBlockSize); - memcpy(m_ptr, ptr, nStrLen); - m_ptr = m_ptr + nStrLen; - *m_ptr++ = 0; // add null termination. - ret = m_start; - } - nUsedSpace += nStrLen; - return ret; - } - char* ReplaceString(const char* str1, const char* str2) - { - int nStrLen1 = strlen(str1); - int nStrLen2 = strlen(str2); - - // undo ptr1 add. - if (m_ptr != m_start) - { - m_ptr = m_ptr - nStrLen1 - 1; - } - - assert(m_ptr == str1); - - int nStrLen = nStrLen1 + nStrLen2; - - char* ret = m_ptr; - if (m_ptr && nStrLen + 1 < (m_end - m_ptr)) - { - memcpy(m_ptr, str1, nStrLen1); - memcpy(m_ptr + nStrLen1, str2, nStrLen2); - m_ptr = m_ptr + nStrLen; - *m_ptr++ = 0; // add null termination. - } - else - { - int nNewBlockSize = Util::getMax(nStrLen + 1, (int)m_blockSize); - if (m_ptr == m_start) - { - ReallocBlock(nNewBlockSize * 2); // Reallocate current block. - memcpy(m_ptr + nStrLen1, str2, nStrLen2); - } - else - { - AllocBlock(nNewBlockSize); - memcpy(m_ptr, str1, nStrLen1); - memcpy(m_ptr + nStrLen1, str2, nStrLen2); - } - - m_ptr = m_ptr + nStrLen; - *m_ptr++ = 0; // add null termination. - ret = m_start; - } - nUsedSpace += nStrLen; - return ret; - } -private: - void AllocBlock(int blockSize) - { - //nMallocs++; - BLOCK* pBlock = (BLOCK*)CryModuleMalloc(offsetof(BLOCK, s) + blockSize * sizeof(char)); - if (!pBlock) - { - // no memory. - //CryError( "Out of memory" ); - m_ptr = 0; - m_start = 0; - m_end = 0; - return; - } - pBlock->size = blockSize; - pBlock->next = m_blocks; - m_blocks = pBlock; - m_ptr = pBlock->s; - m_start = pBlock->s; - m_end = pBlock->s + blockSize; - nUsedBlocks++; - } - void ReallocBlock(int blockSize) - { - BLOCK* pThisBlock = m_blocks; - BLOCK* pPrevBlock = m_blocks->next; - m_blocks = pPrevBlock; - //nMallocs++; - BLOCK* pBlock = (BLOCK*)CryModuleRealloc(pThisBlock, offsetof(BLOCK, s) + blockSize * sizeof(char)); - if (!pBlock) - { - // no memory. - //CryError( "Out of memory" ); - m_ptr = 0; - m_start = 0; - m_end = 0; - return; - } - pBlock->size = blockSize; - pBlock->next = m_blocks; - m_blocks = pBlock; - m_ptr = pBlock->s; - m_start = pBlock->s; - m_end = pBlock->s + blockSize; - } -}; - -////////////////////////////////////////////////////////////////////////// -static int __cdecl ascii_stricmp(const char* dst, const char* src) -{ - int f, l; - do - { - if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z')) - { - f -= 'A' - 'a'; - } - if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z')) - { - l -= 'A' - 'a'; - } - } - while (f && (f == l)); - return(f - l); -} - -////////////////////////////////////////////////////////////////////////// -XmlStrCmpFunc g_pXmlStrCmp = &ascii_stricmp; - -////////////////////////////////////////////////////////////////////////// -class CXmlStringData - : public IXmlStringData -{ -public: - int m_nRefCount; - XmlString m_string; - - CXmlStringData() { m_nRefCount = 0; } - virtual void AddRef() { ++m_nRefCount; } - virtual void Release() - { - if (--m_nRefCount <= 0) - { - delete this; - } - } - - virtual const char* GetString() { return m_string.c_str(); }; - virtual size_t GetStringLength() { return m_string.size(); }; -}; - -class CXmlStringPool - : public IXmlStringPool -{ -public: - char* AddString(const char* str) { return m_stringPool.Append(str, (int)strlen(str)); } -private: - CSimpleStringPool m_stringPool; -}; - -/** -****************************************************************************** -* CXmlNode implementation. -****************************************************************************** -*/ - -void CXmlNode::DeleteThis() -{ - delete this; -} - -CXmlNode::~CXmlNode() -{ - // Clear parent pointer from childs. - for (XmlNodes::const_iterator it = m_childs.begin(); it != m_childs.end(); ++it) - { - IXmlNode* node = *it; - ((CXmlNode*)node)->m_parent = 0; - } - m_pStringPool->Release(); -} - -CXmlNode::CXmlNode() -{ - m_tag = ""; - m_content = ""; - m_parent = 0; - m_nRefCount = 0; - m_pStringPool = 0; // must be changed later. -} - -CXmlNode::CXmlNode(const char* tag) -{ - m_content = ""; - m_parent = 0; - m_nRefCount = 0; - m_pStringPool = new CXmlStringPool; - m_pStringPool->AddRef(); - m_tag = m_pStringPool->AddString(tag); -} - -////////////////////////////////////////////////////////////////////////// -XmlNodeRef CXmlNode::createNode(const char* tag) -{ - CXmlNode* pNewNode = new CXmlNode; - pNewNode->m_pStringPool = m_pStringPool; - m_pStringPool->AddRef(); - pNewNode->m_tag = m_pStringPool->AddString(tag); - return XmlNodeRef(pNewNode); -} - -////////////////////////////////////////////////////////////////////////// -void CXmlNode::setTag(const char* tag) -{ - m_tag = m_pStringPool->AddString(tag); -} - -////////////////////////////////////////////////////////////////////////// -void CXmlNode::setContent(const char* str) -{ - m_content = str; -} - -////////////////////////////////////////////////////////////////////////// -bool CXmlNode::isTag(const char* tag) const -{ - return g_pXmlStrCmp(tag, m_tag) == 0; -} - -const char* CXmlNode::getAttr(const char* key) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - return svalue; - } - return ""; -} - -bool CXmlNode::getAttr(const char* key, const char** value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - *value = svalue; - return true; - } - else - { - *value = ""; - return false; - } -} - -bool CXmlNode::haveAttr(const char* key) const -{ - XmlAttrConstIter it = GetAttrConstIterator(key); - if (it != m_attributes.end()) - { - return true; - } - return false; -} - -void CXmlNode::delAttr(const char* key) -{ - XmlAttrIter it = GetAttrIterator(key); - if (it != m_attributes.end()) - { - m_attributes.erase(it); - } -} - -void CXmlNode::removeAllAttributes() -{ - m_attributes.clear(); -} - -void CXmlNode::setAttr(const char* key, const char* value) -{ - XmlAttrIter it = GetAttrIterator(key); - if (it == m_attributes.end()) - { - XmlAttribute tempAttr; - tempAttr.key = m_pStringPool->AddString(key); - tempAttr.value = m_pStringPool->AddString(value); - m_attributes.push_back(tempAttr); - // Sort attributes. - //std::sort( m_attributes.begin(),m_attributes.end() ); - } - else - { - // If already exist, override this member. - it->value = m_pStringPool->AddString(value); - } -} - -void CXmlNode::setAttr(const char* key, int value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%d", value); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, unsigned int value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%d", value); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, float value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%g", value); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, double value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%.17g", value); - setAttr(key, str); -} - -////////////////////////////////////////////////////////////////////////// -void CXmlNode::setAttr(const char* key, int64 value) -{ - char str[32]; - azsnprintf(str, sizeof(str), "%" PRId64, value); - setAttr(key, str); -} - -////////////////////////////////////////////////////////////////////////// -void CXmlNode::setAttr(const char* key, uint64 value, bool useHexFormat) -{ - char str[32]; - if (useHexFormat) - { - azsnprintf(str, sizeof(str), "%" PRIX64, value); - } - else - { - azsnprintf(str, sizeof(str), "%" PRIu64, value); - } - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, const Ang3& value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%g,%g,%g", value.x, value.y, value.z); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, const Vec2& value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%g,%g", value.x, value.y); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, const Vec2d& value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%.17g,%.17g", value.x, value.y); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, const Vec3& value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%g,%g,%g", value.x, value.y, value.z); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, const Vec3d& value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%.17g,%.17g,%.17g", value.x, value.y, value.z); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, const Vec4& value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%g,%g,%g,%g", value.x, value.y, value.z, value.w); - setAttr(key, str); -} - -void CXmlNode::setAttr(const char* key, const Quat& value) -{ - char str[128]; - azsnprintf(str, sizeof(str), "%g,%g,%g,%g", value.w, value.v.x, value.v.y, value.v.z); - setAttr(key, str); -} - -////////////////////////////////////////////////////////////////////////// -bool CXmlNode::getAttr(const char* key, int& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - value = atoi(svalue); - return true; - } - return false; -} - -bool CXmlNode::getAttr(const char* key, unsigned int& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - value = strtoul(svalue, NULL, 10); - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CXmlNode::getAttr(const char* key, int64& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - azsscanf(svalue, "%" PRId64, &value); - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CXmlNode::getAttr(const char* key, uint64& value, bool useHexFormat) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - if (useHexFormat) - { - azsscanf(svalue, "%" PRIX64, &value); - } - else - { - azsscanf(svalue, "%" PRIu64, &value); - } - return true; - } - return false; -} - -bool CXmlNode::getAttr(const char* key, bool& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - value = atoi(svalue) != 0; - return true; - } - return false; -} - -bool CXmlNode::getAttr(const char* key, float& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - value = (float)atof(svalue); - return true; - } - return false; -} - -bool CXmlNode::getAttr(const char* key, double& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - value = atof(svalue); - return true; - } - return false; -} - -bool CXmlNode::getAttr(const char* key, Ang3& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - float x, y, z; - if (azsscanf(svalue, "%f,%f,%f", &x, &y, &z) == 3) - { - value(x, y, z); - return true; - } - } - return false; -} - -bool CXmlNode::getAttr(const char* key, Vec2& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - float x, y; - if (azsscanf(svalue, "%f,%f", &x, &y) == 2) - { - value = Vec2(x, y); - return true; - } - } - return false; -} - -bool CXmlNode::getAttr(const char* key, Vec2d& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - double x, y; - if (azsscanf(svalue, "%lf,%lf", &x, &y) == 2) - { - value = Vec2d(x, y); - return true; - } - } - return false; -} - -bool CXmlNode::getAttr(const char* key, Vec3& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - float x, y, z; - if (azsscanf(svalue, "%f,%f,%f", &x, &y, &z) == 3) - { - value(x, y, z); - return true; - } - } - return false; -} - -bool CXmlNode::getAttr(const char* key, Vec4& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - float x, y, z, w; - if (azsscanf(svalue, "%f,%f,%f,%f", &x, &y, &z, &w) == 3) - { - value(x, y, z, w); - return true; - } - } - return false; -} - -bool CXmlNode::getAttr(const char* key, Vec3d& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - double x, y, z; - if (azsscanf(svalue, "%lf,%lf,%lf", &x, &y, &z) == 3) - { - value = Vec3d(x, y, z); - return true; - } - } - return false; -} - -bool CXmlNode::getAttr(const char* key, Quat& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - float w, x, y, z; - if (azsscanf(svalue, "%f,%f,%f,%f", &w, &x, &y, &z) == 4) - { - if (fabs(w) > VEC_EPSILON || fabs(x) > VEC_EPSILON || fabs(y) > VEC_EPSILON || fabs(z) > VEC_EPSILON) - { - //[AlexMcC|02.03.10] directly assign to members to avoid triggering the assert in Quat() with data from bad assets - value.w = w; - value.v = Vec3(x, y, z); - return value.IsValid(); - } - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CXmlNode::getAttr(const char* key, ColorB& value) const -{ - const char* svalue = GetValue(key); - if (svalue) - { - unsigned int r, g, b, a = 255; - int numFound = azsscanf(svalue, "%u,%u,%u,%u", &r, &g, &b, &a); - if (numFound == 3 || numFound == 4) - { - // If we only found 3 values, a should be unchanged, and still be 255 - if (r < 256 && g < 256 && b < 256 && a < 256) - { - value = ColorB(r, g, b, a); - return true; - } - } - } - return false; -} - - -XmlNodeRef CXmlNode::findChild(const char* tag) const -{ - for (XmlNodes::const_iterator it = m_childs.begin(); it != m_childs.end(); ++it) - { - if ((*it)->isTag(tag)) - { - return *it; - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CXmlNode::deleteChild(const char* tag) -{ - for (XmlNodes::iterator it = m_childs.begin(); it != m_childs.end(); ++it) - { - if ((*it)->isTag(tag)) - { - m_childs.erase(it); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CXmlNode::deleteChildAt(int nIndex) -{ - if (nIndex >= 0 && nIndex < (int)m_childs.size()) - { - m_childs.erase(m_childs.begin() + nIndex); - } -} - -//! Adds new child node. -void CXmlNode::addChild(const XmlNodeRef& node) -{ - assert(node != 0); - m_childs.push_back(node); - IXmlNode* n = node; - ((CXmlNode*)n)->m_parent = this; -}; - -void CXmlNode::setParent(const XmlNodeRef& inNewParent) -{ - // note, parent ptrs are not ref counted - IXmlNode* n = inNewParent; - m_parent = (CXmlNode*)n; -} - -void CXmlNode::insertChild(int inIndex, const XmlNodeRef& inNewChild) -{ - assert(inIndex >= 0 && inIndex <= getChildCount()); - assert(inNewChild != 0); - if (inIndex >= 0 && inIndex <= getChildCount() && inNewChild) - { - if (getChildCount() == 0) - { - addChild(inNewChild); - } - else - { - IXmlNode* pNode = ((IXmlNode*)inNewChild); - pNode->AddRef(); - m_childs.insert(m_childs.begin() + inIndex, pNode); - pNode->setParent(this); - } - } -} - -void CXmlNode::replaceChild(int inIndex, const XmlNodeRef& inNewChild) -{ - assert(inIndex >= 0 && inIndex < getChildCount()); - assert(inNewChild != 0); - if (inIndex >= 0 && inIndex < getChildCount() && inNewChild) - { - IXmlNode* wasChild = m_childs[inIndex]; - - if (wasChild->getParent() == this) - { - wasChild->setParent(XmlNodeRef()); // child is orphaned, will be freed by Release() below if this parent is last holding a reference to it - } - wasChild->Release(); - inNewChild->AddRef(); - m_childs[inIndex] = inNewChild; - inNewChild->setParent(this); - } -} - -XmlNodeRef CXmlNode::newChild(const char* tagName) -{ - XmlNodeRef node = createNode(tagName); - addChild(node); - return node; -} - -void CXmlNode::removeChild(const XmlNodeRef& node) -{ - XmlNodes::iterator it = std::find(m_childs.begin(), m_childs.end(), (IXmlNode*)node); - if (it != m_childs.end()) - { - m_childs.erase(it); - } -} - -void CXmlNode::removeAllChilds() -{ - m_childs.clear(); -} - -//! Get XML Node child nodes. -XmlNodeRef CXmlNode::getChild(int i) const -{ - assert(i >= 0 && i < (int)m_childs.size()); - return m_childs[i]; -} - -////////////////////////////////////////////////////////////////////////// -void CXmlNode::copyAttributes(XmlNodeRef fromNode) -{ - IXmlNode* inode = fromNode; - CXmlNode* n = (CXmlNode*)inode; - if (n->m_pStringPool == m_pStringPool) - { - m_attributes = n->m_attributes; - } - else - { - m_attributes.resize(n->m_attributes.size()); - for (int i = 0; i < (int)n->m_attributes.size(); i++) - { - m_attributes[i].key = m_pStringPool->AddString(n->m_attributes[i].key); - m_attributes[i].value = m_pStringPool->AddString(n->m_attributes[i].value); - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CXmlNode::getAttributeByIndex(int index, const char** key, const char** value) -{ - XmlAttributes::iterator it = m_attributes.begin(); - if (it != m_attributes.end()) - { - std::advance(it, index); - if (it != m_attributes.end()) - { - *key = it->key; - *value = it->value; - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -XmlNodeRef CXmlNode::clone() -{ - CXmlNode* node = new CXmlNode; - node->m_pStringPool = m_pStringPool; - m_pStringPool->AddRef(); - node->m_tag = m_tag; - node->m_content = m_content; - // Clone attributes. - CXmlNode* n = (CXmlNode*)(IXmlNode*)node; - n->copyAttributes(this); - // Clone sub nodes. - for (XmlNodes::const_iterator it = m_childs.begin(); it != m_childs.end(); ++it) - { - XmlNodeRef child = (*it)->clone(); - node->addChild(child); - } - - return node; -} - -////////////////////////////////////////////////////////////////////////// -static void AddTabsToString(XmlString& xml, int level) -{ - static const char* tabs[] = { - "", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - }; - // Add tabs. - if (level < sizeof(tabs) / sizeof(tabs[0])) - { - xml += tabs[level]; - } - else - { - for (int i = 0; i < level; i++) - { - xml += " "; - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CXmlNode::IsValidXmlString(const char* str) const -{ - if (strcspn(str, "\"\'&><") == strlen(str)) - { - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -XmlString CXmlNode::MakeValidXmlString(const XmlString& instr) const -{ - XmlString str = instr; - - // check if str contains any invalid characters - str.replace("&", "&"); - str.replace("\"", """); - str.replace("\'", "'"); - str.replace("<", "<"); - str.replace(">", ">"); - - return str; -} - -////////////////////////////////////////////////////////////////////////// -void CXmlNode::AddToXmlString(XmlString& xml, int level) const -{ - AddTabsToString(xml, level); - - // Begin Tag - if (m_attributes.empty()) - { - xml += "<"; - xml += m_tag; - if (*m_content == 0 && m_childs.empty()) - { - // Compact tag form. - xml += " />\n"; - return; - } - xml += ">"; - } - else - { - xml += "<"; - xml += m_tag; - xml += " "; - - // Put attributes. - for (XmlAttributes::const_iterator it = m_attributes.begin(); it != m_attributes.end(); ) - { - xml += it->key; - xml += "=\""; - if (IsValidXmlString(it->value)) - { - xml += it->value; - } - else - { - xml += MakeValidXmlString(it->value); - } - it++; - if (it != m_attributes.end()) - { - xml += "\" "; - } - else - { - xml += "\""; - } - } - if (*m_content == 0 && m_childs.empty()) - { - // Compact tag form. - xml += "/>\n"; - return; - } - xml += ">"; - } - - // Put node content. - if (IsValidXmlString(m_content)) - { - xml += m_content; - } - else - { - xml += MakeValidXmlString(m_content); - } - - if (m_childs.empty()) - { - xml += "\n"; - return; - } - - xml += "\n"; - - // Add sub nodes. - for (XmlNodes::const_iterator it = m_childs.begin(); it != m_childs.end(); ++it) - { - IXmlNode* node = *it; - ((CXmlNode*)node)->AddToXmlString(xml, level + 1); - } - - // Add tabs. - AddTabsToString(xml, level); - xml += "\n"; -} - -IXmlStringData* CXmlNode::getXMLData(int nReserveMem) const -{ - CXmlStringData* pStrData = new CXmlStringData; - pStrData->m_string.reserve(nReserveMem); - AddToXmlString(pStrData->m_string, 0); - return pStrData; -} - -XmlString CXmlNode::getXML(int level) const -{ - static XmlString xml; - xml = ""; - xml.reserve(6000000); - - AddToXmlString(xml, level); - return xml; -} - -bool CXmlNode::saveToFile(const char* fileName) -{ - XmlString xml = getXML(); - FILE* file = nullptr; - azfopen(&file, fileName, "wt"); - if (file) - { - const char* sxml = (const char*)xml; - fprintf(file, "%s", sxml); - fclose(file); - return true; - } - return false; -} - -/** -****************************************************************************** -* XmlParserImp class. -****************************************************************************** -*/ -class XmlParserImp - : public IXmlStringPool -{ -public: - explicit XmlParserImp(bool bRemoveNonessentialSpacesFromContent); - ~XmlParserImp(); - void beginParse(); - bool parse(const char* buffer, int bufLen); - XmlNodeRef endParse(XmlString& errorString); - - // Add new string to pool. - char* AddString(const char* str) { return m_stringPool.Append(str, (int)strlen(str)); } - //char* AddString( const char *str ) { return (char*)str; } - -protected: - void onStartElement(const char* tagName, const char** atts); - void onEndElement(const char* tagName); - void onRawData(const char* data); - - static void startElement(void* userData, const char* name, const char** atts) - { - ((XmlParserImp*)userData)->onStartElement(name, atts); - } - static void endElement(void* userData, const char* name) - { - ((XmlParserImp*)userData)->onEndElement(name); - } - static void characterData(void* userData, const char* s, int len) - { - char str[500000]; - if (len > sizeof(str) - 1) - { - assert(0); - len = sizeof(str) - 1; - } - memcpy(str, s, len); - str[len] = 0; - ((XmlParserImp*)userData)->onRawData(str); - } - - // First node will become root node. - std::vector nodeStack; - XmlNodeRef m_root; - - XML_Parser m_parser; - CSimpleStringPool m_stringPool; - bool m_bRemoveNonessentialSpacesFromContent; -}; - -/** -****************************************************************************** -* XmlParserImp -****************************************************************************** -*/ -void XmlParserImp::onStartElement(const char* tagName, const char** atts) -{ - XmlNodeRef parent; - CXmlNode* pCNode = new CXmlNode; - pCNode->m_pStringPool = this; - pCNode->m_pStringPool->AddRef(); - pCNode->m_tag = AddString(tagName); - - XmlNodeRef node = pCNode; - - if (!nodeStack.empty()) - { - parent = nodeStack.back(); - } - else - { - m_root = node; - } - nodeStack.push_back(node); - - if (parent) - { - parent->addChild(node); - } - - uint64 line = XML_GetCurrentLineNumber((XML_Parser)m_parser); - node->setLine(line > INT_MAX ? INT_MAX : (int)line); - - // Call start element callback. - int i = 0; - int numAttrs = 0; - while (atts[i] != 0) - { - numAttrs++; - i += 2; - } - if (numAttrs > 0) - { - i = 0; - pCNode->m_attributes.resize(numAttrs); - int nAttr = 0; - while (atts[i] != 0) - { - pCNode->m_attributes[nAttr].key = AddString(atts[i]); - pCNode->m_attributes[nAttr].value = AddString(atts[i + 1]); - nAttr++; - i += 2; - } - // Sort attributes. - //std::sort( pCNode->m_attributes.begin(),pCNode->m_attributes.end() ); - } -} - -void XmlParserImp::onEndElement([[maybe_unused]] const char* tagName) -{ - assert(!nodeStack.empty()); - if (!nodeStack.empty()) - { - nodeStack.pop_back(); - } -} - -void XmlParserImp::onRawData(const char* const data) -{ - if (data && data[0]) - { - CXmlNode* const node = (CXmlNode*)(IXmlNode*)nodeStack.back(); - - if (!m_bRemoveNonessentialSpacesFromContent) - { - // Implementation note: Skipping spaces in beginning (even although - // m_bRemoveNonessentialSpacesFromContent is false) allows us - // to avoid having lot of "space only" content nodes - if (node->m_content.empty()) - { - const size_t len = strlen(data); - const size_t spaceCount = strspn(data, "\r\n\t "); - - if (spaceCount < len) - { - node->m_content += &data[spaceCount]; - } - } - else - { - node->m_content += data; - } - } - else - { - const size_t len = strlen(data); - const size_t spaceCount = strspn(data, "\r\n\t "); - - if ((spaceCount > 0) && (!node->m_content.empty())) - { - node->m_content += " "; - } - - if (spaceCount < len) - { - node->m_content += &data[spaceCount]; - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -static void* custom_xml_malloc(size_t nSize) -{ - return CryModuleMalloc(nSize); -} -static void* custom_xml_realloc(void* p, size_t nSize) -{ - return CryModuleRealloc(p, nSize); -} -static void custom_xml_free(void* p) -{ - CryModuleFree(p); -} - -namespace CryXML_Internal -{ - XML_Memory_Handling_Suite memHandler; - XML_Memory_Handling_Suite* GetMemoryHandler() - { - memHandler.malloc_fcn = custom_xml_malloc; // CryModuleMalloc; - memHandler.realloc_fcn = custom_xml_realloc; // CryModuleRealloc; - memHandler.free_fcn = custom_xml_free; // CryModuleFree; - return &memHandler; - } -} - -XmlParserImp::XmlParserImp(bool bRemoveNonessentialSpacesFromContent) -{ - m_bRemoveNonessentialSpacesFromContent = bRemoveNonessentialSpacesFromContent; - - m_root = 0; - nodeStack.reserve(100); - - m_parser = XML_ParserCreate_MM(NULL, CryXML_Internal::GetMemoryHandler(), NULL); - - XML_SetUserData(m_parser, this); - XML_SetElementHandler(m_parser, startElement, endElement); - XML_SetCharacterDataHandler(m_parser, characterData); - XML_SetEncoding(m_parser, "utf-8"); -} - -XmlParserImp::~XmlParserImp() -{ - XML_ParserFree(m_parser); -} - -void XmlParserImp::beginParse() -{ - m_root = 0; - - m_stringPool.SetBlockSize(1 << 20); -} - -bool XmlParserImp::parse(const char* buffer, int bufLen) -{ - if (!XML_Parse(m_parser, buffer, (int)bufLen, 0)) - { - m_root = 0; - return false; - } - return true; -} - -XmlNodeRef XmlParserImp::endParse(XmlString& errorString) -{ - errorString = ""; - - if (!XML_Parse(m_parser, "", 0, 1)) - { - m_root = 0; - } - - if (!m_root) - { - const char* const errorText = XML_ErrorString(XML_GetErrorCode(m_parser)); - if (errorText) - { - errorString += "XML Error: "; - errorString += errorText; - // The following code is disabled by 'if (false)' because XML_GetCurrentLineNumber() - // XML_GetCurrentColumnNumber() return incorrect numbers. - // The issue (wrong numbers) might be fixed if/when we upgrade to a newer version - // of the Expat XML library (on 2014/02/26 CryEngine still uses expat version 1.95.2 - // from 2001/07/27, although the latest expat version is 2.1.0 from 2012/03/24). - if (false) - { - char s[64]; - azsprintf(s, " at line %d, column %d", (int)XML_GetCurrentLineNumber(m_parser), (int)XML_GetCurrentColumnNumber(m_parser)); - errorString += s; - } - } - } - - XmlNodeRef root = m_root; - m_root = 0; - return root; -} - -XmlParser::XmlParser(bool bRemoveNonessentialSpacesFromContent) -{ - m_pImpl = new XmlParserImp(bRemoveNonessentialSpacesFromContent); - m_pImpl->AddRef(); -} - -XmlParser::~XmlParser() -{ - m_pImpl->Release(); -} - -//! Parse xml file. -XmlNodeRef XmlParser::parse(const char* fileName) -{ - m_errorString = ""; - - std::vector buf; - auto pPak = GetISystem()->GetIPak(); - AZ::IO::HandleType file = pPak->FOpen(fileName, "rb"); - if (file) - { - pPak->FSeek(file, 0, SEEK_END); - int fileSize = pPak->FTell(file); - pPak->FSeek(file, 0, SEEK_SET); - buf.resize(fileSize); - pPak->FRead(&(buf[0]), fileSize, file); - pPak->FClose(file); - m_pImpl->parse(&buf[0], buf.size()); - return m_pImpl->endParse(m_errorString); - } - else - { - return XmlNodeRef(); - } -} - -//! Parse xml from memory buffer. -XmlNodeRef XmlParser::parseBuffer(const char* buffer) -{ - m_errorString = ""; - m_pImpl->beginParse(); - m_pImpl->parse(buffer, strlen(buffer)); - return m_pImpl->endParse(m_errorString); -} - -XmlNodeRef XmlParser::parseSource(const IXmlBufferSource* source) -{ - m_errorString = ""; - char buffer[40000]; - enum - { - bufferSize = sizeof(buffer) / sizeof(buffer[0]) - }; - m_pImpl->beginParse(); - int bytesRead = source->Read(buffer, bufferSize); - while (bytesRead) - { - if (!m_pImpl->parse(buffer, bytesRead)) - { - break; - } - bytesRead = source->Read(buffer, bufferSize); - } - return m_pImpl->endParse(m_errorString); -} diff --git a/Code/Tools/CryXML/XML/xml.h b/Code/Tools/CryXML/XML/xml.h deleted file mode 100644 index 8e9072acbf..0000000000 --- a/Code/Tools/CryXML/XML/xml.h +++ /dev/null @@ -1,471 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYXML_XML_XML_H -#define CRYINCLUDE_CRYXML_XML_XML_H -#pragma once - - -#include -#include -#include - -#include "IXml.h" - -struct IXmlBufferSource; - -struct IXmlStringPool -{ -public: - IXmlStringPool() { m_refCount = 0; } - virtual ~IXmlStringPool() {}; - void AddRef() { m_refCount++; }; - void Release() - { - if (--m_refCount <= 0) - { - delete this; - } - }; - virtual char* AddString(const char* str) = 0; -private: - int m_refCount; -}; - -/************************************************************************/ -/* XmlParser class, Parse xml and return root xml node if success. */ -/************************************************************************/ -class XmlParser -{ -public: - explicit XmlParser(bool bRemoveNonessentialSpacesFromContent); - ~XmlParser(); - - //! Parse xml file. - XmlNodeRef parse(const char* fileName); - - //! Parse xml from memory buffer. - XmlNodeRef parseBuffer(const char* buffer); - - XmlNodeRef parseSource(const IXmlBufferSource* source); - - const char* getErrorString() const { return m_errorString; } - -private: - XmlString m_errorString; - class XmlParserImp* m_pImpl; -}; - -// Compare function for string comparasion, can be strcmp or _stricmp -typedef int (__cdecl * XmlStrCmpFunc)(const char* str1, const char* str2); -extern XmlStrCmpFunc g_pXmlStrCmp; - -////////////////////////////////////////////////////////////////////////// -// XmlAttribute class -////////////////////////////////////////////////////////////////////////// -struct XmlAttribute -{ - const char* key; - const char* value; - - bool operator<(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) < 0; } - bool operator>(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) > 0; } - bool operator==(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) == 0; } - bool operator!=(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) != 0; } -}; - -//! Xml node attributes class. -typedef std::vector XmlAttributes; -typedef XmlAttributes::iterator XmlAttrIter; -typedef XmlAttributes::const_iterator XmlAttrConstIter; - -/** -****************************************************************************** -* CXmlNode class -* Never use CXmlNode directly instead use reference counted XmlNodeRef. -****************************************************************************** -*/ - -class CXmlNode - : public IXmlNode -{ -public: - //! Constructor. - CXmlNode(); - CXmlNode(const char* tag); - //! Destructor. - ~CXmlNode(); - - virtual void DeleteThis(); - - //! Create new XML node. - XmlNodeRef createNode(const char* tag); - - //! Get XML node tag. - const char* getTag() const { return m_tag; }; - void setTag(const char* tag); - - //! Return true if given tag equal to node tag. - bool isTag(const char* tag) const; - - //! Get XML Node attributes. - virtual int getNumAttributes() const { return (int)m_attributes.size(); }; - //! Return attribute key and value by attribute index. - virtual bool getAttributeByIndex(int index, const char** key, const char** value); - - virtual void copyAttributes(XmlNodeRef fromNode); - - //! Get XML Node attribute for specified key. - const char* getAttr(const char* key) const; - - //! Get XML Node attribute for specified key. - // Returns true if the attribute existes, alse otherwise. - bool getAttr(const char* key, const char** value) const; - - //! Check if attributes with specified key exist. - bool haveAttr(const char* key) const; - - //! Creates new xml node and add it to childs list. - XmlNodeRef newChild(const char* tagName); - - //! Adds new child node. - void addChild(const XmlNodeRef& node); - //! Remove child node. - void removeChild(const XmlNodeRef& node); - - void insertChild(int nIndex, const XmlNodeRef& node); - void replaceChild(int nIndex, const XmlNodeRef& node); - - //! Remove all child nodes. - void removeAllChilds(); - - //! Get number of child XML nodes. - int getChildCount() const { return (int)m_childs.size(); }; - - //! Get XML Node child nodes. - XmlNodeRef getChild(int i) const; - - //! Find node with specified tag. - XmlNodeRef findChild(const char* tag) const; - void deleteChild(const char* tag); - void deleteChildAt(int nIndex); - - //! Get parent XML node. - XmlNodeRef getParent() const { return m_parent; } - void setParent(const XmlNodeRef& inRef); - - //! Returns content of this node. - const char* getContent() const { return m_content.c_str(); }; - void setContent(const char* str); - - XmlNodeRef clone(); - - //! Returns line number for XML tag. - int getLine() const { return m_line; }; - //! Set line number in xml. - void setLine(int line) { m_line = line; }; - - //! Returns XML of this node and sub nodes. - virtual IXmlStringData* getXMLData(int nReserveMem = 0) const; - XmlString getXML(int level = 0) const; - bool saveToFile(const char* fileName) override; - - //! Set new XML Node attribute (or override attribute with same key). - void setAttr(const char* key, const char* value); - void setAttr(const char* key, int value); - void setAttr(const char* key, unsigned int value); - void setAttr(const char* key, int64 value); - void setAttr(const char* key, uint64 value, bool useHexFormat = true); - void setAttr(const char* key, float value); - void setAttr(const char* key, double value); - void setAttr(const char* key, const Vec2& value); - void setAttr(const char* key, const Vec2d& value); - void setAttr(const char* key, const Ang3& value); - void setAttr(const char* key, const Vec3& value); - void setAttr(const char* key, const Vec4& value); - void setAttr(const char* key, const Vec3d& value); - void setAttr(const char* key, const Quat& value); - - //! Delete attrbute. - void delAttr(const char* key); - //! Remove all node attributes. - void removeAllAttributes(); - - //! Get attribute value of node. - bool getAttr(const char* key, int& value) const; - bool getAttr(const char* key, unsigned int& value) const; - bool getAttr(const char* key, int64& value) const; - bool getAttr(const char* key, uint64& value, bool useHexFormat = true /*ignored*/) const; - bool getAttr(const char* key, float& value) const; - bool getAttr(const char* key, double& value) const; - bool getAttr(const char* key, bool& value) const; - bool getAttr(const char* key, XmlString& value) const - { - XmlString v; - if (v = getAttr(key)) - { - value = v; - return true; - } - else - { - return false; - } - } - bool getAttr(const char* key, Vec2& value) const; - bool getAttr(const char* key, Vec2d& value) const; - bool getAttr(const char* key, Ang3& value) const; - bool getAttr(const char* key, Vec3& value) const; - bool getAttr(const char* key, Vec3d& value) const; - bool getAttr(const char* key, Vec4& value) const; - bool getAttr(const char* key, Quat& value) const; - bool getAttr(const char* key, ColorB& value) const; - // bool getAttr( const char *key,string &value ) const { XmlString v; if (getAttr(key,v)) { value = (const char*)v; return true; } else return false; } - -#if !defined(RESOURCE_COMPILER) - // - // Summary: - // Collect all allocated memory - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { assert(0); }; - - // Summary: - // Copies children to this node from a given node. - // Children are reference copied (shallow copy) and the children's parent is NOT set to this - // node, but left with its original parent (which is still the parent) - void shareChildren([[maybe_unused]] const XmlNodeRef& fromNode) { assert(0); }; - - // Summary: - // Returns XML of this node and sub nodes into tmpBuffer without XML checks (much faster) - XmlString getXMLUnsafe(int level, [[maybe_unused]] char* tmpBuffer, [[maybe_unused]] uint32 sizeOfTmpBuffer) const { return getXML(level); } - - // Notes: - // Save in small memory chunks. - bool saveToFile([[maybe_unused]] const char* fileName, [[maybe_unused]] size_t chunkSizeBytes, [[maybe_unused]] AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle) override { assert(0); return false; }; - // -#endif - -private: - void AddToXmlString(XmlString& xml, int level) const; - XmlString MakeValidXmlString(const XmlString& xml) const; - bool IsValidXmlString(const char* str) const; - XmlAttrConstIter GetAttrConstIterator(const char* key) const - { - XmlAttribute tempAttr; - tempAttr.key = key; - - XmlAttributes::const_iterator it = std::find(m_attributes.begin(), m_attributes.end(), tempAttr); - return it; - - /* - XmlAttributes::const_iterator it = std::lower_bound( m_attributes.begin(),m_attributes.end(),tempAttr ); - if (it != m_attributes.end() && _stricmp(it->key,key) == 0) - return it; - return m_attributes.end(); - */ - } - XmlAttrIter GetAttrIterator(const char* key) - { - XmlAttribute tempAttr; - tempAttr.key = key; - - XmlAttributes::iterator it = std::find(m_attributes.begin(), m_attributes.end(), tempAttr); - return it; - - // XmlAttributes::iterator it = std::lower_bound( m_attributes.begin(),m_attributes.end(),tempAttr ); - //if (it != m_attributes.end() && _stricmp(it->key,key) == 0) - //return it; - //return m_attributes.end(); - } - const char* GetValue(const char* key) const - { - XmlAttrConstIter it = GetAttrConstIterator(key); - if (it != m_attributes.end()) - { - return it->value; - } - return 0; - } - -private: - //! Line in XML file where this node firstly appeared (usefull for debugging). - int m_line; - - //! Tag of XML node. - const char* m_tag; - //! Content of XML node. - XmlString m_content; - //! Parent XML node. - CXmlNode* m_parent; - - // String pool used by this node. - IXmlStringPool* m_pStringPool; - - typedef std::vector XmlNodes; - XmlNodes m_childs; - //! Xml node attributes. - XmlAttributes m_attributes; - - friend class XmlParserImp; -}; - -#endif // __XML_HEADER__ - - -/* -#ifndef __XML_HEADER__ -#define __XML_HEADER__ - - - -class CXmlNode : public IXmlNode -{ -public: - //! Constructor. - CXmlNode( const char *tag ); - //! Destructor. - ~CXmlNode(); - - ////////////////////////////////////////////////////////////////////////// - //! Reference counting. - void AddRef() { m_refCount++; }; - //! When ref count reach zero XML node dies. - void Release(); - - //! Create new XML node. - XmlNodeRef createNode( const char *tag ); - - //! Get XML node tag. - const char *getTag() const { return m_tag; }; - void setTag( const char *tag ) { m_tag = tag; } - - //! Return true if givven tag equal to node tag. - bool isTag( const char *tag ) const; - - //! Get XML Node attributes. - virtual int getNumAttributes() const { return (int)m_attributes.size(); }; - //! Return attribute key and value by attribute index. - virtual bool getAttributeByIndex( int index,const char **key,const char **value ); - - virtual void* getFirstAttribute(); - virtual bool getNextAttribute( void** pIterator,const char **key,const char **value ); - - virtual void copyAttributes( XmlNodeRef fromNode ); - - //! Get XML Node attribute for specified key. - const char* getAttr( const char *key ) const; - //! Check if attributes with specified key exist. - bool haveAttr( const char *key ) const; - - //! Adds new child node. - void addChild( const XmlNodeRef &node ); - - //! Creates new xml node and add it to childs list. - XmlNodeRef newChild( const char *tagName ); - - //! Remove child node. - void removeChild( const XmlNodeRef &node ); - - //! Remove all child nodes. - void removeAllChilds(); - - //! Get number of child XML nodes. - int getChildCount() const { return (int)m_childs.size(); }; - - //! Get XML Node child nodes. - XmlNodeRef getChild( int i ) const; - - //! Find node with specified tag. - XmlNodeRef findChild( const char *tag ) const; - - //! Get parent XML node. - XmlNodeRef getParent() const { return m_parent; } - - //! Returns content of this node. - const char* getContent() const { return m_content; }; - void setContent( const char *str ) { m_content = str; }; - void addContent( const char *str ) { m_content += str; }; - - XmlNodeRef clone(); - - //! Returns line number for XML tag. - int getLine() const { return m_line; }; - //! Set line number in xml. - void setLine( int line ) { m_line = line; }; - - //! Returns XML of this node and sub nodes. - XmlString getXML( int level=0 ) const; - XmlString getBinaryXML() const; - bool saveToFile( const char *fileName, bool bBinary = false ); - bool saveToSink(IXMLDataSink* pSink, bool bBinary = false); - - //! Set new XML Node attribute (or override attribute with same key). - void setAttr( const char* key,const char* value ); - void setAttr( const char* key,int value ); - void setAttr( const char* key,unsigned int value ); - void setAttr( const char* key,uint64 value ); - void setAttr( const char* key,float value ); - void setAttr( const char* key,const Ang3& value ); - void setAttr( const char* key,const Vec3& value ); - void setAttr( const char* key,const Quat &value ); - - //! Delete attribute. - void delAttr( const char* key ); - //! Remove all node attributes. - void removeAllAttributes(); - - //! Get attribute value of node. - bool getAttr( const char *key,int &value ) const; - bool getAttr( const char *key,unsigned int &value ) const; - bool getAttr( const char *key,uint64 &value ) const; - bool getAttr( const char *key,float &value ) const; - bool getAttr( const char *key,Ang3& value ) const; - bool getAttr( const char *key,Vec3& value ) const; - bool getAttr( const char *key,Quat &value ) const; - bool getAttr( const char *key,bool &value ) const; - bool getAttr( const char *key,XmlString &value ) const { XmlString v; if (v=getAttr(key)) { value = v; return true; } else return false; } -// bool getAttr( const char *key,string &value ) const { XmlString v; if (getAttr(key,v)) { value = (const char*)v; return true; } else return false; } - - // Add an attribute structure directly. - void addAttr(XmlAttribute& attribute); - - void SetBuffer(StringBuffer* pStringBuffer); - -private: - void AddToXmlString( XmlString &xml,int level ) const; - -private: - StringBuffer* m_pStringBuffer; - - //! Ref count itself, its zeroed on node creation. - int m_refCount; - - //! Line in XML file where this node firstly appeared (usefull for debuggin). - int m_line; - //! Tag of XML node. - XmlString m_tag; - - //! Content of XML node. - XmlString m_content; - //! Parent XML node. - CXmlNode *m_parent; - //! Next XML node in same hierarchy level. - - typedef std::vector XmlNodes; - XmlNodes m_childs; - //! Xml node attributes. - XmlAttributes m_attributes; - static XmlAttribute tempAttr; -}; - -#endif // CRYINCLUDE_CRYXML_XML_XML_H -*/ diff --git a/Code/Tools/CryXML/XMLSerializer.cpp b/Code/Tools/CryXML/XMLSerializer.cpp deleted file mode 100644 index e1152f93a3..0000000000 --- a/Code/Tools/CryXML/XMLSerializer.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CryXML_precompiled.h" -#include "XMLSerializer.h" -#include "XML/xml.h" -#include "IXMLSerializer.h" -#include "StringUtils.h" - -XmlNodeRef XMLSerializer::CreateNode(const char* tag) -{ - return new CXmlNode(tag); -} - -bool XMLSerializer::Write(XmlNodeRef root, const char* szFileName) -{ - return root->saveToFile(szFileName); -} - -XmlNodeRef XMLSerializer::Read(const IXmlBufferSource& source, bool bRemoveNonessentialSpacesFromContent, int nErrorBufferSize, char* szErrorBuffer) -{ - XmlParser parser(bRemoveNonessentialSpacesFromContent); - XmlNodeRef root = parser.parseSource(&source); - if (nErrorBufferSize > 0 && szErrorBuffer) - { - const char* const err = parser.getErrorString(); - cry_strcpy(szErrorBuffer, nErrorBufferSize, err ? err : ""); - } - return root; -} diff --git a/Code/Tools/CryXML/XMLSerializer.h b/Code/Tools/CryXML/XMLSerializer.h deleted file mode 100644 index 7730b19963..0000000000 --- a/Code/Tools/CryXML/XMLSerializer.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYXML_XMLSERIALIZER_H -#define CRYINCLUDE_CRYXML_XMLSERIALIZER_H -#pragma once - - -#include "IXMLSerializer.h" - -class XMLSerializer - : public IXMLSerializer -{ -public: - virtual XmlNodeRef CreateNode(const char* tag); - virtual bool Write(XmlNodeRef root, const char* szFileName); - - virtual XmlNodeRef Read(const IXmlBufferSource& source, bool bRemoveNonessentialSpacesFromContent, int nErrorBufferSize, char* szErrorBuffer); -}; - -#endif // CRYINCLUDE_CRYXML_XMLSERIALIZER_H diff --git a/Code/Tools/CryXML/cryxml_files.cmake b/Code/Tools/CryXML/cryxml_files.cmake deleted file mode 100644 index d81ace11b7..0000000000 --- a/Code/Tools/CryXML/cryxml_files.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - CryXML.cpp - XMLSerializer.cpp - ICryXML.h - IXMLSerializer.h - XMLSerializer.h - XML/xml.cpp - XML/xml.h - CryXML_precompiled.h - CryXML_precompiled.cpp -) diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/Bump2NormalHighQ.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/Bump2NormalHighQ.tif.exportsettings deleted file mode 100644 index e7bbaccd46..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/Bump2NormalHighQ.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /bumptype=1 /mipmirror=1 /preset=Bump2Normalmap_highQ /reduce=1 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/DiffusehighQWithAlpha256512.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/DiffusehighQWithAlpha256512.tif.exportsettings deleted file mode 100644 index 5f78477ca8..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/DiffusehighQWithAlpha256512.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Diffuse_highQ /reduce=1 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/DiffusehighQWithAlpha512256.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/DiffusehighQWithAlpha512256.tif.exportsettings deleted file mode 100644 index 5f78477ca8..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/DiffusehighQWithAlpha512256.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Diffuse_highQ /reduce=1 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/LuminanceOnly.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/LuminanceOnly.tif.exportsettings deleted file mode 100644 index 6466dc9099..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/LuminanceOnly.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /mipalphacoverage=0 /mipmirror=1 /preset=Diffuse_highQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPreset3DC_ddn.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPreset3DC_ddn.tif.exportsettings deleted file mode 100644 index acfbe2a750..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPreset3DC_ddn.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=0 /preset=Normalmap_lowQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8.tif.exportsettings deleted file mode 100644 index 00ecf3a56e..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Diffuse_lowQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8WithAlpha.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8WithAlpha.tif.exportsettings deleted file mode 100644 index 00ecf3a56e..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8WithAlpha.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Diffuse_lowQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8_bump.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8_bump.tif.exportsettings deleted file mode 100644 index cab995b31e..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8_bump.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Bump2Normalmap_lowQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8_ddn.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8_ddn.tif.exportsettings deleted file mode 100644 index c5a53f8bd5..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoPresetX8R8G8B8_ddn.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Normalmap_lowQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings.tif.exportsettings deleted file mode 100644 index 1048249b71..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /preset=Diffuse_lowQ diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings300400.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings300400.tif.exportsettings deleted file mode 100644 index db0b877f24..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings300400.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /preset=ReferenceImage diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettingsGrey_DDNDIF.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettingsGrey_DDNDIF.tif.exportsettings deleted file mode 100644 index 1048249b71..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettingsGrey_DDNDIF.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /preset=Diffuse_lowQ diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings_DDNDIF.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings_DDNDIF.tif.exportsettings deleted file mode 100644 index 84c0416421..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NoTIFSettings_DDNDIF.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /ms=0 /preset=Diffuse_lowQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQ.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQ.tif.exportsettings deleted file mode 100644 index c5a53f8bd5..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQ.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Normalmap_lowQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQReduce1_ddn.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQReduce1_ddn.tif.exportsettings deleted file mode 100644 index cb9f25b5d9..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQReduce1_ddn.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Normalmap_lowQ /reduce=1 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQ_ddn.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQ_ddn.tif.exportsettings deleted file mode 100644 index c5a53f8bd5..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/NormalmapLowQ_ddn.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumpblur=0.000000 /bumpstrength=5.000000 /mipmirror=1 /preset=Normalmap_lowQ /reduce=0 diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/TestColorChart_cch.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/TestColorChart_cch.tif.exportsettings deleted file mode 100644 index 47b9f504fd..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/TestColorChart_cch.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /preset=ColorChart diff --git a/Code/Tools/TestBed/ResourceCompilerImage/Input/diamand_plate_ddn.tif.exportsettings b/Code/Tools/TestBed/ResourceCompilerImage/Input/diamand_plate_ddn.tif.exportsettings deleted file mode 100644 index 3e5edcd652..0000000000 --- a/Code/Tools/TestBed/ResourceCompilerImage/Input/diamand_plate_ddn.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumptype=1 /preset=Bump2Normalmap_lowQ /reduce=0 diff --git a/Gems/Blast/Assets/.p4ignore b/Gems/Blast/Assets/.p4ignore deleted file mode 100644 index 7015097e56..0000000000 --- a/Gems/Blast/Assets/.p4ignore +++ /dev/null @@ -1 +0,0 @@ -*.physx diff --git a/Tools/AnimationTest/assetImportTest.bat b/Tools/AnimationTest/assetImportTest.bat deleted file mode 100644 index 205c17280b..0000000000 --- a/Tools/AnimationTest/assetImportTest.bat +++ /dev/null @@ -1,31 +0,0 @@ -REM -REM -REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -REM its licensors. -REM -REM For complete copyright and license terms please see the LICENSE at the root of this -REM distribution (the "License"). All use of this software is governed by the License, -REM or, if provided, by the license below or the license accompanying this file. Do not -REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -REM - -TITLE asset import test - -SETLOCAL EnableExtensions -set EXE=AssetProcessor_tmp.exe -FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq %EXE%"') DO IF %%x == %EXE% goto FOUND -echo Make sure asset processor is running before run this script. -goto FIN -:FOUND - -SET F="..\..\Cache\SamplesProject\pc\samplesproject\objects" - -IF EXIST %F% ( - RMDIR /S /Q %F% - ECHO Detected folder at %F% - ECHO Make sure there's no fail / crash in asset processor after all job finished. -) ELSE (ECHO folder %F% NOT FOUND) - -:FIN -PAUSE \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/7z.exe b/Tools/DeepBandwidthToExcel/7z.exe deleted file mode 100644 index 85fa5e2917..0000000000 --- a/Tools/DeepBandwidthToExcel/7z.exe +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ca56c2a96859b5171e7d24c81ed4d281da0ea26a7eaff7eac975d337eb4a2e1 -size 266752 diff --git a/Tools/DeepBandwidthToExcel/DeepBandwidthToExcel.exe b/Tools/DeepBandwidthToExcel/DeepBandwidthToExcel.exe deleted file mode 100644 index b89cb8c457..0000000000 --- a/Tools/DeepBandwidthToExcel/DeepBandwidthToExcel.exe +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6b8dc17c53df32173fd82d8bfc844bc3752bf6cbaf1bf2fd334dd6949f44b04b -size 1050344 diff --git a/Tools/DeepBandwidthToExcel/Template/[Content_Types].xml b/Tools/DeepBandwidthToExcel/Template/[Content_Types].xml deleted file mode 100644 index 3c4fc1468a..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/[Content_Types].xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/_rels/.rels b/Tools/DeepBandwidthToExcel/Template/_rels/.rels deleted file mode 100644 index 74bfd8d955..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/_rels/.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/docProps/app.xml b/Tools/DeepBandwidthToExcel/Template/docProps/app.xml deleted file mode 100644 index 6430cd86f5..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/docProps/app.xml +++ /dev/null @@ -1,2 +0,0 @@ - -Microsoft Excel0falseWorksheets9Group TotalsMessage TotalsPolicy CountPolicy ImpactSerialisation ImpactBandwidth Over TimeSocket Packets Over TimeSocket Bits Over TimeWarningsCrytek UKfalsefalsefalse12.0000 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/docProps/core.xml b/Tools/DeepBandwidthToExcel/Template/docProps/core.xml deleted file mode 100644 index f1efda39ff..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/docProps/core.xml +++ /dev/null @@ -1,2 +0,0 @@ - -leelee2012-03-06T13:44:11Z2012-03-23T08:28:17Z \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/_rels/workbook.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/_rels/workbook.xml.rels deleted file mode 100644 index e9dc190f2c..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/_rels/workbook.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/calcChain.xml b/Tools/DeepBandwidthToExcel/Template/xl/calcChain.xml deleted file mode 100644 index 2fb95911c6..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/calcChain.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart1.xml b/Tools/DeepBandwidthToExcel/Template/xl/charts/chart1.xml deleted file mode 100644 index 3e3737423c..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart1.xml +++ /dev/null @@ -1,2 +0,0 @@ - -Overall By Schedule Group'Group Totals'!###---SHEET1_COL0---###peterpaul'Group Totals'!###---SHEET1_COL1---###General55 diff --git a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart2.xml b/Tools/DeepBandwidthToExcel/Template/xl/charts/chart2.xml deleted file mode 100644 index 54d3f0da26..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart2.xml +++ /dev/null @@ -1,2 +0,0 @@ - -Overall By Message'Message Totals'!###---SHEET2_COL0---###peterpaul'Message Totals'!###---SHEET2_COL1---###General55 diff --git a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart3.xml b/Tools/DeepBandwidthToExcel/Template/xl/charts/chart3.xml deleted file mode 100644 index f405df758f..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart3.xml +++ /dev/null @@ -1,2 +0,0 @@ - -Overall By Policy Count'Policy Count'!###---SHEET3_COL0---###ui2eid'Policy Count'!###---SHEET3_COL1---###General20801811398975 diff --git a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart4.xml b/Tools/DeepBandwidthToExcel/Template/xl/charts/chart4.xml deleted file mode 100644 index 6d461a7cd5..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart4.xml +++ /dev/null @@ -1,2 +0,0 @@ - -Overall By Policy Impact (Bits Per Policy)'Policy Impact'!###---SHEET4_COL0---###wrlddMov'Policy Impact'!###---SHEET4_COL1---###General5354582913312905 diff --git a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart5.xml b/Tools/DeepBandwidthToExcel/Template/xl/charts/chart5.xml deleted file mode 100644 index 5276503965..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart5.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - Overall By Serialisation Impact (Bits - - - - Per Serialise) - - - - - - - - - - - - - - - - - - - - 'Serialisation Impact'!###---SHEET5_COL0---### - - - - wrld - - - dMov - - - - - - - 'Serialisation Impact'!###---SHEET5_COL1---### - - General - - - 53545829 - - - 13312905 - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart6.xml b/Tools/DeepBandwidthToExcel/Template/xl/charts/chart6.xml deleted file mode 100644 index 3dbcb710ee..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart6.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - Bandwidth Over Time - - - - - - - - - - ###---SHEET6_CHART---### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart7.xml b/Tools/DeepBandwidthToExcel/Template/xl/charts/chart7.xml deleted file mode 100644 index 324a3d0296..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart7.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - Socket - - - - Packets Per Second - - - - - - - - - - - ###---SHEET7_CHART---### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart8.xml b/Tools/DeepBandwidthToExcel/Template/xl/charts/chart8.xml deleted file mode 100644 index 9aed1eaa0b..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/charts/chart8.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - Socket - - - - Bits Per Second - - - - - - - - - - ###---SHEET8_CHART---### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing1.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing1.xml.rels deleted file mode 100644 index 91223aab09..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing1.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing2.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing2.xml.rels deleted file mode 100644 index 63233beb83..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing2.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing3.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing3.xml.rels deleted file mode 100644 index c53f6617a5..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing3.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing4.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing4.xml.rels deleted file mode 100644 index 7fe138bac4..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing4.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing5.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing5.xml.rels deleted file mode 100644 index 22864411ec..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing5.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing6.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing6.xml.rels deleted file mode 100644 index 424914396d..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing6.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing7.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing7.xml.rels deleted file mode 100644 index b1404c3db9..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing7.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing8.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing8.xml.rels deleted file mode 100644 index a9e371607f..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/_rels/drawing8.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing1.xml b/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing1.xml deleted file mode 100644 index 70ea7ed3be..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing1.xml +++ /dev/null @@ -1,2 +0,0 @@ - -43809902857429952440114299 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing2.xml b/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing2.xml deleted file mode 100644 index f8a60ce08a..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing2.xml +++ /dev/null @@ -1,2 +0,0 @@ - -338100076199285810254057150 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing3.xml b/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing3.xml deleted file mode 100644 index 75e5d9ed25..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing3.xml +++ /dev/null @@ -1,2 +0,0 @@ - -2276225095250283714754019050 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing4.xml b/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing4.xml deleted file mode 100644 index de297dbb14..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing4.xml +++ /dev/null @@ -1,2 +0,0 @@ - -3001333492851435040123824 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing5.xml b/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing5.xml deleted file mode 100644 index b7c2cf9c02..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing5.xml +++ /dev/null @@ -1,2 +0,0 @@ - -25524500104775284572004095250 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing6.xml b/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing6.xml deleted file mode 100644 index c610b4c052..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing6.xml +++ /dev/null @@ -1,2 +0,0 @@ - -338099914287528257174409525 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing7.xml b/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing7.xml deleted file mode 100644 index 14d255a242..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing7.xml +++ /dev/null @@ -1,2 +0,0 @@ - -247624310477526533399389525 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing8.xml b/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing8.xml deleted file mode 100644 index 1b94acd279..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/drawings/drawing8.xml +++ /dev/null @@ -1,2 +0,0 @@ - -23809931047752744767539114301 \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/sharedStrings.xml b/Tools/DeepBandwidthToExcel/Template/xl/sharedStrings.xml deleted file mode 100644 index 2fbc1ad0b7..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/sharedStrings.xml +++ /dev/null @@ -1,2 +0,0 @@ - -###---STRINGSTABLE---### diff --git a/Tools/DeepBandwidthToExcel/Template/xl/styles.xml b/Tools/DeepBandwidthToExcel/Template/xl/styles.xml deleted file mode 100644 index 8238b50fd0..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/styles.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/theme/theme1.xml b/Tools/DeepBandwidthToExcel/Template/xl/theme/theme1.xml deleted file mode 100644 index 9944f3ecab..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/theme/theme1.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/workbook.xml b/Tools/DeepBandwidthToExcel/Template/xl/workbook.xml deleted file mode 100644 index 19c26d83b6..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/workbook.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet1.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet1.xml.rels deleted file mode 100644 index 205832e91b..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet1.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet2.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet2.xml.rels deleted file mode 100644 index b48a928346..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet2.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet3.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet3.xml.rels deleted file mode 100644 index c0c5ded4a6..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet3.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet4.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet4.xml.rels deleted file mode 100644 index f34eab954f..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet4.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet5.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet5.xml.rels deleted file mode 100644 index 67118d3a1e..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet5.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet6.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet6.xml.rels deleted file mode 100644 index 656a337f58..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet6.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet7.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet7.xml.rels deleted file mode 100644 index efc518bb3f..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet7.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet8.xml.rels b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet8.xml.rels deleted file mode 100644 index 586d2d3c76..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/_rels/sheet8.xml.rels +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet1.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet1.xml deleted file mode 100644 index 1fbfb22964..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet1.xml +++ /dev/null @@ -1,2 +0,0 @@ - -###---SHEET1_DATA---### diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet2.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet2.xml deleted file mode 100644 index 0d72f8c9da..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet2.xml +++ /dev/null @@ -1,2 +0,0 @@ - -###---SHEET2_DATA---### diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet3.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet3.xml deleted file mode 100644 index 18717c6987..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet3.xml +++ /dev/null @@ -1,2 +0,0 @@ - -###---SHEET3_DATA---### diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet4.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet4.xml deleted file mode 100644 index 9442249676..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet4.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - -###---SHEET4_DATA---### - - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet5.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet5.xml deleted file mode 100644 index 14f48b192c..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet5.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - -###---SHEET5_DATA---### - - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet6.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet6.xml deleted file mode 100644 index fa7a8d800b..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet6.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - -###---SHEET6_DATA---### - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet7.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet7.xml deleted file mode 100644 index 708d01d20c..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet7.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - -###---SHEET7_DATA---### - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet8.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet8.xml deleted file mode 100644 index 164cdcdde2..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet8.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - -###---SHEET8_DATA---### - - diff --git a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet9.xml b/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet9.xml deleted file mode 100644 index a3a3b40230..0000000000 --- a/Tools/DeepBandwidthToExcel/Template/xl/worksheets/sheet9.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - -###---SHEET9_DATA---### - - diff --git a/scripts/build/package/Platform/Windows/package_filelists/atom.json b/scripts/build/package/Platform/Windows/package_filelists/atom.json index f084173cb2..5f3d3b78cb 100644 --- a/scripts/build/package/Platform/Windows/package_filelists/atom.json +++ b/scripts/build/package/Platform/Windows/package_filelists/atom.json @@ -38,24 +38,13 @@ "AzTestRunner/**": "#include", "CrashHandler/**": "#include", "CryCommonTools/**": "#include", - "CrySCompileServer/**": "#include", - "CryXML/**": "#include", "DeltaCataloger/**": "#include", - "GemRegistry/**": "#include", "GridHub/**": "#include", - "HLSLCrossCompiler/**": "#include", - "HLSLCrossCompilerMETAL/**": "#include", - "LyIdentity/**": "#include", - "LyMetrics/**": "#include", "News/**": "#include", "PythonBindingsExample/**": "#include", - "RC/**": "#include", "RemoteConsole/**": "#include", "SceneAPI/**": "#include", "SerializeContextTools/**": "#include", - "ShaderCacheGen/**": "#include", - "SharedQMLResource/**": "#include", - "Woodpecker/**": "#include", "CMakeLists.txt": "#include" }, "CMakeLists.txt": "#include" From 795aa114e69f6846133442da9d74cae56416ca39 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Thu, 13 May 2021 16:19:53 +0100 Subject: [PATCH 184/225] Improve selection in the viewport (#720) * improve selection in the viewport * remove debug code * updates following review feedback - update API comments from /// to //! from - add [[nodiscard]] attribute to member function - move constructor implementations to .cpp files * use lambda instead of ternary operator * fix unit test failure caused by typo --- .../AzFramework/Viewport/CameraInput.cpp | 95 ++++++----- .../AzFramework/Viewport/CameraInput.h | 29 ++-- .../AzFramework/Viewport/ClickDetector.cpp | 68 ++++++++ .../AzFramework/Viewport/ClickDetector.h | 75 +++++++++ .../AzFramework/Viewport/CursorState.h | 56 +++++++ .../AzFramework/azframework_files.cmake | 3 + .../EditorTransformComponentSelection.cpp | 36 +++- .../EditorTransformComponentSelection.h | 156 +++++++++--------- Code/Framework/Tests/ClickDetectorTests.cpp | 142 ++++++++++++++++ Code/Framework/Tests/CursorStateTests.cpp | 54 ++++++ .../Tests/frameworktests_files.cmake | 2 + 11 files changed, 573 insertions(+), 143 deletions(-) create mode 100644 Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.cpp create mode 100644 Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.h create mode 100644 Code/Framework/AzFramework/AzFramework/Viewport/CursorState.h create mode 100644 Code/Framework/Tests/ClickDetectorTests.cpp create mode 100644 Code/Framework/Tests/CursorStateTests.cpp diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index 8669b58911..daf2c63921 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -156,35 +157,25 @@ namespace AzFramework camera.m_lookAt = transform.GetTranslation() + (camera.Rotation().GetBasisY() * -camera.m_lookDist); } - static ScreenVector CursorDelta(const AZStd::optional& currentPosition, const AZStd::optional& lastPosition) - { - return currentPosition.has_value() && lastPosition.has_value() ? currentPosition.value() - lastPosition.value() - : ScreenVector(0, 0); - } - bool CameraSystem::HandleEvents(const InputEvent& event) { if (const auto& cursor = AZStd::get_if(&event)) { - m_currentCursorPosition = cursor->m_position; + m_cursorState.SetCurrentPosition(cursor->m_position); } else if (const auto& scroll = AZStd::get_if(&event)) { m_scrollDelta = scroll->m_delta; } - return m_cameras.HandleEvents(event, CursorDelta(m_currentCursorPosition, m_lastCursorPosition), m_scrollDelta); + return m_cameras.HandleEvents(event, m_cursorState.CursorDelta(), m_scrollDelta); } Camera CameraSystem::StepCamera(const Camera& targetCamera, const float deltaTime) { - const auto cursorDelta = CursorDelta(m_currentCursorPosition, m_lastCursorPosition); - if (m_currentCursorPosition.has_value()) - { - m_lastCursorPosition = m_currentCursorPosition; - } + const auto nextCamera = m_cameras.StepCamera(targetCamera, m_cursorState.CursorDelta(), m_scrollDelta, deltaTime); - const auto nextCamera = m_cameras.StepCamera(targetCamera, cursorDelta, m_scrollDelta, deltaTime); + m_cursorState.Update(); m_scrollDelta = 0.0f; @@ -236,12 +227,12 @@ namespace AzFramework } } - // accumulate - Camera nextCamera = targetCamera; - for (auto& cameraInput : m_activeCameraInputs) - { - nextCamera = cameraInput->StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime); - } + const Camera nextCamera = AZStd::accumulate( + AZStd::begin(m_activeCameraInputs), AZStd::end(m_activeCameraInputs), targetCamera, + [cursorDelta, scrollDelta, deltaTime](Camera acc, auto& camera) { + acc = camera->StepCamera(acc, cursorDelta, scrollDelta, deltaTime); + return acc; + }); for (int i = 0; i < m_activeCameraInputs.size();) { @@ -275,34 +266,42 @@ namespace AzFramework } } + RotateCameraInput::RotateCameraInput(const InputChannelId rotateChannelId) + : m_rotateChannelId(rotateChannelId) + { + } + void RotateCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { - if (const auto& input = AZStd::get_if(&event)) - { - if (input->m_channelId == m_rotateChannelId) + const ClickDetector::ClickEvent clickEvent = [&event, this] { + if (const auto& input = AZStd::get_if(&event)) { - if (input->m_state == InputChannel::State::Began) + if (input->m_channelId == m_rotateChannelId) { - m_tryingToBegin = true; - m_moveAccumulator = 0.0f; - } - else if (input->m_state == InputChannel::State::Ended) - { - m_tryingToBegin = false; - EndActivation(); + if (input->m_state == InputChannel::State::Began) + { + return ClickDetector::ClickEvent::Down; + } + else if (input->m_state == InputChannel::State::Ended) + { + return ClickDetector::ClickEvent::Up; + } } } - } + return ClickDetector::ClickEvent::Nil; + }(); - if (m_tryingToBegin) + switch (const auto outcome = m_clickDetector.DetectClick(clickEvent, cursorDelta); outcome) { - // only allow the action to begin if the mouse has been moved a small amount - m_moveAccumulator += ScreenVectorLength(cursorDelta); - if (m_moveAccumulator > ed_cameraSystemLookDeadzone) - { - BeginActivation(); - m_tryingToBegin = false; - } + case ClickDetector::ClickOutcome::Move: + BeginActivation(); + break; + case ClickDetector::ClickOutcome::Release: + EndActivation(); + break; + default: + // noop + break; } } @@ -324,6 +323,12 @@ namespace AzFramework return nextCamera; } + PanCameraInput::PanCameraInput(const InputChannelId panChannelId, PanAxesFn panAxesFn) + : m_panAxesFn(AZStd::move(panAxesFn)) + , m_panChannelId(panChannelId) + { + } + void PanCameraInput::HandleEvents( const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { @@ -400,6 +405,11 @@ namespace AzFramework return TranslationType::Nil; } + TranslateCameraInput::TranslateCameraInput(TranslationAxesFn translationAxesFn) + : m_translationAxesFn(AZStd::move(translationAxesFn)) + { + } + void TranslateCameraInput::HandleEvents( const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { @@ -574,6 +584,11 @@ namespace AzFramework return nextCamera; } + OrbitDollyCursorMoveCameraInput::OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId) + : m_dollyChannelId(dollyChannelId) + { + } + void OrbitDollyCursorMoveCameraInput::HandleEvents( const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h index 6475753017..41d7f11385 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include @@ -188,26 +190,21 @@ namespace AzFramework Cameras m_cameras; private: + CursorState m_cursorState; float m_scrollDelta = 0.0f; - AZStd::optional m_lastCursorPosition; - AZStd::optional m_currentCursorPosition; }; class RotateCameraInput : public CameraInput { public: - explicit RotateCameraInput(const InputChannelId rotateChannelId) - : m_rotateChannelId(rotateChannelId) - { - } + explicit RotateCameraInput(InputChannelId rotateChannelId); void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; private: InputChannelId m_rotateChannelId; - float m_moveAccumulator = 0.0f; - bool m_tryingToBegin = false; + ClickDetector m_clickDetector; }; struct PanAxes @@ -240,11 +237,8 @@ namespace AzFramework class PanCameraInput : public CameraInput { public: - PanCameraInput(const InputChannelId panChannelId, PanAxesFn panAxesFn) - : m_panAxesFn(AZStd::move(panAxesFn)) - , m_panChannelId(panChannelId) - { - } + PanCameraInput(InputChannelId panChannelId, PanAxesFn panAxesFn); + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; @@ -283,10 +277,8 @@ namespace AzFramework class TranslateCameraInput : public CameraInput { public: - explicit TranslateCameraInput(TranslationAxesFn translationAxesFn) - : m_translationAxesFn(AZStd::move(translationAxesFn)) - { - } + explicit TranslateCameraInput(TranslationAxesFn translationAxesFn); + void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; void ResetImpl() override; @@ -363,8 +355,7 @@ namespace AzFramework class OrbitDollyCursorMoveCameraInput : public CameraInput { public: - explicit OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId) - : m_dollyChannelId(dollyChannelId) {} + explicit OrbitDollyCursorMoveCameraInput(InputChannelId dollyChannelId); void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.cpp new file mode 100644 index 0000000000..5af44a81bc --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.cpp @@ -0,0 +1,68 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include + +namespace AzFramework +{ + ClickDetector::ClickOutcome ClickDetector::DetectClick(const ClickEvent clickEvent, const ScreenVector& cursorDelta) + { + if (clickEvent == ClickEvent::Down) + { + const auto now = std::chrono::steady_clock::now(); + if (m_tryBeginTime) + { + const std::chrono::duration diff = now - m_tryBeginTime.value(); + if (diff.count() < m_doubleClickInterval) + { + return ClickOutcome::Nil; + } + } + + m_detectionState = DetectionState::WaitingForMove; + m_moveAccumulator = 0.0f; + + m_tryBeginTime = now; + } + else if (clickEvent == ClickEvent::Up) + { + const auto clickOutcome = [detectionState = m_detectionState] { + if (detectionState == DetectionState::WaitingForMove) + { + return ClickOutcome::Click; + } + if (detectionState == DetectionState::Moved) + { + return ClickOutcome::Release; + } + return ClickOutcome::Nil; + }(); + + m_detectionState = DetectionState::Nil; + return clickOutcome; + } + + if (m_detectionState == DetectionState::WaitingForMove) + { + // only allow the action to begin if the mouse has been moved a small amount + m_moveAccumulator += ScreenVectorLength(cursorDelta); + if (m_moveAccumulator > m_deadZone) + { + m_detectionState = DetectionState::Moved; + return ClickOutcome::Move; + } + } + + return ClickOutcome::Nil; + } +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.h b/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.h new file mode 100644 index 0000000000..997ccd07d9 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.h @@ -0,0 +1,75 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#include + +#include + +namespace AzFramework +{ + struct ScreenVector; + + //! Utility class to help detect different types of mouse click (mouse down and up with + //! no movement), mouse move (down and initial move after some threshold) and mouse release + //! (mouse down with movement and then mouse up). + class ClickDetector + { + //! Alias for recording time of mouse down events + using Time = std::chrono::time_point; + + public: + //! Internal representation of click event (map from external event for this when + //! calling DetectClick). + enum class ClickEvent + { + Nil, + Down, + Up + }; + + //! The type of mouse click. + enum class ClickOutcome + { + Nil, //!< Not recognized. + Move, //!< Initial move after mouse down. + Click, //!< Mouse down and up with no intermediate movement. + Release //!< Mouse down with movement and then mouse up. + }; + + //! Called from any type of 'handle event' function. + ClickOutcome DetectClick(ClickEvent clickEvent, const ScreenVector& cursorDelta); + + void SetDoubleClickInterval(float doubleClickInterval); + + private: + //! Internal state of ClickDetector based on incoming events. + enum class DetectionState + { + Nil, //!< Initial state + WaitingForMove, //! Mouse down has happened but mouse hasn't yet moved. + Moved //! Mouse has moved, no longer will be counted as a click. + }; + + float m_moveAccumulator = 0.0f; //!< How far the mouse has moved after mouse down. + float m_deadZone = 2.0f; //!< How far to move before a click is cancelled (when Move will fire). + float m_doubleClickInterval = 0.4f; //!< Default double click interval, can be overridden. + DetectionState m_detectionState; //!< Internal state of ClickDetector. + AZStd::optional
    > -{ -}; - -template -struct FixedDynArray - : LegacyDynArray< T, I, NArray::FastDynStorage > -{ - typedef NArray::ArrayStorage::Store S; - - void set(void* elems, I mem_size) - { - this->m_aElems = (T*)elems; - this->m_nCapacity = mem_size / sizeof(T); - this->m_nCount = 0; - } - void set(Array array) - { - this->m_aElems = array.begin(); - this->m_nCapacity = array.size(); - this->m_nCount = 0; - } -}; - template struct StaticDynArray : LegacyDynArray< T, I, NArray::StaticDynStorage > diff --git a/Code/CryEngine/CryCommon/CryCustomTypes.h b/Code/CryEngine/CryCommon/CryCustomTypes.h index e8f83145eb..25578ce9cc 100644 --- a/Code/CryEngine/CryCommon/CryCustomTypes.h +++ b/Code/CryEngine/CryCommon/CryCustomTypes.h @@ -1207,23 +1207,4 @@ protected: uint nPrefixLength; }; - -// Define an irregular enum with TypeInfo - -#define DEFINE_ENUM_VALS(EType, TInt, ...) \ - struct EType \ - { \ - enum E { __VA_ARGS__ }; \ - DEFINE_ENUM_VALUE(EType, E, TInt) \ - ILINE static uint Count() { return TypeInfo().Count(); } \ - static const CEnumInfo& TypeInfo() { \ - static char enum_str[] = #__VA_ARGS__; \ - static LegacyDynArray Elems; \ - CEnumDef::SInit::Init(Elems); \ - CEnumDef::SInit __VA_ARGS__; \ - static CEnumInfo info( #EType, Elems, enum_str); \ - return info; \ - } \ - }; - #endif // CRYINCLUDE_CRYCOMMON_CRYCUSTOMTYPES_H diff --git a/Code/CryEngine/CryCommon/CryFixedArray.h b/Code/CryEngine/CryCommon/CryFixedArray.h deleted file mode 100644 index 58bdd2b14f..0000000000 --- a/Code/CryEngine/CryCommon/CryFixedArray.h +++ /dev/null @@ -1,309 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -/* -CryFixedArray.h - - no longer support being created on the stack (since the alignment code was changed to support adding CryFixedArrays into stl::vectors) - - performs construction or destruction only on elements as they become live/dead or are moved around during the RemoveAt() reshuffle - - just a range checked equivelant of a standard array - - for now only allows push_back() population of array - - if using as a class member variable ensure to put the CryFixedArrays after all other member variables at the bottom of your class - to ensure all members stay on the same cacheline -*/ - -#ifndef CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H -#define CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H -#pragma once - -#define DEBUG_CRYFIXED_ARRAY _DEBUG - -template< - unsigned int align > -struct CryFixedArrayDatum -{ -}; - -template<> -struct CryFixedArrayDatum< 4 > -{ - typedef uint32 TDatum; -}; - -template<> -struct CryFixedArrayDatum< 8 > -{ - typedef uint64 TDatum; -}; - -template -class CryFixedArray -{ -protected: - enum - { - ALIGN = MAX(alignof(T), sizeof(unsigned int)) - }; // ALIGN at least sizeof(unsigned int) - - typedef typename CryFixedArrayDatum< ALIGN >::TDatum TDatum; - - uint32 m_curSize[ sizeof (TDatum) / sizeof (uint32) ]; // Padded for alignment - - TDatum m_data[(N * sizeof(T) + (sizeof(TDatum) - 1)) / sizeof(TDatum)]; // simple debugging - in VS: just add to a watch as "(T*)m_data, " to see the array. ie. "(int*)m_data, 5" - the size of the array has to be a literal int - -public: - typedef T* iterator; - typedef const T* const_iterator; - - CryFixedArray() - { -#if DEBUG_CRYFIXED_ARRAY - if (((uintptr_t)m_data & (ALIGN - 1)) != 0) - { - CryLogAlways("CryFixedArray() error - data is not aligned. This may happen if you are creating a CryFixedArray on the stack, which isn't supported."); - } -#endif - CRY_ASSERT_MESSAGE(((uintptr_t)m_data & (ALIGN - 1)) == 0, "CryFixedArray() error - data is not aligned. This may happen if you are creating a CryFixedArray on the stack, which isn't supported."); - m_curSize[0] = 0; - } - - CryFixedArray(const CryFixedArray& other) - { - // doesn't require clear() this is newly constructed - m_curSize[0] = other.m_curSize[0]; - - int size = m_curSize[0]; - for (int i = 0; i < size; i++) - { - T& ele = operator[](i); - const T& otherEle = other.operator[](i); - new (&ele)T(otherEle); // placement new - } - } - - CryFixedArray& operator=(const CryFixedArray& other) - { - if (this != &other) - { - clear(); // necessary to avoid potentially leaking within existing elements - - m_curSize[0] = other.m_curSize[0]; - - int size = m_curSize[0]; - for (int i = 0; i < size; i++) - { - T& ele = operator[](i); - const T& otherEle = other.operator[](i); - //ele = otherEle; // assignment instead of placement new to keep type of operation consistent - this cannot be done until this is rewritten to assign over existing elements and deconstruct any left overs, and placement new any new elements - new (&ele)T(otherEle); // placement new - } - } - - return *this; - } - - virtual ~CryFixedArray() - { - clear(); - } - - ILINE T& at(unsigned int i) - { -#if DEBUG_CRYFIXED_ARRAY - if (i < size()) - { - return alias_cast(m_data)[i]; - } - else - { - // Log is required now as its possible to turn off assert output logging, yet you really want to know if this is happening!!!! - CryLogAlways("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d) - forcing a crash", i, m_curSize[0], N); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d)", i, m_curSize[0], N)); - abort(); // better option than dereferncing a nullptr? - } -#else - return alias_cast(m_data)[i]; -#endif - } - - ILINE const T& at(unsigned int i) const - { -#if DEBUG_CRYFIXED_ARRAY - if (i < size()) - { - return alias_cast(m_data)[i]; - } - else - { - // Log is required now as its possible to turn off assert output logging, yet you really want to know if this is happening!!!! - CryLogAlways("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d) - forcing a crash", i, m_curSize[0], N); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d)", i, m_curSize[0], N)); - abort(); // better option than dereferncing a nullptr? - } -#else - return alias_cast(m_data)[i]; -#endif - } - - ILINE const T& operator[](unsigned int i) const - { - return at(i); - } - - ILINE T& operator[](unsigned int i) - { - return at(i); - } - - ILINE void clear() - { - for (uint32 i = 0; i < m_curSize[0]; i++) - { - T& ele = operator[](i); - ele.~T(); - } - m_curSize[0] = 0; -#if DEBUG_CRYFIXED_ARRAY - memset(m_data, 0, N * sizeof(T)); -#endif - } - - ILINE iterator begin() - { - return alias_cast(m_data); - } - ILINE const_iterator begin() const - { - return alias_cast(m_data); - } - ILINE iterator end() - { - return &(alias_cast(m_data))[m_curSize[0]]; - } - ILINE const_iterator end() const - { - return &(alias_cast(m_data))[m_curSize[0]]; - } - - ILINE unsigned int max_size() const { return N; } - ILINE unsigned int size() const { return m_curSize[0]; } - ILINE bool empty() const { return size() == 0; } - ILINE unsigned int isfull() const { return (size() == max_size()); } - - // allows you to push back default constructed elements - ILINE void push_back () - { - unsigned int curSize = size(); - if (curSize < N) - { - T* newT = &(alias_cast(m_data))[curSize]; - new (newT) T(); - - m_curSize[0]++; - } - else - { - CryLogAlways("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N); - CRY_ASSERT_TRACE(0, ("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N)); - } - } - - ILINE void push_back (const T& ele) - { - unsigned int curSize = size(); - if (curSize < N) - { - T* newT = &(alias_cast(m_data))[curSize]; - new (newT) T(ele); // placement new copy constructor - setup vtable etc - - m_curSize[0]++; - } - else - { - CryLogAlways("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N); - CRY_ASSERT_TRACE(0, ("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N)); - } - } - - ILINE void pop_back() - { - if (size() > 0) - { - back().~T(); // destruct back - m_curSize[0]--; - } - else - { - CryLogAlways("CryFixedArray::pop_back() failed as array is empty"); - CRY_ASSERT_MESSAGE(0, "CryFixedArray::pop_back() failed as array is empty"); - } - } - -protected: - ILINE const T& backEx() const - { -#if DEBUG_CRYFIXED_ARRAY - if (m_curSize[0] > 0) - { - return (alias_cast(m_data))[m_curSize[0] - 1]; - } - else - { - CryLogAlways("CryFixedArray::back() failed as array is empty"); - CRY_ASSERT_MESSAGE(0, "CryFixedArray::back() failed as array is empty"); - abort(); // better option than dereferncing a nullptr? - } -#else - return (alias_cast(m_data))[m_curSize[0] - 1]; -#endif - } - -public: - ILINE const T& back() const - { - return backEx(); - } - - ILINE T& back() - { - return (T&)(backEx()); - } - - // if returns true then an element has been swapped into the new element[i] and as such may need updating to reflect its new location in memory - ILINE bool removeAt(uint32 i) - { - bool swappedElement = false; - - if (i < m_curSize[0]) - { - if (i != m_curSize[0] - 1) - { - operator[](i).~T(); // destruct element being removed - - // copy back() into element i - T* newT = &(alias_cast(m_data))[i]; - new (newT) T(back()); // placement new copy constructor - setup vtable etc - - swappedElement = true; - } - pop_back(); // will destruct back() - } - else - { - CryLog("CryFixedArray::removeAt() failed as i=%d is out of range of curSize=%d", i, m_curSize[0]); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::removeAt() failed as i=%d is out of range of curSize=%d", i, m_curSize[0])); - } - return swappedElement; - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H diff --git a/Code/CryEngine/CryCommon/CryFixedString.h b/Code/CryEngine/CryCommon/CryFixedString.h index 9c522ad078..cabcc7d06f 100644 --- a/Code/CryEngine/CryCommon/CryFixedString.h +++ b/Code/CryEngine/CryCommon/CryFixedString.h @@ -2019,21 +2019,6 @@ inline CryStackStringT CryStackStringT::Tokenize(const_str charSet, return CryStackStringT(); } -////////////////////////////////////////////////////////////////////////// -// Specialization providing efficient move semantics for array classes. -template -bool raw_movable(const CryStackStringT& str) -{ - return false; -} - -template -void move_init(CryStackStringT& dest, CryStackStringT& source) -{ - dest.move(source); -} - - #if defined(_RELEASE) #define ASSERT_LEN (void)(0) #define ASSERT_WLEN (void)(0) diff --git a/Code/CryEngine/CryCommon/CryMemoryAllocator.h b/Code/CryEngine/CryCommon/CryMemoryAllocator.h deleted file mode 100644 index b9003fc6fa..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryAllocator.h +++ /dev/null @@ -1,274 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -/* - * Part of this code coming from STLPort alloc - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Copyright (c) 1997 - * Moscow Center for SPARC Technology - * - * Copyright (c) 1999 - * Boris Fomitchev - * - * - */ - -#ifndef CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H -#pragma once - -#include - -#define CRY_STL_ALLOC - -#if defined(LINUX64) || defined(APPLE) -#include -#endif - -#include // memset - -// DON't USE _MAX_BYTES as identifier for Max Bytes, STLPORT defines the same enum -// this leads to situation where the wrong enum is choosen in different compilation units -// which in case leads to errors(The stlport one is defined as 128) -#if defined (__OS400__) || defined (_WIN64) || defined(MAC) || defined(LINUX64) -enum {_ALIGNMENT = 16, _ALIGN_SHIFT = 4, __MAX_BYTES = 512, NFREELISTS=32, ADDRESSSPACE = 2 * 1024 * 1024, ADDRESS_SHIFT = 40}; -#else -enum {_ALIGNMENT = 8, _ALIGN_SHIFT = 3, __MAX_BYTES = 512, NFREELISTS = 64, ADDRESSSPACE = 2 * 1024 * 1024, ADDRESS_SHIFT = 20}; -#endif /* __OS400__ */ - -#define CRY_MEMORY_ALLOCATOR - -#define S_FREELIST_INDEX(__bytes) ((__bytes - size_t(1)) >> (int)_ALIGN_SHIFT) - -class _Node_alloc_obj { -public: - _Node_alloc_obj * _M_next; -}; - -#if defined (_WIN64) || defined(APPLE) || defined(LINUX64) -#define MASK_COUNT 0x000000FFFFFFFFFF -#define MASK_VALUE 0xFFFFFF -#define MASK_NEXT 0xFFFFFFFFFF000000 -#define MASK_SHIFT 24 -#else -#define MASK_COUNT 0x000FFFFF -#define MASK_VALUE 0xFFF -#define MASK_NEXT 0xFFFFF000 -#define MASK_SHIFT 12 -#endif - -#define NUM_OBJ 64 - -struct _Obj_Address { - // short int * _M_next; - // short int - size_t GetNext(size_t pBase) { - return pBase +(size_t)(_M_value >> MASK_SHIFT); - } - - //size_t GetNext() { - // return (size_t)(_M_value >> 20); - //} - - size_t GetCount() { - return _M_value & MASK_VALUE; - } - - void SetNext(/*void **/size_t pNext) { - _M_value &= MASK_COUNT; - _M_value |= (size_t)pNext << MASK_SHIFT; - } - - void SetCount(size_t count) { - _M_value &= MASK_NEXT; - _M_value |= count & MASK_VALUE; - } -private: - size_t _M_value; - // short int * _M_end; -}; - -//struct _Node_Allocations_Tree { -// enum { eListSize = _Size / (sizeof(void *) * _Num_obj); }; -// _Obj_Address * _M_allocations_list[eListSize]; -// int _M_Count; -// _Node_Allocations_Tree * _M_next; -//}; - -template -struct _Node_Allocations_Tree { - //Pointer to the end of the memory block - char *_M_end; - - enum { eListSize = _Size / (sizeof(void *) * NUM_OBJ) }; - // List of allocations - _Obj_Address _M_allocations_list[eListSize]; - int _M_allocations_count; - //Pointer to the next memory block - _Node_Allocations_Tree *_M_Block_next; -}; - - -struct _Node_alloc_Mem_block_Huge { - //Pointer to the end of the memory block - char *_M_end; - // number - int _M_count; - _Node_alloc_Mem_block_Huge *_M_next; -}; - -template -struct _Node_alloc_Mem_block { - //Pointer to the end of the memory block - char *_M_end; - //Pointer to the next memory block - _Node_alloc_Mem_block_Huge *_M_huge_block; - _Node_alloc_Mem_block *_M_next; -}; - - -// Allocators! -enum EAllocFreeType -{ - eCryDefaultMalloc, - eCryMallocCryFreeCRTCleanup, -}; - -template -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryModuleMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - CryModuleFree(ptr); - return 0; - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } -}; - -// partial -template <> -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - size_t n = CryCrtSize(ptr); - CryCrtFree(ptr); - return n; - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } - -}; - -// partial -template <> -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - return CryCrtFree(ptr); - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } - -}; - -#include "MultiThread.h" - -struct InternalCriticalSectionDummy { - char padding[128]; -} ; - -inline void CryInternalCreateCriticalSection(void * pCS) -{ - CryCreateCriticalSectionInplace(pCS); -} - -// A class that forward node allocator calls directly to CRT -struct cry_crt_node_allocator -{ - static const size_t MaxSize = ~0; - - static void *alloc(size_t __n) - { - return CryCrtMalloc(__n); - } - static size_t dealloc( void *p ) - { - return CryCrtFree(p); - } - static void *allocate(size_t __n) - { - return alloc(__n); - } - static void *allocate(size_t __n, [[maybe_unused]] size_t nAlignment) - { - return alloc(__n); - } - static size_t deallocate(void *__p) - { - return dealloc(__p); - } - void cleanup() {} -}; - - -//#endif // WIN32|DEBUG - -#endif // CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/CryMemoryManager.h b/Code/CryEngine/CryCommon/CryMemoryManager.h deleted file mode 100644 index b3f8ba7c8e..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryManager.h +++ /dev/null @@ -1,295 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Defines functions for CryEngine custom memory manager. - -#pragma once - -// Section dictionary -#if defined(AZ_RESTRICTED_PLATFORM) -#define CRYMEMORYMANAGER_H_SECTION_TRAITS 1 -#define CRYMEMORYMANAGER_H_SECTION_ALLOCPOLICY 2 -#endif - -#include -// Traits -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CRYMEMORYMANAGER_H_SECTION_TRAITS - #include AZ_RESTRICTED_FILE(CryMemoryManager_h) -#else -#if !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_MALLOC_H 1 -#endif -#if defined(LINUX) || defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_NEW_NOT_NEW_H 1 -#endif -#if !defined(LINUX) && !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_CRTDBG_H 1 -#endif -#if !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_USE_CRTCHECKMEMORY 1 -#endif -#endif - -#include "platform.h" - -#include -#include - -#if defined(APPLE) || defined(ANDROID) - #include // memalign -#endif // defined(APPLE) - -#ifndef STLALLOCATOR_CLEANUP -#define STLALLOCATOR_CLEANUP -#endif - -#define _CRY_DEFAULT_MALLOC_ALIGNMENT 4 - -#if CRYMEMORYMANAGER_H_TRAIT_INCLUDE_MALLOC_H - #include -#endif - -#if defined(__cplusplus) -#if CRYMEMORYMANAGER_H_TRAIT_INCLUDE_NEW_NOT_NEW_H - #include -#else - #include -#endif -#endif - - #ifdef CRYSYSTEM_EXPORTS - #define CRYMEMORYMANAGER_API DLL_EXPORT - #else - #define CRYMEMORYMANAGER_API DLL_IMPORT - #endif - -#ifdef __cplusplus - -#if defined(_DEBUG) && CRYMEMORYMANAGER_H_TRAIT_INCLUDE_CRTDBG_H - #include -#endif //_DEBUG - -#include "LegacyAllocator.h" - -namespace CryMemory -{ - // checks if the heap is valid in debug; in release, this function shouldn't be called - // returns non-0 if it's valid and 0 if not valid - ILINE int IsHeapValid() - { - #if (defined(_DEBUG) && !defined(RELEASE_RUNTIME) && CRYMEMORYMANAGER_H_TRAIT_USE_CRTCHECKMEMORY) || (defined(DEBUG_MEMORY_MANAGER)) - return _CrtCheckMemory(); - #else - return true; - #endif - } - - inline void* AllocPages(size_t size) - { - const size_t alignment = AZ_PAGE_SIZE; - void* ret = AZ::AllocatorInstance::Get().Allocate(size, alignment, 0, "AllocPages", __FILE__, __LINE__); - return ret; - } - - inline void FreePages(void* p, size_t size) - { - const size_t alignment = AZ_PAGE_SIZE; - AZ::AllocatorInstance::Get().DeAllocate(p, size, alignment); - } -} - -////////////////////////////////////////////////////////////////////////// - -#endif //__cplusplus - -struct ICustomMemoryHeap; -class IGeneralMemoryHeap; -class IPageMappingHeap; -class IMemoryAddressRange; - -// Description: -// Interfaces that allow access to the CryEngine memory manager. -struct IMemoryManager -{ - typedef unsigned char HeapHandle; - enum - { - BAD_HEAP_HANDLE = 0xFF - }; - - struct SProcessMemInfo - { - uint64 PageFaultCount; - uint64 PeakWorkingSetSize; - uint64 WorkingSetSize; - uint64 QuotaPeakPagedPoolUsage; - uint64 QuotaPagedPoolUsage; - uint64 QuotaPeakNonPagedPoolUsage; - uint64 QuotaNonPagedPoolUsage; - uint64 PagefileUsage; - uint64 PeakPagefileUsage; - - uint64 TotalPhysicalMemory; - int64 FreePhysicalMemory; - - uint64 TotalVideoMemory; - int64 FreeVideoMemory; - }; - - enum EAllocPolicy - { - eapDefaultAllocator, - eapPageMapped, - eapCustomAlignment, -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CRYMEMORYMANAGER_H_SECTION_ALLOCPOLICY - #include AZ_RESTRICTED_FILE(CryMemoryManager_h) -#endif - }; - - virtual ~IMemoryManager(){} - - virtual bool GetProcessMemInfo(SProcessMemInfo& minfo) = 0; - - ////////////////////////////////////////////////////////////////////////// - // Heap Tracing API - virtual HeapHandle TraceDefineHeap(const char* heapName, size_t size, const void* pBase) = 0; - virtual void TraceHeapAlloc(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint = 0) = 0; - virtual void TraceHeapFree(HeapHandle heap, void* mem, size_t blockSize) = 0; - virtual void TraceHeapSetColor(uint32 color) = 0; - virtual uint32 TraceHeapGetColor() = 0; - virtual void TraceHeapSetLabel(const char* sLabel) = 0; - ////////////////////////////////////////////////////////////////////////// - - // Create an instance of ICustomMemoryHeap - virtual ICustomMemoryHeap* const CreateCustomMemoryHeapInstance(EAllocPolicy const eAllocPolicy) = 0; - virtual IGeneralMemoryHeap* CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage) = 0; - virtual IGeneralMemoryHeap* CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage) = 0; - - virtual IMemoryAddressRange* ReserveAddressRange(size_t capacity, const char* sName) = 0; - virtual IPageMappingHeap* CreatePageMappingHeap(size_t addressSpace, const char* sName) = 0; -}; - -// Global function implemented in CryMemoryManager_impl.h -IMemoryManager* CryGetIMemoryManager(); - -// Summary: -// Structure filled by call to CryModuleGetMemoryInfo(). -struct CryModuleMemoryInfo -{ - uint64 requested; - // Total Ammount of memory allocated. - uint64 allocated; - // Total Ammount of memory freed. - uint64 freed; - // Total number of memory allocations. - int num_allocations; - // Allocated in CryString. - uint64 CryString_allocated; - // Allocated in STL. - uint64 STL_allocated; - // Amount of memory wasted in pools in stl (not usefull allocations). - uint64 STL_wasted; -}; - -struct CryReplayInfo -{ - uint64 uncompressedLength; - uint64 writtenLength; - uint32 trackingSize; - const char* filename; -}; - -////////////////////////////////////////////////////////////////////////// -// Extern declarations of globals inside CrySystem. -////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -void* CryMalloc(size_t size, size_t& allocated, size_t alignment); -void* CryRealloc(void* memblock, size_t size, size_t& allocated, size_t& oldsize, size_t alignment); -size_t CryFree(void* p, size_t alignment); -size_t CryGetMemSize(void* p, size_t size); -int CryStats(char* buf); -void CryFlushAll(); -void CryCleanup(); -int CryGetUsedHeapSize(); -int CryGetWastedHeapSize(); -size_t CrySystemCrtGetUsedSpace(); -CRYMEMORYMANAGER_API void CryGetIMemoryManagerInterface(void** pIMemoryManager); - -#ifdef __cplusplus -} -#endif //__cplusplus - -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -// Cry Memory Manager accessible in all build modes. -////////////////////////////////////////////////////////////////////////// -#if !defined(USING_CRY_MEMORY_MANAGER) -#define USING_CRY_MEMORY_MANAGER -#endif - -#include "CryLegacyAllocator.h" - - -template -inline T* CryAlignedNew(Args&& ... args) -{ - void* pAlignedMemory = CryModuleMemalign(sizeof(T), std::alignment_of::value); - return new(pAlignedMemory) T(std::forward(args) ...); -} - -// This utility function should be used for allocating arrays of objects with specific alignment requirements on the heap. -// Note: The caller must remember the number of items in the array, since CryAlignedDeleteArray needs this information. -template -inline T* CryAlignedNewArray(size_t count) -{ - T* const pAlignedMemory = reinterpret_cast(CryModuleMemalign(sizeof(T) * count, std::alignment_of::value)); - T* pCurrentItem = pAlignedMemory; - for (size_t i = 0; i < count; ++i, ++pCurrentItem) - { - new(static_cast(pCurrentItem))T(); - } - return pAlignedMemory; -} - -// Utility function that frees an object previously allocated with CryAlignedNew. -template -inline void CryAlignedDelete(T* pObject) -{ - if (pObject) - { - pObject->~T(); - CryModuleMemalignFree(pObject); - } -} - -// Utility function that frees an array of objects previously allocated with CryAlignedNewArray. -// The same count used to allocate the array must be passed to this function. -template -inline void CryAlignedDeleteArray(T* pObject, size_t count) -{ - if (pObject) - { - for (size_t i = 0; i < count; ++i) - { - (pObject + i)->~T(); - } - CryModuleMemalignFree(pObject); - } -} diff --git a/Code/CryEngine/CryCommon/CryMemoryManager_impl.h b/Code/CryEngine/CryCommon/CryMemoryManager_impl.h deleted file mode 100644 index fdb4f5665e..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryManager_impl.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Provides implementation for CryMemoryManager globally defined functions. -// This file included only by platform_impl.cpp, do not include it directly in code! - - -#pragma once - -#ifdef AZ_MONOLITHIC_BUILD - #include // <> required for Interfuscator -#endif // AZ_MONOLITHIC_BUILD - -#include "CryLibrary.h" - -#include - -#define DLL_ENTRY_GETMEMMANAGER "CryGetIMemoryManagerInterface" - -// Resolve IMemoryManager by looking in this DLL, then loading and rummaging through -// CrySystem. Cache the result per DLL, because this is not quick. -IMemoryManager* CryGetIMemoryManager() -{ - static AZ::EnvironmentVariable memMan = nullptr; - if (!memMan) - { - memMan = AZ::Environment::FindVariable("CryIMemoryManagerInterface"); - AZ_Assert(memMan, "Unable to find CryIMemoryManagerInterface via AZ::Environment"); - } - return *memMan; -} diff --git a/Code/CryEngine/CryCommon/CryName.h b/Code/CryEngine/CryCommon/CryName.h index 699525f958..0fb34c9532 100644 --- a/Code/CryEngine/CryCommon/CryName.h +++ b/Code/CryEngine/CryCommon/CryName.h @@ -19,7 +19,6 @@ #include #include #include -#include #include class CNameTable; diff --git a/Code/CryEngine/CryCommon/CrySizer.h b/Code/CryEngine/CryCommon/CrySizer.h index fc45438209..62b1acf489 100644 --- a/Code/CryEngine/CryCommon/CrySizer.h +++ b/Code/CryEngine/CryCommon/CrySizer.h @@ -48,8 +48,6 @@ struct SPipTangents; #include // workaround for Amd64 compiler #endif -#include // <> required for Interfuscator. IResourceCollector - namespace AZ { class Vector3; @@ -335,20 +333,6 @@ public: } } - template - void AddObject(const TArray& rVector) - { - if (!this->AddObject(rVector.begin(), rVector.capacity() * sizeof(T))) - { - return; - } - - for (int i = 0, end = rVector.size(); i < end; ++i) - { - this->AddObject(rVector[i]); - } - } - template void AddObject(const PodArray& rVector) { @@ -427,11 +411,6 @@ public: return AddObject (&rObject, sizeof(T)); } - // used to collect the assets needed for streaming and to gather statistics - // always returns a valid reference - virtual IResourceCollector* GetResourceCollector() = 0; - virtual void SetResourceCollector(IResourceCollector* pColl) = 0; - bool Add (const char* szText) { return AddObject(szText, strlen(szText) + 1); diff --git a/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h b/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h deleted file mode 100644 index aaf5a0889f..0000000000 --- a/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h +++ /dev/null @@ -1,634 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Specialized Container for Renderer data with the following proberties: -// - Created during the 3DEngine Update, comsumed in the renderer in the following frame -// - This Container is very restricted and likely not optimal for other situations - - -#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H -#define CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H -#pragma once - - -// This container is specialized for data which is generated in the 3DEngine and consumed by the renderer -// in the following frame due to multithreaded rendering. To be useable by Jobs as well as other Threads -// some very specific desing choices were taken: -// First of the underlying continous memory block is only resized during a call to 'CoalesceMemory' -// to prevent freeing a memory block which could be used by another thread. -// If new memory is requiered, a page of 4 KB is allocated and used as a temp storage till the next -// call to 'CoalesceMemory' which then copies all page memory into one continous block. -// Also all threading relevant functions are implemented LockLess to prevent lock contention and make -// this container useable from Jobs -// -// Right now, the main usage pattern of this container is by the RenderThread, who calls at the beginning -// of its frame 'CoalesceMemory', since then we can be sure that the 3DEngine has finished creating it's elements. -// -// Since the main purpose of this container is multi-threading adding of elements, a slight change was done to the -// push_back interface compared to std::vector: -// All implemented push_back variants can return a pointer into the storage (safe since no memory is freed during adding) -// and a index for this elements. This is done since calling operator[] could be expensive when called before 'CoalesceMemory' -// -// For ease of implementation (and a little bit of speed), this container only supports POD types (which can be copied with memcpy) -// also note that this container only supports push_back (and resize back to 0) and no pop back due cost (performance and code complexity) of supporting lock-free in parallel pop_back -#define TSRC_ALIGN _MS_ALIGN(128) - -template -class TSRC_ALIGN CThreadSafeRendererContainer -{ -public: - CThreadSafeRendererContainer(); - ~CThreadSafeRendererContainer(); - - //NOTE: be aware that these valus can potentially change if some objects are added in parallel - size_t size() const; - size_t empty() const; - size_t capacity() const; - - //NOTE: be aware that this operator can be more expensive if the memory was not coalesced before - T& operator[](size_t n); - const T& operator[](size_t n) const; - - T* push_back_new(); - T* push_back_new(size_t& nIndex); - - void push_back(const T&); - void push_back(const T&, size_t& nIndex); - - // NOTE: These functions are changing the size of the continous memory block and thus are *not* thread-safe - void clear(); - void resize(size_t n); - void reserve(size_t n); - - void CoalesceMemory(); - - void GetMemoryUsage(ICrySizer*) const; - - // disable copy/assignment - CThreadSafeRendererContainer(const CThreadSafeRendererContainer& rOther) = delete; - CThreadSafeRendererContainer& operator=(const CThreadSafeRendererContainer& rOther) = delete; - -private: - - ///////////////////////////////////// - // Struct to represent a memory chunk - // used in fallback allocations during 'Fill' phase - class CMemoryPage - { - public: - // size of a page to allocate, the CMemoryPage is just the header, - // the actual object data is stored in the 4KB chunk right - // after the header (while keeping the requiered alignment and so on) - enum - { - nMemoryPageSize = 4096 - }; - - CMemoryPage(); - - // allocation functions - static CMemoryPage* AllocateNewPage(); - bool TryAllocateElement(size_t& nIndex, T*& pObj); - - // access to the elements - T& GetElement(size_t n); - T* GetData() const; - - // information about the page (NOTE: not thread-safe in all combinations) - size_t Size() const; - size_t Capacity() const; - size_t GetDataSize() const; - - CMemoryPage* m_pNext; // Pointer to next entry in single-linked list of CMemoryPages - - private: - LONG m_nSize; // Number of elements currently in the page - LONG m_nCapacity; // Number of elements which could fit into the page - T* m_arrData; // Element memory, from the same memory chunk right after the CMemoryPage class - }; - - - ///////////////////////////////////// - // Private functions which do the lock-less updating - T* push_back_impl(size_t& nIndex); - bool try_append_to_continous_memory(size_t& nIndex, T*& pObj); - - T& GetMemoryPageElement(size_t n); - - - ///////////////////////////////////// - // Private Member Variables - T* m_arrData; // Storage for the continous memory part, during coalescing resized to hold all page memory - LONG m_nCapacity; // Avaible Memory in continous memory part, if exhausted during 'Fill' phase, pages as temp memory chunks are allocated - - CMemoryPage* m_pMemoryPages; // Single linked list of memory chunks, used for fallback allocations during 'Fill' phase (to prevent changing the continous memory block during 'Fill' - - LONG m_nSize; // Number of elements currently in the container, can be larger than m_nCapacity due the nonContinousPages - - bool m_bElementAccessSafe; // bool to indicate if we are currently doing a 'CoalasceMemory' step, during which some operations are now allowed -} _ALIGN(128); - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::CThreadSafeRendererContainer() - : m_arrData(NULL) - , m_nCapacity(0) - , m_pMemoryPages(NULL) - , m_nSize(0) - , m_bElementAccessSafe(true) -{ -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::~CThreadSafeRendererContainer() -{ - clear(); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::size() const -{ - return *const_cast(&m_nSize); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::empty() const -{ - return *const_cast(&m_nSize) == 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::capacity() const -{ - // capacity of continous memory block - LONG nCapacity = m_nCapacity; - - // add capacity of all memory pages - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - nCapacity += pCurrentMemoryPage->Capacity(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - - return nCapacity; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeRendererContainer::operator[](size_t n) -{ - assert(m_bElementAccessSafe); - T* pRet = NULL; - -#if !defined(NULL_RENDERER) - assert((LONG)n < m_nSize); -#endif - if ((LONG)n < m_nCapacity) - { - pRet = &m_arrData[n]; - } - else - { - pRet = &GetMemoryPageElement(n); - } - return *pRet; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline const T& CThreadSafeRendererContainer::operator[](size_t n) const -{ - return const_cast(const_cast*>(this)->operator[](n)); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_new() -{ - assert(m_bElementAccessSafe); - size_t nUnused = ~0; - return push_back_impl(nUnused); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_new(size_t& nIndex) -{ - assert(m_bElementAccessSafe); - return push_back_impl(nIndex); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::push_back(const T& rObj) -{ - assert(m_bElementAccessSafe); - size_t nUnused = ~0; - T* pObj = push_back_impl(nUnused); - *pObj = rObj; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::push_back(const T& rObj, size_t& nIndex) -{ - assert(m_bElementAccessSafe); - T* pObj = push_back_impl(nIndex); - *pObj = rObj; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::clear() -{ - assert(m_bElementAccessSafe); - // free continous part - CryModuleMemalignFree(m_arrData); - m_arrData = NULL; - - // free non-continous pages if we have some - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - CMemoryPage* pOldPage = pCurrentMemoryPage; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - CryModuleFree(pOldPage); - } - m_pMemoryPages = NULL; - - m_nSize = 0; - m_nCapacity = 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::resize(size_t n) -{ - assert(m_bElementAccessSafe); - CoalesceMemory(); - size_t nOldSize = m_nSize; - m_nSize = n; - - if ((LONG)n <= m_nCapacity) - { - return; - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, nOldSize * sizeof(T)); - memset(&m_arrData[m_nCapacity], 0, (n - m_nCapacity) * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - m_nCapacity = n; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::reserve(size_t n) -{ - assert(m_bElementAccessSafe); - CoalesceMemory(); - if ((LONG)n <= m_nCapacity) - { - return; - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, m_nSize * sizeof(T)); - memset(&m_arrData[m_nCapacity], 0, (n - m_nCapacity) * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - m_nCapacity = n; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline bool CThreadSafeRendererContainer::try_append_to_continous_memory(size_t& nIndex, T*& pObj) -{ - assert(m_bElementAccessSafe); - LONG nSize = ~0; - LONG nCapacity = ~0; - do - { - // read volatile the new size - nSize = *const_cast(&m_nSize); - nCapacity = *const_cast(&m_nCapacity); - - if (nSize >= nCapacity) - { - return false; - } - } while (CryInterlockedCompareExchange(alias_cast(&m_nSize), nSize + 1, nSize) != nSize); - nIndex = nSize; - pObj = &m_arrData[nSize]; - - return true; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_impl(size_t& nIndex) -{ - assert(m_bElementAccessSafe); - T* pObj = NULL; - - // non atomic check to see if there is space in the continous array - if (try_append_to_continous_memory(nIndex, pObj)) - { - return pObj; - } - - // exhausted continous memory, falling back to page allocation - for (;; ) - { - assert(m_bElementAccessSafe); - size_t nPageBaseIndex = 0; - - // traverse the page list till the first page with free memory - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - size_t nAvaibleElements = pCurrentMemoryPage->Capacity() - pCurrentMemoryPage->Size(); - if (nAvaibleElements) - { - break; - } - - // no memory in this page, go to the next one - nPageBaseIndex += pCurrentMemoryPage->Capacity(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - - // try to allocate a element on this page - if (pCurrentMemoryPage && pCurrentMemoryPage->TryAllocateElement(nIndex, pObj)) - { - // update global elements counter - CryInterlockedIncrement(alias_cast(&m_nSize)); - - // adjust in-page-index to global index - nIndex += nPageBaseIndex + m_nCapacity; - return pObj; - } - else - { - // all pages are empty, allocate and link a new one - CMemoryPage* pNewPage = CMemoryPage::AllocateNewPage(); - - void* volatile* ppLastMemoryPageAddress = NULL; - do - { - // find place to link in page - CMemoryPage* pLastMemoryPage = m_pMemoryPages; - ppLastMemoryPageAddress = alias_cast(&m_pMemoryPages); - - while (pLastMemoryPage) - { - ppLastMemoryPageAddress = alias_cast(&(pLastMemoryPage->m_pNext)); - pLastMemoryPage = pLastMemoryPage->m_pNext; - } - } while (CryInterlockedCompareExchangePointer(ppLastMemoryPageAddress, pNewPage, NULL) != NULL); - } - } -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeRendererContainer::GetMemoryPageElement(size_t n) -{ - assert(m_bElementAccessSafe); - size_t nFirstListIndex = m_nCapacity; - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - - size_t nPageCapacity = pCurrentMemoryPage->Capacity(); - while (n >= (nFirstListIndex + nPageCapacity)) - { - // this is threadsafe because we assume that if we want to get element 'n' - // the clientcode did already fill the container up to element 'n' - // thus up to 'n', m_pNonContinousList will have valid pages - // NOTE: This is not safe when trying to read a element behind the valid - // range (same as std::vector) - nFirstListIndex += nPageCapacity; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - - // update page capacity, since it can differe due alignment - nPageCapacity = pCurrentMemoryPage->Capacity(); - } - - return pCurrentMemoryPage->GetElement(n - nFirstListIndex); -} - -/////////////////////////////////////////////////////////////////////////////// -// When not not in the 'Fill' phase, it is safe to colace all page entries into one continous memory block -template -inline void CThreadSafeRendererContainer::CoalesceMemory() -{ - assert(m_bElementAccessSafe); - if (m_pMemoryPages == NULL) - { - return; // nothing to do - } - // mark state as not accessable - m_bElementAccessSafe = false; - -#if !defined(NDEBUG) - size_t nOldSize = m_nSize; -#endif - - // compute required memory - size_t nRequieredElements = 0; - { - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - nRequieredElements += pCurrentMemoryPage->Size(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign((m_nCapacity + nRequieredElements) * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, m_nCapacity * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - // copy page data into continous memory block - { - size_t nBeginToFillIndex = m_nCapacity; - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - // copy data - memcpy(&m_arrData[nBeginToFillIndex], pCurrentMemoryPage->GetData(), pCurrentMemoryPage->GetDataSize()); - nBeginToFillIndex += pCurrentMemoryPage->Size(); - - // free page - CMemoryPage* pOldPage = pCurrentMemoryPage; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - CryModuleFree(pOldPage); - } - - m_pMemoryPages = NULL; - } - - assert(nOldSize == m_nSize); - m_nCapacity += nRequieredElements; - - // the container can be used again - m_bElementAccessSafe = true; -} - -/////////////////////////////////////////////////////////////////////////////// -// Collect information about used memory -template -void CThreadSafeRendererContainer::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_arrData, m_nCapacity * sizeof(T)); - - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - pSizer->AddObject(pCurrentMemoryPage, CMemoryPage::nMemoryPageSize); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } -} - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::CMemoryPage::CMemoryPage() - : m_pNext(NULL) - , m_nSize(0) -{ - // compute offset for actual data - size_t nObjectAlignment = alignof(T); - UINT_PTR nMemoryBlockBegin = alias_cast(this); - UINT_PTR nMemoryBlockEnd = alias_cast(this) + nMemoryPageSize; - - nMemoryBlockBegin += sizeof(CMemoryPage); - nMemoryBlockBegin = (nMemoryBlockBegin + nObjectAlignment - 1) & ~(nObjectAlignment - 1); - - // compute number of avaible elements - assert(nMemoryBlockEnd > nMemoryBlockBegin); - m_nCapacity = (LONG)((nMemoryBlockEnd - nMemoryBlockBegin) / sizeof(T)); - - // store pointer to store data to - m_arrData = alias_cast(nMemoryBlockBegin); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline typename CThreadSafeRendererContainer::CMemoryPage * CThreadSafeRendererContainer::CMemoryPage::AllocateNewPage() -{ - void* pNewPageMemoryChunk = CryModuleMalloc(nMemoryPageSize); - assert(pNewPageMemoryChunk != NULL); - - memset(pNewPageMemoryChunk, 0, nMemoryPageSize); - CMemoryPage* pNewPage = new(pNewPageMemoryChunk) CMemoryPage(); - return pNewPage; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline bool CThreadSafeRendererContainer::CMemoryPage::TryAllocateElement(size_t & nIndex, T * &pObj) -{ - LONG nSize = ~0; - LONG nCapacity = ~0; - do - { - // read volatile the new size - nSize = *const_cast(&m_nSize); - nCapacity = *const_cast(&m_nCapacity); - // stop trying if this page is full - if (nSize >= nCapacity) - { - return false; - } - } while (CryInterlockedCompareExchange(alias_cast(&m_nSize), nSize + 1, nSize) != nSize); - - //Note: this is the index in the page and it is adjusted in the calling context - nIndex = nSize; - pObj = &m_arrData[nSize]; - - return true; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T&CThreadSafeRendererContainer::CMemoryPage::GetElement(size_t n) -{ - assert((LONG)n < m_nSize); - assert(m_nSize <= m_nCapacity); - return m_arrData[n]; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T * CThreadSafeRendererContainer::CMemoryPage::GetData() const -{ - return m_arrData; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::Size() const -{ - return m_nSize; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::GetDataSize() const -{ - return m_nSize * sizeof(T); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::Capacity() const -{ - return m_nCapacity; -} - -#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H diff --git a/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h b/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h deleted file mode 100644 index 418b363ca1..0000000000 --- a/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h +++ /dev/null @@ -1,602 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Specialized Container for Renderer data with the following properties: -// Created during the 3DEngine Update, consumed in the renderer in the following frame -// This Container is very restricted and likely not optimal for other situations - - -#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H -#define CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H -#pragma once - - -#include "platform.h" -#include - -#include -#include -#include - - -// -// !!! BE CAREFULL WHEN USING THIS CONTAINER !!! -// -// --- Properties: --- -// - Stores data local to worker thread to avoid thread-safety semantics -// - Allows for a single non-worker thread to be tracked which is stored in m_workers[0] -// Hence: As m_workers[0] is shared between all non-worker threads, ensure that only one additional non-worker thread may access this container e.g. MainThread -// - Coalesce memory to obtain a continues memory block -// - Coalesce memory to for faster element access to a continues memory block -// -// --- Restrictions:--- -// - The workers own the memory structure -// - The coalesced memory stores a copy of the workers used memory -// Hence: Be careful when altering data within the coalesced memory. -// If the templated element is a pointer type than altering the memory pointed to, is not be an issue -// If the templated element is of type class or struct than ensure that data changes are done on the worker local data and not on the coalesced memory. Use worker encoded indices to do so. -// - -template -class CThreadSafeWorkerContainer -{ -public: - struct SDefaultNoOpFunctor - { - ILINE void operator()(T* pData) const{} - }; - - struct SDefaultDestructorFunctor - { - ILINE void operator()(T* pData) const - { - pData->~T(); - } - }; - -public: - CThreadSafeWorkerContainer(); - ~CThreadSafeWorkerContainer(); - - void Init(); - void SetNonWorkerThreadID(threadID nThreadId) { m_foreignThreadId = nThreadId; } - - // Safe access of elements for calling thread via operator[] - uint32 ConvertToEncodedWorkerId_threadlocal(uint32 nIndex) const; - - // Returns the number of threads that can use this container, including the one non-worker-thread. - uint32 GetNumWorkers() const; - - // Returns the Worker ID for the current thread. Ranges from 0 to GetNumWorkers()-1. - // Note, WorkerId is not the same thing as JobManager's WorkerThreadId. - uint32 GetWorkerId_threadlocal() const; - - //NOTE: be aware that these values can potentially change if some objects are added in parallel - size_t size() const; - size_t empty() const; - size_t capacity() const; - - size_t size_threadlocal() const; - size_t empty_threadlocal() const; - size_t capacity_threadlocal() const; - - //NOTE: be aware that this operator is more expensive if the memory was not coalesced before - T& operator[](size_t n); - const T& operator[](size_t n) const; - - T* push_back_new(); - T* push_back_new(size_t& nIndex); - - void push_back(const T& rObj); - void push_back(const T& rObj, size_t& nIndex); - - // NOTE: These functions are changing the size of the continous memory block and thus are *not* thread-safe - void clear(); - template< class OnElementDeleteFunctor> - void clear(const OnElementDeleteFunctor& rFunctor = CThreadSafeWorkerContainer::SDefaultNoOpFunctor()); - void erase(const T& rObj); - void resize(size_t n); - void reserve(size_t n); - - // *not* thread-safe functions - void PrefillContainer(T* pElement, size_t numElements); - void CoalesceMemory(); - - void GetMemoryUsage(ICrySizer* pSizer) const; - -private: - - void clear(AZStd::true_type); - void clear(AZStd::false_type); - - class SWorker - { - public: - AZ_CLASS_ALLOCATOR(SWorker, AZ::LegacyAllocator, 0); - - SWorker() - : m_dataSize(0) {} - - uint32 m_dataSize; - AZStd::vector m_data; - } _ALIGN(128); - - T* push_back_impl(size_t& nIndex); - void ReserverCoalescedMemory(size_t n); - - threadID m_foreignThreadId; // OS thread ID of the non-job-manager-worker-thread allowed to use this container, too. - - AZStd::vector m_workers; // Holds data for each thread that can use this container. A non-worker-thread (Main) has data stored at 0. Actual worker threads range from 1 to m_nNumWorkers-1 - uint32 m_nNumWorkers = 0; // The number of threads that can use this container, including one non-worker-thread. - - uint32 m_coalescedArrCapacity; - T* m_coalescedArr; - bool m_isCoalesced; -}; - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeWorkerContainer::CThreadSafeWorkerContainer() - : m_nNumWorkers(0) - , m_coalescedArrCapacity(0) - , m_coalescedArr(0) - , m_isCoalesced(false) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeWorkerContainer::~CThreadSafeWorkerContainer() -{ - clear(); - m_workers.clear(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::Init() -{ - m_nNumWorkers = AZ::JobContext::GetGlobalContext()->GetJobManager().GetNumWorkerThreads() + 1; - m_workers.resize(m_nNumWorkers); - - m_foreignThreadId = THREADID_NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::size() const -{ - uint32 totalSize = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - totalSize += m_workers[i].m_dataSize; - } - return totalSize; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::empty() const -{ - return size() == 0; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::capacity() const -{ - uint32 totalCapacity = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - totalCapacity += m_workers[i].m_data.capacity(); - } - return totalCapacity; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::size_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_dataSize; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::empty_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_data.empty(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::capacity_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_data.capacity(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeWorkerContainer::operator[](size_t n) -{ - const uint32 nHasWorkerEncodedIndex = (n & 0x80000000) >> 31; - - IF ((m_isCoalesced && !nHasWorkerEncodedIndex), 1) - { - AZ_Assert(m_coalescedArr, "null array"); - AZ_Assert(n < m_coalescedArrCapacity, "Index out of bounds"); - return m_coalescedArr[n]; - } - else - { - const uint32 nWorkerThreadId = (n & 0x7F00007F) >> 24; // Mask bit 24-30 (0 is starting bit) - const uint32 nOffset = (n & ~0xFF000000); // Mask out top 8 bits - - // Encoded offset into worker local array - if (nHasWorkerEncodedIndex) - { - return m_workers[nWorkerThreadId].m_data[nOffset]; - } - else // None-coalesced and none worker encoded offset - { - uint32 nTotalOffset = nOffset; - for (int i = 0; i < m_nNumWorkers; ++i) - { - SWorker& worker = m_workers[i]; - - if (nTotalOffset < worker.m_dataSize) - { - return worker.m_data[nTotalOffset]; - } - else - { - nTotalOffset -= worker.m_dataSize; - } - } - - // Out of bound access detected! - CRY_ASSERT_MESSAGE(false, "CThreadSafeWorkerContainer::operator[] - Out of bounds access"); - __debugbreak(); - AZ_Assert(m_coalescedArr, "null array"); - AZ_Assert(m_coalescedArrCapacity > 0, "Index out of bounds"); - return m_coalescedArr[0]; - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline const T& CThreadSafeWorkerContainer::operator[](size_t n) const -{ - return const_cast(const_cast*>(this)->operator[](n)); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_new() -{ - size_t unused = ~0; - return push_back_impl(unused); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_new(size_t& nIndex) -{ - return push_back_impl(nIndex); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::push_back(const T& rObj) -{ - size_t nUnused = ~0; - T* pObj = push_back_impl(nUnused); - *pObj = rObj; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::push_back(const T& rObj, size_t& nIndex) -{ - T* pObj = push_back_impl(nIndex); - *pObj = rObj; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::clear() -{ - clear(typename std::is_destructible::type()); -} - -template -void CThreadSafeWorkerContainer::clear(AZStd::true_type) -{ - clear(SDefaultDestructorFunctor()); -} - -template -void CThreadSafeWorkerContainer::clear(AZStd::false_type) -{ - clear(SDefaultNoOpFunctor()); -} -/////////////////////////////////////////////////////////////////////////////// -template -template -inline void CThreadSafeWorkerContainer::clear(const OnElementDeleteFunctor& rFunctor) -{ - // Reset worker data - for (int i = 0; i < m_nNumWorkers; ++i) - { - // Delete elements - uint32 nSize = m_workers[i].m_data.size(); - for (int j = 0; j < nSize; ++j) - { - // Call on element delete functor - // Note: Default functor will do nothing with the element - rFunctor(&m_workers[i].m_data[j]); - } - - m_workers[i].m_data.clear(); - m_workers[i].m_dataSize = 0; - } - - // Reset container data - if (m_coalescedArr) - { - CryModuleMemalignFree(m_coalescedArr); - } - - m_coalescedArr = 0; - m_coalescedArrCapacity = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::erase(const T& rObj) -{ - for (int i = 0; i < m_nNumWorkers; ++i) - { - typename std::vector::iterator iter = m_workers[i].m_data.begin(); - typename std::vector::iterator iterEnd = m_workers[i].m_data.end(); - - for (; iter != iterEnd; ++iter) - { - if (rObj == *iter) - { - m_workers[i].m_data.erase(iter); - --m_workers[i].m_dataSize; - m_isCoalesced = false; - return; - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::resize(size_t n) -{ - CoalesceMemory(); - - uint32 nSizePerWorker = n / m_nNumWorkers; - uint32 nExcessSize = n % m_nNumWorkers; - - // Resize workers evenly - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nWorkerSize = nSizePerWorker + nExcessSize; - - if (nWorkerSize > m_workers[i].m_data.size()) - { - m_workers[i].m_data.resize(nWorkerSize); - } - - m_workers[i].m_dataSize = nWorkerSize; - nExcessSize = 0; // First worker creates excess items - } - - ReserverCoalescedMemory(n); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::reserve(size_t n) -{ - CoalesceMemory(); - - uint32 nSizePerWorker = n / m_nNumWorkers; - uint32 nExcessSize = n % m_nNumWorkers; - - // Resize workers evenly - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nWorkerSize = nSizePerWorker + nExcessSize; - - if (nWorkerSize > m_workers[i].m_data.size()) - { - m_workers[i].m_data.resize(nWorkerSize); - } - - nExcessSize = 0; // First worker creates excess items - } - - ReserverCoalescedMemory(n); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::PrefillContainer(T* pElement, size_t numElements) -{ - reserve(numElements); - - uint32 nOffset = 0; - uint32 nNumItemPerWorker = numElements / m_nNumWorkers; - uint32 nNumExcessItems = numElements % m_nNumWorkers; - - // Store items evenly in workers - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nNumItems = nNumItemPerWorker + nNumExcessItems; - for (int j = 0; j < nNumItems; ++j) - { - m_workers[i].m_data[j] = pElement[nOffset + j]; - } - - m_workers[i].m_dataSize = nNumItems; - nOffset += nNumItems; - nNumExcessItems = 0; // First worker stores excess items - } - - m_isCoalesced = false; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::CoalesceMemory() -{ - if (m_isCoalesced) - { - return; - } - - // Ensure enough memory exists - uint32 minSizeNeeded = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - minSizeNeeded += m_workers[i].m_dataSize; - } - - IF (minSizeNeeded >= m_coalescedArrCapacity, 0) - { - ReserverCoalescedMemory(minSizeNeeded + (minSizeNeeded / 4)); - } - - // Copy data to coalesced array - uint32 nOffest = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - SWorker& rWorker = m_workers[i]; - if (rWorker.m_dataSize == 0) - { - continue; - } - AZ_Assert((nOffest + rWorker.m_dataSize) <= m_coalescedArrCapacity, "Index out of bounds"); - memcpy(m_coalescedArr + nOffest, &rWorker.m_data[0], sizeof(T) * rWorker.m_dataSize); - nOffest += rWorker.m_dataSize; - } - - m_isCoalesced = true; -} - -/////////////////////////////////////////////////////////////////////////////// -template -uint32 CThreadSafeWorkerContainer::ConvertToEncodedWorkerId_threadlocal(uint32 nIndex) const -{ - const uint32 workerId = GetWorkerId_threadlocal(); - assert(nIndex < m_workers[workerId].m_dataSize); - return (uint32)((1 << 31) | (workerId << 24) | nIndex); -} - -////////////////////////////////////////////////////////////////////////// -template -uint32 CThreadSafeWorkerContainer::GetNumWorkers() const -{ - return m_nNumWorkers; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_coalescedArr, m_coalescedArrCapacity * sizeof(T)); - - for (int i = 0; i < m_nNumWorkers; ++i) - { - pSizer->AddContainer(m_workers[i].m_data); - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::ReserverCoalescedMemory(size_t n) -{ - if (n <= m_coalescedArrCapacity) - { - return; - } - - T* arrOldData = m_coalescedArr; - m_coalescedArr = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_coalescedArr, arrOldData, m_coalescedArrCapacity * sizeof(T)); - if (arrOldData) - { - CryModuleMemalignFree(arrOldData); - } - m_coalescedArrCapacity = n; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_impl(size_t& nIndex) -{ - // Avoid writing to thread share resource and take hit of 'if statement to avoid false-sharing between threads - IF (m_isCoalesced, 0) - { - m_isCoalesced = false; - } - - // Get worker id - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - - SWorker& activeWorker = m_workers[nWorkerThreadId]; - - // Ensure enough space - if (activeWorker.m_dataSize >= activeWorker.m_data.size()) - { - activeWorker.m_data.resize(activeWorker.m_data.size() + (activeWorker.m_data.size() / 2) + 1); - } - - // Encode worker local offset into index and return - T* retItem = &activeWorker.m_data[activeWorker.m_dataSize]; - nIndex = (size_t)((1 << 31) | (nWorkerThreadId << 24) | activeWorker.m_dataSize); - ++activeWorker.m_dataSize; - return retItem; -} - -template -uint32 CThreadSafeWorkerContainer::GetWorkerId_threadlocal() const -{ - const uint32 workerThreadId = AZ::JobContext::GetGlobalContext()->GetJobManager().GetWorkerThreadId(); - - if (workerThreadId == AZ::JobManager::InvalidWorkerThreadId) - { - // Only one non-worker thread is allowed, so check to see if this is that thread. - - const threadID currentThreadId = CryGetCurrentThreadId(); - if (m_foreignThreadId != currentThreadId) - { - CryFatalError("Trying to access CThreadSafeWorkerContainer from an unspecified non-worker thread. The only non-worker threadId with access rights: %" PRI_THREADID ". Current threadId: %" PRI_THREADID, m_foreignThreadId, currentThreadId); - } - } - - // Non-worker has id of ~0 ... add +1 to shift to 0. Worker0 will use slot 1 etc. - static_assert(AZ::JobManager::InvalidWorkerThreadId == ~0u, "Assumptions about InvalidWorkerId no longer hold true"); - return workerThreadId + 1; -} - - -#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H diff --git a/Code/CryEngine/CryCommon/CustomMemoryHeap.h b/Code/CryEngine/CryCommon/CustomMemoryHeap.h deleted file mode 100644 index 2cb0c70713..0000000000 --- a/Code/CryEngine/CryCommon/CustomMemoryHeap.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CustomMemoryHeap_h__ -#define __CustomMemoryHeap_h__ -#pragma once - -#include "IMemory.h" - -class CCustomMemoryHeap; - -////////////////////////////////////////////////////////////////////////// -class CCustomMemoryHeapBlock - : public ICustomMemoryBlock -{ -public: - CCustomMemoryHeapBlock(CCustomMemoryHeap* pHeap); - virtual ~CCustomMemoryHeapBlock(); - - ////////////////////////////////////////////////////////////////////////// - // IMemoryBlock - ////////////////////////////////////////////////////////////////////////// - virtual void* GetData(); - virtual int GetSize() { return m_nSize; } - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // ICustomMemoryBlock - ////////////////////////////////////////////////////////////////////////// - virtual void CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize); - ////////////////////////////////////////////////////////////////////////// - -private: - friend class CCustomMemoryHeap; - CCustomMemoryHeap* m_pHeap; - string m_sUsage; - void* m_pData; - uint32 m_nGPUHandle; - size_t m_nSize; -}; - -////////////////////////////////////////////////////////////////////////// -class CCustomMemoryHeap - : public ICustomMemoryHeap -{ -public: - - explicit CCustomMemoryHeap(IMemoryManager::EAllocPolicy const eAllocPolicy); - ~CCustomMemoryHeap(); - - ////////////////////////////////////////////////////////////////////////// - // ICustomMemoryHeap - ////////////////////////////////////////////////////////////////////////// - virtual ICustomMemoryBlock* AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment = 16); - virtual void GetMemoryUsage(ICrySizer* pSizer); - virtual size_t GetAllocated(); - ////////////////////////////////////////////////////////////////////////// - - void DeallocateBlock(CCustomMemoryHeapBlock* pBlock); - -private: - - friend class CCustomMemoryHeapBlock; - int m_nAllocatedSize; - IMemoryManager::EAllocPolicy m_eAllocPolicy; - IMemoryManager::HeapHandle m_nTraceHeapHandle; -}; - -#endif // __CustomMemoryHeap_h__ diff --git a/Code/CryEngine/CryCommon/HeapAllocator.h b/Code/CryEngine/CryCommon/HeapAllocator.h index c0001ea497..4dfd9f66ec 100644 --- a/Code/CryEngine/CryCommon/HeapAllocator.h +++ b/Code/CryEngine/CryCommon/HeapAllocator.h @@ -420,7 +420,6 @@ namespace stl { nInterval++; nCount = 0; - assert(CryMemory::IsHeapValid()); } #endif } diff --git a/Code/CryEngine/CryCommon/IEntityRenderState.h b/Code/CryEngine/CryCommon/IEntityRenderState.h index 29b1bdc463..3e8f1dce4e 100644 --- a/Code/CryEngine/CryCommon/IEntityRenderState.h +++ b/Code/CryEngine/CryCommon/IEntityRenderState.h @@ -572,7 +572,6 @@ struct IVoxelObject : public IRenderNode { // - virtual struct IMemoryBlock* GetCompiledData(EEndian eEndian) = 0; virtual void SetCompiledData(void* pData, int nSize, uint8 ucChildId, EEndian eEndian) = 0; virtual void SetObjectName(const char* pName) = 0; virtual void SetMatrix(const Matrix34& mat) = 0; diff --git a/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h b/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h deleted file mode 100644 index 7a9c0c8ebf..0000000000 --- a/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H -#define CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H -#pragma once - -namespace AZ -{ - class IAllocator; -} - -class IGeneralMemoryHeap -{ -public: - // - virtual bool Cleanup() = 0; - - virtual int AddRef() = 0; - virtual int Release() = 0; - - virtual bool IsInAddressRange(void* ptr) const = 0; - - virtual void* Calloc(size_t nmemb, size_t size, const char* sUsage) = 0; - virtual void* Malloc(size_t sz, const char* sUsage) = 0; - - // Attempts to free the allocation. Returns the size of the allocation if successful, 0 if the heap doesn't own the address. - virtual size_t Free(void* ptr) = 0; - virtual void* Realloc(void* ptr, size_t sz, const char* sUsage) = 0; - virtual void* ReallocAlign(void* ptr, size_t size, size_t alignment, const char* sUsage) = 0; - virtual void* Memalign(size_t boundary, size_t size, const char* sUsage) = 0; - - virtual AZ::IAllocator* GetAllocator() const = 0; - - // Get the size of the allocation. Returns 0 if the ptr doesn't belong to the heap. - virtual size_t UsableSize(void* ptr) const = 0; - // -protected: - virtual ~IGeneralMemoryHeap() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H diff --git a/Code/CryEngine/CryCommon/IImageHandler.h b/Code/CryEngine/CryCommon/IImageHandler.h deleted file mode 100644 index 3f2e0c871b..0000000000 --- a/Code/CryEngine/CryCommon/IImageHandler.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H -#define CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H -#pragma once - -#include - -/** -Utility for loading and saving images. only works with RGB data(no alpha), and lossless compressed tiff files for now. -*/ -struct IImageHandler -{ - struct IImage - { - virtual ~IImage() {} - - virtual const std::vector& GetData() const = 0; - virtual int GetWidth() const = 0; - virtual int GetHeight() const = 0; - }; - - virtual ~IImageHandler() {} - - ///data must be RGB, 3 bytes per pixel. - virtual std::unique_ptr CreateImage(std::vector&& data, int width, int height) const = 0; - virtual std::unique_ptr LoadImage(const char* filename) const = 0; - virtual bool SaveImage(IImage* image, const char* filename) const = 0; - virtual std::unique_ptr CreateDiffImage(IImage* image1, IImage* image2) const = 0; - virtual float CalculatePSNR(IImage* diffIimage) const = 0; -}; -#endif // CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H diff --git a/Code/CryEngine/CryCommon/IMemory.h b/Code/CryEngine/CryCommon/IMemory.h deleted file mode 100644 index a3b1dc1c2c..0000000000 --- a/Code/CryEngine/CryCommon/IMemory.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IMEMORY_H -#define CRYINCLUDE_CRYCOMMON_IMEMORY_H -#pragma once - -#include -#include // <> required for Interfuscator -#include - -struct IMemoryBlock - : public CMultiThreadRefCount -{ - // - virtual void* GetData() = 0; - virtual int GetSize() = 0; - // -}; -TYPEDEF_AUTOPTR(IMemoryBlock); - -////////////////////////////////////////////////////////////////////////// -struct ICustomMemoryBlock - : public IMemoryBlock -{ - // Copy region from from source memory to the specified output buffer - virtual void CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize) = 0; -}; - -////////////////////////////////////////////////////////////////////////// -struct ICustomMemoryHeap - : public CMultiThreadRefCount -{ - // - virtual ICustomMemoryBlock* AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment = 16) = 0; - virtual void GetMemoryUsage(ICrySizer* pSizer) = 0; - virtual size_t GetAllocated() = 0; - // -}; - -class IMemoryAddressRange -{ -public: - // - virtual void Release() = 0; - - virtual char* GetBaseAddress() const = 0; - virtual size_t GetPageCount() const = 0; - virtual size_t GetPageSize() const = 0; - - virtual void* MapPage(size_t pageIdx) = 0; - virtual void UnmapPage(size_t pageIdx) = 0; - // -protected: - virtual ~IMemoryAddressRange() {} -}; - -class IPageMappingHeap -{ -public: - // - virtual void Release() = 0; - - virtual size_t GetGranularity() const = 0; - virtual bool IsInAddressRange(void* ptr) const = 0; - - virtual size_t FindLargestFreeBlockSize() const = 0; - - virtual void* Map(size_t sz) = 0; - virtual void Unmap(void* ptr, size_t sz) = 0; - // -protected: - virtual ~IPageMappingHeap() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IMEMORY_H diff --git a/Code/CryEngine/CryCommon/IRenderer.h b/Code/CryEngine/CryCommon/IRenderer.h index bb8f8fa572..be72e69864 100644 --- a/Code/CryEngine/CryCommon/IRenderer.h +++ b/Code/CryEngine/CryCommon/IRenderer.h @@ -1510,7 +1510,6 @@ struct IRenderer // Summary: // Loads lightmap for name. virtual int EF_LoadLightmap (const char* name) = 0; - virtual bool EF_RenderEnvironmentCubeHDR (int size, Vec3& Pos, TArray& vecData) = 0; // Summary: // Starts using of the shaders (return first index for allow recursions). @@ -1547,7 +1546,6 @@ struct IRenderer virtual int EF_AddDeferredLight(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0; virtual uint32 EF_GetDeferredLightsNum(eDeferredLightType eLightType = eDLT_DeferredLight) = 0; virtual void EF_ClearDeferredLightsList() = 0; - virtual TArray* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, eDeferredLightType eLightType = eDLT_DeferredLight) = 0; virtual uint8 EF_AddDeferredClipVolume(const IClipVolume* pClipVolume) = 0; virtual bool EF_SetDeferredClipVolumeBlendData(const IClipVolume* pClipVolume, const SClipVolumeBlendInfo& blendInfo) = 0; diff --git a/Code/CryEngine/CryCommon/IResourceCollector.h b/Code/CryEngine/CryCommon/IResourceCollector.h deleted file mode 100644 index a3c88f507b..0000000000 --- a/Code/CryEngine/CryCommon/IResourceCollector.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H -#define CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H -#pragma once - - -// used to collect the assets needed for streaming and to gather statistics -struct IResourceCollector -{ - // - // Arguments: - // dwMemSize 0xffffffff if size is unknown - // Returns: - // true=new resource was added, false=resource was already registered - virtual bool AddResource(const char* szFileName, const uint32 dwMemSize) = 0; - - // Arguments: - // szFileName - needs to be registered before with AddResource() - // pInstance - must not be 0 - virtual void AddInstance(const char* szFileName, void* pInstance) = 0; - // - // Arguments: - // szFileName - needs to be registered before with AddResource() - virtual void OpenDependencies(const char* szFileName) = 0; - // - virtual void CloseDependencies() = 0; - - // Resets the internal data structure for the resource collector. - virtual void Reset() = 0; - // -protected: - virtual ~IResourceCollector() {} -}; - - -class NullResCollector - : public IResourceCollector -{ -public: - virtual bool AddResource([[maybe_unused]] const char* szFileName, [[maybe_unused]] const uint32 dwMemSize) { return true; } - virtual void AddInstance([[maybe_unused]] const char* szFileName, [[maybe_unused]] void* pInstance) {} - virtual void OpenDependencies([[maybe_unused]] const char* szFileName) {} - virtual void CloseDependencies() {} - virtual void Reset() {} - - virtual ~NullResCollector() {} -}; - - -#endif // CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H - - diff --git a/Code/CryEngine/CryCommon/IResourceManager.h b/Code/CryEngine/CryCommon/IResourceManager.h deleted file mode 100644 index 482cb30a5e..0000000000 --- a/Code/CryEngine/CryCommon/IResourceManager.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Resource Manager - - -#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H -#define CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H -#pragma once - -namespace AZ::IO -{ - struct IResourceList; -} - -struct SLayerPakStats -{ - struct SEntry - { - string name; - size_t nSize; - string status; - bool bStreaming; - }; - typedef std::vector TEntries; - TEntries m_entries; - - size_t m_MaxSize; - size_t m_UsedSize; -}; - -////////////////////////////////////////////////////////////////////////// -// IResource manager interface -////////////////////////////////////////////////////////////////////////// -struct IResourceManager -{ - // - virtual ~IResourceManager(){} - // Called by level system to set the level folder - virtual void PrepareLevel(const char* sLevelFolder, const char* sLevelName) = 0; - // Called by level system after the level has been unloaded. - virtual void UnloadLevel() = 0; - // Call to get current level resource list. - virtual AZ::IO::IResourceList* GetLevelResourceList() = 0; - // Load pak file from level cache to memory. - // sBindRoot is a path in virtual file system, where new pak will be mapper to (ex. LevelCache/mtl) - virtual bool LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading = true) = 0; - // Unloads level cache pak file from memory. - virtual void UnloadLevelCachePak(const char* sPakName) = 0; - - //Loads the pak file for mode switching into memory e.g. Single player mode to Multiplayer mode - virtual bool LoadModeSwitchPak(const char* sPakName, const bool multiplayer) = 0; - //Unloads the mode switching pak file - virtual void UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer) = 0; - - // Load general pak file to memory. - virtual bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) = 0; - // Unload all aync paks - virtual void UnloadAllAsyncPaks() = 0; - // Load pak file from active layer to memory. - virtual bool LoadLayerPak(const char* sLayerName) = 0; - // Unloads layer pak file from memory if no more references. - virtual void UnloadLayerPak(const char* sLayerName) = 0; - // Retrieve stats on the layer pak - virtual void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const = 0; - - // Return time it took to load and precache the level. - virtual CTimeValue GetLastLevelLoadTime() const = 0; - - virtual void GetMemoryStatistics(ICrySizer* pSizer) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H diff --git a/Code/CryEngine/CryCommon/ISerialize.h b/Code/CryEngine/CryCommon/ISerialize.h index 9ca4fb665c..5fb0d9a3aa 100644 --- a/Code/CryEngine/CryCommon/ISerialize.h +++ b/Code/CryEngine/CryCommon/ISerialize.h @@ -20,7 +20,6 @@ #include #include -#include "CountedValue.h" #include "MiniQueue.h" #include #include @@ -471,58 +470,6 @@ public: } } - template - void Value(const char* name, CountedValue& countedValue) - { - if (!BeginOptionalGroup(name, true)) - { - return; - } - if (IsWriting()) - { - T rawValue = countedValue.Peek(); - Value("Value", rawValue); - typename CountedValue::TCountedID rawId = countedValue.GetLatestID(); - Value("Id", rawId, 'ui32'); - } - - if (IsReading()) - { - T rawValue; - Value("Value", rawValue); - typename CountedValue::TCountedID rawId; - Value("Id", rawId, 'ui32'); - countedValue.UpdateDuringSerializationOnly(rawValue, rawId); - } - EndGroup(); - } - - template - void Value(const char* name, CountedValue& countedValue, int policy) - { - if (!BeginOptionalGroup(name, true)) - { - return; - } - if (IsWriting()) - { - T rawValue = countedValue.Peek(); - Value("Value", rawValue, policy); - typename CountedValue::TCountedID rawId = countedValue.GetLatestID(); - Value("Id", rawId, 'ui32'); - } - - if (IsReading()) - { - T rawValue; - Value("Value", rawValue, policy); - typename CountedValue::TCountedID rawId; - Value("Id", rawId, 'ui32'); - countedValue.UpdateDuringSerializationOnly(rawValue, rawId); - } - EndGroup(); - } - bool ValueChar(const char* name, char* buffer, int len) { string temp; diff --git a/Code/CryEngine/CryCommon/IShader.h b/Code/CryEngine/CryCommon/IShader.h index 5f5209992e..c74d981864 100644 --- a/Code/CryEngine/CryCommon/IShader.h +++ b/Code/CryEngine/CryCommon/IShader.h @@ -36,8 +36,6 @@ #include #include -#include - struct IMaterial; class CRendElementBase; class CRenderObject; @@ -2238,74 +2236,6 @@ struct SShaderTexSlots } }; -struct SShaderGenBit -{ - SShaderGenBit() - { - m_Mask = 0; - m_Flags = 0; - m_nDependencySet = 0; - m_nDependencyReset = 0; - m_NameLength = 0; - m_dwToken = 0; - } - string m_ParamName; - string m_ParamProp; - string m_ParamDesc; - int m_NameLength; - uint64 m_Mask; - uint32 m_Flags; - uint32 m_dwToken; - std::vector m_PrecacheNames; - std::vector m_DependSets; - std::vector m_DependResets; - uint32 m_nDependencySet; - uint32 m_nDependencyReset; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_ParamName); - pSizer->AddObject(m_ParamProp); - pSizer->AddObject(m_ParamDesc); - pSizer->AddObject(m_PrecacheNames); - pSizer->AddObject(m_DependSets); - pSizer->AddObject(m_DependResets); - } -}; - -struct SShaderGen -{ - uint32 m_nRefCount; - TArray m_BitMask; - SShaderGen() - { - m_nRefCount = 1; - } - ~SShaderGen() - { - uint32 i; - for (i = 0; i < m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = m_BitMask[i]; - SAFE_DELETE(pBit); - } - m_BitMask.Free(); - } - void Release() - { - m_nRefCount--; - if (!m_nRefCount) - { - delete this; - } - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_BitMask); - } -}; - //=================================================================================== enum EShaderType @@ -2570,7 +2500,6 @@ public: virtual void SetFlags2(int Flags) = 0; virtual void ClearFlags2(int Flags) = 0; virtual bool Reload(int nFlags, const char* szShaderName) = 0; - virtual TArray* GetREs (int nTech) = 0; virtual AZStd::vector& GetPublicParams() = 0; virtual int GetTexId () = 0; virtual ITexture* GetBaseTexture(int* nPass, int* nTU) = 0; @@ -2579,7 +2508,6 @@ public: virtual ECull GetCull(void) = 0; virtual int Size(int Flags) = 0; virtual uint64 GetGenerationMask() = 0; - virtual SShaderGen* GetGenerationParams() = 0; virtual size_t GetNumberOfUVSets() = 0; virtual int GetTechniqueID(int nTechnique, int nRegisteredTechnique) = 0; virtual AZ::Vertex::Format GetVertexFormat(void) = 0; diff --git a/Code/CryEngine/CryCommon/IStreamEngine.h b/Code/CryEngine/CryCommon/IStreamEngine.h deleted file mode 100644 index 0536e1f486..0000000000 --- a/Code/CryEngine/CryCommon/IStreamEngine.h +++ /dev/null @@ -1,493 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// This is the prototypes of interfaces that will be used for asynchronous -// I/O (streaming). -// THIS IS NOT FINAL AND IS SUBJECT TO CHANGE WITHOUT NOTICE - -// Some excerpts explaining basic ideas behind streaming design here: - -/* - * The idea is that the data loaded is ready for usage and ideally doesn't need further transformation, - * therefore the client allocates the buffer (to avoid extra copy). All the data transformations should take place in the Resource Compiler. If you have to allocate a lot of small memory objects, you should revise this strategy in favor of one big allocation (again, that will be read directly from the compiled file). - * Anyway, we can negotiate that the streaming engine allocates this memory. - * In the end, it could make use of a memory pool, and copying data is not the bottleneck in our engine - * - * The client should take care of all fast operations. Looking up file size should be fast on the virtual - * file system in a pak file, because the directory should be preloaded in memory - */ - -#ifndef CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H -#define CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H -#pragma once - - -#include -#include "smartptr.h" -#include "CryThread.h" - -#include "IStreamEngineDefs.h" - -class IStreamCallback; -class ICrySizer; - -#define STREAM_TASK_TYPE_AUDIO_ALL ((1 << eStreamTaskTypeMusic) | (1 << eStreamTaskTypeSound) | (1 << eStreamTaskTypeFSBCache)) - -// Description: -// This is used as parameter to the asynchronous read function -// all the unnecessary parameters go here, because there are many of them. -struct StreamReadParams -{ -public: - StreamReadParams() - { - memset(this, 0, sizeof(*this)); - ePriority = estpNormal; - } - - StreamReadParams ( - DWORD_PTR _dwUserData, - EStreamTaskPriority _ePriority = estpNormal, - unsigned _nLoadTime = 0, - unsigned _nMaxLoadTime = 0, - unsigned _nOffset = 0, - unsigned _nSize = 0, - void* _pBuffer = NULL, - unsigned _nFlags = 0 - ) - : dwUserData (_dwUserData) - , ePriority(_ePriority) - , nPerceptualImportance(0) - , nLoadTime(_nLoadTime) - , nMaxLoadTime(_nMaxLoadTime) - , pBuffer (_pBuffer) - , nOffset (_nOffset) - , nSize (_nSize) - , eMediaType(eStreamSourceTypeUnknown) - , nFlags (_nFlags) - { - } - - // Summary: - // File name. - //const char* szFile; - - // Summary: - // The callback. - //IStreamCallback* pAsyncCallback; - - // Summary: - // The user data that'll be used to call the callback. - DWORD_PTR dwUserData; - - // The priority of this read - EStreamTaskPriority ePriority; - - // Value from 0-255 of the perceptual importance of the task (used for debugging task sheduling) - uint8 nPerceptualImportance; - - // Description: - // The desirable loading time, in milliseconds, from the time of call - // 0 means as fast as possible (desirably in this frame). - unsigned nLoadTime; - - // Description: - // The maximum load time, in milliseconds. 0 means forever. If the read lasts longer, it can be discarded. - // WARNING: avoid too small max times, like 1-10 ms, because many loads will be discarded in this case. - unsigned nMaxLoadTime; - - // Description: - // The buffer into which to read the file or the file piece - // if this is NULL, the streaming engine will supply the buffer. - // Notes: - // DO NOT USE THIS BUFFER during read operation! DO NOT READ from it, it can lead to memory corruption! - void* pBuffer; - - // Description: - // Offset in the file to read; if this is not 0, then the file read - // occurs beginning with the specified offset in bytes. - // The callback interface receives the size of already read data as nSize - // and generally behaves as if the piece of file would be a file of its own. - unsigned nOffset; - - // Description: - // Number of bytes to read; if this is 0, then the whole file is read, - // if nSize == 0 && nOffset != 0, then the file from the offset to the end is read. - // If nSize != 0, then the file piece from nOffset is read, at most nSize bytes - // (if less, an error is reported). So, from nOffset byte to nOffset + nSize - 1 byte in the file. - unsigned nSize; - - // Description: - // Media type to use when starting file request - if wrong, the request may take longer to complete - EStreamSourceMediaType eMediaType; - - // Description: - // The combination of one or several flags from the stream engine general purpose flags. - // See also: - // IStreamEngine::EFlags - unsigned nFlags; -}; - -struct StreamReadBatchParams -{ - StreamReadBatchParams() - : tSource((EStreamTaskType)0) - , szFile(NULL) - , pCallback(NULL) - { - } - - EStreamTaskType tSource; - const char* szFile; - IStreamCallback* pCallback; - StreamReadParams params; -}; - -struct IStreamEngineListener -{ - // - virtual ~IStreamEngineListener() {} - - virtual void OnStreamEnqueue(const void* pReq, const char* filename, EStreamTaskType source, const StreamReadParams& readParams) = 0; - virtual void OnStreamComputedSortKey(const void* pReq, uint64 key) = 0; - virtual void OnStreamBeginIO(const void* pReq, uint32 compressSize, uint32 readSize, EStreamSourceMediaType mediaType) = 0; - virtual void OnStreamEndIO(const void* pReq) = 0; - virtual void OnStreamBeginInflate(const void* pReq) = 0; - virtual void OnStreamEndInflate(const void* pReq) = 0; - virtual void OnStreamBeginAsyncCallback(const void* pReq) = 0; - virtual void OnStreamEndAsyncCallback(const void* pReq) = 0; - virtual void OnStreamDone(const void* pReq) = 0; - virtual void OnStreamPreempted(const void* pReq) = 0; - virtual void OnStreamResumed(const void* pReq) = 0; - // -}; - -// Description: -// The highest level. There is only one StreamingEngine in the application -// and it controls all I/O streams. -struct IStreamEngine -{ -public: - - - enum EJobType - { - ejtStarted = 1 << 0, - ejtPending = 1 << 1, - ejtFinished = 1 << 2, - }; - - // Summary: - // General purpose flags. - enum EFlags - { - // Description: - // If this is set only asynchronous callback will be called. - FLAGS_NO_SYNC_CALLBACK = BIT(0), - // Description: - // If this is set the file will be read from disc directly, instead of from the pak system. - FLAGS_FILE_ON_DISK = BIT(1), - // Description: - // Ignore the tmp out of streaming memory for this request - FLAGS_IGNORE_TMP_OUT_OF_MEM = BIT(2), - // Description: - // External buffer is write only - FLAGS_WRITE_ONLY_EXTERNAL_BUFFER = BIT(3), - }; - - // - // Description: - // Starts asynchronous read from the specified file (the file may be on a - // virtual file system, in pak or zip file or wherever). - // Reads the file contents into the given buffer, up to the given size. - // Upon success, calls success callback. If the file is truncated or for other - // reason can not be read, calls error callback. The callback can be NULL (in this case, the client should poll - // the returned IReadStream object; the returned object must be locked for that) - // NOTE: the error/success/ progress callbacks can also be called from INSIDE this function. - // Arguments: - // tSource - - // szFile - - // pCallback - - // pParams - PLACEHOLDER for the future additional parameters (like priority), or really - // a pointer to a structure that will hold the parameters if there are too many of them. - // Return Value: - // IReadStream is reference-counted and will be automatically deleted if you don't refer to it; - // if you don't store it immediately in an auto-pointer, it may be deleted as soon as on the next line of code, - // because the read operation may complete immediately inside StartRead() and the object is self-disposed - // as soon as the callback is called. - // Remarks: - // In some implementations disposal of the old pointers happen synchronously - // (in the main thread) outside StartRead() (it happens in the entity update), - // so you're guaranteed that it won't trash inside the calling function. However, this may change in the future - // and you'll be required to assign it to IReadStream immediately (StartRead will return IReadStream_AutoPtr then). - // See also: - // IReadStream,IReadStream_AutoPtr - virtual IReadStreamPtr StartRead (const EStreamTaskType tSource, const char* szFile, IStreamCallback* pCallback = NULL, const StreamReadParams* pParams = NULL) = 0; - - // Pass a callback to preRequestCallback if you need to execute code right before the requests get enqueued; the callback is called only once per execution - virtual size_t StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback = nullptr) = 0; - - // Call this methods before/after submitting large number of new requests. - virtual void BeginReadGroup() = 0; - virtual void EndReadGroup() = 0; - - // Pause/resumes streaming of specific data types. - // nPauseTypesBitmask is a bit mask of data types (ex, 1< -}; - -// Description: -// This is the file "handle" that can be used to query the status -// of the asynchronous operation on the file. The same object may be returned -// for the same file to multiple clients. -// Notes: -// It will actually represent the asynchronous object in memory, and will be -// thread-safe reference-counted (both AddRef() and Release() will be virtual -// and thread-safe, just like the others) -// Example: -// USE: -// IReadStream_AutoPtr pReadStream = pStreamEngine->StartRead ("bla.xxx", this); -// OR: -// pStreamEngine->StartRead ("MusicSystem","bla.xxx", this); -class IReadStream -{ -public: - // - // Summary: - // Increment ref count, returns new count - virtual int AddRef() = 0; - // Summary: - // Decrement ref count, returns new count - virtual int Release() = 0; - // Summary: - // Returns true if the file read was not successful. - virtual bool IsError() = 0; - // Return Value: - // True if the file read was completed successfully. - // Summary: - // Checks IsError to check if the whole requested file (piece) was read. - virtual bool IsFinished() = 0; - // Description: - // Returns the number of bytes read so far (the whole buffer size if IsFinished()) - // Arguments: - // bWait - if == true, then waits until the pending I/O operation completes. - // Return Value: - // The total number of bytes read (if it completes successfully, returns the size of block being read) - virtual unsigned int GetBytesRead(bool bWait = false) = 0; - // Description: - // Returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read. - // Notes: - // DO NOT USE THIS BUFFER during read operation! DO NOT READ from it, it can lead to memory corruption! - virtual const void* GetBuffer () = 0; - - // Description: - // Returns the transparent DWORD that was passed in the StreamReadParams::dwUserData field - // of the structure passed in the call to IStreamEngine::StartRead. - // See also: - // StreamReadParams::dwUserData,IStreamEngine::StartRead - virtual DWORD_PTR GetUserData() = 0; - - // Summary: - // Set user defined data into stream's params. - virtual void SetUserData(DWORD_PTR dwUserData) = 0; - - // Description: - // Tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - virtual void Abort() = 0; - - // Description: - // Tries to stop reading the stream, as long as IO or the async callback is not currently - // in progress. - virtual bool TryAbort() = 0; - - // Summary: - // Unconditionally waits until the callback is called. - // if nMaxWaitMillis is not negative wait for the specified ammount of milliseconds then exit. - // Example: - // If the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified). - virtual void Wait(int nMaxWaitMillis = -1) = 0; - - // Summary: - // Returns stream params. - virtual const StreamReadParams& GetParams() const = 0; - - // Summary: - // Returns caller type. - virtual const EStreamTaskType GetCallerType() const = 0; - - // Summary: - // Returns media type used to satisfy request - only valid once stream has begun read. - virtual EStreamSourceMediaType GetMediaType() const = 0; - - // Summary: - // Returns pointer to callback routine(can be NULL). - virtual IStreamCallback* GetCallback() const = 0; - - // Summary: - // Returns IO error #. - virtual unsigned GetError() const = 0; - - // Summary: - // Returns IO error name - virtual const char* GetErrorName() const = 0; - - // Summary: - // Returns stream name. - virtual const char* GetName() const = 0; - - // Summary: - // Free temporary memory allocated for this stream, when not needed anymore. - // Can be called from Async callback, to free memory earlier, not waiting for synchrounus callback. - virtual void FreeTemporaryMemory() = 0; - // - -protected: - // Summary: - // The clients are not allowed to destroy this object directly; only via Release(). - virtual ~IReadStream() {} -}; - -TYPEDEF_AUTOPTR(IReadStream); - -// Description: -// CryPak supports asynchronous reading through this interface. The callback -// is called from the main thread in the frame update loop. -// -// The callback receives packets through StreamOnComplete() and -// StreamOnProgress(). The second one can be used to update the asset based -// on the partial data that arrived. the callback that will be called by the -// streaming engine must be implemented by all clients that want to use -// StreamingEngine services -// Remarks: -// the pStream interface is guaranteed to be locked (have reference count > 0) -// while inside the function, but can vanish any time outside the function. -// If you need it, keep it from the beginning (after call to StartRead()) -// some or all callbacks MAY be called from inside IStreamEngine::StartRead() -// -// Example: -// -// IStreamEngine *pStreamEngine = g_pISystem->GetStreamEngine(); // get streaming engine -// IStreamCallback *pAsyncCallback = &MyClass; // user -// -// StreamReadParams params; -// -// params.dwUserData = 0; -// params.nSize = 0; -// params.pBuffer = NULL; -// params.nLoadTime = 10000; -// params.nMaxLoadTime = 10000; -// -// pStreamEngine->StartRead( .. pAsyncCallback .. params .. ); // registers callback -// -class IStreamCallback -{ -public: - // - virtual ~IStreamCallback(){} - - // Description: - // Signals that the file length for the request has been found, and that storage is needed - // Either a pointer to a block of nSize bytes can be returned, into which the file will be - // streamed, or NULL can be returned, in which case temporary memory will be allocated - // internally by the stream engine (which will be freed upon job completion). - virtual void* StreamOnNeedStorage ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nSize, [[maybe_unused]] bool& bAbortOnFailToAlloc) {return NULL; } - - // Description: - // Signals that reading the requested data has completed (with or without error). - // This callback is always called, whether an error occurs or not. - // pStream will signal either IsFinished() or IsError() and will hold the (perhaps partially) read data until this interface is released. - // GetBytesRead() will return the size of the file (the completely read buffer) in case of successful operation end - // or the size of partially read data in case of error (0 if nothing was read). - // Pending status is true during this callback, because the callback itself is the part of IO operation. - // nError == 0 : Success - // nError != 0 : Error code - virtual void StreamAsyncOnComplete ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {} - - // Description: - // Signals that reading the requested data has completed (with or without error). - // This callback is always called, whether an error occurs or not. - // pStream will signal either IsFinished() or IsError() and will hold the (perhaps partially) read data until this interface is released. - // GetBytesRead() will return the size of the file (the completely read buffer) in case of successful operation end - // or the size of partially read data in case of error (0 if nothing was read). - // Pending status is true during this callback, because the callback itself is the part of IO operation. - // nError == 0 : Success - // nError != 0 : Error code - virtual void StreamOnComplete ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {} - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H diff --git a/Code/CryEngine/CryCommon/IStreamEngineDefs.h b/Code/CryEngine/CryCommon/IStreamEngineDefs.h deleted file mode 100644 index e931a6201e..0000000000 --- a/Code/CryEngine/CryCommon/IStreamEngineDefs.h +++ /dev/null @@ -1,236 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H -#define CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H -#pragma once - - -#if defined(ENABLE_PROFILING_CODE) -#define STREAMENGINE_ENABLE_LISTENER -#define STREAMENGINE_ENABLE_STATS -#endif - -enum : unsigned int -{ - ERROR_UNKNOWN_ERROR = 0xF0000000, - ERROR_UNEXPECTED_DESTRUCTION = 0xF0000001, - ERROR_INVALID_CALL = 0xF0000002, - ERROR_CANT_OPEN_FILE = 0xF0000003, - ERROR_REFSTREAM_ERROR = 0xF0000004, - ERROR_OFFSET_OUT_OF_RANGE = 0xF0000005, - ERROR_REGION_OUT_OF_RANGE = 0xF0000006, - ERROR_SIZE_OUT_OF_RANGE = 0xF0000007, - ERROR_CANT_START_READING = 0xF0000008, - ERROR_OUT_OF_MEMORY = 0xF0000009, - ERROR_ABORTED_ON_SHUTDOWN = 0xF000000A, - ERROR_OUT_OF_MEMORY_QUOTA = 0xF000000B, - ERROR_ZIP_CACHE_FAILURE = 0xF000000C, - ERROR_USER_ABORT = 0xF000000D, - ERROR_MISSCHEDULED = 0xF000000F, - ERROR_VERIFICATION_FAIL = 0xF0000010, - ERROR_PREEMPTED = 0xF0000011, - ERROR_DECOMPRESSION_FAIL = 0xF0000012 -}; - -// Summary: -// Types of streaming tasks -// Affects priority directly -enum EStreamTaskType -{ - eStreamTaskTypeCount = 14, - eStreamTaskTypeGeomCache = 13, - eStreamTaskTypePak = 12, - eStreamTaskTypeFlash = 11, - eStreamTaskTypeVideo = 10, - - eStreamTaskTypeMergedMesh = 9, - eStreamTaskTypeShader = 8, - eStreamTaskTypeSound = 7, - eStreamTaskTypeMusic = 6, - eStreamTaskTypeFSBCache = 5, - eStreamTaskTypeAnimation = 4, - eStreamTaskTypeTerrain = 3, - eStreamTaskTypeGeometry = 2, - eStreamTaskTypeTexture = 1, -}; - -// Summary: -// Priority types of streaming tasks -// Affects priority directly -// Limiting number of priority values allows streaming system to minimize seek time -enum EStreamTaskPriority -{ - estpUrgent = 0, - estpPreempted = 1, //For internal use only - estpAboveNormal = 2, - estpNormal = 3, - estpBelowNormal = 4, - estpIdle = 5, -}; - -enum EStreamSourceMediaType : int32_t -{ - eStreamSourceTypeUnknown = 0, - eStreamSourceTypeHDD, - eStreamSourceTypeDisc, - eStreamSourceTypeMemory, -}; - -#if defined(STREAMENGINE_ENABLE_STATS) -struct SStreamEngineStatistics -{ - struct SMediaTypeInfo - { - SMediaTypeInfo() - { - ResetStats(); - } - void ResetStats() - { - memset(this, 0, sizeof(SMediaTypeInfo)); - } - - float fActiveDuringLastSecond; // Amount of time media device was active during last second - float fAverageActiveTime; // Average time since last reset that the media device was active - - uint32 nBytesRead; // Bytes read during last second. - uint32 nRequestCount; // Amount of requests during last second. - uint64 nTotalBytesRead; // Read bytes total from reset. - uint32 nTotalRequestCount; // Number of request from reset. - - uint64 nSeekOffsetLastSecond; // Average seek offset during the last second - uint64 nAverageSeekOffset; // Average seek offset since last reset - - uint32 nCurrentReadBandwidth; // Bytes/second for last second - uint32 nSessionReadBandwidth; // Bytes/second for last second - - uint32 nActualReadBandwidth; // Bytes/second for last second - only taking actual reading into account - uint32 nAverageActualReadBandwidth; // Average read bandwidth in total from reset - only taking actual read time into account - }; - - SMediaTypeInfo hddInfo; - SMediaTypeInfo memoryInfo; - SMediaTypeInfo discInfo; - - uint32 nTotalSessionReadBandwidth;// Average read bandwidth in total from reset - taking full time into account from reset - uint32 nTotalCurrentReadBandwidth;// Total bytes/sec over all types and systems. - - int nPendingReadBytes; // How many bytes still need to be read - float fAverageCompletionTime; // Time in seconds on average takes to complete file request. - float fAverageRequestCount; // Average requests per second being done to streaming engine - - uint64 nMainStreamingThreadWait; - - uint64 nTotalBytesRead; // Read bytes total from reset. - uint32 nTotalRequestCount; // Number of request from reset to the streaming engine. - uint32 nTotalStreamingRequestCount; // Number of request from reset which actually resulted in streaming data. - - int nCurrentDecompressCount; // Number of requests currently waiting to be decompresses - int nCurrentAsyncCount; // Number of requests currently waiting to be async callback - int nCurrentFinishedCount; // Number of requests currently waiting to be finished by mainthread - - uint32 nDecompressBandwidth; // Bytes/second for last second - uint32 nVerifyBandwidth; // Bytes/second for last second - uint32 nDecompressBandwidthAverage; // Bytes/second in total. - uint32 nVerifyBandwidthAverage; // Bytes/second in total. - - bool bTempMemOutOfBudget; // Was the temporary streaming memory out of budget during the last second - int nMaxTempMemory; // Maximum temporary memory used by the streaming system - int nTempMemory; - - struct SRequestTypeInfo - { - SRequestTypeInfo() - : nPendingReadBytes(0) - { - ResetStats(); - } - void ResetStats() - { - nTmpReadBytes = 0; - nTotalStreamingRequestCount = 0; - nTotalReadBytes = 0; - nTotalRequestDataSize = 0; - nTotalRequestCount = 0; - nCurrentReadBandwidth = 0; - nSessionReadBandwidth = 0; - fTotalCompletionTime = .0f; - fAverageCompletionTime = .0f; - } - - void Merge(const SRequestTypeInfo& _other) - { - nPendingReadBytes += _other.nPendingReadBytes; - nTmpReadBytes += _other.nTmpReadBytes; - nTotalStreamingRequestCount += _other.nTotalStreamingRequestCount; - nTotalReadBytes += _other.nTotalReadBytes; - nTotalRequestDataSize += _other.nTotalRequestDataSize; - nTotalRequestCount += _other.nTotalRequestCount; - fTotalCompletionTime += _other.fTotalCompletionTime; - } - - int nPendingReadBytes; // How many bytes still need to be read from media - - uint64 nTmpReadBytes; // Read bytes since last update to compute current bandwidth - - uint32 nTotalStreamingRequestCount; // Total actual streaming requests of this type - uint64 nTotalReadBytes; // Total actual read bytes (compressed data) - uint64 nTotalRequestDataSize; // Total requested bytes from client (uncompressed data) - uint32 nTotalRequestCount; // Total number of finished requests - - uint32 nCurrentReadBandwidth; // Bytes/second for this type during last second - uint32 nSessionReadBandwidth; // Average read bandwidth in total from reset - taking full time into account from reset - - float fTotalCompletionTime; // Time it took to finish all current requests - float fAverageCompletionTime; // Average time it takes to fully complete a request of this type - float fAverageRequestCount; // Average amount of requests made per second - }; - - SRequestTypeInfo typeInfo[eStreamTaskTypeCount]; - - struct SAsset - { - CryStringLocal m_sName; - int m_nSize; - const bool operator<(const SAsset& a) const { return m_nSize > a.m_nSize; } - SAsset() {} - SAsset(const CryStringLocal& sName, const int nSize) - : m_sName(sName) - , m_nSize(nSize) { } - - friend void swap(SAsset& a, SAsset& b) - { - using std::swap; - - a.m_sName.swap(b.m_sName); - swap(a.m_nSize, b.m_nSize); - } - }; - DynArray vecHeavyAssets; -}; -#endif - -struct SStreamEngineOpenStats -{ - int nOpenRequestCount; - int nOpenRequestCountByType[eStreamTaskTypeCount]; -}; - -class IReadStream; -TYPEDEF_AUTOPTR(IReadStream); - -// typedef IReadStream_AutoPtr auto ptr wrapper -typedef IReadStream_AutoPtr IReadStreamPtr; - -#endif // CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H diff --git a/Code/CryEngine/CryCommon/ISystem.h b/Code/CryEngine/CryCommon/ISystem.h index 4c6bd73b61..73341dd16f 100644 --- a/Code/CryEngine/CryCommon/ISystem.h +++ b/Code/CryEngine/CryCommon/ISystem.h @@ -65,12 +65,10 @@ struct IProcess; struct ITimer; struct ICryFont; struct IMovieSystem; -struct IMemoryManager; namespace Audio { struct IAudioSystem; } // namespace Audio -struct IStreamEngine; struct SFileVersion; struct INameTable; struct ILevelSystem; @@ -78,7 +76,6 @@ struct IViewSystem; class ICrySizer; class IXMLBinarySerializer; struct IReadWriteXMLSink; -struct IResourceManager; struct ITextModeConsole; struct IAVI_Reader; class CPNoise3; @@ -89,7 +86,6 @@ struct ILZ4Decompressor; class IZStdDecompressor; struct IOutputPrintSink; struct IWindowMessageHandler; -struct IImageHandler; namespace AZ { @@ -828,10 +824,6 @@ struct ISystem virtual void DoWorkDuringOcclusionChecks() = 0; virtual bool NeedDoWorkDuringOcclusionChecks() = 0; - // Summary: - // Returns the current used memory. - virtual uint32 GetUsedMemory() = 0; - // Summary: // Retrieve the name of the user currently logged in to the computer. virtual const char* GetUserName() = 0; @@ -905,27 +897,18 @@ struct ISystem virtual ILevelSystem* GetILevelSystem() = 0; virtual INameTable* GetINameTable() = 0; virtual IValidator* GetIValidator() = 0; - virtual IStreamEngine* GetStreamEngine() = 0; virtual ICmdLine* GetICmdLine() = 0; virtual ILog* GetILog() = 0; virtual AZ::IO::IArchive* GetIPak() = 0; virtual ICryFont* GetICryFont() = 0; - virtual IMemoryManager* GetIMemoryManager() = 0; virtual IMovieSystem* GetIMovieSystem() = 0; virtual ::IConsole* GetIConsole() = 0; virtual IRemoteConsole* GetIRemoteConsole() = 0; - // Returns: - // Can be NULL, because it only exists when running through the editor, not in pure game mode. - virtual IResourceManager* GetIResourceManager() = 0; virtual IProfilingSystem* GetIProfilingSystem() = 0; virtual ISystemEventDispatcher* GetISystemEventDispatcher() = 0; virtual ITimer* GetITimer() = 0; - virtual void DebugStats(bool checkpoint, bool leaks) = 0; - virtual void DumpWinHeaps() = 0; - virtual int DumpMMStats(bool log) = 0; - // Arguments: // bValue - Set to true when running on a cheat protected server or a client that is connected to it (not used in singleplayer). virtual void SetForceNonDevMode(bool bValue) = 0; @@ -1166,8 +1149,6 @@ struct ISystem // Initializes Steam if needed and returns if it was successful virtual bool SteamInit() = 0; - virtual const IImageHandler* GetImageHandler() const = 0; - // Summary: // Gets the root window message handler function // The returned pointer is platform-specific: diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp b/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp deleted file mode 100644 index 8cf29bcb2a..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -namespace CImageExtensionHelper -{ - ColorF GetAverageColor(uint8 const* pMem) - { - pMem = _findChunkStart(pMem, FOURCC_AvgC); - - if (pMem) - { - ColorF ret = ColorF(SwapEndianValue(*(uint32*)pMem)); - //flip red and blue - const float cRed = ret.r; - ret.r = ret.b; - ret.b = cRed; - return ret; - } - - return Col_White; // chunk does not exist - } - - bool IsRangeless(ETEX_Format eTF) - { - return (eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_R9G9B9E5 || - eTF == eTF_R16G16B16A16F || - eTF == eTF_R32G32B32A32F || - eTF == eTF_R16F || - eTF == eTF_R32F || - eTF == eTF_R16G16F || - eTF == eTF_R11G11B10F); - } - - bool IsQuantized(ETEX_Format eTF) - { - return (eTF == eTF_B4G4R4A4 || - eTF == eTF_B5G6R5 || - eTF == eTF_B5G5R5 || - eTF == eTF_BC1 || - eTF == eTF_BC2 || - eTF == eTF_BC3 || - eTF == eTF_BC4U || - eTF == eTF_BC4S || - eTF == eTF_BC5U || - eTF == eTF_BC5S || - eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_BC7 || - eTF == eTF_R9G9B9E5 || - eTF == eTF_ETC2 || - eTF == eTF_EAC_R11 || - eTF == eTF_ETC2A || - eTF == eTF_EAC_RG11 || - eTF == eTF_PVRTC2 || - eTF == eTF_PVRTC4 || - eTF == eTF_ASTC_4x4 || - eTF == eTF_ASTC_5x4 || - eTF == eTF_ASTC_5x5 || - eTF == eTF_ASTC_6x5 || - eTF == eTF_ASTC_6x6 || - eTF == eTF_ASTC_8x5 || - eTF == eTF_ASTC_8x6 || - eTF == eTF_ASTC_8x8 || - eTF == eTF_ASTC_10x5 || - eTF == eTF_ASTC_10x6 || - eTF == eTF_ASTC_10x8 || - eTF == eTF_ASTC_10x10 || - eTF == eTF_ASTC_12x10 || - eTF == eTF_ASTC_12x12 - ); - } -} diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper.h b/Code/CryEngine/CryCommon/ImageExtensionHelper.h deleted file mode 100644 index 71e58074c9..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper.h +++ /dev/null @@ -1,2155 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#undef AZ_RESTRICTED_SECTION -#define IMAGEEXTENSIONHELPER_H_SECTION_1 1 -#define IMAGEEXTENSIONHELPER_H_SECTION_2 2 -#define IMAGEEXTENSIONHELPER_H_SECTION_CONSTS 3 -#define IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE 4 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_1 - #include AZ_RESTRICTED_FILE(ImageExtensionHelper_h) -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_2 - #include AZ_RESTRICTED_FILE(ImageExtensionHelper_h) -#endif - -#ifndef MAKEFOURCC - #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \ - ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24)) -#endif /* defined(MAKEFOURCC) */ - - -// This header defines constants and structures that are useful when parsing -// DDS files. DDS files were originally designed to use several structures -// and constants that are native to DirectDraw and are defined in ddraw.h, -// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar -// (compatible) constants and structures so that one can use DDS files -// without needing to include ddraw.h. - -// Crytek specific image extensions -// -// usually added to the end of DDS files - -//Needed to write out DDS files on Mac -#if AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) -#define DDPF_ALPHAPIXELS 0x00000001 // Texture contains alpha data -#define DDPF_ALPHA 0x00000002 // For alpha channel only uncompressed data -#define DDPF_FOURCC 0x00000004 // Texture contains compressed RGB data -#define DDPF_RGB 0x00000040 // Texture contains uncompressed RGB data -#define DDPF_YUV 0x00000200 // For YUV uncompressed data -#define DDPF_LUMINANCE 0x00020000 // For single channel color uncompressed data - -#define DDSCAPS_COMPLEX 0x00000008 // Must be used on any file that contains more than one surface -#define DDSCAPS_MIPMAP 0x00400000 // Should be used for a mipmap -#define DDSCAPS_TEXTURE 0x00001000 // Required -#endif - -#define DDS_FOURCC 0x00000004 // DDPF_FOURCC -#define DDS_RGB 0x00000040 // DDPF_RGB -#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE -#define DDS_SIGNED 0x00080000 // DDPF_SIGNED -#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS -#define DDS_LUMINANCEA 0x00020001 // DDS_LUMINANCE | DDPF_ALPHAPIXELS -#define DDS_A 0x00000001 // DDPF_ALPHAPIXELS -#define DDS_A_ONLY 0x00000002 // DDPF_ALPHA - -#define DDS_FOURCC_A16B16G16R16 0x00000024 // FOURCC A16B16G16R16 -#define DDS_FOURCC_V16U16 0x00000040 // FOURCC V16U16 -#define DDS_FOURCC_Q16W16V16U16 0x0000006E // FOURCC Q16W16V16U16 -#define DDS_FOURCC_R16F 0x0000006F // FOURCC R16F -#define DDS_FOURCC_G16R16F 0x00000070 // FOURCC G16R16F -#define DDS_FOURCC_A16B16G16R16F 0x00000071 // FOURCC A16B16G16R16F -#define DDS_FOURCC_R32F 0x00000072 // FOURCC R32F -#define DDS_FOURCC_G32R32F 0x00000073 // FOURCC G32R32F -#define DDS_FOURCC_A32B32G32R32F 0x00000074 // FOURCC A32B32G32R32F - -#define DDSD_CAPS 0x00000001l // default -#define DDSD_PIXELFORMAT 0x00001000l -#define DDSD_WIDTH 0x00000004l -#define DDSD_HEIGHT 0x00000002l -#define DDSD_LINEARSIZE 0x00080000l - -#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT -#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT -#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH -#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH -#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE - -#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE -#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP -#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX - -#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX -#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX -#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY -#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY -#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ -#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ - -#define DDS_CUBEMAP_ALLFACES (DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX | \ - DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY | \ - DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ) - -#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME - -#define DDS_RESF1_NORMALMAP 0x01000000 -#define DDS_RESF1_DSDT 0x02000000 - -#define CRY_DDS_DX10_SUPPORT - -#include - -#if defined(WIN32) && !defined(DXGI_FORMAT_DEFINED) -#include // DX10+ formats -#endif // #if defined(WIN32) && !defined(DXGI_FORMAT_DEFINED) - - -namespace CImageExtensionHelper -{ - struct DDS_PIXELFORMAT - { - DWORD dwSize; - DWORD dwFlags; - DWORD dwFourCC; - DWORD dwRGBBitCount; - DWORD dwRBitMask; - DWORD dwGBitMask; - DWORD dwBBitMask; - DWORD dwABitMask; - - const bool operator == (const DDS_PIXELFORMAT& fmt) const - { - return dwFourCC == fmt.dwFourCC && - dwFlags == fmt.dwFlags && - dwRGBBitCount == fmt.dwRGBBitCount && - dwRBitMask == fmt.dwRBitMask && - dwGBitMask == fmt.dwGBitMask && - dwBBitMask == fmt.dwBBitMask && - dwABitMask == fmt.dwABitMask && - dwSize == fmt.dwSize; - } - - AUTO_STRUCT_INFO - }; - - struct DDS_HEADER_DXT10 - { - // we're unable to use native enums because of TypeInfo(), so we use DWORD instead. - DWORD /*DXGI_FORMAT*/ dxgiFormat; - DWORD /*D3D10_RESOURCE_DIMENSION*/ resourceDimension; - unsigned int miscFlag; - unsigned int arraySize; - unsigned int reserved; - - AUTO_STRUCT_INFO - }; - - struct DDS_HEADER - { - DWORD dwSize; - DWORD dwHeaderFlags; - DWORD dwHeight; - DWORD dwWidth; - DWORD dwPitchOrLinearSize; - DWORD dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwHeaderFlags - DWORD dwMipMapCount; - DWORD dwAlphaBitDepth; - DWORD dwReserved1; // Crytek image flags - float fAvgBrightness; // Average top mip brightness. Could be f16/half - ColorF cMinColor; - ColorF cMaxColor; - DDS_PIXELFORMAT ddspf; - DWORD dwSurfaceFlags; - DWORD dwCubemapFlags; - BYTE bNumPersistentMips; - BYTE bTileMode; - BYTE bReserved2[6]; - DWORD dwTextureStage; - - AUTO_STRUCT_INFO - - inline const bool IsValid() const { return sizeof(*this) == dwSize; } - inline const bool IsDX10Ext() const { return ddspf.dwFourCC == MAKEFOURCC('D', 'X', '1', '0'); } - inline const uint32 GetMipCount() const { return max(1u, (uint32)dwMipMapCount); } - - inline const size_t GetFullHeaderSize() const - { - if (IsDX10Ext()) - { - return sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); - } - - return sizeof(DDS_HEADER); - } - }; - - // standard description of file header - struct DDS_FILE_DESC - { - DWORD dwMagic; - DDS_HEADER header; - - AUTO_STRUCT_INFO - - inline const bool IsValid() const { return dwMagic == MAKEFOURCC('D', 'D', 'S', ' ') && header.IsValid(); } - inline const size_t GetFullHeaderSize() const { return sizeof(dwMagic) + header.GetFullHeaderSize(); } - }; - - // chunk identifier - const static uint32 FOURCC_CExt = MAKEFOURCC('C', 'E', 'x', 't'); // Crytek extension start - const static uint32 FOURCC_AvgC = MAKEFOURCC('A', 'v', 'g', 'C'); // average color - const static uint32 FOURCC_CEnd = MAKEFOURCC('C', 'E', 'n', 'd'); // Crytek extension end - const static uint32 FOURCC_AttC = MAKEFOURCC('A', 't', 't', 'C'); // Chunk Attached Channel - - // flags to propagate from the RC to the engine through GetImageFlags() - // 32bit bitmask, numbers should not change as engine relies on them - const static uint32 EIF_Cubemap = 0x1; - const static uint32 EIF_Volumetexture = 0x2; - const static uint32 EIF_Decal = 0x4; // this is usually set through the preset - const static uint32 EIF_Greyscale = 0x8; // hint for the engine (e.g. greyscale light beams can be applied to shadow mask), can be for DXT1 because compression artfacts don't count as color - const static uint32 EIF_SupressEngineReduce = 0x10; // info for the engine: don't reduce texture resolution on this texture - const static uint32 EIF_UNUSED_BIT = 0x40; // Free to use - const static uint32 EIF_AttachedAlpha = 0x400; // info for the engine: it's a texture with attached alpha channel - const static uint32 EIF_SRGBRead = 0x800; // info for the engine: if gamma corrected rendering is on, this texture requires SRGBRead (it's not stored in linear) - const static uint32 EIF_DontResize = 0x8000; // info for the engine: for dds textures that shouldn't be resized with r_TexResolution - const static uint32 EIF_RenormalizedTexture = 0x10000; // info for the engine: for dds textures that have renormalized color range - const static uint32 EIF_CafeNative = 0x20000; // info for the engine: native Cafe texture format - const static uint32 EIF_Tiled = 0x80000; // info for the engine: texture has been tiled for the platform - const static uint32 EIF_Splitted = 0x200000; // info for the engine: this texture is splitted - const static uint32 EIF_Colormodel = 0x7000000; // info for the engine: bitmask: colormodel used in the texture - const static uint32 EIF_Colormodel_RGB = 0x0000000; // info for the engine: colormodel is RGB (default) - const static uint32 EIF_Colormodel_CIE = 0x1000000; // info for the engine: colormodel is CIE (used for terrain) - const static uint32 EIF_Colormodel_YCC = 0x2000000; // info for the engine: colormodel is Y'CbCr (used for reflectance) - const static uint32 EIF_Colormodel_YFF = 0x3000000; // info for the engine: colormodel is Y'FbFr (used for reflectance) - const static uint32 EIF_Colormodel_IRB = 0x4000000; // info for the engine: colormodel is IRB (used for reflectance) - -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, jasper) - #undef AZ_RESTRICTED_SECTION -#endif - -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, provo) - #undef AZ_RESTRICTED_SECTION -#endif - -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, salem) - #undef AZ_RESTRICTED_SECTION -#endif - - enum ETileMode - { - eTM_None = 0, - eTM_LinearPadded, - eTM_Optimal, - }; - - // Arguments: - // pDDSHeader - must not be 0 - // Returns: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - inline uint32 GetImageFlags(DDS_HEADER* pDDSHeader) - { - assert(pDDSHeader); - - // non standardized way to expose some features in the header (same information is in attached chunk but then - // streaming would need to find this spot in the file) - // if this is causing problems we need to change it - if (pDDSHeader->dwSize >= sizeof(DDS_HEADER)) - { - if (pDDSHeader->dwTextureStage == 'CRYF') - { - return pDDSHeader->dwReserved1; - } - } - - return 0; - } - - // Arguments: - // pDDSHeader - must not be 0 - // Returns: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - inline bool SetImageFlags(DDS_HEADER* pDDSHeader, uint32 flags) - { - assert(pDDSHeader); - - // non standardized way to expose some features in the header (same information is in attached chunk but then - // streaming would need to find this spot in the file) - // if this is causing problems we need to change it - if (pDDSHeader->dwSize >= sizeof(DDS_HEADER)) - { - if (pDDSHeader->dwTextureStage == 'CRYF') - { - pDDSHeader->dwReserved1 = flags; - return true; - } - } - - return false; - } - - // Arguments: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - // Returns: - // true, if this texture is ready for this platform - inline const bool IsImageNative(const uint32 nFlags) - { - return (nFlags & (0 -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, jasper) -#endif -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, provo) -#endif -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, salem) -#endif - )) == 0; - } - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - // Returns: - // 0 if not existing - inline uint8 const* _findChunkStart(uint8 const* pMem, const uint32 dwChunkName, uint32* dwOutSize = NULL) - { - if (pMem) - { - if (*(uint32*)pMem == SwapEndianValue(FOURCC_CExt)) - { - pMem += 4; // jump over chunk name - while (*(uint32*)pMem != SwapEndianValue(FOURCC_CEnd)) - { - if (*(uint32*)pMem == SwapEndianValue(dwChunkName)) - { - pMem += 4; // jump over chunk name - const uint32 size = SwapEndianValue(*(uint32*)(pMem)); - if (dwOutSize) - { - *dwOutSize = size; - } - pMem += 4; // jump over chunk size - return size > 0 ? pMem : NULL; - } - - pMem += 8 + SwapEndianValue(*(uint32*)(&pMem[4])); // jump over chunk - } - } - } - - return 0; // chunk does not exist - } - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - ColorF GetAverageColor(uint8 const* pMem); - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - // Returns: - // pointer to the DDS header - inline DDS_HEADER* GetAttachedImage(uint8 const* pMem, uint32* dwOutSize = NULL) - { - pMem = _findChunkStart(pMem, FOURCC_AttC, dwOutSize); - if (pMem) - { - return (DDS_HEADER*)(pMem + 4); - } - - if (dwOutSize) - { - *dwOutSize = 0; - } - return 0; // chunk does not exist - } - - static ILINE Vec2i GetBlockDim(const ETEX_Format eTF) - { - if (eTF == eTF_BC1 || eTF == eTF_BC2 || eTF == eTF_BC3 || eTF == eTF_BC5U || eTF == eTF_BC5S || eTF == eTF_BC4U || eTF == eTF_BC4S || eTF == eTF_CTX1 || eTF == eTF_BC6UH || eTF == eTF_BC6SH || eTF == eTF_BC7 || eTF == eTF_EAC_R11 || eTF == eTF_EAC_RG11 || eTF == eTF_ETC2 || eTF == eTF_ETC2A) - { - return Vec2i(4, 4); - } - // Apple requires the following for the texture: - // Height and width must be a power of 2 - // Height and width must be at least 8 - // Must be square - switch (eTF) - { - case eTF_PVRTC2: - return Vec2i(8, 4); - case eTF_PVRTC4: - return Vec2i(4, 4); - case eTF_ASTC_4x4: - return Vec2i(4, 4); - case eTF_ASTC_5x4: - return Vec2i(5, 4); - case eTF_ASTC_5x5: - return Vec2i(5, 5); - case eTF_ASTC_6x5: - return Vec2i(6, 5); - case eTF_ASTC_6x6: - return Vec2i(6, 6); - case eTF_ASTC_8x5: - return Vec2i(8, 5); - case eTF_ASTC_8x6: - return Vec2i(8, 6); - case eTF_ASTC_8x8: - return Vec2i(8, 8); - case eTF_ASTC_10x5: - return Vec2i(10, 5); - case eTF_ASTC_10x6: - return Vec2i(10, 6); - case eTF_ASTC_10x8: - return Vec2i(10, 8); - case eTF_ASTC_10x10: - return Vec2i(10, 10); - case eTF_ASTC_12x10: - return Vec2i(12, 10); - case eTF_ASTC_12x12: - return Vec2i(12, 12); - } - - return Vec2i(1, 1); - } - - inline int BytesPerBlock(ETEX_Format eTF) - { - switch (eTF) - { - case eTF_R8G8B8A8S: - return 32 / 8; - case eTF_R8G8B8A8: - return 32 / 8; - - case eTF_A8: - return 8 / 8; - case eTF_R8: - return 8 / 8; - case eTF_R8S: - return 8 / 8; - case eTF_R16: - return 16 / 8; - case eTF_R16U: - return 16 / 8; - case eTF_R16G16U: - return 32 / 8; - case eTF_R10G10B10A2UI: - return 32 / 8; - case eTF_R16F: - return 16 / 8; - case eTF_R32F: - return 32 / 8; - case eTF_R8G8: - return 16 / 8; - case eTF_R8G8S: - return 16 / 8; - case eTF_R16G16: - return 32 / 8; - case eTF_R16G16S: - return 32 / 8; - case eTF_R16G16F: - return 32 / 8; - case eTF_R11G11B10F: - return 32 / 8; - case eTF_R10G10B10A2: - return 32 / 8; - case eTF_R16G16B16A16: - return 64 / 8; - case eTF_R16G16B16A16S: - return 64 / 8; - case eTF_R16G16B16A16F: - return 64 / 8; - case eTF_R32G32B32A32F: - return 128 / 8; - - case eTF_R9G9B9E5: - return 32 / 8; - - case eTF_D16: - return 16 / 8; - case eTF_D24S8: - return 32 / 8; - case eTF_D32F: - return 32 / 8; - case eTF_D32FS8: - return 32 / 8; - - case eTF_B5G6R5: - return 16 / 8; - case eTF_B5G5R5: - return 16 / 8; - case eTF_B4G4R4A4: - return 16 / 8; - - case eTF_A8L8: - return 16 / 8; - case eTF_L8: - return 8 / 8; - case eTF_L8V8U8: - return 24 / 8; - case eTF_B8G8R8: - return 24 / 8; - case eTF_L8V8U8X8: - return 32 / 8; - case eTF_B8G8R8X8: - return 32 / 8; - case eTF_B8G8R8A8: - return 32 / 8; - - case eTF_CTX1: - case eTF_BC1: - case eTF_BC4U: - case eTF_BC4S: - case eTF_ETC2: - case eTF_EAC_R11: - return 8; - - case eTF_BC2: - case eTF_BC3: - case eTF_BC5U: - case eTF_BC5S: - case eTF_BC6UH: - case eTF_BC6SH: - case eTF_BC7: - case eTF_ETC2A: - case eTF_EAC_RG11: - return 16; - - case eTF_PVRTC2: - case eTF_PVRTC4: - return 8; - - case eTF_ASTC_4x4: - case eTF_ASTC_5x4: - case eTF_ASTC_5x5: - case eTF_ASTC_6x5: - case eTF_ASTC_6x6: - case eTF_ASTC_8x5: - case eTF_ASTC_8x6: - case eTF_ASTC_8x8: - case eTF_ASTC_10x5: - case eTF_ASTC_10x6: - case eTF_ASTC_10x8: - case eTF_ASTC_10x10: - case eTF_ASTC_12x10: - case eTF_ASTC_12x12: - return 16; - default: - assert(0); - } - return 0; - } - - - inline bool IsBlockCompressed(ETEX_Format eTF) - { - return (eTF == eTF_BC1 || - eTF == eTF_BC2 || - eTF == eTF_BC3 || - eTF == eTF_BC4U || - eTF == eTF_BC4S || - eTF == eTF_BC5S || - eTF == eTF_BC5U || - eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_BC7 || - eTF == eTF_CTX1 || - eTF == eTF_ETC2 || - eTF == eTF_EAC_R11 || - eTF == eTF_ETC2A || - eTF == eTF_EAC_RG11 || - eTF == eTF_PVRTC2 || - eTF == eTF_PVRTC4 || - eTF == eTF_ASTC_4x4 || - eTF == eTF_ASTC_5x4 || - eTF == eTF_ASTC_5x5 || - eTF == eTF_ASTC_6x5 || - eTF == eTF_ASTC_6x6 || - eTF == eTF_ASTC_8x5 || - eTF == eTF_ASTC_8x6 || - eTF == eTF_ASTC_8x8 || - eTF == eTF_ASTC_10x5 || - eTF == eTF_ASTC_10x6 || - eTF == eTF_ASTC_10x8 || - eTF == eTF_ASTC_10x10 || - eTF == eTF_ASTC_12x10 || - eTF == eTF_ASTC_12x12 - ); - } - - bool IsRangeless(ETEX_Format eTF); - - bool IsQuantized(ETEX_Format eTF); - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const char* NameForTextureFormat(ETEX_Format ETF) - { - switch (ETF) - { - case eTF_Unknown: - return "Unknown"; - - case eTF_R8G8B8A8S: - return "R8G8B8A8S"; - case eTF_R8G8B8A8: - return "R8G8B8A8"; - - case eTF_A8: - return "A8"; - case eTF_R8: - return "R8"; - case eTF_R8S: - return "R8S"; - case eTF_R16: - return "R16"; - case eTF_R16F: - return "R16F"; - case eTF_R32F: - return "R32F"; - case eTF_R8G8: - return "R8G8"; - case eTF_R8G8S: - return "R8G8S"; - case eTF_R16G16: - return "R16G16"; - case eTF_R16G16S: - return "R16G16S"; - case eTF_R16G16F: - return "R16G16F"; - case eTF_R11G11B10F: - return "R11G11B10F"; - case eTF_R10G10B10A2: - return "R10G10B10A2"; - case eTF_R16G16B16A16: - return "R16G16B16A16"; - case eTF_R16G16B16A16S: - return "R16G16B16A16S"; - case eTF_R16G16B16A16F: - return "R16G16B16A16F"; - case eTF_R32G32B32A32F: - return "R32G32B32A32F"; - - case eTF_CTX1: - return "CTX1"; - case eTF_BC1: - return "BC1"; - case eTF_BC2: - return "BC2"; - case eTF_BC3: - return "BC3"; - case eTF_BC4U: - return "BC4"; - case eTF_BC4S: - return "BC4S"; - case eTF_BC5U: - return "BC5"; - case eTF_BC5S: - return "BC5S"; - case eTF_BC6UH: - return "BC6UH"; - case eTF_BC6SH: - return "BC6SH"; - case eTF_BC7: - return "BC7"; - case eTF_R9G9B9E5: - return "R9G9B9E5"; - - case eTF_D16: - return "D16"; - case eTF_D24S8: - return "D24S8"; - case eTF_D32F: - return "D32F"; - case eTF_D32FS8: - return "D32FS8"; - - case eTF_B5G6R5: - return "R5G5B5"; - case eTF_B5G5R5: - return "R5G6B5"; - case eTF_B4G4R4A4: - return "B4G4R4A4"; - - case eTF_EAC_R11: - return "EAC_R11"; - case eTF_EAC_RG11: - return "EAC_RG11"; - case eTF_ETC2: - return "ETC2"; - case eTF_ETC2A: - return "ETC2A"; - - case eTF_PVRTC2: - return "PVRTC2"; - case eTF_PVRTC4: - return "PVRTC4"; - - case eTF_ASTC_4x4: - return "ASTC_4x4"; - case eTF_ASTC_5x4: - return "ASTC_5x4"; - case eTF_ASTC_5x5: - return "ASTC_5x5"; - case eTF_ASTC_6x5: - return "ASTC_6x5"; - case eTF_ASTC_6x6: - return "ASTC_6x6"; - case eTF_ASTC_8x5: - return "ASTC_8x5"; - case eTF_ASTC_8x6: - return "ASTC_8x6"; - case eTF_ASTC_8x8: - return "ASTC_8x8"; - case eTF_ASTC_10x5: - return "ASTC_10x5"; - case eTF_ASTC_10x6: - return "ASTC_10x6"; - case eTF_ASTC_10x8: - return "ASTC_10x8"; - case eTF_ASTC_10x10: - return "ASTC_10x10"; - case eTF_ASTC_12x10: - return "ASTC_12x10"; - case eTF_ASTC_12x12: - return "ASTC_12x12"; - - case eTF_A8L8: - return "A8L8"; - case eTF_L8: - return "L8"; - case eTF_L8V8U8: - return "L8V8U8"; - case eTF_B8G8R8: - return "B8G8R8"; - case eTF_L8V8U8X8: - return "L8V8U8X8"; - case eTF_B8G8R8X8: - return "B8G8R8X8"; - case eTF_B8G8R8A8: - return "B8G8R8A8"; - - default: - assert(0); // pass through for better behaviour in non debug - } - - return "Unknown"; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline ETEX_Format TextureFormatForName(const char* sETF) - { - if (!azstricmp(sETF, "Unknown")) - { - return eTF_Unknown; - } - - if (!azstricmp(sETF, "R8G8B8A8S")) - { - return eTF_R8G8B8A8S; - } - if (!azstricmp(sETF, "R8G8B8A8")) - { - return eTF_R8G8B8A8; - } - - if (!azstricmp(sETF, "A8")) - { - return eTF_A8; - } - if (!azstricmp(sETF, "R8")) - { - return eTF_R8; - } - if (!azstricmp(sETF, "R8S")) - { - return eTF_R8S; - } - if (!azstricmp(sETF, "R16")) - { - return eTF_R16; - } - if (!azstricmp(sETF, "R16F")) - { - return eTF_R16F; - } - if (!azstricmp(sETF, "R32F")) - { - return eTF_R32F; - } - if (!azstricmp(sETF, "R8G8")) - { - return eTF_R8G8; - } - if (!azstricmp(sETF, "R8G8S")) - { - return eTF_R8G8S; - } - if (!azstricmp(sETF, "R16G16")) - { - return eTF_R16G16; - } - if (!azstricmp(sETF, "R16G16S")) - { - return eTF_R16G16S; - } - if (!azstricmp(sETF, "R16G16F")) - { - return eTF_R16G16F; - } - if (!azstricmp(sETF, "R11G11B10F")) - { - return eTF_R11G11B10F; - } - if (!azstricmp(sETF, "R10G10B10A2")) - { - return eTF_R10G10B10A2; - } - if (!azstricmp(sETF, "R16G16B16A16")) - { - return eTF_R16G16B16A16; - } - if (!azstricmp(sETF, "R16G16B16A16S")) - { - return eTF_R16G16B16A16S; - } - if (!azstricmp(sETF, "R16G16B16A16F")) - { - return eTF_R16G16B16A16F; - } - if (!azstricmp(sETF, "R32G32B32A32F")) - { - return eTF_R32G32B32A32F; - } - - if (!azstricmp(sETF, "CTX1")) - { - return eTF_CTX1; - } - if (!azstricmp(sETF, "BC1")) - { - return eTF_BC1; - } - if (!azstricmp(sETF, "BC2")) - { - return eTF_BC2; - } - if (!azstricmp(sETF, "BC3")) - { - return eTF_BC3; - } - if (!azstricmp(sETF, "BC4")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "BC4S")) - { - return eTF_BC4S; - } - if (!azstricmp(sETF, "BC5")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "BC5S")) - { - return eTF_BC5S; - } - if (!azstricmp(sETF, "BC6UH")) - { - return eTF_BC6UH; - } - if (!azstricmp(sETF, "BC6SH")) - { - return eTF_BC6SH; - } - if (!azstricmp(sETF, "BC7")) - { - return eTF_BC7; - } - if (!azstricmp(sETF, "R9G9B9E5")) - { - return eTF_R9G9B9E5; - } - - if (!azstricmp(sETF, "D16")) - { - return eTF_D16; - } - if (!azstricmp(sETF, "D24S8")) - { - return eTF_D24S8; - } - if (!azstricmp(sETF, "D32F")) - { - return eTF_D32F; - } - if (!azstricmp(sETF, "D32FS8")) - { - return eTF_D32FS8; - } - - if (!azstricmp(sETF, "R5G5B5")) - { - return eTF_B5G6R5; - } - if (!azstricmp(sETF, "R5G6B5")) - { - return eTF_B5G5R5; - } - if (!azstricmp(sETF, "B4G4R4A4")) - { - return eTF_B4G4R4A4; - } - - if (!azstricmp(sETF, "EAC_R11")) - { - return eTF_EAC_R11; - } - if (!azstricmp(sETF, "EAC_RG11")) - { - return eTF_EAC_RG11; - } - if (!azstricmp(sETF, "ETC2")) - { - return eTF_ETC2; - } - if (!azstricmp(sETF, "ETC2A")) - { - return eTF_ETC2A; - } - - if (!azstricmp(sETF, "PVRTC2")) - { - return eTF_PVRTC2; - } - if (!azstricmp(sETF, "PVRTC4")) - { - return eTF_PVRTC4; - } - - if (!azstricmp(sETF, "ASTC_4x4")) - { - return eTF_ASTC_4x4; - } - if (!azstricmp(sETF, "ASTC_5x4")) - { - return eTF_ASTC_5x4; - } - if (!azstricmp(sETF, "ASTC_5x5")) - { - return eTF_ASTC_5x5; - } - if (!azstricmp(sETF, "ASTC_6x5")) - { - return eTF_ASTC_6x5; - } - if (!azstricmp(sETF, "ASTC_6x6")) - { - return eTF_ASTC_6x6; - } - if (!azstricmp(sETF, "ASTC_8x5")) - { - return eTF_ASTC_8x5; - } - if (!azstricmp(sETF, "ASTC_8x6")) - { - return eTF_ASTC_8x6; - } - if (!azstricmp(sETF, "ASTC_8x8")) - { - return eTF_ASTC_8x8; - } - if (!azstricmp(sETF, "ASTC_10x5")) - { - return eTF_ASTC_10x5; - } - if (!azstricmp(sETF, "ASTC_10x6")) - { - return eTF_ASTC_10x6; - } - if (!azstricmp(sETF, "ASTC_10x8")) - { - return eTF_ASTC_10x8; - } - if (!azstricmp(sETF, "ASTC_10x10")) - { - return eTF_ASTC_10x10; - } - if (!azstricmp(sETF, "ASTC_12x10")) - { - return eTF_ASTC_12x10; - } - if (!azstricmp(sETF, "ASTC_12x12")) - { - return eTF_ASTC_12x12; - } - - if (!azstricmp(sETF, "A8L8")) - { - return eTF_A8L8; - } - if (!azstricmp(sETF, "L8")) - { - return eTF_L8; - } - if (!azstricmp(sETF, "L8V8U8")) - { - return eTF_L8V8U8; - } - if (!azstricmp(sETF, "B8G8R8")) - { - return eTF_B8G8R8; - } - if (!azstricmp(sETF, "L8V8U8X8")) - { - return eTF_L8V8U8X8; - } - if (!azstricmp(sETF, "B8G8R8X8")) - { - return eTF_B8G8R8X8; - } - if (!azstricmp(sETF, "B8G8R8A8")) - { - return eTF_B8G8R8A8; - } - - if (!azstricmp(sETF, "V8U8")) - { - return eTF_R8G8S; - } - if (!azstricmp(sETF, "V16U16")) - { - return eTF_R16G16S; - } - - if (!azstricmp(sETF, "DXT1")) - { - return eTF_BC1; - } - if (!azstricmp(sETF, "DXT3")) - { - return eTF_BC2; - } - if (!azstricmp(sETF, "DXT5")) - { - return eTF_BC3; - } - if (!azstricmp(sETF, "ATI1")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "ATI2")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "3DCp")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "3DC")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "RGBE")) - { - return eTF_R9G9B9E5; - } - - assert (0); - return eTF_Unknown; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const char* NameForTextureType(ETEX_Type eTT) - { - const char* sETT; - switch (eTT) - { - case eTT_1D: - sETT = "1D"; - break; - case eTT_2D: - sETT = "2D"; - break; - case eTT_2DArray: - sETT = "2D array"; - break; - case eTT_2DMS: - sETT = "2D multi-sampled"; - break; - case eTT_3D: - sETT = "3D"; - break; - case eTT_Cube: - sETT = "Cube"; - break; - case eTT_CubeArray: - sETT = "CubeArray"; - break; - case eTT_Auto2D: - sETT = "Auto2D"; - break; - case eTT_Dyn2D: - sETT = "Dyn2D"; - break; - default: - assert(0); - sETT = "Unknown"; // for better behaviour in non debug - break; - } - return sETT; - } - - inline ETEX_Type TextureTypeForName(const char* sETT) - { - if (!azstricmp(sETT, "1D")) - { - return eTT_1D; - } - if (!azstricmp(sETT, "2D")) - { - return eTT_2D; - } - if (!azstricmp(sETT, "3D")) - { - return eTT_3D; - } - if (!azstricmp(sETT, "Cube")) - { - return eTT_Cube; - } - if (!azstricmp(sETT, "Auto2D")) - { - return eTT_Auto2D; - } - if (!azstricmp(sETT, "Dyn2D")) - { - return eTT_Dyn2D; - } - if (!azstricmp(sETT, "User")) - { - return eTT_User; - } - assert(0); - return eTT_2D; - } - - inline bool HasAlphaForName(const char* sETF) - { - if (!azstricmp(sETF, "R8G8B8A8S")) - { - return true; - } - if (!azstricmp(sETF, "R8G8B8A8")) - { - return true; - } - if (!azstricmp(sETF, "A8")) - { - if (!azstricmp(sETF, "A8L8")) - { - if (!azstricmp(sETF, "BC1") || !azstricmp(sETF, "DXT1")) - { - if (!azstricmp(sETF, "BC2") || !azstricmp(sETF, "DXT3")) - { - if (!azstricmp(sETF, "BC3") || !azstricmp(sETF, "DXT5")) - { - if (!azstricmp(sETF, "BC7")) - { - if (!azstricmp(sETF, "A8")) - { - return true; - } - } - } - } - } - } - } - if (!azstricmp(sETF, "R10G10B10A2")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16S")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16F")) - { - return true; - } - if (!azstricmp(sETF, "R32G32B32A32F")) - { - return true; - } - - if (!azstricmp(sETF, "BC2")) - { - return true; - } - if (!azstricmp(sETF, "BC3")) - { - return true; - } - if (!azstricmp(sETF, "BC7")) - { - return true; - } - - if (!azstricmp(sETF, "B4G4R4A4")) - { - return true; - } - - if (!azstricmp(sETF, "ETC2A")) - { - return true; - } - - if (!azstricmp(sETF, "A8L8")) - { - return true; - } - if (!azstricmp(sETF, "B8G8R8A8")) - { - return true; - } - - if (!azstricmp(sETF, "DXT3")) - { - return true; - } - if (!azstricmp(sETF, "DXT5")) - { - return true; - } - - return false; - } - - inline bool HasAlphaForTextureFormat(ETEX_Format ETF) - { - if (ETF == eTF_R8G8B8A8S) - { - return true; - } - if (ETF == eTF_R8G8B8A8) - { - return true; - } - - if (ETF == eTF_A8) - { - return true; - } - if (ETF == eTF_R10G10B10A2) - { - return true; - } - if (ETF == eTF_R16G16B16A16) - { - return true; - } - if (ETF == eTF_R16G16B16A16S) - { - return true; - } - if (ETF == eTF_R16G16B16A16F) - { - return true; - } - if (ETF == eTF_R32G32B32A32F) - { - return true; - } - - if (ETF == eTF_BC2) - { - return true; - } - if (ETF == eTF_BC3) - { - return true; - } - if (ETF == eTF_BC7) - { - return true; - } - - if (ETF == eTF_B4G4R4A4) - { - return true; - } - - if (ETF == eTF_ETC2A) - { - return true; - } - - if (ETF == eTF_A8L8) - { - return true; - } - if (ETF == eTF_B8G8R8A8) - { - return true; - } - - return false; - } - - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf, DWORD /*DXGI_FORMAT*/ dxgif); -}; - -namespace DDSFormats -{ - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DX10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', '1', '0'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT1 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT3 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '3'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_CTX1 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('C', 'T', 'X', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_3DC = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_3DCP = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_EAC_R11 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'A', 'R', ' '), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_EAC_RG11 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'A', 'R', 'G'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ETC2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'T', '2', ' '), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ETC2A = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'T', '2', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_PVRTC2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('P', 'V', 'R', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_PVRTC4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('P', 'V', 'R', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_4x4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '4', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_5x4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '5', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_5x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '5', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_6x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '6', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_6x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '6', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '8'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '8'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_12x10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'C', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_12x12 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'C', 'C'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_R32F, 32, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G32R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_G32R32F, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A32B32G32R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A32B32G32R32F, 128, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_R16F, 16, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G16R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_G16R16F, 32, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A16B16G16R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A16B16G16R16F, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_U16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_SIGNED, 0, 16, 0x0000ffff, 0x00000000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_V16U16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_SIGNED, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_Q16W16V16U16 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_Q16W16V16U16, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000ffff, 0x00000000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G16R16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A16B16G16R16 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A16B16G16R16, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8B8G8R8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A1R5G5B5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A4R4G4B4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_X8R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R5G6B5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_A, 0, 8, 0x00000000, 0x00000000, 0x00000000, 0x000000ff }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_L8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0x000000ff, 0x000000ff, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8L8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 8, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff }; - - inline ETEX_Format GetFormatByDesc(const CImageExtensionHelper::DDS_PIXELFORMAT& ddspf) - { - if (ddspf.dwFourCC == DDSPF_DXT1.dwFourCC) - { - return eTF_BC1; - } - else if (ddspf.dwFourCC == DDSPF_DXT3.dwFourCC) - { - return eTF_BC2; - } - else if (ddspf.dwFourCC == DDSPF_DXT5.dwFourCC) - { - return eTF_BC3; - } - else if (ddspf.dwFourCC == DDSPF_3DCP.dwFourCC) - { - return eTF_BC4U; - } - else if (ddspf.dwFourCC == DDSPF_3DC.dwFourCC) - { - return eTF_BC5U; - } - else if (ddspf.dwFourCC == DDSPF_CTX1.dwFourCC) - { - return eTF_CTX1; - } - else if (ddspf.dwFourCC == DDSPF_R32F.dwFourCC) - { - return eTF_R32F; - } - // else if( ddspf.dwFourCC == DDSPF_G32R32F.dwFourCC) - // return eTF_R32G32F; // TODO: add to engine - else if (ddspf.dwFourCC == DDSPF_A32B32G32R32F.dwFourCC) - { - return eTF_R32G32B32A32F; - } - else if (ddspf.dwFourCC == DDSPF_R16F.dwFourCC) - { - return eTF_R16F; - } - else if (ddspf.dwFourCC == DDSPF_G16R16F.dwFourCC) - { - return eTF_R16G16F; - } - else if (ddspf.dwFourCC == DDSPF_A16B16G16R16F.dwFourCC) - { - return eTF_R16G16B16A16F; - } - // else if( ddspf == DDSPF_U16) - // return eTF_R16S; // TODO: add to engine - else if (ddspf == DDSPF_V16U16) - { - return eTF_R16G16S; - } - else if (ddspf.dwFourCC == DDSPF_Q16W16V16U16.dwFourCC) - { - return eTF_R16G16B16A16S; - } - else if (ddspf == DDSPF_R16) - { - return eTF_R16; - } - else if (ddspf == DDSPF_G16R16) - { - return eTF_R16G16; - } - else if (ddspf.dwFourCC == DDSPF_A16B16G16R16.dwFourCC) - { - return eTF_R16G16B16A16; - } - else if (ddspf.dwFourCC == DDSPF_EAC_R11.dwFourCC) - { - return eTF_EAC_R11; - } - else if (ddspf.dwFourCC == DDSPF_EAC_RG11.dwFourCC) - { - return eTF_EAC_RG11; - } - else if (ddspf.dwFourCC == DDSPF_ETC2.dwFourCC) - { - return eTF_ETC2; - } - else if (ddspf.dwFourCC == DDSPF_ETC2A.dwFourCC) - { - return eTF_ETC2A; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x000000ff && ddspf.dwABitMask == 0xff000000) - { - return eTF_R8G8B8A8; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x00ff0000 && ddspf.dwABitMask == 0xff000000) - { - return eTF_B8G8R8A8; - } - else if (ddspf.dwFlags == DDS_RGB && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x00ff0000) - { - return eTF_B8G8R8X8; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 16) - { - return eTF_B4G4R4A4; - } - else if (ddspf.dwFlags == DDS_RGB && ddspf.dwRGBBitCount == 24) - { - return eTF_B8G8R8; - } - else if (ddspf.dwFlags == DDS_LUMINANCEA && ddspf.dwRGBBitCount == 8) - { - return eTF_A8L8; - } - else if (ddspf.dwFlags == DDS_LUMINANCE && ddspf.dwRGBBitCount == 8) - { - return eTF_L8; - } - else if ((ddspf.dwFlags == DDS_A || ddspf.dwFlags == DDS_A_ONLY || ddspf.dwFlags == (DDS_A | DDS_A_ONLY)) && ddspf.dwRGBBitCount == 8) - { - return eTF_A8; - } - else if (ddspf.dwFourCC == DDSPF_PVRTC2.dwFourCC) - { - return eTF_PVRTC2; - } - else if (ddspf.dwFourCC == DDSPF_PVRTC4.dwFourCC) - { - return eTF_PVRTC4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_4x4.dwFourCC) - { - return eTF_ASTC_4x4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_5x4.dwFourCC) - { - return eTF_ASTC_5x4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_5x5.dwFourCC) - { - return eTF_ASTC_5x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_6x5.dwFourCC) - { - return eTF_ASTC_6x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_6x6.dwFourCC) - { - return eTF_ASTC_6x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x5.dwFourCC) - { - return eTF_ASTC_8x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x6.dwFourCC) - { - return eTF_ASTC_8x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x8.dwFourCC) - { - return eTF_ASTC_8x8; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x5.dwFourCC) - { - return eTF_ASTC_10x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x6.dwFourCC) - { - return eTF_ASTC_10x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x8.dwFourCC) - { - return eTF_ASTC_10x8; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x10.dwFourCC) - { - return eTF_ASTC_10x10; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_12x10.dwFourCC) - { - return eTF_ASTC_12x10; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_12x12.dwFourCC) - { - return eTF_ASTC_12x12; - } - - assert(0); - return eTF_Unknown; - } - - inline ETEX_Format GetFormatByDesc(const CImageExtensionHelper::DDS_PIXELFORMAT& ddspf, const DWORD /*DXGI_FORMAT*/ dxgif) - { - // 'DX10' indicates the format is not in the FourCC, but in the extended header - if (ddspf.dwFourCC == DDSPF_DX10.dwFourCC) - { -#if defined(CRY_DDS_DX10_SUPPORT) - switch (dxgif) - { - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_UNORM: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_SNORM: - return eTF_R8G8B8A8S; - - case DXGI_FORMAT_A8_UNORM: - return eTF_A8; - case DXGI_FORMAT_R8_UNORM: - return eTF_R8; - case DXGI_FORMAT_R8_SNORM: - return eTF_R8S; - case DXGI_FORMAT_R16_UNORM: - return eTF_R16; - // case DXGI_FORMAT_R16_SNORM: return eTF_R16S; - case DXGI_FORMAT_R16_FLOAT: - return eTF_R16F; - case DXGI_FORMAT_R16_TYPELESS: - return eTF_R16F; // arbitrary choice for F - case DXGI_FORMAT_R32_FLOAT: - return eTF_R32F; - case DXGI_FORMAT_R32_TYPELESS: - return eTF_R32F; - case DXGI_FORMAT_R8G8_UNORM: - return eTF_R8G8; - case DXGI_FORMAT_R8G8_SNORM: - return eTF_R8G8S; - case DXGI_FORMAT_R16G16_UNORM: - return eTF_R16G16; - case DXGI_FORMAT_R16G16_SNORM: - return eTF_R16G16S; - case DXGI_FORMAT_R16G16_FLOAT: - return eTF_R16G16F; - // case DXGI_FORMAT_R32G32_FLOAT: return eTF_R32G32F; - case DXGI_FORMAT_R11G11B10_FLOAT: - return eTF_R11G11B10F; - case DXGI_FORMAT_R10G10B10A2_UNORM: - return eTF_R10G10B10A2; - case DXGI_FORMAT_R16G16B16A16_UNORM: - return eTF_R16G16B16A16; - case DXGI_FORMAT_R16G16B16A16_SNORM: - return eTF_R16G16B16A16S; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return eTF_R16G16B16A16F; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - return eTF_R32G32B32A32F; - - case DXGI_FORMAT_BC1_TYPELESS: - return eTF_BC1; - case DXGI_FORMAT_BC1_UNORM: - return eTF_BC1; - case DXGI_FORMAT_BC1_UNORM_SRGB: - return eTF_BC1; - case DXGI_FORMAT_BC2_TYPELESS: - return eTF_BC2; - case DXGI_FORMAT_BC2_UNORM: - return eTF_BC2; - case DXGI_FORMAT_BC2_UNORM_SRGB: - return eTF_BC2; - case DXGI_FORMAT_BC3_TYPELESS: - return eTF_BC3; - case DXGI_FORMAT_BC3_UNORM: - return eTF_BC3; - case DXGI_FORMAT_BC3_UNORM_SRGB: - return eTF_BC3; - case DXGI_FORMAT_BC4_TYPELESS: - return eTF_BC4U; - case DXGI_FORMAT_BC4_UNORM: - return eTF_BC4U; - case DXGI_FORMAT_BC4_SNORM: - return eTF_BC4S; - case DXGI_FORMAT_BC5_TYPELESS: - return eTF_BC5U; - case DXGI_FORMAT_BC5_UNORM: - return eTF_BC5U; - case DXGI_FORMAT_BC5_SNORM: - return eTF_BC5S; - case DXGI_FORMAT_BC6H_UF16: - return eTF_BC6UH; - case DXGI_FORMAT_BC6H_SF16: - return eTF_BC6SH; - case DXGI_FORMAT_BC7_TYPELESS: - return eTF_BC7; - case DXGI_FORMAT_BC7_UNORM: - return eTF_BC7; - case DXGI_FORMAT_BC7_UNORM_SRGB: - return eTF_BC7; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - return eTF_R9G9B9E5; - - // only available as hardware format under DX11.1 with DXGI 1.2 - case DXGI_FORMAT_B5G6R5_UNORM: - return eTF_B5G6R5; - case DXGI_FORMAT_B5G5R5A1_UNORM: - return eTF_B5G5R5; - // case DXGI_FORMAT_B4G4R4A4_UNORM: return eTF_B4G4R4A4; - -#if defined(OPENGL) || defined(CRY_USE_METAL) - // only available as hardware format under OpenGL - case DXGI_FORMAT_EAC_R11_TYPELESS: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_R11_UNORM: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_R11_SNORM: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_RG11_TYPELESS: - return eTF_EAC_RG11; - case DXGI_FORMAT_EAC_RG11_UNORM: - return eTF_EAC_RG11; - case DXGI_FORMAT_EAC_RG11_SNORM: - return eTF_EAC_RG11; - case DXGI_FORMAT_ETC2_TYPELESS: - return eTF_ETC2; - case DXGI_FORMAT_ETC2_UNORM: - return eTF_ETC2; - case DXGI_FORMAT_ETC2_UNORM_SRGB: - return eTF_ETC2; - case DXGI_FORMAT_ETC2A_TYPELESS: - return eTF_ETC2A; - case DXGI_FORMAT_ETC2A_UNORM: - return eTF_ETC2A; - case DXGI_FORMAT_ETC2A_UNORM_SRGB: - return eTF_ETC2A; -#endif //defined(OPENGL) - -#ifdef CRY_USE_METAL - case DXGI_FORMAT_PVRTC2_TYPELESS: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC2_UNORM: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC2_UNORM_SRGB: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC4_TYPELESS: - return eTF_PVRTC4; - case DXGI_FORMAT_PVRTC4_UNORM: - return eTF_PVRTC4; - case DXGI_FORMAT_PVRTC4_UNORM_SRGB: - return eTF_PVRTC4; -#endif -#if defined(ANDROID) //|| defined(CRY_USE_METAL) - case DXGI_FORMAT_ASTC_4x4_TYPELESS: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_4x4_UNORM: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_4x4_UNORM_SRGB: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_5x4_TYPELESS: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x4_UNORM: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x4_UNORM_SRGB: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x5_TYPELESS: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_5x5_UNORM: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_5x5_UNORM_SRGB: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_6x5_TYPELESS: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x5_UNORM: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x5_UNORM_SRGB: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x6_TYPELESS: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_6x6_UNORM: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_6x6_UNORM_SRGB: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_8x5_TYPELESS: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x5_UNORM: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x5_UNORM_SRGB: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x6_TYPELESS: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x6_UNORM: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x6_UNORM_SRGB: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x8_TYPELESS: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_8x8_UNORM: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_8x8_UNORM_SRGB: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_10x5_TYPELESS: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x5_UNORM: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x5_UNORM_SRGB: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x6_TYPELESS: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x6_UNORM: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x6_UNORM_SRGB: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x8_TYPELESS: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x8_UNORM: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x8_UNORM_SRGB: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x10_TYPELESS: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_10x10_UNORM: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_10x10_UNORM_SRGB: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_12x10_TYPELESS: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x10_UNORM: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x10_UNORM_SRGB: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x12_TYPELESS: - return eTF_ASTC_12x12; - case DXGI_FORMAT_ASTC_12x12_UNORM: - return eTF_ASTC_12x12; - case DXGI_FORMAT_ASTC_12x12_UNORM_SRGB: - return eTF_ASTC_12x12; -#endif - // only available as hardware format under DX9 - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - return eTF_B8G8R8X8; - case DXGI_FORMAT_B8G8R8X8_UNORM: - return eTF_B8G8R8X8; - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return eTF_B8G8R8X8; - } -#endif - return eTF_Unknown; - } - else - { - return GetFormatByDesc(ddspf); - } - } - - inline const bool IsNormalMap(const ETEX_Format eTF) - { - if (eTF == eTF_BC5U || eTF == eTF_BC5S || eTF == eTF_CTX1 || eTF == eTF_EAC_RG11) - { - return true; - } - return false; - } - - inline const bool IsSigned(const ETEX_Format eTF) - { - if (eTF == eTF_BC4S || eTF == eTF_BC5S || eTF == eTF_BC6SH || eTF == eTF_R8S || eTF == eTF_R8G8S || eTF == eTF_R16G16S || eTF == eTF_R8G8B8A8S || eTF == eTF_R16G16B16A16S) - { - return true; - } - return false; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const CImageExtensionHelper::DDS_PIXELFORMAT& GetDescByFormat(const ETEX_Format eTF) - { - switch (eTF) - { - case eTF_BC1: - return DDSPF_DXT1; - case eTF_BC2: - return DDSPF_DXT3; - case eTF_BC3: - return DDSPF_DXT5; - case eTF_BC4U: - return DDSPF_3DCP; - case eTF_BC5U: - return DDSPF_3DC; - case eTF_CTX1: - return DDSPF_CTX1; - case eTF_R32F: - return DDSPF_R32F; - // case eTF_R32G32F: - // return DDSPF_G32R32F; - case eTF_R32G32B32A32F: - return DDSPF_A32B32G32R32F; - case eTF_R16F: - return DDSPF_R16F; - case eTF_R16G16F: - return DDSPF_G16R16F; - case eTF_R16G16B16A16F: - return DDSPF_A16B16G16R16F; - case eTF_R16: - return DDSPF_R16; - case eTF_R16G16: - return DDSPF_G16R16; - case eTF_R16G16B16A16: - return DDSPF_A16B16G16R16; - // case eTF_R16S: - // return DDSPF_U16; - case eTF_R16G16S: - return DDSPF_V16U16; - case eTF_R16G16B16A16S: - return DDSPF_Q16W16V16U16; - case eTF_B8G8R8: - case eTF_L8V8U8: - return DDSPF_R8G8B8; - case eTF_R8G8B8A8: - return DDSPF_A8B8G8R8; - case eTF_B8G8R8X8: - case eTF_L8V8U8X8: - return DDSPF_X8R8G8B8; - case eTF_B8G8R8A8: - return DDSPF_A8R8G8B8; - case eTF_B5G6R5: - return DDSPF_R5G6B5; - case eTF_A8: - return DDSPF_A8; - case eTF_L8: - return DDSPF_L8; - case eTF_A8L8: - return DDSPF_A8L8; - case eTF_EAC_R11: - return DDSPF_EAC_R11; - case eTF_EAC_RG11: - return DDSPF_EAC_RG11; - case eTF_ETC2: - return DDSPF_ETC2; - case eTF_ETC2A: - return DDSPF_ETC2A; - case eTF_PVRTC2: - return DDSPF_PVRTC2; - case eTF_PVRTC4: - return DDSPF_PVRTC4; - - case eTF_ASTC_4x4: - return DDSPF_ASTC_4x4; - case eTF_ASTC_5x4: - return DDSPF_ASTC_5x4; - case eTF_ASTC_5x5: - return DDSPF_ASTC_5x5; - case eTF_ASTC_6x5: - return DDSPF_ASTC_6x5; - case eTF_ASTC_6x6: - return DDSPF_ASTC_6x6; - case eTF_ASTC_8x5: - return DDSPF_ASTC_8x5; - case eTF_ASTC_8x6: - return DDSPF_ASTC_8x6; - case eTF_ASTC_8x8: - return DDSPF_ASTC_8x8; - case eTF_ASTC_10x5: - return DDSPF_ASTC_10x5; - case eTF_ASTC_10x6: - return DDSPF_ASTC_10x6; - case eTF_ASTC_10x8: - return DDSPF_ASTC_10x8; - case eTF_ASTC_10x10: - return DDSPF_ASTC_10x10; - case eTF_ASTC_12x10: - return DDSPF_ASTC_12x10; - case eTF_ASTC_12x12: - return DDSPF_ASTC_12x12; - default: - assert(0); - return DDSPF_A8B8G8R8; - } - } - - inline const CImageExtensionHelper::DDS_PIXELFORMAT& GetDescByFormat(DWORD& dxgifOut, const ETEX_Format eTF) - { - dxgifOut = 0; - - switch (eTF) - { -#if defined(CRY_DDS_DX10_SUPPORT) - case eTF_R8: - dxgifOut = DXGI_FORMAT_R8_UNORM; - return DDSPF_DX10; - case eTF_R8S: - dxgifOut = DXGI_FORMAT_R8_SNORM; - return DDSPF_DX10; - case eTF_R16: - dxgifOut = DXGI_FORMAT_R16_UNORM; - return DDSPF_DX10; - case eTF_R16F: - dxgifOut = DXGI_FORMAT_R16_FLOAT; - return DDSPF_DX10; - case eTF_R8G8: - dxgifOut = DXGI_FORMAT_R8G8_UNORM; - return DDSPF_DX10; - case eTF_R8G8S: - dxgifOut = DXGI_FORMAT_R8G8_SNORM; - return DDSPF_DX10; - case eTF_R16G16: - dxgifOut = DXGI_FORMAT_R16G16_UNORM; - return DDSPF_DX10; - case eTF_R11G11B10F: - dxgifOut = DXGI_FORMAT_R11G11B10_FLOAT; - return DDSPF_DX10; - case eTF_R10G10B10A2: - dxgifOut = DXGI_FORMAT_R10G10B10A2_UNORM; - return DDSPF_DX10; - case eTF_R16G16B16A16: - dxgifOut = DXGI_FORMAT_R16G16B16A16_UNORM; - return DDSPF_DX10; - case eTF_R16G16B16A16S: - dxgifOut = DXGI_FORMAT_R16G16B16A16_SNORM; - return DDSPF_DX10; - case eTF_R32G32B32A32F: - dxgifOut = DXGI_FORMAT_R32G32B32A32_FLOAT; - return DDSPF_DX10; - case eTF_R8G8B8A8S: - dxgifOut = DXGI_FORMAT_R8G8B8A8_SNORM; - return DDSPF_DX10; - - case eTF_BC4S: - dxgifOut = DXGI_FORMAT_BC4_SNORM; - return DDSPF_DX10; - case eTF_BC5S: - dxgifOut = DXGI_FORMAT_BC5_SNORM; - return DDSPF_DX10; - case eTF_BC6SH: - dxgifOut = DXGI_FORMAT_BC6H_SF16; - return DDSPF_DX10; - case eTF_BC6UH: - dxgifOut = DXGI_FORMAT_BC6H_UF16; - return DDSPF_DX10; - case eTF_BC7: - dxgifOut = DXGI_FORMAT_BC7_UNORM; - return DDSPF_DX10; - case eTF_R9G9B9E5: - dxgifOut = DXGI_FORMAT_R9G9B9E5_SHAREDEXP; - return DDSPF_DX10; -#endif - - default: - return GetDescByFormat(eTF); - } - } -}; - -namespace CImageExtensionHelper -{ - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf) - { - ETEX_Format nFormat = DDSFormats::GetFormatByDesc(ddspf); - return NameForTextureFormat(nFormat); - } - - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf, DWORD /*DXGI_FORMAT*/ dxgif) - { - ETEX_Format nFormat = DDSFormats::GetFormatByDesc(ddspf, dxgif); - return NameForTextureFormat(nFormat); - } -}; diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h b/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h deleted file mode 100644 index dae6f9cb2d..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H -#define CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H -#pragma once - -#include "CryString.h" -#include "TypeInfo_decl.h" -#include "ImageExtensionHelper.h" - -// Crytek specific image extensions -// -// usually added to the end of DDS files - - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_PIXELFORMAT) -STRUCT_VAR_INFO(dwSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwFourCC, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwRGBBitCount, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwRBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwGBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwBBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwABitMask, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_PIXELFORMAT) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_HEADER_DXT10) -STRUCT_VAR_INFO(dxgiFormat, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(resourceDimension, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(miscFlag, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(arraySize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(reserved, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_HEADER_DXT10) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_HEADER) -STRUCT_VAR_INFO(dwSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwHeaderFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwHeight, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwWidth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwPitchOrLinearSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwDepth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwMipMapCount, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwAlphaBitDepth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwReserved1, TYPE_ARRAY(10, TYPE_INFO(DWORD))) -STRUCT_VAR_INFO(ddspf, TYPE_INFO(CImageExtensionHelper::DDS_PIXELFORMAT)) -STRUCT_VAR_INFO(dwSurfaceFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwCubemapFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(bNumPersistentMips, TYPE_INFO(BYTE)) -STRUCT_VAR_INFO(bReserved2, TYPE_ARRAY(7, TYPE_INFO(BYTE))) -STRUCT_VAR_INFO(dwTextureStage, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_HEADER) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_FILE_DESC) -STRUCT_VAR_INFO(dwMagic, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(header, TYPE_INFO(CImageExtensionHelper::DDS_HEADER)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_FILE_DESC) - -#endif // CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H diff --git a/Code/CryEngine/CryCommon/Mocks/IRendererMock.h b/Code/CryEngine/CryCommon/Mocks/IRendererMock.h index 74d072c48c..a3fae96310 100644 --- a/Code/CryEngine/CryCommon/Mocks/IRendererMock.h +++ b/Code/CryEngine/CryCommon/Mocks/IRendererMock.h @@ -330,8 +330,6 @@ public: ITexture * (const char* nameTex)); MOCK_METHOD1(EF_LoadLightmap, int(const char* name)); - MOCK_METHOD3(EF_RenderEnvironmentCubeHDR, - bool(int size, Vec3 & Pos, TArray&vecData)); MOCK_METHOD1(EF_StartEf, void(const SRenderingPassInfo& passInfo)); MOCK_METHOD3(EF_GetObjData, @@ -360,8 +358,6 @@ public: uint32(eDeferredLightType)); MOCK_METHOD0(EF_ClearDeferredLightsList, void()); - MOCK_METHOD2(EF_GetDeferredLights, - TArray*(const SRenderingPassInfo&, const eDeferredLightType)); MOCK_METHOD1(EF_AddDeferredClipVolume, uint8(const IClipVolume * pClipVolume)); MOCK_METHOD2(EF_SetDeferredClipVolumeBlendData, diff --git a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h index cfe150c1df..acd7492398 100644 --- a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h +++ b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h @@ -37,8 +37,6 @@ public: bool()); MOCK_METHOD0(RenderStatistics, void()); - MOCK_METHOD0(GetUsedMemory, - uint32()); MOCK_METHOD0(GetUserName, const char*()); MOCK_METHOD0(GetCPUFlags, @@ -88,8 +86,6 @@ public: INameTable * ()); MOCK_METHOD0(GetIValidator, IValidator * ()); - MOCK_METHOD0(GetStreamEngine, - IStreamEngine * ()); MOCK_METHOD0(GetICmdLine, ICmdLine * ()); MOCK_METHOD0(GetILog, @@ -98,8 +94,6 @@ public: AZ::IO::IArchive * ()); MOCK_METHOD0(GetICryFont, ICryFont * ()); - MOCK_METHOD0(GetIMemoryManager, - IMemoryManager * ()); MOCK_METHOD0(GetIMovieSystem, IMovieSystem * ()); MOCK_METHOD0(GetIAudioSystem, @@ -108,20 +102,12 @@ public: ::IConsole * ()); MOCK_METHOD0(GetIRemoteConsole, IRemoteConsole * ()); - MOCK_METHOD0(GetIResourceManager, - IResourceManager * ()); MOCK_METHOD0(GetIProfilingSystem, IProfilingSystem * ()); MOCK_METHOD0(GetISystemEventDispatcher, ISystemEventDispatcher * ()); MOCK_METHOD0(GetITimer, ITimer * ()); - MOCK_METHOD2(DebugStats, - void(bool checkpoint, bool leaks)); - MOCK_METHOD0(DumpWinHeaps, - void()); - MOCK_METHOD1(DumpMMStats, - int(bool log)); MOCK_METHOD1(SetForceNonDevMode, void(bool bValue)); MOCK_CONST_METHOD0(GetForceNonDevMode, @@ -237,8 +223,6 @@ public: MOCK_METHOD0(SteamInit, bool()); - MOCK_CONST_METHOD0(GetImageHandler, - const IImageHandler * ()); MOCK_METHOD0(GetRootWindowMessageHandler, void*()); MOCK_METHOD1(RegisterWindowMessageHandler, diff --git a/Code/CryEngine/CryCommon/PoolAllocator.h b/Code/CryEngine/CryCommon/PoolAllocator.h index d6037289a7..110d25153e 100644 --- a/Code/CryEngine/CryCommon/PoolAllocator.h +++ b/Code/CryEngine/CryCommon/PoolAllocator.h @@ -36,9 +36,6 @@ // require a pointer to the bucket be stored, whereas now no memory is used // while the block is allocated. // -// This allocator is suitable for use with STL lists - see STLPoolAllocator -// for an STL-compatible interface. -// // The class can optionally support multi-threading, using the second // template parameter. By default it is multithread-safe. // See Synchronization.h. diff --git a/Code/CryEngine/CryCommon/STLGlobalAllocator.h b/Code/CryEngine/CryCommon/STLGlobalAllocator.h deleted file mode 100644 index 2067c9b2e9..0000000000 --- a/Code/CryEngine/CryCommon/STLGlobalAllocator.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for an std::allocator using the global heap. -//--------------------------------------------------------------------------- - -#include -#include - -#include "CryMemoryManager.h" - -#include -#include -#include - -struct CryLegacySTLAllocatorDescriptor - : public AZ::HphaSchema::Descriptor -{ - CryLegacySTLAllocatorDescriptor() - { - m_systemChunkSize = 4 * 1024 * 1024; // Ask the OS for 4MB at a time - } -}; - -class CryLegacySTLAllocator - : public AZ::SimpleSchemaAllocator -{ -public: - AZ_TYPE_INFO(CryLegacySTLAllocator, "{87EE21F1-8215-4979-B493-AF13D8D91DAD}"); - using Descriptor = CryLegacySTLAllocatorDescriptor; - using Base = AZ::SimpleSchemaAllocator; - CryLegacySTLAllocator() - : Base("CryLegacySTLAllocator", "Allocator used to dodge limits on static init time allocations") - { - } -}; - -// Specialize for the CryLegacySTLAllocator to provide one per module that does not use the -// environment for its storage, since this thing is designed to get around the lack -// of static allocators -namespace AZ -{ - template <> - class AllocatorInstance : public Internal::AllocatorInstanceBase> - { - }; -} - - -class ICrySizer; -namespace stl -{ - template - class STLGlobalAllocator - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef STLGlobalAllocator other; - }; - - STLGlobalAllocator() throw() - { - } - - STLGlobalAllocator(const STLGlobalAllocator&) throw() - { - } - - template - STLGlobalAllocator(const STLGlobalAllocator&) throw() - { - } - - ~STLGlobalAllocator() throw() - { - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate(size_type n = 1, const void* hint = 0) - { - (void)hint; - pointer ret = static_cast(AZ::AllocatorInstance::Get().Allocate(n * sizeof(T), 0)); - return ret; - } - - void deallocate(pointer p, [[maybe_unused]] size_type n = 1) - { - AZ::AllocatorInstance::Get().DeAllocate(p); - } - - size_type max_size() const throw() - { - return INT_MAX; - } -#if !defined(_LIBCPP_VERSION) - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } -#endif // !_LIBCPP_VERSION - void destroy(pointer p) - { - p->~T(); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const STLGlobalAllocator&) const { return true; } - bool operator!=(const STLGlobalAllocator&) const { return false; } - - static void GetMemoryUsage(ICrySizer* pSizer) - { - } - }; - - template <> - class STLGlobalAllocator - { - public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template - struct rebind - { - typedef STLGlobalAllocator other; - }; - }; -} - -#endif // CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/STLPoolAllocator.h b/Code/CryEngine/CryCommon/STLPoolAllocator.h deleted file mode 100644 index 564720bc02..0000000000 --- a/Code/CryEngine/CryCommon/STLPoolAllocator.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for the pool allocator (see PoolAllocator.h). -// -// This class is suitable for use as an allocator for STL lists. Note it will -// not work with vectors, since it allocates fixed-size blocks, while vectors -// allocate elements in variable-sized contiguous chunks. -// -// To create a list of type UserDataType using this allocator, use the -// following syntax: -// -// std::list > myList; -//--------------------------------------------------------------------------- - -#include "PoolAllocator.h" -#include "MetaUtils.h" -#include -#include - -namespace stl -{ - namespace STLPoolAllocatorHelper - { - inline void destruct(char*) {} - inline void destruct(wchar_t*) {} - template - inline void destruct(T* t) {t->~T(); } - } - - template - struct STLPoolAllocatorStatic - { - // Non-freeing stl pool allocators should just go on the global heap - only if they've been explicitly - // set to cleanup should they go on the default heap. - typedef SizePoolAllocator< - HeapAllocator< - L, - typename metautils::select::type> - > AllocatorType; - - static AllocatorType* GetOrCreateAllocator() - { - if (allocator) - { - return allocator; - } - - allocator = new AllocatorType(S, A, FHeap().FreeWhenEmpty(FreeWhenEmpty)); - return allocator; - } - - static AllocatorType* allocator; - }; - - template - struct STLPoolAllocatorKungFu - : public STLPoolAllocatorStatic - { - }; - - template - class STLPoolAllocator - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef STLPoolAllocator other; - }; - - STLPoolAllocator() throw() - { - } - - STLPoolAllocator(const STLPoolAllocator&) throw() - { - } - - template - STLPoolAllocator(const STLPoolAllocator&) throw() - { - } - - ~STLPoolAllocator() throw() - { - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate([[maybe_unused]] size_type n = 1, [[maybe_unused]] const void* hint = 0) - { - assert(n == 1); - typename STLPoolAllocatorKungFu::AllocatorType * allocator = STLPoolAllocatorKungFu::GetOrCreateAllocator(); - return static_cast(allocator->Allocate()); - } - - void deallocate(pointer p, [[maybe_unused]] size_type n = 1) - { - assert(n == 1); - typename STLPoolAllocatorKungFu::AllocatorType * allocator = STLPoolAllocatorKungFu::allocator; - allocator->Deallocate(p); - } - - size_type max_size() const throw() - { - return INT_MAX; - } -#ifndef _LIBCPP_VERSION - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } -#endif // !(_LIBCPP_VERSION) - void destroy(pointer p) - { - STLPoolAllocatorHelper::destruct(p); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const STLPoolAllocator&) {return true; } - bool operator!=(const STLPoolAllocator&) {return false; } - - static void GetMemoryUsage(ICrySizer* pSizer) - { - pSizer->AddObject(STLPoolAllocatorKungFu::allocator); - } - }; - - template - class STLPoolAllocatorNoMT - : public STLPoolAllocator - { - }; - - template <> - class STLPoolAllocator - { - public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template - struct rebind - { - typedef STLPoolAllocator other; - }; - }; - - template - typename STLPoolAllocatorStatic::AllocatorType * STLPoolAllocatorStatic::allocator; -} - - - -#endif // CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h b/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h deleted file mode 100644 index 28fff38917..0000000000 --- a/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H -#define CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for the pool allocator (see PoolAllocator.h). -// -// this class acts like STLPoolAllocator, but it is also usable for vectors -// which means that it can be used as a more efficient allocator for many -// implementations of hash_map (typically this uses internally a vector and -// a list with the same allocator) -//--------------------------------------------------------------------------- - -#include "STLPoolAllocator.h" - -namespace stl -{ - template - struct STLPoolAllocator_ManyElemsStatic - { - static PoolAllocator* allocator; - }; - - template - class STLPoolAllocator_ManyElems - : public STLPoolAllocator - { - typedef STLPoolAllocator Super; - typedef PoolAllocator LargeAllocator; - - public: - typedef typename Super::pointer pointer; - typedef typename Super::pointer pointer_type; - typedef typename Super::size_type size_type; - typedef AZStd::false_type allow_memory_leaks; - - template - struct rebind - { - typedef STLPoolAllocator_ManyElems other; - }; - - STLPoolAllocator_ManyElems() throw() - { - } - - template - STLPoolAllocator_ManyElems(const STLPoolAllocator_ManyElems&) throw() - { - } - - pointer allocate(size_type n = 1, const void* hint = 0) - { - if (n == 1) - { - return Super::allocate(n, hint); - } - else if (n * sizeof(T) <= LargeAllocationSizeThreshold) - { - if (!STLPoolAllocator_ManyElemsStatic::allocator) - { - STLPoolAllocator_ManyElemsStatic::allocator = new LargeAllocator(); - } - return static_cast(STLPoolAllocator_ManyElemsStatic::allocator->Allocate()); - } - else - { - return static_cast(CryModuleMalloc(n * sizeof(T))); - } - } - - void deallocate(pointer p, size_type n = 1) - { - if (n == 1) - { - Super::deallocate(p); - } - else if (n * sizeof(T) <= LargeAllocationSizeThreshold) - { - STLPoolAllocator_ManyElemsStatic::allocator->Deallocate(p); - } - else - { - CryModuleFree(p); - } - } - }; - - template - PoolAllocator* STLPoolAllocator_ManyElemsStatic::allocator; -} - -#endif // CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H diff --git a/Code/CryEngine/CryCommon/StlUtils.h b/Code/CryEngine/CryCommon/StlUtils.h index df88a14196..9d6090502f 100644 --- a/Code/CryEngine/CryCommon/StlUtils.h +++ b/Code/CryEngine/CryCommon/StlUtils.h @@ -27,7 +27,6 @@ #endif #define STATIC_ASSERT(condition, errMessage) static_assert(condition, errMessage) -#include "STLGlobalAllocator.h" #include #include diff --git a/Code/CryEngine/CryCommon/Tarray.h b/Code/CryEngine/CryCommon/Tarray.h index 035a4b3e0e..32bb249f7c 100644 --- a/Code/CryEngine/CryCommon/Tarray.h +++ b/Code/CryEngine/CryCommon/Tarray.h @@ -19,7 +19,6 @@ #include #include #include -#include #ifndef CLAMP #define CLAMP(X, mn, mx) ((X) < (mn) ? (mn) : ((X) < (mx) ? (X) : (mx))) @@ -58,400 +57,4 @@ } #endif - -// General array class. -// Can refer to a general (unowned) region of memory (m_nAllocatedCount = 0). -// Can allocate, grow, and shrink an array. -// Does not deep copy. - -template -class TArray -{ -protected: - T* m_pElements; - unsigned int m_nCount; - unsigned int m_nAllocatedCount; - -public: - typedef T value_type; - - // Empty array. - TArray() - { - ClearArr(); - } - - // Create a new array, delete it on destruction. - TArray(int Count) - { - m_nCount = Count; - m_nAllocatedCount = Count; - m_pElements = NULL; - Realloc(0); - } - TArray(int Use, int Max) - { - m_nCount = Use; - m_nAllocatedCount = Max; - m_pElements = NULL; - Realloc(0); - } - - // Reference pre-existing memory. Does not delete it. - TArray(T* Elems, int Count) - { - m_pElements = Elems; - m_nCount = Count; - m_nAllocatedCount = 0; - } - ~TArray() - { - Free(); - } - - void Free() - { - m_nCount = 0; - if (m_nAllocatedCount && AZ::AllocatorInstance::IsReady()) - { - AZ::AllocatorInstance::Get().DeAllocate(m_pElements); - } - m_nAllocatedCount = 0; - m_pElements = NULL; - } - - void Create (int Count) - { - m_pElements = NULL; - m_nCount = Count; - m_nAllocatedCount = Count; - Realloc(0); - Clear(); - } - void Copy (const TArray& src) - { - m_pElements = NULL; - m_nCount = m_nAllocatedCount = src.Num(); - Realloc(0); - PREFAST_ASSUME(m_pElements); // realloc asserts if it fails - so this is safe - memcpy(m_pElements, src.m_pElements, src.Num() * sizeof(T)); - } - void Copy (const T* src, unsigned int numElems) - { - int nOffs = m_nCount; - Grow(numElems); - memcpy(&m_pElements[nOffs], src, numElems * sizeof(T)); - } - void Align4Copy (const T* src, unsigned int& numElems) - { - int nOffs = m_nCount; - Grow((numElems + 3) & ~3); - memcpy(&m_pElements[nOffs], src, numElems * sizeof(T)); - if (numElems & 3) - { - int nSet = 4 - (numElems & 3); - memset(&m_pElements[nOffs + numElems], 0, nSet); - numElems += nSet; - } - } - - void Realloc([[maybe_unused]] int nOldAllocatedCount) - { - if (!m_nAllocatedCount) - { - m_pElements = NULL; - } - else - { - m_pElements = static_cast(AZ::AllocatorInstance::Get().ReAllocate(m_pElements, m_nAllocatedCount * sizeof(T), alignof(T))); - assert (m_pElements); - } - } - - void Remove(unsigned int Index, unsigned int Count = 1) - { - if (Count) - { - memmove(m_pElements + Index, m_pElements + (Index + Count), sizeof(T) * (m_nCount - Index - Count)); - m_nCount -= Count; - } - } - - void Shrink() - { - if (m_nCount == 0 || m_nAllocatedCount == 0) - { - return; - } - assert(m_nAllocatedCount >= m_nCount); - if (m_nAllocatedCount != m_nCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount; - Realloc(nOldAllocatedCount); - } - } - - void _Remove(unsigned int Index, unsigned int Count) - { - assert (Index >= 0); - assert (Index <= m_nCount); - assert ((Index + Count) <= m_nCount); - - Remove(Index, Count); - } - - unsigned int Num(void) const { return m_nCount; } - unsigned int Capacity(void) const { return m_nAllocatedCount; } - unsigned int MemSize(void) const { return m_nCount * sizeof(T); } - void SetNum(unsigned int n) { m_nCount = m_nAllocatedCount = n; } - void SetUse(unsigned int n) { m_nCount = n; } - void Alloc(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; m_nAllocatedCount = n; Realloc(nOldAllocatedCount); } - void Reserve(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; SetNum(n); Realloc(nOldAllocatedCount); Clear(); } - void ReserveNoClear(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; SetNum(n); Realloc(nOldAllocatedCount); } - void Expand(unsigned int n) - { - if (n > m_nAllocatedCount) - { - ReserveNew(n); - } - } - void ReserveNew(unsigned int n) - { - int num = m_nCount; - if (n > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = n * 2; - Realloc(nOldAllocatedCount); - } - m_nCount = n; - memset(&m_pElements[num], 0, sizeof(T) * (m_nCount - num)); - } - T* Grow(unsigned int n) - { - int nStart = m_nCount; - m_nCount += n; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount * 2; - Realloc(nOldAllocatedCount); - } - return &m_pElements[nStart]; - } - T* GrowReset(unsigned int n) - { - int num = m_nAllocatedCount; - T* Obj = AddIndex(n); - if (num != m_nAllocatedCount) - { - memset(&m_pElements[num], 0, sizeof(T) * (m_nAllocatedCount - num)); - } - return Obj; - } - - unsigned int* GetNumAddr(void) { return &m_nCount; } - T** GetDataAddr(void) { return &m_pElements; } - - T* Data(void) const { return m_pElements; } - T& Get(unsigned int id) const { return m_pElements[id]; } - - - void Assign(TArray& fa) - { - m_pElements = fa.m_pElements; - m_nCount = fa.m_nCount; - m_nAllocatedCount = fa.m_nAllocatedCount; - } - - - /*const TArray operator=(TArray fa) const - { - TArray t = TArray(fa.m_nCount,fa.m_nAllocatedCount); - for ( int i=0; i 0); return *m_pElements; } - - TArray operator()(unsigned int Start) - { - assert(Start < m_nCount); - return TArray(m_pElements + Start, m_nCount - Start); - } - TArray operator()(unsigned int Start, unsigned int Count) - { - assert(Start < m_nCount); - assert(Start + Count <= m_nCount); - return TArray(m_pElements + Start, Count); - } - - // For simple types only - TArray(const TArray& cTA) - { - m_pElements = NULL; - m_nCount = m_nAllocatedCount = cTA.Num(); - Realloc(0); - if (m_pElements) - { - memcpy(m_pElements, &cTA[0], m_nCount * sizeof(T)); - } - /*for (unsigned int i=0; i m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = nNewCount + (nNewCount >> 1) + 10; - Realloc(nOldAllocatedCount); - } - - m_nCount = nNewCount; - return &m_pElements[nIndex]; - } - - T& Insert(unsigned int nIndex, unsigned int inc = 1) - { - m_nCount += inc; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount + (m_nCount >> 1) + 32; - Realloc(nOldAllocatedCount); - } - memmove(&m_pElements[nIndex + inc], &m_pElements[nIndex], (m_nCount - inc - nIndex) * sizeof(T)); - - return m_pElements[nIndex]; - } - - void AddIndexNoCache(unsigned int inc) - { - m_nCount += inc; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount; - Realloc(nOldAllocatedCount); - } - } - - void Add(const T& elem){AddElem(elem); } - void AddElem(const T& elem) - { - unsigned int m = m_nCount; - AddIndex(1); - m_pElements[m] = elem; - } - void AddElemNoCache(const T& elem) - { - unsigned int m = m_nCount; - AddIndexNoCache(1); - m_pElements[m] = elem; - } - - int Find(const T& p) - { - for (unsigned int i = 0; i < m_nCount; i++) - { - if (p == (*this)[i]) - { - return i; - } - } - return -1; - } - - void Delete(unsigned int n){DelElem(n); } - void DelElem(unsigned int n) - { - // memset(&m_pElements[n],0,sizeof(T)); - _Remove(n, 1); - } - - // Standard compliance interface - // - // This is for those who don't want to learn the non standard and - // thus not very convenient interface of TArray, but are unlucky - // enough not to be able to avoid using it. - void clear(){Free(); } - void resize(unsigned int nSize) { reserve(nSize); m_nCount = nSize; } - void reserve(unsigned int nSize) - { - if (nSize > m_nAllocatedCount) - { - Alloc(nSize); - } - } - unsigned size() const {return m_nCount; } - unsigned capacity() const {return m_nAllocatedCount; } - bool empty() const {return size() == 0; } - void push_back (const T& rSample) {Add(rSample); } - void pop_back () {m_nCount--; } - void erase (T* pElem) - { - int n = int(pElem - m_pElements); - assert(n >= 0 && n < m_nCount); - _Remove(n, 1); - } - T* begin() {return m_pElements; } - T* end() {return m_pElements + m_nCount; } - T last() {return m_pElements[m_nCount - 1]; } - const T* begin() const {return m_pElements; } - const T* end() const {return m_pElements + m_nCount; } - - int GetMemoryUsage() const { return (int)(m_nAllocatedCount * sizeof(T)); } -}; - -template -inline void Exchange(T& X, T& Y) -{ - const T Tmp = X; - X = Y; - Y = Tmp; -} - #endif // CRYINCLUDE_CRYCOMMON_TARRAY_H diff --git a/Code/CryEngine/CryCommon/crycommon_files.cmake b/Code/CryEngine/CryCommon/crycommon_files.cmake index dff4ca66e7..47e57633b4 100644 --- a/Code/CryEngine/CryCommon/crycommon_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_files.cmake @@ -12,7 +12,6 @@ set(FILES QTangent.h CryCommon.cpp - Allocator.h FinalizingSpline.h IAudioInterfacesCommonData.h IAudioSystem.h @@ -26,10 +25,8 @@ set(FILES IFunctorBase.h IFuncVariable.h IGem.h - IGeneralMemoryHeap.h IGeomCache.h IImage.h - IImageHandler.h IIndexedMesh.h IIndexedMesh_info.cpp ILevelSystem.h @@ -39,7 +36,6 @@ set(FILES ILog.h ILZ4Decompressor.h IMaterial.h - IMemory.h IMeshBaking.h IMiniLog.h IMovieSystem.h @@ -51,8 +47,6 @@ set(FILES IRenderAuxGeom.h IRenderer.h IRenderMesh.h - IResourceCollector.h - IResourceManager.h ISerialize.h IShader.h IShader_info.h @@ -60,8 +54,6 @@ set(FILES IStatObj.h StatObjBus.h IStereoRenderer.h - IStreamEngine.h - IStreamEngineDefs.h ISurfaceType.h ISystem.h ITextModeConsole.h @@ -85,10 +77,8 @@ set(FILES IObjManager.h INavigationSystem.h IMNM.h - AzDXGIFormat.h SFunctor.h FunctorBaseFunction.h - CustomMemoryHeap.h FunctorBaseMember.h stridedptr.h Options.h @@ -102,31 +92,21 @@ set(FILES CryTypeInfo.cpp BaseTypes.h CompileTimeAssert.h - CryThreadSafeWorkerContainer.h - CryThreadSafeRendererContainer.h intrusive_list.hpp MemoryAccess.h - Algorithm.h AnimKey.h BitFiddling.h - CGFContent.h - CGFContent_info.cpp Common_TypeInfo.cpp - CountedValue.h - CrtDebugStats.h CryArray.h CryArray2d.h CryAssert.h CryCrc32.h CryCustomTypes.h CryFile.h - CryFixedArray.h CryFixedString.h CryHeaders.h CryHeaders_info.cpp CryListenerSet.h - CryMemoryAllocator.h - CryMemoryManager.h CryLegacyAllocator.h CryName.h CryPath.h @@ -145,9 +125,6 @@ set(FILES HashGrid.h HeapAllocator.h HeapContainer.h - ImageExtensionHelper.cpp - ImageExtensionHelper.h - ImageExtensionHelper_info.h InplaceFactory.h LegacyAllocator.h MetaUtils.h @@ -172,8 +149,6 @@ set(FILES SmartPointersHelpers.h smartptr.h StackContainer.h - STLGlobalAllocator.h - STLPoolAllocator.h StlUtils.h StringUtils.h Synchronization.h @@ -203,7 +178,6 @@ set(FILES Cry_Matrix44.h Cry_MatrixDiag.h Cry_Vector4.h - AABBSV.h Cry_Camera.h Cry_Color.h Cry_Geo.h @@ -224,7 +198,6 @@ set(FILES Cry_HWVector3.h AndroidSpecific.h AppleSpecific.h - Console_std.h CryAssert_Android.h CryAssert_impl.h CryAssert_iOS.h @@ -232,7 +205,6 @@ set(FILES CryAssert_Mac.h CryLibrary.cpp CryLibrary.h - CryMemoryManager_impl.h CryThread_dummy.h CryThread_pthreads.h CryThread_windows.h diff --git a/Code/CryEngine/CryCommon/platform.h b/Code/CryEngine/CryCommon/platform.h index f7361db11d..df8fb125b2 100644 --- a/Code/CryEngine/CryCommon/platform.h +++ b/Code/CryEngine/CryCommon/platform.h @@ -479,15 +479,7 @@ ILINE DestinationType alias_cast(SourceType pPtr) return conv_union.pDst; } -////////////////////////////////////////////////////////////////////////// - -#include "CryMemoryManager.h" - -// Memory manager breaks strdup -// Use something higher level, like CryString - #undef strdup - #define strdup dont_use_strdup - +#include "CryLegacyAllocator.h" ////////////////////////////////////////////////////////////////////////// #ifndef DEPRECATED diff --git a/Code/CryEngine/CryCommon/platform_impl.cpp b/Code/CryEngine/CryCommon/platform_impl.cpp index 885ea2984d..1d784ed8a0 100644 --- a/Code/CryEngine/CryCommon/platform_impl.cpp +++ b/Code/CryEngine/CryCommon/platform_impl.cpp @@ -20,6 +20,7 @@ #include #include +#include #include // Section dictionary @@ -194,11 +195,6 @@ void __stl_debug_message(const char* format_str, ...) #include #endif -// If we use cry memory manager this should be also included in every module. -#if defined(USING_CRY_MEMORY_MANAGER) -#include -#endif - #if defined(APPLE) || defined(LINUX) #include "CryAssert_impl.h" #endif diff --git a/Code/CryEngine/CrySystem/AsyncPakManager.cpp b/Code/CryEngine/CrySystem/AsyncPakManager.cpp deleted file mode 100644 index 40928715d8..0000000000 --- a/Code/CryEngine/CrySystem/AsyncPakManager.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manage async pak files - - -#include "CrySystem_precompiled.h" -#include "AsyncPakManager.h" -#include "System.h" -#include "IStreamEngine.h" -#include -#include -#include "ResourceManager.h" - -#define MEGA_BYTE 1024* 1024 - -////////////////////////////////////////////////////////////////////////// - -string& CAsyncPakManager::SAsyncPak::GetStatus(string& status) const -{ - switch (eState) - { - case STATE_UNLOADED: - status = "Unloaded"; - break; - case STATE_REQUESTED: - status = "Requested"; - break; - case STATE_REQUESTUNLOAD: - status = "RequestUnload"; - break; - case STATE_LOADED: - status = "Loaded"; - break; - default: - status = "Unknown"; - break; - } - - return status; -} - -////////////////////////////////////////////////////////////////////////// - -CAsyncPakManager::CAsyncPakManager() -{ - m_nTotalOpenLayerPakSize = 0; - m_bRequestLayerUpdate = false; -} - -CAsyncPakManager::~CAsyncPakManager() -{ - Clear(); -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::Clear() -{ - //float startTime = gEnv->pTimer->GetAsyncCurTime(); - - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - if (layerPak.bStreaming) - { - // wait until finished - layerPak.pReadStream->Abort(); - } - - ReleaseData(&layerPak); - } - m_paks.clear(); - m_bRequestLayerUpdate = false; - - assert(m_nTotalOpenLayerPakSize == 0); - m_nTotalOpenLayerPakSize = 0; - - //printf("CAsyncPakManager::Clear() %0.4f secs\n", gEnv->pTimer->GetAsyncCurTime() - startTime); -} - -void CAsyncPakManager::UnloadLevelLoadPaks() -{ - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - - if (layerPak.eLifeTime == SAsyncPak::LIFETIME_LOAD_ONLY) - { - if (layerPak.bStreaming) - { - // wait until finished - layerPak.pReadStream->Abort(); - } - - ReleaseData(&layerPak); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::ParseLayerPaks(const string& levelCachePath) -{ - string layerPath = levelCachePath + "/"; // "/layers/"; - string search = layerPath + "*"; - auto pPak = gEnv->pCryPak; - - - // allow this find first to actually touch the file system - AZ::IO::ArchiveFileIterator fileIterator= pPak->FindFirst(search.c_str(), 0, true); - - if (fileIterator) - { - do - { - if ((fileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory || fileIterator.m_filename == "." || fileIterator.m_filename == "..") - { - continue; - } - - string pakName(fileIterator.m_filename.data(), fileIterator.m_filename.size()); - size_t findPos = pakName.find_last_of('.'); - if (findPos == string::npos) - { - continue; - } - - string extension = pakName.substr(findPos + 1, pakName.size()); - if (extension != "pak") - { - continue; - } - - SAsyncPak layerPak; - layerPak.layername = pakName.substr(0, findPos); - layerPak.filename = layerPath + pakName; - layerPak.nSize = pPak->FGetSize(layerPak.filename.c_str(), true); // allow to go to disc for this access - layerPak.bClosePakOnRelease = true; - - m_paks[layerPak.layername] = layerPak; - } while (fileIterator = pPak->FindNext(fileIterator)); - - pPak->FindClose(fileIterator); - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StartStreaming(SAsyncPak* pLayerPak) -{ - StreamReadParams params; - params.dwUserData = (DWORD_PTR) pLayerPak; - params.nSize = 0; - params.pBuffer = NULL; - params.nFlags = IStreamEngine::FLAGS_FILE_ON_DISK; - params.ePriority = estpIdle; - - pLayerPak->pReadStream = gEnv->pSystem->GetStreamEngine()->StartRead(eStreamTaskTypePak, pLayerPak->filename.c_str(), this, ¶ms); - - if (pLayerPak->pReadStream) - { - pLayerPak->bStreaming = true; - } - else - { - pLayerPak->eState = SAsyncPak::STATE_UNLOADED; - pLayerPak->pData.reset(); - } -} - -void CAsyncPakManager::ReleaseData(SAsyncPak* pLayerPak) -{ - if (pLayerPak->eState == SAsyncPak::STATE_LOADED) - { - if (pLayerPak->bClosePakOnRelease) - { - gEnv->pCryPak->ClosePack(pLayerPak->filename.c_str(), 0); - //printf("Unload pak from mem: %s\n", pLayerPak->filename.c_str()); - } - else - { - gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_Unload); - //printf("Close pak: %s\n", pLayerPak->filename.c_str()); - } - - m_nTotalOpenLayerPakSize -= pLayerPak->nSize; - } - - if (pLayerPak->pData) - { - assert(pLayerPak->pData->use_count() == 1); - } - - assert((!pLayerPak->pData) || (pLayerPak->pData && pLayerPak->pData->use_count() == 1)); - pLayerPak->pData.reset(); - pLayerPak->eState = SAsyncPak::STATE_UNLOADED; - - m_bRequestLayerUpdate = true; -} - -////////////////////////////////////////////////////////////////////////// - -bool CAsyncPakManager::LoadLayerPak(const char* sLayerName) -{ - // only load layer paks from valid files - TPakMap::iterator findResult = m_paks.find(sLayerName); - if (findResult != m_paks.end()) - { - return LoadPak(findResult->second); - } - - return false; -} - - -bool CAsyncPakManager::LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) -{ - //check if pak reference exists - TPakMap::iterator findResult = m_paks.find(pPath); - if (findResult != m_paks.end()) - { - return LoadPak(findResult->second); - } - else - { - char szFullPathBuf[AZ::IO::IArchive::MaxPath]; - const char* szFullPath = gEnv->pCryPak->AdjustFileName(pPath, szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FLAGS_PATH_REAL); - - // Check if the pak file actually exists before trying to load - if (!gEnv->pCryPak->IsFileExist(szFullPath, AZ::IO::IArchive::eFileLocation_Any)) - { - // Cached file does not exist - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Level cache pak file %s does not exist", szFullPath); - return false; - } - - SAsyncPak layerPak; - layerPak.layername = pPath; - layerPak.filename = szFullPathBuf; - layerPak.nSize = 0; - layerPak.eLifeTime = bLevelLoadOnly ? SAsyncPak::LIFETIME_LOAD_ONLY : SAsyncPak::LIFETIME_LEVEL_COMPLETE; - - m_paks[layerPak.layername] = layerPak; - - return LoadPak(m_paks[layerPak.layername]); - } - return false; -} - -bool CAsyncPakManager::LoadPak(SAsyncPak& layerPak) -{ - layerPak.nRequestCount++; - if (layerPak.eState == SAsyncPak::STATE_LOADED || layerPak.bStreaming || - layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - return true; - } - - layerPak.eState = SAsyncPak::STATE_REQUESTED; - - //printf("Streaming level pak: %s\n", layerPak.layername.c_str()); - - StartStreaming(&layerPak); - - return false; -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::UnloadLayerPak(const char* sLayerName) -{ - TPakMap::iterator findResult = m_paks.find(sLayerName); - if (findResult == m_paks.end()) - { - return; - } - - SAsyncPak& layerPak = findResult->second; - layerPak.nRequestCount--; - assert(layerPak.nRequestCount >= 0); - if (layerPak.nRequestCount > 0) - { - return; - } - - if (layerPak.bStreaming) - { - if (layerPak.pReadStream) - { - layerPak.pReadStream->Abort(); - } - layerPak.eState = SAsyncPak::STATE_REQUESTUNLOAD; - return; - } - - if (layerPak.eState == SAsyncPak::STATE_LOADED) - { - ReleaseData(&layerPak); - m_bRequestLayerUpdate = true; - } - - if (layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - layerPak.eState = SAsyncPak::STATE_UNLOADED; - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::GetLayerPakStats( - SLayerPakStats& stats, bool bCollectAllStats) const -{ - stats.m_MaxSize = (g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE); - stats.m_UsedSize = m_nTotalOpenLayerPakSize; - - for (TPakMap::const_iterator it = m_paks.begin(); it != m_paks.end(); ++it) - { - const SAsyncPak& layerPak = it->second; - if (bCollectAllStats || layerPak.eState != SAsyncPak::STATE_UNLOADED) - { - SLayerPakStats::SEntry entry; - entry.name = it->first; - entry.nSize = layerPak.nSize; - entry.bStreaming = layerPak.bStreaming; - layerPak.GetStatus(entry.status); - - stats.m_entries.push_back(entry); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StreamAsyncOnComplete( - IReadStream* pStream, unsigned nError) -{ - if (nError != 0) - { - return; - } - - SAsyncPak* pLayerPak = (SAsyncPak*) pStream->GetUserData(); - - //Check is pak is already open, if so, just assign mem - if (gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_GPU, pLayerPak->pData)) - { - pLayerPak->bPakAlreadyOpen = true; - } - else - { - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, - &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - if (usePrefabSystemForLevels) - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL); - } - else - { - // - // ugly hack - depending on the pak file pak may need special root info / open flags - // - if (pLayerPak->layername.find("level.pak") != string::npos) - { - gEnv->pCryPak->OpenPack( - {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL); - } - else if (pLayerPak->layername.find("levelshadercache.pak") != string::npos) - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_PATH_REAL, NULL); - } - else - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, - NULL); - } - } - gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_GPU, pLayerPak->pData); - } - - pLayerPak->eState = SAsyncPak::STATE_LOADED; - - //printf("Finished streaming level pak: %s\n", pLayerPak->layername.c_str()); -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StreamOnComplete( - IReadStream* pStream, unsigned nError) -{ - SAsyncPak* pLayerPak = (SAsyncPak*) pStream->GetUserData(); - - if (nError != 0) - { - ReleaseData(pLayerPak); - } - - pLayerPak->bStreaming = false; - pLayerPak->pReadStream = NULL; - - m_bRequestLayerUpdate = true; -} - -void* CAsyncPakManager::StreamOnNeedStorage(IReadStream* pStream, unsigned nSize, bool& bAbortOnFailToAlloc) -{ - SAsyncPak* pAsyncPak = (SAsyncPak*)pStream->GetUserData(); - - pAsyncPak->nSize = nSize; - - if ((m_nTotalOpenLayerPakSize + nSize) > (size_t)(g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE)) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Not enough space to load in memory layer pak %s (Current: %" PRISIZE_T " Required: %d)", - pAsyncPak->filename.c_str(), m_nTotalOpenLayerPakSize, nSize); - - //printf("Not enough space to load in memory layer pak %s (Current: %d Required: %d)\n", pAsyncPak->filename.c_str(), m_nTotalOpenLayerPakSize, nSize); - - pAsyncPak->eState = SAsyncPak::STATE_UNLOADED; - pAsyncPak->bStreaming = false; - pAsyncPak->pReadStream = NULL; - - bAbortOnFailToAlloc = true; - - return NULL; - } - - if (nSize) - { - auto pCryPak = static_cast(gEnv->pCryPak); - - // allocate the data - const char* szUsage = "In Memory Zip File"; - pAsyncPak->pData = pCryPak->PoolAllocMemoryBlock(nSize, szUsage, alignof(uint8_t)); - - m_nTotalOpenLayerPakSize += nSize; - - return pAsyncPak->pData->m_address.get(); - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::Update() -{ - if (!m_bRequestLayerUpdate) - { - return; - } - - m_bRequestLayerUpdate = false; - - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - if (!layerPak.bStreaming) - { - if (layerPak.eState == SAsyncPak::STATE_REQUESTUNLOAD) - { - // done streaming and not interested in it anymore, then release it again - ReleaseData(&layerPak); - } - else if (layerPak.eState == SAsyncPak::STATE_REQUESTED && - (m_nTotalOpenLayerPakSize + layerPak.nSize <= ((size_t)g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE))) - { - // do we have enough memory now to start streaming the pak - StartStreaming(&layerPak); - } - } - } -} - -// Abort streaming jobs and prevent any more requests -// Paks which are loaded remain, they will be cleaned up as usual -void CAsyncPakManager::CancelPendingJobs() -{ - for (TPakMap::iterator it = m_paks.begin(); it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - - if (layerPak.bStreaming) - { - layerPak.pReadStream->Abort(); - ReleaseData(&layerPak); - - //printf("Pak %s Aborted\n", layerPak.filename.c_str()); - } - else if (layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - layerPak.eState = SAsyncPak::STATE_UNLOADED; - ReleaseData(&layerPak); - - //printf("Pak %s Cancelled\n", layerPak.filename.c_str()); - } - } -} - -////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/AsyncPakManager.h b/Code/CryEngine/CrySystem/AsyncPakManager.h deleted file mode 100644 index 92a319c73c..0000000000 --- a/Code/CryEngine/CrySystem/AsyncPakManager.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manage async pak files - -#ifndef CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H -#pragma once - -#include -#include -#include - -namespace AZ::IO -{ - struct MemoryBlock; -} - -class CAsyncPakManager - : public IStreamCallback -{ -protected: - - struct SAsyncPak - { - enum EState - { - STATE_UNLOADED, - STATE_REQUESTED, - STATE_REQUESTUNLOAD, - STATE_LOADED, - }; - - enum ELifeTime - { - LIFETIME_LOAD_ONLY, - LIFETIME_LEVEL_COMPLETE, - LIFETIME_PERMANENT - }; - - SAsyncPak() - : nRequestCount(0) - , eState(STATE_UNLOADED) - , eLifeTime(LIFETIME_LOAD_ONLY) - , nSize(0) - , pData(0) - , bStreaming(false) - , bPakAlreadyOpen(false) - , bClosePakOnRelease(false) - , pReadStream(0) {} - - string& GetStatus(string&) const; - - string layername; - string filename; - size_t nSize; - AZStd::intrusive_ptr pData; - EState eState; - ELifeTime eLifeTime; - bool bStreaming; - bool bPakAlreadyOpen; - bool bClosePakOnRelease; - int nRequestCount; - IReadStreamPtr pReadStream; - }; - typedef std::map TPakMap; - -public: - - CAsyncPakManager(); - ~CAsyncPakManager(); - - void ParseLayerPaks(const string& levelCachePath); - - bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly); - void UnloadLevelLoadPaks(); - bool LoadLayerPak(const char* sLayerName); - void UnloadLayerPak(const char* sLayerName); - void CancelPendingJobs(); - - void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const; - - void Clear(); - void Update(); - -protected: - - bool LoadPak(SAsyncPak& layerPak); - - void StartStreaming(SAsyncPak* pLayerPak); - void ReleaseData(SAsyncPak* pLayerPak); - - ////////////////////////////////////////////////////////////////////////// - // IStreamCallback interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void StreamAsyncOnComplete (IReadStream* pStream, unsigned nError); - virtual void StreamOnComplete (IReadStream* pStream, unsigned nError); - virtual void* StreamOnNeedStorage(IReadStream* pStream, unsigned nSize, bool& bAbortOnFailToAlloc); - ////////////////////////////////////////////////////////////////////////// - - TPakMap m_paks; - size_t m_nTotalOpenLayerPakSize; - bool m_bRequestLayerUpdate; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H diff --git a/Code/CryEngine/CrySystem/CrashHandler.rc b/Code/CryEngine/CrySystem/CrashHandler.rc deleted file mode 100644 index 01afa72550..0000000000 --- a/Code/CryEngine/CrySystem/CrashHandler.rc +++ /dev/null @@ -1,114 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_CRITICAL_ERROR, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 260 - BOTTOMMARGIN, 223 - END - - IDD_EXCEPTION, DIALOG - BEGIN - END - - IDD_CONFIRM_SAVE_LEVEL, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 239 - TOPMARGIN, 7 - BOTTOMMARGIN, 96 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_CRITICAL_ERROR DIALOGEX 0, 0, 267, 230 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Critical Exception" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "&Abort",IDB_EXIT,100,207,58,14 - EDITTEXT IDC_CALLSTACK,10,95,245,102,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL - EDITTEXT IDC_EXCEPTION_CODE,10,25,50,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Call Stack Trace",IDC_STATIC,13,85,54,8 - LTEXT "Code",IDC_STATIC,10,15,18,8 - LTEXT "Address:",IDC_STATIC,66,15,28,8 - EDITTEXT IDC_EXCEPTION_ADDRESS,65,25,75,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Description",IDC_STATIC,10,40,36,8 - GROUPBOX "Exception Info",IDC_STATIC,5,5,255,200 - EDITTEXT IDC_EXCEPTION_MODULE,145,25,110,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Module",IDC_STATIC,145,15,24,8 - EDITTEXT IDC_EXCEPTION_DESC,10,50,245,30,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY - PUSHBUTTON "&Ignore",IDB_IGNORE,160,207,59,14,WS_DISABLED -END - -IDD_EXCEPTION DIALOG 0, 0, 138, 52 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Exception" -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Exception Intercepted\r\nRetrieving Info...",IDC_STATIC,33,18,71,19 -END - -IDD_CONFIRM_SAVE_LEVEL DIALOGEX 0, 0, 280, 123 -STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION -EXSTYLE WS_EX_TOPMOST -CAPTION "Engine, Game or Editor Crash" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Save",IDB_CONFIRM_SAVE,4,96,68,20 - PUSHBUTTON "Cancel",IDB_DONT_SAVE,206,96,68,20 - LTEXT "Open 3D Engine has encountered an error and needs to close.\n\nA backup has been saved to the '_savebackup' subfolder.\n\nIf you are unable to save your file, you can recover by copying the contents of the _savebackup folder over the broken files.",IDC_STATIC,60,8,210,61 - LTEXT "Attempt save?",IDC_STATIC,60,72,180,21 - CONTROL 128,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZEIMAGE,8,8,48,40 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_CRASH_FACE BITMAP "crash_face.bmp" -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp b/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp deleted file mode 100644 index efc03779de..0000000000 --- a/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "CustomMemoryHeap.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CUSTOMMEMORYHEAP_CPP_SECTION_1 1 -#define CUSTOMMEMORYHEAP_CPP_SECTION_2 2 -#define CUSTOMMEMORYHEAP_CPP_SECTION_3 3 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeapBlock::CCustomMemoryHeapBlock(CCustomMemoryHeap* pHeap) - : m_pHeap(pHeap) - , m_pData(0) - , m_nSize(0) - , m_nGPUHandle(0) -{ -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeapBlock::~CCustomMemoryHeapBlock() -{ - m_pHeap->DeallocateBlock(this); -} - -////////////////////////////////////////////////////////////////////////// -void* CCustomMemoryHeapBlock::GetData() -{ - return m_pData; -} - -////////////////////////////////////////////////////////////////////////// -void CCustomMemoryHeapBlock::CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize) -{ - assert(nOffset + nSize <= m_nSize); - if (nOffset + nSize <= m_nSize) - { - memcpy(pOutputBuffer, (uint8*)m_pData + nOffset, nSize); - } - else - { - CryFatalError("Bad CopyMemoryRegion range"); - } -} - -////////////////////////////////////////////////////////////////////////// -ICustomMemoryBlock* CCustomMemoryHeap::AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment /* = 16 */) -{ - CCustomMemoryHeapBlock* pBlock = new CCustomMemoryHeapBlock(this); - pBlock->m_sUsage = sUsage; - pBlock->m_nSize = nAllocateSize; - - switch (m_eAllocPolicy) - { - case IMemoryManager::eapDefaultAllocator: - { - size_t allocated = 0; - pBlock->m_pData = CryMalloc(nAllocateSize, allocated, nAlignment); - break; - } - case IMemoryManager::eapPageMapped: - pBlock->m_pData = CryMemory::AllocPages(nAllocateSize); - break; - case IMemoryManager::eapCustomAlignment: -#if defined(DEBUG) - if (nAlignment == 0) - { - CryFatalError("CCustomMemoryHeap: trying to allocate memory via eapCustomAlignment with an alignment of zero!"); - } -#endif - pBlock->m_pData = CryModuleMemalign(nAllocateSize, nAlignment); - break; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - default: - CryFatalError("CCustomMemoryHeap: unknown allocation policy during AllocateBlock!"); - break; - } - - CryInterlockedAdd(&m_nAllocatedSize, nAllocateSize); - - return pBlock; -} - -void CCustomMemoryHeap::DeallocateBlock(CCustomMemoryHeapBlock* pBlock) -{ - switch (m_eAllocPolicy) - { - case IMemoryManager::eapDefaultAllocator: - CryFree(pBlock->m_pData, 0); - break; - case IMemoryManager::eapPageMapped: - CryMemory::FreePages(pBlock->m_pData, pBlock->GetSize()); - break; - case IMemoryManager::eapCustomAlignment: - CryModuleMemalignFree(pBlock->m_pData); - break; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - default: - CryFatalError("CCustomMemoryHeap: unknown allocation policy during DeallocateBlock!"); - break; - } - - int nAllocateSize = (int)pBlock->m_nSize; - CryInterlockedAdd(&m_nAllocatedSize, -nAllocateSize); -} - -////////////////////////////////////////////////////////////////////////// -void CCustomMemoryHeap::GetMemoryUsage(ICrySizer* pSizer) -{ - pSizer->AddObject(this, m_nAllocatedSize); -} - -////////////////////////////////////////////////////////////////////////// -size_t CCustomMemoryHeap::GetAllocated() -{ - return m_nAllocatedSize; -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeap::CCustomMemoryHeap(IMemoryManager::EAllocPolicy const eAllocPolicy) -{ - m_nAllocatedSize = 0; - m_eAllocPolicy = eAllocPolicy; - m_nTraceHeapHandle = 0; -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeap::~CCustomMemoryHeap() -{ -} diff --git a/Code/CryEngine/CrySystem/DllMain.cpp b/Code/CryEngine/CrySystem/DllMain.cpp index c3a15812ce..7fd620835b 100644 --- a/Code/CryEngine/CrySystem/DllMain.cpp +++ b/Code/CryEngine/CrySystem/DllMain.cpp @@ -62,46 +62,6 @@ AZ_POP_DISABLE_WARNING } #endif -////////////////////////////////////////////////////////////////////////// -struct CSystemEventListner_System - : public ISystemEventListener -{ -public: - virtual void OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_LOAD_START: - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - CryCleanup(); - break; - } - - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - CryCleanup(); - STLALLOCATOR_CLEANUP; - break; - } - } - } -}; - -static CSystemEventListner_System g_system_event_listener_system; - -static AZ::EnvironmentVariable s_cryMemoryManager; - - -// Force the CryMemoryManager into the AZ::Environment for exposure to other DLLs -void ExportCryMemoryManager() -{ - IMemoryManager* cryMemoryManager = nullptr; - CryGetIMemoryManagerInterface((void**)&cryMemoryManager); - AZ_Assert(cryMemoryManager, "Unable to resolve CryMemoryManager"); - s_cryMemoryManager = AZ::Environment::CreateVariable("CryIMemoryManagerInterface", cryMemoryManager); -} - extern "C" { CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupParams) @@ -113,8 +73,6 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar // Environment should have been attached via InjectEnvironment AZ_Assert(AZ::Environment::IsReady(), "Environment is not attached, must be attached before CreateSystemInterface can be called"); - ExportCryMemoryManager(); - pSystem = new CSystem(startupParams.pSharedEnvironment); ModuleInitISystem(pSystem, "CrySystem"); @@ -146,8 +104,6 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar return 0; } - pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_system); - return pSystem; } }; diff --git a/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp b/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp deleted file mode 100644 index 22a9fa1793..0000000000 --- a/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "GeneralMemoryHeap.h" - -#include -#include - -class GeneralMemoryHeapAllocator - : public AZ::SimpleSchemaAllocator -{ - using Base = AZ::SimpleSchemaAllocator; -public: - static const size_t DEFAULT_ALIGNMENT = sizeof(void*); - - GeneralMemoryHeapAllocator(const char* desc) - : Base("GeneralMemoryHeapAllocator", desc) - { - } - - void Reserve(size_t size) - { - // Allocate a block, then free it, forcing it into the page tree/cache - void* block = m_schema->Allocate(size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, "GeneralMemoryHeapAllocator Reserve", __FILE__, __LINE__); - m_schema->DeAllocate(block); - } -}; - -CGeneralMemoryHeap::CGeneralMemoryHeap([[maybe_unused]] UINT_PTR base, [[maybe_unused]] size_t upperLimit, size_t reserveSize, const char* sUsage) - : m_refCount(0) - , m_block(nullptr) - , m_blockSize(0) -{ - AZ::HphaSchema::Descriptor desc; - desc.m_subAllocator = &AZ::AllocatorInstance::Get(); - m_allocator.reset(new AZ::AllocatorWrapper); - m_allocator->Create(desc, sUsage); - if (reserveSize) - { - (*m_allocator)->Reserve(reserveSize); - } -} - -CGeneralMemoryHeap::CGeneralMemoryHeap(void* base, size_t size, const char* sUsage) - : m_refCount(0) - , m_block(base) - , m_blockSize(size) -{ - AZ::HphaSchema::Descriptor desc; - desc.m_fixedMemoryBlock = base; - desc.m_fixedMemoryBlockByteSize = size; - desc.m_fixedMemoryBlockAlignment = GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT; - m_allocator.reset(new AZ::AllocatorWrapper); - m_allocator->Create(desc, sUsage); -} - -CGeneralMemoryHeap::~CGeneralMemoryHeap() -{ -} - -bool CGeneralMemoryHeap::Cleanup() -{ - (*m_allocator)->GarbageCollect(); - return true; -} - -int CGeneralMemoryHeap::AddRef() -{ - return m_refCount.fetch_add(1); -} - -int CGeneralMemoryHeap::Release() -{ - int nRef = m_refCount.fetch_sub(1); - - if (nRef <= 1) - { - delete this; - } - - return nRef; -} - -void CGeneralMemoryHeap::RecordAlloc(void* ptr, size_t size) -{ - if (m_block == nullptr) - { - m_allocs.emplace(ptr, size); - } -} - -void CGeneralMemoryHeap::RecordFree(void* ptr, size_t size) -{ - if (m_block == nullptr) - { - m_allocs.erase(Alloc(ptr, size)); - } -} - -bool CGeneralMemoryHeap::IsInAddressRange(void* ptr) const -{ - if (m_block) - { - return (static_cast(ptr) - static_cast(m_block)) <= m_blockSize; - } - auto it = m_allocs.find(Alloc(ptr)); - return it != m_allocs.end(); -} - -void* CGeneralMemoryHeap::Calloc(size_t numElements, size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(numElements * size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, sUsage, __FILE__, __LINE__); - memset(ptr, 0, numElements * size); - RecordAlloc(ptr, numElements * size); - return ptr; -} - -void* CGeneralMemoryHeap::Malloc(size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, sUsage, __FILE__, __LINE__); - RecordAlloc(ptr, size); - return ptr; -} - -size_t CGeneralMemoryHeap::Free(void* ptr) -{ - // The client code using these heaps tend to use a guesswork algorithm to freeing - // which involves handing the pointer to every known heap until it frees, so - // it's necessary to validate that the ptr belongs to this heap before attempting to free - if (IsInAddressRange(ptr)) - { - size_t size = (*m_allocator)->AllocationSize(ptr); - RecordFree(ptr, size); - (*m_allocator)->DeAllocate(ptr); - return size; - } - return 0; -} - -void* CGeneralMemoryHeap::Realloc(void* ptr, size_t size, const char* /*sUsage*/) -{ - RecordFree(ptr, (*m_allocator)->AllocationSize(ptr)); - void* newPtr = (*m_allocator)->ReAllocate(ptr, size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT); - RecordAlloc(newPtr, size); - return newPtr; -} - -void* CGeneralMemoryHeap::ReallocAlign(void* ptr, size_t size, size_t alignment, const char* /*sUsage*/) -{ - RecordFree(ptr, (*m_allocator)->AllocationSize(ptr)); - void* newPtr = (*m_allocator)->ReAllocate(ptr, size, alignment); - RecordAlloc(newPtr, size); - return newPtr; -} - -void* CGeneralMemoryHeap::Memalign(size_t boundary, size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(size, boundary, 0, sUsage, __FILE__, __LINE__); - RecordAlloc(ptr, size); - return ptr; -} - -size_t CGeneralMemoryHeap::UsableSize(void* ptr) const -{ - // The client code using these heaps tend to use a guesswork algorithm to determine - // which heap owns the pointer. Calls to UsableSize() are a part of this guesswork. - // The overrun detector doesn't play nicely on AllocationSize() lookups for pointers that - // don't belong to the heap, so validate that we're in the correct address range before trying - // to look up the size. - return IsInAddressRange(ptr) ? (*m_allocator)->AllocationSize(ptr) : 0; -} - -AZ::IAllocator* CGeneralMemoryHeap::GetAllocator() const -{ - return m_allocator->Get(); -} diff --git a/Code/CryEngine/CrySystem/GeneralMemoryHeap.h b/Code/CryEngine/CrySystem/GeneralMemoryHeap.h deleted file mode 100644 index a09556055d..0000000000 --- a/Code/CryEngine/CrySystem/GeneralMemoryHeap.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_GENERALMEMORYHEAP_H -#define CRYINCLUDE_CRYSYSTEM_GENERALMEMORYHEAP_H -#pragma once - - -#include "IMemory.h" -#include -#include -#include - -class GeneralMemoryHeapAllocator; - -class CGeneralMemoryHeap - : public IGeneralMemoryHeap -{ - struct Alloc - { - void* m_base; - size_t m_size; - - Alloc(void* base = nullptr, size_t size = 0) - : m_base(base) - , m_size(size) - {} - - bool operator==(const Alloc& rhs) const - { - // size doesn't matter - return m_base == rhs.m_base; - } - - bool operator<(const Alloc& rhs) const - { - // this will cause allocs to be sorted by address - return m_base < rhs.m_base; - } - }; - -public: - // Create a heap that will map/unmap pages in the range [baseAddress, baseAddress + upperLimit). - CGeneralMemoryHeap(UINT_PTR baseAddress, size_t upperLimit, size_t reserveSize, const char* sUsage); - - // Create a heap that will assumes all memory in the range [base, base + size) is already mapped. - CGeneralMemoryHeap(void* base, size_t size, const char* sUsage); - - ~CGeneralMemoryHeap(); - -public: // IGeneralMemoryHeap Members - bool Cleanup(); - - int AddRef(); - int Release(); - - bool IsInAddressRange(void* ptr) const; - - void* Calloc(size_t nmemb, size_t size, const char* sUsage = NULL); - void* Malloc(size_t sz, const char* sUsage = NULL); - size_t Free(void* ptr); - void* Realloc(void* ptr, size_t sz, const char* sUsage = NULL); - void* ReallocAlign(void* ptr, size_t size, size_t alignment, const char* sUsage = NULL); - void* Memalign(size_t boundary, size_t size, const char* sUsage = NULL); - size_t UsableSize(void* ptr) const; - - AZ::IAllocator* GetAllocator() const override; - -private: - CGeneralMemoryHeap(const CGeneralMemoryHeap&) = delete; - CGeneralMemoryHeap& operator = (const CGeneralMemoryHeap&) = delete; - - void RecordAlloc(void* ptr, size_t size); - void RecordFree(void* ptr, size_t size); - -private: - AZStd::unique_ptr> m_allocator; - AZStd::atomic_int m_refCount; - void* m_block; - size_t m_blockSize; - AZStd::set, AZ::AZStdAlloc> m_allocs; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_GENERALMEMORYHEAP_H diff --git a/Code/CryEngine/CrySystem/ImageHandler.cpp b/Code/CryEngine/CrySystem/ImageHandler.cpp deleted file mode 100644 index 7444aebdc0..0000000000 --- a/Code/CryEngine/CrySystem/ImageHandler.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include "ImageHandler.h" -#include -#include "ScopeGuard.h" -#include "Algorithm.h" -#include "System.h" - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ImageHandler_cpp) -#endif - -#if !(defined(ANDROID) || defined(IOS) || defined(LINUX)) && AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO // Rally US1050 - Compile libtiff for Android and IOS - #include - -static_assert(sizeof(thandle_t) >= sizeof(AZ::IO::HandleType), "Platform defines thandle_t to be smaller than required"); -#endif - -namespace -{ - class Image - : public IImageHandler::IImage - { - public: - Image(std::vector&& data, int width, int height) - { - CRY_ASSERT(data.size() == width * height * ImageHandler::c_BytesPerPixel); - m_data = std::move(data); - m_width = width; - m_height = height; - } - private: - virtual const std::vector& GetData() const override { return m_data; } - virtual int GetWidth() const override { return m_width; } - virtual int GetHeight() const override { return m_height; } - - unsigned int m_width; - unsigned int m_height; - std::vector m_data; - }; -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - struct TiffIO - { - static tsize_t Read(thandle_t handle, tdata_t buffer, tsize_t size) - { - AZ::u64 bytesRead = 0; - AZ::IO::FileIOBase::GetDirectInstance()->Read(static_cast(reinterpret_cast(handle)), buffer, size, false, &bytesRead); - return static_cast(bytesRead); - }; - - static tsize_t Write(thandle_t handle, tdata_t buffer, tsize_t size) - { - AZ::u64 sizeWritten; - if (AZ::IO::FileIOBase::GetDirectInstance()->Write(static_cast(reinterpret_cast(handle)), buffer, size, &sizeWritten)) - { - return static_cast(sizeWritten); - } - else - { - return 0; - } - }; - - static int Close(thandle_t handle) - { - AZ::IO::FileIOBase::GetDirectInstance()->Close(static_cast(reinterpret_cast(handle))); - return 0; - }; - - static toff_t Seek(thandle_t handle, toff_t pos, int mode) - { - if (AZ::IO::FileIOBase::GetDirectInstance()->Seek(static_cast(reinterpret_cast(handle)), static_cast(pos), AZ::IO::GetSeekTypeFromFSeekMode(mode))) - { - if (mode == SEEK_SET) - { - return pos; - } - else - { - AZ::u64 offsetFromBegin; - if (AZ::IO::FileIOBase::GetDirectInstance()->Tell(static_cast(reinterpret_cast(handle)), offsetFromBegin)) - { - return static_cast(offsetFromBegin); - } - else - { - return -1; - } - } - } - return -1; - }; - - static toff_t Size(thandle_t handle) - { - AZ::u64 fileSize = 0; - AZ::IO::FileIOBase::GetDirectInstance()->Size(static_cast(reinterpret_cast(handle)), fileSize); - return static_cast(fileSize); - }; - - static int Map(thandle_t, tdata_t*, toff_t*) - { - return 0; - }; - - static void Unmap(thandle_t, tdata_t, toff_t) - { - return; - }; - }; -#endif -} - -std::unique_ptr ImageHandler::CreateImage(std::vector&& data, int width, int height) const -{ - return std::make_unique(std::move(data), width, height); -} - -std::unique_ptr ImageHandler::LoadImage([[maybe_unused]] const char* filename) const -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - - AZ::IO::HandleType fileHandle; - AZ::IO::FileIOBase::GetDirectInstance()->Open(filename, AZ::IO::GetOpenModeFromStringMode("rb"), fileHandle); - - if (fileHandle == AZ::IO::InvalidHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to open image file %s", filename); - return nullptr; - } - - auto tifHandle = std17::unique_resource_checked(TIFFClientOpen(filename, "rb", reinterpret_cast(static_cast(fileHandle)), TiffIO::Read, TiffIO::Write, TiffIO::Seek, TiffIO::Close, &TiffIO::Size, TiffIO::Map, TiffIO::Unmap), (TIFF*)nullptr, TIFFClose); - if (!tifHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load image %s", filename); - return nullptr; - } - - int width = 0; - int height = 0; - TIFFGetField(tifHandle, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tifHandle, TIFFTAG_IMAGELENGTH, &height); - std::vector data(4 * width * height); - if (!TIFFReadRGBAImageOriented(tifHandle, width, height, reinterpret_cast(data.data()), ORIENTATION_TOPLEFT)) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load image %s", filename); - return nullptr; - } - - //strip alpha - int every4th = 0; - data.erase(std::remove_if(begin(data), end(data), [&](unsigned char) - { - return (every4th++ & 3) == 3; - }), end(data)); - - return std::make_unique(std::move(data), width, height); -#else - CRY_ASSERT(0); // UNIMPLEMENTED - return nullptr; -#endif -} - -bool ImageHandler::SaveImage([[maybe_unused]] IImageHandler::IImage* image, [[maybe_unused]] const char* filename) const -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - - AZ::IO::HandleType fileHandle; - AZ::IO::FileIOBase::GetDirectInstance()->Open(filename, AZ::IO::GetOpenModeFromStringMode("wb"), fileHandle); - - if (fileHandle == AZ::IO::InvalidHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to open image file for write %s", filename); - return false; - } - - auto tifHandle = std17::unique_resource_checked(TIFFClientOpen(filename, "wb", reinterpret_cast(static_cast(fileHandle)), TiffIO::Read, TiffIO::Write, TiffIO::Seek, TiffIO::Close, &TiffIO::Size, TiffIO::Map, TiffIO::Unmap), (TIFF*)nullptr, TIFFClose); - if (!tifHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to save image %s", filename); - return false; - } - - TIFFSetField(tifHandle, TIFFTAG_IMAGEWIDTH, image->GetWidth()); - TIFFSetField(tifHandle, TIFFTAG_IMAGELENGTH, image->GetHeight()); - TIFFSetField(tifHandle, TIFFTAG_SAMPLESPERPIXEL, c_BytesPerPixel); - TIFFSetField(tifHandle, TIFFTAG_BITSPERSAMPLE, 8); - TIFFSetField(tifHandle, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(tifHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(tifHandle, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - TIFFSetField(tifHandle, TIFFTAG_COMPRESSION, COMPRESSION_LZW); - - tsize_t bytesPerLine = c_BytesPerPixel * image->GetWidth(); - std::vector lineBuffer; - if (TIFFScanlineSize(tifHandle) != bytesPerLine) - { - lineBuffer.resize(bytesPerLine); - } - else - { - lineBuffer.resize(TIFFScanlineSize(tifHandle)); - } - TIFFSetField(tifHandle, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tifHandle, image->GetWidth() * c_BytesPerPixel)); - auto srcData = image->GetData().data(); - - for (uint32 row = 0; row < image->GetHeight(); row++) - { - memcpy(lineBuffer.data(), &srcData[row * bytesPerLine], bytesPerLine); - if (TIFFWriteScanline(tifHandle, lineBuffer.data(), row, 0) < 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Failed to write part of image %s", filename); - return false; - } - } - - return true; -#else - CRY_ASSERT(0); // UNIMPLEMENTED - return false; -#endif -} - -std::unique_ptr ImageHandler::CreateDiffImage(IImageHandler::IImage* image1, IImageHandler::IImage* image2) const -{ - if (!image1 || !image2) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, null arguments"); - return nullptr; - } - if (image1->GetWidth() != image2->GetWidth() || image1->GetHeight() != image2->GetHeight()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, 2 images were not the same size"); - return nullptr; - } - CRY_ASSERT(image1->GetData().size() == image1->GetWidth() * image1->GetHeight() * ImageHandler::c_BytesPerPixel); - CRY_ASSERT(image2->GetData().size() == image2->GetWidth() * image2->GetHeight() * ImageHandler::c_BytesPerPixel); - - std::vector resultRGBData; - - auto iter1 = image1->GetData().data(); - auto iter2 = image2->GetData().data(); - for (int i = 0; i < image1->GetWidth() * image1->GetHeight() * c_BytesPerPixel; ++i) - { - resultRGBData.push_back(static_cast(abs(static_cast(iter1[i]) - static_cast(iter2[i])))); - } - - return std::make_unique(std::move(resultRGBData), image1->GetWidth(), image1->GetHeight()); -} - -float ImageHandler::CalculatePSNR(IImageHandler::IImage* diffIimage) const -{ - if (!diffIimage) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, null arguments"); - return 0; - } - CRY_ASSERT(diffIimage->GetData().size() == diffIimage->GetWidth() * diffIimage->GetHeight() * ImageHandler::c_BytesPerPixel); - - auto mse = std17::accumulate(diffIimage->GetData(), 0.0, [](double result, unsigned char value) -> double { return result += (double)value * (double)value; }); - mse /= (c_BytesPerPixel * diffIimage->GetWidth() * diffIimage->GetHeight()); - - if (mse <= 0) - { - return std::numeric_limits::max(); - } - - // see http://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio for a derivation of this formula and source for magic numbers - return static_cast(20 * log10(255) - 10 * log10(mse)); -} diff --git a/Code/CryEngine/CrySystem/ImageHandler.h b/Code/CryEngine/CrySystem/ImageHandler.h deleted file mode 100644 index bba596a266..0000000000 --- a/Code/CryEngine/CrySystem/ImageHandler.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once -#ifndef CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H -#define CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H - -#include "IImageHandler.h" - -class ImageHandler - : public IImageHandler -{ -public: - static const int c_BytesPerPixel = 3; //This only deals with RGB data for now, no alpha -private: - virtual std::unique_ptr CreateImage(std::vector&& rgbData, int width, int height) const override; - virtual std::unique_ptr LoadImage(const char* filename) const override; - virtual bool SaveImage(IImageHandler::IImage* image, const char* filename) const override; - virtual std::unique_ptr CreateDiffImage(IImageHandler::IImage* image1, IImageHandler::IImage* image2) const override; - virtual float CalculatePSNR(IImageHandler::IImage* diffIimage) const override; -}; -#endif // CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H diff --git a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp index 0af52d8cc4..8d9c0dd8e8 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp @@ -17,7 +17,6 @@ #include "LevelSystem.h" #include #include "IMovieSystem.h" -#include #include #include "CryPath.h" #include @@ -778,9 +777,6 @@ void CLevelSystem::PrepareNextLevel(const char* levelName) // switched to level heap, so now imm start the loading screen (renderer will be reinitialized in the levelheap) gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START_LOADINGSCREEN, 0, 0); gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_PREPARE); - - // Inform resource manager about loading of the new level. - GetISystem()->GetIResourceManager()->PrepareLevel(pLevelInfo->GetPath(), pLevelInfo->GetName()); } for (AZStd::vector::const_iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) @@ -987,8 +983,6 @@ void CLevelSystem::UnloadLevel() m_lastLevelName.clear(); - GetISystem()->GetIResourceManager()->UnloadLevel(); - SAFE_RELEASE(m_pCurrentLevel); // Force Lua garbage collection (may no longer be needed now the legacy renderer has been removed). diff --git a/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp index 8b3c75cce2..ff6ebc0d17 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp @@ -14,7 +14,6 @@ #include "SpawnableLevelSystem.h" #include #include "IMovieSystem.h" -#include #include @@ -566,8 +565,6 @@ namespace LegacyLevelSystem m_lastLevelName.clear(); - GetISystem()->GetIResourceManager()->UnloadLevel(); - // Force Lua garbage collection (may no longer be needed now the legacy renderer has been removed). // Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event). EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect); diff --git a/Code/CryEngine/CrySystem/Log.cpp b/Code/CryEngine/CrySystem/Log.cpp index c51947d8bc..63aee4422f 100644 --- a/Code/CryEngine/CrySystem/Log.cpp +++ b/Code/CryEngine/CrySystem/Log.cpp @@ -20,7 +20,6 @@ //this should not be included here #include #include -#include #include "System.h" #include "CryPath.h" // PathUtil::ReplaceExtension() #include @@ -1439,22 +1438,6 @@ void CLog::UpdateLoadingScreen(const char* szFormat, ...) va_end(args); } #endif - - if (CryGetCurrentThreadId() == m_nMainThreadId) - { -#ifndef LINUX - // Take this opportunity to update streaming engine. - if (IStreamEngine* pStreamEngine = GetISystem()->GetStreamEngine()) - { - const float curTime = m_pSystem->GetITimer()->GetAsyncCurTime(); - if (curTime - m_fLastLoadingUpdateTime > .1f) // not frequent than once in 100ms - { - m_fLastLoadingUpdateTime = curTime; - pStreamEngine->Update(); - } - } -#endif - } } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/MTSafeAllocator.cpp b/Code/CryEngine/CrySystem/MTSafeAllocator.cpp deleted file mode 100644 index 7d9c08d3c4..0000000000 --- a/Code/CryEngine/CrySystem/MTSafeAllocator.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "MTSafeAllocator.h" -#include - -extern CMTSafeHeap* g_pPakHeap; - -// Uncomment this define to enable time tracing of the MTSAFE heap -#define MTSAFE_PROFILE 1 -//#undef MTSAFE_PROFILE - -namespace -{ - class CSimpleTimer - { - LARGE_INTEGER& m_result; - LARGE_INTEGER m_start; - public: - - CSimpleTimer(LARGE_INTEGER& li) - : m_result(li) - { QueryPerformanceCounter(&m_start); } - - ~CSimpleTimer() - { - LARGE_INTEGER end; - QueryPerformanceCounter(&end); - m_result.QuadPart = end.QuadPart - m_start.QuadPart; - } - }; -}; - -////////////////////////////////////////////////////////////////////////// -CMTSafeHeap::CMTSafeHeap() - : m_LiveTempAllocations() - , m_TotalAllocations() - , m_TempAllocationsFailed() - , m_TempAllocationsTime() -{ - size_t allocated = 0; - m_pGeneralHeapStorage = (char*)CryMalloc(MTSAFE_GENERAL_HEAP_SIZE, allocated, MTSAFE_DEFAULT_ALIGNMENT); - m_pGeneralHeapStorageEnd = m_pGeneralHeapStorage + MTSAFE_GENERAL_HEAP_SIZE; - m_pGeneralHeap = CryGetIMemoryManager()->CreateGeneralMemoryHeap(m_pGeneralHeapStorage, MTSAFE_GENERAL_HEAP_SIZE, "MTSafeHeap"); -} - -////////////////////////////////////////////////////////////////////////// -CMTSafeHeap::~CMTSafeHeap() -{ - SAFE_RELEASE(m_pGeneralHeap); - CryFree(m_pGeneralHeapStorage, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -size_t CMTSafeHeap::PersistentAllocSize(size_t nSize) -{ - return nSize; -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::PersistentAlloc(size_t nSize) -{ - size_t allocated = 0; - return CryMalloc(nSize, allocated, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::FreePersistent(void* p) -{ - CryFree(p, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::TempAlloc(size_t nSize, const char* szDbgSource, bool& bFallBackToMalloc, uint32 align) -{ -# if MTSAFE_PROFILE - CSimpleTimer timer(m_TempAllocationsTime); -# endif - - void* ptr = NULL; - if (align) - { - ptr = m_pGeneralHeap->Memalign(align, nSize, szDbgSource); - } - else - { - ptr = m_pGeneralHeap->Malloc(nSize, szDbgSource); - } - - //explicit alignment not supported beyond this point, safer to return NULL - if (ptr || !bFallBackToMalloc) - { - bFallBackToMalloc = false; - return ptr; - } - - bFallBackToMalloc = true; - -# if MTSAFE_PROFILE - CryInterlockedAdd((volatile int*)&m_TempAllocationsFailed, (int)nSize); -# endif - - return CryModuleMemalign(nSize, align > 0 ? align : MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::FreeTemporary(void* p) -{ -# if MTSAFE_PROFILE - CSimpleTimer timer(m_TempAllocationsTime); -# endif - - if (m_pGeneralHeap->IsInAddressRange(p)) - { - m_pGeneralHeap->Free(p); - return; - } - - // Fallback to free - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::StaticAlloc([[maybe_unused]] void* pOpaque, unsigned nItems, unsigned nSize) -{ - return g_pPakHeap->TempAlloc(nItems * nSize, "StaticAlloc"); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::StaticFree ([[maybe_unused]] void* pOpaque, void* pAddress) -{ - g_pPakHeap->FreeTemporary(pAddress); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::GetMemoryUsage(ICrySizer* pSizer) -{ - SIZER_COMPONENT_NAME(pSizer, "FileSystem Pool"); -} - -void CMTSafeHeap::PrintStats() -{ -# if MTSAFE_PROFILE - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - const double rFreq = 1. / static_cast(freq.QuadPart); - - CryLogAlways("mtsafe temporary pool failed for %" PRISIZE_T " bytes, time spent in allocations %3.08f seconds", - m_TempAllocationsFailed, static_cast(m_TempAllocationsTime.QuadPart) * rFreq); -# endif -} - diff --git a/Code/CryEngine/CrySystem/MTSafeAllocator.h b/Code/CryEngine/CrySystem/MTSafeAllocator.h deleted file mode 100644 index eeee5ff501..0000000000 --- a/Code/CryEngine/CrySystem/MTSafeAllocator.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - - -#if defined(LINUX) -# include "Linux_Win32Wrapper.h" -#endif -#include - -//////////////////////////////////////////////////////////////////////////////// -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(MTSafeAllocator_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(MOBILE) // IOS/Android -# define MTSAFE_DEFAULT_ALIGNMENT 8 -# define MTSAFE_GENERAL_HEAP_SIZE ((1U << 20) + (1U << 19)) -#elif defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(MAC) -# define MTSAFE_GENERAL_HEAP_SIZE (12U << 20) -# define MTSAFE_DEFAULT_ALIGNMENT 8 -#else -# error Unknown target platform -#endif - -class CMTSafeHeap -{ -public: - // Constructor - CMTSafeHeap(); - - // Destructor - ~CMTSafeHeap(); - - // Performs a persisistent (in other words, non-temporary) allocation. - void* PersistentAlloc(size_t nSize); - - // Retrieves system memory allocation size for any call to PersistentAlloc. - // Required to not count virtual memory usage inside CrySizer - size_t PersistentAllocSize(size_t nSize); - - // Frees memory allocation - void FreePersistent(void* p); - - // Perform a allocation that is considered temporary and will be handled by - // the pool itself. - // Note: It is important that these temporary allocations are actually - // temporary and do not persist for a long persiod of time. - void* TempAlloc (size_t nSize, const char* szDbgSource, uint32 align = 0) - { - bool bFallbackToMalloc = true; - return TempAlloc(nSize, szDbgSource, bFallbackToMalloc, align); - } - - void* TempAlloc (size_t nSize, const char* szDbgSource, bool& bFallBackToMalloc, uint32 align = 0); - - bool IsInGeneralHeap(const void* p) - { - return m_pGeneralHeapStorage <= p && p < m_pGeneralHeapStorageEnd; - } - - // Free a temporary allocaton. - void FreeTemporary(void* p); - - // The number of live allocations allocation within the temporary pool - size_t NumAllocations() const { return m_LiveTempAllocations; } - - // The memory usage of the mtsafe allocator - void GetMemoryUsage(ICrySizer* pSizer); - - // zlib-compatible stubs - static void* StaticAlloc (void* pOpaque, unsigned nItems, unsigned nSize); - static void StaticFree (void* pOpaque, void* pAddress); - - // Dump some statistics to the cry log - void PrintStats(); - - -private: - friend class CSystem; - - IGeneralMemoryHeap* m_pGeneralHeap; - char* m_pGeneralHeapStorage; - char* m_pGeneralHeapStorageEnd; - - // The number of temporary allocations currently active within the pool - size_t m_LiveTempAllocations; - - // The total number of allocations performed in the pool - size_t m_TotalAllocations; - - // The total bytes that weren't temporarily allocated - size_t m_TempAllocationsFailed; - // The total number of temporary allocations that fell back to global system memory - LARGE_INTEGER m_TempAllocationsTime; -}; diff --git a/Code/CryEngine/CrySystem/MemoryAddressRange.cpp b/Code/CryEngine/CrySystem/MemoryAddressRange.cpp deleted file mode 100644 index bb547d80cc..0000000000 --- a/Code/CryEngine/CrySystem/MemoryAddressRange.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "MemoryAddressRange.h" -#include "System.h" - -#if defined(APPLE) || defined(LINUX) -#include -#endif - -CMemoryAddressRange::CMemoryAddressRange(char* pBaseAddress, size_t nPageSize, size_t nPageCount, [[maybe_unused]] const char* sName) - : m_pBaseAddress(pBaseAddress) - , m_nPageSize(nPageSize) - , m_nPageCount(nPageCount) -{ -} - -void CMemoryAddressRange::Release() -{ - delete this; -} - -char* CMemoryAddressRange::GetBaseAddress() const -{ - return m_pBaseAddress; -} - -size_t CMemoryAddressRange::GetPageCount() const -{ - return m_nPageCount; -} - -size_t CMemoryAddressRange::GetPageSize() const -{ - return m_nPageSize; -} - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_MEMADDRESSRANGE_WINDOWS_STYLE - -void* CMemoryAddressRange::ReserveSpace(size_t capacity) -{ - return VirtualAlloc(NULL, capacity, MEM_RESERVE, PAGE_READWRITE); -} - -size_t CMemoryAddressRange::GetSystemPageSize() -{ - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwPageSize; -} - -CMemoryAddressRange::CMemoryAddressRange(size_t capacity, [[maybe_unused]] const char* name) -{ - m_nPageSize = GetSystemPageSize(); - - size_t algnCap = Align(capacity, m_nPageSize); - m_pBaseAddress = (char*)ReserveSpace(algnCap); - m_nPageCount = algnCap / m_nPageSize; -} - -CMemoryAddressRange::~CMemoryAddressRange() -{ - VirtualFree(m_pBaseAddress, 0, MEM_RELEASE); -} - -void* CMemoryAddressRange::MapPage(size_t pageIdx) -{ - void* pRet = VirtualAlloc(m_pBaseAddress + pageIdx * m_nPageSize, m_nPageSize, MEM_COMMIT, PAGE_READWRITE); - return pRet; -} - -void CMemoryAddressRange::UnmapPage(size_t pageIdx) -{ - char* pBase = m_pBaseAddress + pageIdx * m_nPageSize; - - // Disable warning about only decommitting pages, and not releasing them - VirtualFree(pBase, m_nPageSize, MEM_DECOMMIT); -} - -#elif defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(MemoryAddressRange_cpp) -#elif defined(APPLE) || defined(LINUX) - -void* CMemoryAddressRange::ReserveSpace(size_t capacity) -{ - return mmap(0, capacity, PROT_NONE, MAP_ANON | MAP_NORESERVE | MAP_PRIVATE, -1, 0); -} - -size_t CMemoryAddressRange::GetSystemPageSize() -{ - return sysconf(_SC_PAGESIZE); -} - -CMemoryAddressRange::CMemoryAddressRange(size_t capacity, const char* name) -{ - m_nPageSize = GetSystemPageSize(); - - m_allocatedSpace = Align(capacity, m_nPageSize); - m_pBaseAddress = (char*)ReserveSpace(m_allocatedSpace); - assert(m_pBaseAddress != MAP_FAILED); - m_nPageCount = m_allocatedSpace / m_nPageSize; -} - -CMemoryAddressRange::~CMemoryAddressRange() -{ - int ret = munmap(m_pBaseAddress, m_allocatedSpace); - (void) ret; - assert(ret == 0); -} - -void* CMemoryAddressRange::MapPage(size_t pageIdx) -{ - // There is no equivalent to this function with mmap, this - // happens automatically in the OS. We just return the - // correct address. - void* pRet = NULL; - if (0 == mprotect(m_pBaseAddress + (pageIdx * m_nPageSize), m_nPageSize, PROT_READ | PROT_WRITE)) - { - pRet = m_pBaseAddress + (pageIdx * m_nPageSize); - } - - return pRet; -} - -void CMemoryAddressRange::UnmapPage(size_t pageIdx) -{ - char* pBase = m_pBaseAddress + pageIdx * m_nPageSize; - int ret = mprotect(pBase, m_nPageSize, PROT_NONE); - (void) ret; - assert(ret == 0); -} - - -#endif diff --git a/Code/CryEngine/CrySystem/MemoryAddressRange.h b/Code/CryEngine/CrySystem/MemoryAddressRange.h deleted file mode 100644 index b2679f6667..0000000000 --- a/Code/CryEngine/CrySystem/MemoryAddressRange.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_MEMORYADDRESSRANGE_H -#define CRYINCLUDE_CRYSYSTEM_MEMORYADDRESSRANGE_H -#pragma once - - -#include "IMemory.h" - -class CMemoryAddressRange - : public IMemoryAddressRange -{ -public: - static void* ReserveSpace(size_t sz); - static size_t GetSystemPageSize(); - -public: - CMemoryAddressRange(char* pBaseAddress, size_t nPageSize, size_t nPageCount, const char* sName); - CMemoryAddressRange(size_t capacity, const char* name); - ~CMemoryAddressRange(); - - ILINE bool IsInRange(void* p) const - { - return m_pBaseAddress <= p && p < (m_pBaseAddress + m_nPageSize * m_nPageCount); - } - -public: - void Release(); - - char* GetBaseAddress() const; - size_t GetPageCount() const; - size_t GetPageSize() const; - - void* MapPage(size_t pageIdx); - void UnmapPage(size_t pageIdx); - -private: - CMemoryAddressRange(const CMemoryAddressRange&); - CMemoryAddressRange& operator = (const CMemoryAddressRange&); - -private: - char* m_pBaseAddress; - size_t m_nPageSize; - size_t m_nPageCount; -#if defined(APPLE) || defined(LINUX) - size_t m_allocatedSpace; // Required to unmap latter on -#endif -}; - -#endif // CRYINCLUDE_CRYSYSTEM_MEMORYADDRESSRANGE_H diff --git a/Code/CryEngine/CrySystem/MemoryManager.cpp b/Code/CryEngine/CrySystem/MemoryManager.cpp deleted file mode 100644 index 3021d68539..0000000000 --- a/Code/CryEngine/CrySystem/MemoryManager.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "MemoryManager.h" -#include "platform.h" -#include "CustomMemoryHeap.h" -#include "GeneralMemoryHeap.h" -#include "PageMappingHeap.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define MEMORYMANAGER_CPP_SECTION_1 1 -#endif - -#if defined(WIN32) - #define WIN32_LEAN_AND_MEAN - #include - #include -#endif - -#if defined(APPLE) -#include // task_info -#endif - -#if defined(APPLE) || defined(LINUX) -#include // required by mman.h -#include //mmap - virtual memory manager -#endif - -#ifdef MEMMAN_STATIC -CCryMemoryManager g_memoryManager; -#endif - -////////////////////////////////////////////////////////////////////////// -CCryMemoryManager* CCryMemoryManager::GetInstance() -{ -#ifdef MEMMAN_STATIC - return &g_memoryManager; -#else - static CCryMemoryManager memman; - return &memman; -#endif -} - -////////////////////////////////////////////////////////////////////////// -bool CCryMemoryManager::GetProcessMemInfo(SProcessMemInfo& minfo) -{ - ZeroStruct(minfo); -#if defined(WIN32) - - MEMORYSTATUSEX mem; - mem.dwLength = sizeof(mem); - GlobalMemoryStatusEx (&mem); - - minfo.TotalPhysicalMemory = mem.ullTotalPhys; - minfo.FreePhysicalMemory = mem.ullAvailPhys; - - ////////////////////////////////////////////////////////////////////////// - typedef BOOL (WINAPI * GetProcessMemoryInfoProc)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD); - - PROCESS_MEMORY_COUNTERS pc; - ZeroStruct(pc); - pc.cb = sizeof(pc); - static HMODULE hPSAPI = LoadLibraryA("psapi.dll"); - if (hPSAPI) - { - static GetProcessMemoryInfoProc pGetProcessMemoryInfo = (GetProcessMemoryInfoProc)GetProcAddress(hPSAPI, "GetProcessMemoryInfo"); - if (pGetProcessMemoryInfo) - { - if (pGetProcessMemoryInfo(GetCurrentProcess(), &pc, sizeof(pc))) - { - minfo.PageFaultCount = pc.PageFaultCount; - minfo.PeakWorkingSetSize = pc.PeakWorkingSetSize; - minfo.WorkingSetSize = pc.WorkingSetSize; - minfo.QuotaPeakPagedPoolUsage = pc.QuotaPeakPagedPoolUsage; - minfo.QuotaPagedPoolUsage = pc.QuotaPagedPoolUsage; - minfo.QuotaPeakNonPagedPoolUsage = pc.QuotaPeakNonPagedPoolUsage; - minfo.QuotaNonPagedPoolUsage = pc.QuotaNonPagedPoolUsage; - minfo.PagefileUsage = pc.PagefileUsage; - minfo.PeakPagefileUsage = pc.PeakPagefileUsage; - - return true; - } - } - } - return false; - -#else - -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION MEMORYMANAGER_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(MemoryManager_cpp) -#endif - - bool retVal = true; - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(LINUX) - - MEMORYSTATUS MemoryStatus; - GlobalMemoryStatus(&MemoryStatus); - minfo.PagefileUsage = minfo.PeakPagefileUsage = MemoryStatus.dwTotalPhys - MemoryStatus.dwAvailPhys; - - minfo.FreePhysicalMemory = MemoryStatus.dwAvailPhys; - minfo.TotalPhysicalMemory = MemoryStatus.dwTotalPhys; - -#if defined(ANDROID) - // On Android, mallinfo() is an EXTREMELY time consuming operation. Nearly 80% CPU time will be spent - // on this operation once -memreplay is given. Since WorkingSetSize is only used for statistics and - // debugging purpose, it's simply ignored. - minfo.WorkingSetSize = 0; -#else - struct mallinfo meminfo = mallinfo(); - minfo.WorkingSetSize = meminfo.usmblks + meminfo.uordblks; -#endif - -#elif defined(APPLE) - - MEMORYSTATUS MemoryStatus; - GlobalMemoryStatus(&MemoryStatus); - minfo.PagefileUsage = minfo.PeakPagefileUsage = MemoryStatus.dwTotalPhys - MemoryStatus.dwAvailPhys; - - minfo.FreePhysicalMemory = MemoryStatus.dwAvailPhys; - minfo.TotalPhysicalMemory = MemoryStatus.dwTotalPhys; - - // Retrieve WorkingSetSize from task_info - task_basic_info kTaskInfo; - mach_msg_type_number_t uInfoCount(sizeof(kTaskInfo) / sizeof(natural_t)); - if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&kTaskInfo, &uInfoCount) != 0) - { - gEnv->pLog->LogError("task_info failed\n"); - return false; - } - minfo.WorkingSetSize = kTaskInfo.resident_size; - -#else - - retVal = false; - -#endif - - return retVal; -#endif -} - -////////////////////////////////////////////////////////////////////////// -CCryMemoryManager::HeapHandle CCryMemoryManager::TraceDefineHeap([[maybe_unused]] const char* heapName, [[maybe_unused]] size_t size, [[maybe_unused]] const void* pBase) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapAlloc([[maybe_unused]] HeapHandle heap, [[maybe_unused]] void* mem, [[maybe_unused]] size_t size, [[maybe_unused]] size_t blockSize, [[maybe_unused]] const char* sUsage, [[maybe_unused]] const char* sNameHint) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapFree([[maybe_unused]] HeapHandle heap, [[maybe_unused]] void* mem, [[maybe_unused]] size_t blockSize) -{ -} - - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapSetColor([[maybe_unused]] uint32 color) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapSetLabel([[maybe_unused]] const char* sLabel) -{ -} - -////////////////////////////////////////////////////////////////////////// -uint32 CCryMemoryManager::TraceHeapGetColor() -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////// -ICustomMemoryHeap* const CCryMemoryManager::CreateCustomMemoryHeapInstance(IMemoryManager::EAllocPolicy const eAllocPolicy) -{ - return new CCustomMemoryHeap(eAllocPolicy); -} - -IGeneralMemoryHeap* CCryMemoryManager::CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage) -{ - return new CGeneralMemoryHeap(static_cast(0), upperLimit, reserveSize, sUsage); -} - -IGeneralMemoryHeap* CCryMemoryManager::CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage) -{ - return new CGeneralMemoryHeap(base, sz, sUsage); -} - -IMemoryAddressRange* CCryMemoryManager::ReserveAddressRange(size_t capacity, const char* sName) -{ - return new CMemoryAddressRange(capacity, sName); -} - -IPageMappingHeap* CCryMemoryManager::CreatePageMappingHeap(size_t addressSpace, const char* sName) -{ - return new CPageMappingHeap(addressSpace, sName); -} - -extern "C" -{ - CRYMEMORYMANAGER_API void CryGetIMemoryManagerInterface(void** pIMemoryManager) - { - // Static instance of the memory manager - *pIMemoryManager = CCryMemoryManager::GetInstance(); - } -}; diff --git a/Code/CryEngine/CrySystem/MemoryManager.h b/Code/CryEngine/CrySystem/MemoryManager.h deleted file mode 100644 index e29d5404d8..0000000000 --- a/Code/CryEngine/CrySystem/MemoryManager.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_MEMORYMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_MEMORYMANAGER_H -#pragma once - -#include "ISystem.h" - -////////////////////////////////////////////////////////////////////////// -// Class that implements IMemoryManager interface. -////////////////////////////////////////////////////////////////////////// -#ifndef MEMMAN_STATIC -class CCryMemoryManager - : public IMemoryManager -{ -public: - // Singleton - static CCryMemoryManager* GetInstance(); - - ////////////////////////////////////////////////////////////////////////// - virtual bool GetProcessMemInfo(SProcessMemInfo& minfo); - - virtual HeapHandle TraceDefineHeap(const char* heapName, size_t size, const void* pBase); - virtual void TraceHeapAlloc(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint = 0); - virtual void TraceHeapFree(HeapHandle heap, void* mem, size_t blockSize); - virtual void TraceHeapSetColor(uint32 color); - virtual uint32 TraceHeapGetColor(); - virtual void TraceHeapSetLabel(const char* sLabel); - - virtual ICustomMemoryHeap* const CreateCustomMemoryHeapInstance(IMemoryManager::EAllocPolicy const eAllocPolicy); - virtual IGeneralMemoryHeap* CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage); - virtual IGeneralMemoryHeap* CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage); - - virtual IMemoryAddressRange* ReserveAddressRange(size_t capacity, const char* sName); - virtual IPageMappingHeap* CreatePageMappingHeap(size_t addressSpace, const char* sName); -}; -#else -typedef IMemoryManager CCryMemoryManager; -#endif - -#endif // CRYINCLUDE_CRYSYSTEM_MEMORYMANAGER_H diff --git a/Code/CryEngine/CrySystem/PageMappingHeap.cpp b/Code/CryEngine/CrySystem/PageMappingHeap.cpp deleted file mode 100644 index d42d75db5b..0000000000 --- a/Code/CryEngine/CrySystem/PageMappingHeap.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "PageMappingHeap.h" - -namespace -{ - template - inline void FindZeroRanges(const uint32* str, size_t strLen, Func& yield) - { - size_t carry = 0; - size_t bitIdx = 0; - - for (size_t wordIdx = 0; wordIdx < strLen; ++wordIdx) - { - size_t wordBitIdx = 0; - int64 word = str[wordIdx]; - - // Set up sign extension to insert bits that are the last bit, inverted. - - if (!(word & 0x80000000)) - { - reinterpret_cast(word) |= 0xffffffff00000000ULL; - } - - do - { - size_t wordZeroRunLen = countTrailingZeroes(word); - - wordBitIdx += wordZeroRunLen; - carry += wordZeroRunLen; - - if (wordBitIdx == 32) - { - break; - } - - yield(bitIdx, carry); - word >>= wordZeroRunLen; - bitIdx += carry; - carry = 0; - - size_t wordOneRunLen = countTrailingZeroes(~word); - bitIdx += wordOneRunLen; - wordBitIdx += wordOneRunLen; - - if (wordBitIdx == 32) - { - break; - } - - word >>= wordOneRunLen; - } - while (true); - } - - if (carry) - { - yield(bitIdx, carry); - } - } - - struct DLMMapFindBest - { - DLMMapFindBest(size_t size) - : requiredLength(size) - , bestPosition(-1) - , bestFragmentLength(INT_MAX) - { - } - - bool operator () (size_t position, size_t length) - { - if (length == requiredLength) - { - bestPosition = position; - bestFragmentLength = 0; - return false; - } - else if (length > requiredLength) - { - size_t fragment = length - requiredLength; - if (fragment < bestFragmentLength) - { - bestPosition = position; - bestFragmentLength = fragment; - } - } - - return true; - } - - size_t requiredLength; - ptrdiff_t bestPosition; - size_t bestFragmentLength; - }; - - struct FindLargest - { - FindLargest() - : largest(0) - { - } - bool operator () (size_t, size_t length) - { - largest = max(largest, length); - return true; - } - - size_t largest; - }; -} - -CPageMappingHeap::CPageMappingHeap(char* pAddressSpace, size_t nNumPages, size_t nPageSize, const char* sName) - : m_addrRange(pAddressSpace, nPageSize, nNumPages, sName) -{ - Init(); -} - -CPageMappingHeap::CPageMappingHeap(size_t addressSpace, const char* sName) - : m_addrRange(addressSpace, sName) -{ - Init(); -} - -CPageMappingHeap::~CPageMappingHeap() -{ -} - -void CPageMappingHeap::Release() -{ - delete this; -} - -size_t CPageMappingHeap::GetGranularity() const -{ - return m_addrRange.GetPageSize(); -} - -bool CPageMappingHeap::IsInAddressRange(void* ptr) const -{ - return m_addrRange.IsInRange(ptr); -} - -size_t CPageMappingHeap::FindLargestFreeBlockSize() const -{ - CryAutoLock lock(m_lock); - - const size_t pageSize = m_addrRange.GetPageSize(); - - FindLargest findLargest; - FindZeroRanges(&m_pageBitmap[0], m_pageBitmap.size(), findLargest); - - return findLargest.largest * pageSize; -} - -void* CPageMappingHeap::Map(size_t length) -{ - CryAutoLock lock(m_lock); - - const size_t pageBitmapElemBitSize = (sizeof(uint32) * 8); - const size_t pageSize = m_addrRange.GetPageSize(); - const size_t numPages = m_addrRange.GetPageCount(); - - if (length % pageSize) - { - __debugbreak(); - length = (length + (pageSize - 1)) & ~(pageSize - 1); - } - - DLMMapFindBest findBest(length / pageSize); - FindZeroRanges(&m_pageBitmap[0], m_pageBitmap.size(), findBest); - - if ((findBest.bestPosition == -1) || (findBest.bestPosition >= (int)numPages)) - { - return NULL; - } - - void* mapAddress = m_addrRange.GetBaseAddress() + pageSize * findBest.bestPosition; - - for (size_t pageIdx = findBest.bestPosition, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - if (!m_addrRange.MapPage(pageIdx)) - { - // Unwind the pages we've already mapped. - for (; pageIdx > static_cast(findBest.bestPosition); --pageIdx) - { - m_addrRange.UnmapPage(pageIdx - 1); - } - - return NULL; - } - } - - for (size_t pageIdx = findBest.bestPosition, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - size_t pageSegment = pageIdx / pageBitmapElemBitSize; - uint32 pageMask = 1U << static_cast(pageIdx % pageBitmapElemBitSize); - - m_pageBitmap[pageSegment] |= pageMask; - } - - return mapAddress; -} - -void CPageMappingHeap::Unmap(void* mem, size_t length) -{ - CryAutoLock lock(m_lock); - const size_t pageSize = m_addrRange.GetPageSize(); - - if (length % pageSize) - { - __debugbreak(); - length = (length + (pageSize - 1)) & ~(pageSize - 1); - } - - char* mapAddress = reinterpret_cast(mem); - for (size_t pageIdx = (mapAddress - m_addrRange.GetBaseAddress()) / pageSize, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - m_addrRange.UnmapPage(pageIdx); - - const size_t pageBitmapElemBitSize = (sizeof(uint32) * 8); - - size_t pageSegment = pageIdx / pageBitmapElemBitSize; - uint32 pageMask = ~(1U << static_cast(pageIdx % pageBitmapElemBitSize)); - - m_pageBitmap[pageSegment] &= pageMask; - } -} - -void CPageMappingHeap::Init() -{ - UINT_PTR start = (UINT_PTR)m_addrRange.GetBaseAddress(); - UINT_PTR end = start + m_addrRange.GetPageCount() * m_addrRange.GetPageSize(); - - size_t addressSpace = end - start; - size_t pageSize = m_addrRange.GetPageSize(); - size_t numPages = (addressSpace + pageSize - 1) / pageSize; - m_pageBitmap.resize((numPages + 31) / 32); - - size_t pageCapacity = m_pageBitmap.size() * 32; - size_t numUnavailablePages = pageCapacity - numPages; - if (numUnavailablePages > 0) - { - m_pageBitmap.back() = ~((1 << (32 - numUnavailablePages)) - 1); - } -} diff --git a/Code/CryEngine/CrySystem/PageMappingHeap.h b/Code/CryEngine/CrySystem/PageMappingHeap.h deleted file mode 100644 index 8cd3a7a315..0000000000 --- a/Code/CryEngine/CrySystem/PageMappingHeap.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_PAGEMAPPINGHEAP_H -#define CRYINCLUDE_CRYSYSTEM_PAGEMAPPINGHEAP_H -#pragma once - - -#include "MemoryAddressRange.h" - -#include "IMemory.h" - -class CPageMappingHeap - : public IPageMappingHeap -{ -public: - CPageMappingHeap(char* pAddressSpace, size_t nNumPages, size_t nPageSize, const char* sName); - CPageMappingHeap(size_t addressSpace, const char* sName); - ~CPageMappingHeap(); - -public: // IPageMappingHeap Members - virtual void Release(); - - virtual size_t GetGranularity() const; - virtual bool IsInAddressRange(void* ptr) const; - - virtual size_t FindLargestFreeBlockSize() const; - - virtual void* Map(size_t sz); - virtual void Unmap(void* ptr, size_t sz); - -private: - CPageMappingHeap(const CPageMappingHeap&); - CPageMappingHeap& operator = (const CPageMappingHeap&); - -private: - void Init(); - -private: - mutable CryCriticalSectionNonRecursive m_lock; - CMemoryAddressRange m_addrRange; - std::vector m_pageBitmap; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_PAGEMAPPINGHEAP_H diff --git a/Code/CryEngine/CrySystem/ResourceManager.cpp b/Code/CryEngine/CrySystem/ResourceManager.cpp deleted file mode 100644 index 5e9477a99c..0000000000 --- a/Code/CryEngine/CrySystem/ResourceManager.cpp +++ /dev/null @@ -1,868 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Resource Manager - - -#include "CrySystem_precompiled.h" -#include "ResourceManager.h" -#include "System.h" -#include "MaterialUtils.h" -#include -#include -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define RESOURCEMANAGER_CPP_SECTION_1 1 -#define RESOURCEMANAGER_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION RESOURCEMANAGER_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(ResourceManager_cpp) -#endif - -#define LEVEL_PAK_FILENAME "level.pak" -#define LEVEL_PAK_INMEMORY_MAXSIZE 10 * 1024 * 1024 - -#define ENGINE_PAK_FILENAME "engine.pak" -#define LEVEL_CACHE_PAK_FILENAME "xml.pak" - -#define GAME_DATA_PAK_FILENAME "gamedata.pak" -#define FAST_LOADING_PAKS_SRC_FOLDER "_fastload/" -#define FRONTEND_COMMON_PAK_FILENAME_SP "modes/menucommon_sp.pak" -#define FRONTEND_COMMON_PAK_FILENAME_MP "modes/menucommon_mp.pak" -#define FRONTEND_COMMON_LIST_FILENAME "menucommon" -#define LEVEL_CACHE_SRC_FOLDER "_levelcache/" -#define LEVEL_CACHE_BIND_ROOT "LevelCache" -#define LEVEL_RESOURCE_LIST "resourcelist.txt" -#define AUTO_LEVEL_RESOURCE_LIST "auto_resourcelist.txt" -#define AUTO_LEVEL_SEQUENCE_RESOURCE_LIST "auto_resources_sequence.txt" -#define AUTO_LEVEL_TOTAL_RESOURCE_LIST "auto_resourcelist_total.txt" -#define AUTO_LEVEL_TOTAL_SEQUENCE_RESOURCE_LIST "auto_resources_total_sequence.txt" - -////////////////////////////////////////////////////////////////////////// -// IResourceList implementation class. -////////////////////////////////////////////////////////////////////////// -class CLevelResourceList - : public AZ::IO::IResourceList -{ -public: - CLevelResourceList() - { - m_pFileBuffer = 0; - m_nBufferSize = 0; - m_nCurrentLine = 0; - }; - ~CLevelResourceList() - { - Clear(); - }; - - uint32 GetFilenameHash(const char* sResourceFile) - { - char filename[512]; - azstrcpy(filename, AZ_ARRAY_SIZE(filename), sResourceFile); - MaterialUtils::UnifyMaterialName(filename); - - uint32 code = CCrc32::ComputeLowercase(filename); - return code; - } - - virtual void Add([[maybe_unused]] AZStd::string_view sResourceFile) - { - assert(0); // Not implemented. - } - virtual void Clear() - { - delete [] m_pFileBuffer; - m_pFileBuffer = 0; - m_nBufferSize = 0; - stl::free_container(m_lines); - stl::free_container(m_resources_crc32); - m_nCurrentLine = 0; - } - - struct ComparePredicate - { - bool operator()(const char* s1, const char* s2) - { - return strcmp(s1, s2) < 0; - } - }; - - virtual bool IsExist(AZStd::string_view sResourceFile) - { - uint32 nHash = GetFilenameHash(sResourceFile.data()); - if (stl::binary_find(m_resources_crc32.begin(), m_resources_crc32.end(), nHash) != m_resources_crc32.end()) - { - return true; - } - return false; - } - virtual bool Load(AZStd::string_view sResourceListFilename) - { - Clear(); - CCryFile file; - if (file.Open(sResourceListFilename.data(), "rb", AZ::IO::IArchive::FOPEN_ONDISK)) // File access can happen from disk as well. - { - m_nBufferSize = file.GetLength(); - if (m_nBufferSize > 0) - { - m_pFileBuffer = new char[m_nBufferSize]; - size_t numBytesRead = file.ReadRaw(m_pFileBuffer, file.GetLength()); - - if (numBytesRead <= 0 || numBytesRead != file.GetLength()) - { - AZ_Error("ResourceManager", false, "Unable to read data for: %.*s", aznumeric_cast(sResourceListFilename.size()), sResourceListFilename.data()); - return false; - } - m_pFileBuffer[m_nBufferSize - 1] = 0; - - char seps[] = "\r\n"; - - m_lines.reserve(5000); - - // Parse file, every line in a file represents a resource filename. - char* nextToken = nullptr; - char* token = azstrtok(m_pFileBuffer, 0, seps, &nextToken); - while (token != NULL) - { - m_lines.push_back(token); - token = azstrtok(NULL, 0, seps, &nextToken); - } - - m_resources_crc32.resize(m_lines.size()); - for (int i = 0, numlines = m_lines.size(); i < numlines; i++) - { - MaterialUtils::UnifyMaterialName(const_cast(m_lines[i])); - m_resources_crc32[i] = CCrc32::ComputeLowercase(m_lines[i]); - } - std::sort(m_resources_crc32.begin(), m_resources_crc32.end()); - } - return true; - } - return false; - } - virtual const char* GetFirst() - { - m_nCurrentLine = 0; - if (!m_lines.empty()) - { - return m_lines[0]; - } - return NULL; - } - virtual const char* GetNext() - { - m_nCurrentLine++; - if (m_nCurrentLine < (int)m_lines.size()) - { - return m_lines[m_nCurrentLine]; - } - return NULL; - } - - void GetMemoryStatistics(ICrySizer* pSizer) - { - pSizer->Add(this, sizeof(*this)); - pSizer->Add(m_pFileBuffer, m_nBufferSize); - pSizer->AddContainer(m_lines); - pSizer->AddContainer(m_resources_crc32); - } - -public: - char* m_pFileBuffer; - int m_nBufferSize; - typedef std::vector Lines; - Lines m_lines; - int m_nCurrentLine; - std::vector m_resources_crc32; -}; - - -////////////////////////////////////////////////////////////////////////// -CResourceManager::CResourceManager() -{ - m_bRegisteredFileOpenSink = false; - m_bOwnResourceList = false; - m_bLevelTransitioning = false; - - m_fastLoadPakPaths.reserve(8); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::PrepareLevel(const char* sLevelFolder, const char* sLevelName) -{ - LOADING_TIME_PROFILE_SECTION; - - m_sLevelFolder = sLevelFolder; - m_sLevelName = sLevelName; - m_bLevelTransitioning = false; - m_currentLevelCacheFolder = CryPathString(LEVEL_CACHE_SRC_FOLDER) + sLevelName; - - if (g_cvars.archiveVars.nLoadCache) - { - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - // The prefab system doesn't use level.pak - if (!usePrefabSystemForLevels) - { - CryPathString levelpak = PathUtil::Make(sLevelFolder, LEVEL_PAK_FILENAME); - size_t nPakFileSize = gEnv->pCryPak->FGetSize(levelpak.c_str()); - if (nPakFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs. - { - // Force level.pak from this level in memory. - gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - } - } - - gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - - // - // Load _levelCache paks in the order they are stored on the disk - reduce seek time - // - - if (gEnv->pConsole->GetCVar("e_StreamCgf") && gEnv->pConsole->GetCVar("e_StreamCgf")->GetIVal() != 0) - { - LoadLevelCachePak("cga.pak", "", true); - LoadLevelCachePak("cgf.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("cgf_cache.pak", "", false); - } - } - - LoadLevelCachePak("chr.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("chr_cache.pak", "", false); - } - - LoadLevelCachePak("dds0.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("dds_cache.pak", "", false); - } - - LoadLevelCachePak("skin.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("skin_cache.pak", "", false); - } - - LoadLevelCachePak(LEVEL_CACHE_PAK_FILENAME, "", true); - } - - AZStd::intrusive_ptr pResList = new CLevelResourceList; - gEnv->pCryPak->SetResourceList(AZ::IO::IArchive::RFOM_Level, pResList.get()); - m_bOwnResourceList = true; - - // Load resourcelist.txt, TODO: make sure there are no duplicates - if (g_cvars.archiveVars.nSaveLevelResourceList == 0) - { - string filename = PathUtil::Make(sLevelFolder, AUTO_LEVEL_RESOURCE_LIST); - if (!pResList->Load(filename.c_str())) // If we saving resource list do not use auto_resourcelist.txt - { - // Try resource list created by the editor. - filename = PathUtil::Make(sLevelFolder, LEVEL_RESOURCE_LIST); - pResList->Load(filename.c_str()); - } - } - //LoadFastLoadPaks(); - - if (g_cvars.archiveVars.nStreamCache) - { - m_AsyncPakManager.ParseLayerPaks(GetCurrentLevelCacheFolder()); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadFastLoadPaks(bool bToMemory) -{ - if (g_cvars.archiveVars.nSaveFastloadResourceList != 0) - { - // Record a file list for _FastLoad/startup.pak - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return false; - } - else - { - LOADING_TIME_PROFILE_SECTION; - - // Load a special _fastload paks - int nPakPreloadFlags = AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32 | AZ::IO::INestedArchive::FLAGS_OVERRIDE_PAK; - if (bToMemory && g_cvars.archiveVars.nLoadCache) - { - nPakPreloadFlags |= AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY; - } - - const char* const assetsDir = "@assets@"; - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION RESOURCEMANAGER_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(ResourceManager_cpp) -#endif - - gEnv->pCryPak->OpenPacks(assetsDir, AZ::IO::PathString(FAST_LOADING_PAKS_SRC_FOLDER) + "*.pak", nPakPreloadFlags, &m_fastLoadPakPaths); - gEnv->pCryPak->OpenPack(assetsDir, "Engine.pak", AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY); - return !m_fastLoadPakPaths.empty(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadFastLoadPaks() -{ - for (uint32 i = 0; i < m_fastLoadPakPaths.size(); i++) - { - // Unload a special _fastload paks - gEnv->pCryPak->ClosePack(m_fastLoadPakPaths[i].c_str(), AZ::IO::IArchive::FLAGS_PATH_REAL); - } - m_fastLoadPakPaths.clear(); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadLevel() -{ - gEnv->pCryPak->SetResourceList(AZ::IO::IArchive::RFOM_Level, NULL); - - if (m_bRegisteredFileOpenSink) - { - if (g_cvars.archiveVars.nSaveTotalResourceList) - { - SaveRecordedResources(true); - m_recordedFiles.clear(); - } - } - - stl::free_container(m_sLevelFolder); - stl::free_container(m_sLevelName); - stl::free_container(m_currentLevelCacheFolder); - - // should always be empty, since it is freed at the end of - // the level loading process, if it is not - // something went wrong and we have a levelheap leak - assert(m_openedPaks.capacity() == 0); - - m_pSequenceResourceList = NULL; -} - -////////////////////////////////////////////////////////////////////////// -AZ::IO::IResourceList* CResourceManager::GetLevelResourceList() -{ - auto pResList = gEnv->pCryPak->GetResourceList(AZ::IO::IArchive::RFOM_Level); - return pResList; -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading) -{ - LOADING_TIME_PROFILE_SECTION; - CryPathString pakPath = GetCurrentLevelCacheFolder() + "/" + sPakName; - - pakPath.MakeLower(); - pakPath.replace(AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR); - - // Check if pak is already loaded - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if (strstr(m_openedPaks[i].filename.c_str(), pakPath.c_str())) - { - return true; - } - } - - // check pak file size. - size_t nFileSize = gEnv->pCryPak->FGetSize(pakPath.c_str(), true); - - if (nFileSize <= 0) - { - // Cached file does not exist - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Level cache pak file %s does not exist", pakPath.c_str()); - return false; - } - - //set these flags as DLC LevelCache Paks are found via the mod paths, - //and the paks can never be inside other paks so we optimise the search - uint32 nOpenPakFlags = AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32 | AZ::IO::IArchive::FLAGS_CHECK_MOD_PATHS | AZ::IO::IArchive::FLAGS_NEVER_IN_PAK; - - if (nFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs. - { - if (!(nOpenPakFlags & AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY_CPU)) - { - nOpenPakFlags |= AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY; - } - } - - SOpenedPak op; - - if (gEnv->pCryPak->OpenPack(sBindRoot, { pakPath.c_str(), pakPath.size() }, nOpenPakFlags | AZ::IO::IArchive::FOPEN_HINT_QUIET, NULL, &op.filename)) - { - op.bOnlyDuringLevelLoading = bOnlyDuringLevelLoading; - m_openedPaks.push_back(op); - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadModeSwitchPak(const char* sPakName, const bool multiplayer) -{ - if (g_cvars.archiveVars.nSaveLevelResourceList) - { - //Don't load the pak if we're trying to save a resourcelist in order to build it. - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return true; - } - else - { - if (g_cvars.archiveVars.nLoadModePaks) - { - // Unload SP common pak if switching to multiplayer - if (multiplayer) - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp"); - } - else - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP, FRONTEND_COMMON_LIST_FILENAME "_mp"); - } - //Load the mode switching pak. If this is available and up to date it speeds up this process considerably - bool bOpened = gEnv->pCryPak->OpenPack("@assets@", sPakName, 0); - bool bLoaded = gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - return (bOpened && bLoaded); - } - else - { - return true; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer) -{ - if (g_cvars.archiveVars.nSaveLevelResourceList && m_bRegisteredFileOpenSink) - { - m_sLevelFolder = sResourceListName; - SaveRecordedResources(); - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - else - { - if (g_cvars.archiveVars.nLoadModePaks) - { - //Unload the mode switching pak. - gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - gEnv->pCryPak->ClosePack(sPakName, 0); - //Load the frontend common mode switch pak, this can considerably reduce the time spent switching especially from disc, currently SP only - if (!multiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_SP); - } - else if (multiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_MP); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadMenuCommonPak(const char* sPakName) -{ - if (g_cvars.archiveVars.nSaveMenuCommonResourceList) - { - //Don't load the pak if we're trying to save a resourcelist in order to build it. - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return true; - } - else - { - //Load the mode switching pak. If this is available and up to date it speeds up this process considerably - bool bOpened = gEnv->pCryPak->OpenPack("@assets@", sPakName, 0); - bool bLoaded = gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - return (bOpened && bLoaded); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadMenuCommonPak(const char* sPakName, const char* sResourceListName) -{ - if (g_cvars.archiveVars.nSaveMenuCommonResourceList) - { - m_sLevelFolder = sResourceListName; - SaveRecordedResources(); - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - else - { - //Unload the mode switching pak. - gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - gEnv->pCryPak->ClosePack(sPakName, 0); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadLevelCachePak(const char* sPakName) -{ - LOADING_TIME_PROFILE_SECTION; - CryPathString pakPath = GetCurrentLevelCacheFolder() + "/" + sPakName; - pakPath.MakeLower(); - pakPath.replace(AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR); - - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if (strstr(m_openedPaks[i].filename.c_str(), pakPath.c_str())) - { - gEnv->pCryPak->ClosePack(m_openedPaks[i].filename.c_str(), AZ::IO::IArchive::FLAGS_PATH_REAL); - m_openedPaks.erase(m_openedPaks.begin() + i); - break; - } - } - - if (m_openedPaks.empty()) - { - stl::free_container(m_openedPaks); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadAllLevelCachePaks(bool bLevelLoadEnd) -{ - LOADING_TIME_PROFILE_SECTION; - - if (!bLevelLoadEnd) - { - m_AsyncPakManager.Clear(); - UnloadFastLoadPaks(); - } - else - { - m_AsyncPakManager.UnloadLevelLoadPaks(); - } - - uint32 nClosePakFlags = AZ::IO::IArchive::FLAGS_PATH_REAL; //AZ::IO::IArchive::FLAGS_CHECK_MOD_PATHS | AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL; - - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if ((m_openedPaks[i].bOnlyDuringLevelLoading && bLevelLoadEnd) || - !bLevelLoadEnd) - { - gEnv->pCryPak->ClosePack(m_openedPaks[i].filename.c_str(), nClosePakFlags); - } - } - - if (g_cvars.archiveVars.nLoadCache) - { - gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - if (!usePrefabSystemForLevels) - { - // Force level.pak out of memory. - gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - } - } - if (!bLevelLoadEnd) - { - stl::free_container(m_openedPaks); - } -} - -////////////////////////////////////////////////////////////////////////// - -bool CResourceManager::LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) -{ - return m_AsyncPakManager.LoadPakToMemAsync(pPath, bLevelLoadOnly); -} - -bool CResourceManager::LoadLayerPak(const char* sLayerName) -{ - return m_AsyncPakManager.LoadLayerPak(sLayerName); -} - -void CResourceManager::UnloadLayerPak(const char* sLayerName) -{ - m_AsyncPakManager.UnloadLayerPak(sLayerName); -} - -void CResourceManager::GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const -{ - m_AsyncPakManager.GetLayerPakStats(stats, bCollectAllStats); -} - -void CResourceManager::UnloadAllAsyncPaks() -{ - m_AsyncPakManager.Clear(); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Update() -{ - m_AsyncPakManager.Update(); -} -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Init() -{ - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Shutdown() -{ - UnloadAllLevelCachePaks(false); - if (GetISystem() && GetISystem()->GetISystemEventDispatcher()) - { - GetISystem()->GetISystemEventDispatcher()->RemoveListener(this); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::IsStreamingCachePak(const char* filename) const -{ - const char* cachePaks[] = { - "dds_cache.pak", - "cgf_cache.pak", - "skin_cache.pak", - "chr_cache.pak" - }; - - for (int i = 0; i < sizeof(cachePaks) / sizeof(cachePaks[0]); ++i) - { - if (strstr(filename, cachePaks[i])) - { - return true; - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) -{ - switch (event) - { - case ESYSTEM_EVENT_FRONTEND_INITIALISED: - { - GetISystem()->GetStreamEngine()->PauseStreaming(false, -1); - } - break; - - case ESYSTEM_EVENT_GAME_POST_INIT_DONE: - { - if (g_cvars.archiveVars.nSaveFastloadResourceList != 0) - { - SaveRecordedResources(); - - if (g_cvars.archiveVars.nSaveLevelResourceList == 0 && g_cvars.archiveVars.nSaveTotalResourceList == 0) - { - m_recordedFiles.clear(); - } - } - // Unload all paks from memory, after game init. - UnloadAllLevelCachePaks(false); - gEnv->pCryPak->LoadPaksToMemory(0, false); - - if (g_cvars.archiveVars.nLoadCache) - { - //Load the frontend common mode switch pak, this can considerably reduce the time spent switching especially from disc - if (LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_SP); - } - } - - break; - } - - case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE: - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp"); - - m_bLevelTransitioning = !m_sLevelName.empty(); - - m_lastLevelLoadTime.SetValue(0); - m_beginLevelLoadTime = gEnv->pTimer->GetAsyncTime(); - if (g_cvars.archiveVars.nSaveLevelResourceList || g_cvars.archiveVars.nSaveTotalResourceList) - { - if (!g_cvars.archiveVars.nSaveTotalResourceList) - { - m_recordedFiles.clear(); - } - - if (!m_bRegisteredFileOpenSink) - { - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - } - } - - // Cancel any async pak loading, it will fight with the impending sync IO - m_AsyncPakManager.CancelPendingJobs(); - - // Pause streaming engine for anything but sound, music, video and flash. - uint32 nMask = (1 << eStreamTaskTypeFlash) | (1 << eStreamTaskTypeVideo) | STREAM_TASK_TYPE_AUDIO_ALL; // Unblock specified streams - nMask = ~nMask; // Invert mask, bit set means blocking type. - GetISystem()->GetStreamEngine()->PauseStreaming(true, nMask); - } - break; - - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - if (m_bOwnResourceList) - { - m_bOwnResourceList = false; - // Clear resource list, after level loading. - auto pResList = gEnv->pCryPak->GetResourceList(AZ::IO::IArchive::RFOM_Level); - if (pResList) - { - pResList->Clear(); - } - } - } - - break; - - case ESYSTEM_EVENT_LEVEL_UNLOAD: - UnloadAllLevelCachePaks(false); - - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_START: - { - // Unpause all streams in streaming engine. - GetISystem()->GetStreamEngine()->PauseStreaming(false, -1); - } - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_FIRST_FRAME: - { - UnloadAllLevelCachePaks(true); - } - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_END: - { - CTimeValue t = gEnv->pTimer->GetAsyncTime(); - m_lastLevelLoadTime = t - m_beginLevelLoadTime; - - if (g_cvars.archiveVars.nSaveLevelResourceList && m_bRegisteredFileOpenSink) - { - SaveRecordedResources(); - - if (!g_cvars.archiveVars.nSaveTotalResourceList) - { - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - } - - UnloadAllLevelCachePaks(true); - } - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::GetMemoryStatistics(ICrySizer* pSizer) -{ - pSizer->AddContainer(m_openedPaks); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::ReportFileOpen([[maybe_unused]] AZ::IO::HandleType inFileHandle, AZStd::string_view szFullPath) -{ - if (!g_cvars.archiveVars.nSaveLevelResourceList && !g_cvars.archiveVars.nSaveFastloadResourceList && !g_cvars.archiveVars.nSaveMenuCommonResourceList && !g_cvars.archiveVars.nSaveTotalResourceList) - { - return; - } - - string file = PathUtil::MakeGamePath(string(szFullPath.data(), szFullPath.size())); - file.replace('\\', '/'); - file.MakeLower(); - { - CryAutoCriticalSection lock(recordedFilesLock); - m_recordedFiles.push_back(file); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::SaveRecordedResources(bool bTotalList) -{ - CryAutoCriticalSection lock(recordedFilesLock); - - std::set fileset; - - // eliminate duplicate values - std::vector::iterator endLocation = std::unique(m_recordedFiles.begin(), m_recordedFiles.end()); - m_recordedFiles.erase(endLocation, m_recordedFiles.end()); - - fileset.insert(m_recordedFiles.begin(), m_recordedFiles.end()); - - string sSequenceFilename = PathUtil::AddSlash(m_sLevelFolder) + (bTotalList ? AUTO_LEVEL_TOTAL_SEQUENCE_RESOURCE_LIST : AUTO_LEVEL_SEQUENCE_RESOURCE_LIST); - { - AZ::IO::HandleType fileHandle = fxopen(sSequenceFilename, "wb", true); - if (fileHandle != AZ::IO::InvalidHandle) - { - for (std::vector::iterator it = m_recordedFiles.begin(); it != m_recordedFiles.end(); ++it) - { - const char* str = it->c_str(); - AZ::IO::Print(fileHandle, "%s\n", str); - } - gEnv->pFileIO->Close(fileHandle); - } - } - - string sResourceSetFilename = PathUtil::AddSlash(m_sLevelFolder) + (bTotalList ? AUTO_LEVEL_TOTAL_RESOURCE_LIST : AUTO_LEVEL_RESOURCE_LIST); - { - AZ::IO::HandleType fileHandle = fxopen(sResourceSetFilename, "wb", true); - if (fileHandle != AZ::IO::InvalidHandle) - { - for (std::set::iterator it = fileset.begin(); it != fileset.end(); ++it) - { - const char* str = it->c_str(); - AZ::IO::Print(fileHandle, "%s\n", str); - } - gEnv->pFileIO->Close(fileHandle); - } - } -} - -////////////////////////////////////////////////////////////////////////// -CTimeValue CResourceManager::GetLastLevelLoadTime() const -{ - return m_lastLevelLoadTime; -} diff --git a/Code/CryEngine/CrySystem/ResourceManager.h b/Code/CryEngine/CrySystem/ResourceManager.h deleted file mode 100644 index aa697b3927..0000000000 --- a/Code/CryEngine/CrySystem/ResourceManager.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Resource Manager - - -#ifndef CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H -#pragma once - - -#include -#include "AsyncPakManager.h" - -////////////////////////////////////////////////////////////////////////// -// IResource manager interface -////////////////////////////////////////////////////////////////////////// -class CResourceManager - : public IResourceManager - , public ISystemEventListener - , public AZ::IO::IArchiveFileAccessSink -{ -public: - CResourceManager(); - - void Init(); - void Shutdown(); - - bool IsStreamingCachePak(const char* filename) const; - - ////////////////////////////////////////////////////////////////////////// - // IResourceManager interface implementation. - ////////////////////////////////////////////////////////////////////////// - void PrepareLevel(const char* sLevelFolder, const char* sLevelName); - void UnloadLevel(); - AZ::IO::IResourceList* GetLevelResourceList(); - bool LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading); - void UnloadLevelCachePak(const char* sPakName); - bool LoadModeSwitchPak(const char* sPakName, const bool multiplayer); - void UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer); - bool LoadMenuCommonPak(const char* sPakName); - void UnloadMenuCommonPak(const char* sPakName, const char* sResourceListName); - bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly); - void UnloadAllAsyncPaks(); - bool LoadLayerPak(const char* sLayerName); - void UnloadLayerPak(const char* sLayerName); - void UnloadAllLevelCachePaks(bool bLevelLoadEnd); - void GetMemoryStatistics(ICrySizer* pSizer); - bool LoadFastLoadPaks(bool bToMemory); - void UnloadFastLoadPaks(); - CTimeValue GetLastLevelLoadTime() const; - void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // ISystemEventListener interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // IArchiveFileAccessSink interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void ReportFileOpen(AZ::IO::HandleType inFileHandle, AZStd::string_view szFullPath); - ////////////////////////////////////////////////////////////////////////// - - // Per frame update of the resource manager. - void Update(); - - CryPathString GetCurrentLevelCacheFolder() const { return m_currentLevelCacheFolder; }; - void SaveRecordedResources(bool bTotalList = false); - -private: - - ////////////////////////////////////////////////////////////////////////// - - CryPathString m_currentLevelCacheFolder; - - struct SOpenedPak - { - AZStd::fixed_string filename; - bool bOnlyDuringLevelLoading; - }; - std::vector m_openedPaks; - - CAsyncPakManager m_AsyncPakManager; - - string m_sLevelFolder; - string m_sLevelName; - bool m_bLevelTransitioning; - - bool m_bRegisteredFileOpenSink; - bool m_bOwnResourceList; - - CTimeValue m_beginLevelLoadTime; - CTimeValue m_lastLevelLoadTime; - - AZStd::intrusive_ptr m_pSequenceResourceList; - - CryCriticalSection recordedFilesLock; - std::vector m_recordedFiles; - - AZStd::vector< AZStd::fixed_string > m_fastLoadPakPaths; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp b/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp deleted file mode 100644 index 4344af45dc..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine - - -#include "CrySystem_precompiled.h" -#include -#include - -#include "AZRequestReadStream.h" -#include -#include -#include -#include "StreamEngine.h" - -AZRequestReadStream* AZRequestReadStream::Allocate(const EStreamTaskType tSource, const char* filename, IStreamCallback* callback, - const StreamReadParams* params) -{ - //Once an async method is available to read file sizes this code should be removed: - // and the file size should be known before calling this method and pass it as a - // parameter to this method. - //REMOVE In the Future START. - AZ::IO::SizeType fileSize = 0; - if (params && params->nSize) - { - fileSize = params->nSize; - } - else - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ::IO::Result res = fileIO->Size(filename, fileSize); - if (!res) - { - AZ_Error("AZRequestReadStream", false, "Failed to read file size of %s", filename); - return nullptr; - } - //REMOVE In the Future END. - } - - auto streamer = AZ::Interface::Get(); - - AZRequestReadStream* retReq; - retReq = aznew AZRequestReadStream(); - - retReq->m_Type = tSource; - retReq->m_fileName = filename; - retReq->m_callback = callback; - retReq->m_fileSize = fileSize; - //REMARK: if params->pBuffer is NOT NULL, then retReq->m_buffer - //should become params->pBuffer, this is called stream-in-place. - //The only reason we are not doing this here is because - //some platforms support stream-in-place to WRITE ONLY buffers. - //Because there are no guarantees that low level streaming and decompression apis - //would treat the output buffer as WRITE ONLY, we still allocate the buffer and memcpy - //to params->pBuffer upon the completion callback being called. - //Once LY-98089 is complete/fixed, we should be able to safely - //set retReq->m_buffer = params->pBuffer and skip the memory allocation. - retReq->m_buffer = azmalloc(fileSize, streamer->GetRecommendations().m_memoryAlignment); - if (params) - { - retReq->m_params = *params; - } - - return retReq; -} - -////////////////////////////////////////////////////////////////////////// -AZRequestReadStream::AZRequestReadStream() : m_fileName(""), m_fileRequest(nullptr), - m_buffer(nullptr), m_Type(eStreamTaskTypeTexture), - m_callback(nullptr), m_fileSize(0), m_numBytesRead(0), m_isAsyncCallbackExecuted(false), - m_isSyncCallbackExecuted(false), m_isFileRequestComplete(false), m_isError(false), m_isFinished(false), - m_IOError(0) -{ - AZStd::atomic_init(&m_refCount, 0); - m_params = StreamReadParams(); -} - -////////////////////////////////////////////////////////////////////////// -AZRequestReadStream::~AZRequestReadStream() -{ - azfree(m_buffer); -} - -// tries to stop reading the stream; this is advisory and may have no effect -// all the callbacks will be called after this. If you just destructing object, -// dereference this object and it will automatically abort and release all associated resources. -void AZRequestReadStream::Abort() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - // Increase ref counting to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (m_isFileRequestComplete || m_isError) - { - // It is possible the file I/O request to be completed by AZ::IO::Streamer, - // but if the completion callback is deferred for the main thread then - // the stream is not finished. So, only if it is finished then - // it is safe to do nothing. - if (m_isFinished) - { - return; - } - } - - m_isError = true; - m_IOError = ERROR_USER_ABORT; - m_isFileRequestComplete = true; - m_numBytesRead = 0; - - if (m_fileRequest) - { - auto streamer = AZ::Interface::Get(); - streamer->QueueRequest(streamer->Cancel(m_fileRequest)); - } - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_callback = nullptr; - } - -} - -bool AZRequestReadStream::TryAbort() -{ - // Increase ref counting to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (!m_callbackLock.TryLock()) - { - return false; - } - - if (m_isFileRequestComplete || m_isError) - { - // It is possible the file I/O request to be completed by AZ::IO::Streamer, - // but if the completion callback is deferred for the main thread then - // the stream is not finished. So, only if it is finished then - // it is safe to do nothing. - if (m_isFinished) - { - m_callbackLock.Unlock(); - return false; - } - } - - m_isError = true; - m_IOError = ERROR_USER_ABORT; - m_isFileRequestComplete = true; - m_numBytesRead = 0; - - if (m_fileRequest) - { - auto streamer = AZ::Interface::Get(); - streamer->QueueRequest(streamer->Cancel(m_fileRequest)); - } - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_callback = nullptr; - - m_callbackLock.Unlock(); - - return true; -} - -// tries to raise the priority of the read; this is advisory and may have no effect -void AZRequestReadStream::SetPriority(EStreamTaskPriority ePriority) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (m_params.ePriority != ePriority) - { - m_params.ePriority = ePriority; - if (m_fileRequest) - { - AZ::Interface::Get()->RescheduleRequest(m_fileRequest, AZ::IO::IStreamerTypes::s_noDeadline, - CStreamEngine::CryStreamPriorityToAZStreamPriority(ePriority)); - } - } -} - -// unconditionally waits until the callback is called -// i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback -// is called before return from this function (unless no callback was specified) -void AZRequestReadStream::Wait(int maxWaitMillis) -{ - // lock this object to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (!m_isFinished && !m_isError && !m_fileRequest) - { - AZ_Error("AZRequestReadStream", false, "Stream for file %s is unwaitable", m_fileName.c_str()); - return; - } - - if (maxWaitMillis > 0) - { - m_wait.try_acquire_for(AZStd::chrono::milliseconds(maxWaitMillis)); - } - else - { - m_wait.acquire(); - } -} - -////////////////////////////////////////////////////////////////////////// -const char* AZRequestReadStream::GetErrorName() const -{ - switch (m_IOError) - { - case ERROR_UNKNOWN_ERROR: - return "Unknown error"; - case ERROR_UNEXPECTED_DESTRUCTION: - return "Unexpected destruction"; - case ERROR_INVALID_CALL: - return "Invalid call"; - case ERROR_CANT_OPEN_FILE: - return "Cannot open the file"; - case ERROR_REFSTREAM_ERROR: - return "Refstream error"; - case ERROR_OFFSET_OUT_OF_RANGE: - return "Offset out of range"; - case ERROR_REGION_OUT_OF_RANGE: - return "Region out of range"; - case ERROR_SIZE_OUT_OF_RANGE: - return "Size out of range"; - case ERROR_CANT_START_READING: - return "Cannot start reading"; - case ERROR_OUT_OF_MEMORY: - return "Out of memory"; - case ERROR_ABORTED_ON_SHUTDOWN: - return "Aborted on shutdown"; - case ERROR_OUT_OF_MEMORY_QUOTA: - return "Out of memory quota"; - case ERROR_ZIP_CACHE_FAILURE: - return "ZIP cache failure"; - case ERROR_USER_ABORT: - return "User aborted"; - } - return "Unrecognized error"; -} - -int AZRequestReadStream::AddRef() -{ - return m_refCount.fetch_add(1) + 1; -} - -int AZRequestReadStream::Release() -{ - int refCount = m_refCount.fetch_sub(1); - -#ifndef _RELEASE - if (refCount < 1) - { - __debugbreak(); - } -#endif - - if (refCount == 1) - { - //UNUSUAL, yet necessary. - //Why "delete this"? - //So, AZRequestReadStream is a replacement of CReadStream. The original design of - //Cry Texture Mips Streaming makes use of CReadStream through IReadStreamPtr, which - //is a smart pointer design that calls AddRef() and Release() but never calls "delete", - //like AZStd::shared_ptr<> does. This means the original Cry design had a memory leak - //because it never called delete on IReadStream objects. If you look at the original - //code of CReadStream (StreamReadStream.cpp) , the static Allocate method has two paths - //to allocate memory, one used a stack based memory allocation hack, and the other path - //was doing a "new CReadStream". Using VS2017 debugger I found both paths to be used, but - //"delete" and hence the destructor of CReadStream is never called causing minor memory leaks. - //The best solution I found was to call "delete this" here and later when we chnage IReadStreamPtr - //for AZstd::smart_ptr then AddRef() and Release() won't be needed anymore and this "delete this" - //hack won't be necessary either. - delete this; - } - - return refCount - 1; -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::ExecuteAsyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_isAsyncCallbackExecuted && m_callback) - { - m_isAsyncCallbackExecuted = true; - m_callback->StreamAsyncOnComplete(this, m_IOError); - } -} - -void AZRequestReadStream::ExecuteSyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_isSyncCallbackExecuted && m_callback && (0 == (m_params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK))) - { - m_isSyncCallbackExecuted = true; - - AZRequestReadStream_AutoPtr refCountLock(this); // Stream can be freed inside the callback! - - m_callback->StreamOnComplete(this, m_IOError); - - m_isFinished = true; - FreeTemporaryMemory(); - } - -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::FreeTemporaryMemory() -{ - // Make sure m_buffer is not freed if the file request is still in flight, as Streamer can still write to m_buffer in that case - if (!m_fileRequest || AZ::Interface::Get()->HasRequestCompleted(m_fileRequest)) - { - azfree(m_buffer); - m_buffer = nullptr; - m_numBytesRead = 0; - } -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::OnRequestComplete(AZ::IO::SizeType numBytesRead, [[maybe_unused]] void* buffer, AZ::IO::IStreamerTypes::RequestStatus requestState) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (!m_isFileRequestComplete) - { - switch (requestState) - { - case AZ::IO::IStreamerTypes::RequestStatus::Completed: - m_IOError = 0; - m_numBytesRead = static_cast(numBytesRead); - m_isError = false; - if (m_params.pBuffer) - { - //In some systems, streaming-in-place is supported. The caveat - //is that in some cases, the destination buffer is write-only. This is why - //a final memcpy must be done here until support is added to AZ::IO::Streamer API - //to decompress/load data into write-only buffers. SEE: LY-98089 - AZ_Assert(m_params.pBuffer != m_buffer, "Streaming-In-Place requires destination and source buffers to be different"); - memcpy(m_params.pBuffer, m_buffer, numBytesRead); - } - break; - case AZ::IO::IStreamerTypes::RequestStatus::Canceled: - m_IOError = ERROR_USER_ABORT; - m_numBytesRead = 0; - m_isError = true; - break; - default: - m_IOError = ERROR_UNKNOWN_ERROR; - m_numBytesRead = 0; - m_isError = true; - break; - } - - ExecuteAsyncCallback_CBLocked(); - m_isFileRequestComplete = true; - - if (m_params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) - { - // We do not need FileRequest here anymore, and not its temporary memory. - m_fileRequest = nullptr; - m_isFinished = true; - } - else - { - //The completion must be triggered from MainThread. (Typically only happens when loading Terrain Macro Textures - AddRef(); - AZ::SystemTickBus::QueueFunction([this] { - RequestCompleteOnMainThread(); - }); - } - } - - m_wait.release(); -} - - -void AZRequestReadStream::RequestCompleteOnMainThread() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - // call asynchronous callback function if needed synchronously - { - CryAutoCriticalSection lock(m_callbackLock); - ExecuteSyncCallback_CBLocked(); - } - - //Always called because before enqueuing this call was called AddRef() - Release(); -} - diff --git a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h b/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h deleted file mode 100644 index be925ad6c0..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Description : An IReadStream implementation designed to work with AZ::IO::Streamer -// instead of CStreamEngine. - -#pragma once - -#include -#include -#include -#include -#include "IStreamEngine.h" - -namespace AZ -{ - namespace IO - { - class Request; - } -} - -//This class is a wrapper of AZ::IO::Request so Cry Classes can use AZ::IO::Streamer. -//Basicallythis replaces CReadStream. -class AZRequestReadStream - : public IReadStream -{ -public: - AZ_CLASS_ALLOCATOR(AZRequestReadStream, AZ::SystemAllocator, 0); - - static AZRequestReadStream* Allocate(const EStreamTaskType tSource, const char* filename, IStreamCallback* callback, - const StreamReadParams* params); - - int AddRef() override; - int Release() override; - - DWORD_PTR GetUserData() override {return m_params.dwUserData; } - - // set user defined data into stream's params - void SetUserData(DWORD_PTR userData) override { m_params.dwUserData = userData; }; - - // returns true if the file read was not successful. - bool IsError() override { return m_isError; }; - - // returns true if the file read was completed (successfully or unsuccessfully) - // check IsError to check if the whole requested file (piece) was read - bool IsFinished() override { return m_isFinished; }; - - // returns the number of bytes read so far (the whole buffer size if IsFinished()) - unsigned int GetBytesRead([[maybe_unused]] bool bWait) override { return static_cast(m_numBytesRead); }; - - // returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read - const void* GetBuffer() override { return m_buffer; }; - - // tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - void Abort() override; - bool TryAbort() override; - - - - // unconditionally waits until the callback is called - // i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified) - void Wait(int maxWaitMillis = -1) override; - - const StreamReadParams& GetParams() const override {return m_params; } - - const EStreamTaskType GetCallerType() const override { return m_Type; } - - //We must define this one. But it is never used in the context of AZ::IO::Streamer. - //Legacy Cry StreamEngine stuff. - EStreamSourceMediaType GetMediaType() const override { return EStreamSourceMediaType::eStreamSourceTypeUnknown; } - - // return pointer to callback routine(can be NULL) - IStreamCallback* GetCallback() const override { return m_callback; }; - - // return IO error # - unsigned GetError() const override { return m_IOError; }; - - // Returns IO error name - const char* GetErrorName() const override; - - // return stream name - const char* GetName() const override { return m_fileName.c_str(); }; - - void FreeTemporaryMemory() override; - - // tries to raise the priority of the read; this is advisory and may have no effect - void SetPriority(EStreamTaskPriority EPriority); - uint64 GetPriority() const { return m_params.ePriority; }; - - void* GetFileReadBuffer() { return m_buffer; } //GetBuffer from IReadStream is "const void *" - AZStd::size_t GetFileSize() { return m_fileSize; } - - void SetFileRequest(AZ::IO::FileRequestPtr request) { m_fileRequest = AZStd::move(request); } - AZ::IO::FileRequestPtr GetFileRequest() { return m_fileRequest; } - - void OnRequestComplete(AZ::IO::SizeType numBytesRead, void* buffer, AZ::IO::IStreamerTypes::RequestStatus requestState); - -private: - AZRequestReadStream(); - virtual ~AZRequestReadStream(); - - // call the async callback - void ExecuteAsyncCallback_CBLocked(); - void ExecuteSyncCallback_CBLocked(); - void RequestCompleteOnMainThread(); - - AZStd::atomic_int m_refCount; - - CryCriticalSection m_callbackLock; - StreamReadParams m_params; - AZStd::semaphore m_wait; - - CryStringLocal m_fileName; - AZ::IO::FileRequestPtr m_fileRequest; - - // Bytes actually read from media. - void* m_buffer; - - // the type of the task - EStreamTaskType m_Type; - // the initial data from the user - // the callback; may be NULL - IStreamCallback* m_callback; - - AZ::IO::SizeType m_fileSize; //Expected number of bytes to be read. - AZ::IO::SizeType m_numBytesRead; //On a successful read m_nBytesRead == m_fileSize; - - bool m_isAsyncCallbackExecuted; - bool m_isSyncCallbackExecuted; - bool m_isFileRequestComplete; - - bool m_isError; - bool m_isFinished; - unsigned int m_IOError; -}; - -TYPEDEF_AUTOPTR(AZRequestReadStream); diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp deleted file mode 100644 index 61052bc991..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp +++ /dev/null @@ -1,1027 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "StreamAsyncFileRequest.h" - -#include - -#include "StreamEngine.h" -#include "../System.h" -#include -#include - -extern CMTSafeHeap* g_pPakHeap; - -#if defined(STREAMENGINE_ENABLE_STATS) -extern SStreamEngineStatistics* g_pStreamingStatistics; -#endif - -extern SStreamEngineOpenStats* g_pStreamingOpenStatistics; - -volatile int CAsyncIOFileRequest::s_nLiveRequests; -SLockFreeSingleLinkedListHeader CAsyncIOFileRequest::s_freeRequests; - - -#ifdef STREAMENGINE_ENABLE_LISTENER - -class NotifyListenerIO -{ -public: - NotifyListenerIO(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq, AZ::IO::CCachedFileData* pZipEntry, uint32 readSize) - : m_pL(pL) - , m_pReq(pReq) - { - if (m_pL) - { - m_pL->OnStreamBeginIO( - m_pReq, - (pZipEntry && pZipEntry->m_pFileEntry->nMethod) ? pZipEntry->GetFileEntry()->desc.lSizeCompressed : m_pReq->m_nFileSize, - readSize, - pReq->m_eMediaType); - } - } - ~NotifyListenerIO() - { - End(); - } - void End() - { - if (m_pL) - { - m_pL->OnStreamEndIO(m_pReq); - m_pL = NULL; - } - } - -private: - NotifyListenerIO(const NotifyListenerIO&); - NotifyListenerIO& operator = (const NotifyListenerIO&); - -private: - IStreamEngineListener* m_pL; - CAsyncIOFileRequest* m_pReq; -}; - -#endif //STREAMENGINE_ENABLE_LISTENER - -////////////////////////////////////////////////////////////////////////// - -void* CAsyncIOFileRequest::operator new (size_t sz) -{ - return CryModuleMemalign(sz, alignof(CAsyncIOFileRequest)); -} - -void CAsyncIOFileRequest::operator delete(void* p) -{ - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest::CAsyncIOFileRequest() - : m_nRefCount(0) - , m_pMemoryBuffer(NULL) -{ - Reset(); -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest::~CAsyncIOFileRequest() -{ -#ifndef _RELEASE - if (m_pMemoryBuffer) - { - __debugbreak(); - } - if (m_eType) - { - __debugbreak(); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -uint32 CAsyncIOFileRequest::ConfigureRead(AZ::IO::CCachedFileData* pFileData) -{ - AZ::IO::ZipDir::FileEntry* pFileEntry = pFileData ? pFileData->m_pFileEntry : NULL; - - if (!pFileData || !pFileEntry->IsCompressed()) - { - m_bCompressedBuffer = false; - m_nFileSizeCompressed = m_nFileSize; - m_nSizeOnMedia = m_nRequestedSize; - - m_nPageReadStart = m_nRequestedOffset; - m_nPageReadEnd = m_nRequestedOffset + m_nRequestedSize; - } - else - { - m_bCompressedBuffer = true; - m_nFileSize = pFileEntry->desc.lSizeUncompressed; - m_nFileSizeCompressed = pFileEntry->desc.lSizeCompressed; - m_nSizeOnMedia = m_nFileSizeCompressed; - - m_nPageReadStart = 0; - m_nPageReadEnd = m_nFileSizeCompressed; - } - - if (pFileData && !m_bWriteOnlyExternal) - { - m_crc32FromHeader = pFileEntry->desc.lCRC32; - } - - m_nPageReadCurrent = 0; - - m_bStreamInPlace = !m_bCompressedBuffer || ((!m_pExternalMemoryBuffer || !m_bWriteOnlyExternal) && (m_nFileSize > m_nFileSizeCompressed)); - m_bReadBegun = 1; - - return 0; -} - -bool CAsyncIOFileRequest::CanReadInPages() -{ - bool bReadInBlocks = false; - - if (g_cvars.sys_streaming_in_blocks) - { - //stream is compressed and uncompressed size is greater than one page - if (!m_bCompressedBuffer || m_nFileSizeCompressed > STREAMING_BLOCK_SIZE) - { - bReadInBlocks = true; - } - } - - return bReadInBlocks; -} - -uint32 CAsyncIOFileRequest::AllocateOutput([[maybe_unused]] AZ::IO::CCachedFileData* pZipEntry) -{ - if (!m_bOutputAllocated) - { - uint32 nAllocSize = 0; - uint32 nReadAllocSize = 0; - uint32 nZStreamOffs = 0; - uint32 nLookaheadOffs = 0; - - if (m_pExternalMemoryBuffer) - { - nReadAllocSize = m_bCompressedBuffer - ? (m_nRequestedSize < m_nFileSize ? m_nFileSize : 0) - : 0; - } - else - { - nReadAllocSize = m_bCompressedBuffer - ? m_nFileSize - : m_nRequestedSize; - } - - nAllocSize = Align(nReadAllocSize, BUFFER_ALIGNMENT); - - bool bReadInBlocks = CanReadInPages(); - bool bNeedsLookahead = m_bStreamInPlace; - bool bBlockDecompress = m_bCompressedBuffer && bReadInBlocks; - - if (bBlockDecompress) - { - nZStreamOffs = nAllocSize; - nAllocSize += Align(sizeof(z_stream), BUFFER_ALIGNMENT); - - if (bNeedsLookahead) - { - nLookaheadOffs = nAllocSize; - nAllocSize += Align(sizeof(*m_pLookahead), BUFFER_ALIGNMENT); - } - } - - char* pBuffer = NULL; - - if (nAllocSize) - { - const char* usageHint = "AsyncIO TempBuffer"; - pBuffer = (char*)GetStreamEngine()->TempAlloc(nAllocSize, usageHint, true, IgnoreOutofTmpMem(), BUFFER_ALIGNMENT); - if (!pBuffer) - { - return ERROR_OUT_OF_MEMORY; - } - } - - if (pBuffer) - { - m_pMemoryBuffer = pBuffer; - m_nMemoryBufferSize = nAllocSize; - } - - if (nReadAllocSize) - { - m_pReadMemoryBuffer = pBuffer; - m_nReadMemoryBufferSize = nReadAllocSize; - } - else - { - m_pReadMemoryBuffer = m_pExternalMemoryBuffer; - m_nReadMemoryBufferSize = m_nRequestedSize; - } - - m_pOutputMemoryBuffer = m_pExternalMemoryBuffer - ? m_pExternalMemoryBuffer - : m_pReadMemoryBuffer; - - if (bBlockDecompress) - { - m_pZlibStream = (z_stream*)&pBuffer[nZStreamOffs]; - memset(m_pZlibStream, 0, sizeof(z_stream)); - - if (bNeedsLookahead) - { - m_pLookahead = new (&pBuffer[nLookaheadOffs]) AZ::IO::ZipDir::UncompressLookahead; - } - - m_pZlibStream->zalloc = CMTSafeHeap::StaticAlloc; - m_pZlibStream->zfree = CMTSafeHeap::StaticFree; - m_pZlibStream->opaque = g_pPakHeap; - } - - if (m_bCompressedBuffer) - { - m_pDecompQueue = new SStreamJobQueue; - } - - // Doesn't need to be atomic, as there's no concurrency yet. - int nMemoryBufferUsers = 0; - if (nReadAllocSize > 0) - { - ++nMemoryBufferUsers; - } - if (m_bCompressedBuffer) - { - ++nMemoryBufferUsers; - } - m_nMemoryBufferUsers = nMemoryBufferUsers; - - m_bOutputAllocated = 1; - } - - return 0; -} - -byte* CAsyncIOFileRequest::AllocatePage(size_t sz, bool bOnlyPakMem, SStreamPageHdr*& pHdrOut) -{ - const char* usageHint = "streaming page"; - size_t nSzAligned = Align(sz, BUFFER_ALIGNMENT); - size_t nToAlloc = nSzAligned + sizeof(SStreamPageHdr); - byte* pRet = (byte*)GetStreamEngine()->TempAlloc(nToAlloc, usageHint, true, !bOnlyPakMem, BUFFER_ALIGNMENT); - if (pRet) - { - pHdrOut = new (pRet + nSzAligned)SStreamPageHdr(nToAlloc); - } - - return pRet; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::Cancel() -{ - if (!HasFailed()) - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - CryOptionalAutoLock decompLock(m_externalBufferLockDecompress, m_pExternalMemoryBuffer != NULL); - - Failed(ERROR_USER_ABORT); - } -} - -void CAsyncIOFileRequest::SyncWithDecompress() -{ - m_decompJobExecutor.reset(); // destructor waits on job completion -} - -////////////////////////////////////////////////////////////////////////// -bool CAsyncIOFileRequest::TryCancel() -{ - if (!HasFailed()) - { - bool bExt = false; - if (m_pExternalMemoryBuffer != NULL) - { - if (!m_externalBufferLockRead.TryLock()) - { - return false; - } - if (!m_externalBufferLockDecompress.TryLock()) - { - m_externalBufferLockRead.Unlock(); - return false; - } - bExt = true; - } - - Failed(ERROR_USER_ABORT); - - if (bExt) - { - m_externalBufferLockDecompress.Unlock(); - m_externalBufferLockRead.Unlock(); - } - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::FreeBuffer() -{ - if (m_pZlibStream) - { - //if the stream was cancelled in flight, inform zlib to free internal allocs - if (m_pZlibStream->state) - { - inflateEnd(m_pZlibStream); - } - - m_pZlibStream = NULL; - } - - m_pLookahead = NULL; - - SStreamEngineTempMemStats& tms = GetStreamEngine()->GetTempMemStats(); - - if (m_pDecompQueue) - { - m_pDecompQueue->Flush(tms); - delete m_pDecompQueue; - m_pDecompQueue = NULL; - } - - if (m_pMemoryBuffer) - { - CStreamEngine* pStreamEngine = GetStreamEngine(); - - pStreamEngine->TempFree(m_pMemoryBuffer, m_nMemoryBufferSize); - m_pMemoryBuffer = 0; - } - -#ifdef STREAMENGINE_ENABLE_STATS - // Update Streaming statistics. - if (g_pStreamingStatistics && m_nSizeOnMedia != 0 && m_bStatsUpdated) - { - m_bStatsUpdated = false; - int nSize = (int)m_nSizeOnMedia; - SStreamEngineStatistics& stats = *g_pStreamingStatistics; - CryInterlockedAdd(&stats.nPendingReadBytes, -nSize); - CryInterlockedAdd(&stats.typeInfo[m_eType].nPendingReadBytes, -nSize); - } -#endif -} - -CAsyncIOFileRequest* CAsyncIOFileRequest::Allocate(EStreamTaskType eType) -{ - CAsyncIOFileRequest* pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests)); - IF_UNLIKELY (!pReq) - { - pReq = new CAsyncIOFileRequest; - } - - pReq->Init(eType); - - return pReq; -} - -void CAsyncIOFileRequest::Flush() -{ - for (CAsyncIOFileRequest* pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests)); - pReq; - pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests))) - { - delete pReq; - } -} - -void CAsyncIOFileRequest::Reset() -{ - m_decompJobExecutor.reset(); // destructor waits on job completion - -#ifndef _RELEASE - if (m_pMemoryBuffer) - { - __debugbreak(); - } -#endif - - m_pReadStream = NULL; - m_strFileName.resize(0); - m_pakFile.resize(0); - - // Reset POD members of the structure - memset(&m_nSortKey, 0, ((char*)(this + 1) - (char*)&m_nSortKey)); -} - -void CAsyncIOFileRequest::Init(EStreamTaskType eType) -{ -#ifndef _RELEASE - if (!eType) - { - __debugbreak(); - } -#endif - - m_eType = eType; - -#ifdef STREAMENGINE_ENABLE_STATS - m_startTime = gEnv->pTimer->GetAsyncTime(); -#endif - - if (g_pStreamingOpenStatistics) - { - SStreamEngineOpenStats& stats = *g_pStreamingOpenStatistics; - CryInterlockedIncrement(&stats.nOpenRequestCount); - CryInterlockedIncrement(&stats.nOpenRequestCountByType[eType]); - } - - CryInterlockedIncrement(&s_nLiveRequests); -} - -void CAsyncIOFileRequest::Finalize() -{ -#ifndef _RELEASE - if (!m_eType) - { - __debugbreak(); - } -#endif - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamDone(this); - } -#endif - - if (g_pStreamingOpenStatistics) - { - SStreamEngineOpenStats& stats = *g_pStreamingOpenStatistics; - CryInterlockedDecrement(&stats.nOpenRequestCount); - CryInterlockedDecrement(&stats.nOpenRequestCountByType[m_eType]); - } - - CryInterlockedDecrement(&s_nLiveRequests); - - FreeBuffer(); - Reset(); -} - -uint32 CAsyncIOFileRequest::OpenFile(CCryFile& file) -{ - auto* pIPak = gEnv ? gEnv->pCryPak : NULL; - PREFAST_ASSUME(pIPak); - - if (m_pReadStream && m_pReadStream->GetParams().nFlags & IStreamEngine::FLAGS_FILE_ON_DISK) - { - pIPak = 0; - } - - file = CCryFile(pIPak); - if (!file.Open(m_strFileName.c_str(), "rb", AZ::IO::IArchive::FOPEN_FORSTREAMING)) - { - return ERROR_CANT_OPEN_FILE; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -uint32 CAsyncIOFileRequest::ReadFile(CStreamingIOThread* pIOThread) -{ - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - CCryFile file; - nError = OpenFile(file); - if (nError) - { - return nError; - } - - m_nFileSize = file.GetLength(); - - if (m_nRequestedOffset >= m_nFileSize) - { - return ERROR_OFFSET_OUT_OF_RANGE; - } - - if (m_nRequestedOffset + m_nRequestedSize > m_nFileSize) - { - return ERROR_SIZE_OUT_OF_RANGE; - } - - if (m_nRequestedSize == 0) - { - // by default, we read the whole file - m_nRequestedSize = m_nFileSize - m_nRequestedOffset; - } - - if (!m_pExternalMemoryBuffer && m_pReadStream) - { - bool bAbortOnFailToAlloc = false; - CReadStream* pReadStream = static_cast(&*m_pReadStream); - m_pExternalMemoryBuffer = pReadStream->OnNeedStorage(m_nFileSize, bAbortOnFailToAlloc); - - if (!m_pExternalMemoryBuffer && bAbortOnFailToAlloc) - { - Cancel(); - m_pReadStream->Abort(); - return ERROR_USER_ABORT; - } - } - - if (HasFailed()) - { - return m_nError; - } - - auto pZipEntry = ((AZ::IO::Archive*)(gEnv->pCryPak))->GetOpenedFileDataInZip(file.GetHandle()); - nError = ConfigureRead(pZipEntry.get()); - if (nError) - { - return nError; - } - - nError = AllocateOutput(pZipEntry.get()); - if (nError) - { - return nError; - } - - return ReadFileInPages(pIOThread, file); -} - -uint32 CAsyncIOFileRequest::ReadFileResume(CStreamingIOThread* pIOThread) -{ - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - CCryFile file; - nError = OpenFile(file); - if (nError) - { - return nError; - } - - auto pZipEntry = ((AZ::IO::Archive*)(gEnv->pCryPak))->GetOpenedFileDataInZip(file.GetHandle()); - - nError = AllocateOutput(pZipEntry.get()); - if (nError) - { - return nError; - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamResumed(this); - } -#endif - - return ReadFileInPages(pIOThread, file); -} - -uint32 CAsyncIOFileRequest::ReadFileInPages(CStreamingIOThread* pIOThread, CCryFile& file) -{ - auto pCryPak = static_cast(gEnv->pCryPak); - auto pZipEntry = pCryPak->GetOpenedFileDataInZip(file.GetHandle()); - - AZ::IO::ZipDir::Cache* pZip = NULL; - unsigned int nZipFlags = 0; - if (pZipEntry) - { - pZip = pZipEntry->GetZip(); - nZipFlags = pZipEntry->m_nArchiveFlags; - } - - if (pIOThread->IsMisscheduled(EStreamSourceMediaType::eStreamSourceTypeHDD)) - { - // We're on the wrong IO thread! - return ERROR_MISSCHEDULED; - } - - bool bReadInPages = CanReadInPages(); - - uint32 nPageReadLen = (m_nPageReadEnd - m_nPageReadStart); - - bool const bCompressed = m_bCompressedBuffer; - bool const bInPlace = m_bStreamInPlace; - bool const bIgnoreOutOfTmp = IgnoreOutofTmpMem(); - - size_t const nReadStartOffset = bCompressed - ? (m_nFileSize - m_nFileSizeCompressed) - : 0; - - byte* const pReadBase = (byte*)m_pReadMemoryBuffer + nReadStartOffset; - byte* const pReadEnd = (byte*)m_pReadMemoryBuffer + m_nReadMemoryBufferSize; - - CStreamEngine* pStreamEngine = static_cast(gEnv->pSystem->GetStreamEngine()); - - uint32 nPageSize = bReadInPages - ? min((uint32)STREAMING_PAGE_SIZE, nPageReadLen - m_nPageReadCurrent) - : nPageReadLen - m_nPageReadCurrent; - - while (nPageSize > 0) - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - //check if job needs to be pre-empted - nError = ReadFileCheckPreempt(pIOThread); - if (nError) - { - return nError; - } - - byte* pReadTarget = pReadBase + m_nPageReadCurrent; - byte* pReadTargetEnd = pReadTarget + nPageSize; - bool bTemporaryReadTarget = false; - SStreamPageHdr* pTemporaryPageHdr = NULL; - - if (bInPlace) - { - if (pReadTargetEnd > pReadEnd) - { - __debugbreak(); - } - } - else - { - pReadTarget = AllocatePage(nPageSize, !bIgnoreOutOfTmp, pTemporaryPageHdr); - - if (!pReadTarget) - { - return ERROR_OUT_OF_MEMORY; - } - - bTemporaryReadTarget = true; - pTemporaryPageHdr->nRefs = 1; - } - -#ifndef _RELEASE - if (m_nPageReadCurrent + nPageSize > nPageReadLen) - { - __debugbreak(); - } -#endif - - { -#ifdef STREAMENGINE_ENABLE_LISTENER - NotifyListenerIO IOListener(gEnv->pSystem->GetStreamEngine()->GetListener(), this, pZipEntry.get(), nPageSize); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - CTimeValue t0 = gEnv->pTimer->GetAsyncTime(); -#endif - - //printf("[StreamRead] %p %i %p %i %i\n", this, m_bCompressedBuffer, pReadTarget, m_nPageReadStart + m_nPageReadCurrent, nPageSize); - - bool bReadOk = false; - - if (pZipEntry) - { - bReadOk = pZipEntry->m_pZip->ReadFile(pZipEntry->m_pFileEntry, pReadTarget, nullptr) == AZ::IO::ZipDir::ZD_ERROR_SUCCESS; - } - else - { - file.Seek(m_nPageReadStart + m_nPageReadCurrent, SEEK_SET); - bReadOk = file.ReadRaw(pReadTarget, nPageSize) == nPageSize; - } - - if (bReadOk) - { - //send each block to listener -#ifdef STREAMENGINE_ENABLE_LISTENER - IOListener.End(); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - m_readTime += gEnv->pTimer->GetAsyncTime() - t0; -#endif - - //release external mem lock, allows jobs to be cancelled mid stream - readLock.Release(); - } - else - { - if (bTemporaryReadTarget) - { - GetStreamEngine()->TempFree(pReadTarget, pTemporaryPageHdr->nSize); - } - - return ERROR_REFSTREAM_ERROR; - } - - bool bLastBlock = (m_nPageReadCurrent + nPageSize) == nPageReadLen; - - if (bCompressed) - { - PushDecompressPage(pStreamEngine->GetJobEngineState(), pReadTarget, pTemporaryPageHdr, nPageSize, bLastBlock); - } - else if (bTemporaryReadTarget) - { - __debugbreak(); - } - - if (pTemporaryPageHdr && CryInterlockedDecrement(&pTemporaryPageHdr->nRefs) == 0) - { - GetStreamEngine()->TempFree(pReadTarget, pTemporaryPageHdr->nSize); - } - - m_nPageReadCurrent += nPageSize; - nPageSize = min((uint32)STREAMING_PAGE_SIZE, nPageReadLen - m_nPageReadCurrent); - } - } - - return 0; -} - -uint32 CAsyncIOFileRequest::ReadFileCheckPreempt(CStreamingIOThread* pIOThread) -{ - if (m_ePriority != estpUrgent) - { - if (pIOThread->HasUrgentRequests()) - { - //printf("Read Job %s pre-empted mid stream. Progress %d / %d bytes\n", m_strFileName.c_str(), m_nBytesRead, m_nFileSizeCompressed); -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamPreempted(this); - } -#endif - return ERROR_PREEMPTED; - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -CStreamEngine* CAsyncIOFileRequest::GetStreamEngine() -{ - return (CStreamEngine*)GetISystem()->GetStreamEngine(); -} - -////////////////////////////////////////////////////////////////////////// -EStreamSourceMediaType CAsyncIOFileRequest::GetMediaType() -{ - EStreamSourceMediaType mediaType = m_eMediaType; - - if (mediaType == eStreamSourceTypeUnknown) - { - if (m_bSortKeyComputed) - { - return mediaType; - } - - if (m_strFileName.empty()) - { - mediaType = eStreamSourceTypeMemory; - return mediaType; - } - - mediaType = gEnv->pCryPak->GetFileMediaType(m_strFileName.c_str()); - } - - return mediaType; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::ComputeSortKey(uint64 nCurrentKeyInProgress) -{ - if (m_bSortKeyComputed) - { - return; - } - - m_bSortKeyComputed = true; - - if (m_strFileName.empty()) - { - m_eMediaType = eStreamSourceTypeMemory; - m_nSortKey = m_ePriority; - return; - } - if (HasFailed()) - { - m_nSortKey = 0; - return; - } - - const int MaxPath = 0x800; - char szFullPathBuf[MaxPath]; - const char* szFullPath = gEnv->pCryPak->AdjustFileName(m_strFileName.c_str(), szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), AZ::IO::IArchive::FOPEN_HINT_QUIET); - - auto pCryPak = static_cast(gEnv->pCryPak); - - AZ::IO::ZipDir::CachePtr pZip = 0; - unsigned int archFlags = 0; - AZ::IO::ZipDir::FileEntry* pFileEntry = NULL; - - // tests if the given file path refers to an existing file inside registered (opened) packs - // the path must be absolute normalized lower-case with forward-slashes - AZ::IO::ArchiveLocationPriority varPakPriority = pCryPak->GetPakPriority(); - bool willOpenFromPak = (varPakPriority != AZ::IO::ArchiveLocationPriority::ePakPriorityFileFirst) - || !AZ::IO::FileIOBase::GetDirectInstance()->Exists(szFullPath); - - if (willOpenFromPak) - { - pFileEntry = pCryPak->FindPakFileEntry(szFullPath, archFlags, &pZip, false); - } - - EStreamSourceMediaType ssmt = pCryPak->GetFileMediaType(szFullPath); - - if (pFileEntry) - { - pZip->Refresh(pFileEntry); - m_nDiskOffset = (uint64)pFileEntry->nFileDataOffset; - - m_nSizeOnMedia = pFileEntry->desc.lSizeCompressed; - m_nFileSize = pFileEntry->desc.lSizeUncompressed; - - m_pakFile = pZip->GetFilePath(); - } - - m_eMediaType = ssmt; - - if (ssmt != eStreamSourceTypeMemory) - { - int32 nCurrentSweep = (nCurrentKeyInProgress >> 30) & ((1 << 10) - 1); - int32 nCurrentTG = (nCurrentKeyInProgress >> 40) & ((1 << 20) - 1); - - if (pFileEntry && !pFileEntry->IsCompressed()) - { - m_nDiskOffset += m_nRequestedOffset; - } - - // group items by priority, then by snapped request time, then sort by disk offset - m_nTimeGroup = (uint64)(gEnv->pTimer->GetAsyncTime().GetSeconds() / max(1, g_cvars.sys_streaming_requests_grouping_time_period)); - m_nSweep = (m_nTimeGroup == nCurrentTG) - ? nCurrentSweep - : 0; - uint64 nPrioriry = m_ePriority; - - int64 nDiskOffsetKB = m_nDiskOffset >> 10; // KB - m_nSortKey = (nDiskOffsetKB) | (((uint64)m_nTimeGroup) << 40) | ((uint64)m_nSweep << 30) | (nPrioriry << 60); - - // make sure we do not break incremental head movement within time group on every new request - if (m_nSortKey <= nCurrentKeyInProgress) - { - ++m_nSweep; - m_nSortKey = (nDiskOffsetKB) | (((uint64)m_nTimeGroup) << 40) | ((uint64)m_nSweep << 30) | (nPrioriry << 60); - } - } - else - { - m_nSortKey = m_ePriority; - } - -#if defined(STREAMENGINE_ENABLE_STATS) - // Update Streaming statistics. - if (!m_bStatsUpdated && g_pStreamingStatistics && m_nSizeOnMedia != 0) - { - m_bStatsUpdated = true; - SStreamEngineStatistics& stats = *g_pStreamingStatistics; - - // if the file is not compressed then it will only read the requested size - uint32 nReadSize = m_nSizeOnMedia; - if (m_nSizeOnMedia == m_nFileSize) - { - nReadSize = m_nRequestedSize; - } - - CryInterlockedAdd(&stats.nPendingReadBytes, nReadSize); - CryInterlockedAdd(&stats.typeInfo[m_eType].nPendingReadBytes, nReadSize); - } -#endif -} - -void CAsyncIOFileRequest::SetPriority(EStreamTaskPriority estp) -{ - m_ePriority = estp; - - if (m_eMediaType != eStreamSourceTypeMemory) - { - m_nSortKey &= ~(15ULL << 60); - m_nSortKey |= static_cast(estp) << 60; - } - else - { - m_nSortKey = m_ePriority; - } -} - -void CAsyncIOFileRequest::BumpSweep() -{ - ++m_nSweep; - if (m_eMediaType != eStreamSourceTypeMemory) - { - m_nSortKey += 1 << 30; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CAsyncIOFileRequest::IgnoreOutofTmpMem() const -{ - if (m_pReadStream && - (m_pReadStream->GetParams().ePriority == estpUrgent || - m_pReadStream->GetParams().nFlags & IStreamEngine::FLAGS_IGNORE_TMP_OUT_OF_MEM)) - { - return true; - } - - return false; -} - -SStreamRequestQueue::SStreamRequestQueue() -{ - m_requests.reserve(4096); -} - -SStreamRequestQueue::~SStreamRequestQueue() -{ - Reset(); -} - -void SStreamRequestQueue::Reset() -{ - CryAutoLock l(m_lock); - for (size_t i = 0, c = m_requests.size(); i != c; ++i) - { - m_requests[i]->Release(); - } - m_requests.clear(); -} - -bool SStreamRequestQueue::IsEmpty() const -{ - return m_requests.empty(); -} - -bool SStreamRequestQueue::TryPopRequest(CAsyncIOFileRequest_AutoPtr& pOut) -{ - CryAutoLock l(m_lock); - if (!m_requests.empty()) - { - pOut = m_requests.front(); - pOut->Release(); - m_requests.erase(m_requests.begin()); - return true; - } - return false; -} - -void* SStreamEngineTempMemStats::TempAlloc(CMTSafeHeap* pHeap, size_t nSize, const char* szDbgSource, bool bFallBackToMalloc, bool bUrgent, uint32 align) -{ - // Only allow falling back to malloc if the size fits within the stream budget, the request is urgent, or the temp memory is 0 - for those files that are over budget on their own. - long nInUse = m_nTempAllocatedMemory; - bFallBackToMalloc = - bUrgent - || (bFallBackToMalloc && ((nInUse == 0) || (nInUse + static_cast(nSize) <= m_nTempMemoryBudget))) - ; - - void* p = pHeap->TempAlloc(nSize, szDbgSource, bFallBackToMalloc, align); -#if MTSAFE_USE_GENERAL_HEAP - bool bInGenHeap = pHeap->IsInGeneralHeap(p); -#else - bool bInGenHeap = false; -#endif - if (p && !bInGenHeap) - { - ReportTempMemAlloc(nSize, 0, false); - } - - return p; -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h deleted file mode 100644 index 4a112ef68f..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h +++ /dev/null @@ -1,571 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Thread for IO - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H -#pragma once - -#include -#include -#include "TimeValue.h" - -#define STREAMENGINE_LL_ALIGN _MS_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) - -class CStreamEngine; -class CAsyncIOFileRequest; -struct z_stream_s; -class CStreamingIOThread; -namespace AZ::IO -{ - struct CCachedFileData; -} -class CCryFile; -struct SStreamJobEngineState; -class CMTSafeHeap; -class CAsyncIOFileRequest_TransferPtr; -struct SStreamEngineTempMemStats; - -#if !defined(USE_EDGE_ZLIB) -// Prevent compilation conflicts - zconf.h (included by zlib.h) defines WINDOWS and WIN32 - those -// definitions conflict with CryEngine's definitions. - -# if defined(CRY_TMP_DEFINED_WINDOWS) || defined(CRY_TMP_DEFINED_WIN32) -# error CRY_TMP_DEFINED_WINDOWS and/or CRY_TMP_DEFINED_WIN32 already defined -# endif - -# if defined(WINDOWS) -# define CRY_TMP_DEFINED_WINDOWS 1 -# endif -# if defined(WIN32) -# define CRY_TMP_DEFINED_WIN32 1 -# endif - -# include - -# if !defined(CRY_TMP_DEFINED_WINDOWS) -# undef WINDOWS -#endif -# undef CRY_TMP_DEFINED_WINDOWS -# if !defined(CRY_TMP_DEFINED_WIN32) -# undef WIN32 -# endif -# undef CRY_TMP_DEFINED_WIN32 - -// Undefine macros defined in zutil.h to prevent compilation errors in 'steamclientpublic.h', 'OVR_Math.h' etc. -# undef Assert -# undef Trace -# undef Tracev -# undef Tracevv -# undef Tracec -# undef Tracecv - -#endif // !defined(USE_EDGE_ZLIB) - -namespace AZ::IO::ZipDir { - struct UncompressLookahead; -} - -struct IAsyncIOFileCallback -{ - virtual ~IAsyncIOFileCallback(){} - // Asynchronous finished event. - // Must be thread safe, can be called from a different thread. - virtual void OnAsyncFinished(CAsyncIOFileRequest* pFileRequest) = 0; -}; - -struct SStreamPageHdr -{ - explicit SStreamPageHdr(int size) - : nRefs() - , nSize(size) - {} - - volatile int nRefs; - int nSize; -}; - -struct SStreamJobQueue -{ - enum - { - MaxJobs = 256, - }; - - struct Job - { - void* pSrc; - SStreamPageHdr* pSrcHdr; - uint32 nOffs; - uint32 nBytes : 31; - uint32 bLast : 1; - }; - - SStreamJobQueue() - : m_sema(MaxJobs, MaxJobs) - { - m_nQueueLen = 0; - m_nPush = 0; - m_nPop = 0; - memset(m_jobs, 0, sizeof(m_jobs)); - } - - void Flush(SStreamEngineTempMemStats& tms); - - int Push(void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast); - int Pop(); - - CryFastSemaphore m_sema; - Job m_jobs[MaxJobs]; - volatile int m_nQueueLen; - volatile int m_nPush; - volatile int m_nPop; -}; - -// This class represent a request to read some file from disk asynchronously via one of the IO threads. -class CAsyncIOFileRequest -{ -public: - enum EStatus - { - eStatusNotReady, - eStatusInFileQueue, - eStatusFailed, - eStatusUnzipComplete, - eStatusDone, - }; - - enum - { - BUFFER_ALIGNMENT = 128, - WINDOW_SIZE = 1 << 15, - -#if defined(ANDROID) - STREAMING_PAGE_SIZE = (128 * 1024), -#else - STREAMING_PAGE_SIZE = (1 * 1024 * 1024), -#endif - -#if defined(ANDROID) - STREAMING_BLOCK_SIZE = (64 * 1024), -#else - STREAMING_BLOCK_SIZE = (32 * 1024), -#endif - }; - -public: - static CAsyncIOFileRequest* Allocate(EStreamTaskType eType); - static void Flush(); - -public: - void AddRef(); - int Release(); - -public: - void Init(EStreamTaskType eType); - void Finalize(); - - void Reset(); - - ILINE bool IsCancelled() const { return m_nError == ERROR_USER_ABORT; } - ILINE bool HasFailed() const { return m_nError != 0; } - void Failed(uint32 nError) - { - CryInterlockedCompareExchange(reinterpret_cast(&m_nError), nError, 0); - } - - uint32 OpenFile(CCryFile& file); - - uint32 ReadFile(CStreamingIOThread* pIOThread); - uint32 ReadFileResume(CStreamingIOThread* pIOThread); - uint32 ReadFileInPages(CStreamingIOThread* pIOThread, CCryFile& file); - uint32 ReadFileCheckPreempt(CStreamingIOThread* pIOThread); - - uint32 ConfigureRead(AZ::IO::CCachedFileData* pFileData); - bool CanReadInPages(); - uint32 AllocateOutput(AZ::IO::CCachedFileData* pZipEntry); - unsigned char* AllocatePage(size_t sz, bool bOnlyPakMem, SStreamPageHdr*& pHdrOut); - - static void JobFinalize_Read(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - - uint32 PushDecompressPage(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nBytes, bool bLast); - uint32 PushDecompressBlock(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast); - static void JobStart_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState, int nSlot); - void DecompressBlockEntry(SStreamJobEngineState engineState, int nJob); - - void Cancel(); - bool TryCancel(); - void SyncWithDecompress(); - void ComputeSortKey(uint64 nCurrentKeyInProgress); - void SetPriority(EStreamTaskPriority estp); - void BumpSweep(); - void FreeBuffer(); - - bool IgnoreOutofTmpMem() const; - - CStreamEngine* GetStreamEngine(); - - EStreamSourceMediaType GetMediaType(); - -private: - void* operator new (size_t sz); - void operator delete(void* p); - -private: - static void JobFinalize_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - static void JobFinalize_Transfer(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - -private: - void JobFinalize_Buffer(const SStreamJobEngineState& engineState); - void JobFinalize_Validate(const SStreamJobEngineState& engineState); - -private: - CAsyncIOFileRequest(); - ~CAsyncIOFileRequest(); - -public: - static volatile int s_nLiveRequests; - static SLockFreeSingleLinkedListHeader s_freeRequests; - -public: - // Must be first - STREAMENGINE_LL_ALIGN SLockFreeSingleLinkedListEntry m_nextFree; - - volatile int m_nRefCount; - - // Locks to be held whilst the file is being read, and an external memory buffer is in use - // (to ensure that if cancelled, the stream engine doesn't write to the external buffer) - // Separate locks for read and decomp as they can overlap (block decompress) - // Cancel() must acquire both - CryCriticalSection m_externalBufferLockRead; - CryCriticalSection m_externalBufferLockDecompress; - - CryStringLocal m_strFileName; - string m_pakFile; - - // If request come from stream, it will be not 0. - IReadStreamPtr m_pReadStream; - - AZStd::unique_ptr m_decompJobExecutor; - - // Only POD data should exist beyond this point - will be memsetted to 0 on Reset ! - - uint64 m_nSortKey; - - EStreamTaskPriority m_ePriority; - EStreamSourceMediaType m_eMediaType; - EStreamTaskType m_eType; - - volatile EStatus m_status; - volatile uint32 m_nError; - - uint32 m_nRequestedOffset; - uint32 m_nRequestedSize; - - // the file size, or 0 if the file couldn't be opened - uint32 m_nFileSize; - uint32 m_nFileSizeCompressed; - - void* m_pMemoryBuffer; - uint32 m_nMemoryBufferSize; - volatile int m_nMemoryBufferUsers; - - void* m_pExternalMemoryBuffer; - void* m_pOutputMemoryBuffer; - void* m_pReadMemoryBuffer; - uint32 m_nReadMemoryBufferSize; - - uint32 m_bCompressedBuffer : 1; - uint32 m_bStatsUpdated : 1; - uint32 m_bStreamInPlace : 1; - uint32 m_bWriteOnlyExternal : 1; - uint32 m_bSortKeyComputed : 1; - uint32 m_bOutputAllocated : 1; - uint32 m_bReadBegun : 1; - - // Actual size of the data on the media. - uint32 m_nSizeOnMedia; - - int64 m_nDiskOffset; - int32 m_nReadHeadOffsetKB; // Offset of the Read Head when reading from media. - int32 m_nTimeGroup; - int32 m_nSweep; - - IAsyncIOFileCallback* m_pCallback; - - // - // Block based streaming - // - - uint32 m_nPageReadStart; - uint32 m_nPageReadCurrent; - uint32 m_nPageReadEnd; - - volatile uint32 m_nBytesDecompressed; - - uint32 m_crc32FromHeader; - - volatile LONG m_nFinalised; - - z_stream_s* m_pZlibStream; - AZ::IO::ZipDir::UncompressLookahead* m_pLookahead; - SStreamJobQueue* m_pDecompQueue; - -#ifdef STREAMENGINE_ENABLE_STATS - // Time that read operation took. - CTimeValue m_readTime; - CTimeValue m_unzipTime; - CTimeValue m_verifyTime; - CTimeValue m_startTime; - CTimeValue m_completionTime; - - uint32 m_nReadCounter; -#endif -}; -TYPEDEF_AUTOPTR(CAsyncIOFileRequest); - -struct SStreamRequestQueue -{ - CryCriticalSection m_lock; - std::vector m_requests; - - CryEvent m_awakeEvent; - - SStreamRequestQueue(); - ~SStreamRequestQueue(); - - void Reset(); - bool IsEmpty() const; - - // Transfers ownership (rather than shares ownership) to the queue - void TransferRequest(CAsyncIOFileRequest_TransferPtr& pReq); - bool TryPopRequest(CAsyncIOFileRequest_AutoPtr& pOut); - -private: - SStreamRequestQueue(const SStreamRequestQueue&); - SStreamRequestQueue& operator = (const SStreamRequestQueue&); -}; - -#if defined(STREAMENGINE_ENABLE_STATS) -struct SStreamEngineDecompressStats -{ - uint64 m_nTotalBytesUnziped; - uint64 m_nTempBytesUnziped; - uint64 m_nTotalBytesVerified; - uint64 m_nTempBytesVerified; - - CTimeValue m_totalUnzipTime; - CTimeValue m_tempUnzipTime; - CTimeValue m_totalVerifyTime; - CTimeValue m_tempVerifyTime; -}; -#endif - -class CAsyncIOFileRequest_TransferPtr -{ -public: - explicit CAsyncIOFileRequest_TransferPtr(CAsyncIOFileRequest* p) - : m_p(p) - { - } - - ~CAsyncIOFileRequest_TransferPtr() - { - if (m_p) - { - m_p->Release(); - } - } - - CAsyncIOFileRequest* operator -> () { return m_p; } - CAsyncIOFileRequest& operator * () { return *m_p; } - - const CAsyncIOFileRequest* operator -> () const { return m_p; } - const CAsyncIOFileRequest& operator * () const { return *m_p; } - - operator bool () const { - return m_p != NULL; - } - - CAsyncIOFileRequest* Relinquish() - { - CAsyncIOFileRequest* p = m_p; - m_p = NULL; - return p; - } - - CAsyncIOFileRequest_TransferPtr& operator = (CAsyncIOFileRequest* p) - { -#ifndef _RELEASE - if (m_p) - { - __debugbreak(); - } -#endif - m_p = p; - return *this; - } - -private: - CAsyncIOFileRequest_TransferPtr(const CAsyncIOFileRequest_TransferPtr&); - CAsyncIOFileRequest_TransferPtr& operator = (const CAsyncIOFileRequest_TransferPtr&); - -private: - CAsyncIOFileRequest* m_p; -}; - -class CStreamEngineWakeEvent -{ -public: - CStreamEngineWakeEvent() - : m_state(0) - { - } - - void Set() - { - volatile LONG oldState, newState; - bool bSignalInner; - - do - { - bSignalInner = false; - oldState = m_state; - - newState = oldState | 0x80000000; - if (oldState & 0x7fffffff) - { - bSignalInner = true; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - - if (bSignalInner) - { - m_innerEvent.Set(); - } - } - - bool Wait(uint32 timeout = 0) - { - bool bTimedOut = false; - bool bAcquiredSignal = false; - - while (!bTimedOut && !bAcquiredSignal) - { - volatile long oldState, newState; - do - { - bAcquiredSignal = false; - - oldState = m_state; - if (oldState & 0x80000000) - { - // Signalled - newState = oldState & 0x7fffffff; - bAcquiredSignal = true; - } - else - { - newState = oldState + 1; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - - if (!bAcquiredSignal) - { - if (!timeout) - { - m_innerEvent.Wait(); - } - else - { - bTimedOut = !m_innerEvent.Wait(timeout); - } - - if (!bTimedOut) - { - m_innerEvent.Reset(); - } - - do - { - bAcquiredSignal = false; - - oldState = m_state; - if (!bTimedOut && (oldState & 0x80000000)) - { - newState = (oldState & 0x7fffffff) - 1; - bAcquiredSignal = true; - } - else - { - newState = oldState - 1; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - } - } - - return bAcquiredSignal; - } - -private: - CStreamEngineWakeEvent(const CStreamEngineWakeEvent&); - CStreamEngineWakeEvent& operator = (const CStreamEngineWakeEvent&); - -private: - volatile LONG m_state; - CryEvent m_innerEvent; -}; - -struct SStreamEngineTempMemStats -{ - enum - { - MaxWakeEvents = 8, - }; - - SStreamEngineTempMemStats() - { - memset(this, 0, sizeof(*this)); - } - - void* TempAlloc(CMTSafeHeap* pHeap, size_t nSize, const char* szDbgSource, bool bFallBackToMalloc = true, bool bUrgent = false, uint32 align = 0); - void TempFree(CMTSafeHeap* pHeap, const void* p, size_t nSize); - void ReportTempMemAlloc(uint32 nSizeAlloc, uint32 nSizeFree, bool bTriggerWake); - - volatile LONG m_nTempAllocatedMemory; - volatile LONG m_nTempAllocatedMemoryFrameMax; - int m_nTempMemoryBudget; - CStreamEngineWakeEvent* m_wakeEvents[MaxWakeEvents]; - int m_nWakeEvents; -}; - -struct SStreamJobEngineState -{ - std::vector* pReportQueues; - -#if defined(STREAMENGINE_ENABLE_STATS) - SStreamEngineStatistics* pStats; - SStreamEngineDecompressStats* pDecompressStats; -#endif - - SStreamEngineTempMemStats* pTempMem; - - CMTSafeHeap* pHeap; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp deleted file mode 100644 index b8bebb49c3..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include - -#include -#include "StreamAsyncFileRequest.h" - -#include "MTSafeAllocator.h" - -namespace AZ::IO::ZipDir::ZipDirStructuresInternal -{ - extern void ZlibInflateElementPartial_Impl( - int* pReturnCode, z_stream* pZStream, ZipDir::UncompressLookahead* pLookahead, - uint8_t* pOutput, size_t nOutputLen, bool bOutputWriteOnly, - const uint8_t* pInput, size_t nInputLen, size_t* pTotalOut); -} - -#ifdef STREAMENGINE_ENABLE_LISTENER -#include "IStreamEngine.h" -class NotifyListener -{ -public: - NotifyListener(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq) - : m_pL(pL) - , m_pReq(pReq) - , m_bInProgress(false) {} - virtual ~NotifyListener() {} -protected: - IStreamEngineListener* m_pL; - CAsyncIOFileRequest* m_pReq; - bool m_bInProgress; -}; -class NotifyListenerInflate - : NotifyListener -{ -public: - NotifyListenerInflate(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq) - : NotifyListener(pL, pReq) - { - if (m_pL) - { - m_pL->OnStreamBeginInflate(m_pReq); - m_bInProgress = true; - } - } - ~NotifyListenerInflate() - { - End(); - } - void End() - { - if (m_bInProgress) - { - m_pL->OnStreamEndInflate(m_pReq); - m_bInProgress = false; - } - } -}; -#endif - -#if defined(STREAMENGINE_ENABLE_STATS) -#define STREAMENGINE_ENABLE_TIMING -#endif - -//#define STREAM_DECOMPRESS_TRACE(...) OutputDebugString(AZStd::string::format(__VA_ARGS__).c_str()); -#define STREAM_DECOMPRESS_TRACE(...) - -void SStreamJobQueue::Flush(SStreamEngineTempMemStats& tms) -{ - extern CMTSafeHeap* g_pPakHeap; - - for (int c = m_nQueueLen, i = m_nPop % MaxJobs; c; --c, i = (i + 1) % MaxJobs) - { - Job& j = m_jobs[i]; - if (j.pSrcHdr && CryInterlockedDecrement(&j.pSrcHdr->nRefs) == 0) - { - tms.TempFree(g_pPakHeap, j.pSrc, j.pSrcHdr->nSize); - } - j.pSrc = NULL; - } -} - -int SStreamJobQueue::Push(void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast) -{ - m_sema.Acquire(); - - int nSlot = (m_nPush++) % MaxJobs; - - Job& j = m_jobs[nSlot]; - j.pSrc = pSrc; - j.pSrcHdr = pSrcHdr; - j.nOffs = nOffs; - j.nBytes = nBytes; - j.bLast = (uint32)bLast; - - bool bStartNext = CryInterlockedIncrement(&m_nQueueLen) == 1; - return bStartNext ? nSlot : -1; -} - -int SStreamJobQueue::Pop() -{ - int nSlot = (++m_nPop) % MaxJobs; - bool bStartNext = CryInterlockedDecrement(&m_nQueueLen) > 0; - - m_sema.Release(); - - return bStartNext ? nSlot : -1; -} - -void CAsyncIOFileRequest::AddRef() -{ - //int nRef = - CryInterlockedIncrement(&m_nRefCount); - STREAM_DECOMPRESS_TRACE("[StreamDecompress],AddRef,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nRef); -} - -int CAsyncIOFileRequest::Release() -{ - int nRef = CryInterlockedDecrement(&m_nRefCount); - STREAM_DECOMPRESS_TRACE("[StreamDecompress],Release,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nRef); - -#ifndef _RELEASE - if (nRef < 0) - { - __debugbreak(); - } -#endif - - if (nRef == 0) - { - Finalize(); - - CryInterlockedPushEntrySList(s_freeRequests, m_nextFree); - } - - return nRef; -} - -void CAsyncIOFileRequest::DecompressBlockEntry(SStreamJobEngineState engineState, int nJob) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::System); - - STREAM_DECOMPRESS_TRACE("[StreamDecompress],DecompressBlockEntry,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nJob); - - CAsyncIOFileRequest_TransferPtr pSelf(this); - - SStreamJobQueue::Job& job = m_pDecompQueue->m_jobs[nJob]; - - void* pSrc = job.pSrc; - SStreamPageHdr* const pSrcHdr = job.pSrcHdr; - const uint32 nOffs = job.nOffs; - const uint32 nBytes = job.nBytes; - const bool bLast = job.bLast; - const bool bFailed = HasFailed(); - - if (!bFailed) - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liStart; - QueryPerformanceCounter(&liStart); -#endif - - //printf("Inflate: %s Avail in: %d, Avail Out: %d, Next In: 0x%p, Next Out: 0x%p\n", m_strFileName.c_str(), m_pZlibStream->avail_in, m_pZlibStream->avail_out, m_pZlibStream->next_in, m_pZlibStream->next_out); - -#ifdef STREAMENGINE_ENABLE_LISTENER - NotifyListenerInflate inflateListener(gEnv->pSystem->GetStreamEngine()->GetListener(), this); -#endif - - size_t nBytesDecomped = m_nBytesDecompressed; - - STREAM_DECOMPRESS_TRACE ("[StreamDecompress],ZlibInflateElementPartial_Impl,0x%x,%s,0x%p,%i,0x%p,%i,%i\n", - CryGetCurrentThreadId(), - m_strFileName.c_str(), - (uint8_t*)m_pReadMemoryBuffer + nBytesDecomped, - m_nFileSize - nBytesDecomped, - (uint8_t*)pSrc + nOffs, - nBytes, - nBytesDecomped); - - int readStatus = Z_OK; - - { - CryOptionalAutoLock decompLock(m_externalBufferLockDecompress, m_pExternalMemoryBuffer != NULL); - - AZ::IO::ZipDir::ZipDirStructuresInternal::ZlibInflateElementPartial_Impl( - &readStatus, - m_pZlibStream, - m_pLookahead, - (uint8_t*)m_pReadMemoryBuffer + nBytesDecomped, - m_nFileSize - nBytesDecomped, - m_bWriteOnlyExternal, - (uint8_t*)pSrc + nOffs, - nBytes, - &nBytesDecomped - ); - } - - m_nBytesDecompressed = nBytesDecomped; - - //inform listen, so aysnc callback does not overlap -#ifdef STREAMENGINE_ENABLE_LISTENER - inflateListener.End(); -#endif - - if (readStatus == Z_OK || readStatus == Z_STREAM_END) - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liEnd, liFreq; - QueryPerformanceCounter(&liEnd); - QueryPerformanceFrequency(&liFreq); - - m_unzipTime += CTimeValue((int64)((liEnd.QuadPart - liStart.QuadPart) * CTimeValue::TIMEVALUE_PRECISION / liFreq.QuadPart)); -#endif - } - else - { -#ifndef _RELEASE - AZ_Assert(false, "Decomp Error: %s : %s\n", m_strFileName.c_str(), m_pZlibStream ? m_pZlibStream->msg : "m_pZlibStream == NULL, no message available"); -#endif - Failed(ERROR_DECOMPRESSION_FAIL); - } - } - - if (pSrcHdr) - { - if (CryInterlockedDecrement(&pSrcHdr->nRefs) == 0) - { - engineState.pTempMem->TempFree(engineState.pHeap, pSrc, pSrcHdr->nSize); - } - } - - job.pSrc = NULL; - - int nPopSlot = m_pDecompQueue->Pop(); - - // job is no longer valid - - if (HasFailed() || bLast) - { - JobFinalize_Decompress(pSelf, engineState); - } - else if (nPopSlot >= 0) - { - // Chain start the next job, we're responsible for it. - STREAM_DECOMPRESS_TRACE("[StreamDecompress],Chaining,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nPopSlot); - JobStart_Decompress(pSelf, engineState, nPopSlot); - } - -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedDecrement(&engineState.pStats->nCurrentDecompressCount); -#endif -} - -////////////////////////////////////////////////////////////////////////// - -uint32 CAsyncIOFileRequest::PushDecompressPage(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nBytes, bool bLast) -{ - uint32 nError = 0; - - for (uint32 nBlockPos = 0; !nError && (nBlockPos < nBytes); nBlockPos += STREAMING_BLOCK_SIZE) - { - bool bLastBlock = (nBlockPos + STREAMING_BLOCK_SIZE) >= nBytes; - uint32 nBlockSize = min(nBytes - nBlockPos, (uint32)STREAMING_BLOCK_SIZE); - - nError = PushDecompressBlock(engineState, pSrc, pSrcHdr, nBlockPos, nBlockSize, bLast && bLastBlock); - } - - return nError; -} - -uint32 CAsyncIOFileRequest::PushDecompressBlock(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast) -{ - uint32 nError = m_nError; - - if (!nError) - { - if (pSrcHdr) - { - CryInterlockedIncrement(&pSrcHdr->nRefs); - } - - int nPushJob = m_pDecompQueue->Push(pSrc, pSrcHdr, nOffs, nBytes, bLast); - if (nPushJob >= 0) - { - STREAM_DECOMPRESS_TRACE("[StreamDecompress],PushDecompressBlock,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nPushJob); - - AddRef(); - CAsyncIOFileRequest_TransferPtr pSelf(this); - JobStart_Decompress(pSelf, engineState, nPushJob); - } - } - - return nError; -} - -void CAsyncIOFileRequest::JobStart_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState, int nJob) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],QueueDecompressBlockAppend,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, nJob); - -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedIncrement(&engineState.pStats->nCurrentDecompressCount); -#endif - - CAsyncIOFileRequest* request = pSelf.Relinquish(); - if (!request->m_decompJobExecutor) - { - request->m_decompJobExecutor = AZStd::make_unique(); - } - request->m_decompJobExecutor->StartJob([request, engineState, nJob]() - { - request->DecompressBlockEntry(engineState, nJob); - }); // Legacy JobManager priority: eStreamPriority -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::JobFinalize_Read(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - if (!pSelf->m_bCompressedBuffer || pSelf->HasFailed()) - { - JobFinalize_Transfer(pSelf, engineState); - } -} - -void CAsyncIOFileRequest::JobFinalize_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],FinalizeDecompress,0x%x,%s,0x%p,0x%p,0x%p,0x%p\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, &engineState, engineState.pStats, engineState.pDecompressStats); - - CAsyncIOFileRequest* pReq = &*pSelf; - - if (!pReq->HasFailed()) - { - // Handle reads of subsections of a compressed file, by copying the section to the output - uint8_t* pDst = (uint8_t*)pReq->m_pOutputMemoryBuffer; - uint8_t* pSrc = (uint8_t*)pReq->m_pReadMemoryBuffer + pReq->m_nRequestedOffset; - - if (pDst != pSrc) - { - memmove(pReq->m_pOutputMemoryBuffer, pSrc, pReq->m_nRequestedSize); - } - - pReq->JobFinalize_Validate(engineState); - } - - pReq->JobFinalize_Buffer(engineState); - -#if defined(STREAMENGINE_ENABLE_STATS) && defined(STREAMENGINE_ENABLE_TIMING) - if (pReq->m_unzipTime.GetValue() != 0) - { - engineState.pDecompressStats->m_nTotalBytesUnziped += pReq->m_nFileSize; - engineState.pDecompressStats->m_totalUnzipTime += pReq->m_unzipTime; - - engineState.pDecompressStats->m_nTempBytesUnziped += pReq->m_nFileSize; - engineState.pDecompressStats->m_tempUnzipTime += pReq->m_unzipTime; - } -#endif - - JobFinalize_Transfer(pSelf, engineState); -} - -void CAsyncIOFileRequest::JobFinalize_Buffer(const SStreamJobEngineState& engineState) -{ - if (CryInterlockedDecrement(&m_nMemoryBufferUsers) == 0) - { - z_stream_s* pZlib = m_pZlibStream; - - if (pZlib) - { - //if the stream was cancelled in flight, inform zlib to free internal allocs - if (pZlib->state) - { - inflateEnd(pZlib); - } - - m_pZlibStream = NULL; - } - - if (m_pMemoryBuffer) - { - engineState.pTempMem->TempFree(engineState.pHeap, m_pMemoryBuffer, m_nMemoryBufferSize); - - m_pMemoryBuffer = NULL; - m_nMemoryBufferSize = 0; - } - } -} - -void CAsyncIOFileRequest::JobFinalize_Validate([[maybe_unused]] const SStreamJobEngineState& engineState) -{ -#if defined(SKIP_CHECKSUM_FROM_OPTICAL_MEDIA) - if (m_eMediaType != eStreamSourceTypeDisc) -#endif //SKIP_CHECKSUM_FROM_OPTICAL_MEDIA - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - if (!HasFailed()) - { - if (m_crc32FromHeader != 0 && m_nPageReadStart == 0 && m_nRequestedSize == m_nFileSize) //Compute the CRC32 if appropriate. - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liStart, liEnd, liFreq; - QueryPerformanceCounter(&liStart); -#endif //STREAMENGINE_ENABLE_TIMING - - uint32 nCRC32 = crc32(0, (uint8_t*)m_pReadMemoryBuffer + m_nPageReadStart, m_nRequestedSize); - -#if defined(STREAMENGINE_ENABLE_TIMING) - QueryPerformanceCounter(&liEnd); - QueryPerformanceFrequency(&liFreq); - - m_verifyTime += CTimeValue((int64)((liEnd.QuadPart - liStart.QuadPart) * CTimeValue::TIMEVALUE_PRECISION / liFreq.QuadPart)); - - engineState.pDecompressStats->m_nTotalBytesVerified += m_nFileSize; - engineState.pDecompressStats->m_totalVerifyTime += m_verifyTime; - engineState.pDecompressStats->m_nTempBytesVerified += m_nFileSize; - engineState.pDecompressStats->m_tempVerifyTime += m_verifyTime; -#endif //STREAMENGINE_ENABLE_TIMING - - if (m_crc32FromHeader != nCRC32) - { - //The contents of this file don't match what the header expects -#if !defined(_RELEASE) - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR_DBGBRK, "Streaming Engine Failed to verify a file (%s). Computed CRC32 %d does not match stored CRC32 %d", m_strFileName.c_str(), nCRC32, m_crc32FromHeader); -#endif //!_RELEASE - Failed(ERROR_VERIFICATION_FAIL); - } - } - } - } -} - -void CAsyncIOFileRequest::JobFinalize_Transfer(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],FinalizeTransform,0x%x,%s,0x%p,0x%p,0x%p,0x%p\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, &engineState, engineState.pStats, engineState.pDecompressStats); - - if (CryInterlockedCompareExchange(&pSelf->m_nFinalised, 1, 0) == 0) - { -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedIncrement(&engineState.pStats->nCurrentAsyncCount); -#endif - -#if defined(STREAMENGINE_ENABLE_TIMING) - pSelf->m_completionTime = gEnv->pTimer->GetAsyncTime(); -#endif - - int nCallbackThreads = engineState.pReportQueues->size(); - - EStreamTaskType eType = pSelf->m_eType; - if (nCallbackThreads > 1 && eType == eStreamTaskTypeGeometry) - { - // If we have more then 1 call back threads, use this one for geometry only. - (*engineState.pReportQueues)[1]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 2 && eType == eStreamTaskTypeTexture) - { - // If we have more then 1 call back threads, use this one for textures only. - (*engineState.pReportQueues)[2]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 3 && eType == eStreamTaskTypeMergedMesh) - { - // If we have more then 3 call back threads, use this one for merged meshes only. - (*engineState.pReportQueues)[3]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 0) - { - (*engineState.pReportQueues)[0]->TransferRequest(pSelf); - } - else - { - __debugbreak(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void SStreamRequestQueue::TransferRequest(CAsyncIOFileRequest_TransferPtr& pRequest) -{ - { - CryAutoLock l(m_lock); - - m_requests.push_back(pRequest.Relinquish()); - } - - m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void SStreamEngineTempMemStats::TempFree(CMTSafeHeap* pHeap, const void* p, size_t nSize) -{ -#if MTSAFE_USE_GENERAL_HEAP - bool bInGenHeap = pHeap->IsInGeneralHeap(p); -#else - bool bInGenHeap = false; -#endif - pHeap->FreeTemporary(const_cast(p)); - ReportTempMemAlloc(0, bInGenHeap ? 0 : nSize, true); -} - -void SStreamEngineTempMemStats::ReportTempMemAlloc(uint32 nSizeAlloc, uint32 nSizeFree, bool bTriggerWake) -{ - int nAdd = (int)nSizeAlloc - (int)nSizeFree; - int const nOldSize = CryInterlockedExchangeAdd(&m_nTempAllocatedMemory, nAdd); - int const nNewSize = nOldSize + nAdd; - - LONG nNewMax = 0; - LONG nOldMax = 0; - do - { - nOldMax = m_nTempAllocatedMemoryFrameMax; - nNewMax = (LONG)max((int)nNewSize, (int)nOldMax); - } - while (CryInterlockedCompareExchange(&m_nTempAllocatedMemoryFrameMax, nNewMax, nOldMax) != nOldMax); - - if (bTriggerWake) - { - for (int i = 0, c = m_nWakeEvents; i != c; ++i) - { - m_wakeEvents[i]->Set(); - } - } -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp deleted file mode 100644 index 7f8c75b2a8..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp +++ /dev/null @@ -1,1698 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine implementation - - -#include "CrySystem_precompiled.h" -#include "StreamEngine.h" - -//CReadStream is 99% unused since the introduction of AZRequestReadStream. -//In the near future CReadStream will disappear altogether and StreamReadStream cpp/h -// won't be needed anymore. -#include "StreamReadStream.h" - -#include "AZRequestReadStream.h" -#include "Pak/CryPakUtils.h" - -#include "../System.h" - -#include -#include - -#include -#include - -#define MAX_HEAVY_ASSETS 20 - -#if defined(STREAMENGINE_ENABLE_STATS) -SStreamEngineStatistics* g_pStreamingStatistics = 0; -#endif - -SStreamEngineOpenStats* g_pStreamingOpenStatistics = 0; - -extern CMTSafeHeap* g_pPakHeap; - -////////////////////////////////////////////////////////////////////////// -CStreamEngine::CStreamEngine() - : AzFramework::InputChannelEventListener(AzFramework::InputChannelEventListener::GetPriorityDebug()) -{ - m_nBatchMode = 0; - m_bShutDown = false; - m_bUseOpticalDriveThread = g_cvars.sys_streaming_use_optical_drive_thread != 0; - m_nPausedDataTypesMask = 0; - m_bStreamDataOnHDD = gEnv->pCryPak->IsInstalledToHDD(); - -#ifdef STREAMENGINE_ENABLE_STATS - g_pStreamingStatistics = &m_Statistics; - m_Statistics.nPendingReadBytes = 0; - - m_Statistics.nCurrentAsyncCount = 0; - m_Statistics.nCurrentDecompressCount = 0; - m_Statistics.nCurrentFinishedCount = 0; - - memset(&m_decompressStats, 0, sizeof(m_decompressStats)); - - m_nUnzipBandwidth = 0; - m_nUnzipBandwidthAverage = 0; - m_bStreamingStatsPaused = false; - m_bInputCallback = false; - m_bTempMemOutOfBudget = false; - - ClearStatistics(); -#endif - - memset(&m_OpenStatistics, 0, sizeof(m_OpenStatistics)); - g_pStreamingOpenStatistics = &m_OpenStatistics; - -#ifdef STREAMENGINE_ENABLE_LISTENER - m_pListener = NULL; -#endif - - StartThreads(); - - // register system listener - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); -} - -////////////////////////////////////////////////////////////////////////// -// MT: Main thread only -CStreamEngine::~CStreamEngine() -{ -#ifdef STREAMENGINE_ENABLE_STATS - g_pStreamingStatistics = 0; - if (m_bInputCallback) - { - AzFramework::InputChannelEventListener::Disconnect(); - } -#endif - g_pStreamingOpenStatistics = NULL; - Shutdown(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::BeginReadGroup() -{ - CryInterlockedIncrement(&m_nBatchMode); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::EndReadGroup() -{ - CryInterlockedDecrement(&m_nBatchMode); - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - // New requests accomulated untill all Start stream requests are submitted and can be properly sorted. - m_pThreadIO[i]->SignalStartWork(false); - } - } -} - -AZ::IO::IStreamerTypes::Priority CStreamEngine::CryStreamPriorityToAZStreamPriority(EStreamTaskPriority cryPriority) -{ - switch (cryPriority) - { - case estpUrgent: - return AZ::IO::IStreamerTypes::s_priorityHighest; - // estpPreempted = 1, //For internal use only - case estpAboveNormal: - return AZ::IO::IStreamerTypes::s_priorityHigh; - case estpNormal: - return AZ::IO::IStreamerTypes::s_priorityMedium; - case estpBelowNormal: - return AZ::IO::IStreamerTypes::s_priorityLow; - case estpIdle: - [[fallthrough]]; - default: - return AZ::IO::IStreamerTypes::s_priorityLowest; - } -} - -AZStd::chrono::milliseconds CStreamEngine::AZDeadlineFromReadParams(const StreamReadParams& params) -{ - - if (params.nLoadTime == 0) - { - // File should be loaded right away. - return AZStd::chrono::milliseconds(0); - } - else - { - return AZStd::chrono::milliseconds(AZStd::max(params.nLoadTime, params.nMaxLoadTime)); - } -} - -////////////////////////////////////////////////////////////////////////// -// Starts asynchronous read from the specified file -// It is expected that the callbacks are called from Main Thread only when -// the async data loading is finished. -IReadStreamPtr CStreamEngine::StartRead (const EStreamTaskType tSource, const char* szFilePath, IStreamCallback* pCallback, const StreamReadParams* pParams) -{ - using namespace AZ::IO; - - if (!szFilePath) - { - CryFatalError("Use of the stream engine without a file is deprecated! Use the job system."); - return NULL; - } - - if (gEnv->IsDedicated()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Attempting to use the stream engine on a dedicated server! Don't do that!"); - return NULL; - } - - if (!m_bShutDown) - { - AZRequestReadStream* pStream = AZRequestReadStream::Allocate(tSource, szFilePath, pCallback, pParams); - if (!pStream) - { - CryFatalError("Failed to create Request Stream for %s", szFilePath); - return nullptr; - } - - size_t offset = pParams ? pParams->nOffset : 0; - AZStd::chrono::microseconds deadline = pParams - ? AZStd::chrono::duration_cast(AZDeadlineFromReadParams(*pParams)) - : AZStd::chrono::microseconds(0); - AZ::IO::IStreamerTypes::Priority priority = pParams - ? CryStreamPriorityToAZStreamPriority(pParams->ePriority) - : AZ::IO::IStreamerTypes::s_priorityHighest; - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - pStream->AddRef(); - - auto callback = [this, pStream](FileRequestHandle request) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRenderDetailed); - auto streamer = AZ::Interface::Get(); - void* buffer = nullptr; - AZ::u64 bytesRead = 0; - [[maybe_unused]] bool result = streamer->GetReadRequestResult(request, buffer, bytesRead); - AZ_Assert(result, "Cry Stream Engine requested a callback on reading, but couldn't retrieve result."); - QueueRequestCompleteJob(pStream, bytesRead, buffer, streamer->GetRequestStatus(request)); - // Release reference that was taken above in order to hold onto stream while job is queued - pStream->Release(); - }; - - // Register stream and start file request. - IReadStreamPtr result = static_cast(pStream); - - auto streamer = AZ::Interface::Get(); - FileRequestPtr azRequest = streamer->Read(szFilePath, pStream->GetFileReadBuffer(), pStream->GetFileSize(), - pStream->GetFileSize(), deadline, priority, offset); - streamer->SetRequestCompleteCallback(azRequest, callback); - pStream->SetFileRequest(azRequest); - streamer->QueueRequest(azRequest); - - return result; - } - - return NULL; -} - -//It is NOT necessary to schedule the callbacks on the main thread. -//Regular async calls is OK. -size_t CStreamEngine::StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback) -{ - using namespace AZ::IO; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - - size_t nValidStreams = 0; - - if (!m_bShutDown) - { - enum - { - MaxStreamsPerBatch = 32 - }; - - size_t nReqIdx = 0; - - // we have requests to evaluate, call the callback before enqueing the requests - if (numReqs > 0 && preRequestCallback != nullptr) - { - (*preRequestCallback)(); - } - - if (numReqs > 0) - { - numReqs = AZStd::min(numReqs, aznumeric_cast(MaxStreamsPerBatch)); - AZStd::vector batch; - - auto streamer = AZ::Interface::Get(); - streamer->CreateRequestBatch(batch, numReqs); - - while (numReqs > 0) - { - const StreamReadBatchParams& args = pReqs[nReqIdx]; - - if (!args.szFile) - { - CryFatalError("Use of the stream engine without a file is deprecated! Use the job system."); - } - - AZRequestReadStream* pStream; - - { - FRAME_PROFILER_FAST("CStreamEngine::StartBatchRead_AllocReadStream", gEnv->pSystem, PROFILE_SYSTEM, gEnv->bProfilerEnabled); - pStream = AZRequestReadStream::Allocate(args.tSource, args.szFile, args.pCallback, &args.params); - } - - if (pStream) - { - FileRequestPtr& request = batch[nValidStreams]; - pStreamsOut[nValidStreams++] = pStream; - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - pStream->AddRef(); - auto callback = [this, pStream](FileRequestHandle request) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRenderDetailed); - auto streamer = AZ::Interface::Get(); - void* buffer = nullptr; - AZ::u64 bytesRead = 0; - [[maybe_unused]] bool result = streamer->GetReadRequestResult(request, buffer, bytesRead); - AZ_Assert(result, "Cry Stream Engine requested a callback on reading, but couldn't retrieve result."); - QueueRequestCompleteJob(pStream, bytesRead, buffer, streamer->GetRequestStatus(request)); - // Release reference that was taken above in order to hold onto stream while job is queued - pStream->Release(); - }; - - streamer->Read(request, args.szFile, pStream->GetFileReadBuffer(), pStream->GetFileSize(), - pStream->GetFileSize(), AZDeadlineFromReadParams(args.params), - CryStreamPriorityToAZStreamPriority(args.params.ePriority), args.params.nOffset); - streamer->SetRequestCompleteCallback(request, callback); - pStream->SetFileRequest(request); - } - else - { - CryFatalError("Failed to create Request Stream for %s at mip number %d", args.szFile, (int)nReqIdx); - } - - --numReqs; - ++nReqIdx; - } - - streamer->QueueRequestBatch(AZStd::move(batch)); - } - } - - return nValidStreams; -} - -void CStreamEngine::QueueRequestCompleteJob(AZRequestReadStream* stream, AZ::IO::SizeType numBytesRead, void* buffer, - AZ::IO::IStreamerTypes::RequestStatus requestState) -{ - // Some graphics APIs don't support multiple threads instancing resources such as textures. To work around this limitation - // the jobs that complete a streaming request are queued and a previous request will kick off the next one. This will cause - // only one job that finishes a streaming request to ever be active without causing mutexes to cause stalls in the job system. - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - stream->AddRef(); - auto jobFunction = [this, stream, numBytesRead, buffer, requestState]() - { - stream->OnRequestComplete(numBytesRead, buffer, requestState); - // Release reference that was taken above in order to hold onto stream while job is queued - stream->Release(); - - CryAutoLock lock(m_pendingRequestCompletionsLock); - AZ_Assert(!m_pendingRequestCompletions.empty(), - "CStreamEngine::QueueRequestCompleteJob expects at least one job in the queue as this is this is the job ran from the callback.") - // The top request is always the one that's running, so pop that one of the queue and start any other pending jobs. - m_pendingRequestCompletions.pop(); - if (!m_pendingRequestCompletions.empty()) - { - m_pendingRequestCompletions.front()->Start(); - } - }; - - AZ::Job* job = AZ::CreateJobFunction(jobFunction, true, AZ::JobContext::GetGlobalContext()); - - CryAutoLock lock(m_pendingRequestCompletionsLock); - if (m_pendingRequestCompletions.empty()) - { - m_pendingRequestCompletions.push(job); - job->Start(); - } - else - { - m_pendingRequestCompletions.push(job); - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::ResumePausedStreams_PauseLocked() -{ - for (size_t i = 0; i < (size_t)m_pausedStreams.size(); ) - { - CReadStream* pStream = (CReadStream*)(IReadStream*)m_pausedStreams[i]; - int nStreamMask = 1 << (uint32)pStream->m_Type; - if (0 == (nStreamMask & m_nPausedDataTypesMask)) - { - if (pStream->GetError() == 0) // If was not aborted - { - // This stream must be resumed - m_streams.insert(pStream); - CAsyncIOFileRequest* pFileRequest = pStream->CreateFileRequest(); - if (!StartFileRequest(pFileRequest)) - { - pFileRequest->Release(); - } - } - m_pausedStreams.erase(m_pausedStreams.begin() + i); - } - else - { - i++; - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CStreamEngine::StartFileRequest(CAsyncIOFileRequest* pFileRequest) -{ - bool bStartImmidietly = m_nBatchMode == 0; - - EStreamSourceMediaType eMediaType = pFileRequest->GetMediaType(); - bool bQueued = false; - - CStreamingIOThread* pIO = m_pThreadIO[0]; - - for (size_t i = 1; i < eIOThread_Last; ++i) - { - CStreamingIOThread* pAltIO = m_pThreadIO[i]; - - if (pAltIO && pAltIO->GetMediaType() == eMediaType) - { - pIO = pAltIO; - break; - } - } - - if (pIO) - { -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamEnqueue(pFileRequest, pFileRequest->m_strFileName.c_str(), pFileRequest->m_pReadStream->GetCallerType(), pFileRequest->m_pReadStream->GetParams()); - } -#endif - - pIO->AddRequest(pFileRequest, bStartImmidietly); - bQueued = true; - } - - if (!bQueued) - { - assert(0); // No IO thread. - return false; - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.typeInfo[pFileRequest->m_eType].nTotalStreamingRequestCount++; - - if (g_cvars.sys_streaming_debug == 3) - { - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!pFileRequest->m_strFileName.empty() && !m_bStreamingStatsPaused) - { - if (!sFileFilter || !sFileFilter[0] || strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - CryAutoCriticalSection lock(m_csStats); - m_statsRequestList.insert(m_statsRequestList.begin(), pFileRequest); - } - } - } -#endif - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::SignalToStartWork(EIOThread e, bool bForce) -{ - if ((e >= 0) && (e < eIOThread_Last)) - { - if (m_pThreadIO[e]) - { - m_pThreadIO[e]->SignalStartWork(bForce); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -#ifdef STREAMENGINE_ENABLE_STATS -void UpdateIOThreadStats( - SStreamEngineStatistics::SMediaTypeInfo* pNotInMemoryInfo, - SStreamEngineStatistics::SMediaTypeInfo* pInMemoryInfo, - CStreamingIOThread* pIOThread, - float fSecSinceLastReset) -{ - if (pNotInMemoryInfo == 0 || pIOThread == 0) - { - return; - } - - // not in memory reading - pNotInMemoryInfo->fActiveDuringLastSecond = pIOThread->m_NotInMemoryStats.m_fReadingDuringLastSecond; - pNotInMemoryInfo->fAverageActiveTime = - pIOThread->m_NotInMemoryStats.m_TotalReadTime.GetSeconds() / fSecSinceLastReset * 100; - - pNotInMemoryInfo->nBytesRead = pIOThread->m_NotInMemoryStats.m_nReadBytesInLastSecond; - pNotInMemoryInfo->nRequestCount = pIOThread->m_NotInMemoryStats.m_nRequestCountInLastSecond; - pNotInMemoryInfo->nTotalBytesRead = pIOThread->m_NotInMemoryStats.m_nTotalReadBytes; - pNotInMemoryInfo->nTotalRequestCount = pIOThread->m_NotInMemoryStats.m_nTotalRequestCount; - - pNotInMemoryInfo->nSeekOffsetLastSecond = pIOThread->m_NotInMemoryStats.m_nReadOffsetInLastSecond; - if (pIOThread->m_NotInMemoryStats.m_nTotalRequestCount > 0) - { - pNotInMemoryInfo->nAverageSeekOffset = pIOThread->m_NotInMemoryStats.m_nTotalReadOffset / - pIOThread->m_NotInMemoryStats.m_nTotalRequestCount; - } - else - { - pNotInMemoryInfo->nAverageSeekOffset = 0; - } - - pNotInMemoryInfo->nCurrentReadBandwidth = pIOThread->m_NotInMemoryStats.m_nCurrentReadBandwith; - pNotInMemoryInfo->nSessionReadBandwidth = (uint32)(pNotInMemoryInfo->nTotalBytesRead / fSecSinceLastReset); - - pNotInMemoryInfo->nActualReadBandwidth = pIOThread->m_NotInMemoryStats.m_nActualReadBandwith; - float fTotalReadTime = pIOThread->m_NotInMemoryStats.m_TotalReadTime.GetSeconds(); - if (fTotalReadTime > 0.0f) - { - pNotInMemoryInfo->nAverageActualReadBandwidth = (uint32)(pNotInMemoryInfo->nTotalBytesRead / fTotalReadTime); - } - - // in memory reading - if (pInMemoryInfo) - { - pInMemoryInfo->nBytesRead = pIOThread->m_InMemoryStats.m_nReadBytesInLastSecond; - pInMemoryInfo->nRequestCount = pIOThread->m_InMemoryStats.m_nRequestCountInLastSecond; - pInMemoryInfo->nTotalBytesRead = pIOThread->m_InMemoryStats.m_nTotalReadBytes; - pInMemoryInfo->nTotalRequestCount = pIOThread->m_InMemoryStats.m_nTotalRequestCount; - } -} -#endif - -void CStreamEngine::Update(uint32 nUpdateTypesBitmask) -{ - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_SYSTEM); - AZ_TRACE_METHOD(); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - // Dispatch completed callbacks. - MainThread_FinalizeIOJobs(nUpdateTypesBitmask); -} - -// Gets called regularly, to finalize those proxies whose jobs have -// already been executed (e.g. to call the callbacks) -// - to be called from the main thread only -// - starts new jobs in the single-threaded model -void CStreamEngine::Update() -{ - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - // Dispatch completed callbacks. - MainThread_FinalizeIOJobs(); - -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_resetstats) - { - ClearStatistics(); - g_cvars.sys_streaming_resetstats = 0; - } - - CTimeValue t = gEnv->pTimer->GetAsyncTime(); - if ((t - m_nLastBandwidthUpdateTime).GetMilliSecondsAsInt64() > 1000) - { - // Repeat every second. - m_nUnzipBandwidth = m_decompressStats.m_tempUnzipTime.GetValue() == 0 ? 0 : (uint32)(m_decompressStats.m_nTempBytesUnziped / m_decompressStats.m_tempUnzipTime.GetSeconds()); - m_nVerifyBandwidth = m_decompressStats.m_tempVerifyTime.GetValue() == 0 ? 0 : (uint32)(m_decompressStats.m_nTempBytesVerified / m_decompressStats.m_tempVerifyTime.GetSeconds()); - - m_decompressStats.m_tempUnzipTime.SetValue(0); - m_decompressStats.m_nTempBytesUnziped = 0; - m_decompressStats.m_tempVerifyTime.SetValue(0); - m_decompressStats.m_nTempBytesVerified = 0; - - m_nLastBandwidthUpdateTime = t; - } - if (m_decompressStats.m_totalUnzipTime.GetValue() != 0) - { - m_nUnzipBandwidthAverage = (uint32)(m_decompressStats.m_nTotalBytesUnziped / m_decompressStats.m_totalUnzipTime.GetSeconds()); - } - if (m_decompressStats.m_totalVerifyTime.GetValue() != 0) - { - m_nVerifyBandwidthAverage = (uint32)(m_decompressStats.m_nTotalBytesVerified / m_decompressStats.m_totalVerifyTime.GetSeconds()); - } - - m_Statistics.nDecompressBandwidth = m_nUnzipBandwidth; - m_Statistics.nVerifyBandwidth = m_nVerifyBandwidth; - m_Statistics.nDecompressBandwidthAverage = m_nUnzipBandwidthAverage; - m_Statistics.nVerifyBandwidthAverage = m_nVerifyBandwidthAverage; - - CTimeValue currentTime = gEnv->pTimer->GetAsyncTime(); - - CTimeValue timeSinceLastReset = currentTime - m_TimeOfLastReset; - float fSecSinceLastReset = timeSinceLastReset.GetSeconds(); - - CTimeValue timeSinceLastUpdate = currentTime - m_TimeOfLastUpdate; - - // update the stats every second - if (timeSinceLastUpdate.GetMilliSecondsAsInt64() > 1000) - { - UpdateIOThreadStats(&m_Statistics.hddInfo, &m_Statistics.memoryInfo, m_pThreadIO[eIOThread_HDD], fSecSinceLastReset); - UpdateIOThreadStats(&m_Statistics.discInfo, 0, m_pThreadIO[eIOThread_Optical], fSecSinceLastReset); - UpdateIOThreadStats(&m_Statistics.memoryInfo, 0, m_pThreadIO[eIOThread_InMemory], fSecSinceLastReset); - - SStreamEngineStatistics::SRequestTypeInfo totals; - - // update stats on all types - for (int i = 0; i < eStreamTaskTypeCount; i++) - { - SStreamEngineStatistics::SRequestTypeInfo& info = m_Statistics.typeInfo[i]; - - if (info.nTotalStreamingRequestCount) - { - info.fAverageCompletionTime = info.fTotalCompletionTime / info.nTotalStreamingRequestCount; - } - else - { - info.fAverageCompletionTime = 0; - } - info.nSessionReadBandwidth = (uint32)(info.nTotalReadBytes / fSecSinceLastReset); - info.nCurrentReadBandwidth = (uint32)(info.nTmpReadBytes / timeSinceLastUpdate.GetSeconds()); - - info.fAverageRequestCount = info.nTotalStreamingRequestCount / fSecSinceLastReset; - - totals.Merge(info); - - info.nTmpReadBytes = 0; - } - - if (totals.nTotalStreamingRequestCount > 0) - { - m_Statistics.fAverageCompletionTime = totals.fTotalCompletionTime / totals.nTotalStreamingRequestCount; - } - - m_Statistics.nTotalSessionReadBandwidth = (uint32)(totals.nTotalReadBytes / fSecSinceLastReset); - m_Statistics.nTotalCurrentReadBandwidth = (uint32)(totals.nTmpReadBytes / timeSinceLastUpdate.GetSeconds()); - m_Statistics.fAverageRequestCount = totals.nTotalStreamingRequestCount / fSecSinceLastReset; - - m_Statistics.nTotalRequestCount = totals.nTotalRequestCount; - m_Statistics.nTotalStreamingRequestCount = totals.nTotalStreamingRequestCount; - m_Statistics.nTotalBytesRead = totals.nTotalReadBytes; - - // update this flag only once a second to be sure it's visible in display info - m_Statistics.bTempMemOutOfBudget = m_bTempMemOutOfBudget; - m_bTempMemOutOfBudget = false; - - m_TimeOfLastUpdate = currentTime; - } - - int nTmpAllocated = m_tempMem.m_nTempAllocatedMemoryFrameMax; - m_Statistics.nMaxTempMemory = max(m_Statistics.nMaxTempMemory, nTmpAllocated); - m_Statistics.nTempMemory = nTmpAllocated; - - m_tempMem.m_nTempAllocatedMemoryFrameMax = m_tempMem.m_nTempAllocatedMemory; - - if (m_Statistics.vecHeavyAssets.size() > MAX_HEAVY_ASSETS) - { - AZStd::sort(m_Statistics.vecHeavyAssets.begin(), m_Statistics.vecHeavyAssets.end()); - m_Statistics.vecHeavyAssets.resize(MAX_HEAVY_ASSETS); - } - - if (g_cvars.sys_streaming_debug) - { - DrawStatistics(); - - if (!m_bInputCallback) - { - AzFramework::InputChannelEventListener::Connect(); - m_bInputCallback = true; - } - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -// Only waits at most the specified amount of time for some IO to complete -void CStreamEngine::UpdateAndWait(bool bAbortAll) -{ - // for stream->Wait sync - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - if (bAbortAll) - { - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->AbortAll(bAbortAll); - } - } - } - - while (!m_finishedStreams.empty() || !m_streams.empty()) - { - Update(); - // In case we still have cancelled or aborted streams in the queue, - // we wake the io threads here to ensure they are removed correctly; - for (uint32 i = 0; i < (uint32)eIOThread_Last; ++i) - { - SignalToStartWork((EIOThread)i, true); - } - CrySleep(10); - } - - if (bAbortAll) - { - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->AbortAll(false); - } - } - } -} - -// In the Multi-Threaded model (with the IO Worker thread) -// removes the proxies from the IO Queue as needed, and the proxies may call their callbacks -void CStreamEngine::MainThread_FinalizeIOJobs(uint32 type) -{ - static bool bNoReentrant = false; - - if (!bNoReentrant) - { - bNoReentrant = true; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks(); -#endif - - int nCount = 0; - - CryMT::vector finishedStreams; - // Dispatch completed callbacks. - CReadStream_AutoPtr pStream(0); - while (m_finishedStreams.try_pop_front(pStream)) - { - if (pStream->m_Type & type) - { - pStream->MainThread_Finalize(); - -#ifdef STREAMENGINE_ENABLE_STATS - // update statistics - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); - UpdateStatistics(pStream); -#endif - - m_streams.erase(pStream); - - nCount++; - // perform time slicing if requested - if (g_cvars.sys_streaming_max_finalize_per_frame > 0 && - nCount > g_cvars.sys_streaming_max_finalize_per_frame) - { - break; - } - } - else - { - finishedStreams.push_back(pStream); - } - } - - bNoReentrant = false; - - while (finishedStreams.try_pop_front(pStream)) - { - m_finishedStreams.push_back(pStream); - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks() - m_Statistics.nMainStreamingThreadWait; -#endif - } -} - - -// In the Multi-Threaded model (with the IO Worker thread) -// removes the proxies from the IO Queue as needed, and the proxies may call their callbacks -void CStreamEngine::MainThread_FinalizeIOJobs() -{ - static bool bNoReentrant = false; - - if (!bNoReentrant) - { - bNoReentrant = true; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks(); -#endif - - int nCount = 0; - - //Optim: swap finished streams out into a non MT vector - //avoid expensive push / pop operations. - m_tempFinishedStreams.clear(); - m_finishedStreams.swap(m_tempFinishedStreams); - - int numFinishedStreams = m_tempFinishedStreams.size(); - - // Dispatch completed callbacks. - for (int i = 0; i < numFinishedStreams; i++) - { - CReadStream_AutoPtr pStream = m_tempFinishedStreams[i]; - - //Check for a certain type of error that we need to handle in a TRC compliant way - if (pStream->GetError() == ERROR_VERIFICATION_FAIL) - { -#if !defined(_RELEASE) - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_COMMENT, "Stream error detected."); -#endif //!_RELEASE - } - - pStream->MainThread_Finalize(); - -#ifdef STREAMENGINE_ENABLE_STATS - // update statistics - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); - UpdateStatistics(pStream); -#endif - - m_streams.erase(pStream); - - nCount++; - - // AM: Optim, no longer support this behavior - // perform time slicing if requested - if (g_cvars.sys_streaming_max_finalize_per_frame > 0 && - nCount > g_cvars.sys_streaming_max_finalize_per_frame) - { - CryLogAlways("sys_streaming_max_finalize_per_frame is now deprecated"); - //break; - } - } - - m_tempFinishedStreams.clear(); - - bNoReentrant = false; - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks() - m_Statistics.nMainStreamingThreadWait; -#endif - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::UpdateJobPriority(IReadStreamPtr pJobStream) -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->NeedSorting(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::StopThreads() -{ - for (int i = 0; i < eIOThread_Last; i++) - { - m_pThreadIO[i] = 0; - } - - m_asyncCallbackThreads.clear(); - m_tempMem.m_nWakeEvents = 0; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::StartThreads() -{ - StopThreads(); - - m_tempMem.m_nWakeEvents = 0; - - m_pThreadIO[eIOThread_HDD] = new CStreamingIOThread(this, eStreamSourceTypeHDD, "Streaming File IO HDD");//, 160); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_HDD]->GetWakeEvent(); - - if (!(gEnv->IsDedicated())) - { - if (m_bUseOpticalDriveThread) - { - m_pThreadIO[eIOThread_Optical] = new CStreamingIOThread(this, eStreamSourceTypeDisc, "Streaming File IO Optical"); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_Optical]->GetWakeEvent(); - } - - m_pThreadIO[eIOThread_InMemory] = new CStreamingIOThread(this, eStreamSourceTypeMemory, "Streaming File IO InMemory"); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_InMemory]->GetWakeEvent(); - } - - // Initialise fallback thread matrix, needed for rescheduling - for (int i = 0; i < eIOThread_Last; ++i) - { - if (!m_pThreadIO[i]) - { - continue; - } - - for (int j = 0; j < eIOThread_Last; ++j) - { - if (i == j) - { - continue; - } - if (!m_pThreadIO[j]) - { - continue; - } - - m_pThreadIO[i]->RegisterFallbackIOThread(m_pThreadIO[j]->GetMediaType(), m_pThreadIO[j]); - } - } - - // More decompress threads can be added here. - m_asyncCallbackQueues.push_back(new SStreamRequestQueue); - m_asyncCallbackThreads.push_back(new CStreamingWorkerThread(this, "Streaming AsyncCallback", CStreamingWorkerThread::eWorkerAsyncCallback, m_asyncCallbackQueues.back())); - - //m_asyncCallbackThreads.push_back( new CStreamingWorkerThread(this,"Streaming AsyncCallback Pak 1",CStreamingWorkerThread::eWorkerAsyncCallback, m_asyncCallbackQueues[eStreamTaskTypePak]) ); -} - -//! Puts the memory statistics into the given sizer object -//! According to the specifications in interface ICrySizer -void CStreamEngine::GetMemoryStatistics(ICrySizer* pSizer) -{ - SIZER_COMPONENT_NAME(pSizer, "CRefStreamEngine"); - - size_t nSize = sizeof(*this); - - pSizer->AddObject(this, nSize); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::AbortJob(CReadStream* pStream) -{ - if (m_finishedStreams.try_remove((CReadStream*)pStream)) - { -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); -#endif - } - - { - CryAutoLock pausedLock(m_pausedLock); - if (!m_pausedStreams.empty()) - { - std::vector::iterator it = std::find(m_pausedStreams.begin(), m_pausedStreams.end(), pStream); - if (it != m_pausedStreams.end()) - { - m_pausedStreams.erase(it); - } - } - } - - m_streams.erase(pStream); -} - -#if defined(STREAMENGINE_ENABLE_STATS) -SStreamEngineStatistics& CStreamEngine::GetStreamingStatistics() -{ - return m_Statistics; -} -#endif - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::UpdateStatistics(CReadStream* pReadStream) -{ - uint32 nBytesRead = pReadStream->m_nBytesRead; - - SStreamEngineStatistics::SRequestTypeInfo& info = m_Statistics.typeInfo[pReadStream->m_Type]; - info.nTotalRequestCount++; - - // only add to stats if request was valid - const string& name = pReadStream->GetName(); - if (name.length() > 0) - { - info.nTotalReadBytes += nBytesRead; - info.nTmpReadBytes += nBytesRead; - info.nTotalRequestDataSize += pReadStream->m_Params.nSize; - - CTimeValue completionTime = gEnv->pTimer->GetAsyncTime() - pReadStream->GetRequestTime(); - float fCompletionTime = completionTime.GetMilliSeconds(); - info.fTotalCompletionTime += fCompletionTime; - - size_t splitter = name.find_last_of("."); - if (splitter != string::npos) - { - string extension = name.substr(splitter + 1); - TExtensionInfoMap::iterator findRes = m_PerExtensionInfo.find(extension); - if (findRes == m_PerExtensionInfo.end()) - { - m_PerExtensionInfo[extension] = SExtensionInfo(); - findRes = m_PerExtensionInfo.find(extension); - } - - SExtensionInfo& extensionInfo = findRes->second; - extensionInfo.m_fTotalReadTime += pReadStream->m_ReadTime.GetMilliSeconds(); - extensionInfo.m_nTotalRequests++; - extensionInfo.m_nTotalReadSize += nBytesRead; - extensionInfo.m_nTotalRequestSize += pReadStream->m_Params.nSize; - } - } - - if (nBytesRead > 64 * 1024) - { - m_Statistics.vecHeavyAssets.push_back(SStreamEngineStatistics::SAsset(pReadStream->m_strFileName, nBytesRead)); - } -} -#endif - -void CStreamEngine::Shutdown() -{ - m_bShutDown = true; - - // make sure we don't have queued paused streams during shutdown for the audio system - // or we can suffer from deadlocks - uint32 nPauseMask = GetPauseMask(); - uint32 nUnPauseMask = ~(nPauseMask & ~STREAM_TASK_TYPE_AUDIO_ALL); - PauseStreaming(false, nUnPauseMask); - PauseStreaming(true, nPauseMask); - - UpdateAndWait(true); - CancelAll(); - - StopThreads(); - - m_streams.clear(); - m_finishedStreams.clear(); - - // unregister system listener - GetISystem()->GetISystemEventDispatcher()->RemoveListener(this); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::CancelAll() -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->BeginReset(); - } - } - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->EndReset(); - } - } - - for (size_t i = 0; i < m_asyncCallbackThreads.size(); ++i) - { - m_asyncCallbackThreads[i]->BeginReset(); - } - for (size_t i = 0; i < m_asyncCallbackThreads.size(); ++i) - { - m_asyncCallbackThreads[i]->EndReset(); - } - - // make sure we don't check for canceled tasks when destroying the m_finishedStreams container - m_streams.clear(); - stl::free_container(m_finishedStreams); - stl::free_container(m_tempFinishedStreams); - { - CryAutoLock lock(m_pausedLock); - - std::vector paused; - paused.swap(m_pausedStreams); - - for (std::vector::iterator it = paused.begin(), itEnd = paused.end(); it != itEnd; ++it) - { - CReadStream* pStream = &**it; - pStream->AbortShutdown(); - } - } - - CReadStream::Flush(); - CAsyncIOFileRequest::Flush(); -} - - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::ReportAsyncFileRequestComplete(CAsyncIOFileRequest_AutoPtr pFileRequest) -{ - if (!pFileRequest->IsCancelled()) - { -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamBeginAsyncCallback(&*pFileRequest); - } -#endif - - if (pFileRequest->m_pCallback) - { - pFileRequest->m_pCallback->OnAsyncFinished(pFileRequest); - } - if (pFileRequest->m_pReadStream) - { - CReadStream_AutoPtr pStream = (CReadStream*)(IReadStream*)pFileRequest->m_pReadStream; - pStream->OnAsyncFileRequestComplete(); - m_finishedStreams.push_back(pStream); - -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedIncrement(&m_Statistics.nCurrentFinishedCount); -#endif - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamEndAsyncCallback(&*pFileRequest); - } -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug != 0) - { - if (g_cvars.sys_streaming_debug == 2 || g_cvars.sys_streaming_debug == 4) - { - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!pFileRequest->m_strFileName.empty() && !m_bStreamingStatsPaused) - { - if (!sFileFilter || !sFileFilter[0] || strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - CryAutoCriticalSection lock(m_csStats); - m_statsRequestList.insert(m_statsRequestList.begin(), pFileRequest); - } - } - } - } -#endif - } -} - -////////////////////////////////////////////////////////////////////////// -const char* CStreamEngine::GetStreamTaskTypeName(EStreamTaskType type) -{ - switch (type) - { - case eStreamTaskTypeMusic: - return "Music"; - case eStreamTaskTypeAnimation: - return "Animation"; - case eStreamTaskTypeGeometry: - return "Geometry"; - case eStreamTaskTypeSound: - return "Sound"; - case eStreamTaskTypeTexture: - return "Texture"; - case eStreamTaskTypeShader: - return "Shader"; - case eStreamTaskTypeTerrain: - return "Terrain"; - case eStreamTaskTypeVideo: - return "Video"; - case eStreamTaskTypeFlash: - return "Flash"; - case eStreamTaskTypePak: - return "Pak"; - case eStreamTaskTypeGeomCache: - return "GeomCache"; - case eStreamTaskTypeMergedMesh: - return "MergedMesh"; - } - return ""; -} - -SStreamJobEngineState CStreamEngine::GetJobEngineState() -{ - m_tempMem.m_nTempMemoryBudget = g_cvars.sys_streaming_memory_budget * 1024; - - SStreamJobEngineState state; - state.pReportQueues = &m_asyncCallbackQueues; -#ifdef STREAMENGINE_ENABLE_STATS - state.pStats = &m_Statistics; - state.pDecompressStats = &m_decompressStats; -#endif - state.pHeap = g_pPakHeap; - state.pTempMem = &m_tempMem; - return state; -} - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::GetBandwidthStats(EStreamTaskType type, float* bandwidth) -{ - *bandwidth = m_Statistics.typeInfo[type].nCurrentReadBandwidth / 1024.0f; -} -#endif - -void CStreamEngine::GetStreamingOpenStatistics(SStreamEngineOpenStats& openStatsOut) -{ - openStatsOut = m_OpenStatistics; -} - -#ifdef STREAMENGINE_ENABLE_LISTENER -void CStreamEngine::SetListener(IStreamEngineListener* pListener) -{ - m_pListener = pListener; -} -#endif - -#ifdef STREAMENGINE_ENABLE_LISTENER -IStreamEngineListener* CStreamEngine::GetListener() -{ - return m_pListener; -} -#endif - -////////////////////////////////////////////////////////////////////////// -void* CStreamEngine::TempAlloc(size_t nSize, const char* szDbgSource, bool bFallBackToMalloc, bool bUrgent, uint32 align) -{ - return m_tempMem.TempAlloc(g_pPakHeap, nSize, szDbgSource, bFallBackToMalloc, bUrgent, align); -} - -void CStreamEngine::TempFree(void* p, size_t nSize) -{ - m_tempMem.TempFree(g_pPakHeap, p, nSize); -} - -namespace -{ -#ifdef STREAMENGINE_ENABLE_STATS - void DrawText(const float, const float, ColorF, const char*, ...) - { - // ToDo: Remove whole file with SPEC-343, or update to draw with Atom? Likely the former as I think this whole system is dead. - } -#endif - - void WriteToStreamingLog([[maybe_unused]] const char* str) - { -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug == 4) - { - // ignore invalid file access when logging steaming data - CDebugAllowFileAccess ignoreInvalidFileAccess; - - static string sFileName; - static bool bFirstTime = true; - if (bFirstTime) - { - char path[AZ::IO::IArchive::MaxPath]; - path[sizeof(path) - 1] = 0; - gEnv->pCryPak->AdjustFileName("@usercache@\\TestResults\\StreamingLog.txt", path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING); - sFileName = path; - } - AZ::IO::HandleType fileHandle = fxopen(sFileName, (bFirstTime) ? "wt" : "at"); - bFirstTime = false; - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "%s\n", str); - gEnv->pFileIO->Close(fileHandle); - } - } -#endif - } -} - -#ifdef STREAMENGINE_ENABLE_STATS -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::DrawStatistics() -{ - std::vector tempRequests; - - if (g_cvars.sys_streaming_debug == 4) - { - float tx = 0; - float ty = 30; - float ystep = 12.0f; - ColorF clText(1, 0, 0, 1); - - DrawText(tx, ty += ystep, clText, "Recording streaming stats to file ..."); - - { - CryAutoCriticalSection lock(m_csStats); - tempRequests.swap(m_statsRequestList); - } - - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!tempRequests.empty()) - { - for (int i = (int)tempRequests.size() - 1; i >= 0; i--) - { - CAsyncIOFileRequest* pFileRequest = tempRequests[i]; - - if (g_cvars.sys_streaming_debug_filter > 0 && pFileRequest->m_eType != g_cvars.sys_streaming_debug_filter) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter == -1 && pFileRequest->m_eMediaType == eStreamSourceTypeMemory) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter_min_time && (pFileRequest->m_readTime.GetMilliSeconds() < (float)g_cvars.sys_streaming_debug_filter_min_time)) - { - continue; - } - if (sFileFilter && sFileFilter[0] && !strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - continue; - } - - const char* sFlags = (pFileRequest->m_eMediaType == eStreamSourceTypeHDD) ? "HDD" : ((pFileRequest->m_eMediaType == eStreamSourceTypeMemory) ? "mem" : "DVD"); - const char* sPriority = ""; - switch (pFileRequest->m_ePriority) - { - case estpUrgent: - sPriority = " Urgent"; - break; - case estpNormal: - sPriority = " Normal"; - break; - case estpIdle: - sPriority = " Idle"; - break; - case estpPreempted: - sPriority = " Preempted"; - break; - case estpBelowNormal: - sPriority = "BelowNormal"; - break; - case estpAboveNormal: - sPriority = "AboveNormal"; - break; - default: - sPriority = " Unknown"; - break; - } - - string str; - str.Format("[N%6d] [%+8d] [%8d] [%6.2f ms] (%5d|%5d) [%5.3fs] <%3d> <%s> <%s> <%s> %s:", - pFileRequest->m_nReadCounter, - pFileRequest->m_nReadHeadOffsetKB, - pFileRequest->m_nDiskOffset >> 10, - pFileRequest->m_readTime.GetMilliSeconds(), - pFileRequest->m_nSizeOnMedia / 1024, - ((pFileRequest->m_nRequestedSize) ? pFileRequest->m_nRequestedSize : pFileRequest->m_nFileSize) / 1024, - (pFileRequest->m_completionTime - pFileRequest->m_startTime).GetSeconds(), - pFileRequest->m_nTimeGroup, - sPriority, - sFlags, - pFileRequest->m_pakFile.c_str(), - pFileRequest->m_strFileName.c_str()); - - WriteToStreamingLog(str.c_str()); - } - } - - return; - } - - - { - CryAutoCriticalSection lock(m_csStats); - tempRequests = m_statsRequestList; - - size_t nMaxRequests = g_cvars.sys_streaming_debug_filter_min_time ? 1000 : 100; - if (m_statsRequestList.size() > nMaxRequests) - { - m_statsRequestList.resize(nMaxRequests); - } - } - - std::vector& requests = tempRequests; - - stack_string temp; - float tx = 0; - float ty = 30; - float ystep = 12.0f; - float xColumn = 80; - ColorF clText(0, 1, 1, 1); - - SStreamEngineStatistics& stats = m_Statistics; - SStreamEngineOpenStats openStats = m_OpenStatistics; - - const char* sMediaType = m_bStreamDataOnHDD ? "HDD" : "DVD"; - const char* sStatus = (m_bStreamingStatsPaused) ? "Paused" : ""; - DrawText(tx, ty += ystep, clText, "Streaming IO: %.2f|%.2fMB/s, ACT: %3dmsec, Unzip: %.2fMB/s, Verify: %.2fMB/s, Jobs:%5d (%4d) %s %s", - (float)stats.nTotalCurrentReadBandwidth / (1024 * 1024), (float)stats.nTotalSessionReadBandwidth / (1024 * 1024), - (uint32)stats.fAverageCompletionTime, (float)stats.nDecompressBandwidth / (1024 * 1024), (float)stats.nVerifyBandwidth / (1024 * 1024), - (uint32)stats.nTotalStreamingRequestCount, (uint32)(stats.nTotalRequestCount - stats.nTotalStreamingRequestCount), - sMediaType, sStatus); - - DrawText(tx, ty += ystep, clText, "\t Request: Active:%2d (%2.1fMB) Live:%2d Decompress:%2d Async:%2d Finished:%2d Temp Pool Max:%2.1fMB", openStats.nOpenRequestCount, - (float)stats.nPendingReadBytes / (1024 * 1024), CAsyncIOFileRequest::s_nLiveRequests, stats.nCurrentDecompressCount, stats.nCurrentAsyncCount, stats.nCurrentFinishedCount, - (float)stats.nMaxTempMemory / (1024 * 1024)); - - ty += ystep; - - // HDD stats - if (stats.hddInfo.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "HDD : Request: %3d|%5d (%4d MB|%3d KB) - BW: %1.2f|%1.2f Mb/s (Eff: %2.1f|%2.1f Mb/s) \n", - stats.hddInfo.nRequestCount, stats.hddInfo.nTotalRequestCount, (uint32)(stats.hddInfo.nTotalBytesRead / (1024 * 1024)), - (uint32)(stats.hddInfo.nTotalBytesRead / (1024 * stats.hddInfo.nTotalRequestCount)), - (float)stats.hddInfo.nCurrentReadBandwidth / (1024 * 1024), (float)stats.hddInfo.nSessionReadBandwidth / (1024 * 1024), - (float)stats.hddInfo.nActualReadBandwidth / (1024 * 1024), (float)stats.hddInfo.nAverageActualReadBandwidth / (1024 * 1024)); - DrawText(tx, ty += ystep, clText, "\t Seek: %1.2f GB - Active: %2.1f%%(%2.1f%%)", - (float)stats.hddInfo.nAverageSeekOffset / (1024 * 1024), - stats.hddInfo.fActiveDuringLastSecond, stats.hddInfo.fAverageActiveTime); - } - // Optical stats - if (stats.discInfo.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "Disc: Request: %3d|%5d (%4d MB|%3d KB) - BW: %1.2f|%1.2f Mb/s (Eff: %2.1f|%2.1f Mb/s) \n", - stats.discInfo.nRequestCount, stats.discInfo.nTotalRequestCount, (uint32)(stats.discInfo.nTotalBytesRead / (1024 * 1024)), - (uint32)(stats.discInfo.nTotalBytesRead / (1024 * stats.discInfo.nTotalRequestCount)), - (float)stats.discInfo.nCurrentReadBandwidth / (1024 * 1024), (float)stats.discInfo.nSessionReadBandwidth / (1024 * 1024), - (float)stats.discInfo.nActualReadBandwidth / (1024 * 1024), (float)stats.discInfo.nAverageActualReadBandwidth / (1024 * 1024)); - DrawText(tx, ty += ystep, clText, "\t Seek: %1.2f GB - Active: %2.1f%%(%2.1f%%)", - (float)stats.discInfo.nAverageSeekOffset / (1024 * 1024), - stats.discInfo.fActiveDuringLastSecond, stats.discInfo.fAverageActiveTime); - } - DrawText(tx, ty += ystep, clText, "Mem : Request: %3d|%5d (%4d MB)", - stats.memoryInfo.nRequestCount, stats.memoryInfo.nTotalRequestCount, (stats.memoryInfo.nTotalBytesRead / (1024 * 1024))); - - ty += ystep; - - for (int i = eStreamTaskTypeCount - 1; i >= 1; i--) - { - EStreamTaskType eTaskType = (EStreamTaskType)i; - SStreamEngineStatistics::SRequestTypeInfo info = stats.typeInfo[eTaskType]; - - if (g_cvars.sys_streaming_debug > 1 || info.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "%9s: BSize:%3dKb Read:%4dMb BW:%1.2f|%1.2f Mb/s ACT:%5dms %2d(%2.1fMB)|%5d", - gEnv->pSystem->GetStreamEngine()->GetStreamTaskTypeName(eTaskType), - (uint32)(info.nTotalReadBytes / max((uint32)1, info.nTotalStreamingRequestCount) / 1024), - (uint32)(info.nTotalReadBytes / (1024 * 1024)), (float)info.nCurrentReadBandwidth / (1024 * 1024), - (float)info.nSessionReadBandwidth / (1024 * 1024), (uint32)info.fAverageCompletionTime, - openStats.nOpenRequestCountByType[eTaskType], (float)info.nPendingReadBytes / (1024 * 1024), (uint32)info.nTotalStreamingRequestCount); - } - } - - if (g_cvars.sys_streaming_debug == 5) - { - ty += ystep; - ty += ystep; - - DrawText(tx, ty += ystep, clText, "Name | Time(s) | Size(Kb) | Read(Mb) | ReqS(Mb) | Count"); - - for (TExtensionInfoMap::iterator it = m_PerExtensionInfo.begin(); it != m_PerExtensionInfo.end(); ++it) - { - SExtensionInfo& extensionInfo = it->second; - DrawText(tx, ty += ystep, clText, "%4s | %7.3f | %8d | %8.3f | %8.3f | %5d", - it->first.c_str(), extensionInfo.m_fTotalReadTime / 1000, (uint32)(extensionInfo.m_nTotalReadSize / max((size_t)1, extensionInfo.m_nTotalRequests) / 1024), - extensionInfo.m_nTotalReadSize / (1024.0f * 1024.0f), extensionInfo.m_nTotalRequestSize / (1024.0f * 1024.0f), extensionInfo.m_nTotalRequests); - } - } - else if (g_cvars.sys_streaming_debug > 1) - { - ty += ystep; - - DrawText(tx, ty += ystep, clText, "[Offset KB]"); - DrawText(tx + xColumn, ty, clText, "[io ms]\t(read | size) [t sec] [Grp] < Priority> Filename"); - - ty += ystep; - - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - for (size_t i = 0, nRequests = requests.size(); i < nRequests; i++) - { - CAsyncIOFileRequest* pFileRequest = requests[i]; - - if (g_cvars.sys_streaming_debug_filter > 0 && pFileRequest->m_eType != g_cvars.sys_streaming_debug_filter) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter == -1 && pFileRequest->m_eMediaType == eStreamSourceTypeMemory) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter_min_time && (pFileRequest->m_readTime.GetMilliSeconds() < (float)g_cvars.sys_streaming_debug_filter_min_time)) - { - continue; - } - if (sFileFilter != 0 && sFileFilter[0] && !strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - continue; - } - - { - float fMillis = pFileRequest->m_readTime.GetMilliSeconds(); - const char* sFlags = ""; - switch (pFileRequest->m_eMediaType) - { - case eStreamSourceTypeHDD: - sFlags = "HDD"; - break; - case eStreamSourceTypeDisc: - sFlags = "DVD"; - break; - case eStreamSourceTypeMemory: - sFlags = "MEM"; - break; - } - const char* sPriority = ""; - switch (pFileRequest->m_ePriority) - { - case estpUrgent: - sPriority = " Urgent"; - break; - case estpNormal: - sPriority = " Normal"; - break; - case estpIdle: - sPriority = " Idle"; - break; - case estpPreempted: - sPriority = " Preempted"; - break; - case estpBelowNormal: - sPriority = "BelowNormal"; - break; - case estpAboveNormal: - sPriority = "AboveNormal"; - break; - default: - sPriority = " Unknown"; - break; - } - uint32 nRequestedSize = (pFileRequest->m_nRequestedSize != 0) ? pFileRequest->m_nRequestedSize : pFileRequest->m_nFileSize; - - ////////////////////////////////////////////////////////////////////////// - ColorF colOffset; - if (pFileRequest->m_nReadHeadOffsetKB >= 0) - { - colOffset = ColorF (0, 1, 0, 1); // Green - if (pFileRequest->m_nReadHeadOffsetKB > 32) - { - colOffset = ColorF (0.5f, 1.f, 0, 1.f); // Cyan - } - } - else - { - colOffset = ColorF (1, 0, 0, 1); // Red - } - if (pFileRequest->m_eMediaType != eStreamSourceTypeMemory) - { - DrawText(tx, ty, colOffset, "[%+d]", pFileRequest->m_nReadHeadOffsetKB); - } - ////////////////////////////////////////////////////////////////////////// - - DrawText(tx + xColumn, ty, clText, "[%6.2f]\t(%5d|%5d) [%5.2f] [%3d] <%s> <%s>\t%s", - fMillis, pFileRequest->m_nSizeOnMedia / 1024, nRequestedSize / 1024, (pFileRequest->m_completionTime - pFileRequest->m_startTime).GetSeconds(), - pFileRequest->m_nTimeGroup, sPriority, sFlags, pFileRequest->m_strFileName.c_str()); - - ty += ystep; - } - } - } -} -#endif //STREAMENGINE_ENABLE_STATS - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::ClearStatistics() -{ - m_TimeOfLastReset = gEnv->pTimer->GetAsyncTime(); - m_TimeOfLastUpdate = m_TimeOfLastReset; - - m_Statistics.hddInfo.ResetStats(); - m_Statistics.discInfo.ResetStats(); - - m_PerExtensionInfo.clear(); - - m_Statistics.nDecompressBandwidth = 0; - m_Statistics.nVerifyBandwidth = 0; - m_Statistics.nDecompressBandwidthAverage = 0; - m_Statistics.nVerifyBandwidthAverage = 0; - - m_Statistics.nTotalBytesRead = 0; - m_Statistics.nTotalRequestCount = 0; - m_Statistics.nTotalStreamingRequestCount = 0; - - m_Statistics.nMaxTempMemory = 0; - - m_Statistics.fAverageCompletionTime = 0; - - for (int i = 0; i < eStreamTaskTypeCount; i++) - { - m_Statistics.typeInfo[i].ResetStats(); - } - m_Statistics.vecHeavyAssets.clear(); - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->m_InMemoryStats.Reset(); - m_pThreadIO[i]->m_NotInMemoryStats.Reset(); - } - } -} -#endif - -////////////////////////////////////////////////////////////////////////// -bool CStreamEngine::OnInputChannelEventFiltered([[maybe_unused]] const AzFramework::InputChannel& inputChannel) -{ -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug) - { - if (inputChannel.GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::Function11) - { - m_bStreamingStatsPaused = true; - } - if (inputChannel.GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::Function12) - { - m_bStreamingStatsPaused = false; - } - } -#endif - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) -{ - switch (event) - { - case ESYSTEM_EVENT_GAME_POST_INIT_DONE: - { - // unpause the streaming engine, when init phase is done - PauseStreaming(false, -1); - break; - } - case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE: -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - - WriteToStreamingLog("*LEVEL_LOAD_PREPARE"); - break; - - case ESYSTEM_EVENT_LEVEL_LOAD_START: - { - WriteToStreamingLog("*LEVEL_LOAD_START"); - break; - } - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - WriteToStreamingLog("*LEVEL_LOAD_END"); - break; - } - case ESYSTEM_EVENT_LEVEL_PRECACHE_START: - { - WriteToStreamingLog("*LEVEL_LOAD_PRECACHE_START"); - break; - } - case ESYSTEM_EVENT_LEVEL_PRECACHE_END: - { - WriteToStreamingLog("*LEVEL_LOAD_PRECACHE_END"); - break; - } - case ESYSTEM_EVENT_LEVEL_UNLOAD: - { - UpdateAndWait(true); - CancelAll(); - -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - break; - } - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - UpdateAndWait(true); - CancelAll(); - -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - } - break; - case ESYSTEM_EVENT_FAST_SHUTDOWN: - { - Shutdown(); - break; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::PauseStreaming(bool bPause, uint32 nPauseTypesBitmask) -{ - CryAutoLock pausedLock(m_pausedLock); - if (bPause) - { - m_nPausedDataTypesMask |= nPauseTypesBitmask; - } - else - { - m_nPausedDataTypesMask &= ~nPauseTypesBitmask; - ResumePausedStreams_PauseLocked(); - } -} -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::PauseIO(bool bPause) -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->Pause(bPause); - } - } -} -////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h b/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h deleted file mode 100644 index 57d47b8674..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h +++ /dev/null @@ -1,239 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H -#pragma once - - -#include "IStreamEngine.h" -#include "ISystem.h" -#include "TimeValue.h" - -#include -#include "StreamIOThread.h" -#include "StreamReadStream.h" - -#include -#include -#include -#include - -enum EIOThread -{ - eIOThread_HDD = 0, - eIOThread_Optical = 1, - eIOThread_InMemory = 2, - eIOThread_Last = 3, -}; - -////////////////////////////////////////////////////////////////////////// -class CStreamEngine - : public IStreamEngine - , public ISystemEventListener - , public AzFramework::InputChannelEventListener -{ -public: - CStreamEngine(); - ~CStreamEngine(); - - void Shutdown(); - // This is called to cancel all pending requests, without sending callbacks. - void CancelAll(); - - - //Helper added to aid in migration from Cry's CStreamEngine to AZ::IO::Streamer - static AZ::IO::IStreamerTypes::Priority CryStreamPriorityToAZStreamPriority(EStreamTaskPriority cryPriority); - static AZStd::chrono::milliseconds AZDeadlineFromReadParams(const StreamReadParams& params); - - ////////////////////////////////////////////////////////////////////////// - // IStreamEngine interface - ////////////////////////////////////////////////////////////////////////// - IReadStreamPtr StartRead (const EStreamTaskType tSource, const char* szFile, IStreamCallback* pCallback, const StreamReadParams* pParams = NULL); - size_t StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback = nullptr); - void BeginReadGroup(); - void EndReadGroup(); - - bool IsStreamDataOnHDD() const { return m_bStreamDataOnHDD; } - void SetStreamDataOnHDD(bool bFlag) { m_bStreamDataOnHDD = bFlag; } - - void Update(); - void UpdateAndWait(bool bAbortAll = false); - void Update(uint32 nUpdateTypesBitmask); - - void GetMemoryStatistics(ICrySizer* pSizer); - -#if defined(STREAMENGINE_ENABLE_STATS) - SStreamEngineStatistics& GetStreamingStatistics(); - void ClearStatistics(); - - void GetBandwidthStats(EStreamTaskType type, float* bandwidth); -#endif - - void GetStreamingOpenStatistics(SStreamEngineOpenStats& openStatsOut); - - const char* GetStreamTaskTypeName(EStreamTaskType type); - - SStreamJobEngineState GetJobEngineState(); - SStreamEngineTempMemStats& GetTempMemStats() { return m_tempMem; } - - // Will pause or unpause streaming of specified by mask data types - void PauseStreaming(bool bPause, uint32 nPauseTypesBitmask); - // Pause/resumes any IO active from the streaming engine - void PauseIO(bool bPause); - - uint32 GetPauseMask() const { return m_nPausedDataTypesMask; } - -#if defined(STREAMENGINE_ENABLE_LISTENER) - void SetListener(IStreamEngineListener* pListener); - IStreamEngineListener* GetListener(); -#endif - - ////////////////////////////////////////////////////////////////////////// - - // updates the job priority of an IO job into the IOQueue while maintaining order in the queue - void UpdateJobPriority(IReadStreamPtr pJobStream); - - void ReportAsyncFileRequestComplete(CAsyncIOFileRequest_AutoPtr pFileRequest); - void AbortJob(CReadStream* pStream); - - - // Dispatches synchrnous callbacks, free temporary memory hold for callbacks. - void MainThread_FinalizeIOJobs(); - void MainThread_FinalizeIOJobs(uint32 type); - - void* TempAlloc(size_t nSize, const char* szDbgSource, bool bFallBackToMalloc = true, bool bUrgent = false, uint32 align = 0); - void TempFree(void* p, size_t nSize); - - uint32 GetCurrentTempMemorySize() const { return m_tempMem.m_nTempAllocatedMemory; } - void FlagTempMemOutOfBudget() - { -#ifdef STREAMENGINE_ENABLE_STATS - m_bTempMemOutOfBudget = true; -#endif - } - - ////////////////////////////////////////////////////////////////////////// - // AzFramework::InputChannelEventListener - ////////////////////////////////////////////////////////////////////////// - bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override; - ////////////////////////////////////////////////////////////////////////// - - bool StartFileRequest(CAsyncIOFileRequest* pFileRequest); - void SignalToStartWork(EIOThread e, bool bForce); - -private: - void StartThreads(); - void StopThreads(); - - void ResumePausedStreams_PauseLocked(); - -#if defined(STREAMENGINE_ENABLE_STATS) - // add job to current statistics - void UpdateStatistics(CReadStream* pReadStream); - void DrawStatistics(); -#endif - - void QueueRequestCompleteJob(class AZRequestReadStream* stream, AZ::IO::SizeType numBytesRead, void* buffer, - AZ::IO::IStreamerTypes::RequestStatus requestState); - - ////////////////////////////////////////////////////////////////////////// - // ISystemEventListener - ////////////////////////////////////////////////////////////////////////// - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); - ////////////////////////////////////////////////////////////////////////// - -private: - - ////////////////////////////////////////////////////////////////////////// - CryMT::set m_streams; - CryMT::vector m_finishedStreams; - std::vector m_tempFinishedStreams; - - CryCriticalSection m_pendingRequestCompletionsLock; - AZStd::queue m_pendingRequestCompletions; - - // 2 IO threads. - _smart_ptr m_pThreadIO[eIOThread_Last]; - std::vector<_smart_ptr > m_asyncCallbackThreads; - std::vector m_asyncCallbackQueues; - - CryCriticalSection m_pausedLock; - std::vector m_pausedStreams; - volatile uint32 m_nPausedDataTypesMask; - - bool m_bStreamDataOnHDD; - bool m_bUseOpticalDriveThread; - - ////////////////////////////////////////////////////////////////////////// - // Streaming statistics. - ////////////////////////////////////////////////////////////////////////// - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* m_pListener; -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - SStreamEngineStatistics m_Statistics; - SStreamEngineDecompressStats m_decompressStats; - CTimeValue m_TimeOfLastReset; - CTimeValue m_TimeOfLastUpdate; - - CryCriticalSection m_csStats; - std::vector m_statsRequestList; - - struct SExtensionInfo - { - SExtensionInfo() - : m_fTotalReadTime(0.0f) - , m_nTotalRequests(0) - , m_nTotalReadSize(0) - , m_nTotalRequestSize(0) - { - } - float m_fTotalReadTime; - size_t m_nTotalRequests; - uint64 m_nTotalReadSize; - uint64 m_nTotalRequestSize; - }; - typedef std::map TExtensionInfoMap; - TExtensionInfoMap m_PerExtensionInfo; - - ////////////////////////////////////////////////////////////////////////// - // Used to calculate unzip/verify bandwidth for statistics. - uint32 m_nUnzipBandwidth; - uint32 m_nUnzipBandwidthAverage; - uint32 m_nVerifyBandwidth; - uint32 m_nVerifyBandwidthAverage; - CTimeValue m_nLastBandwidthUpdateTime; - - bool m_bStreamingStatsPaused; - bool m_bInputCallback; - bool m_bTempMemOutOfBudget; - ////////////////////////////////////////////////////////////////////////// -#endif - - SStreamEngineOpenStats m_OpenStatistics; - - bool m_bShutDown; - - volatile int m_nBatchMode; - - // Memory currently allocated by streaming engine for temporary storage. - SStreamEngineTempMemStats m_tempMem; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp deleted file mode 100644 index e3d184fc31..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp +++ /dev/null @@ -1,819 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Thread for IO - - -#include "CrySystem_precompiled.h" -#include "StreamIOThread.h" -#include "StreamEngine.h" -#include "../System.h" - -extern SSystemCVars g_cvars; - -//#pragma("control %push O=0") // to disable optimization - -////////////////////////////////////////////////////////////////////////// -CStreamingIOThread::CStreamingIOThread(CStreamEngine* pStreamEngine, EStreamSourceMediaType mediaType, const char* name) -{ - m_pStreamEngine = pStreamEngine; - m_bCancelThreadRequest = false; - m_bNeedSorting = false; - m_bNeedReset = false; - m_bNewRequests = false; - m_name = name; - m_eMediaType = mediaType; - m_nFallbackMTs = 0; - - m_iUrgentRequests = 0; - - m_bPaused = false; - m_bAbortReads = false; - - m_nReadCounter = 0; - m_nStreamingCPU = -1; - - Start((unsigned)(1 << g_cvars.sys_streaming_cpu), name); -} - -CStreamingIOThread::~CStreamingIOThread() -{ - Cancel(); - Stop(); - WaitForThread(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::AddRequest(CAsyncIOFileRequest* pRequest, bool bStartImmidietly) -{ - pRequest->AddRef(); // Acquire ownership on file request. - pRequest->m_status = CAsyncIOFileRequest::eStatusInFileQueue; - if (pRequest->m_eMediaType != eStreamSourceTypeMemory) - { - pRequest->m_eMediaType = m_eMediaType; - } - // does this ignore the tmp out of memory - if (pRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - m_newFileRequests.push_back(pRequest); - - if (bStartImmidietly) - { - READ_WRITE_BARRIER - m_bNewRequests = true; - m_awakeEvent.Set(); - } -} - - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::SignalStartWork(bool bForce) -{ - if (!m_newFileRequests.empty() || bForce) - { - READ_WRITE_BARRIER - m_bNewRequests = true; - - m_awakeEvent.Set(); - } -} - -////////////////////////////////////////////////////////////////////////// - -void CStreamingIOThread::Pause(bool bPause) -{ - m_bPaused = bPause; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::Run() -{ - SetName(m_name); - - CTimeValue t0 = gEnv->pTimer->GetAsyncTime(); - - m_nLastReadDiskOffset = 0; - - // - // Main thread loop - while (!m_bCancelThreadRequest) - { - if (m_nStreamingCPU != g_cvars.sys_streaming_cpu) - { - m_nStreamingCPU = g_cvars.sys_streaming_cpu; - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define STREAMIOTHREAD_CPP_SECTION_1 1 -#define STREAMIOTHREAD_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION STREAMIOTHREAD_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(StreamEngine/StreamIOThread_cpp) -#endif - } - - if (m_bNewRequests || !m_newFileRequests.empty()) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - else - { -#if defined(_RELEASE) - m_awakeEvent.Wait(); -#elif defined(STREAMENGINE_ENABLE_STATS) - // compute max time to wait - revive thread every second at least once to update stats - bool bWaiting = true; - while (bWaiting) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - uint64 msec = deltaT.GetMilliSecondsAsInt64(); - if (msec < 1000) - { - bWaiting = !m_awakeEvent.Wait(1000 - (uint32)msec); - } - - if (bWaiting) - { - // update the delta time again - t1 = gEnv->pTimer->GetAsyncTime(); - deltaT = t1 - t0; - - m_InMemoryStats.Update(deltaT); - m_NotInMemoryStats.Update(deltaT); - - t0 = t1; - } - } -#endif - } - - if (m_bNeedReset) - { - ProcessReset(); - } - - bool bIsOOM = false; - - while (!m_bCancelThreadRequest && !m_fileRequestQueue.empty()) - { - CAsyncIOFileRequest_TransferPtr pFileRequest(m_fileRequestQueue.back()); - m_fileRequestQueue.pop_back(); - - assert (&*pFileRequest); - - if (pFileRequest->HasFailed()) - { - // check if request was high prio, then decr open count - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - - continue; - } - - ////////////////////////////////////////////////////////////////////////// - // When temporary memory goes out of budget we must loop here and wait until previous file requests are finished and free up memory. - // Only allow processing of requests which are flagged for processing when out of tmp memory - ////////////////////////////////////////////////////////////////////////// - if (bIsOOM && !m_bCancelThreadRequest) - { - m_pStreamEngine->FlagTempMemOutOfBudget(); - if (m_iUrgentRequests > 0) - { - if (m_bNewRequests || !m_newFileRequests.empty()) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - - // readd the current request - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - - // search for the first request which ignores the current out of mem state - // Search for next highest priority request - std::vector::reverse_iterator rit; - for (rit = m_fileRequestQueue.rbegin(); rit != m_fileRequestQueue.rend(); ++rit) - { - if ((*rit)->IgnoreOutofTmpMem()) - { - pFileRequest = *rit; - std::vector::iterator it(rit.base()); - --it; - m_fileRequestQueue.erase(it); - break; - } - } - } - else - { - // read the current request - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - } - } - - // Simply let the io thread sleep when paused before doing any actual IO - while (m_bPaused) - { - CrySleep(10); - } - - // If at this point, the filerequest is zero, the above prioritization of - // urgent requests couldn't find a new task to displace the current - // one. As the current one had been pushed back previously, we can safely - // assume that restarting the loop will grab it again (eventually). - if (!pFileRequest) - { - break; - } - - // check if request was high prio, then decr open count - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - - bIsOOM = false; - - uint32 nSizeOnMedia = pFileRequest->m_nSizeOnMedia; - uint32 nError = 0; - - // Handle file request. - if (m_bAbortReads) - { - nError = ERROR_ABORTED_ON_SHUTDOWN; - } - else if (pFileRequest->m_bReadBegun) - { - nError = pFileRequest->ReadFileResume(this); - } - else - { - nError = pFileRequest->ReadFile(this); - } - -#ifdef STREAMENGINE_ENABLE_STATS - pFileRequest->m_nReadCounter = m_nReadCounter++; -#endif - - if (nError == 0) - { - if (pFileRequest->m_eMediaType != eStreamSourceTypeMemory) - { - pFileRequest->m_nReadHeadOffsetKB = (int32)(((int64)pFileRequest->m_nDiskOffset - m_nLastReadDiskOffset) >> 10); // in KB - m_nLastReadDiskOffset = pFileRequest->m_nDiskOffset + nSizeOnMedia; - -#ifdef STREAMENGINE_ENABLE_STATS - m_NotInMemoryStats.m_nTempReadOffset += abs(pFileRequest->m_nReadHeadOffsetKB); - m_NotInMemoryStats.m_nTotalReadOffset += abs(pFileRequest->m_nReadHeadOffsetKB); - - m_NotInMemoryStats.m_nTempRequestCount++; - - // Calc IO bandwidth only for non memory files. - m_NotInMemoryStats.m_nTempBytesRead += nSizeOnMedia; - m_NotInMemoryStats.m_TempReadTime += pFileRequest->m_readTime; -#endif - } - else - { -#ifdef STREAMENGINE_ENABLE_STATS - m_InMemoryStats.m_nTempRequestCount++; - - // Calc IO bandwidth only for in memory files. - m_InMemoryStats.m_nTempBytesRead += nSizeOnMedia; - m_InMemoryStats.m_TempReadTime += pFileRequest->m_readTime; -#endif - } - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - } - else - { - switch (nError) - { - case ERROR_OUT_OF_MEMORY: - bIsOOM = true; - - pFileRequest->SetPriority(estpPreempted); - - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - m_bNewRequests = true; - break; - - case ERROR_PREEMPTED: - pFileRequest->SetPriority(estpPreempted); - - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - m_bNewRequests = true; - break; - - case ERROR_MISSCHEDULED: - // Request tried to read a file that has changed media type. Reset the sort key - // and reschedule. - pFileRequest->m_bSortKeyComputed = 0; - AddRequest(&*pFileRequest, false); - break; - - default: - pFileRequest->SyncWithDecompress(); - pFileRequest->Failed(nError); - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - break; - } - } - - ////////////////////////////////////////////////////////////////////////// - if (m_bNewRequests) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - if (m_bNeedReset) - { - ProcessReset(); - } - if (m_bNeedSorting) - { - SortRequests(); - } - - ////////////////////////////////////////////////////////////////////////// -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_max_bandwidth != 0) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - - // Sleep in case we are streaming too fast. - const float fTheoreticalReadTime = float(nSizeOnMedia) / g_cvars.sys_streaming_max_bandwidth * 0.00000095367431640625f; // / (1024*1024) - - if (fTheoreticalReadTime - deltaT.GetSeconds() > FLT_EPSILON) - { - uint32 nSleepTime = uint32(1000.f * (fTheoreticalReadTime - deltaT.GetSeconds())); - CrySleep(nSleepTime); - } - } - - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - - // update the stats every second - if (deltaT.GetMilliSecondsAsInt64() > 1000) - { - m_InMemoryStats.Update(deltaT); - m_NotInMemoryStats.Update(deltaT); - - t0 = t1; - } -#endif - } - } -} - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamingIOThread::SStats::Update(const CTimeValue& deltaT) -{ - m_nReadBytesInLastSecond = (uint32)m_nTempBytesRead; - m_nRequestCountInLastSecond = m_nTempRequestCount; - m_nTotalReadBytes += (uint32)m_nTempBytesRead; - m_nTotalRequestCount += m_nTempRequestCount; - m_TotalReadTime += m_TempReadTime; - - if (m_TempReadTime.GetValue() != 0) - { - m_nActualReadBandwith = (uint32)(m_nTempBytesRead / m_TempReadTime.GetSeconds()); - } - else - { - m_nActualReadBandwith = 0; - } - m_nCurrentReadBandwith = (uint32)(m_nTempBytesRead / deltaT.GetSeconds()); - m_fReadingDuringLastSecond = m_TempReadTime.GetSeconds() / deltaT.GetSeconds() * 100; - - if (m_nTempRequestCount > 0) - { - m_nReadOffsetInLastSecond = m_nTempReadOffset / m_nTempRequestCount; - } - else - { - m_nReadOffsetInLastSecond = 0; - } - - m_TempReadTime.SetValue(0); - m_nTempBytesRead = 0; - m_nTempReadOffset = 0; - m_nTempRequestCount = 0; -} -#endif - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::Cancel() -{ - m_bCancelThreadRequest = true; - m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -struct SCompareAsyncFileRequest -{ - bool operator()(CAsyncIOFileRequest* pFile1, CAsyncIOFileRequest* pFile2) const - { - return pFile1->m_nSortKey > pFile2->m_nSortKey; - } -}; - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::SortRequests() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - std::sort(m_fileRequestQueue.begin(), m_fileRequestQueue.end(), SCompareAsyncFileRequest()); - - /* - int nStartOfQueue = 0; - int64 nDiskOffsetLimit = m_nLastReadDiskOffset - 32*1024; // 32KB less only - - int nCount = (int)m_fileRequestQueue.size(); - for (int i = nCount-1; i >= 0; i--) - { - if (m_fileRequestQueue[i]->m_nDiskOffset > nDiskOffsetLimit) - { - nStartOfQueue = i+1; - break; - } - } - if (nStartOfQueue < nCount && nStartOfQueue > 0) - { - int nElements = nCount - nStartOfQueue; - // Move all elements up to nStartOfQueue, from begining of the request array to the end. - m_temporaryArray.resize(0); - // Copy to temp array elements up to nStartOfQueue - m_temporaryArray.insert( m_temporaryArray.end(),m_fileRequestQueue.begin()+nStartOfQueue,m_fileRequestQueue.end() ); - // Remove elements up to nStartOfQueue from request list - m_fileRequestQueue.erase( m_fileRequestQueue.begin()+nStartOfQueue,m_fileRequestQueue.end() ); - // Add elemenets at the end from temp array. - m_fileRequestQueue.insert( m_fileRequestQueue.begin(),m_temporaryArray.begin(),m_temporaryArray.end() ); - } - */ - m_bNeedSorting = false; -} - -void CStreamingIOThread::NeedSorting() -{ - m_bNeedSorting = true; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::ProcessNewRequests() -{ - m_bNewRequests = false; - - std::vector temporaryArray; - temporaryArray.reserve(m_newFileRequests.size()); - m_newFileRequests.swap(temporaryArray); - - std::vector& newFiles = temporaryArray; - - if (!newFiles.empty()) - { - uint64 nCurrentKeyInProgress = m_fileRequestQueue.size() ? m_fileRequestQueue.back()->m_nSortKey : 0; - - // Compute sorting key for new file entries. - int iWakeFallback(0); - const TFallbackIOVecConstIt itEnd = m_FallbackIOThreads.end(); - const size_t fallbackNum = m_FallbackIOThreads.size(); - PREFAST_SUPPRESS_WARNING(6255) - uint8 * pFallbackSignals = fallbackNum ? (uint8*)alloca(fallbackNum) : NULL; - for (uint32 fb = 0; fb < fallbackNum; ++fb) - { - pFallbackSignals[fb] = 0; - } - - for (size_t i = 0, num = newFiles.size(); i < num; i++) - { - CAsyncIOFileRequest* pFilepRequest = newFiles[i]; - - pFilepRequest->ComputeSortKey(nCurrentKeyInProgress); - static_cast(&*pFilepRequest->m_pReadStream)->ComputedMediaType(pFilepRequest->m_eMediaType); - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = m_pStreamEngine->GetListener(); - if (pListener) - { - pListener->OnStreamComputedSortKey(pFilepRequest, pFilepRequest->m_nSortKey); - } -#endif - - bool bFallback = false; - int idx = -1; - for (TFallbackIOVecConstIt it = m_FallbackIOThreads.begin(); it != itEnd && !bFallback; ++it) - { - ++idx; - if (it->second == pFilepRequest->GetMediaType()) - { - if (pFilepRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - (it->first)->AddRequest(pFilepRequest, true); - pFilepRequest->Release(); // Release local ownership of request (moved to fallback IO thread) - iWakeFallback++; - bFallback = true; - pFallbackSignals[idx] = 1; - } - } - if (!bFallback) - { - m_fileRequestQueue.push_back(pFilepRequest); - } - } - - for (uint32 fb = 0; fb < fallbackNum; ++fb) - { - if (pFallbackSignals[fb] != 0) - { - (m_FallbackIOThreads[fb].first)->SignalStartWork(false); - } - } - - SortRequests(); - /* - if (m_fileRequestQueue.back() != pRequest && pRequest != 0) - { - // Highest priority changed. - if (m_fileRequestQueue.back()->m_nDiskOffset < (m_nLastReadDiskOffset-32*1024)) - { - //CryLog( "Bad Offset in Queue" ); - } - } - */ - } -} - -void CStreamingIOThread::ProcessReset() -{ - if (!m_fileRequestQueue.empty()) - { - for (std::vector::iterator it = m_fileRequestQueue.begin(), itEnd = m_fileRequestQueue.end(); it != itEnd; ++it) - { - (*it)->Release(); - } - } - - stl::free_container(m_fileRequestQueue); - - if (!m_temporaryArray.empty()) - { - for (std::vector::iterator it = m_temporaryArray.begin(), itEnd = m_temporaryArray.end(); it != itEnd; ++it) - { - (*it)->Release(); - } - } - - stl::free_container(m_temporaryArray); - - m_bNeedReset = false; - m_resetDoneEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::CancelAll() -{ - { - CryMT::vector::AutoLock lock(m_newFileRequests.get_lock()); - - if (!m_newFileRequests.empty()) - { - CAsyncIOFileRequest* const* it = &m_newFileRequests.front(); - CAsyncIOFileRequest* const* itEnd = it + m_newFileRequests.size(); - for (; it != itEnd; ++it) - { - (*it)->Release(); - } - } - } - - m_newFileRequests.free_memory(); - m_iUrgentRequests = 0; -} - -void CStreamingIOThread::AbortAll(bool bAbort) -{ - m_bAbortReads = bAbort; -} - -void CStreamingIOThread::BeginReset() -{ - CancelAll(); - - m_resetDoneEvent.Reset(); - m_bNeedReset = true; - m_awakeEvent.Set(); -} - -void CStreamingIOThread::EndReset() -{ - m_resetDoneEvent.Wait(); -} -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::RegisterFallbackIOThread(EStreamSourceMediaType mediaType, CStreamingIOThread* pIOThread) -{ - //check if media has not yet been registered - if (!pIOThread) - { - return;//no need for NULL register anymore - } - const TFallbackIOVecConstIt itEnd = m_FallbackIOThreads.end(); - for (TFallbackIOVecConstIt it = m_FallbackIOThreads.begin(); it != itEnd; ++it) - { - if (it->second == mediaType) - { - return; - } - } - m_FallbackIOThreads.push_back(std::make_pair(pIOThread, mediaType)); - m_nFallbackMTs |= 1 << mediaType; -} - -bool CStreamingIOThread::HasUrgentRequests() -{ - bool ret = false; - - if (m_iUrgentRequests > 0) - { - //lock to prevent list modification whilst traversing - m_newFileRequests.get_lock().Lock(); - - int nRequests = m_newFileRequests.size(); - - if (nRequests) - { - for (int i = 0; i < nRequests; i++) - { - if (m_newFileRequests[i]->m_ePriority == estpUrgent) - { - //printf("Urgent task pending: %s\n", m_newFileRequests[i]->m_strFileName.c_str()); - ret = true; - break; - } - } - } - m_newFileRequests.get_lock().Unlock(); - } - return ret; -} - -bool CStreamingIOThread::IsMisscheduled(EStreamSourceMediaType mt) const -{ - if (mt == m_eMediaType) - { - return false; - } - - if (m_nFallbackMTs & (1 << mt)) - { - return true; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -CStreamingWorkerThread::CStreamingWorkerThread(CStreamEngine* pStreamEngine, const char* name, EWorkerType type, SStreamRequestQueue* pQueue) -{ - m_type = type; - m_name = name; - m_pStreamEngine = pStreamEngine; - m_pQueue = pQueue; - m_bCancelThreadRequest = false; - m_bNeedsReset = false; - - Start((unsigned)1 << g_cvars.sys_streaming_cpu_worker, name); -} - -CStreamingWorkerThread::~CStreamingWorkerThread() -{ - Cancel(); - Stop(); - WaitForThread(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::Run() -{ - SetName(m_name); - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION STREAMIOTHREAD_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(StreamEngine/StreamIOThread_cpp) -#endif - - // Main thread loop - while (!m_bCancelThreadRequest) - { - m_pQueue->m_awakeEvent.Wait(); - m_pQueue->m_awakeEvent.Reset(); - - CAsyncIOFileRequest_AutoPtr pFileRequest; - while (!m_bCancelThreadRequest && !m_bNeedsReset && m_pQueue->TryPopRequest(pFileRequest)) - { - switch (m_type) - { - case eWorkerAsyncCallback: - { -#ifndef _RELEASE - float fTime = gEnv->pTimer->GetAsyncCurTime(); -#endif - - m_pStreamEngine->ReportAsyncFileRequestComplete(pFileRequest); -#ifndef _RELEASE - float fTime1 = gEnv->pTimer->GetAsyncCurTime(); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedDecrement(&m_pStreamEngine->GetStreamingStatistics().nCurrentAsyncCount); -#endif - -#ifndef _RELEASE - if ((fTime1 - fTime) > 1.f && !pFileRequest->m_strFileName.empty()) - { - string str; - str.Format("[ACALL] %s time=%.5f\n", pFileRequest->m_strFileName.c_str(), (fTime1 - fTime)); - if (gEnv && gEnv->pSystem && gEnv->pLog) - { - gEnv->pLog->Log(str.c_str()); - } - } -#endif - } - break; - } - } - - if (m_bNeedsReset) - { - m_pQueue->Reset(); - m_bNeedsReset = false; - m_resetDoneEvent.Set(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::Cancel() -{ - m_bCancelThreadRequest = true; - m_pQueue->m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::CancelAll() -{ - m_pQueue->Reset(); -} - -void CStreamingWorkerThread::BeginReset() -{ - CancelAll(); - - m_resetDoneEvent.Reset(); - m_bNeedsReset = true; - m_pQueue->m_awakeEvent.Set(); -} - -void CStreamingWorkerThread::EndReset() -{ - m_resetDoneEvent.Wait(); -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h b/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h deleted file mode 100644 index 14bac3a372..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Thread for IO - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H -#pragma once - -#include -#include "StreamAsyncFileRequest.h" - - -class CStreamEngine; - -////////////////////////////////////////////////////////////////////////// -// Thread that performs IO operations. -////////////////////////////////////////////////////////////////////////// -class CStreamingIOThread - : public CrySimpleThread - , public CMultiThreadRefCount -{ -public: - CStreamingIOThread(CStreamEngine* pStreamEngine, EStreamSourceMediaType mediaType, const char* name); - ~CStreamingIOThread(); - - void CancelAll(); - void AbortAll(bool bAbort); - - void BeginReset(); - void EndReset(); - - void AddRequest(CAsyncIOFileRequest* pRequest, bool bStartImmidietly); - int GetRequestCount() const { return m_fileRequestQueue.size(); }; - void SortRequests(); - void NeedSorting(); - void SignalStartWork(bool bForce); - bool HasUrgentRequests(); - EStreamSourceMediaType GetMediaType() const { return m_eMediaType; } - bool IsMisscheduled(EStreamSourceMediaType mt) const; - - void Pause(bool bPause); - - void RegisterFallbackIOThread(EStreamSourceMediaType mediaType, CStreamingIOThread* pIOThread); - - CStreamEngineWakeEvent& GetWakeEvent() { return m_awakeEvent; } - - ////////////////////////////////////////////////////////////////////////// - // CrySimpleThread - ////////////////////////////////////////////////////////////////////////// - virtual void Run(); - virtual void Cancel(); - ////////////////////////////////////////////////////////////////////////// - -protected: - - void ProcessNewRequests(); - void ProcessReset(); - -public: - -#ifdef STREAMENGINE_ENABLE_STATS - struct SStats - { - SStats() - : m_nTotalReadBytes(0) - , m_nCurrentReadBandwith(0) - , m_nReadBytesInLastSecond(0) - , m_fReadingDuringLastSecond(.0f) - , m_nTempBytesRead(0) - , m_nActualReadBandwith(0) - , m_nTempReadOffset(0) - , m_nTotalReadOffset(0) - , m_nReadOffsetInLastSecond(0) - , m_nTempRequestCount(0) - , m_nTotalRequestCount(0) - , m_nRequestCountInLastSecond(0) - {} - - void Update(const CTimeValue& deltaT); - - void Reset() - { - m_nTotalReadBytes = 0; - m_nTotalReadOffset = 0; - m_nTotalRequestCount = 0; - m_TotalReadTime.SetValue(0); - } - - float m_fReadingDuringLastSecond; - CTimeValue m_TotalReadTime; - uint64 m_nTotalReadBytes; - uint64 m_nTotalReadOffset; - uint32 m_nTotalRequestCount; - uint32 m_nCurrentReadBandwith; // Read bandwidth over one second - uint32 m_nActualReadBandwith; // Actual read bandwidth extrapolated over one second - uint32 m_nReadBytesInLastSecond; - uint32 m_nRequestCountInLastSecond; - uint64 m_nReadOffsetInLastSecond; - - uint32 m_nTempRequestCount; - uint64 m_nTempBytesRead; - uint64 m_nTempReadOffset; - CTimeValue m_TempReadTime; - }; - - SStats m_InMemoryStats; - SStats m_NotInMemoryStats; -#endif - - int64 m_nLastReadDiskOffset; - int m_nStreamingCPU; - -private: - CStreamEngine* m_pStreamEngine; - std::vector m_fileRequestQueue; - std::vector m_temporaryArray; - CryMT::vector m_newFileRequests; - - EStreamSourceMediaType m_eMediaType; - uint32 m_nFallbackMTs; - - typedef std::pair TFallbackIOPair; - typedef std::vector TFallbackIOVec; - typedef TFallbackIOVec::iterator TFallbackIOVecConstIt; - TFallbackIOVec m_FallbackIOThreads; - - volatile bool m_bCancelThreadRequest; - volatile bool m_bNeedSorting; - volatile bool m_bNewRequests; - volatile bool m_bPaused; - volatile bool m_bNeedReset; - volatile bool m_bAbortReads; - - volatile int m_iUrgentRequests; - - CStreamEngineWakeEvent m_awakeEvent; - CryEvent m_resetDoneEvent; - string m_name; - uint32 m_nReadCounter; -}; - -////////////////////////////////////////////////////////////////////////// -// Thread that performs IO operations. -////////////////////////////////////////////////////////////////////////// -class CStreamingWorkerThread - : public CrySimpleThread - , public CMultiThreadRefCount -{ -public: - enum EWorkerType - { - eWorkerAsyncCallback, - }; - CStreamingWorkerThread(CStreamEngine* pStreamEngine, const char* name, EWorkerType type, SStreamRequestQueue* pQueue); - ~CStreamingWorkerThread(); - - void BeginReset(); - void EndReset(); - - void CancelAll(); - - ////////////////////////////////////////////////////////////////////////// - // CrySimpleThread - ////////////////////////////////////////////////////////////////////////// - virtual void Run(); - virtual void Cancel(); - ////////////////////////////////////////////////////////////////////////// - -private: - EWorkerType m_type; - CStreamEngine* m_pStreamEngine; - SStreamRequestQueue* m_pQueue; - - volatile bool m_bCancelThreadRequest; - volatile bool m_bNeedsReset; - - CryEvent m_resetDoneEvent; - string m_name; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp deleted file mode 100644 index 729f268d78..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine - - -#include "CrySystem_precompiled.h" -#include -#include - -#include "StreamReadStream.h" -#include "StreamEngine.h" -#include "MTSafeAllocator.h" - -extern CMTSafeHeap* g_pPakHeap; -SLockFreeSingleLinkedListHeader CReadStream::s_freeRequests; - -CReadStream* CReadStream::Allocate(CStreamEngine* pEngine, const EStreamTaskType tSource, const char* szFilename, IStreamCallback* pCallback, const StreamReadParams* pParams) -{ - char* pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests)); - - CReadStream* pReq; - IF_LIKELY (pFree) - { - AZ_PUSH_DISABLE_WARNING(,"-Winvalid-offsetof") - ptrdiff_t offs = offsetof(CReadStream, m_nextFree); - AZ_POP_DISABLE_WARNING - pReq = reinterpret_cast(pFree - offs); - } - else - { - pReq = new CReadStream; - } - - pReq->m_pEngine = pEngine; - pReq->m_Type = tSource; - pReq->m_strFileName = szFilename; - pReq->m_pCallback = pCallback; - if (pParams) - { - pReq->m_Params = *pParams; - } - pReq->m_pBuffer = pReq->m_Params.pBuffer; - -#ifdef STREAMENGINE_ENABLE_STATS - pReq->m_requestTime = gEnv->pTimer->GetAsyncTime(); -#endif - - return pReq; -} - -void CReadStream::Flush() -{ - AZ_PUSH_DISABLE_WARNING(, "-Winvalid-offsetof") - ptrdiff_t offs = offsetof(CReadStream, m_nextFree); - AZ_POP_DISABLE_WARNING - - for (char* pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests)); - pFree; - pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests))) - { - CReadStream* pReq = reinterpret_cast(pFree - offs); - delete pReq; - } -} - -////////////////////////////////////////////////////////////////////////// -CReadStream::CReadStream() -{ - Reset(); -} - -////////////////////////////////////////////////////////////////////////// -CReadStream::~CReadStream() -{ -} - -// returns true if the file read was completed (successfully or unsuccessfully) -// check IsError to check if the whole requested file (piece) was read -bool CReadStream::IsFinished() -{ - return m_bFinished; -} - -// returns the number of bytes read so far (the whole buffer size if IsFinished()) -unsigned int CReadStream::GetBytesRead ([[maybe_unused]] bool bWait) -{ - if (!m_bError) - { - return m_Params.nSize; - } - return 0; -} - - -// returns the buffer into which the data has been or will be read -// at least GetBytesRead() bytes in this buffer are guaranteed to be already read -const void* CReadStream::GetBuffer () -{ - return m_pBuffer; -} - -void CReadStream::AbortShutdown() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - - m_bError = true; - m_nIOError = ERROR_ABORTED_ON_SHUTDOWN; - m_bFileRequestComplete = true; - - if (m_pFileRequest) - { - __debugbreak(); - } - } - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - { - CryAutoCriticalSection lock(m_callbackLock); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - } -} - -// tries to stop reading the stream; this is advisory and may have no effect -// all the callbacks will be called after this. If you just destructing object, -// dereference this object and it will automatically abort and release all associated resources. -void CReadStream::Abort() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - - m_bError = true; - m_nIOError = ERROR_USER_ABORT; - m_bFileRequestComplete = true; - - if (m_pFileRequest) - { - m_pFileRequest->Cancel(); - m_pFileRequest = 0; - } - } - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - { - CryAutoCriticalSection lock(m_callbackLock); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - } - - m_pEngine->AbortJob(this); -} - -bool CReadStream::TryAbort() -{ - if (!m_callbackLock.TryLock()) - { - return false; - } - - if (m_pFileRequest && !m_pFileRequest->TryCancel()) - { - m_callbackLock.Unlock(); - return false; - } - - m_bError = true; - m_nIOError = ERROR_USER_ABORT; - m_bFileRequestComplete = true; - m_pFileRequest = 0; - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - - m_callbackLock.Unlock(); - - m_pEngine->AbortJob(this); - - return true; -} - -// tries to raise the priority of the read; this is advisory and may have no effect -void CReadStream::SetPriority (EStreamTaskPriority ePriority) -{ - if (m_Params.ePriority != ePriority) - { - m_Params.ePriority = ePriority; - if (m_pFileRequest && m_pFileRequest->m_status == CAsyncIOFileRequest::eStatusInFileQueue) - { - m_pEngine->UpdateJobPriority(this); - } - } -} - -// unconditionally waits until the callback is called -// i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback -// is called before return from this function (unless no callback was specified) -void CReadStream::Wait(int nMaxWaitMillis) -{ - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - bool bNeedFinalize = (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) == 0; - - if (!m_bFinished && !m_bError && !m_pFileRequest) - { - assert(m_pFileRequest != NULL); // If we want to Wait for stream its file request must not be NULL. - // This will almost certainly cause Dead-Lock - CryFatalError("Waiting for stream when StreamingEngine is paused"); - } - - CTimeValue t0; - - if (nMaxWaitMillis > 0) - { - t0 = gEnv->pTimer->GetAsyncTime(); - } - - while (!m_bFinished && !m_bError) - { - if (bNeedFinalize) - { - m_pEngine->MainThread_FinalizeIOJobs(); - } - if (!m_bFileRequestComplete) - { - CrySleep(5); - } - - if (nMaxWaitMillis > 0) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - if (CTimeValue(t1 - t0).GetMilliSeconds() > nMaxWaitMillis) - { - // Break if we are waiting for too long. - break; - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -uint64 CReadStream::GetPriority() const -{ - return 0; -} - -// this gets called upon the IO has been executed to call the callbacks -void CReadStream::MainThread_Finalize() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - // call asynchronous callback function if needed synchronously - { - CryAutoCriticalSection lock(m_callbackLock); - ExecuteSyncCallback_CBLocked(); - } - m_pFileRequest = 0; -} - -IStreamCallback* CReadStream::GetCallback() const -{ - return m_pCallback; -} - -unsigned CReadStream::GetError() const -{ - return m_nIOError; -} - -const char* CReadStream::GetErrorName() const -{ - switch (m_nIOError) - { - case ERROR_UNKNOWN_ERROR: - return "Unknown error"; - case ERROR_UNEXPECTED_DESTRUCTION: - return "Unexpected destruction"; - case ERROR_INVALID_CALL: - return "Invalid call"; - case ERROR_CANT_OPEN_FILE: - return "Cannot open the file"; - case ERROR_REFSTREAM_ERROR: - return "Refstream error"; - case ERROR_OFFSET_OUT_OF_RANGE: - return "Offset out of range"; - case ERROR_REGION_OUT_OF_RANGE: - return "Region out of range"; - case ERROR_SIZE_OUT_OF_RANGE: - return "Size out of range"; - case ERROR_CANT_START_READING: - return "Cannot start reading"; - case ERROR_OUT_OF_MEMORY: - return "Out of memory"; - case ERROR_ABORTED_ON_SHUTDOWN: - return "Aborted on shutdown"; - case ERROR_OUT_OF_MEMORY_QUOTA: - return "Out of memory quota"; - case ERROR_ZIP_CACHE_FAILURE: - return "ZIP cache failure"; - case ERROR_USER_ABORT: - return "User aborted"; - } - return "Unrecognized error"; -} - -int CReadStream::AddRef() -{ - return CryInterlockedIncrement(&m_nRefCount); -} - -int CReadStream::Release() -{ - int nRef = CryInterlockedDecrement(&m_nRefCount); - -#ifndef _RELEASE - if (nRef < 0) - { - __debugbreak(); - } -#endif - - if (nRef == 0) - { - Reset(); - CryInterlockedPushEntrySList(s_freeRequests, m_nextFree); - } - - return nRef; -} - -void CReadStream::Reset() -{ - m_strFileName.clear(); - m_pFileRequest = NULL; - m_Params = StreamReadParams(); - memset((void*)&m_nRefCount, 0, (char*)(this + 1) - (char*)(&m_nRefCount)); -} - -void CReadStream::SetUserData(DWORD_PTR dwUserData) -{ - m_Params.dwUserData = dwUserData; -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::ExecuteAsyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_bIsAsyncCallbackExecuted && m_pCallback) - { - m_bIsAsyncCallbackExecuted = true; - m_pCallback->StreamAsyncOnComplete(this, m_nIOError); - } -} - -void CReadStream::ExecuteSyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_bIsSyncCallbackExecuted && m_pCallback && (0 == (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK))) - { - m_bIsSyncCallbackExecuted = true; - - CReadStream_AutoPtr protectMe(this); // Stream can be freed inside the callback! - - m_pCallback->StreamOnComplete(this, m_nIOError); - - // We do not need FileRequest here anymore, and not its temporary memory. - m_pFileRequest = 0; - m_pBuffer = NULL; - m_bFinished = true; - } - else - { - m_pFileRequest = 0; - m_pBuffer = NULL; - m_bFinished = true; - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = m_pEngine->GetListener(); - if (pListener) - { - pListener->OnStreamDone(this); - } -#endif -} - -void* CReadStream::operator new (size_t sz) -{ - return CryModuleMemalign(sz, alignof(CReadStream)); -} - -void CReadStream::operator delete(void* p) -{ - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::FreeTemporaryMemory() -{ - // Free temporary block. - if (m_pFileRequest) - { - m_pFileRequest->SyncWithDecompress(); - m_pFileRequest->FreeBuffer(); - } - m_pBuffer = 0; -} - -////////////////////////////////////////////////////////////////////////// -bool CReadStream::IsReqReading() -{ - if (m_strFileName.empty()) - { - return false; - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest* CReadStream::CreateFileRequest() -{ - m_pFileRequest = CAsyncIOFileRequest::Allocate(m_Type); - m_pFileRequest->m_nRequestedSize = m_Params.nSize; - m_pFileRequest->m_nRequestedOffset = m_Params.nOffset; - m_pFileRequest->m_pExternalMemoryBuffer = m_pBuffer; - m_pFileRequest->m_bWriteOnlyExternal = (m_Params.nFlags & IStreamEngine::FLAGS_WRITE_ONLY_EXTERNAL_BUFFER) != 0; - m_pFileRequest->m_pReadStream = this; - m_pFileRequest->m_strFileName = m_strFileName; - m_pFileRequest->m_ePriority = m_Params.ePriority; - m_pFileRequest->m_eMediaType = m_Params.eMediaType; - - m_bFileRequestComplete = false; - return m_pFileRequest; -} - -void* CReadStream::OnNeedStorage(size_t size, bool& bAbortOnFailToAlloc) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (m_pCallback) - { - return m_pCallback->StreamOnNeedStorage(this, size, bAbortOnFailToAlloc); - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::OnAsyncFileRequestComplete() -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (!m_bFileRequestComplete) - { - if (m_pFileRequest) - { - m_Params.nSize = m_pFileRequest->m_nRequestedSize; - m_pBuffer = m_pFileRequest->m_pOutputMemoryBuffer; - m_nBytesRead = m_pFileRequest->m_nSizeOnMedia; - m_nIOError = m_pFileRequest->m_nError; - m_bError = m_nIOError != 0; - if (m_bError) - { - m_nBytesRead = 0; - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_ReadTime = m_pFileRequest->m_readTime; -#endif - } - - ExecuteAsyncCallback_CBLocked(); - - if (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) - { - // We do not need FileRequest here anymore, and not its temporary memory. - m_pFileRequest = 0; - m_bFinished = true; - } - - m_bFileRequestComplete = true; - } -} - - diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h b/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h deleted file mode 100644 index cf6ee25d97..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h +++ /dev/null @@ -1,178 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H -#pragma once - - -#include "IStreamEngine.h" -#include "StreamAsyncFileRequest.h" - -class CStreamEngine; - -class CReadStream - : public IReadStream -{ - friend class CStreamEngine; - -public: - static CReadStream* Allocate(CStreamEngine* pEngine, const EStreamTaskType tSource, const char* szFilename, IStreamCallback* pCallback, const StreamReadParams* pParams); - static void Flush(); - -public: - CReadStream(); - virtual ~CReadStream (); - - virtual int AddRef(); - virtual int Release(); - - virtual DWORD_PTR GetUserData() {return m_Params.dwUserData; } - - // set user defined data into stream's params - virtual void SetUserData(DWORD_PTR dwUserData); - - // returns true if the file read was not successful. - virtual bool IsError() { return m_bError; }; - - // returns true if the file read was completed (successfully or unsuccessfully) - // check IsError to check if the whole requested file (piece) was read - virtual bool IsFinished(); - - // returns the number of bytes read so far (the whole buffer size if IsFinished()) - virtual unsigned int GetBytesRead (bool bWait); - - // returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read - virtual const void* GetBuffer (); - - void AbortShutdown(); - - // tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - virtual void Abort(); - virtual bool TryAbort(); - - // tries to raise the priority of the read; this is advisory and may have no effect - virtual void SetPriority (EStreamTaskPriority EPriority); - - // unconditionally waits until the callback is called - // i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified) - virtual void Wait(int nMaxWaitMillis = -1); - - virtual uint64 GetPriority() const; - - virtual const StreamReadParams& GetParams() const {return m_Params; } - - virtual const EStreamTaskType GetCallerType() const { return m_Type; } - - virtual EStreamSourceMediaType GetMediaType() const { return m_MediaType; } - - // return pointer to callback routine(can be NULL) - virtual IStreamCallback* GetCallback() const; - - // return IO error # - virtual unsigned GetError() const; - - // Returns IO error name - virtual const char* GetErrorName() const; - - // return stream name - virtual const char* GetName() const { return m_strFileName.c_str(); }; - - virtual void FreeTemporaryMemory(); - - // this gets called upon the IO has been executed to call the callbacks - void MainThread_Finalize(); - - bool IsReqReading(); - -#ifdef STREAMENGINE_ENABLE_STATS - void SetRequestTime(CTimeValue& time) { m_requestTime = time; } - const CTimeValue& GetRequestTime() { return m_requestTime; } -#endif - - // decompression of zip-compressed files with default behavior - CAsyncIOFileRequest* CreateFileRequest(); - void ComputedMediaType(EStreamSourceMediaType eMT) { m_MediaType = eMT; } - void* OnNeedStorage(size_t size, bool& bAbortOnFailToAlloc); - void OnAsyncFileRequestComplete(); - CAsyncIOFileRequest* GetFileRequest() { return m_pFileRequest; } - -private: - void Reset(); - - // call the async callback - void ExecuteAsyncCallback_CBLocked(); - - // call the sync callback - void ExecuteSyncCallback_CBLocked(); - -private: - void* operator new (size_t sz); - void operator delete(void* p); - -private: - static SLockFreeSingleLinkedListHeader s_freeRequests; - -private: - STREAMENGINE_LL_ALIGN SLockFreeSingleLinkedListEntry m_nextFree; - - CryStringLocal m_strFileName; - CryCriticalSection m_callbackLock; - CAsyncIOFileRequest_AutoPtr m_pFileRequest; - - StreamReadParams m_Params; - - // Only POD types must exist below here. They will be memset! - - volatile int m_nRefCount; - CStreamEngine* m_pEngine; - - // the type of the task - EStreamTaskType m_Type; - EStreamSourceMediaType m_MediaType; - // the initial data from the user - // the callback; may be NULL - IStreamCallback* m_pCallback; - - // Bytes actually read from media. - uint32 m_nBytesRead; - - volatile bool m_bIsAsyncCallbackExecuted; - volatile bool m_bIsSyncCallbackExecuted; - volatile bool m_bFileRequestComplete; - - // the actual buffer to read to - void* m_pBuffer; - - volatile bool m_bError; - volatile bool m_bFinished; - unsigned int m_nIOError; - -#ifdef STREAMENGINE_ENABLE_STATS - // time when request was made - CTimeValue m_requestTime; - // Time for actual reading - CTimeValue m_ReadTime; -#endif -}; - -TYPEDEF_AUTOPTR(CReadStream); - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H diff --git a/Code/CryEngine/CrySystem/System.cpp b/Code/CryEngine/CrySystem/System.cpp index 9016ea99f1..b105ec2f27 100644 --- a/Code/CryEngine/CrySystem/System.cpp +++ b/Code/CryEngine/CrySystem/System.cpp @@ -135,14 +135,12 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include "XML/xml.h" #include "XML/ReadWriteXMLSink.h" -#include "StreamEngine/StreamEngine.h" #include "PhysRenderer.h" #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" #include "SystemEventDispatcher.h" #include "ServerThrottle.h" -#include "ResourceManager.h" #include "HMDBus.h" #include "IZLibCompressor.h" @@ -157,7 +155,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include "CryWaterMark.h" WATERMARKDATA(_m); -#include "ImageHandler.h" #include #include #include @@ -179,7 +176,6 @@ WATERMARKDATA(_m); #include -#include #include // profilers api. @@ -191,14 +187,6 @@ SSystemCVars g_cvars; #include "ITextModeConsole.h" -extern int CryMemoryGetAllocatedSize(); - -// these heaps are used by underlying System structures -// to allocate, accordingly, small (like elements of std::set<..*>) and big (like memory for reading files) objects -// hopefully someday we'll have standard MT-safe heap -//CMTSafeHeap g_pakHeap; -CMTSafeHeap* g_pPakHeap = 0;// = &g_pakHeap; - ////////////////////////////////////////////////////////////////////////// #include "Validator.h" @@ -266,7 +254,6 @@ namespace // System Implementation. ////////////////////////////////////////////////////////////////////////// CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) - : m_imageHandler(std::make_unique()) { CrySystemRequestBus::Handler::BusConnect(); @@ -307,8 +294,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_env.pSharedEnvironment = pSharedEnvironment; ////////////////////////////////////////////////////////////////////////// - m_pStreamEngine = NULL; - m_pIFont = NULL; m_pIFontUi = NULL; m_rWidth = NULL; @@ -322,7 +307,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_rStencilBits = NULL; m_rFullscreen = NULL; m_sysNoUpdate = NULL; - m_pMemoryManager = NULL; m_pProcess = NULL; m_pValidator = NULL; @@ -387,12 +371,8 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_pXMLUtils = new CXmlUtils(this); - m_pMemoryManager = CryGetIMemoryManager(); - m_pResourceManager = new CResourceManager; m_pTextModeConsole = NULL; - g_pPakHeap = new CMTSafeHeap; - if (!AZ::AllocatorInstance::IsReady()) { m_initedOSAllocator = true; @@ -433,11 +413,8 @@ CSystem::~CSystem() CRY_ASSERT(m_windowMessageHandlers.empty() && "There exists a dangling window message handler somewhere"); SAFE_DELETE(m_pXMLUtils); - SAFE_DELETE(m_pResourceManager); SAFE_DELETE(m_pSystemEventDispatcher); - SAFE_DELETE(g_pPakHeap); - AZCoreLogSink::Disconnect(); if (m_initedSysAllocator) { @@ -477,12 +454,6 @@ void CSystem::FreeLib(AZStd::unique_ptr& hLibModule) } } -////////////////////////////////////////////////////////////////////////// -IStreamEngine* CSystem::GetStreamEngine() -{ - return m_pStreamEngine; -} - ////////////////////////////////////////////////////////////////////////// IRemoteConsole* CSystem::GetIRemoteConsole() { @@ -582,9 +553,6 @@ void CSystem::ShutDown() // Shutdown any running VR devices. EBUS_EVENT(AZ::VR::HMDInitRequestBus, Shutdown); - // Shutdown resource manager. - m_pResourceManager->Shutdown(); - if (gEnv && gEnv->pLyShine) { gEnv->pLyShine->Release(); @@ -645,11 +613,6 @@ void CSystem::ShutDown() SAFE_DELETE(m_pLocalizationManager); - //DebugStats(false, false);//true); - //CryLogAlways(""); - //CryLogAlways("release mode memory manager stats:"); - //DumpMMStats(true); - SAFE_DELETE(m_pCpu); delete m_pCmdLine; @@ -659,8 +622,7 @@ void CSystem::ShutDown() // Shut down audio as late as possible but before the streaming system and console get released! Audio::Gem::AudioSystemGemRequestBus::Broadcast(&Audio::Gem::AudioSystemGemRequestBus::Events::Release); - // Shut down the streaming system and console as late as possible and after audio! - SAFE_DELETE(m_pStreamEngine); + // Shut down console as late as possible and after audio! SAFE_RELEASE(m_env.pConsole); // Log must be last thing released. @@ -904,12 +866,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) } #endif //PROFILE_WITH_VTUNE - if (m_pStreamEngine) - { - FRAME_PROFILER("StreamEngine::Update()", this, PROFILE_SYSTEM); - m_pStreamEngine->Update(); - } - #ifndef EXCLUDE_UPDATE_ON_CONSOLE if (m_bIgnoreUpdates) { @@ -1024,14 +980,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) } } - ////////////////////////////////////////////////////////////////////////// - // Update Resource Manager. - ////////////////////////////////////////////////////////////////////////// - { - FRAME_PROFILER("SysUpdate:ResourceManager", this, PROFILE_SYSTEM); - m_pResourceManager->Update(); - } - // Use UI timer for CryMovie, because it should not be affected by pausing game time const float fMovieFrameTime = m_Time.GetFrameTime(ITimer::ETIMER_UI); @@ -1419,24 +1367,12 @@ void CSystem::Relaunch(bool bRelaunch) SaveConfiguration(); } -////////////////////////////////////////////////////////////////////////// -uint32 CSystem::GetUsedMemory() -{ - return CryMemoryGetAllocatedSize(); -} - ////////////////////////////////////////////////////////////////////////// ILocalizationManager* CSystem::GetLocalizationManager() { return m_pLocalizationManager; } -////////////////////////////////////////////////////////////////////////// -IResourceManager* CSystem::GetIResourceManager() -{ - return m_pResourceManager; -} - ////////////////////////////////////////////////////////////////////////// void CSystem::debug_GetCallStackRaw(void** callstack, uint32& callstackLength) { diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index e27dfe4866..2e272c2f9e 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -23,7 +23,6 @@ #include "CmdLine.h" #include "CryName.h" -#include "MTSafeAllocator.h" #include "CPUDetect.h" #include #include "RenderBus.h" @@ -276,33 +275,6 @@ extern SSystemCVars g_cvars; class CSystem; -struct SmallModuleInfo -{ - string name; - CryModuleMemoryInfo memInfo; -}; - -struct SCryEngineStatsModuleInfo -{ - string name; - CryModuleMemoryInfo memInfo; - uint32 moduleStaticSize; - uint32 usedInModule; - uint32 SizeOfCode; - uint32 SizeOfInitializedData; - uint32 SizeOfUninitializedData; -}; - -struct SCryEngineStatsGlobalMemInfo -{ - int totalUsedInModules; - int totalCodeAndStatic; - int countedMemoryModules; - uint64 totalAllocatedInModules; - int totalNumAllocsInModules; - std::vector modules; -}; - struct CProfilingSystem : public IProfilingSystem { @@ -338,17 +310,6 @@ class CSystem , public CrySystemRequestBus::Handler { public: - - inline void* operator new(std::size_t) - { - size_t allocated = 0; - return CryMalloc(sizeof(CSystem), allocated, 64); - } - inline void operator delete(void* p) - { - CryFree(p, 64); - } - CSystem(SharedEnvironmentInstance* pSharedEnvironment); ~CSystem(); @@ -390,8 +351,6 @@ public: ISystem* GetCrySystem() override; //////////////////////////////////////////////////////////////////////// - uint32 GetUsedMemory(); - virtual bool SteamInit(); void Relaunch(bool bRelaunch); @@ -412,17 +371,14 @@ public: IConsole* GetIConsole() { return m_env.pConsole; }; IRemoteConsole* GetIRemoteConsole(); IMovieSystem* GetIMovieSystem() { return m_env.pMovieSystem; }; - IMemoryManager* GetIMemoryManager(){ return m_pMemoryManager; } ICryFont* GetICryFont(){ return m_env.pCryFont; } ILog* GetILog(){ return m_env.pLog; } ICmdLine* GetICmdLine(){ return m_pCmdLine; } - IStreamEngine* GetStreamEngine(); IValidator* GetIValidator() { return m_pValidator; }; INameTable* GetINameTable() { return m_env.pNameTable; }; IViewSystem* GetIViewSystem(); ILevelSystem* GetILevelSystem(); ISystemEventDispatcher* GetISystemEventDispatcher() { return m_pSystemEventDispatcher; } - IResourceManager* GetIResourceManager(); ITextModeConsole* GetITextModeConsole(); IProfilingSystem* GetIProfilingSystem() { return &m_ProfilingSystem; } IZLibCompressor* GetIZLibCompressor() { return m_pIZLibCompressor; } @@ -509,11 +465,6 @@ public: virtual int ShowMessage(const char* text, const char* caption, unsigned int uType); bool CheckLogVerbosity(int verbosity); - virtual void DebugStats(bool checkpoint, bool leaks); - void DumpWinHeaps(); - - virtual int DumpMMStats(bool log); - //! Return pointer to user defined callback. ISystemUserCallback* GetUserCallback() const { return m_pUserCallback; }; @@ -541,8 +492,6 @@ public: void SetVersionInfo(const char* const szVersion); #endif - virtual const IImageHandler* GetImageHandler() const override { return m_imageHandler.get(); } - void ShutdownModuleLibraries(); #if defined(WIN32) @@ -570,7 +519,6 @@ private: bool InitConsole(); bool InitFileSystem(); bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams); - bool InitStreamEngine(); bool InitAudioSystem(const SSystemInitParams& initParams); bool InitShine(const SSystemInitParams& initParams); @@ -597,7 +545,6 @@ private: #endif // #ifndef _RELEASE bool ReLaunchMediaCenter(); - void LogSystemInfo(); void UpdateAudioSystems(); void AddCVarGroupDirectory(const string& sPath); @@ -690,14 +637,9 @@ private: // ------------------------------------------------------ std::map > m_moduleDLLHandles; - //! THe streaming engine - class CStreamEngine* m_pStreamEngine; - //! current active process IProcess* m_pProcess; - IMemoryManager* m_pMemoryManager; - CCamera m_PhysRendererCamera; ICVar* m_p_draw_helpers_str; int m_iJumpToPhysProfileEnt; @@ -914,7 +856,6 @@ public: protected: // ------------------------------------------------------------- CCmdLine* m_pCmdLine; - class CResourceManager* m_pResourceManager; ITextModeConsole* m_pTextModeConsole; string m_currentLanguageAudio; @@ -943,7 +884,6 @@ protected: // ------------------------------------------------------------- bool m_bIsSteamInitialized; - std::unique_ptr m_imageHandler; std::vector m_windowMessageHandlers; bool m_initedOSAllocator = false; bool m_initedSysAllocator = false; diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index 7d3a13d1a2..239f670453 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -95,7 +95,6 @@ #include "XConsole.h" #include "Log.h" #include "XML/xml.h" -#include "StreamEngine/StreamEngine.h" #include "PhysRenderer.h" #include "LocalizedStringManager.h" #include "SystemEventDispatcher.h" @@ -103,8 +102,6 @@ #include "ServerThrottle.h" #include "SystemCFG.h" #include "AutoDetectSpec.h" -#include "ResourceManager.h" -#include "MTSafeAllocator.h" #include "ZLibCompressor.h" #include "ZLibDecompressor.h" #include "ZStdDecompressor.h" @@ -245,8 +242,6 @@ CUNIXConsole* pUnixConsole; #define AZ_TRACE_SYSTEM_WINDOW AZ::Debug::Trace::GetDefaultSystemWindow() -extern CMTSafeHeap* g_pPakHeap; - #ifdef WIN32 extern HMODULE gDLLHandle; #endif @@ -274,7 +269,6 @@ struct SCVarsClientConfigSink ////////////////////////////////////////////////////////////////////////// static inline void InlineInitializationProcessing([[maybe_unused]] const char* sDescription) { - assert(CryMemory::IsHeapValid()); if (gEnv->pLog) { gEnv->pLog->UpdateLoadingScreen(0); @@ -1101,12 +1095,7 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&) auto projectName = AZ::Utils::GetProjectName(); AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Name: %s\n", projectName.empty() ? "None specified" : projectName.c_str()); - // simply open all paks if fast load pak can't be found - if (!m_pResourceManager->LoadFastLoadPaks(true)) - { - OpenBasicPaks(); - } - + OpenBasicPaks(); // Load game-specific folder. LoadConfiguration("game.cfg"); @@ -1120,21 +1109,6 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&) return (true); } -////////////////////////////////////////////////////////////////////////// -bool CSystem::InitStreamEngine() -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - if (m_pUserCallback) - { - m_pUserCallback->OnInitProgress("Initializing Stream Engine..."); - } - - m_pStreamEngine = new CStreamEngine(); - - return true; -} - ////////////////////////////////////////////////////////////////////////// bool CSystem::InitAudioSystem(const SSystemInitParams& initParams) { @@ -1299,8 +1273,6 @@ void CSystem::OpenBasicPaks() ////////////////////////////////////////////////////////////////////////// const char* const assetsDir = "@assets@"; - const char* shaderCachePakDir = "@assets@/shadercache.pak"; - const char* shaderCacheStartupPakDir = "@assets@/shadercachestartup.pak"; // After game paks to have same search order as with files on disk m_env.pCryPak->OpenPack(assetsDir, "Engine.pak"); @@ -1310,11 +1282,6 @@ void CSystem::OpenBasicPaks() #include AZ_RESTRICTED_FILE(SystemInit_cpp) #endif - m_env.pCryPak->OpenPack(assetsDir, shaderCachePakDir); - m_env.pCryPak->OpenPack(assetsDir, shaderCacheStartupPakDir); - m_env.pCryPak->OpenPack(assetsDir, "Shaders.pak"); - m_env.pCryPak->OpenPack(assetsDir, "ShadersBin.pak"); - #ifdef AZ_PLATFORM_ANDROID // Load Android Obb files if available const char* obbStorage = AZ::Android::Utils::GetObbStoragePath(); @@ -1326,22 +1293,6 @@ void CSystem::OpenBasicPaks() InlineInitializationProcessing("CSystem::OpenBasicPaks OpenPacks( Engine... )"); - ////////////////////////////////////////////////////////////////////////// - // Open paks in MOD subfolders. - ////////////////////////////////////////////////////////////////////////// -#if !defined(_RELEASE) - if (const ICmdLineArg* pModArg = GetICmdLine()->FindArg(eCLAT_Pre, "MOD")) - { - if (IsMODValid(pModArg->GetValue())) - { - AZStd::string modFolder = "Mods\\"; - modFolder += pModArg->GetValue(); - modFolder += "\\*.pak"; - GetIPak()->OpenPacks(assetsDir, modFolder, AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::INestedArchive::FLAGS_OVERRIDE_PAK); - } - } -#endif // !defined(_RELEASE) - // Load paks required for game init to mem gEnv->pCryPak->LoadPakToMemory("Engine.pak", AZ::IO::IArchive::eInMemoryPakLocale_GPU); } @@ -1687,8 +1638,6 @@ bool CSystem::Init(const SSystemInitParams& startupParams) m_systemConfigName += ".cfg"; } - AZ_Assert(CryMemory::IsHeapValid(), "Memory heap must be valid before continuing SystemInit."); - #if defined(WIN32) || defined(WIN64) // check OS version - we only want to run on XP or higher - talk to Martin Mittring if you want to change this { @@ -1709,8 +1658,6 @@ AZ_POP_DISABLE_WARNING } #endif - m_pResourceManager->Init(); - // Get file version information. QueryVersionInfo(); DetectGameFolderAccessRights(); @@ -1983,11 +1930,6 @@ AZ_POP_DISABLE_WARNING return false; } - if (!startupParams.bSkipConsole) - { - LogSystemInfo(); - } - InlineInitializationProcessing("CSystem::Init Load Engine Folders"); ////////////////////////////////////////////////////////////////////////// @@ -2052,29 +1994,6 @@ AZ_POP_DISABLE_WARNING gEnv->bNoAssertDialog = true; } - ////////////////////////////////////////////////////////////////////////// - // Stream Engine - ////////////////////////////////////////////////////////////////////////// - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Stream Engine Initialization"); - InitStreamEngine(); - InlineInitializationProcessing("CSystem::Init StreamEngine"); - - - { - if (m_pCmdLine->FindArg(eCLAT_Pre, "NullRenderer")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "NULL"); - } - else if (m_pCmdLine->FindArg(eCLAT_Pre, "DX11")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "DX11"); - } - else if (m_pCmdLine->FindArg(eCLAT_Pre, "GL")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "GL"); - } - } - LogBuildInfo(); InlineInitializationProcessing("CSystem::Init LoadConfigurations"); diff --git a/Code/CryEngine/CrySystem/SystemRender.cpp b/Code/CryEngine/CrySystem/SystemRender.cpp index b608ef5335..2314f593b7 100644 --- a/Code/CryEngine/CrySystem/SystemRender.cpp +++ b/Code/CryEngine/CrySystem/SystemRender.cpp @@ -47,13 +47,10 @@ #define SYSTEMRENDERER_CPP_SECTION_2 2 #endif -extern CMTSafeHeap* g_pPakHeap; #if defined(AZ_PLATFORM_ANDROID) #include #endif -extern int CryMemoryGetAllocatedSize(); - ///////////////////////////////////////////////////////////////////////////////// bool CSystem::GetPrimaryPhysicalDisplayDimensions([[maybe_unused]] int& o_widthPixels, [[maybe_unused]] int& o_heightPixels) { diff --git a/Code/CryEngine/CrySystem/SystemWin32.cpp b/Code/CryEngine/CrySystem/SystemWin32.cpp index 72c43bceed..c40b0f7c7b 100644 --- a/Code/CryEngine/CrySystem/SystemWin32.cpp +++ b/Code/CryEngine/CrySystem/SystemWin32.cpp @@ -51,7 +51,6 @@ #endif #include "XConsole.h" -#include "StreamEngine/StreamEngine.h" #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" #include "AutoDetectSpec.h" @@ -121,19 +120,6 @@ struct PEHeader_DLL #pragma pack(pop) #endif -const SmallModuleInfo* FindModuleInfo(std::vector& vec, const char* name) -{ - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].name.compareNoCase(name)) - { - return &vec[i]; - } - } - - return 0; -} - ////////////////////////////////////////////////////////////////////////// const char* CSystem::GetUserName() { @@ -231,30 +217,6 @@ int CSystem::GetApplicationLogInstance([[maybe_unused]] const char* logFilePath) #endif } -// these 2 functions are duplicated in System.cpp in editor -////////////////////////////////////////////////////////////////////////// -#if !defined(LINUX) -extern int CryStats(char* buf); -#endif -int CSystem::DumpMMStats(bool log) -{ -#if defined(LINUX) - return 0; -#else - if (log) - { - char buf[1024]; - int n = CryStats(buf); - GetILog()->Log(buf); - return n; - } - else - { - return CryStats(NULL); - }; -#endif -}; - ////////////////////////////////////////////////////////////////////////// struct CryDbgModule { @@ -264,273 +226,7 @@ struct CryDbgModule DWORD dwSize; }; -////////////////////////////////////////////////////////////////////////// -void CSystem::DebugStats([[maybe_unused]] bool checkpoint, [[maybe_unused]] bool leaks) -{ #ifdef WIN32 - std::vector dbgmodules; - - ////////////////////////////////////////////////////////////////////////// - // Use windows Performance Monitoring API to enumerate all modules of current process. - ////////////////////////////////////////////////////////////////////////// - HANDLE hSnapshot; - hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); - if (hSnapshot != INVALID_HANDLE_VALUE) - { - MODULEENTRY32 me; - memset (&me, 0, sizeof(me)); - me.dwSize = sizeof(me); - - if (Module32First (hSnapshot, &me)) - { - // the sizes of each module group - do - { - CryDbgModule module; - module.handle = me.hModule; - module.name = me.szModule; - module.dwSize = me.modBaseSize; - dbgmodules.push_back(module); - } while (Module32Next(hSnapshot, &me)); - } - CloseHandle (hSnapshot); - } - ////////////////////////////////////////////////////////////////////////// - - int nolib = 0; - -#ifdef _DEBUG - ILog* log = GetILog(); - int totalal = 0; - int totalbl = 0; - int extrastats[10]; -#endif - - int totalUsedInModules = 0; - int countedMemoryModules = 0; - for (int i = 0; i < (int)(dbgmodules.size()); i++) - { - if (!dbgmodules[i].handle) - { - CryLogAlways("WARNING: CSystem::DebugStats: NULL handle for %s", dbgmodules[i].name.c_str()); - nolib++; - continue; - } - ; - - typedef int (* PFN_MODULEMEMORY)(); - PFN_MODULEMEMORY fpCryModuleGetAllocatedMemory = (PFN_MODULEMEMORY)::GetProcAddress((HMODULE)dbgmodules[i].handle, "CryModuleGetAllocatedMemory"); - if (fpCryModuleGetAllocatedMemory) - { - int allocatedMemory = fpCryModuleGetAllocatedMemory(); - totalUsedInModules += allocatedMemory; - countedMemoryModules++; - CryLogAlways("%8d K used in Module %s: ", allocatedMemory / 1024, dbgmodules[i].name.c_str()); - } - -#ifdef _DEBUG - typedef void (* PFNUSAGESUMMARY)(ILog* log, const char*, int*); - typedef void (* PFNCHECKPOINT)(); - PFNUSAGESUMMARY fpu = (PFNUSAGESUMMARY)::GetProcAddress((HMODULE)dbgmodules[i].handle, "UsageSummary"); - PFNCHECKPOINT fpc = (PFNCHECKPOINT)::GetProcAddress((HMODULE)dbgmodules[i].handle, "CheckPoint"); - if (fpu && fpc) - { - if (checkpoint) - { - fpc(); - } - else - { - extrastats[2] = (int)leaks; - fpu(log, dbgmodules[i].name.c_str(), extrastats); - totalal += extrastats[0]; - totalbl += extrastats[1]; - }; - } - else - { - CryLogAlways("WARNING: CSystem::DebugStats: could not retrieve function from DLL %s", dbgmodules[i].name.c_str()); - nolib++; - }; -#endif - - typedef HANDLE(* PFNGETDLLHEAP)(); - PFNGETDLLHEAP fpg = (PFNGETDLLHEAP)::GetProcAddress((HMODULE)dbgmodules[i].handle, "GetDLLHeap"); - if (fpg) - { - dbgmodules[i].heap = fpg(); - } - ; - } - ; - - CryLogAlways("-------------------------------------------------------"); - CryLogAlways("%8d K Total Memory Allocated in %d Modules", totalUsedInModules / 1024, countedMemoryModules); -#ifdef _DEBUG - CryLogAlways("$8GRAND TOTAL: %d k, %d blocks (%d dlls not included)", totalal / 1024, totalbl, nolib); - CryLogAlways("estimated debugalloc overhead: between %d k and %d k", totalbl * 36 / 1024, totalbl * 72 / 1024); -#endif - - ////////////////////////////////////////////////////////////////////////// - // Get HeapQueryInformation pointer if on windows XP. - ////////////////////////////////////////////////////////////////////////// - typedef BOOL (WINAPI * FUNC_HeapQueryInformation)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T); - FUNC_HeapQueryInformation pFnHeapQueryInformation = NULL; - HMODULE hKernelInstance = CryLoadLibrary("Kernel32.dll"); - if (hKernelInstance) - { - pFnHeapQueryInformation = (FUNC_HeapQueryInformation)(::GetProcAddress(hKernelInstance, "HeapQueryInformation")); - } - ////////////////////////////////////////////////////////////////////////// - - const int MAXHANDLES = 100; - HANDLE handles[MAXHANDLES]; - int realnumh = GetProcessHeaps(MAXHANDLES, handles); - char hinfo[1024]; - PROCESS_HEAP_ENTRY phe; - CryLogAlways("$6--------------------- dump of windows heaps ---------------------"); - int nTotalC = 0, nTotalCP = 0, nTotalUC = 0, nTotalUCP = 0, totalo = 0; - for (int i = 0; i < realnumh; i++) - { - HANDLE hHeap = handles[i]; - HeapCompact(hHeap, 0); - hinfo[0] = 0; - if (pFnHeapQueryInformation) - { - pFnHeapQueryInformation(hHeap, HeapCompatibilityInformation, hinfo, 1024, NULL); - } - else - { - for (int m = 0; m < (int)(dbgmodules.size()); m++) - { - if (dbgmodules[m].heap == handles[i]) - { - azstrcpy(hinfo, AZ_ARRAY_SIZE(hinfo), dbgmodules[m].name.c_str()); - } - } - } - phe.lpData = NULL; - int nCommitted = 0, nUncommitted = 0, nOverhead = 0; - int nCommittedPieces = 0, nUncommittedPieces = 0; -#if !defined(NDEBUG) - int nPrevRegionIndex = -1; -#endif - while (HeapWalk(hHeap, &phe)) - { - if (phe.wFlags & PROCESS_HEAP_REGION) - { - assert (++nPrevRegionIndex == phe.iRegionIndex); - nCommitted += phe.Region.dwCommittedSize; - nUncommitted += phe.Region.dwUnCommittedSize; - assert (phe.cbData == 0 || (phe.wFlags & PROCESS_HEAP_ENTRY_BUSY)); - } - else - if (phe.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) - { - nUncommittedPieces += phe.cbData; - } - else - { - //if (phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) - nCommittedPieces += phe.cbData; - } - - - { - /* - MEMORY_BASIC_INFORMATION mbi; - if (VirtualQuery(phe.lpData, &mbi,sizeof(mbi)) == sizeof(mbi)) - { - if (mbi.State == MEM_COMMIT) - nCommittedPieces += phe.cbData;//mbi.RegionSize; - //else - // nUncommitted += mbi.RegionSize; - } - else - nCommittedPieces += phe.cbData; - */ - } - - nOverhead += phe.cbOverhead; - } - - CryLogAlways("* heap %8x: %6d (or ~%6d) K in use, %6d..%6d K uncommitted, %6d K overhead (%s)\n", - handles[i], nCommittedPieces / 1024, nCommitted / 1024, nUncommittedPieces / 1024, nUncommitted / 1024, nOverhead / 1024, hinfo); - - nTotalC += nCommitted; - nTotalCP += nCommittedPieces; - nTotalUC += nUncommitted; - nTotalUCP += nUncommittedPieces; - totalo += nOverhead; - } - ; - CryLogAlways("$6----------------- total in heaps: %d megs committed (win stats shows ~%d) (%d..%d uncommitted, %d k overhead) ---------------------", nTotalCP / 1024 / 1024, nTotalC / 1024 / 1024, nTotalUCP / 1024 / 1024, nTotalUC / 1024 / 1024, totalo / 1024); - -#endif //WIN32 -}; - -#ifdef WIN32 -struct DumpHeap32Stats -{ - DumpHeap32Stats() - : dwFree(0) - , dwMoveable(0) - , dwFixed(0) - , dwUnknown(0) - { - } - void operator += (const DumpHeap32Stats& right) - { - dwFree += right.dwFree; - dwMoveable += right.dwMoveable; - dwFixed += right.dwFixed; - dwUnknown += right.dwUnknown; - } - DWORD dwFree; - DWORD dwMoveable; - DWORD dwFixed; - DWORD dwUnknown; -}; -static void DumpHeap32 (const HEAPLIST32& hl, DumpHeap32Stats& stats) -{ - HEAPENTRY32 he; - memset (&he, 0, sizeof(he)); - he.dwSize = sizeof(he); - - if (Heap32First (&he, hl.th32ProcessID, hl.th32HeapID)) - { - DumpHeap32Stats heap; - do - { - if (he.dwFlags & LF32_FREE) - { - heap.dwFree += he.dwBlockSize; - } - else - if (he.dwFlags & LF32_MOVEABLE) - { - heap.dwMoveable += he.dwBlockSize; - } - else - if (he.dwFlags & LF32_FIXED) - { - heap.dwFixed += he.dwBlockSize; - } - else - { - heap.dwUnknown += he.dwBlockSize; - } - } while (Heap32Next (&he)); - - CryLogAlways ("%08X %6d %6d %6d (%d)", hl.th32HeapID, heap.dwFixed / 0x400, heap.dwFree / 0x400, heap.dwMoveable / 0x400, heap.dwUnknown / 0x400); - stats += heap; - } - else - { - CryLogAlways ("%08X empty or invalid"); - } -} - ////////////////////////////////////////////////////////////////////////// class CStringOrder { @@ -566,94 +262,6 @@ const char* GetModuleGroup (const char* szString) #endif -////////////////////////////////////////////////////////////////////////// -void CSystem::DumpWinHeaps() -{ -#ifdef WIN32 - // - // Retrieve modules and log them; remember the process id - - HANDLE hSnapshot; - hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) - { - CryLogAlways ("Cannot get the module snapshot, error code %d", GetLastError()); - return; - } - - DWORD dwProcessID = GetCurrentProcessId(); - - MODULEENTRY32 me; - memset (&me, 0, sizeof(me)); - me.dwSize = sizeof(me); - - if (Module32First (hSnapshot, &me)) - { - // the sizes of each module group - StringToSizeMap mapGroupSize; - DWORD dwTotalModuleSize = 0; - CryLogAlways ("base size module"); - do - { - dwProcessID = me.th32ProcessID; - const char* szGroup = GetModuleGroup (me.szModule); - CryLogAlways ("%08X %8X %25s - %s", me.modBaseAddr, me.modBaseSize, me.szModule, azstricmp(szGroup, "Other") ? szGroup : ""); - dwTotalModuleSize += me.modBaseSize; - AddSize (mapGroupSize, szGroup, me.modBaseSize); - } while (Module32Next(hSnapshot, &me)); - - CryLogAlways ("------------------------------------"); - for (StringToSizeMap::iterator it = mapGroupSize.begin(); it != mapGroupSize.end(); ++it) - { - CryLogAlways (" %6.3f Mbytes - %s", double(it->second) / 0x100000, it->first); - } - CryLogAlways ("------------------------------------"); - CryLogAlways (" %6.3f Mbytes - TOTAL", double(dwTotalModuleSize) / 0x100000); - CryLogAlways ("------------------------------------"); - } - else - { - CryLogAlways ("No modules to dump"); - } - - CloseHandle (hSnapshot); - - // - // Retrieve the heaps and dump each of them with a special function - - hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) - { - CryLogAlways ("Cannot get the heap LIST snapshot, error code %d", GetLastError()); - return; - } - - HEAPLIST32 hl; - memset (&hl, 0, sizeof(hl)); - hl.dwSize = sizeof(hl); - - CryLogAlways ("__Heap__ fixed free move (unknown)"); - if (Heap32ListFirst (hSnapshot, &hl)) - { - DumpHeap32Stats stats; - do - { - DumpHeap32 (hl, stats); - } while (Heap32ListNext (hSnapshot, &hl)); - - CryLogAlways ("-------------------------------------------------"); - CryLogAlways ("$6 %6.3f %6.3f %6.3f (%.3f) Mbytes", double(stats.dwFixed) / 0x100000, double(stats.dwFree) / 0x100000, double(stats.dwMoveable) / 0x100000, double(stats.dwUnknown) / 0x100000); - CryLogAlways ("-------------------------------------------------"); - } - else - { - CryLogAlways ("No heaps to dump"); - } - - CloseHandle(hSnapshot); -#endif -} - // Make system error message string ////////////////////////////////////////////////////////////////////////// //! \return pointer to the null terminated error string or 0 @@ -739,8 +347,6 @@ void CSystem::FatalError(const char* format, ...) assert(szBuffer[0] >= ' '); // strcpy(szBuffer,szBuffer+1); // remove verbosity tag since it is not supported by ::MessageBox - LogSystemInfo(); - OutputDebugString(szBuffer); #ifdef WIN32 OnFatalError(szBuffer); @@ -879,146 +485,6 @@ bool CSystem::ReLaunchMediaCenter() } #endif //defined(WIN32) -////////////////////////////////////////////////////////////////////////// -#if defined(WIN32) -void CSystem::LogSystemInfo() -{ - ////////////////////////////////////////////////////////////////////// - // Write the system informations to the log - ////////////////////////////////////////////////////////////////////// - - char szBuffer[1024]; - char szProfileBuffer[128]; - char szLanguageBuffer[64]; - //char szCPUModel[64]; - - MEMORYSTATUSEX MemoryStatus; - MemoryStatus.dwLength = sizeof(MemoryStatus); - - DEVMODE DisplayConfig; - OSVERSIONINFO OSVerInfo; - OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - // log system language - GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, szLanguageBuffer, sizeof(szLanguageBuffer)); - azsprintf(szBuffer, "System language: %s", szLanguageBuffer); - CryLogAlways(szBuffer); - - // log Windows directory - GetWindowsDirectory(szBuffer, sizeof(szBuffer)); - string str = "Windows Directory: \""; - str += szBuffer; - str += "\""; - CryLogAlways(str); - - ////////////////////////////////////////////////////////////////////// - // Send system time & date - ////////////////////////////////////////////////////////////////////// - - str = "Local time is "; - azstrtime(szBuffer); - str += szBuffer; - str += " "; - _strdate_s(szBuffer); - str += szBuffer; - azsprintf(szBuffer, ", system running for %lu minutes", GetTickCount() / 60000); - str += szBuffer; - CryLogAlways(str); - - ////////////////////////////////////////////////////////////////////// - // Send system memory status - ////////////////////////////////////////////////////////////////////// - - GlobalMemoryStatusEx(&MemoryStatus); - azsprintf(szBuffer, "%I64dMB physical memory installed, %I64dMB available, %I64dMB virtual memory installed, %ld percent of memory in use", - MemoryStatus.ullTotalPhys / 1048576 + 1, - MemoryStatus.ullAvailPhys / 1048576, - MemoryStatus.ullTotalVirtual / 1048576, - MemoryStatus.dwMemoryLoad); - CryLogAlways(szBuffer); - - if (GetISystem()->GetIMemoryManager()) - { - IMemoryManager::SProcessMemInfo memCounters; - GetISystem()->GetIMemoryManager()->GetProcessMemInfo(memCounters); - - uint64 PagefileUsage = memCounters.PagefileUsage; - uint64 PeakPagefileUsage = memCounters.PeakPagefileUsage; - uint64 WorkingSetSize = memCounters.WorkingSetSize; - azsprintf(szBuffer, "PageFile usage: %I64dMB, Working Set: %I64dMB, Peak PageFile usage: %I64dMB,", - (uint64)PagefileUsage / (1024 * 1024), - (uint64)WorkingSetSize / (1024 * 1024), - (uint64)PeakPagefileUsage / (1024 * 1024)); - CryLogAlways(szBuffer); - } - - ////////////////////////////////////////////////////////////////////// - // Send display settings - ////////////////////////////////////////////////////////////////////// - - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DisplayConfig); - GetPrivateProfileString("boot.description", "display.drv", - "(Unknown graphics card)", szProfileBuffer, sizeof(szProfileBuffer), - "system.ini"); - azsprintf(szBuffer, "Current display mode is %lux%lux%lu, %s", - DisplayConfig.dmPelsWidth, DisplayConfig.dmPelsHeight, - DisplayConfig.dmBitsPerPel, szProfileBuffer); - CryLogAlways(szBuffer); - - ////////////////////////////////////////////////////////////////////// - // Send input device configuration - ////////////////////////////////////////////////////////////////////// - - str = ""; - // Detect the keyboard type - switch (GetKeyboardType(0)) - { - case 1: - str = "IBM PC/XT (83-key)"; - break; - case 2: - str = "ICO (102-key)"; - break; - case 3: - str = "IBM PC/AT (84-key)"; - break; - case 4: - str = "IBM enhanced (101/102-key)"; - break; - case 5: - str = "Nokia 1050"; - break; - case 6: - str = "Nokia 9140"; - break; - case 7: - str = "Japanese"; - break; - default: - str = "Unknown"; - break; - } - - // Any mouse attached ? - if (!GetSystemMetrics(SM_MOUSEPRESENT)) - { - CryLogAlways(str + " keyboard and no mouse installed"); - } - else - { - azsprintf(szBuffer, " keyboard and %i+ button mouse installed", - GetSystemMetrics(SM_CMOUSEBUTTONS)); - CryLogAlways(str + szBuffer); - } - - CryLogAlways("--------------------------------------------------------------------------------"); -} -#else -void CSystem::LogSystemInfo() -{ -} -#endif - #if (defined(WIN32) || defined(WIN64)) ////////////////////////////////////////////////////////////////////////// bool CSystem::GetWinGameFolder(char* szMyDocumentsPath, int maxPathSize) diff --git a/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp b/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp index 637682065f..e384893e10 100644 --- a/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp +++ b/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp @@ -15,7 +15,6 @@ #include #include #include -#include namespace UnitTests { @@ -25,10 +24,6 @@ namespace UnitTests public: void SetUp() override { - IMemoryManager* cryMemoryManager = nullptr; - CryGetIMemoryManagerInterface((void**)&cryMemoryManager); - AZ_Assert(cryMemoryManager, "Unable to resolve CryMemoryManager"); - m_cryMemoryManager = AZ::Environment::CreateVariable("CryIMemoryManagerInterface", cryMemoryManager); SSystemInitParams startupParams; AZ::AllocatorInstance::Create(); AZ::AllocatorInstance::Create(); @@ -44,8 +39,6 @@ namespace UnitTests CSystem* m_system = nullptr; - AZ::EnvironmentVariable m_cryMemoryManager; - }; TEST_F(CSystemUnitTests, ApplicationLogInstanceUnitTests) diff --git a/Code/CryEngine/CrySystem/XML/XmlUtils.cpp b/Code/CryEngine/CrySystem/XML/XmlUtils.cpp index de5a14ecd7..d4feec04f2 100644 --- a/Code/CryEngine/CrySystem/XML/XmlUtils.cpp +++ b/Code/CryEngine/CrySystem/XML/XmlUtils.cpp @@ -272,7 +272,6 @@ void CXmlUtils::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wpar case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: case ESYSTEM_EVENT_LEVEL_LOAD_END: g_pCXmlNode_PoolAlloc->FreeMemoryIfEmpty(); - STLALLOCATOR_CLEANUP; break; } } diff --git a/Code/CryEngine/CrySystem/crysystem_files.cmake b/Code/CryEngine/CrySystem/crysystem_files.cmake index 50cbdc24e4..6eff1ee8e2 100644 --- a/Code/CryEngine/CrySystem/crysystem_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_files.cmake @@ -19,13 +19,10 @@ set(FILES ConsoleBatchFile.cpp ConsoleHelpGen.cpp CryAsyncMemcpy.cpp - GeneralMemoryHeap.cpp HandlerBase.cpp - AsyncPakManager.cpp Log.cpp SystemRender.cpp PhysRenderer.cpp - ResourceManager.cpp ServerHandler.cpp ServerThrottle.cpp SyncLock.cpp @@ -42,9 +39,7 @@ set(FILES AutoDetectSpec.h ClientHandler.h HandlerBase.h - AsyncPakManager.h PhysRenderer.h - ResourceManager.h ServerHandler.h ServerThrottle.h SyncLock.h @@ -58,7 +53,6 @@ set(FILES ConsoleBatchFile.h ConsoleHelpGen.h CryWaterMark.h - GeneralMemoryHeap.h Log.h resource.h SimpleStringPool.h @@ -71,18 +65,6 @@ set(FILES WindowsConsole.h XConsole.h XConsoleVariable.h - crash_face.bmp - ImageHandler.h - ImageHandler.cpp - MemoryAddressRange.cpp - PageMappingHeap.cpp - CustomMemoryHeap.cpp - MemoryManager.cpp - MTSafeAllocator.cpp - MemoryAddressRange.h - PageMappingHeap.h - MemoryManager.h - MTSafeAllocator.h XML/SerializeXMLReader.cpp XML/SerializeXMLWriter.cpp XML/xml.cpp @@ -126,18 +108,6 @@ set(FILES ViewSystem/ViewSystem.h ZStdDecompressor.h ZStdDecompressor.cpp - StreamEngine/StreamAsyncFileRequest.cpp - StreamEngine/StreamAsyncFileRequest_Jobs.cpp - StreamEngine/StreamEngine.cpp - StreamEngine/StreamIOThread.cpp - StreamEngine/StreamReadStream.cpp - StreamEngine/AZRequestReadStream.cpp - StreamEngine/StreamAsyncFileRequest.h - StreamEngine/StreamEngine.h - StreamEngine/StreamIOThread.h - StreamEngine/StreamReadStream.h - StreamEngine/AZRequestReadStream.h - CrashHandler.rc CrySystem_precompiled.cpp CPUDetect.cpp CPUDetect.h diff --git a/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h b/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h index 4e89e0a45c..f5f1428ed6 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h +++ b/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h @@ -24,7 +24,7 @@ namespace AZ::IO ePakPriorityPakOnly = 2 }; - // variables that control behavior of Archive/StreamEngine subsystems + // variables that control behavior of the Archive subsystem struct ArchiveVars { #if defined(_RELEASE) diff --git a/Code/Framework/AzTest/AzTest/AzTest.h b/Code/Framework/AzTest/AzTest/AzTest.h index a3d43bd521..c82598cb0c 100644 --- a/Code/Framework/AzTest/AzTest/AzTest.h +++ b/Code/Framework/AzTest/AzTest/AzTest.h @@ -17,7 +17,7 @@ #include AZ_PUSH_DISABLE_WARNING(4389 4800, "-Wunknown-warning-option"); // 'int' : forcing value to bool 'true' or 'false' (performance warning). -#undef strdup // platform.h in CryCommon changes this define which is required by googletest +#undef strdup // This define is required by googletest #include #include AZ_POP_DISABLE_WARNING; @@ -477,8 +477,7 @@ int main(int argc, char** argv) } \ } while (0); // safe multi-line macro - creates a single statement -// Avoid accidentally being managed by CryMemory, or problems with new/delete when -// AZ allocators are not ready or properly un/initialized. +// Avoid problems with new/delete when AZ allocators are not ready or properly un/initialized. #define AZ_TEST_CLASS_ALLOCATOR(Class_) \ void* operator new (size_t size) \ { \ diff --git a/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp b/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp index b7f04a7e10..8f8d310475 100644 --- a/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp +++ b/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp @@ -50,7 +50,6 @@ int APIENTRY WinMain([[maybe_unused]] HINSTANCE hInstance, [[maybe_unused]] HINS { // HACK HACK HACK - is this still needed?!?! // CrySystem module can get loaded multiple times (even from within CrySystem itself) - // and currently there is no way to track them (\ref _CryMemoryManagerPoolHelper::Init() in CryMemoryManager_impl.h) // so we will release it as many times as it takes until it actually unloads. void* hModule = CryLoadLibraryDefName("CrySystem"); if (hModule) diff --git a/Code/Sandbox/Editor/GotoPositionDlg.cpp b/Code/Sandbox/Editor/GotoPositionDlg.cpp index dc0f024bcb..a09f594b7b 100644 --- a/Code/Sandbox/Editor/GotoPositionDlg.cpp +++ b/Code/Sandbox/Editor/GotoPositionDlg.cpp @@ -106,8 +106,7 @@ void CGotoPositionDlg::OnChangeEdit() { const int lengthInSw = 8; const int strNum = 6; - TArray< float > pos(strNum); - pos.Set(0); + AZStd::vector pos(strNum); m_sPos = m_ui->m_posEdit->text(); const QStringList parts = m_sPos.split(QRegularExpression("[\\s,;\\t]"), Qt::SkipEmptyParts); diff --git a/Code/Sandbox/Editor/IEditorImpl.cpp b/Code/Sandbox/Editor/IEditorImpl.cpp index 380fc80e66..4b3c494413 100644 --- a/Code/Sandbox/Editor/IEditorImpl.cpp +++ b/Code/Sandbox/Editor/IEditorImpl.cpp @@ -92,7 +92,6 @@ AZ_POP_DISABLE_WARNING #ifdef _RELEASE #undef _RELEASE #endif -#include #include "Core/QtEditorApplication.h" // for Editor::EditorQtApplication diff --git a/Code/Sandbox/Editor/TrackView/TrackViewDopeSheetBase.cpp b/Code/Sandbox/Editor/TrackView/TrackViewDopeSheetBase.cpp index 407c124f5e..98123a016b 100644 --- a/Code/Sandbox/Editor/TrackView/TrackViewDopeSheetBase.cpp +++ b/Code/Sandbox/Editor/TrackView/TrackViewDopeSheetBase.cpp @@ -2734,9 +2734,6 @@ void CTrackViewDopeSheetBase::DrawKeys(CTrackViewTrack* pTrack, QPainter* painte const int kDefaultWidthForDescription = 200; const int kSmallMargin = 10; - FixedDynArray drawnKeyTimes; - drawnKeyTimes.set(ArrayT((float*)alloca(numKeys * sizeof(float)), numKeys)); - AZStd::vector sortedKeys; sortedKeys.reserve(numKeys); for (int i = 0; i < numKeys; ++i) @@ -2751,11 +2748,6 @@ void CTrackViewDopeSheetBase::DrawKeys(CTrackViewTrack* pTrack, QPainter* painte CTrackViewKeyHandle keyHandle = sortedKeys[i]; const float time = keyHandle.GetTime(); - if (!stl::push_back_unique(drawnKeyTimes, time)) - { - continue; - } - int x = TimeToClient(time); if (x - kSmallMargin > rect.right()) { diff --git a/Code/Sandbox/Editor/Util/ImageTIF.cpp b/Code/Sandbox/Editor/Util/ImageTIF.cpp index 0182d9654b..f69acc4161 100644 --- a/Code/Sandbox/Editor/Util/ImageTIF.cpp +++ b/Code/Sandbox/Editor/Util/ImageTIF.cpp @@ -440,7 +440,6 @@ bool CImageTIF::SaveRAW(const QString& fileName, const void* pData, int width, i { size_t offset = h * pitch; int err = TIFFWriteScanline(tif, raster + offset, h, 0); - assert(CryMemory::IsHeapValid()); if (err < 0) { bRet = false; diff --git a/Code/Sandbox/Editor/Util/IndexedFiles.h b/Code/Sandbox/Editor/Util/IndexedFiles.h index 641aff0333..0ae26b5adf 100644 --- a/Code/Sandbox/Editor/Util/IndexedFiles.h +++ b/Code/Sandbox/Editor/Util/IndexedFiles.h @@ -22,7 +22,6 @@ #include "FileUtil.h" -#include "STLPoolAllocator.h" #include class CIndexedFiles @@ -117,15 +116,8 @@ private: std::vector > m_updateCallbacks; IFileUtil::FileArray m_files; std::map m_pathToIndex; -#if defined(_DEBUG) || defined(AZ_COMPILER_CLANG) - // In debug, the validation phase of the pool allocator when destructed takes so much time, - // and using the STLPoolAllocator causes a strange issue when compiling with clang typedef std::set > int_set; typedef std::map > TagTable; -#else - typedef std::set, stl::STLPoolAllocator > int_set; - typedef std::map, stl::STLPoolAllocator > > TagTable; -#endif TagTable m_tags; QString m_rootPath; diff --git a/Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer.h b/Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer.h index 951877ab28..a35e39ff6b 100644 --- a/Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer.h +++ b/Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer.h @@ -12,6 +12,7 @@ #pragma once #include +#include namespace AssetMemoryAnalyzer { diff --git a/Code/CryEngine/CryCommon/AzDXGIFormat.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/AzDXGIFormat.h similarity index 97% rename from Code/CryEngine/CryCommon/AzDXGIFormat.h rename to Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/AzDXGIFormat.h index 6315dd3955..74a7f469fb 100644 --- a/Code/CryEngine/CryCommon/AzDXGIFormat.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/AzDXGIFormat.h @@ -17,11 +17,11 @@ #include -#if defined(AZ_PLATFORM_WINDOWS) && !defined(OPENGL) -#include +#if __has_include() +# include // For non-windows platforms need to define the formats so that the ImageExtension // class used by the editor can have access to these -#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(OPENGL) || defined(AZ_PLATFORM_LINUX) || defined(AZ_PLATFORM_ANDROID) +#else #define DXGI_FORMAT_DEFINED 1 diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/DDSHeader.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/DDSHeader.h index f280d4df48..25ee79c414 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/DDSHeader.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/DDSHeader.h @@ -15,9 +15,6 @@ #include #include -//! The following defines and constants are extracted from ImageExtensionHelper.h -//! Please make sure they are always synced with ImageExtensionHelper.h - #define IMAGE_BUIDER_MAKEFOURCC(ch0, ch1, ch2, ch3) \ ((AZ::u32)(AZ::u8)(ch0) | ((AZ::u32)(AZ::u8)(ch1) << 8) | \ ((AZ::u32)(AZ::u8)(ch2) << 16) | ((AZ::u32)(AZ::u8)(ch3) << 24)) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageFlags.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageFlags.h index f8942d0b61..6cf0a0e6dc 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageFlags.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageFlags.h @@ -12,9 +12,6 @@ #pragma once -//! The following constants are extracted from ImageExtensionHelper.h -//! Please make sure they are always synced with the same constants defined in ImageExtensionHelper.h - namespace ImageProcessingAtom { // flags to propagate from the RC to the engine through GetImageFlags() diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageObjectImpl.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageObjectImpl.h index 7dd81fb195..8a4f8df1b2 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageObjectImpl.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageObjectImpl.h @@ -164,7 +164,7 @@ namespace ImageProcessingAtom AZ::Color m_colMinARGB; // ARGB will be added the properties of the DDS file AZ::Color m_colMaxARGB; // ARGB will be added the properties of the DDS file float m_averageBrightness; // will be added to the properties of the DDS file - AZ::u32 m_imageFlags; // combined from CImageExtensionHelper::EIF_Cubemap,... + AZ::u32 m_imageFlags; // AZ::u32 m_numPersistentMips; // number of mipmaps won't be splitted public: diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/PixelFormatInfo.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/PixelFormatInfo.h index 7d8c6f9284..6b099468ea 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/PixelFormatInfo.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/PixelFormatInfo.h @@ -12,7 +12,7 @@ #pragma once -#include // DX10+ formats. DXGI_FORMAT +#include // DX10+ formats. DXGI_FORMAT #include diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/imageprocessing_files.cmake b/Gems/Atom/Asset/ImageProcessingAtom/Code/imageprocessing_files.cmake index dfcfdfc319..69c678877d 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/imageprocessing_files.cmake +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/imageprocessing_files.cmake @@ -41,6 +41,7 @@ set(FILES Source/BuilderSettings/PresetSettings.h Source/BuilderSettings/TextureSettings.cpp Source/BuilderSettings/TextureSettings.h + Source/Processing/AzDXGIFormat.h Source/Processing/DDSHeader.h Source/Processing/ImageAssetProducer.cpp Source/Processing/ImageAssetProducer.h diff --git a/Gems/AudioSystem/Code/Platform/Android/AudioSystem_Traits_Android.h b/Gems/AudioSystem/Code/Platform/Android/AudioSystem_Traits_Android.h index eaecb67e94..954ab9365f 100644 --- a/Gems/AudioSystem/Code/Platform/Android/AudioSystem_Traits_Android.h +++ b/Gems/AudioSystem/Code/Platform/Android/AudioSystem_Traits_Android.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 256 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "256" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 72 << 10 /* 72 MiB (re-evaluate this size!) */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "2048 (2 MiB)" diff --git a/Gems/AudioSystem/Code/Platform/Linux/AudioSystem_Traits_Linux.h b/Gems/AudioSystem/Code/Platform/Linux/AudioSystem_Traits_Linux.h index 951eec5d54..472afd51e5 100644 --- a/Gems/AudioSystem/Code/Platform/Linux/AudioSystem_Traits_Linux.h +++ b/Gems/AudioSystem/Code/Platform/Linux/AudioSystem_Traits_Linux.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 512 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "512" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 384 << 10 /* 384 MiB */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "393216 (384 MiB)" diff --git a/Gems/AudioSystem/Code/Platform/Mac/AudioSystem_Traits_Mac.h b/Gems/AudioSystem/Code/Platform/Mac/AudioSystem_Traits_Mac.h index 951eec5d54..472afd51e5 100644 --- a/Gems/AudioSystem/Code/Platform/Mac/AudioSystem_Traits_Mac.h +++ b/Gems/AudioSystem/Code/Platform/Mac/AudioSystem_Traits_Mac.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 512 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "512" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 384 << 10 /* 384 MiB */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "393216 (384 MiB)" diff --git a/Gems/AudioSystem/Code/Platform/Windows/AudioSystem_Traits_Windows.h b/Gems/AudioSystem/Code/Platform/Windows/AudioSystem_Traits_Windows.h index 11fb0ee66d..fa37cf1e89 100644 --- a/Gems/AudioSystem/Code/Platform/Windows/AudioSystem_Traits_Windows.h +++ b/Gems/AudioSystem/Code/Platform/Windows/AudioSystem_Traits_Windows.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 1024 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "1024" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 384 << 10 /* 384 MiB */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "393216 (384 MiB)" diff --git a/Gems/AudioSystem/Code/Platform/iOS/AudioSystem_Traits_iOS.h b/Gems/AudioSystem/Code/Platform/iOS/AudioSystem_Traits_iOS.h index 3ffcf4a345..7a008237e2 100644 --- a/Gems/AudioSystem/Code/Platform/iOS/AudioSystem_Traits_iOS.h +++ b/Gems/AudioSystem/Code/Platform/iOS/AudioSystem_Traits_iOS.h @@ -18,6 +18,5 @@ #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE 128 #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_OBJECT_POOL_SIZE_DEFAULT_TEXT "128" #define AZ_TRAIT_AUDIOSYSTEM_AUDIO_THREAD_AFFINITY AFFINITY_MASK_ALL -#define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY IMemoryManager::eapCustomAlignment #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE 2 << 10 /* 2 MiB (re-evaluate this size!) */ #define AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_SIZE_DEFAULT_TEXT "2048 (2 MiB)" diff --git a/Gems/AudioSystem/Code/Source/Engine/ATLEntities.h b/Gems/AudioSystem/Code/Source/Engine/ATLEntities.h index fa72a78db9..c6624a125b 100644 --- a/Gems/AudioSystem/Code/Source/Engine/ATLEntities.h +++ b/Gems/AudioSystem/Code/Source/Engine/ATLEntities.h @@ -29,9 +29,6 @@ #include #include -#include - - namespace Audio { @@ -393,7 +390,7 @@ namespace Audio , m_memoryBlockAlignment(AUDIO_MEMORY_ALIGNMENT) , m_flags(eAFF_NOTFOUND) , m_dataScope(eADS_ALL) - , m_memoryBlock(nullptr) + // , m_memoryBlock(nullptr) // ToDo: Update to use non-legacy memory: LYN-3792 , m_implData(implData) { } @@ -406,7 +403,7 @@ namespace Audio size_t m_memoryBlockAlignment; Flags m_flags; EATLDataScope m_dataScope; - AZStd::unique_ptr m_memoryBlock; + // AZStd::unique_ptr m_memoryBlock; // ToDo: Update to use non-legacy memory: LYN-3792 AZ::IO::FileRequestPtr m_asyncStreamRequest; diff --git a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp index 7be14244d0..0e84679261 100644 --- a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp +++ b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp @@ -25,7 +25,6 @@ #include #include -#include #include namespace Audio @@ -76,12 +75,13 @@ namespace Audio { if (size > 0) { - m_memoryHeap.reset(static_cast(gEnv->pSystem->GetIMemoryManager()->CreateCustomMemoryHeapInstance(AZ_TRAIT_AUDIOSYSTEM_FILE_CACHE_MANAGER_ALLOCATION_POLICY))); + // ToDo: Update to use non-legacy memory: LYN-3792 + /*m_memoryHeap.reset(???); if (m_memoryHeap.get()) { m_maxByteTotal = size << 10; - } + }*/ } } @@ -541,7 +541,7 @@ namespace Audio CATLAudioFileEntry* audioFileEntry = fileEntryIter->second; AZ_Assert(audioFileEntry, "FileCacheManager - Audio file entry is null!"); - AZ_Assert(buffer == audioFileEntry->m_memoryBlock->GetData(), "FileCacheManager - The memory buffer doesn't match the file entry memory block!"); + // AZ_Assert(buffer == audioFileEntry->m_memoryBlock->GetData(), "FileCacheManager - The memory buffer doesn't match the file entry memory block!"); // ToDo: Update to use non-legacy memory: LYN-3792 FinishCachingFileInternal(audioFileEntry, numBytesRead, streamer->GetRequestStatus(request)); } } @@ -574,7 +574,7 @@ namespace Audio SATLAudioFileEntryInfo fileEntryInfo; fileEntryInfo.nMemoryBlockAlignment = audioFileEntry->m_memoryBlockAlignment; - fileEntryInfo.pFileData = audioFileEntry->m_memoryBlock->GetData(); + // fileEntryInfo.pFileData = audioFileEntry->m_memoryBlock->GetData(); // ToDo: Update to use non-legacy memory: LYN-3792 fileEntryInfo.nSize = audioFileEntry->m_fileSize; fileEntryInfo.pImplData = audioFileEntry->m_implData; fileEntryInfo.sFileName = PathUtil::GetFile(audioFileEntry->m_filePath.c_str()); @@ -649,9 +649,12 @@ namespace Audio } /////////////////////////////////////////////////////////////////////////////////////////////// - bool CFileCacheManager::AllocateMemoryBlockInternal(CATLAudioFileEntry* const audioFileEntry) + bool CFileCacheManager::AllocateMemoryBlockInternal([[maybe_unused]]CATLAudioFileEntry* const audioFileEntry) { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Audio); + // ToDo: Update to use non-legacy memory: LYN-3792 + return false; + + /*AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Audio); // Must not have valid memory yet. AZ_Assert(!audioFileEntry->m_memoryBlock, "FileCacheManager AllocateMemoryBlockInternal - Memory appears to be set already!"); @@ -673,7 +676,7 @@ namespace Audio } } - return (audioFileEntry->m_memoryBlock != nullptr); + return (audioFileEntry->m_memoryBlock != nullptr);*/ } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -700,7 +703,8 @@ namespace Audio audioFileEntry->m_asyncStreamRequest.reset(); } - if (audioFileEntry->m_memoryBlock && audioFileEntry->m_memoryBlock->GetData()) + // ToDo: Update to use non-legacy memory heap: LYN-3792 + /*if (audioFileEntry->m_memoryBlock && audioFileEntry->m_memoryBlock->GetData()) { SATLAudioFileEntryInfo fileEntryInfo; fileEntryInfo.nMemoryBlockAlignment = audioFileEntry->m_memoryBlockAlignment; @@ -713,7 +717,7 @@ namespace Audio g_audioLogger.Log(eALT_COMMENT, "FileCacheManager - File Uncached: '%s'\n", fileEntryInfo.sFileName); } - audioFileEntry->m_memoryBlock.reset(); + audioFileEntry->m_memoryBlock.reset();*/ audioFileEntry->m_flags.ClearFlags(eAFF_CACHED | eAFF_REMOVABLE); AZ_Warning("FileCacheManager", audioFileEntry->m_useCount == 0, "Use-count of file '%s' is non-zero while uncaching it! Use Count: %d", audioFileEntry->m_filePath.c_str(), audioFileEntry->m_useCount); audioFileEntry->m_useCount = 0; @@ -765,7 +769,7 @@ namespace Audio bool CFileCacheManager::TryCacheFileCacheEntryInternal( CATLAudioFileEntry* const audioFileEntry, [[maybe_unused]] const TAudioFileEntryID fileEntryId, - const bool loadSynchronously, + [[maybe_unused]] const bool loadSynchronously, const bool overrideUseCount /* = false */, const size_t useCount /* = 0 */) { @@ -775,7 +779,8 @@ namespace Audio if (!audioFileEntry->m_filePath.empty() && !audioFileEntry->m_flags.AreAnyFlagsActive(eAFF_CACHED | eAFF_LOADING)) { - if (DoesRequestFitInternal(audioFileEntry->m_fileSize) && AllocateMemoryBlockInternal(audioFileEntry)) + // ToDo: Update to use non-legacy memory heap: LYN-3792 + /*if (DoesRequestFitInternal(audioFileEntry->m_fileSize) && AllocateMemoryBlockInternal(audioFileEntry)) { auto streamer = AZ::Interface::Get(); AZ_Assert(streamer, "FileCacheManager - Streamer should be ready!"); @@ -849,7 +854,7 @@ namespace Audio // The user should be made aware of it. g_audioLogger.Log(eALT_ERROR, "FileCacheManager: Could not cache '%s' - out of memory or fragmented memory!", audioFileEntry->m_filePath.c_str()); - } + }*/ } else if (audioFileEntry->m_flags.AreAnyFlagsActive(eAFF_CACHED | eAFF_LOADING)) { diff --git a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.h b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.h index 0e780bd467..b06a810e49 100644 --- a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.h +++ b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.h @@ -23,7 +23,6 @@ #include // Forward declarations -class CCustomMemoryHeap; struct IRenderAuxGeom; namespace Audio @@ -103,7 +102,7 @@ namespace Audio TATLPreloadRequestLookup& m_preloadRequests; TAudioFileEntries m_audioFileEntries; - AZStd::unique_ptr m_memoryHeap; + // AZStd::unique_ptr m_memoryHeap; // ToDo: Update to use non-legacy memory: LYN-3792 size_t m_currentByteTotal; size_t m_maxByteTotal; }; diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp index bb15996223..57c52671df 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewDopeSheetBase.cpp @@ -2308,20 +2308,12 @@ void CUiAnimViewDopeSheetBase::DrawKeys(CUiAnimViewTrack* pTrack, QPainter* pain const int kDefaultWidthForDescription = 200; const int kSmallMargin = 10; - FixedDynArray drawnKeyTimes; - drawnKeyTimes.set(ArrayT((float*)alloca(numKeys * sizeof(float)), numKeys)); - // Draw keys. for (int i = 0; i < numKeys; ++i) { CUiAnimViewKeyHandle keyHandle = pTrack->GetKey(i); const float time = keyHandle.GetTime(); - if (!stl::push_back_unique(drawnKeyTimes, time)) - { - continue; - } - int x = TimeToClient(time); if (x - kSmallMargin > rect.right()) { diff --git a/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp b/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp index 24b8841059..29e63f62c3 100644 --- a/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp +++ b/Gems/LyShine/Code/Editor/Animation/Util/UiEditorUtils.cpp @@ -21,34 +21,6 @@ ////////////////////////////////////////////////////////////////////////// void HeapCheck::Check([[maybe_unused]] const char* file, [[maybe_unused]] int line) { -#ifdef _DEBUG - AZ_Assert(CryMemory::IsHeapValid(), "Invalid heap"); -#endif - - /* - int heapstatus = _heapchk(); - switch( heapstatus ) - { - case _HEAPOK: - break; - case _HEAPEMPTY: - break; - case _HEAPBADBEGIN: - { - CString str; - str.Format( "Bad Start of Heap, at file %s line:%d",file,line ); - MessageBox( NULL,str,"Heap Check",MB_OK ); - } - break; - case _HEAPBADNODE: - { - CString str; - str.Format( "Bad Node in Heap, at file %s line:%d",file,line ); - MessageBox( NULL,str,"Heap Check",MB_OK ); - } - break; - } - */ } #include diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp index 8e8079e18e..f55c8c5957 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp @@ -56,26 +56,6 @@ #include "UiDynamicScrollBoxComponent.h" #include "UiNavigationSettings.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -struct CSystemEventListener_UI - : public ISystemEventListener -{ -public: - virtual void OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - STLALLOCATOR_CLEANUP; - break; - } - } - } -}; -static CSystemEventListener_UI g_system_event_listener_ui; - - namespace LyShine { const AZStd::list* LyShineSystemComponent::m_componentDescriptors = nullptr; @@ -228,9 +208,6 @@ namespace LyShine //////////////////////////////////////////////////////////////////////////////////////////////////// void LyShineSystemComponent::InitializeSystem() { - // Not sure if this is still required - gEnv->pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_ui); - m_pLyShine = new CLyShine(gEnv->pSystem); gEnv->pLyShine = m_pLyShine; BroadcastCursorImagePathname(); diff --git a/Gems/Maestro/Code/Source/MaestroSystemComponent.cpp b/Gems/Maestro/Code/Source/MaestroSystemComponent.cpp index cd0dfb02b3..1ee2ddc1c8 100644 --- a/Gems/Maestro/Code/Source/MaestroSystemComponent.cpp +++ b/Gems/Maestro/Code/Source/MaestroSystemComponent.cpp @@ -105,34 +105,11 @@ namespace Maestro MaestroAllocatorScope::DeactivateAllocators(); } - ////////////////////////////////////////////////////////////////////////// - void CSystemEventListener_Movie::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - STLALLOCATOR_CLEANUP; - CLightAnimWrapper::ReconstructCache(); - break; - } - } - } - /////////////////////////////////////////////////////////////////////////////////////////////// void MaestroSystemComponent::OnCrySystemInitialized(ISystem& system, const SSystemInitParams& startupParams) { if (!startupParams.bSkipMovie) { - // OnCrySystemInitialized should only ever be called once, and we should be the only one initializing gEnv->pMovieSystem - AZ_Assert(!m_movieSystemEventListener && gEnv && !gEnv->pMovieSystem, "MaestroSystemComponent::OnCrySystemInitialized - movie system was alread initialized."); - - if (!m_movieSystemEventListener) - { - m_movieSystemEventListener.reset(new CSystemEventListener_Movie); - } - system.GetISystemEventDispatcher()->RegisterListener(m_movieSystemEventListener.get()); - // Create the movie System m_movieSystem.reset(new CMovieSystem(&system)); gEnv->pMovieSystem = m_movieSystem.get(); @@ -142,17 +119,6 @@ namespace Maestro /////////////////////////////////////////////////////////////////////////////////////////////// void MaestroSystemComponent::OnCrySystemShutdown([[maybe_unused]] ISystem& system) { - // Remove the system movie listener and clean up allocations - if (m_movieSystemEventListener) - { - if (gEnv && gEnv->pSystem && gEnv->pSystem->GetISystemEventDispatcher()) - { - gEnv->pSystem->GetISystemEventDispatcher()->RemoveListener(m_movieSystemEventListener.get()); - } - // delete m_movieSystemEventListener - m_movieSystemEventListener.reset(); - } - if (gEnv && gEnv->pMovieSystem) { gEnv->pMovieSystem = nullptr; diff --git a/Gems/Maestro/Code/Source/MaestroSystemComponent.h b/Gems/Maestro/Code/Source/MaestroSystemComponent.h index ca8ae35d06..39a087eaa7 100644 --- a/Gems/Maestro/Code/Source/MaestroSystemComponent.h +++ b/Gems/Maestro/Code/Source/MaestroSystemComponent.h @@ -42,13 +42,6 @@ namespace Maestro void Deactivate() override; }; - ////////////////////////////////////////////////////////////////////////// - struct CSystemEventListener_Movie - : public ISystemEventListener - { - void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam) override; - }; - ////////////////////////////////////////////////////////////////////////// class MaestroSystemComponent : public AZ::Component @@ -91,6 +84,5 @@ namespace Maestro private: // singletons representing the movie system AZStd::unique_ptr m_movieSystem; - AZStd::unique_ptr m_movieSystemEventListener; }; } From 5cc0cc9ee76a05c6077b3e85bd38e203ff181688 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 14 May 2021 11:03:31 -0500 Subject: [PATCH 205/225] Fixed the loading of uicanvas assets due to the NetBindable class being (#755) removed from the SerializeContext. The TransformComponent and ScriptComponent which used to Serialize a NetBindable instance didn't have their version numbers bumped in order to skip the old data when loading a binary ObjectStream --- .../Components/TransformComponent.cpp | 2 +- .../AzFramework/Script/ScriptComponent.cpp | 2 +- .../Code/Source/UiInteractableComponent.cpp | 1 + .../Code/Source/UiInteractableState.cpp | 26 +++++++++++++------ .../LyShine/Code/Source/UiInteractableState.h | 2 ++ .../Comp/Text/ImageMarkup.uicanvas | 2 +- 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp index 3c05887a89..9083cb7d0d 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp @@ -881,7 +881,7 @@ namespace AzFramework serializeContext->ClassDeprecate("NetBindable", "{80206665-D429-4703-B42E-94434F82F381}"); serializeContext->Class() - ->Version(4, &TransformComponentVersionConverter) + ->Version(5, &TransformComponentVersionConverter) ->Field("Parent", &TransformComponent::m_parentId) ->Field("Transform", &TransformComponent::m_worldTM) ->Field("LocalTransform", &TransformComponent::m_localTM) diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp index 30343b1322..cdfad7f116 100644 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp @@ -979,7 +979,7 @@ namespace AzFramework }; serializeContext->Class() - ->Version(3, converter) + ->Version(4, converter) ->Field("ContextID", &ScriptComponent::m_contextId) ->Field("Properties", &ScriptComponent::m_properties) ->Field("Script", &ScriptComponent::m_script) diff --git a/Gems/LyShine/Code/Source/UiInteractableComponent.cpp b/Gems/LyShine/Code/Source/UiInteractableComponent.cpp index b665bbe1dc..e4ba507340 100644 --- a/Gems/LyShine/Code/Source/UiInteractableComponent.cpp +++ b/Gems/LyShine/Code/Source/UiInteractableComponent.cpp @@ -546,6 +546,7 @@ void UiInteractableComponent::Reflect(AZ::ReflectContext* context) ->Handler(); } + UiInteractableStateAction::Reflect(context); UiInteractableStateColor::Reflect(context); UiInteractableStateAlpha::Reflect(context); UiInteractableStateSprite::Reflect(context); diff --git a/Gems/LyShine/Code/Source/UiInteractableState.cpp b/Gems/LyShine/Code/Source/UiInteractableState.cpp index f5d703d87a..965899a958 100644 --- a/Gems/LyShine/Code/Source/UiInteractableState.cpp +++ b/Gems/LyShine/Code/Source/UiInteractableState.cpp @@ -41,6 +41,16 @@ void UiInteractableStateAction::SetInteractableEntity(AZ::EntityId interactableE m_interactableEntity = interactableEntityId; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +void UiInteractableStateAction::Reflect(AZ::ReflectContext* context) +{ + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class(); + } +} + + //////////////////////////////////////////////////////////////////////////////////////////////////// void UiInteractableStateAction::Init(AZ::EntityId interactableEntityId) { @@ -128,8 +138,8 @@ void UiInteractableStateColor::Reflect(AZ::ReflectContext* context) if (serializeContext) { - serializeContext->Class() - ->Version(2, &VersionConverter) + serializeContext->Class() + ->Version(3, &VersionConverter) ->Field("TargetEntity", &UiInteractableStateColor::m_targetEntity) ->Field("Color", &UiInteractableStateColor::m_color); @@ -223,8 +233,8 @@ void UiInteractableStateAlpha::Reflect(AZ::ReflectContext* context) if (serializeContext) { - serializeContext->Class() - ->Version(1) + serializeContext->Class() + ->Version(2) ->Field("TargetEntity", &UiInteractableStateAlpha::m_targetEntity) ->Field("Alpha", &UiInteractableStateAlpha::m_alpha); @@ -379,8 +389,8 @@ void UiInteractableStateSprite::Reflect(AZ::ReflectContext* context) if (serializeContext) { - serializeContext->Class() - ->Version(3) + serializeContext->Class() + ->Version(4) ->Field("TargetEntity", &UiInteractableStateSprite::m_targetEntity) ->Field("Sprite", &UiInteractableStateSprite::m_spritePathname) ->Field("Index", &UiInteractableStateSprite::m_spriteSheetCellIndex); @@ -633,8 +643,8 @@ void UiInteractableStateFont::Reflect(AZ::ReflectContext* context) if (serializeContext) { - serializeContext->Class() - ->Version(1) + serializeContext->Class() + ->Version(2) ->Field("TargetEntity", &UiInteractableStateFont::m_targetEntity) ->Field("FontFileName", &UiInteractableStateFont::m_fontFilename) ->Field("EffectIndex", &UiInteractableStateFont::m_fontEffectIndex); diff --git a/Gems/LyShine/Code/Source/UiInteractableState.h b/Gems/LyShine/Code/Source/UiInteractableState.h index 966c24f202..81e9ac48e1 100644 --- a/Gems/LyShine/Code/Source/UiInteractableState.h +++ b/Gems/LyShine/Code/Source/UiInteractableState.h @@ -42,6 +42,8 @@ public: // member functions virtual ~UiInteractableStateAction() {} + static void Reflect(AZ::ReflectContext* context); + //! Called from the Init of the UiInteractableComponent virtual void Init(AZ::EntityId); diff --git a/Gems/LyShineExamples/Assets/UI/Canvases/LyShineExamples/Comp/Text/ImageMarkup.uicanvas b/Gems/LyShineExamples/Assets/UI/Canvases/LyShineExamples/Comp/Text/ImageMarkup.uicanvas index 2e3ab0121f..3bcd4f3db3 100644 --- a/Gems/LyShineExamples/Assets/UI/Canvases/LyShineExamples/Comp/Text/ImageMarkup.uicanvas +++ b/Gems/LyShineExamples/Assets/UI/Canvases/LyShineExamples/Comp/Text/ImageMarkup.uicanvas @@ -56,7 +56,7 @@ - + From 77278a03297113632ac95e5f558f4e4591e168d1 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Fri, 14 May 2021 11:18:15 -0500 Subject: [PATCH 206/225] First version of the slice-to-prefab converter It converts .slice and .ly files to .prefab files, but doesn't handle nested or complicated slices correctly yet. --- .../Tools/SerializeContextTools/Converter.cpp | 4 +- Code/Tools/SerializeContextTools/Converter.h | 2 +- Code/Tools/SerializeContextTools/Dumper.cpp | 2 +- .../SerializeContextTools/SliceConverter.cpp | 263 ++++++++++++++++++ .../SerializeContextTools/SliceConverter.h | 53 ++++ .../Tools/SerializeContextTools/Utilities.cpp | 32 ++- Code/Tools/SerializeContextTools/Utilities.h | 2 +- Code/Tools/SerializeContextTools/main.cpp | 13 + .../serializecontexttools_files.cmake | 2 + 9 files changed, 358 insertions(+), 15 deletions(-) create mode 100644 Code/Tools/SerializeContextTools/SliceConverter.cpp create mode 100644 Code/Tools/SerializeContextTools/SliceConverter.h diff --git a/Code/Tools/SerializeContextTools/Converter.cpp b/Code/Tools/SerializeContextTools/Converter.cpp index b15bb4fa8e..0b19d4e981 100644 --- a/Code/Tools/SerializeContextTools/Converter.cpp +++ b/Code/Tools/SerializeContextTools/Converter.cpp @@ -117,7 +117,7 @@ namespace AZ } return true; }; - if (!Utilities::InspectSerializedFile(filePath, convertSettings.m_serializeContext, callback)) + if (!Utilities::InspectSerializedFile(filePath.c_str(), convertSettings.m_serializeContext, callback)) { AZ_Warning("Convert", false, "Failed to load '%s'. File may not contain an object stream.", filePath.c_str()); result = false; @@ -287,7 +287,7 @@ namespace AZ } return true; }; - if (!Utilities::InspectSerializedFile(filePath, convertSettings.m_serializeContext, callback)) + if (!Utilities::InspectSerializedFile(filePath.c_str(), convertSettings.m_serializeContext, callback)) { AZ_Warning("Convert", false, "Failed to load '%s'. File may not contain an object stream.", filePath.c_str()); result = false; diff --git a/Code/Tools/SerializeContextTools/Converter.h b/Code/Tools/SerializeContextTools/Converter.h index 18f30cc562..c6338b8d29 100644 --- a/Code/Tools/SerializeContextTools/Converter.h +++ b/Code/Tools/SerializeContextTools/Converter.h @@ -42,7 +42,7 @@ namespace AZ //! Can be used to convert *.ini and *.cfg files static bool ConvertConfigFile(Application& application); - private: + protected: using PathDocumentPair = AZStd::pair; using PathDocumentContainer = AZStd::vector; diff --git a/Code/Tools/SerializeContextTools/Dumper.cpp b/Code/Tools/SerializeContextTools/Dumper.cpp index 55c9581602..590ee65571 100644 --- a/Code/Tools/SerializeContextTools/Dumper.cpp +++ b/Code/Tools/SerializeContextTools/Dumper.cpp @@ -85,7 +85,7 @@ namespace AZ::SerializeContextTools result = false; } }; - if (!Utilities::InspectSerializedFile(filePath, sc, callback)) + if (!Utilities::InspectSerializedFile(filePath.c_str(), sc, callback)) { result = false; continue; diff --git a/Code/Tools/SerializeContextTools/SliceConverter.cpp b/Code/Tools/SerializeContextTools/SliceConverter.cpp new file mode 100644 index 0000000000..2df3888607 --- /dev/null +++ b/Code/Tools/SerializeContextTools/SliceConverter.cpp @@ -0,0 +1,263 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// SliceConverter reads in a slice file (saved in an ObjectStream format), instantiates it, creates a prefab out of the data, +// and saves the prefab in a JSON format. This can be used for one-time migrations of slices or slice-based levels to prefabs. +// This converter is still in an early state. It can convert trivial slices, but it cannot handle nested slices yet. +// +// If the slice contains legacy data, it will print out warnings / errors about the data that couldn't be serialized. +// The prefab will be generated without that data. + +namespace AZ +{ + namespace SerializeContextTools + { + bool SliceConverter::ConvertSliceFiles(Application& application) + { + using namespace AZ::JsonSerializationResult; + + const AZ::CommandLine* commandLine = application.GetAzCommandLine(); + if (!commandLine) + { + AZ_Error("SerializeContextTools", false, "Command line not available."); + return false; + } + + JsonSerializerSettings convertSettings; + convertSettings.m_keepDefaults = commandLine->HasSwitch("keepdefaults"); + convertSettings.m_registrationContext = application.GetJsonRegistrationContext(); + convertSettings.m_serializeContext = application.GetSerializeContext(); + if (!convertSettings.m_serializeContext) + { + AZ_Error("Convert-Slice", false, "No serialize context found."); + return false; + } + if (!convertSettings.m_registrationContext) + { + AZ_Error("Convert-Slice", false, "No json registration context found."); + return false; + } + AZStd::string logggingScratchBuffer; + SetupLogging(logggingScratchBuffer, convertSettings.m_reporting, *commandLine); + + bool isDryRun = commandLine->HasSwitch("dryrun"); + + JsonDeserializerSettings verifySettings; + verifySettings.m_registrationContext = application.GetJsonRegistrationContext(); + verifySettings.m_serializeContext = application.GetSerializeContext(); + SetupLogging(logggingScratchBuffer, verifySettings.m_reporting, *commandLine); + + auto archiveInterface = AZ::Interface::Get(); + + // Find the Prefab System Component for use in creating and saving the prefab + AZ::Entity* systemEntity = application.FindEntity(AZ::SystemEntityId); + AZ_Assert(systemEntity != nullptr, "System entity doesn't exist."); + auto prefabSystemComponent = systemEntity->FindComponent(); + AZ_Assert(prefabSystemComponent != nullptr, "Prefab System component doesn't exist"); + + bool result = true; + rapidjson::StringBuffer scratchBuffer; + + AZStd::vector fileList = Utilities::ReadFileListFromCommandLine(application, "files"); + for (AZStd::string& filePath : fileList) + { + bool packOpened = false; + + AZ::IO::Path outputPath = filePath; + outputPath.ReplaceExtension("prefab"); + + AZ_Printf("Convert-Slice", "------------------------------------------------------------------------------------------\n"); + AZ_Printf("Convert-Slice", "Converting '%s' to '%s'\n", filePath.c_str(), outputPath.c_str()); + + AZ::IO::Path inputPath = filePath; + auto fileExtension = inputPath.Extension(); + if (fileExtension == ".ly") + { + // Special case: for level files, we need to open the .ly zip file and convert the levelentities.editor_xml file + // inside of it. All the other files can be ignored as they are deprecated legacy system files that are no longer + // loaded with prefab-based levels. + packOpened = archiveInterface->OpenPack(filePath); + inputPath.ReplaceFilename("levelentities.editor_xml"); + AZ_Warning("Convert-Slice", packOpened, " '%s' could not be opened as a pack file.\n", filePath.c_str()); + } + else + { + AZ_Warning( + "Convert-Slice", (fileExtension == ".slice"), + " Warning: Only .ly and .slice files are supported, conversion of '%.*s' may not work.\n", + AZ_STRING_ARG(fileExtension.Native())); + } + + auto callback = [prefabSystemComponent, &outputPath, isDryRun] + (void* classPtr, const Uuid& classId, [[maybe_unused]] SerializeContext* context) + { + if (classId != azrtti_typeid()) + { + AZ_Printf("Convert-Slice", " File not converted: Slice root is not an entity.\n"); + return false; + } + + AZ::Entity* rootEntity = reinterpret_cast(classPtr); + return ConvertSliceFile(prefabSystemComponent, outputPath, isDryRun, rootEntity); + }; + + if (!Utilities::InspectSerializedFile(inputPath.c_str(), convertSettings.m_serializeContext, callback)) + { + AZ_Warning("Convert-Slice", false, "Failed to load '%s'. File may not contain an object stream.", inputPath.c_str()); + result = false; + } + + if (packOpened) + { + [[maybe_unused]] bool closeResult = archiveInterface->ClosePack(filePath); + AZ_Warning("Convert-Slice", !closeResult, "Failed to close '%s'.", filePath.c_str()); + } + + AZ_Printf("Convert-Slice", "Finished converting '%s' to '%s'\n", filePath.c_str(), outputPath.c_str()); + AZ_Printf("Convert-Slice", "------------------------------------------------------------------------------------------\n"); + } + + return result; + } + + bool SliceConverter::ConvertSliceFile( + AzToolsFramework::Prefab::PrefabSystemComponent* prefabSystemComponent, AZ::IO::PathView outputPath, bool isDryRun, + AZ::Entity* rootEntity) + { + // Find the slice from the root entity. + SliceComponent* sliceComponent = AZ::EntityUtils::FindFirstDerivedComponent(rootEntity); + if (sliceComponent == nullptr) + { + AZ_Printf("Convert-Slice", " File not converted: Root entity did not contain a slice component.\n"); + return false; + } + + // Get all of the entities from the slice. + SliceComponent::EntityList sliceEntities; + bool getEntitiesResult = sliceComponent->GetEntities(sliceEntities); + if ((!getEntitiesResult) || (sliceEntities.empty())) + { + AZ_Printf("Convert-Slice", " File not converted: Slice entities could not be retrieved.\n"); + return false; + } + + // Create the Prefab with the entities from the slice + AZStd::unique_ptr sourceInstance( + prefabSystemComponent->CreatePrefab(sliceEntities, {}, outputPath)); + + // Dispatch events here, because prefab creation might trigger asset loads in rare circumstances. + AZ::Data::AssetManager::Instance().DispatchEvents(); + + // Set up the Prefab container entity to be a proper Editor entity. (This logic is normally triggered + // via an EditorRequests EBus in CreatePrefab, but the subsystem that listens for it isn't present in this tool.) + AzToolsFramework::Prefab::EntityOptionalReference container = sourceInstance->GetContainerEntity(); + AzToolsFramework::EditorEntityContextRequestBus::Broadcast( + &AzToolsFramework::EditorEntityContextRequestBus::Events::AddRequiredComponents, container->get()); + container->get().AddComponent(aznew AzToolsFramework::Prefab::EditorPrefabComponent()); + + // Reparent any root-level slice entities to the container entity. + for (auto entity : sliceEntities) + { + AzToolsFramework::Components::TransformComponent* transformComponent = + entity->FindComponent(); + if (transformComponent) + { + if (!transformComponent->GetParentId().IsValid()) + { + transformComponent->SetParent(container->get().GetId()); + } + } + } + + auto templateId = sourceInstance->GetTemplateId(); + + if (templateId == AzToolsFramework::Prefab::InvalidTemplateId) + { + AZ_Printf("Convert-Slice", " Path error. Path could be invalid, or the prefab may not be loaded in this level.\n"); + return false; + } + + // Update the prefab template with the fixed-up data in our prefab instance. + AzToolsFramework::Prefab::PrefabDom prefabDom; + bool storeResult = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*sourceInstance, prefabDom); + if (storeResult == false) + { + AZ_Printf("Convert-Slice", " Failed to convert prefab instance data to a PrefabDom.\n"); + return false; + } + prefabSystemComponent->UpdatePrefabTemplate(templateId, prefabDom); + + // Dispatch events here, because prefab serialization might trigger asset loads in rare circumstances. + AZ::Data::AssetManager::Instance().DispatchEvents(); + + if (isDryRun) + { + PrintPrefab(prefabDom, sourceInstance->GetTemplateSourcePath()); + return true; + } + else + { + return SavePrefab(templateId); + } + } + + void SliceConverter::PrintPrefab(const AzToolsFramework::Prefab::PrefabDom& prefabDom, const AZ::IO::Path& templatePath) + { + rapidjson::StringBuffer prefabBuffer; + rapidjson::PrettyWriter writer(prefabBuffer); + prefabDom.Accept(writer); + AZ_Printf("Convert-Slice", "JSON for %s:\n", templatePath.c_str()); + + // We use Output() to print out the JSON because AZ_Printf has a 4096-character limit. + AZ::Debug::Trace::Instance().Output("", prefabBuffer.GetString()); + AZ::Debug::Trace::Instance().Output("", "\n"); + } + + bool SliceConverter::SavePrefab(AzToolsFramework::Prefab::TemplateId templateId) + { + auto prefabLoaderInterface = AZ::Interface::Get(); + + if (!prefabLoaderInterface->SaveTemplate(templateId)) + { + AZ_Printf("Convert-Slice", " Could not save prefab - internal error (Json write operation failure).\n"); + return false; + } + + return true; + } + + } // namespace SerializeContextTools +} // namespace AZ diff --git a/Code/Tools/SerializeContextTools/SliceConverter.h b/Code/Tools/SerializeContextTools/SliceConverter.h new file mode 100644 index 0000000000..90dfa0d50a --- /dev/null +++ b/Code/Tools/SerializeContextTools/SliceConverter.h @@ -0,0 +1,53 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace AZ +{ + class CommandLine; + class Entity; + class ModuleEntity; + class SerializeContext; + struct Uuid; + + namespace SerializeContextTools + { + class Application; + + class SliceConverter : public Converter + { + public: + static bool ConvertSliceFiles(Application& application); + + private: + + static bool ConvertSliceFile(AzToolsFramework::Prefab::PrefabSystemComponent* prefabSystemComponent, + AZ::IO::PathView outputPath, bool isDryRun, AZ::Entity* rootEntity); + + static void PrintPrefab(const AzToolsFramework::Prefab::PrefabDom& prefabDom, const AZ::IO::Path& templatePath); + static bool SavePrefab(AzToolsFramework::Prefab::TemplateId templateId); + }; + } // namespace SerializeContextTools +} // namespace AZ diff --git a/Code/Tools/SerializeContextTools/Utilities.cpp b/Code/Tools/SerializeContextTools/Utilities.cpp index 1c50466443..cfd75a44e7 100644 --- a/Code/Tools/SerializeContextTools/Utilities.cpp +++ b/Code/Tools/SerializeContextTools/Utilities.cpp @@ -209,30 +209,42 @@ namespace AZ::SerializeContextTools return result; } - bool Utilities::InspectSerializedFile(const AZStd::string& filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback) + bool Utilities::InspectSerializedFile(const char* filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback) { - if (!AZ::IO::SystemFile::Exists(filePath.c_str())) + if (!AZ::IO::FileIOBase::GetInstance()->Exists(filePath)) { - AZ_Error("Verify", false, "Unable to open file '%s' as it doesn't exist.", filePath.c_str()); + AZ_Error("Verify", false, "Unable to open file '%s' as it doesn't exist.", filePath); return false; } - u64 fileLength = AZ::IO::SystemFile::Length(filePath.c_str()); - if (fileLength == 0) + AZ::IO::HandleType fileHandle; + auto openResult = AZ::IO::FileIOBase::GetInstance()->Open(filePath, AZ::IO::OpenMode::ModeRead, fileHandle); + if (!openResult) { - AZ_Error("Verify", false, "File '%s' doesn't have content.", filePath.c_str()); + AZ_Error("Verify", false, "File '%s' could not be opened.", filePath); + return false; + } + + u64 fileLength = 0; + auto sizeResult = AZ::IO::FileIOBase::GetInstance()->Size(fileHandle, fileLength); + if (!sizeResult || (fileLength == 0)) + { + AZ_Error("Verify", false, "File '%s' doesn't have content.", filePath); return false; } AZStd::vector data; data.resize_no_construct(fileLength); - u64 bytesRead = AZ::IO::SystemFile::Read(filePath.c_str(), data.data()); - if (bytesRead != fileLength) + u64 bytesRead = 0; + auto readResult = AZ::IO::FileIOBase::GetInstance()->Read(fileHandle, data.data(), fileLength, true, &bytesRead); + if (!readResult || (bytesRead != fileLength)) { - AZ_Error("Verify", false, "Unable to read file '%s'.", filePath.c_str()); + AZ_Error("Verify", false, "Unable to read file '%s'.", filePath); return false; } + AZ::IO::FileIOBase::GetInstance()->Close(fileHandle); + AZ::IO::MemoryStream stream(data.data(), fileLength); ObjectStream::FilterDescriptor filter; @@ -241,7 +253,7 @@ namespace AZ::SerializeContextTools filter.m_assetCB = AZ::Data::AssetFilterNoAssetLoading; if (!ObjectStream::LoadBlocking(&stream, *sc, classCallback, filter)) { - AZ_Printf("Verify", "Failed to deserialize '%s'\n", filePath.c_str()); + AZ_Printf("Verify", "Failed to deserialize '%s'\n", filePath); return false; } return true; diff --git a/Code/Tools/SerializeContextTools/Utilities.h b/Code/Tools/SerializeContextTools/Utilities.h index d04f67a304..f08bfc2f64 100644 --- a/Code/Tools/SerializeContextTools/Utilities.h +++ b/Code/Tools/SerializeContextTools/Utilities.h @@ -39,7 +39,7 @@ namespace AZ static AZStd::vector GetSystemComponents(const Application& application); - static bool InspectSerializedFile(const AZStd::string& filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback); + static bool InspectSerializedFile(const char* filePath, SerializeContext* sc, const ObjectStream::ClassReadyCB& classCallback); private: Utilities() = delete; diff --git a/Code/Tools/SerializeContextTools/main.cpp b/Code/Tools/SerializeContextTools/main.cpp index fb2dc442ed..d9f2cfbcc2 100644 --- a/Code/Tools/SerializeContextTools/main.cpp +++ b/Code/Tools/SerializeContextTools/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include void PrintHelp() @@ -74,6 +75,14 @@ void PrintHelp() AZ_Printf("Help", R"( On Windows the should be in quotes, as \"/\" is treated as command option prefix)" "\n"); AZ_Printf("Help", R"( [opt] -verbose: Report additional details during the conversion process.)" "\n"); AZ_Printf("Help", R"( example: 'convert-ini --files=AssetProcessorPlatformConfig.ini;bootstrap.cfg --ext=setreg)" "\n"); + AZ_Printf("Help", " 'convert-slice': Converts ObjectStream-based slice files or legacy levels to a JSON-based prefab.\n"); + AZ_Printf("Help", " [arg] -files=: -separated list of files to convert. Supports wildcards.\n"); + AZ_Printf("Help", " [opt] -dryrun: Processes as normal, but doesn't write files.\n"); + AZ_Printf("Help", " [opt] -keepdefaults: Fields are written if a default value was found.\n"); + AZ_Printf("Help", " [opt] -verbose: Report additional details during the conversion process.\n"); + AZ_Printf("Help", " example: 'convert-slice -files=*.slice -specializations=editor\n"); + AZ_Printf("Help", " example: 'convert-slice -files=Levels/TestLevel/TestLevel.ly -specializations=editor\n"); + AZ_Printf("Help", "\n"); } int main(int argc, char** argv) @@ -114,6 +123,10 @@ int main(int argc, char** argv) { result = Converter::ConvertConfigFile(application); } + else if (AZ::StringFunc::Equal("convert-slice", action.c_str())) + { + result = SliceConverter::ConvertSliceFiles(application); + } else { PrintHelp(); diff --git a/Code/Tools/SerializeContextTools/serializecontexttools_files.cmake b/Code/Tools/SerializeContextTools/serializecontexttools_files.cmake index db584ff385..814c55ea08 100644 --- a/Code/Tools/SerializeContextTools/serializecontexttools_files.cmake +++ b/Code/Tools/SerializeContextTools/serializecontexttools_files.cmake @@ -17,6 +17,8 @@ set(FILES Dumper.h Dumper.cpp main.cpp + SliceConverter.h + SliceConverter.cpp Utilities.h Utilities.cpp ) From 05fec17ebd1bc28ee992a4f57425750671349936 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Fri, 14 May 2021 10:35:50 -0700 Subject: [PATCH 207/225] Remove hardcoded paths to Atom gems in registration.py and clean up gem.json files --- Gems/Atom/Asset/ImageProcessingAtom/gem.json | 27 --------- Gems/Atom/Asset/Shader/gem.json | 27 --------- Gems/Atom/Bootstrap/gem.json | 25 -------- Gems/Atom/Component/DebugCamera/gem.json | 25 -------- Gems/Atom/Feature/Common/gem.json | 43 -------------- Gems/Atom/RHI/DX12/gem.json | 35 ----------- Gems/Atom/RHI/Metal/gem.json | 35 ----------- Gems/Atom/RHI/Null/gem.json | 26 --------- Gems/Atom/RHI/Vulkan/gem.json | 39 ------------- Gems/Atom/RHI/gem.json | 30 ---------- Gems/Atom/RPI/gem.json | 48 --------------- Gems/Atom/Tools/AtomToolsFramework/gem.json | 17 ------ Gems/Atom/Tools/MaterialEditor/gem.json | 58 ------------------- .../Tools/ShaderManagementConsole/gem.json | 50 ---------------- Gems/Atom/Utils/gem.json | 31 ---------- Gems/Atom/gem.json | 3 + Gems/AtomLyIntegration/AtomBridge/gem.json | 37 ------------ Gems/AtomLyIntegration/AtomFont/gem.json | 19 ------ .../AtomLyIntegration/AtomImGuiTools/gem.json | 25 -------- .../AtomLyIntegration/CommonFeatures/gem.json | 45 -------------- Gems/AtomLyIntegration/EMotionFXAtom/gem.json | 36 ------------ Gems/AtomLyIntegration/ImguiAtom/gem.json | 32 ---------- .../DccScriptingInterface/gem.json | 17 ------ Gems/AtomLyIntegration/gem.json | 3 + cmake/Tools/registration.py | 2 - 25 files changed, 6 insertions(+), 729 deletions(-) delete mode 100644 Gems/Atom/Asset/ImageProcessingAtom/gem.json delete mode 100644 Gems/Atom/Asset/Shader/gem.json delete mode 100644 Gems/Atom/Bootstrap/gem.json delete mode 100644 Gems/Atom/Component/DebugCamera/gem.json delete mode 100644 Gems/Atom/Feature/Common/gem.json delete mode 100644 Gems/Atom/RHI/DX12/gem.json delete mode 100644 Gems/Atom/RHI/Metal/gem.json delete mode 100644 Gems/Atom/RHI/Null/gem.json delete mode 100644 Gems/Atom/RHI/Vulkan/gem.json delete mode 100644 Gems/Atom/RHI/gem.json delete mode 100644 Gems/Atom/RPI/gem.json delete mode 100644 Gems/Atom/Tools/AtomToolsFramework/gem.json delete mode 100644 Gems/Atom/Tools/MaterialEditor/gem.json delete mode 100644 Gems/Atom/Tools/ShaderManagementConsole/gem.json delete mode 100644 Gems/Atom/Utils/gem.json create mode 100644 Gems/Atom/gem.json delete mode 100644 Gems/AtomLyIntegration/AtomBridge/gem.json delete mode 100644 Gems/AtomLyIntegration/AtomFont/gem.json delete mode 100644 Gems/AtomLyIntegration/AtomImGuiTools/gem.json delete mode 100644 Gems/AtomLyIntegration/CommonFeatures/gem.json delete mode 100644 Gems/AtomLyIntegration/EMotionFXAtom/gem.json delete mode 100644 Gems/AtomLyIntegration/ImguiAtom/gem.json delete mode 100644 Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/gem.json create mode 100644 Gems/AtomLyIntegration/gem.json diff --git a/Gems/Atom/Asset/ImageProcessingAtom/gem.json b/Gems/Atom/Asset/ImageProcessingAtom/gem.json deleted file mode 100644 index abe759ed71..0000000000 --- a/Gems/Atom/Asset/ImageProcessingAtom/gem.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "gem_name": "ImageProcessingAtom", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI" - } - ], - "GemFormatVersion": 4, - "Uuid": "9d10b00be96045caa64c705e5772cb64", - "Name": "ImageProcessingAtom", - "DisplayName": "Atom.Asset.ImageProcessing", - "Version": "0.1.0", - "Summary": "Contains Asset Processor builder for processing image files for Atom and UI for Atom texture property editing in Asset Browser", - "Tags": [ "Atom Image Builder", "Atom Texture Property Editor" ], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Editor", - "Type": "EditorModule" - } - ] -} diff --git a/Gems/Atom/Asset/Shader/gem.json b/Gems/Atom/Asset/Shader/gem.json deleted file mode 100644 index 3371b10f7a..0000000000 --- a/Gems/Atom/Asset/Shader/gem.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "gem_name": "Atom_Asset_Shader", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI" - } - ], - "GemFormatVersion": 4, - "Uuid": "d32452026dae4b7dba2ad89dbde9c48f", - "Name": "Atom_Asset_Shader", - "DisplayName": "Atom.Asset.Shader", - "Version": "0.1.0", - "Summary": "The systems necessary to build and use AZSL Shaders", - "Tags": ["Assets", "Atom", "Shader"], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Builders", - "Type": "EditorModule" - } - ] -} diff --git a/Gems/Atom/Bootstrap/gem.json b/Gems/Atom/Bootstrap/gem.json deleted file mode 100644 index 21b909c249..0000000000 --- a/Gems/Atom/Bootstrap/gem.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "gem_name": "Atom_Bootstrap", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI.Public" - } - ], - "GemFormatVersion": 4, - "Uuid": "c7ff89ad6e8b4b45b2fadef2bcf12d6e", - "Name": "Atom_Bootstrap", - "DisplayName": "Atom.Bootstrap", - "Version": "0.1.0", - "Summary": "Bootstrap gem to setup any necessary Atom components.", - "Tags": ["Atom", "Bootstrap"], - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - } - ] -} diff --git a/Gems/Atom/Component/DebugCamera/gem.json b/Gems/Atom/Component/DebugCamera/gem.json deleted file mode 100644 index eb59669951..0000000000 --- a/Gems/Atom/Component/DebugCamera/gem.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "gem_name": "Atom_Component_DebugCamera", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI" - } - ], - "GemFormatVersion": 4, - "Uuid": "013d1b42ad314c929b292c143bcbf045", - "Version": "0.1.0", - "Name": "Atom_Component_DebugCamera", - "DisplayName": "Atom.Component.DebugCamera", - "Tags": ["Atom", "Camera", "Debug"], - "Summary": "Debug Camera for testing RPI/RHI", - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - } - ] -} diff --git a/Gems/Atom/Feature/Common/gem.json b/Gems/Atom/Feature/Common/gem.json deleted file mode 100644 index 689deb492e..0000000000 --- a/Gems/Atom/Feature/Common/gem.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "gem_name": "Atom_Feature_Common", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI" - } - ], - "GemFormatVersion": 4, - "Uuid": "b58e5eed0901428ca78544b04dbd61bd", - "Name": "Atom_Feature_Common", - "DisplayName": "Atom.Feature.Common", - "Version": "0.1.0", - "LinkType": "Dynamic", - "Summary": "Provides commonly used render features.", - "Tags": [ "Atom", "Feature", "Common" ], - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - }, - { - "Name": "Builders", - "Type": "EditorModule" - }, - { - "Name": "Public", - "Type": "StaticLib" - }, - { - "Name": "Editor", - "Type": "EditorModule", - "Extends": "GameModule" - }, - { - "Name": "StaticLibrary", - "Type": "StaticLib" - } - ] -} diff --git a/Gems/Atom/RHI/DX12/gem.json b/Gems/Atom/RHI/DX12/gem.json deleted file mode 100644 index 1af6988a2f..0000000000 --- a/Gems/Atom/RHI/DX12/gem.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "gem_name": "Atom_RHI_DX12", - "Dependencies": [ - { - "Uuid": "fb7f322c8bdb42228d9e155c954f98bd", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RHI" - } - ], - "GemFormatVersion": 4, - "Uuid": "e011969cf32442fdaac2443a960ab5ff", - "Name": "Atom_RHI_DX12", - "DisplayName": "Atom RHI.DX12", - "Version": "0.1.0", - "Summary": "The DirectX 12 backend for the Atom Render Hardware Interface", - "Tags": ["Atom", "RHI", "DX12"], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Private", - "Type": "GameModule" - }, - { - "Name": "Reflect", - "Type": "StaticLib" - }, - { - "Name": "Builders", - "Type": "EditorModule" - } - ] -} diff --git a/Gems/Atom/RHI/Metal/gem.json b/Gems/Atom/RHI/Metal/gem.json deleted file mode 100644 index 5724c6e4a4..0000000000 --- a/Gems/Atom/RHI/Metal/gem.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "gem_name": "Atom_RHI_Metal", - "Dependencies": [ - { - "Uuid": "fb7f322c8bdb42228d9e155c954f98bd", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RHI" - } - ], - "GemFormatVersion": 4, - "Uuid": "5f27cdc951e64fe0be9d823dc7acbc28", - "Name": "Atom_RHI_Metal", - "DisplayName": "Atom RHI.Metal", - "Version": "0.1.0", - "Summary": "The Metal backend for the Atom Render Hardware Interface", - "Tags": ["Atom", "RHI", "Metal"], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Private", - "Type": "GameModule" - }, - { - "Name": "Reflect", - "Type": "StaticLib" - }, - { - "Name": "Builders", - "Type": "EditorModule" - } - ] -} diff --git a/Gems/Atom/RHI/Null/gem.json b/Gems/Atom/RHI/Null/gem.json deleted file mode 100644 index 7327b6af77..0000000000 --- a/Gems/Atom/RHI/Null/gem.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "gem_name": "Atom_RHI_Null", - "GemFormatVersion": 4, - "Uuid": "1f64c07a7d2f4722a3969fcf3be34d30", - "Name": "Atom_RHI_Null", - "DisplayName": "Atom RHI.Null", - "Version": "0.1.0", - "Summary": "The Null backend for the Atom Render Hardware Interface", - "Tags": ["Atom", "RHI", "Null"], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Private", - "Type": "GameModule" - }, - { - "Name": "Reflect", - "Type": "StaticLib" - }, - { - "Name": "Builders", - "Type": "EditorModule" - } - ] -} diff --git a/Gems/Atom/RHI/Vulkan/gem.json b/Gems/Atom/RHI/Vulkan/gem.json deleted file mode 100644 index fb89def7b5..0000000000 --- a/Gems/Atom/RHI/Vulkan/gem.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "gem_name": "Atom_RHI_Vulkan", - "Dependencies": [ - { - "Uuid": "fb7f322c8bdb42228d9e155c954f98bd", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RHI" - } - ], - "GemFormatVersion": 4, - "Uuid": "150d40d376124d98a388dfe890551c03", - "Name": "Atom_RHI_Vulkan", - "DisplayName": "Atom RHI.Vulkan", - "Version": "0.1.0", - "Summary": "The Vulkan backend for the Atom Render Hardware Interface", - "Tags": ["Atom", "RHI", "Vulkan"], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Private", - "Type": "GameModule" - }, - { - "Name": "Reflect", - "Type": "StaticLib" - }, - { - "Name": "Glad", - "Type": "StaticLib" - }, - { - "Name": "Builders", - "Type": "EditorModule" - } - ] -} diff --git a/Gems/Atom/RHI/gem.json b/Gems/Atom/RHI/gem.json deleted file mode 100644 index 96dabe2c91..0000000000 --- a/Gems/Atom/RHI/gem.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "gem_name": "Atom_RHI", - "GemFormatVersion": 4, - "Uuid": "fb7f322c8bdb42228d9e155c954f98bd", - "Name": "Atom_RHI", - "DisplayName": "Atom RHI", - "Version": "0.1.0", - "Summary": "The Atom Render Hardware Interface", - "Tags": ["Atom", "RHI"], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Private", - "Type": "GameModule" - }, - { - "Name": "Public", - "Type": "StaticLib" - }, - { - "Name": "Reflect", - "Type": "StaticLib" - }, - { - "Name": "Tests", - "Type": "Standalone" - } - ] -} diff --git a/Gems/Atom/RPI/gem.json b/Gems/Atom/RPI/gem.json deleted file mode 100644 index 4a144fe53f..0000000000 --- a/Gems/Atom/RPI/gem.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "gem_name": "Atom_RPI", - "Dependencies": [ - { - "Uuid": "fb7f322c8bdb42228d9e155c954f98bd", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RHI" - } - ], - "GemFormatVersion": 4, - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "Name": "Atom_RPI", - "DisplayName": "Atom RPI", - "Version": "0.1.0", - "Summary": "The Atom Render Pipeline Interface", - "Tags": ["Atom", "RPI"], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Builders", - "Type": "EditorModule" - }, - { - "Name": "Private", - "Type": "GameModule" - }, - { - "Name": "Public", - "Type": "StaticLib" - }, - { - "Name": "Reflect", - "Type": "StaticLib" - }, - { - "Name": "Editor", - "Type": "EditorModule", - "Extends": "Private" - }, - { - "Name": "Tests", - "Type": "Standalone" - } - ] -} diff --git a/Gems/Atom/Tools/AtomToolsFramework/gem.json b/Gems/Atom/Tools/AtomToolsFramework/gem.json deleted file mode 100644 index e3caecf339..0000000000 --- a/Gems/Atom/Tools/AtomToolsFramework/gem.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "gem_name": "AtomToolsFramework", - "GemFormatVersion": 4, - "Uuid": "3e0ee0c27f204f5188146baac822d020", - "Name": "AtomToolsFramework", - "DisplayName": "AtomToolsFramework", - "Version": "0.1.0", - "Summary": "AtomToolsFramework", - "Tags": [ "Untagged" ], - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Editor", - "Type": "EditorModule" - } - ] -} diff --git a/Gems/Atom/Tools/MaterialEditor/gem.json b/Gems/Atom/Tools/MaterialEditor/gem.json deleted file mode 100644 index ce913e552c..0000000000 --- a/Gems/Atom/Tools/MaterialEditor/gem.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "gem_name": "MaterialEditor", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI" - }, - { - "Uuid": "b58e5eed0901428ca78544b04dbd61bd", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom Feature Common" - }, - { - "Uuid": "b658359393884c4381c2fe2952b1472a", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "EditorPythonBindings" - }, - { - "Uuid": "3e0ee0c27f204f5188146baac822d020", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "AtomToolsFramework" - }, - { - "Uuid": "9d10b00be96045caa64c705e5772cb64", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "ImageProcessingAtom" - }, - { - "Uuid": "4e981f3b17394f5d84d674fff0f54f4f", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "AtomLyIntegration.CommonFeatures" - } - ], - "GemFormatVersion": 4, - "Uuid": "36f854c260b84d438dde4bc5789d8123", - "Name": "MaterialEditor", - "DisplayName": "Material Editor", - "Version": "0.1.0", - "LinkType": "Dynamic", - "Summary": "Tools for editing Atom materials", - "Tags": ["Untagged"], - "IconPath": "preview.svg", - "Modules": [ - ] -} diff --git a/Gems/Atom/Tools/ShaderManagementConsole/gem.json b/Gems/Atom/Tools/ShaderManagementConsole/gem.json deleted file mode 100644 index 8cf05dc725..0000000000 --- a/Gems/Atom/Tools/ShaderManagementConsole/gem.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "gem_name": "ShaderManagementConsole", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI" - }, - { - "Uuid": "b658359393884c4381c2fe2952b1472a", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "EditorPythonBindings" - }, - { - "Uuid": "3e0ee0c27f204f5188146baac822d020", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "AtomToolsFramework" - }, - { - "Uuid": "9d10b00be96045caa64c705e5772cb64", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "ImageProcessingAtom" - }, - { - "Uuid": "4e981f3b17394f5d84d674fff0f54f4f", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "AtomLyIntegration.CommonFeatures" - } - ], - "GemFormatVersion": 4, - "Uuid": "77967ca0a6264a8e95b138a31bf78fe0", - "Name": "ShaderManagementConsole", - "DisplayName": "Shader Management Console", - "Version": "0.1.0", - "LinkType": "Dynamic", - "Summary": "Shader Management Console", - "IconPath": "preview.svg", - "Modules": [ - ] -} diff --git a/Gems/Atom/Utils/gem.json b/Gems/Atom/Utils/gem.json deleted file mode 100644 index 7f9ae3041a..0000000000 --- a/Gems/Atom/Utils/gem.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "gem_name": "Atom_Utils", - "Dependencies": [ - { - "Uuid": "fb7f322c8bdb42228d9e155c954f98bd", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RHI" - } - ], - "GemFormatVersion": 4, - "Uuid": "5c850809e890497c82cd9999ecb33250", - "Name": "Atom_Utils", - "DisplayName": "Atom.Utils", - "Version": "0.1.0", - "Summary": "Various utility classes used by Atom.", - "Tags": ["Atom", "Utils"], - "LinkType": "Dynamic", - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Utils", - "Type": "StaticLib" - }, - { - "Name": "Tests", - "Type": "Standalone" - } - ] -} diff --git a/Gems/Atom/gem.json b/Gems/Atom/gem.json new file mode 100644 index 0000000000..c74a9013f3 --- /dev/null +++ b/Gems/Atom/gem.json @@ -0,0 +1,3 @@ +{ + "gem_name": "Atom" +} diff --git a/Gems/AtomLyIntegration/AtomBridge/gem.json b/Gems/AtomLyIntegration/AtomBridge/gem.json deleted file mode 100644 index 17cb022932..0000000000 --- a/Gems/AtomLyIntegration/AtomBridge/gem.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "gem_name": "Atom_AtomBridge", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI" - }, - { - "Uuid": "c7ff89ad6e8b4b45b2fadef2bcf12d6e", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom_Bootstrap" - } - ], - "GemFormatVersion": 4, - "Uuid": "b55b2738aa4a46c8b034fe98e6e5158b", - "Name": "Atom_AtomBridge", - "DisplayName": "Atom.AtomBridge", - "Version": "0.1.0", - "Summary": "A short description of my Gem.", - "Tags": ["Untagged"], - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - }, - { - "Name": "Editor", - "Type": "EditorModule", - "Extends": "GameModule" - } - ] -} diff --git a/Gems/AtomLyIntegration/AtomFont/gem.json b/Gems/AtomLyIntegration/AtomFont/gem.json deleted file mode 100644 index d5ca7834fd..0000000000 --- a/Gems/AtomLyIntegration/AtomFont/gem.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "gem_name": "AtomFont", - "Dependencies": [ - ], - "GemFormatVersion": 4, - "Uuid": "{16ef36f2e3fc4e6ca15fcc484ec895fc}", - "Name": "AtomLyIntegration_AtomFont", - "DisplayName": "AtomLyIntegration.AtomFont", - "Version": "0.1.0", - "LinkType": "Dynamic", - "Summary": "Implement ICryFont & IFFont interfaces on Atom. Uses duplicated CryFont code", - "Tags": [ "Atom", "Font" ], - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - } - ] -} diff --git a/Gems/AtomLyIntegration/AtomImGuiTools/gem.json b/Gems/AtomLyIntegration/AtomImGuiTools/gem.json deleted file mode 100644 index 4d399e56e2..0000000000 --- a/Gems/AtomLyIntegration/AtomImGuiTools/gem.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "gem_name": "AtomImGuiTools", - "GemFormatVersion": 4, - "Uuid": "1a9d10de1b8a45fab2fe04517f613962", - "Name": "AtomImGuiTools", - "DisplayName": "Atom ImGui Tools", - "Version": "0.1.0", - "Summary": "ImGui tools for Atom renderer.", - "Tags": [ "Atom", "ImGui" ], - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - } - ], - "Dependencies": [ - { - "Uuid": "9986e22e14184f2fb6bb1e7dd185b2f9", - "VersionConstraints": [ - "~>0.1" - ], - "_comment": "ImGui.Atom" - } - ] -} diff --git a/Gems/AtomLyIntegration/CommonFeatures/gem.json b/Gems/AtomLyIntegration/CommonFeatures/gem.json deleted file mode 100644 index 6c5d21c7f1..0000000000 --- a/Gems/AtomLyIntegration/CommonFeatures/gem.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "gem_name": "AtomLyIntegration_CommonFeatures", - "Dependencies": [ - { - "Uuid": "3e0ee0c27f204f5188146baac822d020", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "AtomToolsFramework" - }, - { - "Uuid": "ff06785f7145416b9d46fde39098cb0c", - "VersionConstraints": [ - "~>0.1" - ], - "_comment": "LmbrCentral" - }, - { - "Uuid": "b58e5eed0901428ca78544b04dbd61bd", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom Common Features" - } - ], - "GemFormatVersion": 4, - "Uuid": "4e981f3b17394f5d84d674fff0f54f4f", - "Name": "AtomLyIntegration_CommonFeatures", - "DisplayName": "AtomLyIntegration.CommonFeatures", - "Version": "0.1.0", - "LinkType": "Dynamic", - "Summary": "Lumberyard integration for common Atom features.", - "Tags": [ "Atom", "Feature", "Common" ], - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - }, - { - "Name": "Editor", - "Type": "EditorModule", - "Extends": "GameModule" - } - ] -} diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/gem.json b/Gems/AtomLyIntegration/EMotionFXAtom/gem.json deleted file mode 100644 index bdc959cc69..0000000000 --- a/Gems/AtomLyIntegration/EMotionFXAtom/gem.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "gem_name": "EMotionFX_Atom", - "Dependencies": [ - { - "Uuid": "b58e5eed0901428ca78544b04dbd61bd", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom Common Features" - }, - { - "Uuid": "4e981f3b17394f5d84d674fff0f54f4f", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "AtomLyIntegration.CommonFeatures" - }, - { - "Uuid": "044a63ea67d04479aa5daf62ded9d9ca", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "EMotionFX" - } - ], - "GemFormatVersion": 3, - "Uuid": "{4f8a4d073ba34b43be45705f18705f1e}", - "Name": "EMotionFX_Atom", - "DisplayName": "EMotionFX.Atom", - "Version": "0.1.0", - "LinkType": "Dynamic", - "Summary": "EMotionFX support for Atom. Since some Atom projects will not include EMotionFX, and some projects using EMotionFX will not include Atom, this gem exists to prevent creating a hard dependency in either direction.", - "Tags": ["Atom", "EMotionFX", "Actor", "Skinned", "Mesh"], - "IconPath": "preview.png", - "EditorModule": true -} diff --git a/Gems/AtomLyIntegration/ImguiAtom/gem.json b/Gems/AtomLyIntegration/ImguiAtom/gem.json deleted file mode 100644 index dffef8fcc0..0000000000 --- a/Gems/AtomLyIntegration/ImguiAtom/gem.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "gem_name": "ImguiAtom", - "GemFormatVersion": 4, - "Uuid": "9986e22e14184f2fb6bb1e7dd185b2f9", - "Name": "ImguiAtom", - "DisplayName": "ImGui.Atom", - "Version": "0.1.0", - "Summary": "Provides ImGui implementation for Atom renderer", - "Tags": ["Atom", "ImGui"], - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - } - ], - "Dependencies": [ - { - "Uuid": "bab8807a1bc646b3909f3cc200ffeedf", - "VersionConstraints": [ - "~>0.1" - ], - "_comment": "ImGui" - }, - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1" - ], - "_comment": "Atom RPI" - } - ] -} diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/gem.json b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/gem.json deleted file mode 100644 index ca80c62dd0..0000000000 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/gem.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "gem_name": "Atom_DccScriptingInterface", - "GemFormatVersion": 4, - "Uuid": "7bf5a77dacd8438bb4966a66b5a678d8", - "Name": "Atom_DccScriptingInterface", - "DisplayName": "Atom DccScriptingInterface (DCCsi)", - "Version": "0.1.0", - "Summary": "A python framework for working with various DCC tools and workflows.", - "Tags": ["DCC","Digital","Content","Creation"], - "IconPath": "preview.png", - "Modules": [ - { - "Name": "Editor", - "Type": "EditorModule" - } - ] -} diff --git a/Gems/AtomLyIntegration/gem.json b/Gems/AtomLyIntegration/gem.json new file mode 100644 index 0000000000..0971ad53c2 --- /dev/null +++ b/Gems/AtomLyIntegration/gem.json @@ -0,0 +1,3 @@ +{ + "gem_name": "AtomLyIntegration" +} diff --git a/cmake/Tools/registration.py b/cmake/Tools/registration.py index 292ec33d1f..04b6f61496 100755 --- a/cmake/Tools/registration.py +++ b/cmake/Tools/registration.py @@ -259,8 +259,6 @@ def register_shipped_engine_o3de_objects() -> int: ret_val = error_code starting_external_subdirectories = [ - f'{engine_path}/Gems/Atom', - f'{engine_path}/Gems/AtomLyIntegration' ] for external_subdir in sorted(starting_external_subdirectories, reverse=True): error_code = add_external_subdirectory(engine_path=engine_path, external_subdir=external_subdir) From 8b8a582f029ceaa8ad934570240b4afa8d7d6d64 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 14 May 2021 13:01:11 -0500 Subject: [PATCH 208/225] External Project Build Path Support using SDK Binaries (#690) * Updated the DynamicModuleHandle code to search within the SettingsRegistry for the FilePathKey_ProjectBuildPath setting in order to determine the binary directory for the Project. This is used to locate shared libraries and executables built by the project when running and Engine SDK binary from within the Engine SDK * Added a generation step within the Projects.cmake file to generate a .setreg file containing the CMake build directory root. The file is output to the /user/Registry/build_path.setreg file. This occurs only on non-host platforms when configuring for non-Monolithic builds, since the Build Directory is used to located the project binary directory in order to located the project's generated ${CMAKE_BINARY_DIR}/bin/$/Registry directory containing the cmake_dependencies...setreg file containing the list of gem modules to load for a given application Updated the SettingsRegistryMergeUtils AddRuntimeFilePaths function to be read in the new "/Amazon/Project/Settings/Build/project_build_path" and use that to form an absolute path to the project build directory by appending it to the FilePathKey_ProjectPath key. That key is set in the 'FilePathKey_ProjectBuildPath' constant Next updated the SettingsRegistryMergeUtils MergeSettingsToRegistry_TargetBuildDependencyRegistry function to look within the project build directory to locate the cmake_dependencies.*.setreg file to load Tweaked the Settings Registry merge order of the ComponentApplication, GameApplication and Settings Registry builder to merge the command line after merging the global user registry and after merging the project user registry. Moved the call to MergeSettingsToRegistry_TargetBuildDependencyRegistry to occur after the above calls to make sure the properly overriden projects' user registry was merged in order for the correct project build path to be stored in the SettingsRegistry * Added a ProjectConfigurationBinPath key which contains the path to the /bin/$ directory for a project which is used to load gem dlls and the Registry/cmake_dependencies.*.setreg files when using an pre-built Editor/AssetProcessor on an external project * Fixed variable reference to fileNamePath variable * Removing the default Project Build Path from the Settings Registry Runtime Filepaths. Any paths would have to be set explicitly via .setreg/.setregpatch file or the --project-build-path parameter Updated the setting of the project build path and project binary directory to perform existance checks on the paths before setting the keys of /Amazon/AzCore/Runtime/FilePaths/ProjectBuildPath and /Amazon/AzCore/Runtime/FilePaths/ProjectConfigurationBinPath Added a backup project binary path of /bin/$/$ which is used if the path of /bin/$ has not been found Fixed compile error in DynamicModuleHandle_Apple.cpp * UnixLike Platform Build fix for the DynamicModuleHandle code --- .../AzCore/Component/ComponentApplication.cpp | 30 +++++++- .../Settings/SettingsRegistryMergeUtils.cpp | 39 +++++++++- .../Settings/SettingsRegistryMergeUtils.h | 10 ++- .../Module/DynamicModuleHandle_Android.cpp | 8 +- .../Module/DynamicModuleHandle_Apple.cpp | 16 +--- .../Module/DynamicModuleHandle_UnixLike.cpp | 77 +++++++++++-------- .../Module/DynamicModuleHandle_WinAPI.cpp | 28 ++++++- .../Module/DynamicModuleHandle_Linux.cpp | 16 +--- .../AzCore/Module/DynamicModuleHandle_iOS.cpp | 22 +++--- .../Application/GameApplication.cpp | 8 +- .../SettingsRegistryBuilder.cpp | 22 ++++-- Registry/application_options.setreg | 1 + cmake/Projects.cmake | 48 +++++++++++- 13 files changed, 236 insertions(+), 89 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp index b2fe4417d3..c93f825a2c 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp @@ -916,27 +916,49 @@ namespace AZ SetSettingsRegistrySpecializations(specializations); AZStd::vector scratchBuffer; - // Retrieves the list gem module build targets that the active project depends on - SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, - AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) // In development builds apply the o3de registry and the command line to allow early overrides. This will // allow developers to override things like default paths or Asset Processor connection settings. Any additional // values will be replaced by later loads, so this step will happen again at the end of loading. SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); + // Project User Registry is merged after the command line here to allow make sure the any command line override of the project path + // is used for merging the project's user registry SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); #endif + //! Retrieves the list gem targets that the project has load dependencies on + //! This populates the /Amazon/Gems//SourcePaths array entries which is required + //! by the MergeSettingsToRegistry_GemRegistry() function below to locate the gem's root folder + //! and merge in the gem's registry files. + //! But when running from a pre-built app from the O3DE SDK(Editor/AssetProcessor), the projects binary + //! directory is needed in order to located the load dependency registry files + //! That project binary folder is generated with the /user/Registry when CMake is configured + //! for the project + //! Therefore the order of merging must be as follows + //! 1. MergeSettingsToRegistry_ProjectUserRegistry - Populates the /Amazon/Project/Settings/Build/project_build_path + //! which contains the path to the project binary directory + //! 2. MergeSettingsToRegistry_TargetBuildDependencyRegistry - Loads the cmake_dependencies...setreg + //! file from the locations in order of + //! 1. /Registry + //! 2. /Registry + //! 3. /bin/$/Registry + //! 3. MergeSettingsToRegistry_GemRegistries - Merges the settings registry files from each gem's /Registry directory + + SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, + AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_EngineRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_GemRegistries(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true); #endif // Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); } void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations) diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp index 56dfbdcb71..bd73162498 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp @@ -599,6 +599,34 @@ namespace AZ::SettingsRegistryMergeUtils ? devWriteStorage.value() : projectUserPath.Native()); + // Set the project in-memory build path if the ProjectBuildPath key has been supplied + if (AZ::IO::FixedMaxPath projectBuildPath; registry.Get(projectBuildPath.Native(), ProjectBuildPath)) + { + registry.Remove(FilePathKey_ProjectBuildPath); + registry.Remove(FilePathKey_ProjectConfigurationBinPath); + AZ::IO::FixedMaxPath buildConfigurationPath = normalizedProjectPath / projectBuildPath; + if (IO::SystemFile::Exists(buildConfigurationPath.c_str())) + { + registry.Set(FilePathKey_ProjectBuildPath, buildConfigurationPath.LexicallyNormal().Native()); + } + + // Add the specific build configuration paths to the Settings Registry + // First try /bin/$ and if that path doesn't exist + // try /bin/$/$ + buildConfigurationPath /= "bin"; + if (IO::SystemFile::Exists((buildConfigurationPath / AZ_BUILD_CONFIGURATION_TYPE).c_str())) + { + registry.Set(FilePathKey_ProjectConfigurationBinPath, + (buildConfigurationPath / AZ_BUILD_CONFIGURATION_TYPE).LexicallyNormal().Native()); + } + else if (IO::SystemFile::Exists((buildConfigurationPath / AZ_TRAIT_OS_PLATFORM_CODENAME / AZ_BUILD_CONFIGURATION_TYPE).c_str())) + { + registry.Set(FilePathKey_ProjectConfigurationBinPath, + (buildConfigurationPath / AZ_TRAIT_OS_PLATFORM_CODENAME / AZ_BUILD_CONFIGURATION_TYPE).LexicallyNormal().Native()); + } + + } + // Project name - if it was set via merging project.json use that value, otherwise use the project path's folder name. auto projectNameKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) @@ -689,6 +717,14 @@ namespace AZ::SettingsRegistryMergeUtils mergePath /= SettingsRegistryInterface::RegistryFolder; registry.MergeSettingsFolder(mergePath.Native(), specializations, platform, "", scratchBuffer); } + + AZ::IO::FixedMaxPath projectBinPath; + if (registry.Get(projectBinPath.Native(), FilePathKey_ProjectConfigurationBinPath)) + { + // Append the project build path path to the project root + projectBinPath /= SettingsRegistryInterface::RegistryFolder; + registry.MergeSettingsFolder(projectBinPath.Native(), specializations, platform, "", scratchBuffer); + } } void MergeSettingsToRegistry_EngineRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform, @@ -934,7 +970,8 @@ namespace AZ::SettingsRegistryMergeUtils "project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}, OptionKeyToRegsetKey{ "project-cache-path", - AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}}; + AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}, + OptionKeyToRegsetKey{"project-build-path", ProjectBuildPath} }; AZStd::fixed_vector overrideArgs; diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h index 4e00c0e6ec..576066c29f 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h @@ -52,6 +52,14 @@ namespace AZ::SettingsRegistryMergeUtils //! project settings can be stored inline static constexpr char FilePathKey_ProjectUserPath[] = "/Amazon/AzCore/Runtime/FilePaths/SourceProjectUserPath"; + //! User facing key which represents the root of a project cmake build tree. i.e the ${CMAKE_BINARY_DIR} + //! A relative path is taking relative to the *project* root, NOT *engine* root. + inline constexpr AZStd::string_view ProjectBuildPath = "/Amazon/Project/Settings/Build/project_build_path"; + //! In-Memory only key which stores an absolute path to the project build directory + inline constexpr AZStd::string_view FilePathKey_ProjectBuildPath = "/Amazon/AzCore/Runtime/FilePaths/ProjectBuildPath"; + //! In-Memory only key which stores the configuration directory containing the built binaries + inline constexpr AZStd::string_view FilePathKey_ProjectConfigurationBinPath = "/Amazon/AzCore/Runtime/FilePaths/ProjectConfigurationBinPath"; + //! Development write storage path may be considered temporary or cache storage on some platforms inline static constexpr char FilePathKey_DevWriteStorage[] = "/Amazon/AzCore/Runtime/FilePaths/DevWriteStorage"; @@ -128,7 +136,7 @@ namespace AZ::SettingsRegistryMergeUtils //! Callback function that is after a has been filtered through the CommentPrefixFunc //! to determine if the text matches a section header //! returns a view of the section name if the line contains a section - //! Otherwise an empty view is returend + //! Otherwise an empty view is returned using SectionHeaderFunc = AZStd::function; //! Root JSON pointer path to place all key=values pairs of configuration data within diff --git a/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp b/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp index 169a4db6ff..30ec08538a 100644 --- a/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp +++ b/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp @@ -17,8 +17,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { + return {}; } void* OpenModule(const AZ::OSString& fileName, bool&) @@ -26,10 +27,9 @@ namespace AZ // Android 19 does not have RTLD_NOLOAD but it should be OK since only the Editor expects to reopen modules return dlopen(fileName.c_str(), RTLD_NOW); } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp index 8457ff14a6..7dd889e94d 100644 --- a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp +++ b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - path = exePath; - path.push_back('/'); - } + return AZ::Utils::GetExecutableDirectory(); } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,9 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp index 1c16f50203..8e2b40aaca 100644 --- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp +++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp @@ -11,9 +11,11 @@ */ #include -#include // for AZ_MAX_PATH_LEN +#include +#include #include +#include #include #include @@ -21,9 +23,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path); + AZ::IO::FixedMaxPath GetModulePath(); void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen); - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath); + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath& fullPath); } class DynamicModuleHandleUnixLike @@ -36,40 +38,55 @@ namespace AZ : DynamicModuleHandle(fullFileName) , m_handle(nullptr) { - AZ::OSString path; - AZ::OSString fileName; - AZ::OSString fullPath = ""; - AZ::OSString::size_type finalSlash = m_fileName.find_last_of("/"); - if (finalSlash != AZ::OSString::npos) + AZ::IO::FixedMaxPath fullFilePath(AZStd::string_view{m_fileName}); + if (fullFilePath.HasFilename()) { - // Path up to and including final slash - path = m_fileName.substr(0, finalSlash + 1); - // Everything after the final slash - // If m_fileName ends in /, the end result is path/lib.dylib, which just fails to load. - fileName = m_fileName.substr(finalSlash + 1); - } - else - { - // If no slash found, assume empty path, only file name - path = ""; - Platform::GetModulePath(path); - fileName = m_fileName; + AZ::IO::FixedMaxPathString fileNamePath{fullFilePath.Filename().Native()}; + if (!fileNamePath.starts_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX)) + { + fileNamePath = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX + fileNamePath; + } + + if (!fileNamePath.ends_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION)) + { + fileNamePath += AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + } + + fullFilePath.ReplaceFilename(AZStd::string_view(fileNamePath)); } - if (fileName.substr(0, 3) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX) + Platform::ConstructModuleFullFileName(fullFilePath); + + // Check if the module exist at the given path within the current working directory + // If it doesn't attempt to append the path to the executable path + if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str())) { - fileName = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX + fileName; + auto candidatePath = Platform::GetModulePath() / fullFilePath; + if (AZ::IO::SystemFile::Exists(candidatePath.c_str())) + { + fullFilePath = candidatePath; + } } - size_t extensionLen = strlen(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION); - if (fileName.substr(fileName.length() - extensionLen, extensionLen) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION) + // If the path still doesn't exist at this point, check the SettingsRegistryMergeUtils + // FilePathKey_ProjectBuildPath key to see if a project-build-path argument has been supplied + if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str())) { - fileName = fileName + AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + if(AZ::IO::FixedMaxPath projectModulePath; + settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath)) + { + projectModulePath /= fullFilePath; + if (AZ::IO::SystemFile::Exists(projectModulePath.c_str())) + { + fullFilePath = projectModulePath; + } + } + } } - - Platform::ConstructModuleFullFileName(path, fileName, fullPath); - m_fileName = fullPath; + m_fileName = AZStd::string_view{fullFilePath.Native()}; } ~DynamicModuleHandleUnixLike() override @@ -81,9 +98,9 @@ namespace AZ { AZ::Debug::Trace::Printf("Module", "Attempting to load module:%s\n", m_fileName.c_str()); bool alreadyOpen = false; - + m_handle = Platform::OpenModule(m_fileName, alreadyOpen); - + if(m_handle) { if (alreadyOpen) diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp index 49d5360faa..9daabfb86b 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace AZ @@ -31,13 +32,13 @@ namespace AZ { // Ensure filename ends in ".dll" // Otherwise filenames like "gem.1.0.0" fail to load (.0 is assumed to be the extension). - if (m_fileName.substr(m_fileName.length() - 4) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION) + if (!m_fileName.ends_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION)) { - m_fileName = m_fileName + AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + m_fileName += AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; } AZ::IO::PathView modulePathView{ m_fileName }; - // If the module path doesn't have a directory within it, prepend it to the path + // If the module path doesn't have a directory within it, prepend the executable directory to the path // and check if the new path exist if (modulePathView.HasFilename() && !modulePathView.HasParentPath()) { @@ -54,6 +55,27 @@ namespace AZ } } } + + // If the module file path does not exist, attempt to search for the module within + // the project's build directory + if (!AZ::IO::SystemFile::Exists(m_fileName.c_str())) + { + // The Settings Registry may not exist in early startup if modules are loaded + // before the ComponentApplication is crated(such as in the Editor main.cpp) + // Therefore an existence check is needed + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + if(AZ::IO::FixedMaxPath projectModulePath; + settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath)) + { + projectModulePath /= AZStd::string_view(m_fileName); + if (AZ::IO::SystemFile::Exists(projectModulePath.c_str())) + { + m_fileName.assign(projectModulePath.c_str(), projectModulePath.Native().size()); + } + } + } + } } ~DynamicModuleHandleWindows() override diff --git a/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp b/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp index 8457ff14a6..7dd889e94d 100644 --- a/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp +++ b/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - path = exePath; - path.push_back('/'); - } + return AZ::Utils::GetExecutableDirectory(); } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,9 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp b/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp index 8a082a01a6..569aae6f53 100644 --- a/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp +++ b/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - AZ::OSString frameworks = "/Frameworks/"; - path = exePath + frameworks; - } + return AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / "Frameworks"; } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,15 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath& fullPath) { - fullPath = path + fileName + ".framework/" + fileName; + // Append .framework to the name of full path + // Afterwards use the AZ::IO::Path Append function append the filename as a child + // of the framework directory + AZ::IO::FixedMaxPathString fileName = fullPath.Filename().Native(); + fullPath.ReplaceFilename(fileName + ".framework"); + fullPath /= fileName; } } } diff --git a/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp b/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp index edd4af293d..1fb440e6e5 100644 --- a/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp +++ b/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp @@ -57,13 +57,16 @@ namespace AzGameFramework AZStd::vector scratchBuffer; - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); #endif + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + // Used the lowercase the platform name since the bootstrap.game...setreg is being loaded // from the asset cache root where all the files are in lowercased from regardless of the filesystem case-sensitivity static constexpr char filename[] = "bootstrap.game." AZ_BUILD_CONFIGURATION_TYPE "." AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER ".setreg"; @@ -77,6 +80,7 @@ namespace AzGameFramework #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true); #endif diff --git a/Code/Tools/AssetProcessor/native/InternalBuilders/SettingsRegistryBuilder.cpp b/Code/Tools/AssetProcessor/native/InternalBuilders/SettingsRegistryBuilder.cpp index 37c8d0adee..523e39d622 100644 --- a/Code/Tools/AssetProcessor/native/InternalBuilders/SettingsRegistryBuilder.cpp +++ b/Code/Tools/AssetProcessor/native/InternalBuilders/SettingsRegistryBuilder.cpp @@ -297,20 +297,28 @@ namespace AssetProcessor AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, platform, specialization, &scratchBuffer); // Merge the Project User and User home settings registry only in non-release builds + constexpr bool executeRegDumpCommands = false; + AZ::CommandLine* commandLine{}; + AZ::ComponentApplicationBus::Broadcast([®istry, &commandLine](AZ::ComponentApplicationRequests* appRequests) + { + commandLine = appRequests->GetAzCommandLine(); + }); + if (!specialization.Contains("release")) { AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, platform, specialization, &scratchBuffer); + if (commandLine) + { + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands); + } AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, platform, specialization, &scratchBuffer); } - AZ::ComponentApplicationBus::Broadcast([®istry](AZ::ComponentApplicationRequests* appRequests) + if (commandLine) { - if (AZ::CommandLine* commandLine = appRequests->GetAzCommandLine(); commandLine != nullptr) - { - constexpr bool executeRegDumpCommands = false; - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands); - } - }); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, *commandLine, executeRegDumpCommands); + } + if (registry.Visit(exporter, "")) { diff --git a/Registry/application_options.setreg b/Registry/application_options.setreg index 06ccdc9b41..8dbb6fe418 100644 --- a/Registry/application_options.setreg +++ b/Registry/application_options.setreg @@ -6,6 +6,7 @@ "project-path", "engine-path", "project-cache-path", + "project-build-path", "regset", "regremove", "regdump", diff --git a/cmake/Projects.cmake b/cmake/Projects.cmake index 139c2a24d1..781fee3711 100644 --- a/cmake/Projects.cmake +++ b/cmake/Projects.cmake @@ -105,9 +105,54 @@ function(ly_add_project_dependencies) ) endfunction() +#template for generating the project build_path setreg +set(project_build_path_template [[ +{ + "Amazon": { + "Project": { + "Settings": { + "Build": { + "project_build_path": "@project_bin_path@" + } + } + } + } +}]] +) + + +#! ly_generate_project_build_path_setreg: Generates a .setreg file that contains an absolute path to the ${CMAKE_BINARY_DIR} +# This allows locate the directory where the project it's binaries are built to be located within the engine. +# Which are the shared libraries and launcher executables +# When an a pre-built engine application runs from a directory other than the project build directory, it needs +# to be able to locate the project build directory to determine the list of gems that the project depends on to load +# as well the location of those gems. +# For example if the project uses an external gem not associated with the engine, that gem's dlls/so/dylib files +# would be located within the project build directory and the engine SDK binary directory would need that info + +# NOTE: This only needed for non-monolithic host platforms. +# This is because there are no dynamic gems to load on monolithic builds +# Furthermore the pre-built SDK engine applications such as the Editor and AssetProcessor +# can only run on the host platform +# \arg:project_real_path Full path to the o3de project directory +function(ly_generate_project_build_path_setreg project_real_path) + # The build path isn't needed on non-monolithic platforms + # Nor on any non-host platforms + if (LY_MONOLITHIC_GAME OR NOT PAL_TRAIT_BUILD_HOST_TOOLS) + return() + endif() + + # Set the project_bin_path to the ${CMAKE_BINARY_DIR} to provide the configure template + # with the project build directory + set(project_bin_path ${CMAKE_BINARY_DIR}) + string(CONFIGURE ${project_build_path_template} project_build_path_setreg_content @ONLY) + set(project_user_build_path_setreg_file ${project_real_path}/user/Registry/Platform/${PAL_PLATFORM_NAME}/build_path.setreg) + file(GENERATE OUTPUT ${project_user_build_path_setreg_file} CONTENT ${project_build_path_setreg_content}) +endfunction() + # Add the projects here so the above function is found foreach(project ${LY_PROJECTS}) - get_filename_component(full_directory_path ${project} REALPATH ${CMAKE_SOURCE_DIR}) + file(REAL_PATH ${project} full_directory_path BASE_DIRECTORY ${CMAKE_SOURCE_DIR}) string(SHA256 full_directory_hash ${full_directory_path}) # Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit @@ -117,5 +162,6 @@ foreach(project ${LY_PROJECTS}) get_filename_component(project_folder_name ${project} NAME) list(APPEND LY_PROJECTS_FOLDER_NAME ${project_folder_name}) add_subdirectory(${project} "${project_folder_name}-${full_directory_hash}") + ly_generate_project_build_path_setreg(${full_directory_path}) endforeach() ly_set(LY_PROJECTS_FOLDER_NAME ${LY_PROJECTS_FOLDER_NAME}) From 883786796d759532d8604a385518419d0285bf70 Mon Sep 17 00:00:00 2001 From: Aaron Ruiz Mora Date: Fri, 14 May 2021 19:10:58 +0100 Subject: [PATCH 209/225] [NvCloth] Replace legacy IsDedicated() call with new AZ_CVAR sv_isDedicated --- Gems/NvCloth/Code/CMakeLists.txt | 6 +- .../Code/Source/Components/ClothComponent.cpp | 13 ++-- Gems/NvCloth/Code/Source/Module.cpp | 31 -------- .../Tests/Components/ClothComponentTest.cpp | 70 ++++++++----------- 4 files changed, 37 insertions(+), 83 deletions(-) diff --git a/Gems/NvCloth/Code/CMakeLists.txt b/Gems/NvCloth/Code/CMakeLists.txt index d83190a05c..0f019a985f 100644 --- a/Gems/NvCloth/Code/CMakeLists.txt +++ b/Gems/NvCloth/Code/CMakeLists.txt @@ -30,11 +30,7 @@ ly_add_target( BUILD_DEPENDENCIES PUBLIC 3rdParty::NvCloth - # CryCommon required for 'gEnv->IsDedicated()'. - # Because of this the module will need CrySystemEventBus to initialize gEnv - # and tests targets will need to fake gEnv. To be removed when there is - # an AZ replacement for asking if the game is running on a server or not. - Legacy::CryCommon + AZ::AzFramework Gem::AtomLyIntegration_CommonFeatures.Public PRIVATE Gem::EMotionFXStaticLib diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp index 912255c798..0170fd65bd 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponent.cpp @@ -10,9 +10,8 @@ * */ -#include - #include +#include #include @@ -55,10 +54,14 @@ namespace NvCloth void ClothComponent::Activate() { // Cloth components do not run on dedicated servers. - AZ_Assert(gEnv, "Environment not ready"); - if (gEnv->IsDedicated()) + if (auto* console = AZ::Interface::Get()) { - return; + bool isDedicated = false; + if (const auto result = console->GetCvarValue("sv_isDedicated", isDedicated); + result == AZ::GetValueResult::Success && isDedicated) + { + return; + } } AZ::Render::MeshComponentNotificationBus::Handler::BusConnect(GetEntityId()); diff --git a/Gems/NvCloth/Code/Source/Module.cpp b/Gems/NvCloth/Code/Source/Module.cpp index 08d673fd07..66390dda86 100644 --- a/Gems/NvCloth/Code/Source/Module.cpp +++ b/Gems/NvCloth/Code/Source/Module.cpp @@ -10,9 +10,6 @@ * */ -#include -#include - #include #include @@ -31,7 +28,6 @@ namespace NvCloth { class Module : public AZ::Module - , protected CrySystemEventBus::Handler { public: AZ_RTTI(Module, "{34C529D4-688F-4B51-BF60-75425754A7E6}", AZ::Module); @@ -47,8 +43,6 @@ namespace NvCloth m_fabricCooker = AZStd::make_unique(); m_tangentSpaceHelper = AZStd::make_unique(); - CrySystemEventBus::Handler::BusConnect(); - // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. m_descriptors.insert(m_descriptors.end(), { SystemComponent::CreateDescriptor(), @@ -64,8 +58,6 @@ namespace NvCloth ~Module() { - CrySystemEventBus::Handler::BusDisconnect(); - m_tangentSpaceHelper.reset(); m_fabricCooker.reset(); @@ -85,33 +77,10 @@ namespace NvCloth }; } - protected: - // CrySystemEventBus ... - void OnCrySystemPreInitialize(ISystem& system, const SSystemInitParams& systemInitParams) override; - void OnCrySystemPostShutdown() override; - private: AZStd::unique_ptr m_fabricCooker; AZStd::unique_ptr m_tangentSpaceHelper; }; - - void Module::OnCrySystemPreInitialize( - [[maybe_unused]] ISystem& system, - [[maybe_unused]] const SSystemInitParams& systemInitParams) - { -#if !defined(AZ_MONOLITHIC_BUILD) - // When module is linked dynamically, we must set our gEnv pointer. - // When module is linked statically, we'll share the application's gEnv pointer. - gEnv = system.GetGlobalEnvironment(); -#endif - } - - void Module::OnCrySystemPostShutdown() - { -#if !defined(AZ_MONOLITHIC_BUILD) - gEnv = nullptr; -#endif - } } // namespace NvCloth // DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM diff --git a/Gems/NvCloth/Code/Tests/Components/ClothComponentTest.cpp b/Gems/NvCloth/Code/Tests/Components/ClothComponentTest.cpp index 379cf6988d..ad37c8f079 100644 --- a/Gems/NvCloth/Code/Tests/Components/ClothComponentTest.cpp +++ b/Gems/NvCloth/Code/Tests/Components/ClothComponentTest.cpp @@ -12,8 +12,6 @@ #include -#include - #include #include #include @@ -25,48 +23,14 @@ namespace UnitTest { - //! Sets up a mock global environment to - //! change between server and client. class NvClothComponent : public ::testing::Test { - public: - static void SetUpTestCase(); - static void TearDownTestCase(); - protected: AZStd::unique_ptr CreateClothActorEntity(const NvCloth::ClothConfiguration& clothConfiguration); bool IsConnectedToMeshComponentNotificationBus(NvCloth::ClothComponent* clothComponent) const; - - private: - static AZStd::unique_ptr s_mockGEnv; - static SSystemGlobalEnvironment* s_previousGEnv; }; - AZStd::unique_ptr NvClothComponent::s_mockGEnv; - SSystemGlobalEnvironment* NvClothComponent::s_previousGEnv = nullptr; - - void NvClothComponent::SetUpTestCase() - { - // override global environment - s_previousGEnv = gEnv; - s_mockGEnv = AZStd::make_unique(); - gEnv = s_mockGEnv.get(); - -#if !defined(CONSOLE) - // Set environment to not be a server by default. - gEnv->SetIsDedicated(false); -#endif - } - - void NvClothComponent::TearDownTestCase() - { - // restore global environment - gEnv = s_previousGEnv; - s_mockGEnv.reset(); - s_previousGEnv = nullptr; - } - AZStd::unique_ptr NvClothComponent::CreateClothActorEntity(const NvCloth::ClothConfiguration& clothConfiguration) { AZStd::unique_ptr entity = AZStd::make_unique(); @@ -101,10 +65,35 @@ namespace UnitTest EXPECT_TRUE(sortOutcome.IsSuccess()); } -#if !defined(CONSOLE) - TEST_F(NvClothComponent, ClothComponent_OnServer_DoesNotConnectToMeshComponentNotificationBusOnActivation) + TEST_F(NvClothComponent, ClothComponent_WithoutMultiplayerGem_ConnectsToMeshComponentNotificationBusOnActivation) { - gEnv->SetIsDedicated(true); + AZStd::unique_ptr entity = CreateClothActorEntity({}); + entity->Activate(); + + auto* clothComponent = entity->FindComponent(); + + EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent)); + } + + TEST_F(NvClothComponent, ClothComponent_WithMultiplayerGem_Game_ConnectsToMeshComponentNotificationBusOnActivation) + { + // Fake that multiplayer gem is enabled by creating a local sv_isDedicated AZ_CVAR + AZ::ConsoleDataWrapper> sv_isDedicated(false, + nullptr, "sv_isDedicated", "", AZ::ConsoleFunctorFlags::DontReplicate); + + AZStd::unique_ptr entity = CreateClothActorEntity({}); + entity->Activate(); + + auto* clothComponent = entity->FindComponent(); + + EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent)); + } + + TEST_F(NvClothComponent, ClothComponent_WithMultiplayerGem_Server_DoesNotConnectToMeshComponentNotificationBusOnActivation) + { + // Fake that multiplayer gem is enabled by creating a local sv_isDedicated AZ_CVAR + AZ::ConsoleDataWrapper> sv_isDedicated(true, + nullptr, "sv_isDedicated", "", AZ::ConsoleFunctorFlags::DontReplicate); AZStd::unique_ptr entity = CreateClothActorEntity({}); entity->Activate(); @@ -112,10 +101,7 @@ namespace UnitTest auto* clothComponent = entity->FindComponent(); EXPECT_FALSE(IsConnectedToMeshComponentNotificationBus(clothComponent)); - - gEnv->SetIsDedicated(false); } -#endif TEST_F(NvClothComponent, ClothComponent_OneEntityWithTwoClothComponents_BothConnectToMeshComponentNotificationBusOnActivation) { From f759f471bffa4041192eb8704ac94d8d7a42aa9d Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Fri, 14 May 2021 11:15:52 -0700 Subject: [PATCH 210/225] Remove unused code --- cmake/Tools/registration.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cmake/Tools/registration.py b/cmake/Tools/registration.py index 04b6f61496..184d2cdb31 100755 --- a/cmake/Tools/registration.py +++ b/cmake/Tools/registration.py @@ -258,13 +258,6 @@ def register_shipped_engine_o3de_objects() -> int: if error_code: ret_val = error_code - starting_external_subdirectories = [ - ] - for external_subdir in sorted(starting_external_subdirectories, reverse=True): - error_code = add_external_subdirectory(engine_path=engine_path, external_subdir=external_subdir) - if error_code: - ret_val = error_code - json_data = load_o3de_manifest() engine_object = find_engine_data(json_data) gems = json_data['gems'].copy() From 1a456cc9b9545455c2ee04316b46b8f0478f34ca Mon Sep 17 00:00:00 2001 From: srikappa Date: Fri, 14 May 2021 11:48:31 -0700 Subject: [PATCH 211/225] Marked an our parameter correctly and changed a ref to const ref --- .../AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h | 2 +- .../AzToolsFramework/Prefab/PrefabPublicHandler.cpp | 2 +- .../AzToolsFramework/Prefab/PrefabPublicHandler.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index 6f7d2fe9b1..5ee91c85ae 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -103,7 +103,7 @@ namespace AzToolsFramework /** * Gets a set of all the template source paths in the given dom. * @param prefabDom The DOM to get the template source paths from. - * @param templateSourcePaths The set of template source paths to populate. + * @param[out] templateSourcePaths The set of template source paths to populate. */ void GetTemplateSourcePaths(const PrefabDomValue& prefabDom, AZStd::unordered_set& templateSourcePaths); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index e2c616d5d8..c4fe97bf11 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -282,7 +282,7 @@ namespace AzToolsFramework } bool PrefabPublicHandler::IsCyclicalDependencyFound( - InstanceOptionalConstReference instance, AZStd::unordered_set& templateSourcePaths) + InstanceOptionalConstReference instance, const AZStd::unordered_set& templateSourcePaths) { InstanceOptionalConstReference currentInstance = instance; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 519c7ca53f..fb3c3462d8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -114,7 +114,7 @@ namespace AzToolsFramework * \return true if any of the template source paths could be found in the ancestor hierarchy of instance, false otherwise. */ bool IsCyclicalDependencyFound( - InstanceOptionalConstReference instance, AZStd::unordered_set& templateSourcePaths); + InstanceOptionalConstReference instance, const AZStd::unordered_set& templateSourcePaths); static Instance* GetParentInstance(Instance* instance); static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant); From 58759bddf7f8e009900c17498be12cb7e4250aa3 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Fri, 14 May 2021 12:36:40 -0700 Subject: [PATCH 212/225] Tidy up Script/ScriptTimePoint --- .../AzCore/AzCore/Script/ScriptTimePoint.h | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h b/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h index 08c997de2d..41d80f42a3 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h +++ b/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h @@ -24,9 +24,7 @@ namespace AZ AZ_TYPE_INFO_SPECIALIZE(AZStd::chrono::system_clock::time_point, "{5C48FD59-7267-405D-9C06-1EA31379FE82}"); - /** - * Wrapper that reflects a AZStd::chrono::system_clock::time_point to script. - */ + //! Wrapper that reflects a AZStd::chrono::system_clock::time_point to script. class ScriptTimePoint { public: @@ -38,33 +36,45 @@ namespace AZ explicit ScriptTimePoint(AZStd::chrono::system_clock::time_point timePoint) : m_timePoint(timePoint) {} - AZStd::string ToString() const - { - return AZStd::string::format("Time %llu", m_timePoint.time_since_epoch().count()); - } + //! Formats the time point in a string formatted as: "Time ". + AZStd::string ToString() const; - const AZStd::chrono::system_clock::time_point& Get() const { return m_timePoint; } + //! Returns the time point. + const AZStd::chrono::system_clock::time_point& Get() const; - // Returns the time point in seconds - double GetSeconds() const - { - typedef AZStd::chrono::duration double_seconds; - return AZStd::chrono::duration_cast(m_timePoint.time_since_epoch()).count(); - } + //! Returns the time point in seconds + double GetSeconds() const; - // Returns the time point in milliseconds - double GetMilliseconds() const - { - typedef AZStd::chrono::duration double_ms; - return AZStd::chrono::duration_cast(m_timePoint.time_since_epoch()).count(); - } + //! Returns the time point in milliseconds + double GetMilliseconds() const; static void Reflect(ReflectContext* reflection); protected: - AZStd::chrono::system_clock::time_point m_timePoint; }; + + inline AZStd::string ScriptTimePoint::ToString() const + { + return AZStd::string::format("Time %llu", m_timePoint.time_since_epoch().count()); + } + + inline const AZStd::chrono::system_clock::time_point& ScriptTimePoint::Get() const + { + return m_timePoint; + } + + inline double ScriptTimePoint::GetSeconds() const + { + typedef AZStd::chrono::duration double_seconds; + return AZStd::chrono::duration_cast(m_timePoint.time_since_epoch()).count(); + } + + inline double ScriptTimePoint::GetMilliseconds() const + { + typedef AZStd::chrono::duration double_ms; + return AZStd::chrono::duration_cast(m_timePoint.time_since_epoch()).count(); + } } From f7a9b28000d78c509cabc38b103d2f1de1845229 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Fri, 14 May 2021 12:37:35 -0700 Subject: [PATCH 213/225] Make AtomFont's API use copy semantics for string_view --- .../AzFramework/Font/FontInterface.h | 30 +++++++++---------- .../AtomLyIntegration/AtomFont/FFont.h | 8 ++--- .../AtomFont/Code/Source/FFont.cpp | 22 +++++++------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h b/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h index 48fa5bc2d2..b64b61e22c 100644 --- a/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h +++ b/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h @@ -40,18 +40,18 @@ namespace AzFramework //! Standard parameters for drawing text on screen struct TextDrawParameters { - ViewportId m_drawViewportId = InvalidViewportId; //! Viewport to draw into - AZ::Vector3 m_position; //! world space position for 3d draws, screen space x,y,depth for 2d. - AZ::Color m_color = AZ::Colors::White; //! Color to draw the text - AZ::Vector2 m_scale = AZ::Vector2(1.0f); //! font scale - float m_lineSpacing; //! Spacing between new lines, as a percentage of m_scale. - TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //! Horizontal text alignment - TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //! Vertical text alignment - bool m_monospace = false; //! disable character proportional spacing - bool m_depthTest = false; //! Test character against the depth buffer - bool m_virtual800x600ScreenSize = true; //! Text placement and size are scaled relative to a virtual 800x600 resolution - bool m_scaleWithWindow = false; //! Font gets bigger as the window gets bigger - bool m_multiline = true; //! text respects ascii newline characters + ViewportId m_drawViewportId = InvalidViewportId; //!< Viewport to draw into + AZ::Vector3 m_position; //!< world space position for 3d draws, screen space x,y,depth for 2d. + AZ::Color m_color = AZ::Colors::White; //!< Color to draw the text + AZ::Vector2 m_scale = AZ::Vector2(1.0f); //!< font scale + float m_lineSpacing; //!< Spacing between new lines, as a percentage of m_scale. + TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //!< Horizontal text alignment + TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //!< Vertical text alignment + bool m_monospace = false; //!< disable character proportional spacing + bool m_depthTest = false; //!< Test character against the depth buffer + bool m_virtual800x600ScreenSize = true; //!< Text placement and size are scaled relative to a virtual 800x600 resolution + bool m_scaleWithWindow = false; //!< Font gets bigger as the window gets bigger + bool m_multiline = true; //!< text respects ascii newline characters }; class FontDrawInterface @@ -64,13 +64,13 @@ namespace AzFramework virtual void DrawScreenAlignedText2d( const TextDrawParameters& params, - const AZStd::string_view& string) = 0; + AZStd::string_view text) = 0; virtual void DrawScreenAlignedText3d( const TextDrawParameters& params, - const AZStd::string_view& string) = 0; + AZStd::string_view text) = 0; virtual AZ::Vector2 GetTextSize( const TextDrawParameters& params, - const AZStd::string_view& string) = 0; + AZStd::string_view text) = 0; }; class FontQueryInterface diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h index 84d53a5446..1e224d6090 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h +++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h @@ -207,15 +207,15 @@ namespace AZ // AzFramework::FontDrawInterface implementation void DrawScreenAlignedText2d( const AzFramework::TextDrawParameters& params, - const AZStd::string_view& string) override; + AZStd::string_view text) override; void DrawScreenAlignedText3d( const AzFramework::TextDrawParameters& params, - const AZStd::string_view& string) override; + AZStd::string_view text) override; AZ::Vector2 GetTextSize( const AzFramework::TextDrawParameters& params, - const AZStd::string_view& string) override; + AZStd::string_view text) override; public: FFont(AtomFont* atomFont, const char* fontName); @@ -294,7 +294,7 @@ namespace AZ AZ::RPI::ViewportContextPtr m_viewportContext; const AZ::RHI::Viewport* m_viewport; }; - DrawParameters ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize); + DrawParameters ExtractDrawParameters(const AzFramework::TextDrawParameters& params, AZStd::string_view text, bool forceCalculateSize); private: static constexpr uint32_t NumBuffers = 2; diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp index cc14014e48..21b57e0908 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp @@ -1675,11 +1675,11 @@ static void SetCommonContextFlags(AZ::TextDrawContext& ctx, const AzFramework::T } } -AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize) +AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::TextDrawParameters& params, AZStd::string_view text, bool forceCalculateSize) { DrawParameters internalParams; if (params.m_drawViewportId == AzFramework::InvalidViewportId || - string.empty()) + text.empty()) { return internalParams; } @@ -1711,7 +1711,7 @@ AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::Te params.m_vAlign != AzFramework::TextVerticalAlignment::Top || forceCalculateSize) { - Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, internalParams.m_ctx); + Vec2 textSize = GetTextSizeUInternal(viewport, text.data(), params.m_multiline, internalParams.m_ctx); // If we're using virtual 800x600 coordinates, convert the text size from // pixels to that before using it as an offset. if (internalParams.m_ctx.m_sizeIn800x600) @@ -1750,9 +1750,9 @@ AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::Te void AZ::FFont::DrawScreenAlignedText2d( const AzFramework::TextDrawParameters& params, - const AZStd::string_view& string) + AZStd::string_view text) { - DrawParameters internalParams = ExtractDrawParameters(params, string, false); + DrawParameters internalParams = ExtractDrawParameters(params, text, false); if (!internalParams.m_viewportContext) { return; @@ -1764,7 +1764,7 @@ void AZ::FFont::DrawScreenAlignedText2d( internalParams.m_position.GetX(), internalParams.m_position.GetY(), params.m_position.GetZ(), // Z - string.data(), + text.data(), params.m_multiline, internalParams.m_ctx ); @@ -1772,9 +1772,9 @@ void AZ::FFont::DrawScreenAlignedText2d( void AZ::FFont::DrawScreenAlignedText3d( const AzFramework::TextDrawParameters& params, - const AZStd::string_view& string) + AZStd::string_view text) { - DrawParameters internalParams = ExtractDrawParameters(params, string, false); + DrawParameters internalParams = ExtractDrawParameters(params, text, false); if (!internalParams.m_viewportContext) { return; @@ -1798,15 +1798,15 @@ void AZ::FFont::DrawScreenAlignedText3d( internalParams.m_position.GetX(), internalParams.m_position.GetY(), params.m_position.GetZ(), // Z - string.data(), + text.data(), params.m_multiline, internalParams.m_ctx ); } -AZ::Vector2 AZ::FFont::GetTextSize(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string) +AZ::Vector2 AZ::FFont::GetTextSize(const AzFramework::TextDrawParameters& params, AZStd::string_view text) { - DrawParameters sizeParams = ExtractDrawParameters(params, string, true); + DrawParameters sizeParams = ExtractDrawParameters(params, text, true); return sizeParams.m_size; } From 810c63b80e687f9fcfe20c47ee00687db8f973e1 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Fri, 14 May 2021 12:38:01 -0700 Subject: [PATCH 214/225] Streamline AtomLyIntegration/AtomViewportDisplayInfo/gem.json --- .../AtomViewportDisplayInfo/gem.json | 38 +++++-------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json index a54dc188a7..dd92a99ea9 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json @@ -1,32 +1,12 @@ { "gem_name": "AtomLyIntegration_AtomViewportDisplayInfo", - "Dependencies": [ - { - "Uuid": "a218db9eb2114477b46600fea4441a6c", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom RPI" - }, - { - "Uuid": "c7ff89ad6e8b4b45b2fadef2bcf12d6e", - "VersionConstraints": [ - "~>0.1.0" - ], - "_comment": "Atom_Bootstrap" - } - ], - "GemFormatVersion": 4, - "Uuid": "7c255c884bae4046b0640abe3c88cc4c", - "Name": "AtomLyIntegration_AtomViewportDisplayInfo", - "DisplayName": "Atom.AtomViewportDisplayInfo", - "Version": "0.1.0", - "Summary": "Provides a diagnostic viewport overlay for the default O3DE Atom viewport.", - "Tags": ["Atom"], - "IconPath": "preview.png", - "Modules": [ - { - "Type": "GameModule" - } + "display_name": "Atom Viewport Display Info Overlay", + "summary": "Provides a diagnostic viewport overlay for the default O3DE Atom viewport.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "AtomLyIntegration", + "AtomViewportDisplayInfo" ] -} +} \ No newline at end of file From a8b29bf603922674a9bdc53bb68b438987d2ad32 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Fri, 14 May 2021 12:38:46 -0700 Subject: [PATCH 215/225] Remove memory info from the overlay for now (depended on the now-dead CryMemoryManager) --- ...AtomViewportDisplayInfoSystemComponent.cpp | 32 ++----------------- .../AtomViewportDisplayInfoSystemComponent.h | 1 - 2 files changed, 3 insertions(+), 30 deletions(-) diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp index ed6b910b76..11c727eeca 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include @@ -149,7 +148,7 @@ namespace AZ::Render { if (auto rootPass = AZ::RPI::PassSystemInterface::Get()->GetRootPass()) { - rootPass->SetPipelineStatisticsQueryEnabled(displayLevel == AtomBridge::ViewportInfoDisplayState::FullInfo); + rootPass->SetPipelineStatisticsQueryEnabled(displayLevel != AtomBridge::ViewportInfoDisplayState::CompactInfo); m_updateRootPassQuery = false; } } @@ -175,11 +174,10 @@ namespace AZ::Render if (displayLevel == AtomBridge::ViewportInfoDisplayState::FullInfo) { DrawCameraInfo(); - DrawPassInfo(); } if (displayLevel != AtomBridge::ViewportInfoDisplayState::CompactInfo) { - DrawMemoryInfo(); + DrawPassInfo(); } DrawFramerate(); } @@ -251,30 +249,6 @@ namespace AZ::Render )); } - void AtomViewportDisplayInfoSystemComponent::DrawMemoryInfo() - { - static IMemoryManager::SProcessMemInfo processMemInfo; - - // Throttle memory usage updates to avoid potentially expensive memory usage API calls every tick. - constexpr AZStd::chrono::duration memoryUpdateInterval = AZStd::chrono::seconds(0.5); - AZStd::chrono::time_point currentTime = m_fpsHistory.back().Get(); - if (m_lastMemoryUpdate.has_value()) - { - if (currentTime - m_lastMemoryUpdate.value() > memoryUpdateInterval) - { - if (auto memoryManager = GetISystem()->GetIMemoryManager()) - { - memoryManager->GetProcessMemInfo(processMemInfo); - } - } - } - m_lastMemoryUpdate = currentTime; - - int peakUsageMB = aznumeric_cast(processMemInfo.PeakPagefileUsage >> 20); - int currentUsageMB = aznumeric_cast(processMemInfo.PagefileUsage >> 20); - DrawLine(AZStd::string::format("Mem=%d Peak=%d", currentUsageMB, peakUsageMB)); - } - void AtomViewportDisplayInfoSystemComponent::UpdateFramerate() { if (!m_tickRequests) @@ -287,7 +261,7 @@ namespace AZ::Render } AZ::ScriptTimePoint currentTime = m_tickRequests->GetTimeAtCurrentTick(); - // Only keep as much sampling data is is required by our FPS history. + // Only keep as much sampling data as is required by our FPS history. while (!m_fpsHistory.empty() && (currentTime.Get() - m_fpsHistory.front().Get()) > m_fpsInterval) { m_fpsHistory.pop_front(); diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h index 08bec4a1d2..135082fd8c 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h @@ -63,7 +63,6 @@ namespace AZ void DrawRendererInfo(); void DrawCameraInfo(); void DrawPassInfo(); - void DrawMemoryInfo(); void DrawFramerate(); AZStd::string m_rendererDescription; From 1426052a5f69ff6ba30dba126216d99bb330b159 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Fri, 14 May 2021 13:01:46 -0700 Subject: [PATCH 216/225] Address a bit more review feedback -Use aznumeric_cast for enum <-> int casts -Short circuit logic a bit more nicely --- Code/Sandbox/Editor/ViewportTitleDlg.cpp | 4 ++-- .../AtomViewportDisplayInfoSystemComponent.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Code/Sandbox/Editor/ViewportTitleDlg.cpp b/Code/Sandbox/Editor/ViewportTitleDlg.cpp index d7c8929540..5ccb83cd5b 100644 --- a/Code/Sandbox/Editor/ViewportTitleDlg.cpp +++ b/Code/Sandbox/Editor/ViewportTitleDlg.cpp @@ -187,8 +187,8 @@ void CViewportTitleDlg::OnToggleDisplayInfo() state, &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::GetDisplayState ); - state = static_cast( - (static_cast(state)+1) % static_cast(AZ::AtomBridge::ViewportInfoDisplayState::Invalid)); + state = aznumeric_cast( + (aznumeric_cast(state)+1) % aznumeric_cast(AZ::AtomBridge::ViewportInfoDisplayState::Invalid)); // SetDisplayState will fire OnViewportInfoDisplayStateChanged and notify us, no need to call UpdateDisplayInfo. AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast( &AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp index 11c727eeca..672c26a9ab 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp @@ -35,7 +35,7 @@ namespace AZ::Render // This callback only gets triggered by console commands, so this will not recurse. AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast( &AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, - static_cast(newDisplayInfoVal) + aznumeric_cast(newDisplayInfoVal) ); }, AZ::ConsoleFunctorFlags::DontReplicate, "Toggles debugging information display.\n" @@ -184,12 +184,12 @@ namespace AZ::Render AtomBridge::ViewportInfoDisplayState AtomViewportDisplayInfoSystemComponent::GetDisplayState() const { - return static_cast(r_displayInfo.operator int()); + return aznumeric_cast(r_displayInfo.operator int()); } void AtomViewportDisplayInfoSystemComponent::SetDisplayState(AtomBridge::ViewportInfoDisplayState state) { - r_displayInfo = static_cast(state); + r_displayInfo = aznumeric_cast(state); AtomBridge::AtomViewportInfoDisplayNotificationBus::Broadcast( &AtomBridge::AtomViewportInfoDisplayNotificationBus::Events::OnViewportInfoDisplayStateChanged, state); @@ -254,10 +254,10 @@ namespace AZ::Render if (!m_tickRequests) { m_tickRequests = AZ::TickRequestBus::FindFirstHandler(); - } - if (!m_tickRequests) - { - return; + if (!m_tickRequests) + { + return; + } } AZ::ScriptTimePoint currentTime = m_tickRequests->GetTimeAtCurrentTick(); From 1c575763c7bacb0929264fa73a409d8b510ed229 Mon Sep 17 00:00:00 2001 From: Vicky <55564570+VickyAtAZ@users.noreply.github.com> Date: Fri, 14 May 2021 13:45:26 -0700 Subject: [PATCH 217/225] ATOM-4661 Improvement with pass templates registration from data (#735) * ATOM-4661 Improvement with pass templates registration from data - Update PassLibrary so it can load pass templates from more than one files and report duplicate pass templates. - Added load templates events to pass system so the handlers from any gems can load their own pass templates. - Added PassSystemInterface::OnReadyLoadTemplatesEvent::Handler in FeatureCommon gem's CommonSystemeComponet to load the PassTemplates.azasset in featureCommon gem. - Misc: moved BindlessPrototypeSrg.asli from RPI to ASV project; fixed an assert issue when exit ASV --- .../Code/Source/CommonSystemComponent.cpp | 11 ++ .../Code/Source/CommonSystemComponent.h | 7 + .../BindlessPrototypeSrg.azsli | 136 ------------------ .../RPI/Assets/atom_rpi_asset_files.cmake | 1 - .../Atom/RPI.Public/Pass/PassFactory.h | 2 +- .../Atom/RPI.Public/Pass/PassLibrary.h | 5 +- .../Include/Atom/RPI.Public/Pass/PassSystem.h | 8 ++ .../RPI.Public/Pass/PassSystemInterface.h | 24 ++-- .../Atom/RPI.Reflect/Asset/AssetUtils.h | 18 ++- .../Atom/RPI.Reflect/RPISystemDescriptor.h | 3 - .../Source/RPI.Public/Pass/PassFactory.cpp | 6 +- .../Source/RPI.Public/Pass/PassLibrary.cpp | 30 +++- .../Source/RPI.Public/Pass/PassSystem.cpp | 12 +- .../RPI/Code/Source/RPI.Public/RPISystem.cpp | 7 +- .../Atom/RPI/Code/Source/RPI.Public/Scene.cpp | 11 +- 15 files changed, 106 insertions(+), 175 deletions(-) delete mode 100644 Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli diff --git a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp index be6d438a62..089a6168b1 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp @@ -274,6 +274,10 @@ namespace AZ passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurPass"), &Render::ReflectionScreenSpaceBlurPass::Create); passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurChildPass"), &Render::ReflectionScreenSpaceBlurChildPass::Create); passSystem->AddPassCreator(Name("ReflectionCopyFrameBufferPass"), &Render::ReflectionCopyFrameBufferPass::Create); + + // setup handler for load pass template mappings + m_loadTemplatesHandler = RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler([this]() { this->LoadPassTemplateMappings(); }); + RPI::PassSystemInterface::Get()->ConnectEvent(m_loadTemplatesHandler); } void CommonSystemComponent::Deactivate() @@ -292,5 +296,12 @@ namespace AZ AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor(); AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor(); } + + void CommonSystemComponent::LoadPassTemplateMappings() + { + const char* passTemplatesFile = "Passes/PassTemplates.azasset"; + RPI::PassSystemInterface::Get()->LoadPassTemplateMappings(passTemplatesFile); + } + } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.h b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.h index 595faba523..92705f0fa6 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.h +++ b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.h @@ -14,6 +14,8 @@ #include #include +#include + #if AZ_TRAIT_LUXCORE_SUPPORTED #include "LuxCore/LuxCoreRenderer.h" #endif @@ -41,6 +43,11 @@ namespace AZ void Activate() override; void Deactivate() override; + // Load pass template mappings for this gem + void LoadPassTemplateMappings(); + + RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler m_loadTemplatesHandler; + #if AZ_TRAIT_LUXCORE_SUPPORTED // LuxCore LuxCoreRenderer m_luxCore; diff --git a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli deleted file mode 100644 index 7304af9e1e..0000000000 --- a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli +++ /dev/null @@ -1,136 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -// NOTE: Nest this array, so Azslc will output a size of the bindingslot to 1 -struct FloatBuffer -{ - float buffer; -}; - -// Listed on update frequency -ShaderResourceGroupSemantic FrequencyPerScene -{ - FrequencyId = 6; -}; - -ShaderResourceGroupSemantic FloatBufferSemanticId -{ - FrequencyId = 7; -}; - -ShaderResourceGroup ImageSrg : FrequencyPerScene -{ - Sampler m_sampler - { - MaxAnisotropy = 16; - AddressU = Wrap; - AddressV = Wrap; - AddressW = Wrap; - }; - - // Array of textures - Texture2D m_textureArray[]; -} - -ShaderResourceGroup FloatBufferSrg : FloatBufferSemanticId -{ - StructuredBuffer m_floatBuffer; -}; - -// Helper functions to read data from the FloatBuffer. The FloatBuffer is accessed with a descriptor and a index. -// The descriptor holds the initial offset within the FloatBuffer, and the index is a sub-index, which increments with each property that is being read. -// The data needs to be read in the same order as it is allocated on the host. - -// All float setters -void SetFloat(out float outFloat, in uint desc, inout uint index) -{ - outFloat = FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer; - index += 1; -} - -void SetFloat2(out float2 outFloat, in uint desc, inout uint index) -{ - outFloat.x = FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer; - outFloat.y = FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer; - index += 2; -} - -void SetFloat3(out float3 outFloat, in uint desc, inout uint index) -{ - outFloat.x = FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer; - outFloat.y = FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer; - outFloat.z = FloatBufferSrg::m_floatBuffer[desc + index + 2].buffer; - index += 3; -} - -void SetFloat4(out float4 outFloat, in uint desc, inout uint index) -{ - outFloat.x = FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer; - outFloat.y = FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer; - outFloat.z = FloatBufferSrg::m_floatBuffer[desc + index + 2].buffer; - outFloat.w = FloatBufferSrg::m_floatBuffer[desc + index + 3].buffer; - index += 4; -} - -// All matrix setters -void SetFloat4x4(out float4x4 outFloat, in uint desc, inout uint index) -{ - [unroll(4)] - for(uint i = 0; i < 4; i++) - { - SetFloat4(outFloat[i], desc, index); - } -} - -// All uint setters -void SetUint(out uint outUInt, in uint desc, inout uint index) -{ - outUInt = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer); - index += 1; -} - -void SetUint2(out uint2 outUInt, in uint desc, inout uint index) -{ - outUInt.x = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer); - outUInt.y = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer); - index += 2; -} - -void SetUint3(out uint3 outUInt, in uint desc, inout uint index) -{ - outUInt.x = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer); - outUInt.y = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer); - outUInt.z = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 2].buffer); - index += 3; -} - -void SetUint4(out uint4 outUInt, in uint desc, inout uint index) -{ - outUInt.x = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer); - outUInt.y = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer); - outUInt.z = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 2].buffer); - outUInt.w = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 3].buffer); - index += 4; -} - -// All double setters -void SetDouble(out double outDouble, in uint desc, inout uint index) -{ - uint lowBits; - uint highBits; - SetUint(highBits, desc, index); - SetUint(lowBits, desc, index); - - outDouble = asdouble(lowBits, highBits); -} diff --git a/Gems/Atom/RPI/Assets/atom_rpi_asset_files.cmake b/Gems/Atom/RPI/Assets/atom_rpi_asset_files.cmake index 47bece22c9..b7dd571002 100644 --- a/Gems/Atom/RPI/Assets/atom_rpi_asset_files.cmake +++ b/Gems/Atom/RPI/Assets/atom_rpi_asset_files.cmake @@ -21,7 +21,6 @@ set(FILES Shader/ImagePreview.shader ShaderLib/Atom/RPI/Math.azsli ShaderLib/Atom/RPI/TangentSpace.azsli - ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli ShaderLib/Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli ShaderLib/Atom/RPI/ShaderResourceGroups/DefaultObjectSrg.azsli ) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassFactory.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassFactory.h index dc39687a97..2252838541 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassFactory.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassFactory.h @@ -89,7 +89,7 @@ namespace AZ // --- Members --- // Cached pointer to the pass library to simplify code - PassLibrary* m_passLibary = nullptr; + PassLibrary* m_passLibrary = nullptr; // ClassNames are used to look up PassCreators. This list is 1-to-1 with the PassCreator list AZStd::vector m_passClassNames; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h index 283cea7c0a..d26f15096b 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h @@ -56,6 +56,9 @@ namespace AZ // The list of passes created from this template AZStd::vector m_passes; + + // The pass templates mapping asset id which this template is coming from. + Data::AssetId m_mappingAssetId; }; typedef AZStd::unordered_map TemplateEntriesByName; @@ -105,7 +108,7 @@ namespace AZ bool LoadPassAsset(const Name& name, const Data::Asset& passAsset, bool hotReloading = false); // Find asset with specified pass template asset id and load pass template from the asset. - void LoadPassAsset(const Name& name, const Data::AssetId& passAssetId); + bool LoadPassAsset(const Name& name, const Data::AssetId& passAssetId); // Data::AssetBus::Handler overrides... void OnAssetReloaded(Data::Asset asset) override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h index d37868025c..fd30f4f406 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h @@ -55,6 +55,10 @@ namespace AZ //! Initializes the PassSystem and the Root Pass and creates the Pass InstanceDatabase void Init(); + //! Initialize and load pass templates + //! This function need to be called after Init() + void InitPassTemplates(); + //! Deletes the Root Pass and shuts down the PassSystem void Shutdown(); @@ -74,6 +78,7 @@ namespace AZ void SetHotReloading(bool hotReloading) override; void SetTargetedPassDebuggingName(const AZ::Name& targetPassName) override; const AZ::Name& GetTargetedPassDebuggingName() const override; + void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) override; // PassSystemInterface factory related functions... void AddPassCreator(Name className, PassCreator createFunction) override; @@ -139,6 +144,9 @@ namespace AZ // Counts the number of passes int32_t m_passCounter = 0; + + // Events + OnReadyLoadTemplatesEvent m_loadTemplatesEvent; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h index 82d52ab5a2..1224bf9545 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h @@ -64,7 +64,10 @@ namespace AZ //! initializing a scene; virtual void ProcessQueuedChanges() = 0; - //! Load pass templates listed in a name-assetid mapping asset + //! Load pass templates listed in a name-assetid mapping asset + //! This function should be called before the render pipelines which use templates from this mappings are created. + //! To load pass template mapping before any render pipelines are created, use OnReadyLoadTemplatesEvent::Handler to + //! load desired pass template mappings virtual bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath) = 0; //! Writes a pass template to a .pass file which can then be used as a pass asset. Useful for @@ -148,6 +151,12 @@ namespace AZ //! Find the SwapChainPass associated with window Handle virtual SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const = 0; + using OnReadyLoadTemplatesEvent = AZ::Event<>; + //! Connect a handler to listen to the event that the pass system is ready to load pass templates + //! The event is triggered when pass system is initialized and asset system is ready. + //! The handler can add new pass templates or load pass template mappings from assets + virtual void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) = 0; + private: // These functions are only meant to be used by the Pass class @@ -164,17 +173,10 @@ namespace AZ virtual void UnregisterPass(Pass* pass) = 0; }; - - //! Notifications of the pass system such attachments were rebuilt, pass tree changes - class PassSystemNotificiations - : public AZ::EBusTraits + + namespace PassSystemEvents { - public: + } - //! Notify when any pass's attachment was rebuilt - virtual void OnPassAttachmentsBuilt() = 0; - }; - - using PassSystemNotificiationBus = AZ::EBus; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h index 5a169a9e61..1a8ddb5d97 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h @@ -137,13 +137,19 @@ namespace AZ template Data::Asset LoadCriticalAsset(const AZStd::string& assetFilePath, TraceLevel reporting) { - AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; - AzFramework::AssetSystemRequestBus::BroadcastResult(status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilePath); - - if (status != AzFramework::AssetSystem::AssetStatus_Compiled) + bool apConnected = false; + AzFramework::AssetSystemRequestBus::BroadcastResult( + apConnected, &AzFramework::AssetSystemRequestBus::Events::ConnectedWithAssetProcessor); + if (apConnected) { - AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not compile asset '%s'", assetFilePath.c_str()).c_str()); - return {}; + AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; + AzFramework::AssetSystemRequestBus::BroadcastResult( + status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilePath); + if (status != AzFramework::AssetSystem::AssetStatus_Compiled) + { + AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not compile asset '%s'", assetFilePath.c_str()).c_str()); + return {}; + } } return LoadAssetByProductPath(assetFilePath.c_str(), reporting); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/RPISystemDescriptor.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/RPISystemDescriptor.h index 1223f984fd..3d0b9f4f63 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/RPISystemDescriptor.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/RPISystemDescriptor.h @@ -44,9 +44,6 @@ namespace AZ //! The path of the only one view srg asset for the RPI system. This is used to create any RPI::View. AZStd::string m_viewSrgAssetPath = "shaderlib/viewsrg_viewsrg.azsrg"; - //! Path of pass templates' name-assetid mapping file. - AZStd::string m_passTemplatesMappingPath = "Passes/PassTemplates.azasset"; - ImageSystemDescriptor m_imageSystemDescriptor; GpuQuerySystemDescriptor m_gpuQuerySystemDescriptor; DynamicDrawSystemDescriptor m_dynamicDrawSystemDescriptor; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassFactory.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassFactory.cpp index 6a2e756403..90df206a3d 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassFactory.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassFactory.cpp @@ -36,7 +36,7 @@ namespace AZ { void PassFactory::Init(PassLibrary* passLibrary) { - m_passLibary = passLibrary; + m_passLibrary = passLibrary; AddCorePasses(); } @@ -125,7 +125,7 @@ namespace AZ Ptr PassFactory::CreatePassFromTemplate(Name templateName, Name passName) { - const AZStd::shared_ptr& passTemplate = m_passLibary->GetPassTemplate(templateName); + const AZStd::shared_ptr& passTemplate = m_passLibrary->GetPassTemplate(templateName); if (passTemplate == nullptr) { AZ_Error("PassFactory", false, "FAILED TO CREATE PASS [%s]. Could not find pass template [%s]", passName.GetCStr(), templateName.GetCStr()); @@ -143,7 +143,7 @@ namespace AZ return nullptr; } - const AZStd::shared_ptr& passTemplate = m_passLibary->GetPassTemplate(passRequest->m_templateName); + const AZStd::shared_ptr& passTemplate = m_passLibrary->GetPassTemplate(passRequest->m_templateName); if (passTemplate == nullptr) { AZ_Error("PassFactory", false, "FAILED TO CREATE PASS [%s]. Could not find pass template [%s]", passRequest->m_passName.GetCStr(), passRequest->m_templateName.GetCStr()); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp index 6c1f96e414..346ccc7d76 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp @@ -262,6 +262,7 @@ namespace AZ } // Handle template mapping reload + // Note: it's a known issue that when mapping asset got reloaded, we only handle the new entries Data::Asset templateMappings = { asset.GetAs(), AZ::Data::AssetLoadBehavior::PreLoad }; if (templateMappings) { @@ -310,7 +311,7 @@ namespace AZ return success; } - void PassLibrary::LoadPassAsset(const Name& name, const Data::AssetId& passAssetId) + bool PassLibrary::LoadPassAsset(const Name& name, const Data::AssetId& passAssetId) { Data::Asset passAsset; if (passAssetId.IsValid()) @@ -325,11 +326,20 @@ namespace AZ { Data::AssetBus::MultiHandler::BusConnect(passAssetId); } + + return loadSuccess; } bool PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) { Data::Asset mappingAsset = AssetUtils::LoadCriticalAsset(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error); + + if (m_templateMappingAssets.find(mappingAsset.GetId()) != m_templateMappingAssets.end()) + { + AZ_Warning("PassLibrary", false, "Pass template mapping [%s] was already loaded", mappingAsset.GetHint().c_str()); + return true; + } + bool success = LoadPassTemplateMappings(mappingAsset); if (success) { @@ -350,13 +360,29 @@ namespace AZ } const AZStd::unordered_map& assetMapping = mappings->GetAssetMapping(); + Data::AssetId mappingAssetId = mappingAsset.GetId(); m_templateEntries.reserve(m_templateEntries.size() + assetMapping.size()); for (const auto& assetInfo : assetMapping) { Name templateName = AZ::Name(assetInfo.first); if (!HasTemplate(templateName)) { - LoadPassAsset(templateName, assetInfo.second); + bool loaded = LoadPassAsset(templateName, assetInfo.second); + if (loaded) + { + auto& entry = m_templateEntries[templateName]; + entry.m_mappingAssetId = mappingAssetId; + } + } + else + { + // Report a warning if the template was setup in another mappping asset. + // We won't report a warning if the template was loaded from same asset. This only happens when the asset got reloaded. + if (m_templateEntries[templateName].m_mappingAssetId != mappingAssetId) + { + AZ_Warning("PassLibrary", false, "Template [%s] was aleady added to the library. Duplicated template from [%s]", + templateName.GetCStr(), mappingAsset.ToString().c_str()); + } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp index 706d759231..448c28f202 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp @@ -100,6 +100,12 @@ namespace AZ m_rootPass->m_flags.m_partOfHierarchy = true; } + void PassSystem::InitPassTemplates() + { + AZ_Assert(m_rootPass, "PassSystem::Init() need to be called"); + m_loadTemplatesEvent.Signal(); + } + bool PassSystem::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) { return m_passLibrary.LoadPassTemplateMappings(templateMappingPath); @@ -213,7 +219,6 @@ namespace AZ DebugPrintPassHierarchy(); } #endif - PassSystemNotificiationBus::Broadcast(&PassSystemNotificiationBus::Events::OnPassAttachmentsBuilt); } m_isBuilding = false; @@ -323,6 +328,11 @@ namespace AZ return m_targetedPassDebugName; } + void PassSystem::ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) + { + handler.Connect(m_loadTemplatesEvent); + } + // --- Pass Factory Functions --- void PassSystem::AddPassCreator(Name className, PassCreator createFunction) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp index 5cd6f93715..44be2dabeb 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp @@ -369,12 +369,7 @@ namespace AZ m_bufferSystem.Init(); m_dynamicDraw.Init(m_descriptor.m_dynamicDrawSystemDescriptor); - // Have pass system load default pass template mapping - bool passSystemReady = m_passSystem.LoadPassTemplateMappings(m_descriptor.m_passTemplatesMappingPath); - if (!passSystemReady) - { - return; - } + m_passSystem.InitPassTemplates(); m_systemAssetsInitialized = true; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp index a66471e038..7e33750eb5 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp @@ -99,7 +99,6 @@ namespace AZ { WaitAndCleanCompletionJob(m_simulationCompletion); SceneRequestBus::Handler::BusDisconnect(); - DisableAllFeatureProcessors(); // Remove all the render pipelines. Need to process queued changes with pass system before and after remove render pipelines AZ::RPI::PassSystemInterface::Get()->ProcessQueuedChanges(); @@ -111,6 +110,8 @@ namespace AZ m_pipelines.clear(); AZ::RPI::PassSystemInterface::Get()->ProcessQueuedChanges(); + Deactivate(); + delete m_cullingScene; } @@ -138,8 +139,11 @@ namespace AZ void Scene::Deactivate() { - AZ_Assert(m_activated, "Not activated"); - + if (!m_activated) + { + return; + } + for (auto& fp : m_featureProcessors) { fp->Deactivate(); @@ -240,7 +244,6 @@ namespace AZ fp->Deactivate(); } m_featureProcessors.clear(); - m_pipelineStatesLookup.clear(); } FeatureProcessor* Scene::GetFeatureProcessor(const FeatureProcessorId& featureProcessorId) const From 5acdc4059531f2aeab472369ce4f5c1214bf147e Mon Sep 17 00:00:00 2001 From: karlberg Date: Fri, 14 May 2021 14:24:33 -0700 Subject: [PATCH 218/225] Many fixes for external gem multiplayer components and component network inputs, fixes an uninitialized variable resulting in continual desyncs, restructures our public includes to match the directory structure of source, allows autogen artefacts to be included by external gems, allowing for external multiplayer components to interact with multiplayer gem components with no extra code --- .../Serialization/HashSerializer.h | 2 +- .../LocalPredictionPlayerInputComponent.h | 2 +- .../{ => Components}/MultiplayerComponent.h | 8 ++- .../MultiplayerComponentRegistry.h | 12 ++++- .../{ => Components}/MultiplayerController.h | 12 +++-- .../{ => Components}/NetBindComponent.h | 13 +++-- .../Components/NetworkTransformComponent.h | 0 .../{ => ConnectionData}/IConnectionData.h | 2 +- .../{ => EntityDomains}/IEntityDomain.h | 2 +- .../Code/Include/Multiplayer/IMultiplayer.h | 27 ++-------- .../Multiplayer/INetworkPlayerSpawner.h | 18 ------- .../EntityReplication}/ReplicationRecord.h | 0 .../INetworkEntityManager.h | 2 +- .../{ => NetworkEntity}/NetworkEntityHandle.h | 2 +- .../NetworkEntityHandle.inl | 0 .../NetworkEntityRpcMessage.h | 0 .../NetworkEntityUpdateMessage.h | 0 .../IMultiplayerComponentInput.h | 2 +- .../{ => NetworkInput}/NetworkInput.h | 14 ++--- .../{ => NetworkTime}/INetworkTime.h | 0 .../{ => NetworkTime}/RewindableObject.h | 4 +- .../{ => NetworkTime}/RewindableObject.inl | 0 .../IReplicationWindow.h | 2 +- .../AutoGen/AutoComponentTypes_Source.jinja | 8 ++- .../Source/AutoGen/AutoComponent_Common.jinja | 54 +++++++++++++++---- .../Source/AutoGen/AutoComponent_Header.jinja | 39 ++++++++------ .../Source/AutoGen/AutoComponent_Source.jinja | 51 +++++++++++++----- ...tionPlayerInputComponent.AutoComponent.xml | 6 +-- .../AutoGen/Multiplayer.AutoPackets.xml | 6 +-- ...etworkTransformComponent.AutoComponent.xml | 2 +- .../LocalPredictionPlayerInputComponent.cpp | 16 +++--- .../Components/MultiplayerComponent.cpp | 23 ++++++-- .../MultiplayerComponentRegistry.cpp | 8 ++- .../Components/MultiplayerController.cpp | 15 ++++-- .../Source/Components/NetBindComponent.cpp | 41 ++++++++++---- .../Components/NetworkTransformComponent.cpp | 4 +- .../ClientToServerConnectionData.h | 2 +- .../ServerToClientConnectionData.h | 2 +- .../Debug/MultiplayerDebugSystemComponent.cpp | 15 +++--- .../EntityDomains/FullOwnershipEntityDomain.h | 2 +- .../Code/Source/MultiplayerGem.cpp | 2 +- .../MultiplayerStats.cpp | 0 .../Source/MultiplayerSystemComponent.cpp | 22 +------- .../Code/Source/MultiplayerSystemComponent.h | 4 -- .../EntityReplicationManager.cpp | 17 +++--- .../EntityReplicationManager.h | 10 ++-- .../EntityReplication/EntityReplicator.cpp | 6 +-- .../EntityReplication/EntityReplicator.h | 4 +- .../EntityReplication/PropertyPublisher.h | 2 +- .../EntityReplication/PropertySubscriber.cpp | 2 +- .../EntityReplication/ReplicationRecord.cpp | 2 +- .../NetworkEntityAuthorityTracker.cpp | 4 +- .../NetworkEntity/NetworkEntityHandle.cpp | 8 +-- .../NetworkEntity/NetworkEntityManager.cpp | 2 +- .../NetworkEntity/NetworkEntityManager.h | 8 +-- .../NetworkEntity/NetworkEntityRpcMessage.cpp | 2 +- .../NetworkEntity/NetworkEntityTracker.cpp | 2 +- .../NetworkEntity/NetworkEntityTracker.h | 2 +- .../NetworkEntityUpdateMessage.cpp | 2 +- .../Code/Source/NetworkInput/NetworkInput.cpp | 23 ++++---- .../Source/NetworkInput/NetworkInputArray.cpp | 2 +- .../Source/NetworkInput/NetworkInputArray.h | 4 +- .../Source/NetworkInput/NetworkInputChild.h | 2 +- .../Source/NetworkInput/NetworkInputHistory.h | 2 +- .../NetworkInputMigrationVector.h | 4 +- .../Code/Source/NetworkTime/NetworkTime.cpp | 2 +- .../Code/Source/NetworkTime/NetworkTime.h | 2 +- .../Pipeline/NetworkPrefabProcessor.cpp | 2 +- .../NullReplicationWindow.h | 2 +- .../ServerToClientReplicationWindow.cpp | 2 +- .../ServerToClientReplicationWindow.h | 4 +- .../Code/Tests/RewindableObjectTests.cpp | 2 +- Gems/Multiplayer/Code/multiplayer_files.cmake | 43 ++++++++------- 73 files changed, 348 insertions(+), 267 deletions(-) rename Gems/Multiplayer/Code/{Source => Include/Multiplayer}/Components/LocalPredictionPlayerInputComponent.h (98%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => Components}/MultiplayerComponent.h (96%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => Components}/MultiplayerComponentRegistry.h (83%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => Components}/MultiplayerController.h (92%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => Components}/NetBindComponent.h (93%) rename Gems/Multiplayer/Code/{Source => Include/Multiplayer}/Components/NetworkTransformComponent.h (100%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => ConnectionData}/IConnectionData.h (97%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => EntityDomains}/IEntityDomain.h (96%) delete mode 100644 Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkEntity/EntityReplication}/ReplicationRecord.h (100%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkEntity}/INetworkEntityManager.h (99%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkEntity}/NetworkEntityHandle.h (99%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkEntity}/NetworkEntityHandle.inl (100%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkEntity}/NetworkEntityRpcMessage.h (100%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkEntity}/NetworkEntityUpdateMessage.h (100%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkInput}/IMultiplayerComponentInput.h (94%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkInput}/NetworkInput.h (85%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkTime}/INetworkTime.h (100%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkTime}/RewindableObject.h (97%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => NetworkTime}/RewindableObject.inl (100%) rename Gems/Multiplayer/Code/Include/Multiplayer/{ => ReplicationWindows}/IReplicationWindow.h (96%) rename Gems/Multiplayer/Code/{Include/Multiplayer => Source}/MultiplayerStats.cpp (100%) diff --git a/Code/Framework/AzNetworking/AzNetworking/Serialization/HashSerializer.h b/Code/Framework/AzNetworking/AzNetworking/Serialization/HashSerializer.h index 2f86d1aafe..1cc44cf5bd 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Serialization/HashSerializer.h +++ b/Code/Framework/AzNetworking/AzNetworking/Serialization/HashSerializer.h @@ -56,6 +56,6 @@ namespace AzNetworking private: - AZ::HashValue64 m_hash; + AZ::HashValue64 m_hash = AZ::HashValue64{ 0 }; }; } diff --git a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/LocalPredictionPlayerInputComponent.h similarity index 98% rename from Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.h rename to Gems/Multiplayer/Code/Include/Multiplayer/Components/LocalPredictionPlayerInputComponent.h index 924fd78391..7a6105a7e3 100644 --- a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/LocalPredictionPlayerInputComponent.h @@ -13,7 +13,7 @@ #pragma once #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h similarity index 96% rename from Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponent.h rename to Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h index 29348a698a..6f410dd97c 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h @@ -15,7 +15,8 @@ #include #include #include -#include +#include +#include #include #include @@ -62,7 +63,10 @@ namespace Multiplayer //! @} NetEntityId GetNetEntityId() const; - NetEntityRole GetNetEntityRole() const; + bool IsAuthority() const; + bool IsAutonomous() const; + bool IsServer() const; + bool IsClient() const; ConstNetworkEntityHandle GetEntityHandle() const; NetworkEntityHandle GetEntityHandle(); void MarkDirty(); diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponentRegistry.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponentRegistry.h similarity index 83% rename from Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponentRegistry.h rename to Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponentRegistry.h index d06362ed4b..d3064d87dd 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerComponentRegistry.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponentRegistry.h @@ -14,7 +14,8 @@ #include #include -#include +#include +#include namespace Multiplayer { @@ -22,13 +23,15 @@ namespace Multiplayer { public: using PropertyNameLookupFunction = AZStd::function; - using RpcNameLookupFunction = AZStd::function; + using RpcNameLookupFunction = AZStd::function; + using AllocComponentInputFunction = AZStd::function()>; struct ComponentData { AZ::Name m_gemName; AZ::Name m_componentName; PropertyNameLookupFunction m_componentPropertyNameLookupFunction; RpcNameLookupFunction m_componentRpcNameLookupFunction; + AllocComponentInputFunction m_allocComponentInputFunction; }; //! Registers a multiplayer component with the multiplayer system. @@ -36,6 +39,11 @@ namespace Multiplayer //! @return the NetComponentId assigned to this particular component NetComponentId RegisterMultiplayerComponent(const ComponentData& componentData); + //! Allocates a new component input for the provided netComponentId. + //! @param netComponentId the NetComponentId to allocate a component input for + //! @return pointer to the allocated component input, caller assumes ownership + AZStd::unique_ptr AllocateComponentInput(NetComponentId netComponentId); + //! Returns the gem name associated with the provided NetComponentId. //! @param netComponentId the NetComponentId to return the gem name of //! @return the name of the gem that contains the requested component diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerController.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerController.h similarity index 92% rename from Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerController.h rename to Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerController.h index 89c47c40d4..a8017ef9d1 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerController.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerController.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer @@ -47,9 +47,13 @@ namespace Multiplayer //! @return the networkId for the entity that owns this controller NetEntityId GetNetEntityId() const; - //! Returns the networkRole for the entity that owns this controller. - //! @return the networkRole for the entity that owns this controller - NetEntityRole GetNetEntityRole() const; + //! Returns true if this controller has authority. + //! @return boolean true if this controller has authority + bool IsAuthority() const; + + //! Returns true if this controller has autonomy (can locally predict). + //! @return boolean true if this controller has autonomy + bool IsAutonomous() const; //! Returns the raw AZ::Entity pointer for the entity that owns this controller. //! @return the raw AZ::Entity pointer for the entity that owns this controller diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetBindComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h similarity index 93% rename from Gems/Multiplayer/Code/Include/Multiplayer/NetBindComponent.h rename to Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h index 464333e3b2..257e7cab4b 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/NetBindComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h @@ -20,10 +20,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -63,12 +63,16 @@ namespace Multiplayer NetEntityRole GetNetEntityRole() const; bool IsAuthority() const; + bool IsAutonomous() const; + bool IsServer() const; + bool IsClient() const; bool HasController() const; NetEntityId GetNetEntityId() const; const PrefabEntityId& GetPrefabEntityId() const; ConstNetworkEntityHandle GetEntityHandle() const; NetworkEntityHandle GetEntityHandle(); + void SetAllowAutonomy(bool value); MultiplayerComponentInputVector AllocateComponentInputs(); bool IsProcessingInput() const; void CreateInput(NetworkInput& networkInput, float deltaTime); @@ -155,6 +159,7 @@ namespace Multiplayer bool m_isProcessingInput = false; bool m_isMigrationDataValid = false; bool m_needsToBeStopped = false; + bool m_allowAutonomy = false; // Set to true for the hosts controlled entity friend class NetworkEntityManager; friend class EntityReplicationManager; diff --git a/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetworkTransformComponent.h similarity index 100% rename from Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.h rename to Gems/Multiplayer/Code/Include/Multiplayer/Components/NetworkTransformComponent.h diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IConnectionData.h b/Gems/Multiplayer/Code/Include/Multiplayer/ConnectionData/IConnectionData.h similarity index 97% rename from Gems/Multiplayer/Code/Include/Multiplayer/IConnectionData.h rename to Gems/Multiplayer/Code/Include/Multiplayer/ConnectionData/IConnectionData.h index 39fdb61435..1fb3003c7b 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IConnectionData.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/ConnectionData/IConnectionData.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IEntityDomain.h b/Gems/Multiplayer/Code/Include/Multiplayer/EntityDomains/IEntityDomain.h similarity index 96% rename from Gems/Multiplayer/Code/Include/Multiplayer/IEntityDomain.h rename to Gems/Multiplayer/Code/Include/Multiplayer/EntityDomains/IEntityDomain.h index 70215612b0..dd7a11bb4a 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IEntityDomain.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/EntityDomains/IEntityDomain.h @@ -12,7 +12,7 @@ #pragma once -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 4931fb167f..6a615465c2 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -15,8 +15,9 @@ #include #include #include -#include -#include +#include +#include +#include #include namespace AzNetworking @@ -101,28 +102,6 @@ namespace Multiplayer //! @return pointer to the network entity manager instance bound to this multiplayer instance virtual INetworkEntityManager* GetNetworkEntityManager() = 0; - //! Returns the gem name associated with the provided component index. - //! @param netComponentId the componentId to return the gem name of - //! @return the name of the gem that contains the requested component - virtual const char* GetComponentGemName(NetComponentId netComponentId) const = 0; - - //! Returns the component name associated with the provided component index. - //! @param netComponentId the componentId to return the component name of - //! @return the name of the component - virtual const char* GetComponentName(NetComponentId netComponentId) const = 0; - - //! Returns the property name associated with the provided component index and property index. - //! @param netComponentId the component index to return the property name of - //! @param propertyIndex the index of the network property to return the property name of - //! @return the name of the network property - virtual const char* GetComponentPropertyName(NetComponentId netComponentId, PropertyIndex propertyIndex) const = 0; - - //! Returns the Rpc name associated with the provided component index and rpc index. - //! @param netComponentId the componentId to return the property name of - //! @param rpcIndex the index of the rpc to return the rpc name of - //! @return the name of the requested rpc - virtual const char* GetComponentRpcName(NetComponentId netComponentId, RpcIndex rpcIndex) const = 0; - //! Retrieve the stats object bound to this multiplayer instance. //! @return the stats object bound to this multiplayer instance MultiplayerStats& GetStats() { return m_stats; } diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h b/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h deleted file mode 100644 index f50d60e82d..0000000000 --- a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkPlayerSpawner.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -namespace Multiplayer -{ - -} diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/ReplicationRecord.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/EntityReplication/ReplicationRecord.h similarity index 100% rename from Gems/Multiplayer/Code/Include/Multiplayer/ReplicationRecord.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/EntityReplication/ReplicationRecord.h diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkEntityManager.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/INetworkEntityManager.h similarity index 99% rename from Gems/Multiplayer/Code/Include/Multiplayer/INetworkEntityManager.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/INetworkEntityManager.h index 17224e64cb..72dbe201e5 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkEntityManager.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/INetworkEntityManager.h @@ -13,7 +13,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityHandle.h similarity index 99% rename from Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityHandle.h index 813589fac6..21d4ae9c62 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityHandle.h @@ -138,4 +138,4 @@ namespace Multiplayer }; } -#include +#include diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.inl b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityHandle.inl similarity index 100% rename from Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityHandle.inl rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityHandle.inl diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityRpcMessage.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h similarity index 100% rename from Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityRpcMessage.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityUpdateMessage.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h similarity index 100% rename from Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntityUpdateMessage.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerComponentInput.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h similarity index 94% rename from Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerComponentInput.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h index b26feadc4f..13faff3a7e 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerComponentInput.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h @@ -28,7 +28,7 @@ namespace Multiplayer { public: virtual ~IMultiplayerComponentInput() = default; - virtual NetComponentId GetComponentId() const = 0; + virtual NetComponentId GetNetComponentId() const = 0; virtual bool Serialize(AzNetworking::ISerializer& serializer) = 0; }; diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/NetworkInput.h similarity index 85% rename from Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/NetworkInput.h index 9c6d2ce66a..b2e0134ea9 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/NetworkInput.h @@ -12,9 +12,9 @@ #pragma once -#include -#include -#include +#include +#include +#include #include namespace Multiplayer @@ -57,15 +57,15 @@ namespace Multiplayer IMultiplayerComponentInput* FindComponentInput(NetComponentId componentId); template - const InputType* FindInput() const + const InputType* FindComponentInput() const { - return static_cast(FindInput(InputType::s_Type)); + return static_cast(FindComponentInput(InputType::s_netComponentId)); } template - InputType* FindInput() + InputType* FindComponentInput() { - return static_cast(FindInput(InputType::s_Type)); + return static_cast(FindComponentInput(InputType::s_netComponentId)); } private: diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkTime/INetworkTime.h similarity index 100% rename from Gems/Multiplayer/Code/Include/Multiplayer/INetworkTime.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkTime/INetworkTime.h diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkTime/RewindableObject.h similarity index 97% rename from Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.h rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkTime/RewindableObject.h index 9e1655aec7..d5b7d563ab 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkTime/RewindableObject.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include #include #include @@ -115,4 +115,4 @@ namespace AZ AZ_TYPE_INFO_TEMPLATE(Multiplayer::RewindableObject, "{B2937B44-FEE1-4277-B1E0-863DE76D363F}", AZ_TYPE_INFO_TYPENAME, AZ_TYPE_INFO_AUTO); } -#include +#include diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.inl b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkTime/RewindableObject.inl similarity index 100% rename from Gems/Multiplayer/Code/Include/Multiplayer/RewindableObject.inl rename to Gems/Multiplayer/Code/Include/Multiplayer/NetworkTime/RewindableObject.inl diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IReplicationWindow.h b/Gems/Multiplayer/Code/Include/Multiplayer/ReplicationWindows/IReplicationWindow.h similarity index 96% rename from Gems/Multiplayer/Code/Include/Multiplayer/IReplicationWindow.h rename to Gems/Multiplayer/Code/Include/Multiplayer/ReplicationWindows/IReplicationWindow.h index d0192e8aa4..5d90fc286b 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IReplicationWindow.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/ReplicationWindows/IReplicationWindow.h @@ -13,7 +13,7 @@ #pragma once #include -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja index 453d74c907..7bb4bdcc2c 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponentTypes_Source.jinja @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include {% for Component in dataFiles %} {% set ComponentDerived = Component.attrib['OverrideComponent']|booleanTrue %} {% set ControllerDerived = Component.attrib['OverrideController']|booleanTrue %} @@ -38,7 +38,11 @@ namespace {{ Namespace }} componentData.m_componentName = AZ::Name("{{ Component.attrib['Name'] }}"); componentData.m_componentPropertyNameLookupFunction = {{ ComponentBaseName }}::GetNetworkPropertyName; componentData.m_componentRpcNameLookupFunction = {{ ComponentBaseName }}::GetRpcName; + componentData.m_allocComponentInputFunction = {{ ComponentBaseName }}::AllocateComponentInput; {{ ComponentBaseName }}::s_netComponentId = multiplayerComponentRegistry->RegisterMultiplayerComponent(componentData); +{% if NetworkInputCount > 0 %} + {{ ComponentName }}NetworkInput::s_netComponentId = {{ ComponentBaseName }}::s_netComponentId; +{% endif %} stats.ReserveComponentStats({{ ComponentBaseName }}::s_netComponentId, static_cast({{ NetworkPropertyCount }}), static_cast({{ RpcCount }})); } {% endfor %} diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Common.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Common.jinja index d211b933c5..d187a151fd 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Common.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Common.jinja @@ -207,11 +207,11 @@ namespace {{ Component.attrib['Namespace'] }} public: AZ_MULTIPLAYER_COMPONENT({{ Component.attrib['Namespace'] }}::{{ ComponentName }}, s_{{ LowerFirst(ComponentName) }}ConcreteUuid, {{ Component.attrib['Namespace'] }}::{{ ComponentNameBase }}); - static void Reflect([[maybe_unused]] AZ::ReflectContext* context); + static void Reflect(AZ::ReflectContext* context); - void OnInit() override {} - void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {} - void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {} + void OnInit() override; + void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override; + void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override; {{ DeclareRpcHandlers(Component, 'Authority', 'Client', true)|indent(8) }} }; @@ -222,15 +222,15 @@ namespace {{ Component.attrib['Namespace'] }} : public {{ ControllerNameBase }} { public: - {{ ControllerName }}({{ ComponentName }}& parent) : {{ ControllerNameBase }}(parent) {} + {{ ControllerName }}({{ ComponentName }}& parent); - void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {} - void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {} + void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override; + void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override; {% if NetworkInputCount > 0 %} //! Common input processing logic for the NetworkInput. //! @param input input structure to process //! @param deltaTime amount of time to integrate the provided inputs over - void ProcessInput([[maybe_unused]] Multiplayer::NetworkInput& input, [[maybe_unused]] float deltaTime) override {} + void ProcessInput(Multiplayer::NetworkInput& input, float deltaTime) override; {%endif %} {{ DeclareRpcHandlers(Component, 'Server', 'Authority', true)|indent(8) }} {{ DeclareRpcHandlers(Component, 'Client', 'Authority', true)|indent(8) }} @@ -239,10 +239,12 @@ namespace {{ Component.attrib['Namespace'] }} }; {% endif %} } -{% if ComponentDerived %} /// Place in your .cpp +#include <{{ Component.attrib['OverrideInclude'] }}> + namespace {{ Component.attrib['Namespace'] }} { +{% if ComponentDerived %} void {{ ComponentName }}::{{ ComponentName }}::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); @@ -251,7 +253,41 @@ namespace {{ Component.attrib['Namespace'] }} serializeContext->Class<{{ ComponentName }}, {{ ComponentNameBase }}>() ->Version(1); } + {{ ComponentNameBase }}::Reflect(context); } + + void {{ ComponentName }}::OnInit() + { + } + + void {{ ComponentName }}::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) + { + } + + void {{ ComponentName }}::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) + { + } + +{% endif %} +{% if ControllerDerived %} + {{ ControllerName }}::{{ ControllerName }}({{ ComponentName }}& parent) + : {{ ControllerNameBase }}(parent) + { + } + + void {{ ControllerName }}::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) + { + } + + void {{ ControllerName }}::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) + { + } +{% if NetworkInputCount > 0 %} + + void {{ ControllerName }}::ProcessInput([[maybe_unused]] Multiplayer::NetworkInput& input, [[maybe_unused]] float deltaTime) + { + } +{% endif %} } {% endif %} */ diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja index c22945c983..0d4e7146a0 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja @@ -7,25 +7,25 @@ {% macro DeclareNetworkPropertyGetter(Property) %} {% set PropertyName = UpperFirst(Property.attrib['Name']) %} {% if Property.attrib['Container'] == 'Array' %} -{% if Property.attrib['GenerateEventBindings']|booleanTrue %} -void {{ PropertyName }}AddEvent(AZ::Event::Handler& handler); -{% endif %} const AZStd::array<{% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{% endif %}{{ Property.attrib['Type'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, Multiplayer::k_RewindHistorySize>{% endif %}, {{ Property.attrib['Count'] }}> &Get{{ PropertyName }}Array() const; const {{ Property.attrib['Type'] }} &Get{{ PropertyName }}(int32_t index) const; -{% elif Property.attrib['Container'] == 'Vector' %} {% if Property.attrib['GenerateEventBindings']|booleanTrue %} void {{ PropertyName }}AddEvent(AZ::Event::Handler& handler); -void {{ PropertyName }}SizeChangedAddEvent(AZ::Event::Handler& handler); {% endif %} +{% elif Property.attrib['Container'] == 'Vector' %} const AZStd::fixed_vector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> &Get{{ PropertyName }}Vector() const; const {{ Property.attrib['Type'] }} &Get{{ PropertyName }}(int32_t index) const; const {{ Property.attrib['Type'] }} &{{ PropertyName }}GetBack() const; uint32_t {{ PropertyName }}GetSize() const; +{% if Property.attrib['GenerateEventBindings']|booleanTrue %} +void {{ PropertyName }}AddEvent(AZ::Event::Handler& handler); +void {{ PropertyName }}SizeChangedAddEvent(AZ::Event::Handler& handler); +{% endif %} {% else %} +const {{ Property.attrib['Type'] }}& Get{{ PropertyName }}() const; {% if Property.attrib['GenerateEventBindings']|booleanTrue %} void {{ PropertyName }}AddEvent(AZ::Event<{{ Property.attrib['Type'] }}>::Handler& handler); {% endif %} -const {{ Property.attrib['Type'] }}& Get{{ PropertyName }}() const; {% endif %} {% endmacro %} {# @@ -221,14 +221,14 @@ AZStd::fixed_vector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] } #include #include #include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include {% call(Include) AutoComponentMacros.ParseIncludes(Component) %} #include <{{ Include.attrib['File'] }}> {% endcall %} @@ -323,17 +323,19 @@ namespace {{ Component.attrib['Namespace'] }} }; {% if NetworkInputCount > 0 %} - class NetworkInput + class {{ ComponentName }}NetworkInput : public Multiplayer::IMultiplayerComponentInput { public: - Multiplayer::NetComponentId GetComponentId() const override; - INetworkInput& operator=(const INetworkInput& rhs) override; - bool Serialize(AzNetworking::ISerializer& serializer); + Multiplayer::NetComponentId GetNetComponentId() const override; + bool Serialize(AzNetworking::ISerializer& serializer) override; {% call(Input) AutoComponentMacros.ParseNetworkInputs(Component) %} {{ Input.attrib['Type'] }} m_{{ LowerFirst(Input.attrib['Name']) }} = {{ Input.attrib['Type'] }}({{ Input.attrib['Init'] }}); {% endcall %} + + static Multiplayer::NetComponentId s_netComponentId; + friend void RegisterMultiplayerComponents(); }; {% endif %} @@ -415,6 +417,8 @@ namespace {{ Component.attrib['Namespace'] }} static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + static AZStd::unique_ptr AllocateComponentInput(); + {{ ComponentBaseName }}() = default; ~{{ ComponentBaseName }}() override = default; @@ -428,6 +432,7 @@ namespace {{ Component.attrib['Namespace'] }} {% endif %} {{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Server', false)|indent(8) -}} + {{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Autonomous', false)|indent(8) -}} {{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Client', false)|indent(8) }} {{ DeclareArchetypePropertyGetters(Component)|indent(8) -}} {{ DeclareRpcInvocations(Component, 'Server', 'Authority', false)|indent(8) }} diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 200d38910b..516e6a05e8 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -476,7 +476,7 @@ bool {{ ClassName }}::Serialize{{ AutoComponentMacros.GetNetPropertiesSetName(Re {%- if networkPropertyCount.update({'value': networkPropertyCount.value + 1}) %}{% endif -%} {% endcall %} {% if networkPropertyCount.value > 0 %} - MultiplayerStats& stats = GetMultiplayer()->GetStats(); + Multiplayer::MultiplayerStats& stats = Multiplayer::GetMultiplayer()->GetStats(); // We modify the record if we are writing an update so that we don't notify for a change that really didn't change the value (just a duplicated send from the server) [[maybe_unused]] bool modifyRecord = serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject; {% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %} @@ -492,9 +492,9 @@ bool {{ ClassName }}::Serialize{{ AutoComponentMacros.GetNetPropertiesSetName(Re if (deltaRecord.AnySet()) { {% if Property.attrib['Container'] == 'Vector' %} - NovaNet::SerializableFixedSizeVectorDeltaStruct<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> deltaStruct(m_{{ LowerFirst(Property.attrib['Name']) }}, deltaRecord); + Multiplayer::SerializableFixedSizeVectorDeltaStruct<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> deltaStruct(m_{{ LowerFirst(Property.attrib['Name']) }}, deltaRecord); {% else %} - NovaNet::SerializableFixedSizeArrayDeltaStruct<{% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{% endif %}{{ Property.attrib['Type'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, Multiplayer::RewindHistorySize>{% endif %}, {{ Property.attrib['Count'] }}> deltaStruct(m_{{ Property.attrib['Name'] }}, deltaRecord); + Multiplayer::SerializableFixedSizeArrayDeltaStruct<{% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{% endif %}{{ Property.attrib['Type'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, Multiplayer::RewindHistorySize>{% endif %}, {{ Property.attrib['Count'] }}> deltaStruct(m_{{ Property.attrib['Name'] }}, deltaRecord); {% endif %} serializer.Serialize(deltaStruct, "{{ UpperFirst(Property.attrib['Name']) }}"); } @@ -509,7 +509,7 @@ bool {{ ClassName }}::Serialize{{ AutoComponentMacros.GetNetPropertiesSetName(Re m_{{ LowerFirst(Property.attrib['Name']) }}, "{{ Property.attrib['Name'] }}", GetNetComponentId(), - static_cast({{ UpperFirst(Component.attrib['Name']) }}Internal::NetworkProperties::{{ UpperFirst(Property.attrib['Name']) }}), + static_cast({{ UpperFirst(Component.attrib['Name']) }}Internal::NetworkProperties::{{ UpperFirst(Property.attrib['Name']) }}), stats ); {% endif %} @@ -902,8 +902,8 @@ m_{{ LowerFirst(Property.attrib['Name']) }} = m_{{ LowerFirst(Property.attrib['N #include #include #include -#include -#include +#include +#include {% if ComponentDerived or ControllerDerived %} #include <{{ Component.attrib['OverrideInclude'] }}> {% endif %} @@ -916,6 +916,9 @@ m_{{ LowerFirst(Property.attrib['Name']) }} = m_{{ LowerFirst(Property.attrib['N namespace {{ Component.attrib['Namespace'] }} { Multiplayer::NetComponentId {{ UpperFirst(ComponentBaseName) }}::s_netComponentId = Multiplayer::InvalidNetComponentId; +{% if NetworkInputCount > 0 %} + Multiplayer::NetComponentId {{ ComponentName }}NetworkInput::s_netComponentId = Multiplayer::InvalidNetComponentId; +{% endif %} namespace {{ UpperFirst(Component.attrib['Name']) }}Internal { @@ -1051,6 +1054,21 @@ namespace {{ Component.attrib['Namespace'] }} {{ GenerateModelReplicationRecordPredictableBits(Component, ClassType, 'Autonomous', 'Authority')|indent(8) }} } +{% if NetworkInputCount > 0 %} + Multiplayer::NetComponentId {{ ComponentName }}NetworkInput::GetNetComponentId() const + { + return {{ ComponentName }}NetworkInput::s_netComponentId; + } + + bool {{ ComponentName }}NetworkInput::Serialize(AzNetworking::ISerializer& serializer) + { +{% call(Input) AutoComponentMacros.ParseNetworkInputs(Component) %} + serializer.Serialize(m_{{ LowerFirst(Input.attrib['Name']) }}, "{{ UpperFirst(Input.attrib['Name']) }}"); +{% endcall %} + return serializer.IsValid(); + } + +{% endif %} {{ ControllerBaseName }}::{{ ControllerBaseName }}({{ ComponentName }}& parent) : MultiplayerController(parent) { @@ -1107,10 +1125,10 @@ namespace {{ Component.attrib['Namespace'] }} {{ DefineRpcInvocations(Component, ControllerBaseName, 'Authority', 'Client', true)|indent(4) }} {% for Service in Component.iter('ComponentRelation') %} {% if (Service.attrib['HasController']|booleanTrue) and (Service.attrib['Constraint'] != 'Incompatible') %} - {{ Service.attrib['Name'] }}Controller* {{ ControllerBaseName }}::Get{{ Service.attrib['Name'] }}Controller() + {{ Service.attrib['Namespace'] }}::{{ Service.attrib['Name'] }}Controller* {{ ControllerBaseName }}::Get{{ Service.attrib['Name'] }}Controller() { - MultiplayerComponent* controllerComponent = GetParent().Get{{ Service.attrib['Name'] }}(); - return static_cast<{{ Service.attrib['Name'] }}Controller*>(controllerComponent->GetController()); + Multiplayer::MultiplayerComponent* controllerComponent = GetParent().Get{{ Service.attrib['Name'] }}(); + return static_cast<{{ Service.attrib['Namespace'] }}::{{ Service.attrib['Name'] }}Controller*>(controllerComponent->GetController()); } {% endif %} @@ -1164,7 +1182,7 @@ namespace {{ Component.attrib['Namespace'] }} void {{ ComponentBaseName }}::{{ ComponentBaseName }}::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC_CE("{{ ComponentName }}Service")); + provided.push_back(AZ_CRC_CE("{{ ComponentName }}")); } void {{ ComponentBaseName }}::{{ ComponentBaseName }}::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) @@ -1184,12 +1202,21 @@ namespace {{ Component.attrib['Namespace'] }} void {{ ComponentBaseName }}::{{ ComponentBaseName }}::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.push_back(AZ_CRC_CE("{{ ComponentName }}Service")); + incompatible.push_back(AZ_CRC_CE("{{ ComponentName }}")); {% call(ComponentService) ParseComponentServiceNames(Component, ClassType, 'Incompatible') %} incompatible.push_back(AZ_CRC_CE("{{ ComponentService }}")); {% endcall %} } + AZStd::unique_ptr {{ ComponentBaseName }}::AllocateComponentInput() + { +{% if NetworkInputCount > 0 %} + return AZStd::make_unique<{{ ComponentName }}NetworkInput>(); +{% else %} + return nullptr; +{% endif %} + } + void {{ ComponentBaseName }}::Init() { if (m_netBindComponent == nullptr) @@ -1408,6 +1435,7 @@ namespace {{ Component.attrib['Namespace'] }} } {% endif %} +{% endfor %} const char* {{ ComponentBaseName }}::GetNetworkPropertyName([[maybe_unused]] Multiplayer::PropertyIndex propertyIndex) { {% if NetworkPropertyCount > 0 %} @@ -1437,6 +1465,5 @@ namespace {{ Component.attrib['Namespace'] }} {% endif %} return "Unknown Rpc"; } -{% endfor %} } {% endfor %} diff --git a/Gems/Multiplayer/Code/Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.xml b/Gems/Multiplayer/Code/Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.xml index a5a7e8decd..94bdac2b5d 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.xml +++ b/Gems/Multiplayer/Code/Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.xml @@ -5,13 +5,13 @@ Namespace="Multiplayer" OverrideComponent="true" OverrideController="true" - OverrideInclude="Source/Components/LocalPredictionPlayerInputComponent.h" + OverrideInclude="Multiplayer/Components/LocalPredictionPlayerInputComponent.h" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - + - + diff --git a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml index 1260075cba..2f934979b1 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml +++ b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml @@ -3,9 +3,9 @@ - - - + + + diff --git a/Gems/Multiplayer/Code/Source/AutoGen/NetworkTransformComponent.AutoComponent.xml b/Gems/Multiplayer/Code/Source/AutoGen/NetworkTransformComponent.AutoComponent.xml index e76ac75edc..96653a607c 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/NetworkTransformComponent.AutoComponent.xml +++ b/Gems/Multiplayer/Code/Source/AutoGen/NetworkTransformComponent.AutoComponent.xml @@ -5,7 +5,7 @@ Namespace="Multiplayer" OverrideComponent="true" OverrideController="true" - OverrideInclude="Source/Components/NetworkTransformComponent.h" + OverrideInclude="Multiplayer/Components/NetworkTransformComponent.h" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> diff --git a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp index b57c465df2..46136fcde9 100644 --- a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include @@ -81,12 +81,7 @@ namespace Multiplayer , m_migrateStartHandler([this](ClientInputId migratedInputId) { OnMigrateStart(migratedInputId); }) , m_migrateEndHandler([this]() { OnMigrateEnd(); }) { - if (GetNetEntityRole() == NetEntityRole::Autonomous) - { - m_autonomousUpdateEvent.Enqueue(AZ::TimeMs{ 1 }, true); - parent.GetNetBindComponent()->AddEntityMigrationStartEventHandler(m_migrateStartHandler); - parent.GetNetBindComponent()->AddEntityMigrationEndEventHandler(m_migrateEndHandler); - } + ; } void LocalPredictionPlayerInputComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) @@ -96,6 +91,13 @@ namespace Multiplayer m_allowMigrateClientInput = true; m_serverMigrateFrameId = GetNetworkTime()->GetHostFrameId(); } + + if (IsAutonomous()) + { + m_autonomousUpdateEvent.Enqueue(AZ::TimeMs{ 1 }, true); + GetParent().GetNetBindComponent()->AddEntityMigrationStartEventHandler(m_migrateStartHandler); + GetParent().GetNetBindComponent()->AddEntityMigrationEndEventHandler(m_migrateEndHandler); + } } void LocalPredictionPlayerInputComponentController::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp index ae6fc50f5a..8542288b23 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp @@ -10,8 +10,8 @@ * */ -#include -#include +#include +#include #include namespace Multiplayer @@ -46,9 +46,24 @@ namespace Multiplayer return m_netBindComponent ? m_netBindComponent->GetNetEntityId() : InvalidNetEntityId; } - NetEntityRole MultiplayerComponent::GetNetEntityRole() const + bool MultiplayerComponent::IsAuthority() const { - return m_netBindComponent ? m_netBindComponent->GetNetEntityRole() : NetEntityRole::InvalidRole; + return m_netBindComponent ? m_netBindComponent->IsAuthority() : false; + } + + bool MultiplayerComponent::IsAutonomous() const + { + return m_netBindComponent ? m_netBindComponent->IsAutonomous() : false; + } + + bool MultiplayerComponent::IsServer() const + { + return m_netBindComponent ? m_netBindComponent->IsServer() : false; + } + + bool MultiplayerComponent::IsClient() const + { + return m_netBindComponent ? m_netBindComponent->IsClient() : false; } ConstNetworkEntityHandle MultiplayerComponent::GetEntityHandle() const diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.cpp b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.cpp index 648b28633e..7e7cbfc480 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.cpp +++ b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponentRegistry.cpp @@ -10,7 +10,7 @@ * */ -#include +#include namespace Multiplayer { @@ -21,6 +21,12 @@ namespace Multiplayer return netComponentId; } + AZStd::unique_ptr MultiplayerComponentRegistry::AllocateComponentInput(NetComponentId netComponentId) + { + const ComponentData& componentData = GetMultiplayerComponentData(netComponentId); + return AZStd::move(componentData.m_allocComponentInputFunction()); + } + const char* MultiplayerComponentRegistry::GetComponentGemName(NetComponentId netComponentId) const { const ComponentData& componentData = GetMultiplayerComponentData(netComponentId); diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp b/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp index 9b8f41d5bc..b0bafccf79 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp +++ b/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp @@ -10,9 +10,9 @@ * */ -#include -#include -#include +#include +#include +#include namespace Multiplayer { @@ -27,9 +27,14 @@ namespace Multiplayer return m_owner.GetNetEntityId(); } - NetEntityRole MultiplayerController::GetNetEntityRole() const + bool MultiplayerController::IsAuthority() const { - return GetNetBindComponent()->GetNetEntityRole(); + return GetNetBindComponent() ? GetNetBindComponent()->IsAuthority() : false; + } + + bool MultiplayerController::IsAutonomous() const + { + return GetNetBindComponent() ? GetNetBindComponent()->IsAutonomous() : false; } AZ::Entity* MultiplayerController::GetEntity() const diff --git a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp index 6dc661415e..6449f57e8e 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp @@ -10,13 +10,13 @@ * */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -110,6 +110,22 @@ namespace Multiplayer return (m_netEntityRole == NetEntityRole::Authority); } + bool NetBindComponent::IsAutonomous() const + { + return (m_netEntityRole == NetEntityRole::Autonomous) + || (m_netEntityRole == NetEntityRole::Authority) && m_allowAutonomy; + } + + bool NetBindComponent::IsServer() const + { + return (m_netEntityRole == NetEntityRole::Server); + } + + bool NetBindComponent::IsClient() const + { + return (m_netEntityRole == NetEntityRole::Client); + } + bool NetBindComponent::HasController() const { return (m_netEntityRole == NetEntityRole::Authority) @@ -136,14 +152,21 @@ namespace Multiplayer return m_netEntityHandle; } + void NetBindComponent::SetAllowAutonomy(bool value) + { + // This flag allows a player host to autonomously control their player entity, even though the entity is in an authority role + m_allowAutonomy = value; + } + MultiplayerComponentInputVector NetBindComponent::AllocateComponentInputs() { MultiplayerComponentInputVector componentInputs; const size_t multiplayerComponentSize = m_multiplayerInputComponentVector.size(); for (size_t i = 0; i < multiplayerComponentSize; ++i) { - // TODO: ComponentInput factory, needs multiplayer component architecture and autogen - AZStd::unique_ptr componentInput = nullptr; // ComponentInputFactory(multiplayerComponent->GetComponentId()); + const NetComponentId netComponentId = m_multiplayerInputComponentVector[i]->GetNetComponentId(); + AZStd::unique_ptr componentInput = AZStd::move(GetMultiplayerComponentRegistry()->AllocateComponentInput(netComponentId)); + if (componentInput != nullptr) { componentInputs.emplace_back(AZStd::move(componentInput)); diff --git a/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp index 607e2813ec..0cc4cb131e 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetworkTransformComponent.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include @@ -96,7 +96,7 @@ namespace Multiplayer void NetworkTransformComponentController::OnTransformChangedEvent(const AZ::Transform& worldTm) { - if (GetNetEntityRole() == NetEntityRole::Authority) + if (IsAuthority()) { SetRotation(worldTm.GetRotation()); SetTranslation(worldTm.GetTranslation()); diff --git a/Gems/Multiplayer/Code/Source/ConnectionData/ClientToServerConnectionData.h b/Gems/Multiplayer/Code/Source/ConnectionData/ClientToServerConnectionData.h index 449ffafe45..2e7be47842 100644 --- a/Gems/Multiplayer/Code/Source/ConnectionData/ClientToServerConnectionData.h +++ b/Gems/Multiplayer/Code/Source/ConnectionData/ClientToServerConnectionData.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h b/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h index 6274a6ba31..faa11bc225 100644 --- a/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h +++ b/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp index 1ae4bffd07..4ae7c3fdfe 100644 --- a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp @@ -138,7 +138,7 @@ namespace Multiplayer void DrawComponentDetails(const MultiplayerStats& stats, NetComponentId netComponentId) { - IMultiplayer* multiplayer = AZ::Interface::Get(); + MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry(); { const MultiplayerStats::Metric metric = stats.CalculateComponentPropertyUpdateSentMetrics(netComponentId); float callsPerSecond = 0.0f; @@ -150,7 +150,7 @@ namespace Multiplayer for (AZStd::size_t index = 0; index < componentStats.m_propertyUpdatesSent.size(); ++index) { const PropertyIndex propertyIndex = aznumeric_cast(index); - const char* propertyName = multiplayer->GetComponentPropertyName(netComponentId, propertyIndex); + const char* propertyName = componentRegistry->GetComponentPropertyName(netComponentId, propertyIndex); const MultiplayerStats::Metric& subMetric = componentStats.m_propertyUpdatesSent[index]; callsPerSecond = 0.0f; bytesPerSecond = 0.0f; @@ -172,7 +172,7 @@ namespace Multiplayer for (AZStd::size_t index = 0; index < componentStats.m_propertyUpdatesRecv.size(); ++index) { const PropertyIndex propertyIndex = aznumeric_cast(index); - const char* propertyName = multiplayer->GetComponentPropertyName(netComponentId, propertyIndex); + const char* propertyName = componentRegistry->GetComponentPropertyName(netComponentId, propertyIndex); const MultiplayerStats::Metric& subMetric = componentStats.m_propertyUpdatesRecv[index]; callsPerSecond = 0.0f; bytesPerSecond = 0.0f; @@ -194,7 +194,7 @@ namespace Multiplayer for (AZStd::size_t index = 0; index < componentStats.m_rpcsSent.size(); ++index) { const RpcIndex rpcIndex = aznumeric_cast(index); - const char* rpcName = multiplayer->GetComponentRpcName(netComponentId, rpcIndex); + const char* rpcName = componentRegistry->GetComponentRpcName(netComponentId, rpcIndex); const MultiplayerStats::Metric& subMetric = componentStats.m_rpcsSent[index]; callsPerSecond = 0.0f; bytesPerSecond = 0.0f; @@ -216,7 +216,7 @@ namespace Multiplayer for (AZStd::size_t index = 0; index < componentStats.m_rpcsRecv.size(); ++index) { const RpcIndex rpcIndex = aznumeric_cast(index); - const char* rpcName = multiplayer->GetComponentRpcName(netComponentId, rpcIndex); + const char* rpcName = componentRegistry->GetComponentRpcName(netComponentId, rpcIndex); const MultiplayerStats::Metric& subMetric = componentStats.m_rpcsRecv[index]; callsPerSecond = 0.0f; bytesPerSecond = 0.0f; @@ -238,6 +238,7 @@ namespace Multiplayer if (ImGui::Begin("Multiplayer Stats", &m_displayMultiplayerStats, ImGuiWindowFlags_None)) { IMultiplayer* multiplayer = AZ::Interface::Get(); + MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry(); const Multiplayer::MultiplayerStats& stats = multiplayer->GetStats(); ImGui::Text("Multiplayer operating in %s mode", GetEnumString(multiplayer->GetAgentType())); ImGui::Text("Total networked entities: %llu", aznumeric_cast(stats.m_entityCount)); @@ -267,8 +268,8 @@ namespace Multiplayer { const NetComponentId netComponentId = aznumeric_cast(index); using StringLabel = AZStd::fixed_string<128>; - const StringLabel gemName = multiplayer->GetComponentGemName(netComponentId); - const StringLabel componentName = multiplayer->GetComponentName(netComponentId); + const StringLabel gemName = componentRegistry->GetComponentGemName(netComponentId); + const StringLabel componentName = componentRegistry->GetComponentName(netComponentId); const StringLabel label = gemName + "::" + componentName; if (DrawComponentRow(label.c_str(), stats, netComponentId)) { diff --git a/Gems/Multiplayer/Code/Source/EntityDomains/FullOwnershipEntityDomain.h b/Gems/Multiplayer/Code/Source/EntityDomains/FullOwnershipEntityDomain.h index 3bf6eb554f..d8d264dc34 100644 --- a/Gems/Multiplayer/Code/Source/EntityDomains/FullOwnershipEntityDomain.h +++ b/Gems/Multiplayer/Code/Source/EntityDomains/FullOwnershipEntityDomain.h @@ -12,7 +12,7 @@ #pragma once -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/MultiplayerGem.cpp b/Gems/Multiplayer/Code/Source/MultiplayerGem.cpp index aef3e546ad..14bb71bcd5 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerGem.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerGem.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.cpp b/Gems/Multiplayer/Code/Source/MultiplayerStats.cpp similarity index 100% rename from Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerStats.cpp rename to Gems/Multiplayer/Code/Source/MultiplayerStats.cpp diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 80a09d7d48..a10bbf8a1a 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -576,26 +576,6 @@ namespace Multiplayer return &m_networkEntityManager; } - const char* MultiplayerSystemComponent::GetComponentGemName(NetComponentId netComponentId) const - { - return GetMultiplayerComponentRegistry()->GetComponentGemName(netComponentId); - } - - const char* MultiplayerSystemComponent::GetComponentName(NetComponentId netComponentId) const - { - return GetMultiplayerComponentRegistry()->GetComponentName(netComponentId); - } - - const char* MultiplayerSystemComponent::GetComponentPropertyName(NetComponentId netComponentId, PropertyIndex propertyIndex) const - { - return GetMultiplayerComponentRegistry()->GetComponentPropertyName(netComponentId, propertyIndex); - } - - const char* MultiplayerSystemComponent::GetComponentRpcName(NetComponentId netComponentId, RpcIndex rpcIndex) const - { - return GetMultiplayerComponentRegistry()->GetComponentRpcName(netComponentId, rpcIndex); - } - void MultiplayerSystemComponent::DumpStats([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) { const MultiplayerStats& stats = GetStats(); diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index ba59a82eae..6bedd0599b 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -94,10 +94,6 @@ namespace Multiplayer AZ::TimeMs GetCurrentHostTimeMs() const override; INetworkTime* GetNetworkTime() override; INetworkEntityManager* GetNetworkEntityManager() override; - const char* GetComponentGemName(NetComponentId netComponentId) const override; - const char* GetComponentName(NetComponentId netComponentId) const override; - const char* GetComponentPropertyName(NetComponentId netComponentId, PropertyIndex propertyIndex) const override; - const char* GetComponentRpcName(NetComponentId netComponentId, RpcIndex rpcIndex) const override; //! @} //! Console commands. diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp index 286090ca74..e47d142be8 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp @@ -15,13 +15,13 @@ #include #include #include -#include -#include -#include -#include #include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -828,12 +828,11 @@ namespace Multiplayer { if (entityReplicator == nullptr) { - IMultiplayer* multiplayer = GetMultiplayer(); AZLOG_INFO ( "EntityReplicationManager: Dropping remote RPC message for component %s of rpc index %s, entityId %u has already been deleted", - multiplayer->GetComponentName(message.GetComponentId()), - multiplayer->GetComponentRpcName(message.GetComponentId(), message.GetRpcIndex()), + GetMultiplayerComponentRegistry()->GetComponentName(message.GetComponentId()), + GetMultiplayerComponentRegistry()->GetComponentRpcName(message.GetComponentId(), message.GetRpcIndex()), message.GetEntityId() ); return false; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.h b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.h index 50a4ad43d4..083413e19e 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.h @@ -13,11 +13,11 @@ #pragma once #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp index 15293d518d..f84487080b 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp @@ -16,11 +16,11 @@ #include #include #include -#include #include #include -#include -#include +#include +#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.h b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.h index 3587c28975..ced665abf3 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.h @@ -18,8 +18,8 @@ #include #include #include -#include -#include +#include +#include namespace AzNetworking { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.h b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.h index be8ac1b65b..fb23adfbd5 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace AzNetworking diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp index 4994884364..b74c8af081 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertySubscriber.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp index 6aa6c10b11..41cc86aaee 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp @@ -10,7 +10,7 @@ * */ -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp index ecfd416380..f30b7ee9e0 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp @@ -11,8 +11,8 @@ */ #include -#include -#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp index 0dd7292d25..3ca56f01b3 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp @@ -10,10 +10,10 @@ * */ -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp index 28b72abf25..6f3fdf2b23 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h index e763e7ebca..3291f2c38d 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h @@ -18,10 +18,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp index d58c192162..f636fb6447 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.cpp index 42104e79fd..2dac90deee 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.h index 34f5d03f2f..1b4b7f15f1 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityTracker.h @@ -13,7 +13,7 @@ #pragma once #include -#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp index 5ece0c7157..3fe5a497cb 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp index eafd4375e7..7b9cba5a93 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp @@ -10,8 +10,10 @@ * */ -#include -#include +#include +#include +#include +#include #include #include @@ -111,13 +113,12 @@ namespace Multiplayer // This happens when deserializing a non-delta'd input command // However in the delta serializer case, we use the previous input as our initial value // which will have the NetworkInputs setup and therefore won't write out the componentId - NetComponentId componentId = m_componentInputs[i] ? m_componentInputs[i]->GetComponentId() : InvalidNetComponentId; + NetComponentId componentId = m_componentInputs[i] ? m_componentInputs[i]->GetNetComponentId() : InvalidNetComponentId; serializer.Serialize(componentId, "ComponentType"); // Create a new input if we don't have one or the types do not match - if ((m_componentInputs[i] == nullptr) || (componentId != m_componentInputs[i]->GetComponentId())) + if ((m_componentInputs[i] == nullptr) || (componentId != m_componentInputs[i]->GetNetComponentId())) { - // TODO: ComponentInput factory, needs multiplayer component architecture and autogen - m_componentInputs[i] = nullptr; // ComponentInputFactory(componentId); + m_componentInputs[i] = AZStd::move(GetMultiplayerComponentRegistry()->AllocateComponentInput(componentId)); } if (!m_componentInputs[i]) { @@ -135,7 +136,7 @@ namespace Multiplayer // We assume that the order of the network inputs is fixed between the server and client for (auto& componentInput : m_componentInputs) { - NetComponentId componentId = componentInput->GetComponentId(); + NetComponentId componentId = componentInput->GetNetComponentId(); serializer.Serialize(componentId, "ComponentId"); serializer.Serialize(*componentInput, "ComponentInput"); } @@ -148,7 +149,7 @@ namespace Multiplayer // linear search since we expect to have very few components for (auto& componentInput : m_componentInputs) { - if (componentInput->GetComponentId() == componentId) + if (componentInput->GetNetComponentId() == componentId) { return componentInput.get(); } @@ -169,10 +170,10 @@ namespace Multiplayer m_componentInputs.resize(rhs.m_componentInputs.size()); for (int32_t i = 0; i < rhs.m_componentInputs.size(); ++i) { - if (m_componentInputs[i] == nullptr || m_componentInputs[i]->GetComponentId() != rhs.m_componentInputs[i]->GetComponentId()) + const NetComponentId rhsComponentId = rhs.m_componentInputs[i]->GetNetComponentId(); + if (m_componentInputs[i] == nullptr || m_componentInputs[i]->GetNetComponentId() != rhsComponentId) { - // TODO: ComponentInput factory, needs multiplayer component architecture and autogen - m_componentInputs[i] = nullptr; // ComponentInputFactory(rhs.m_componentInputs[i]->GetComponentId()); + m_componentInputs[i] = AZStd::move(GetMultiplayerComponentRegistry()->AllocateComponentInput(rhsComponentId)); } *m_componentInputs[i] = *rhs.m_componentInputs[i]; } diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp index 82e5cea0c4..d95310e4b5 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h index d5cbcbbed3..b67ce79112 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h @@ -12,8 +12,8 @@ #pragma once -#include -#include +#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.h index fa4ab1e4e9..e81bce0210 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputChild.h @@ -12,7 +12,7 @@ #pragma once -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputHistory.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputHistory.h index c5f0a70fd3..76eeebf73a 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputHistory.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputHistory.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.h index 454cef4e0a..e5f8fdf648 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputMigrationVector.h @@ -12,8 +12,8 @@ #pragma once -#include -#include +#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp index d991e59d05..98ece0a8cc 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp @@ -11,8 +11,8 @@ */ #include -#include #include +#include #include namespace Multiplayer diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h index ff2da0f759..f714e046b3 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.h @@ -12,7 +12,7 @@ #pragma once -#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp index 805a982506..4661df7564 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/NullReplicationWindow.h b/Gems/Multiplayer/Code/Source/ReplicationWindows/NullReplicationWindow.h index 5cb9c0de70..f633a35a14 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/NullReplicationWindow.h +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/NullReplicationWindow.h @@ -12,7 +12,7 @@ #pragma once -#include +#include namespace Multiplayer { diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp index bf370c1952..d048476cc0 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.cpp @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h index 25fbfd481d..fc143a7cc4 100644 --- a/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h +++ b/Gems/Multiplayer/Code/Source/ReplicationWindows/ServerToClientReplicationWindow.h @@ -13,8 +13,8 @@ #pragma once #include -#include -#include +#include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp b/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp index f614dc2690..4596e3b35c 100644 --- a/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp +++ b/Gems/Multiplayer/Code/Tests/RewindableObjectTests.cpp @@ -10,8 +10,8 @@ * */ -#include #include +#include #include #include #include diff --git a/Gems/Multiplayer/Code/multiplayer_files.cmake b/Gems/Multiplayer/Code/multiplayer_files.cmake index 26909cbfd3..7b335854fa 100644 --- a/Gems/Multiplayer/Code/multiplayer_files.cmake +++ b/Gems/Multiplayer/Code/multiplayer_files.cmake @@ -10,33 +10,34 @@ # set(FILES - Include/Multiplayer/IConnectionData.h - Include/Multiplayer/IEntityDomain.h Include/Multiplayer/IMultiplayer.h - Include/Multiplayer/IMultiplayerComponentInput.h - Include/Multiplayer/INetworkEntityManager.h - Include/Multiplayer/INetworkPlayerSpawner.h - Include/Multiplayer/INetworkTime.h - Include/Multiplayer/IReplicationWindow.h - Include/Multiplayer/MultiplayerComponent.h - Include/Multiplayer/MultiplayerController.h - Include/Multiplayer/MultiplayerComponentRegistry.h - Include/Multiplayer/MultiplayerStats.cpp Include/Multiplayer/MultiplayerStats.h Include/Multiplayer/MultiplayerTypes.h - Include/Multiplayer/NetBindComponent.h - Include/Multiplayer/NetworkEntityRpcMessage.h - Include/Multiplayer/NetworkEntityUpdateMessage.h - Include/Multiplayer/NetworkEntityHandle.h - Include/Multiplayer/NetworkEntityHandle.inl - Include/Multiplayer/NetworkInput.h - Include/Multiplayer/ReplicationRecord.h - Include/Multiplayer/RewindableObject.h - Include/Multiplayer/RewindableObject.inl + Include/Multiplayer/Components/LocalPredictionPlayerInputComponent.h + Include/Multiplayer/Components/MultiplayerComponent.h + Include/Multiplayer/Components/MultiplayerController.h + Include/Multiplayer/Components/MultiplayerComponentRegistry.h + Include/Multiplayer/Components/NetBindComponent.h + Include/Multiplayer/Components/NetworkTransformComponent.h + Include/Multiplayer/ConnectionData/IConnectionData.h + Include/Multiplayer/EntityDomains/IEntityDomain.h + Include/Multiplayer/NetworkEntity/INetworkEntityManager.h + Include/Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h + Include/Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h + Include/Multiplayer/NetworkEntity/NetworkEntityHandle.h + Include/Multiplayer/NetworkEntity/NetworkEntityHandle.inl + Include/Multiplayer/NetworkEntity/EntityReplication/ReplicationRecord.h + Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h + Include/Multiplayer/NetworkInput/NetworkInput.h + Include/Multiplayer/NetworkTime/INetworkTime.h + Include/Multiplayer/NetworkTime/RewindableObject.h + Include/Multiplayer/NetworkTime/RewindableObject.inl + Include/Multiplayer/ReplicationWindows/IReplicationWindow.h Source/Multiplayer_precompiled.cpp Source/Multiplayer_precompiled.h Source/MultiplayerSystemComponent.cpp Source/MultiplayerSystemComponent.h + Source/MultiplayerStats.cpp Source/AutoGen/AutoComponent_Header.jinja Source/AutoGen/AutoComponent_Source.jinja Source/AutoGen/AutoComponent_Common.jinja @@ -46,13 +47,11 @@ set(FILES Source/AutoGen/Multiplayer.AutoPackets.xml Source/AutoGen/NetworkTransformComponent.AutoComponent.xml Source/Components/LocalPredictionPlayerInputComponent.cpp - Source/Components/LocalPredictionPlayerInputComponent.h Source/Components/MultiplayerComponent.cpp Source/Components/MultiplayerController.cpp Source/Components/MultiplayerComponentRegistry.cpp Source/Components/NetBindComponent.cpp Source/Components/NetworkTransformComponent.cpp - Source/Components/NetworkTransformComponent.h Source/ConnectionData/ClientToServerConnectionData.cpp Source/ConnectionData/ClientToServerConnectionData.h Source/ConnectionData/ClientToServerConnectionData.inl From 9ecbbe471bbeb42a732aae8e5f8b04dd424d05c7 Mon Sep 17 00:00:00 2001 From: bosnichd Date: Fri, 14 May 2021 15:38:59 -0600 Subject: [PATCH 219/225] Remove lots of unused things from CrySystem (#765) Remove lots of unused things from CrySystem --- Code/CryEngine/CryCommon/ILZ4Decompressor.h | 32 - Code/CryEngine/CryCommon/ISystem.h | 104 - Code/CryEngine/CryCommon/ITextModeConsole.h | 35 - Code/CryEngine/CryCommon/IZLibCompressor.h | 219 - Code/CryEngine/CryCommon/IZStdDecompressor.h | 25 - Code/CryEngine/CryCommon/IZlibDecompressor.h | 94 - Code/CryEngine/CryCommon/Mocks/ISystemMock.h | 35 - Code/CryEngine/CryCommon/ProjectDefines.h | 2 - Code/CryEngine/CryCommon/RenderBus.h | 8 - .../CryEngine/CryCommon/crycommon_files.cmake | 5 - Code/CryEngine/CrySystem/AndroidConsole.cpp | 94 - Code/CryEngine/CrySystem/AndroidConsole.h | 62 - Code/CryEngine/CrySystem/AutoDetectSpec.cpp | 1097 --- Code/CryEngine/CrySystem/AutoDetectSpec.h | 54 - Code/CryEngine/CrySystem/CMakeLists.txt | 63 - Code/CryEngine/CrySystem/CPUDetect.cpp | 1622 ---- Code/CryEngine/CrySystem/CPUDetect.h | 180 - Code/CryEngine/CrySystem/ClientHandler.cpp | 90 - Code/CryEngine/CrySystem/ClientHandler.h | 36 - .../Components/MathConversionTests.cpp | 167 - Code/CryEngine/CrySystem/CompressedFile.cpp | 38 - Code/CryEngine/CrySystem/CryAsyncMemcpy.cpp | 58 - Code/CryEngine/CrySystem/CryDLMalloc.c | 6645 ----------------- Code/CryEngine/CrySystem/CrySystem.rc | 91 - Code/CryEngine/CrySystem/CryWaterMark.h | 34 - Code/CryEngine/CrySystem/HandlerBase.cpp | 131 - Code/CryEngine/CrySystem/HandlerBase.h | 35 - Code/CryEngine/CrySystem/IOSConsole.h | 54 - Code/CryEngine/CrySystem/IOSConsole.mm | 94 - Code/CryEngine/CrySystem/LZ4Decompressor.cpp | 29 - Code/CryEngine/CrySystem/LZ4Decompressor.h | 35 - .../CrySystem/LevelSystem/LevelSystem.cpp | 10 - Code/CryEngine/CrySystem/Log.cpp | 24 +- Code/CryEngine/CrySystem/MobileDetectSpec.cpp | 151 - Code/CryEngine/CrySystem/MobileDetectSpec.h | 35 - .../CrySystem/MobileDetectSpec_Android.cpp | 47 - .../CrySystem/MobileDetectSpec_Ios.cpp | 40 - Code/CryEngine/CrySystem/PhysRenderer.cpp | 18 - Code/CryEngine/CrySystem/PhysRenderer.h | 22 - .../Platform/Android/platform_android.cmake | 16 - .../Android/platform_android_files.cmake | 18 - .../Platform/Linux/platform_linux.cmake | 21 - .../Platform/Linux/platform_linux_files.cmake | 13 - .../CrySystem/Platform/Mac/platform_mac.cmake | 16 - .../Platform/Mac/platform_mac_files.cmake | 10 - .../Platform/Windows/platform_windows.cmake | 16 - .../Windows/platform_windows_files.cmake | 13 - .../CrySystem/Platform/iOS/platform_ios.cmake | 22 - .../Platform/iOS/platform_ios_files.cmake | 18 - Code/CryEngine/CrySystem/SSAPI.DLL | 3 - Code/CryEngine/CrySystem/Sampler.cpp | 287 - Code/CryEngine/CrySystem/Sampler.h | 82 - Code/CryEngine/CrySystem/ServerHandler.cpp | 85 - Code/CryEngine/CrySystem/ServerHandler.h | 36 - Code/CryEngine/CrySystem/ServerThrottle.cpp | 164 - Code/CryEngine/CrySystem/ServerThrottle.h | 48 - Code/CryEngine/CrySystem/SyncLock.cpp | 246 - Code/CryEngine/CrySystem/SyncLock.h | 48 - Code/CryEngine/CrySystem/System.cpp | 162 - Code/CryEngine/CrySystem/System.h | 139 - Code/CryEngine/CrySystem/SystemInit.cpp | 725 +- Code/CryEngine/CrySystem/SystemInit.h | 36 - Code/CryEngine/CrySystem/SystemRender.cpp | 115 - Code/CryEngine/CrySystem/SystemWin32.cpp | 1 - Code/CryEngine/CrySystem/Tests/Test_CLog.cpp | 187 - .../Tests/Test_CommandRegistration.cpp | 282 - .../CrySystem/Tests/Test_CryPrimitives.cpp | 463 -- .../CrySystem/Tests/Test_Localization.cpp | 157 - .../CrySystem/Tests/test_CrySystem.cpp | 54 - Code/CryEngine/CrySystem/Tests/test_Main.cpp | 43 - .../CrySystem/Tests/test_MaterialUtils.cpp | 84 - Code/CryEngine/CrySystem/Timer.h | 2 +- Code/CryEngine/CrySystem/UnixConsole.cpp | 2518 ------- Code/CryEngine/CrySystem/UnixConsole.h | 573 -- Code/CryEngine/CrySystem/Validator.h | 66 - Code/CryEngine/CrySystem/WindowsConsole.cpp | 1153 --- Code/CryEngine/CrySystem/WindowsConsole.h | 245 - .../CrySystem/WindowsErrorReporting.cpp | 151 - Code/CryEngine/CrySystem/ZLibCompressor.cpp | 336 - Code/CryEngine/CrySystem/ZLibCompressor.h | 36 - Code/CryEngine/CrySystem/ZLibDecompressor.cpp | 251 - Code/CryEngine/CrySystem/ZLibDecompressor.h | 35 - Code/CryEngine/CrySystem/ZStdDecompressor.cpp | 26 - Code/CryEngine/CrySystem/ZStdDecompressor.h | 28 - Code/CryEngine/CrySystem/ZipFile.h | 19 - Code/CryEngine/CrySystem/ZipFileFormat_info.h | 76 - Code/CryEngine/CrySystem/crash_face.bmp | 3 - .../CrySystem/crysystem_android_files.cmake | 18 - .../CrySystem/crysystem_dlmalloc_files.cmake | 14 - .../CryEngine/CrySystem/crysystem_files.cmake | 40 - .../CrySystem/crysystem_ios_files.cmake | 16 - .../CrySystem/crysystem_mac_files.cmake | 11 - .../CrySystem/crysystem_test_files.cmake | 22 - Code/CryEngine/CrySystem/resource.h | 38 - .../AzFramework/Thermal}/ThermalInfo.h | 0 .../AzFramework/azframework_files.cmake | 1 + .../Application/Application_Android.cpp | 6 + .../Thermal/ThermalInfo_Android.cpp} | 2 +- .../Thermal/ThermalInfo_Android.h} | 2 +- .../Android/platform_android_files.cmake | 2 + Code/Sandbox/Editor/GameEngine.cpp | 1 - .../Sandbox/Editor/GraphicsSettingsDialog.cpp | 30 - Code/Sandbox/Editor/IEditorImpl.cpp | 9 +- Code/Sandbox/Editor/Util/PathUtil.cpp | 15 - .../Windows/package_filelists/atom.json | 1 - 105 files changed, 15 insertions(+), 20956 deletions(-) delete mode 100644 Code/CryEngine/CryCommon/ILZ4Decompressor.h delete mode 100644 Code/CryEngine/CryCommon/ITextModeConsole.h delete mode 100644 Code/CryEngine/CryCommon/IZLibCompressor.h delete mode 100644 Code/CryEngine/CryCommon/IZStdDecompressor.h delete mode 100644 Code/CryEngine/CryCommon/IZlibDecompressor.h delete mode 100644 Code/CryEngine/CrySystem/AndroidConsole.cpp delete mode 100644 Code/CryEngine/CrySystem/AndroidConsole.h delete mode 100644 Code/CryEngine/CrySystem/AutoDetectSpec.cpp delete mode 100644 Code/CryEngine/CrySystem/AutoDetectSpec.h delete mode 100644 Code/CryEngine/CrySystem/CPUDetect.cpp delete mode 100644 Code/CryEngine/CrySystem/CPUDetect.h delete mode 100644 Code/CryEngine/CrySystem/ClientHandler.cpp delete mode 100644 Code/CryEngine/CrySystem/ClientHandler.h delete mode 100644 Code/CryEngine/CrySystem/Components/MathConversionTests.cpp delete mode 100644 Code/CryEngine/CrySystem/CompressedFile.cpp delete mode 100644 Code/CryEngine/CrySystem/CryAsyncMemcpy.cpp delete mode 100644 Code/CryEngine/CrySystem/CryDLMalloc.c delete mode 100644 Code/CryEngine/CrySystem/CrySystem.rc delete mode 100644 Code/CryEngine/CrySystem/CryWaterMark.h delete mode 100644 Code/CryEngine/CrySystem/HandlerBase.cpp delete mode 100644 Code/CryEngine/CrySystem/HandlerBase.h delete mode 100644 Code/CryEngine/CrySystem/IOSConsole.h delete mode 100644 Code/CryEngine/CrySystem/IOSConsole.mm delete mode 100644 Code/CryEngine/CrySystem/LZ4Decompressor.cpp delete mode 100644 Code/CryEngine/CrySystem/LZ4Decompressor.h delete mode 100644 Code/CryEngine/CrySystem/MobileDetectSpec.cpp delete mode 100644 Code/CryEngine/CrySystem/MobileDetectSpec.h delete mode 100644 Code/CryEngine/CrySystem/MobileDetectSpec_Android.cpp delete mode 100644 Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp delete mode 100644 Code/CryEngine/CrySystem/PhysRenderer.cpp delete mode 100644 Code/CryEngine/CrySystem/PhysRenderer.h delete mode 100644 Code/CryEngine/CrySystem/Platform/Android/platform_android.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/Android/platform_android_files.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/Linux/platform_linux.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/Linux/platform_linux_files.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/Windows/platform_windows.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/Windows/platform_windows_files.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/iOS/platform_ios.cmake delete mode 100644 Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake delete mode 100644 Code/CryEngine/CrySystem/SSAPI.DLL delete mode 100644 Code/CryEngine/CrySystem/Sampler.cpp delete mode 100644 Code/CryEngine/CrySystem/Sampler.h delete mode 100644 Code/CryEngine/CrySystem/ServerHandler.cpp delete mode 100644 Code/CryEngine/CrySystem/ServerHandler.h delete mode 100644 Code/CryEngine/CrySystem/ServerThrottle.cpp delete mode 100644 Code/CryEngine/CrySystem/ServerThrottle.h delete mode 100644 Code/CryEngine/CrySystem/SyncLock.cpp delete mode 100644 Code/CryEngine/CrySystem/SyncLock.h delete mode 100644 Code/CryEngine/CrySystem/SystemInit.h delete mode 100644 Code/CryEngine/CrySystem/SystemRender.cpp delete mode 100644 Code/CryEngine/CrySystem/Tests/Test_CLog.cpp delete mode 100644 Code/CryEngine/CrySystem/Tests/Test_CommandRegistration.cpp delete mode 100644 Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp delete mode 100644 Code/CryEngine/CrySystem/Tests/Test_Localization.cpp delete mode 100644 Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp delete mode 100644 Code/CryEngine/CrySystem/Tests/test_Main.cpp delete mode 100644 Code/CryEngine/CrySystem/Tests/test_MaterialUtils.cpp delete mode 100644 Code/CryEngine/CrySystem/UnixConsole.cpp delete mode 100644 Code/CryEngine/CrySystem/UnixConsole.h delete mode 100644 Code/CryEngine/CrySystem/Validator.h delete mode 100644 Code/CryEngine/CrySystem/WindowsConsole.cpp delete mode 100644 Code/CryEngine/CrySystem/WindowsConsole.h delete mode 100644 Code/CryEngine/CrySystem/WindowsErrorReporting.cpp delete mode 100644 Code/CryEngine/CrySystem/ZLibCompressor.cpp delete mode 100644 Code/CryEngine/CrySystem/ZLibCompressor.h delete mode 100644 Code/CryEngine/CrySystem/ZLibDecompressor.cpp delete mode 100644 Code/CryEngine/CrySystem/ZLibDecompressor.h delete mode 100644 Code/CryEngine/CrySystem/ZStdDecompressor.cpp delete mode 100644 Code/CryEngine/CrySystem/ZStdDecompressor.h delete mode 100644 Code/CryEngine/CrySystem/ZipFile.h delete mode 100644 Code/CryEngine/CrySystem/ZipFileFormat_info.h delete mode 100644 Code/CryEngine/CrySystem/crash_face.bmp delete mode 100644 Code/CryEngine/CrySystem/crysystem_android_files.cmake delete mode 100644 Code/CryEngine/CrySystem/crysystem_dlmalloc_files.cmake delete mode 100644 Code/CryEngine/CrySystem/crysystem_ios_files.cmake delete mode 100644 Code/CryEngine/CrySystem/crysystem_mac_files.cmake delete mode 100644 Code/CryEngine/CrySystem/crysystem_test_files.cmake delete mode 100644 Code/CryEngine/CrySystem/resource.h rename Code/{CryEngine/CryCommon => Framework/AzFramework/AzFramework/Thermal}/ThermalInfo.h (100%) rename Code/{CryEngine/CrySystem/ThermalInfoAndroid.cpp => Framework/AzFramework/Platform/Android/AzFramework/Thermal/ThermalInfo_Android.cpp} (99%) rename Code/{CryEngine/CrySystem/ThermalInfoAndroid.h => Framework/AzFramework/Platform/Android/AzFramework/Thermal/ThermalInfo_Android.h} (95%) diff --git a/Code/CryEngine/CryCommon/ILZ4Decompressor.h b/Code/CryEngine/CryCommon/ILZ4Decompressor.h deleted file mode 100644 index c136a7518d..0000000000 --- a/Code/CryEngine/CryCommon/ILZ4Decompressor.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Provides the interface for the lz4 hc decompress wrapper - -#ifndef CRYINCLUDE_CRYCOMMON_ILZ4DECOMPRESSOR_H -#define CRYINCLUDE_CRYCOMMON_ILZ4DECOMPRESSOR_H -#pragma once - - -struct ILZ4Decompressor -{ -protected: - virtual ~ILZ4Decompressor() {}; // use Release() - -public: - virtual bool DecompressData(const char* pIn, char* pOut, const uint outputSize) const = 0; - - virtual void Release() = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMON_ILZ4DECOMPRESSOR_H diff --git a/Code/CryEngine/CryCommon/ISystem.h b/Code/CryEngine/CryCommon/ISystem.h index 73341dd16f..f863804f3d 100644 --- a/Code/CryEngine/CryCommon/ISystem.h +++ b/Code/CryEngine/CryCommon/ISystem.h @@ -76,14 +76,9 @@ struct IViewSystem; class ICrySizer; class IXMLBinarySerializer; struct IReadWriteXMLSink; -struct ITextModeConsole; struct IAVI_Reader; class CPNoise3; struct ILocalizationManager; -struct IZLibCompressor; -struct IZLibDecompressor; -struct ILZ4Decompressor; -class IZStdDecompressor; struct IOutputPrintSink; struct IWindowMessageHandler; @@ -524,7 +519,6 @@ struct SSystemInitParams ISystemUserCallback* pUserCallback; const char* sLogFileName; // File name to use for log. bool autoBackupLogs; // if true, logs will be automatically backed up each startup - IValidator* pValidator; // You can specify different validator object to use by System. IOutputPrintSink* pPrintSync; // Print Sync which can be used to catch all output from engine char szSystemCmdLine[2048]; // Command line. @@ -554,7 +548,6 @@ struct SSystemInitParams pUserCallback = NULL; sLogFileName = NULL; autoBackupLogs = true; - pValidator = NULL; pPrintSync = NULL; memset(szSystemCmdLine, 0, sizeof(szSystemCmdLine)); @@ -828,14 +821,6 @@ struct ISystem // Retrieve the name of the user currently logged in to the computer. virtual const char* GetUserName() = 0; - // Summary: - // Gets current supported CPU features flags. (CPUF_SSE, CPUF_SSE2, CPUF_3DNOW, CPUF_MMX) - virtual int GetCPUFlags() = 0; - - // Summary: - // Gets number of CPUs - virtual int GetLogicalCPUCount() = 0; - // Summary: // Quits the application. virtual void Quit() = 0; @@ -852,13 +837,6 @@ struct ISystem virtual bool IsRelaunch() const = 0; - // Summary: - // Displays an error message to display info for certain time - // Arguments: - // acMessage - Message to show - // fTime - Amount of seconds to show onscreen - virtual void DisplayErrorMessage(const char* acMessage, float fTime, const float* pfColor = 0, bool bHardError = true) = 0; - // Description: // Displays error message. // Logs it to console and file and error message box then terminates execution. @@ -889,14 +867,9 @@ struct ISystem // return the related subsystem interface // - virtual IZLibCompressor* GetIZLibCompressor() = 0; - virtual IZLibDecompressor* GetIZLibDecompressor() = 0; - virtual ILZ4Decompressor* GetLZ4Decompressor() = 0; - virtual IZStdDecompressor* GetZStdDecompressor() = 0; virtual IViewSystem* GetIViewSystem() = 0; virtual ILevelSystem* GetILevelSystem() = 0; virtual INameTable* GetINameTable() = 0; - virtual IValidator* GetIValidator() = 0; virtual ICmdLine* GetICmdLine() = 0; virtual ILog* GetILog() = 0; virtual AZ::IO::IArchive* GetIPak() = 0; @@ -917,7 +890,6 @@ struct ISystem virtual bool GetForceNonDevMode() const = 0; virtual bool WasInDevMode() const = 0; virtual bool IsDevMode() const = 0; - virtual bool IsMODValid(const char* szMODName) const = 0; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -974,13 +946,6 @@ struct ISystem // Gets build version. virtual const SFileVersion& GetBuildVersion() = 0; - // Summary: - // Data compression - //##@{ - virtual bool CompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize, int level = 3) = 0; - virtual bool DecompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize) = 0; - //##@} - ////////////////////////////////////////////////////////////////////////// // Configuration. ////////////////////////////////////////////////////////////////////////// @@ -1002,21 +967,8 @@ struct ISystem // pCallback - 0 means normal LoadConfigVar behaviour is used virtual void LoadConfiguration(const char* sFilename, ILoadConfigurationEntrySink* pSink = 0, bool warnIfMissing = true) = 0; - // Summary: - // Retrieves current configuration specification for client or server. - // Arguments: - // bClient - If true returns local client config spec, if false returns server config spec. - virtual ESystemConfigSpec GetConfigSpec(bool bClient = true) = 0; - virtual ESystemConfigSpec GetMaxConfigSpec() const = 0; - // Summary: - // Changes current configuration specification for client or server. - // Arguments: - // bClient - If true changes client config spec (sys_spec variable changed), - // if false changes only server config spec (as known on the client). - virtual void SetConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient) = 0; - ////////////////////////////////////////////////////////////////////////// // Summary: @@ -1028,10 +980,6 @@ struct ISystem virtual void SetConfigPlatform(ESystemConfigPlatform platform) = 0; ////////////////////////////////////////////////////////////////////////// - // Summary: - // Detects and set optimal spec. - virtual void AutoDetectSpec(bool detectResolution) = 0; - // Summary: // Query if system is now paused. // Pause flag is set when calling system update with pause mode. @@ -1041,8 +989,6 @@ struct ISystem // Retrieves localized strings manager interface. virtual ILocalizationManager* GetLocalizationManager() = 0; - virtual ITextModeConsole* GetITextModeConsole() = 0; - // Summary: // Retrieves the perlin noise singleton instance. virtual CPNoise3* GetNoiseGen() = 0; @@ -1133,22 +1079,10 @@ struct ISystem virtual ESystemGlobalState GetSystemGlobalState(void) = 0; virtual void SetSystemGlobalState(ESystemGlobalState systemGlobalState) = 0; - // Summary: - // Asynchronous memcpy - // Note sync variable will be incremented (in calling thread) before job starts - // and decremented when job finishes. Multiple async copies can therefore be - // tied to the same sync variable, therefore it's advised to wait for completion with - // while(*sync) (yield()); - virtual void AsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync) = 0; - // - #if !defined(_RELEASE) virtual bool IsSavingResourceList() const = 0; #endif - // Initializes Steam if needed and returns if it was successful - virtual bool SteamInit() = 0; - // Summary: // Gets the root window message handler function // The returned pointer is platform-specific: @@ -1752,44 +1686,6 @@ inline void CryLogAlways(const char* format, ...) #endif // EXCLUDE_NORMAL_LOG -/***************************************************** -ASYNC MEMCPY FUNCTIONS -*****************************************************/ - -// Complex delegation required because it is not really easy to -// export a external standalone symbol like a memcpy function when -// building with modules. Dll pay an extra indirection cost for calling this -// function. -#if !defined(AZ_MONOLITHIC_BUILD) -# define CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM -#endif -#define CRY_ASYNC_MEMCPY_API extern "C" - -// Note sync variable will be incremented (in calling thread) before job starts -// and decremented when job finishes. Multiple async copies can therefore be -// tied to the same sync variable, therefore wait for completion with -// while(*sync) (yield()); -#if defined(CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM) -inline void cryAsyncMemcpy( - void* dst - , const void* src - , size_t size - , int nFlags - , volatile int* sync) -{ - GetISystem()->AsyncMemcpy(dst, src, size, nFlags, sync); -} -# else -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpy( - void* dst - , const void* src - , size_t size - , int nFlags - , volatile int* sync); -#endif - - - ////////////////////////////////////////////////////////////////////////// // Additional headers. ////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CryCommon/ITextModeConsole.h b/Code/CryEngine/CryCommon/ITextModeConsole.h deleted file mode 100644 index 026f6d945f..0000000000 --- a/Code/CryEngine/CryCommon/ITextModeConsole.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Allows creation of text mode displays the for dedicated server - - -#ifndef CRYINCLUDE_CRYCOMMON_ITEXTMODECONSOLE_H -#define CRYINCLUDE_CRYCOMMON_ITEXTMODECONSOLE_H -#pragma once - - -struct ITextModeConsole -{ - // - virtual ~ITextModeConsole() {} - virtual Vec2_tpl BeginDraw() = 0; - virtual void PutText(int x, int y, const char* msg) = 0; - virtual void EndDraw() = 0; - virtual void OnShutdown() = 0; - - virtual void SetTitle([[maybe_unused]] const char* title) {} - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ITEXTMODECONSOLE_H diff --git a/Code/CryEngine/CryCommon/IZLibCompressor.h b/Code/CryEngine/CryCommon/IZLibCompressor.h deleted file mode 100644 index df85992eef..0000000000 --- a/Code/CryEngine/CryCommon/IZLibCompressor.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IZLIBCOMPRESSOR_H -#define CRYINCLUDE_CRYCOMMON_IZLIBCOMPRESSOR_H -#pragma once - - -/* - wrapper interface for the zlib compression / deflate interface - - supports multiple compression streams with an async compatible wrapper - - Gotchas: - the ptr to the input data must remain valid whilst the stream is deflating - the ptr to the output buffer must remain valid whilst the stream is deflating - - **************************************************************************************** - - usage example: - - IZLibCompressor *pComp=GetISystem()->GetIZLibCompressor(); - // see deflateInit2() documentation zlib manual for more info on the parameters here - // this initializes the stream to produce a gzip format block with fairly low memory requirements - IZLibDeflateStream *pStream=pComp->CreateDeflateStream(2,eZMeth_Deflated,24,3,eZStrat_Default,eZFlush_NoFlush); - char *pOutput=new char[512]; // arbitrary size - const char *pInputData="This is an example piece of data that is to be compressed. It can be any arbitrary block of binary data - not just text"; - const int inputBlockSize=16; // to simulate streaming of input, this example provides the input in 16 byte blocks - int totalInput=sizeof(pInputData); - int bytesInput=0; - bool done=false; - FILE *outputFile=fopen("myfile.gz","rb"); - - do - { - EZDeflateState state=pStream->GetState(); - - switch (state) - { - case eZDefState_AwaitingInput: - // 'stream' input data, there is no restriction on the block size you can input, if all the data is available immediately, input all of it at once - { - int inputSize=min(inputBlockSize,totalInput-bytesInput); - - if (inputSize<=0) - { - pStream->EndInput(); - } - else - { - pStream->Input(pInputData+bytesInput,inputSize); - bytesInput+=inputSize; - } - } - break; - - case eZDefState_Deflating: - // do something more interesting... like getting out of this loop and running the rest of your game... - break; - - case eZDefState_ConsumeOutput: - // stream output to a file - { - int bytesToOutput=pStream->GetBytesOutput(); - - if (bytesToOutput>0) - { - fwrite(pOutput,1,bytesToOutput,outputFile); - } - - pStream->SetOutputBuffer(pOutput,sizeof(pOutput)); - } - break; - - case eZDefState_Finished: - case ezDefState_Error: - done=true; - break; - } - - } while (!done); - - fclose(outputFile); - - pStream->Release(); - delete [] pOutput; - -****************************************************************************************/ - -// don't change the order of these zlib wrapping enum values without updating the mapping -// implementation in CZLibCompressorStream -enum EZLibStrategy -{ - eZStrat_Default, // Z_DEFAULT_STRATEGY - eZStrat_Filtered, // Z_FILTERED - eZStrat_HuffmanOnly, // Z_HUFFMAN_ONLY - eZStrat_RLE // Z_RLE -}; -enum EZLibMethod -{ - eZMeth_Deflated // Z_DEFLATED -}; -enum EZLibFlush -{ - eZFlush_NoFlush, // Z_NO_FLUSH - eZFlush_PartialFlush, // Z_PARTIAL_FLUSH - eZFlush_SyncFlush, // Z_SYNC_FLUSH - eZFlush_FullFlush, // Z_FULL_FLUSH -}; - -enum EZDeflateState -{ - eZDefState_AwaitingInput, // caller must call Input() or Finish() to continue - eZDefState_Deflating, // caller must wait - eZDefState_ConsumeOutput, // caller must consume output and then call SetOutputBuffer() to continue - eZDefState_Finished, // stream finished, caller must call Release() to destroy stream - eZDefState_Error // error has occurred and the stream has been closed and will no longer compress -}; - -struct IZLibDeflateStream -{ -protected: - virtual ~IZLibDeflateStream() {}; // use Release() - -public: - struct SStats - { - int bytesInput; - int bytesOutput; - int curMemoryUsed; - int peakMemoryUsed; - }; - - // - // Description: - // Specifies the output buffer for the deflate operation - // Should be set before providing input - // The specified buffer must remain valid (ie do not free) whilst compression is in progress (state == eZDefState_Deflating) - virtual void SetOutputBuffer(char* pInBuffer, int inSize) = 0; - - // Description: - // Returns the number of bytes from the output buffer that are ready to be consumed. After consuming any output, you should call SetOutputBuffer() again to mark the buffer as available - virtual int GetBytesOutput() = 0; - - // Description: - // Begins compressing the source data pInSource of length inSourceSize to a previously specified output buffer - // Only valid to be called if the stream is in state eZDefState_AwaitingInput - // The specified buffer must remain valid (ie do not free) whilst compression is in progress (state == eZDefState_Deflating) - virtual void Input(const char* pInSource, int inSourceSize) = 0; - - // Description: - // Finishes the compression, causing all data to be flushed to the output buffer - // Once called no more data can be input - // After calling the caller must wait until GetState() reutrns eZDefState_Finished - virtual void EndInput() = 0; - - // Description: - // Returns the state of the stream, - virtual EZDeflateState GetState() = 0; - - // Description: - // Gets stats on deflate stream, valid to call at anytime - virtual void GetStats(SStats* pOutStats) = 0; - - // Description: - // Deletes the deflate stream. Will assert if stream is in an invalid state to be released (in state eZDefState_Deflating) - virtual void Release() = 0; - // -}; - -// md5 support structure -struct SMD5Context -{ - uint32 buf[4]; - uint32 bits[2]; - unsigned char in[64]; -}; - -struct IZLibCompressor -{ -protected: - virtual ~IZLibCompressor() {}; // use Release() - -public: - // - // Description: - // Creates a deflate stream to compress data using zlib - // See documentation for zlib deflateInit2() for usage details - // inFlushMethod is passed to calls to zlib deflate(), see zlib docs on deflate() for more details - virtual IZLibDeflateStream* CreateDeflateStream(int inLevel, EZLibMethod inMethod, int inWindowBits, int inMemLevel, EZLibStrategy inStrategy, EZLibFlush inFlushMethod) = 0; - - virtual void Release() = 0; - - // Description: - // Initializes an MD5 context - virtual void MD5Init(SMD5Context* pIOCtx) = 0; - - // Description: - // Digests some data into an existing MD5 context - virtual void MD5Update(SMD5Context* pIOCtx, const char* pInBuff, unsigned int len) = 0; - - // Description: - // Closes the MD5 context and extract the final 16 byte MD5 digest value - virtual void MD5Final(SMD5Context * pIOCtx, char outDigest[16]) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_IZLIBCOMPRESSOR_H - diff --git a/Code/CryEngine/CryCommon/IZStdDecompressor.h b/Code/CryEngine/CryCommon/IZStdDecompressor.h deleted file mode 100644 index b5ab0f3088..0000000000 --- a/Code/CryEngine/CryCommon/IZStdDecompressor.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - - -class IZStdDecompressor -{ -public: - virtual bool DecompressData(const char* pIn, const uint inputSize, char* pOut, const uint outputSize) = 0; - virtual void Release() = 0; - -protected: - virtual ~IZStdDecompressor() = default; // use Release() -}; - diff --git a/Code/CryEngine/CryCommon/IZlibDecompressor.h b/Code/CryEngine/CryCommon/IZlibDecompressor.h deleted file mode 100644 index bd9417c935..0000000000 --- a/Code/CryEngine/CryCommon/IZlibDecompressor.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Provides the interface for the zlib inflate wrapper - - -#ifndef CRYINCLUDE_CRYCOMMON_IZLIBDECOMPRESSOR_H -#define CRYINCLUDE_CRYCOMMON_IZLIBDECOMPRESSOR_H -#pragma once - - -enum EZInflateState -{ - eZInfState_AwaitingInput, // caller must call Input() to continue - eZInfState_Inflating, // caller must wait - eZInfState_ConsumeOutput, // caller must consume output and then call SetOutputBuffer() to continue - eZInfState_Finished, // caller must call Release() - eZInfState_Error // error has occurred and the stream has been closed and will no longer compress -}; - -struct IZLibInflateStream -{ -protected: - virtual ~IZLibInflateStream() {}; // use Release() - -public: - struct SStats - { - int bytesInput; - int bytesOutput; - int curMemoryUsed; - int peakMemoryUsed; - }; - - // Description: - // Specifies the output buffer for the inflate operation - // Should be set before providing input - // The specified buffer must remain valid (ie do not free) whilst compression is in progress (state == eZInfState_Inflating) - virtual void SetOutputBuffer(char* pInBuffer, unsigned int inSize) = 0; - - // Description: - // Returns the number of bytes from the output buffer that are ready to be consumed. After consuming any output, you should call SetOutputBuffer() again to mark the buffer as available - virtual unsigned int GetBytesOutput() = 0; - - // Description: - // Begins decompressing the source data pInSource of length inSourceSize to a previously specified output buffer - // Only valid to be called if the stream is in state eZInfState_AwaitingInput - // The specified buffer must remain valid (ie do not free) whilst compression is in progress (state == eZInfState_Inflating) - virtual void Input(const char* pInSource, unsigned int inSourceSize) = 0; - - // Description: - // Finishes the compression, causing all data to be flushed to the output buffer - // Once called no more data can be input - // After calling the caller must wait until GetState() reuturns eZInfState_Finished - virtual void EndInput() = 0; - - // Description: - // Returns the state of the stream, - virtual EZInflateState GetState() = 0; - - // Description: - // Gets stats on inflate stream, valid to call at anytime - virtual void GetStats(SStats* pOutStats) = 0; - - // Description: - // Deletes the inflate stream. Will assert if stream is in an invalid state to be released (in state eZInfState_Inflating) - virtual void Release() = 0; -}; - -struct IZLibDecompressor -{ -protected: - virtual ~IZLibDecompressor() {}; // use Release() - -public: - // Description: - // Creates a inflate stream to decompress data using zlib - virtual IZLibInflateStream* CreateInflateStream() = 0; - - virtual void Release() = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMON_IZLIBDECOMPRESSOR_H - diff --git a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h index acd7492398..8c9c98b3ee 100644 --- a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h +++ b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h @@ -39,10 +39,6 @@ public: void()); MOCK_METHOD0(GetUserName, const char*()); - MOCK_METHOD0(GetCPUFlags, - int()); - MOCK_METHOD0(GetLogicalCPUCount, - int()); MOCK_METHOD0(Quit, void()); MOCK_METHOD1(Relaunch, @@ -55,8 +51,6 @@ public: int()); MOCK_CONST_METHOD0(IsRelaunch, bool()); - MOCK_METHOD4(DisplayErrorMessage, - void(const char*, float, const float*, bool)); void FatalError([[maybe_unused]] const char* sFormat, ...) override {} void ReportBug([[maybe_unused]] const char* sFormat, ...) override {} @@ -70,22 +64,12 @@ public: int(const char* text, const char* caption, unsigned int uType)); MOCK_METHOD1(CheckLogVerbosity, bool(int verbosity)); - MOCK_METHOD0(GetIZLibCompressor, - IZLibCompressor * ()); - MOCK_METHOD0(GetIZLibDecompressor, - IZLibDecompressor * ()); - MOCK_METHOD0(GetLZ4Decompressor, - ILZ4Decompressor * ()); - MOCK_METHOD0(GetZStdDecompressor, - IZStdDecompressor * ()); MOCK_METHOD0(GetIViewSystem, IViewSystem * ()); MOCK_METHOD0(GetILevelSystem, ILevelSystem * ()); MOCK_METHOD0(GetINameTable, INameTable * ()); - MOCK_METHOD0(GetIValidator, - IValidator * ()); MOCK_METHOD0(GetICmdLine, ICmdLine * ()); MOCK_METHOD0(GetILog, @@ -116,8 +100,6 @@ public: bool()); MOCK_CONST_METHOD0(IsDevMode, bool()); - MOCK_CONST_METHOD1(IsMODValid, - bool(const char* szMODName)); MOCK_METHOD3(CreateXmlNode, XmlNodeRef(const char*, bool, bool)); MOCK_METHOD4(LoadXmlFromBuffer, @@ -147,11 +129,6 @@ public: MOCK_METHOD0(GetBuildVersion, const SFileVersion&()); - MOCK_METHOD5(CompressDataBlock, - bool(const void*, size_t, void*, size_t &, int)); - - MOCK_METHOD4(DecompressDataBlock, - bool(const void* input, size_t inputSize, void* output, size_t & outputSize)); MOCK_METHOD1(AddCVarGroupDirectory, void(const string&)); MOCK_METHOD0(SaveConfiguration, @@ -159,24 +136,16 @@ public: MOCK_METHOD3(LoadConfiguration, void(const char*, ILoadConfigurationEntrySink*, bool)); - MOCK_METHOD1(GetConfigSpec, - ESystemConfigSpec(bool)); MOCK_CONST_METHOD0(GetMaxConfigSpec, ESystemConfigSpec()); - MOCK_METHOD3(SetConfigSpec, - void(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient)); MOCK_CONST_METHOD0(GetConfigPlatform, ESystemConfigPlatform()); MOCK_METHOD1(SetConfigPlatform, void(ESystemConfigPlatform platform)); - MOCK_METHOD1(AutoDetectSpec, - void(bool detectResolution)); MOCK_CONST_METHOD0(IsPaused, bool()); MOCK_METHOD0(GetLocalizationManager, ILocalizationManager * ()); - MOCK_METHOD0(GetITextModeConsole, - ITextModeConsole * ()); MOCK_METHOD0(GetNoiseGen, CPNoise3 * ()); MOCK_METHOD0(GetUpdateCounter, @@ -213,16 +182,12 @@ public: ESystemGlobalState(void)); MOCK_METHOD1(SetSystemGlobalState, void(ESystemGlobalState systemGlobalState)); - MOCK_METHOD5(AsyncMemcpy, - void(void* dst, const void* src, size_t size, int nFlags, volatile int* sync)); #if !defined(_RELEASE) MOCK_CONST_METHOD0(IsSavingResourceList, bool()); #endif - MOCK_METHOD0(SteamInit, - bool()); MOCK_METHOD0(GetRootWindowMessageHandler, void*()); MOCK_METHOD1(RegisterWindowMessageHandler, diff --git a/Code/CryEngine/CryCommon/ProjectDefines.h b/Code/CryEngine/CryCommon/ProjectDefines.h index 67ae58a324..1f151caf2e 100644 --- a/Code/CryEngine/CryCommon/ProjectDefines.h +++ b/Code/CryEngine/CryCommon/ProjectDefines.h @@ -40,8 +40,6 @@ #endif #endif -#define USE_STEAM 0 // Enable this to start using Steam - // The following definitions are used by Sandbox and RC to determine which platform support is needed #define TOOLS_SUPPORT_POWERVR #define TOOLS_SUPPORT_ETC2COMP diff --git a/Code/CryEngine/CryCommon/RenderBus.h b/Code/CryEngine/CryCommon/RenderBus.h index efd004219a..21c56f607c 100644 --- a/Code/CryEngine/CryCommon/RenderBus.h +++ b/Code/CryEngine/CryCommon/RenderBus.h @@ -33,14 +33,6 @@ namespace AZ static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; ////////////////////////////////////////////////////////////////////////// - /** - * This event gets posted at the end of CD3D9Renderer's EF_Scene3D method. - * CSystem (in SystemRenderer.cpp) uses this to render the console, aux geom and UI - * in a manner that will make sure the render calls end up as part of the scene's render. - * This is important or else those render calls won't show up properly in VR. - */ - virtual void OnScene3DEnd() {}; - /** * This event gets posted at the beginning of CD3D9Renderer's FreeResources method, before the resources have been freed. */ diff --git a/Code/CryEngine/CryCommon/crycommon_files.cmake b/Code/CryEngine/CryCommon/crycommon_files.cmake index 47e57633b4..3c1d1605e7 100644 --- a/Code/CryEngine/CryCommon/crycommon_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_files.cmake @@ -34,7 +34,6 @@ set(FILES LocalizationManagerBus.h LocalizationManagerBus.inl ILog.h - ILZ4Decompressor.h IMaterial.h IMeshBaking.h IMiniLog.h @@ -56,7 +55,6 @@ set(FILES IStereoRenderer.h ISurfaceType.h ISystem.h - ITextModeConsole.h ITexture.h ITimer.h IValidator.h @@ -64,9 +62,6 @@ set(FILES IViewSystem.h IWindowMessageHandler.h IXml.h - IZLibCompressor.h - IZlibDecompressor.h - IZStdDecompressor.h IProximityTriggerSystem.h MicrophoneBus.h physinterface.h diff --git a/Code/CryEngine/CrySystem/AndroidConsole.cpp b/Code/CryEngine/CrySystem/AndroidConsole.cpp deleted file mode 100644 index 2716df3a22..0000000000 --- a/Code/CryEngine/CrySystem/AndroidConsole.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for Android, reports back to the main interface. - - -#include "CrySystem_precompiled.h" -#if defined(ANDROID) -#include "AndroidConsole.h" - -#include "android/log.h" -CAndroidConsole::CAndroidConsole() - : m_isInitialized(false) -{ -} - -CAndroidConsole::~CAndroidConsole() -{ -} - -// Interface IOutputPrintSink ///////////////////////////////////////////// -void CAndroidConsole::Print(const char* line) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "CryEngine", "MSG: %s\n", line); -} -// Interface ISystemUserCallback ////////////////////////////////////////// -bool CAndroidConsole::OnError(const char* errorString) -{ - __android_log_print(ANDROID_LOG_ERROR, "CryEngine", "ERR: %s\n", errorString); - return true; -} - -void CAndroidConsole::OnInitProgress(const char* sProgressMsg) -{ - (void) sProgressMsg; - // Do Nothing -} -void CAndroidConsole::OnInit(ISystem* pSystem) -{ - if (!m_isInitialized) - { - IConsole* pConsole = pSystem->GetIConsole(); - if (pConsole != 0) - { - pConsole->AddOutputPrintSink(this); - } - m_isInitialized = true; - } -} -void CAndroidConsole::OnShutdown() -{ - if (m_isInitialized) - { - // remove outputprintsink - m_isInitialized = false; - } -} -void CAndroidConsole::OnUpdate() -{ - // Do Nothing -} -void CAndroidConsole::GetMemoryUsage(ICrySizer* pSizer) -{ - size_t size = sizeof(*this); - - - - pSizer->AddObject(this, size); -} - -// Interface ITextModeConsole ///////////////////////////////////////////// -Vec2_tpl CAndroidConsole::BeginDraw() -{ - return Vec2_tpl(0, 0); -} -void CAndroidConsole::PutText(int x, int y, const char* msg) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "CryEngine", "PUT: %s\n", msg); -} -void CAndroidConsole::EndDraw() -{ - // Do Nothing -} -#endif // ANDROID diff --git a/Code/CryEngine/CrySystem/AndroidConsole.h b/Code/CryEngine/CrySystem/AndroidConsole.h deleted file mode 100644 index af45a68d5e..0000000000 --- a/Code/CryEngine/CrySystem/AndroidConsole.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for Android, reports back to the main interface. - - -#ifndef CRYINCLUDE_CRYSYSTEM_ANDROIDCONSOLE_H -#define CRYINCLUDE_CRYSYSTEM_ANDROIDCONSOLE_H -#pragma once - - -#include -#include - - - -class CAndroidConsole - : public ISystemUserCallback - , public IOutputPrintSink - , public ITextModeConsole -{ - CAndroidConsole(const CAndroidConsole&); - CAndroidConsole& operator = (const CAndroidConsole&); - - bool m_isInitialized; -public: - static CryCriticalSectionNonRecursive s_lock; -public: - CAndroidConsole(); - ~CAndroidConsole(); - - // Interface IOutputPrintSink ///////////////////////////////////////////// - DLL_EXPORT virtual void Print(const char* line); - - // Interface ISystemUserCallback ////////////////////////////////////////// - virtual bool OnError(const char* errorString); - virtual bool OnSaveDocument() { return false; } - virtual void OnProcessSwitch() { } - virtual void OnInitProgress(const char* sProgressMsg); - virtual void OnInit(ISystem*); - virtual void OnShutdown(); - virtual void OnUpdate(); - virtual void GetMemoryUsage(ICrySizer* pSizer); - void SetRequireDedicatedServer(bool) {} - void SetHeader(const char*) {} - // Interface ITextModeConsole ///////////////////////////////////////////// - virtual Vec2_tpl BeginDraw(); - virtual void PutText(int x, int y, const char* msg); - virtual void EndDraw(); -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ANDROIDCONSOLE_H diff --git a/Code/CryEngine/CrySystem/AutoDetectSpec.cpp b/Code/CryEngine/CrySystem/AutoDetectSpec.cpp deleted file mode 100644 index aa344684e3..0000000000 --- a/Code/CryEngine/CrySystem/AutoDetectSpec.cpp +++ /dev/null @@ -1,1097 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#if defined(WIN32) || defined(WIN64) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "System.h" -#include "AutoDetectSpec.h" - -// both function live in CPUDetect.cpp -bool IsAMD(); -bool IsIntel(); - - -static void TrimExcessiveWhiteSpaces(char* pStr) -{ - size_t len(strlen(pStr)); - bool remove(true); - for (size_t i(0); i < len; ++i) - { - if (pStr[i] == ' ' && remove) - { - size_t newlen(len - 1); - - size_t j(i + 1); - for (; j < len && pStr[j] == ' '; ++j) - { - --newlen; - } - - size_t ii(i); - for (; j < len + 1; ++j, ++ii) - { - pStr[ii] = pStr[j]; - } - - assert(newlen == strlen(pStr)); - len = newlen; - remove = false; - } - else - { - remove = pStr[i] == ' '; - } - } - - if (len > 0 && pStr[len - 1] == ' ') - { - pStr[len - 1] = '\0'; - } -} - - -static void GetCPUName(char* pName, size_t bufferSize) -{ - if (!pName || !bufferSize) - { - return; - } - - char name[12 * 4 + 1]; - - int CPUInfo[4]; - __cpuid(CPUInfo, 0x80000000); - if (CPUInfo[0] >= 0x80000004) - { - __cpuid(CPUInfo, 0x80000002); - ((int*)name)[0] = CPUInfo[0]; - ((int*)name)[1] = CPUInfo[1]; - ((int*)name)[2] = CPUInfo[2]; - ((int*)name)[3] = CPUInfo[3]; - - __cpuid(CPUInfo, 0x80000003); - ((int*)name)[4] = CPUInfo[0]; - ((int*)name)[5] = CPUInfo[1]; - ((int*)name)[6] = CPUInfo[2]; - ((int*)name)[7] = CPUInfo[3]; - - __cpuid(CPUInfo, 0x80000004); - ((int*)name)[8] = CPUInfo[0]; - ((int*)name)[9] = CPUInfo[1]; - ((int*)name)[10] = CPUInfo[2]; - ((int*)name)[11] = CPUInfo[3]; - - name[48] = '\0'; - } - else - { - name[0] = '\0'; - } - - int ret(azsnprintf(pName, bufferSize, name)); - if (ret >= bufferSize || ret < 0) - { - pName[bufferSize - 1] = '\0'; - } -} - - -void Win32SysInspect::GetOS(SPlatformInfo::EWinVersion& ver, bool& is64Bit, char* pName, size_t bufferSize) -{ - ver = SPlatformInfo::WinUndetected; - is64Bit = false; - - if (pName && bufferSize) - { - pName[0] = '\0'; - } - - //GetVersionEx was changed to work based on how the application is manifest - //meaning we have to specifically state that this application supports - //Windows 10, Windows 8.1 etc if we want GetVersionEx to return those version numbers. - //RtlGetVersion does not require a manifest. - auto RtlGetVersion = reinterpret_cast(GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion")); - AZ_Assert(RtlGetVersion, "Failed to get address to RtlGetVersion from ntdll.dll"); - - RTL_OSVERSIONINFOEXW sysInfo; - sysInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); - - if (RtlGetVersion(&sysInfo) == 0) - { - if (sysInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - if (sysInfo.dwMajorVersion == 5) - { - if (sysInfo.dwMinorVersion == 0) - { - ver = SPlatformInfo::Win2000; - } - else if (sysInfo.dwMinorVersion == 1) - { - ver = SPlatformInfo::WinXP; - } - else if (sysInfo.dwMinorVersion == 2) - { - if (sysInfo.wProductType == VER_NT_WORKSTATION) - { - ver = SPlatformInfo::WinXP; // 64 bit windows actually but this will be detected later anyway - } - else if (sysInfo.wProductType == VER_NT_SERVER || sysInfo.wProductType == VER_NT_DOMAIN_CONTROLLER) - { - ver = SPlatformInfo::WinSrv2003; - } - } - } - else if (sysInfo.dwMajorVersion == 6) - { - if (sysInfo.dwMinorVersion == 0) - { - ver = SPlatformInfo::WinVista; - } - else if (sysInfo.dwMinorVersion == 1) - { - ver = SPlatformInfo::Win7; - } - else if (sysInfo.dwMinorVersion == 2) - { - ver = SPlatformInfo::Win8; - } - else if (sysInfo.dwMinorVersion == 3) - { - ver = SPlatformInfo::Win81; - } - } - else if (sysInfo.dwMajorVersion == 10) - { - ver = SPlatformInfo::Win10; - } - } - - typedef BOOL (WINAPI * FP_GetSystemWow64Directory)(LPSTR, UINT); - FP_GetSystemWow64Directory pgsw64d((FP_GetSystemWow64Directory) GetProcAddress(GetModuleHandle("kernel32"), "GetSystemWow64DirectoryA")); - if (pgsw64d) - { - char str[MAX_PATH]; - if (!pgsw64d(str, sizeof(str))) - { - is64Bit = GetLastError() != ERROR_CALL_NOT_IMPLEMENTED; - } - else - { - is64Bit = true; - } - } - - if (pName && bufferSize) - { - const char* windowsVersionText(0); - switch (ver) - { - case SPlatformInfo::Win2000: - windowsVersionText = "Windows 2000"; - break; - case SPlatformInfo::WinXP: - windowsVersionText = "Windows XP"; - break; - case SPlatformInfo::WinSrv2003: - windowsVersionText = "Windows Server 2003"; - break; - case SPlatformInfo::WinVista: - windowsVersionText = "Windows Vista"; - break; - case SPlatformInfo::Win7: - windowsVersionText = "Windows 7"; - break; - case SPlatformInfo::Win8: - windowsVersionText = "Windows 8"; - break; - case SPlatformInfo::Win81: - windowsVersionText = "Windows 8.1"; - break; - case SPlatformInfo::Win10: - windowsVersionText = "Windows 10"; - break; - default: - windowsVersionText = "Windows"; - break; - } - - char sptext[32]; - sptext[0] = '\0'; - if (sysInfo.wServicePackMajor > 0) - { - azsnprintf(sptext, sizeof(sptext), "SP %d ", sysInfo.wServicePackMajor); - } - - int ret(azsnprintf(pName, bufferSize, "%s %s %s(build %d.%d.%d)", windowsVersionText, is64Bit ? "64 bit" : "32 bit", - sptext, sysInfo.dwMajorVersion, sysInfo.dwMinorVersion, sysInfo.dwBuildNumber)); - if (ret >= bufferSize || ret < 0) - { - pName[bufferSize - 1] = '\0'; - } - } - } -} - -bool Win32SysInspect::IsVistaKB940105Required() -{ -#if defined(WIN32) && !defined(WIN64) - OSVERSIONINFO osv; - memset(&osv, 0, sizeof(osv)); - osv.dwOSVersionInfoSize = sizeof(osv); - GetVersionEx(&osv); - - if (osv.dwMajorVersion != 6 || osv.dwMinorVersion != 0 || (osv.dwBuildNumber > 6000)) - { - // This QFE only ever applies to Windows Vista RTM. Windows Vista SP1 already has this fix, - // and earlier versions of Windows do not implement WDDM - return false; - } - - //MEMORYSTATUSEX mex; - //memset(&mex, 0, sizeof(mex)); - //mex.dwLength = sizeof(mex); - //GlobalMemoryStatusEx(&mex); - - //if (mex.ullTotalVirtual >= 4294836224) - //{ - // // If there is 4 GB of VA space total for this process, then we are a - // // 32-bit Large Address Aware application running on a Windows 64-bit OS. - - // // We could be a 32-bit Large Address Aware application running on a - // // Windows 32-bit OS and get up to 3 GB, but that has stability implications. - // // Therefore, we recommend the QFE for all 32-bit versions of the OS. - - // // No need for the fix unless the game is pushing 4 GB of VA - // return false; - //} - - const char* sysFile = "dxgkrnl.sys"; - - // Ensure we are checking the system copy of the file - char sysPath[MAX_PATH]; - GetSystemDirectory(sysPath, sizeof(sysPath)); - - cry_strcat(sysPath, "\\drivers\\"); - cry_strcat(sysPath, sysFile); - - char buf[2048]; - if (!GetFileVersionInfo(sysPath, 0, sizeof(buf), buf)) - { - // This should never happen, but we'll assume it's a newer .sys file since we've - // narrowed the test to a Windows Vista RTM OS. - return false; - } - - VS_FIXEDFILEINFO* ver; - UINT size; - if (!VerQueryValue(buf, "\\", (void**) &ver, &size) || size != sizeof(VS_FIXEDFILEINFO) || ver->dwSignature != 0xFEEF04BD) - { - // This should never happen, but we'll assume it's a newer .sys file since we've - // narrowed the test to a Windows Vista RTM OS. - return false; - } - - // File major.minor.build.qfe version comparison - // WORD major = HIWORD( ver->dwFileVersionMS ); WORD minor = LOWORD( ver->dwFileVersionMS ); - // WORD build = HIWORD( ver->dwFileVersionLS ); WORD qfe = LOWORD( ver->dwFileVersionLS ); - - if (ver->dwFileVersionMS > MAKELONG(0, 6) || (ver->dwFileVersionMS == MAKELONG(0, 6) && ver->dwFileVersionLS >= MAKELONG(20648, 6000))) - { - // QFE fix version of dxgkrnl.sys is 6.0.6000.20648 - return false; - } - - return true; -#else - return false; // The QFE is not required for a 64-bit native application as it has 8 TB of VA -#endif -} - - -static void GetSystemMemory(uint64& totSysMem) -{ - typedef BOOL (WINAPI * FP_GlobalMemoryStatusEx)(LPMEMORYSTATUSEX); - FP_GlobalMemoryStatusEx pgmsex((FP_GlobalMemoryStatusEx) GetProcAddress(GetModuleHandle("kernel32"), "GlobalMemoryStatusEx")); - if (pgmsex) - { - MEMORYSTATUSEX memStats; - memStats.dwLength = sizeof(memStats); - if (pgmsex(&memStats)) - { - totSysMem = memStats.ullTotalPhys; - } - else - { - totSysMem = 0; - } - } - else - { - MEMORYSTATUS memStats; - memStats.dwLength = sizeof(memStats); - GlobalMemoryStatus(&memStats); - totSysMem = memStats.dwTotalPhys; - } -} - - -static bool IsVistaOrAbove() -{ - typedef BOOL (WINAPI * FP_VerifyVersionInfo)(LPOSVERSIONINFOEX, DWORD, DWORDLONG); - FP_VerifyVersionInfo pvvi((FP_VerifyVersionInfo) GetProcAddress(GetModuleHandle("kernel32"), "VerifyVersionInfoA")); - - if (pvvi) - { - typedef ULONGLONG (WINAPI * FP_VerSetConditionMask)(ULONGLONG, DWORD, BYTE); - FP_VerSetConditionMask pvscm((FP_VerSetConditionMask) GetProcAddress(GetModuleHandle("kernel32"), "VerSetConditionMask")); - assert(pvscm); - - OSVERSIONINFOEX osvi; - memset(&osvi, 0, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - osvi.dwMajorVersion = 6; - osvi.dwMinorVersion = 0; - osvi.wServicePackMajor = 0; - osvi.wServicePackMinor = 0; - - ULONGLONG mask(0); - mask = pvscm(mask, VER_MAJORVERSION, VER_GREATER_EQUAL); - mask = pvscm(mask, VER_MINORVERSION, VER_GREATER_EQUAL); - mask = pvscm(mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - mask = pvscm(mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); - - if (pvvi(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, mask)) - { - return true; - } - } - - return false; -} - - -// Preferred solution to determine the number of available CPU cores, works reliably only on WinVista/Win7 32/64 and above -// See http://msdn2.microsoft.com/en-us/library/ms686694.aspx for reasons -static void GetNumCPUCoresGlpi(unsigned int& totAvailToSystem, unsigned int& totAvailToProcess) -{ - typedef BOOL (WINAPI * FP_GetLogicalProcessorInformation)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); - FP_GetLogicalProcessorInformation pglpi((FP_GetLogicalProcessorInformation) GetProcAddress(GetModuleHandle("kernel32"), "GetLogicalProcessorInformation")); - if (pglpi && IsVistaOrAbove()) - { - unsigned long bufferSize(0); - pglpi(0, &bufferSize); - - void* pBuffer(alloca(bufferSize)); - - SYSTEM_LOGICAL_PROCESSOR_INFORMATION* pLogProcInfo((SYSTEM_LOGICAL_PROCESSOR_INFORMATION*) pBuffer); - if (pLogProcInfo && pglpi(pLogProcInfo, &bufferSize)) - { - DWORD_PTR processAffinity, systemAffinity; - GetProcessAffinityMask(GetCurrentProcess(), &processAffinity, &systemAffinity); - - unsigned long numEntries(bufferSize / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); - for (unsigned long i(0); i < numEntries; ++i) - { - switch (pLogProcInfo[i].Relationship) - { - case RelationProcessorCore: - { - ++totAvailToSystem; - if (pLogProcInfo[i].ProcessorMask & processAffinity) - { - ++totAvailToProcess; - } - } - break; - - default: - break; - } - } - } - } -} - - -class CApicExtractor -{ -public: - CApicExtractor(unsigned int logProcsPerPkg = 1, unsigned int coresPerPkg = 1) - { - SetPackageTopology(logProcsPerPkg, coresPerPkg); - } - - unsigned char SmtId(unsigned char apicId) const - { - return apicId & m_smtIdMask.mask; - } - - unsigned char CoreId(unsigned char apicId) const - { - return (apicId & m_coreIdMask.mask) >> m_smtIdMask.width; - } - - unsigned char PackageId(unsigned char apicId) const - { - return (apicId & m_pkgIdMask.mask) >> (m_smtIdMask.width + m_coreIdMask.width); - } - - unsigned char PackageCoreId(unsigned char apicId) const - { - return (apicId & (m_pkgIdMask.mask | m_coreIdMask.mask)) >> m_smtIdMask.width; - } - - unsigned int GetLogProcsPerPkg() const - { - return m_logProcsPerPkg; - } - - unsigned int GetCoresPerPkg() const - { - return m_coresPerPkg; - } - - void SetPackageTopology(unsigned int logProcsPerPkg, unsigned int coresPerPkg) - { - m_logProcsPerPkg = (unsigned char) logProcsPerPkg; - m_coresPerPkg = (unsigned char) coresPerPkg; - - m_smtIdMask.width = GetMaskWidth(m_logProcsPerPkg / m_coresPerPkg); - m_coreIdMask.width = GetMaskWidth(m_coresPerPkg); - m_pkgIdMask.width = 8 - (m_smtIdMask.width + m_coreIdMask.width); - - m_pkgIdMask.mask = (unsigned char) (0xFF << (m_smtIdMask.width + m_coreIdMask.width)); - m_coreIdMask.mask = (unsigned char) ((0xFF << m_smtIdMask.width) ^ m_pkgIdMask.mask); - m_smtIdMask.mask = (unsigned char) ~(0xFF << m_smtIdMask.width); - } - -private: - unsigned char GetMaskWidth(unsigned char maxIds) const - { - --maxIds; - unsigned char msbIdx(8); - unsigned char msbMask(0x80); - while (msbMask && !(msbMask & maxIds)) - { - --msbIdx; - msbMask >>= 1; - } - return msbIdx; - } - - struct IdMask - { - unsigned char width; - unsigned char mask; - }; - - unsigned char m_logProcsPerPkg; - unsigned char m_coresPerPkg; - IdMask m_smtIdMask; - IdMask m_coreIdMask; - IdMask m_pkgIdMask; -}; - - -// Fallback solution for WinXP 32/64 -static void GetNumCPUCoresApic(unsigned int& totAvailToSystem, unsigned int& totAvailToProcess) -{ - unsigned int numLogicalPerPhysical(1); - unsigned int numCoresPerPhysical(1); - - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - if ((CPUInfo[3] & 0x10000000) != 0) // Hyperthreading / Multicore bit set - { - numLogicalPerPhysical = (CPUInfo[1] & 0x00FF0000) >> 16; - - if (IsIntel()) - { - __cpuid(CPUInfo, 0x00000000); - if (CPUInfo[0] >= 0x00000004) - { - __cpuidex(CPUInfo, 4, 0); - numCoresPerPhysical = ((CPUInfo[0] & 0xFC000000) >> 26) + 1; - } - } - else if (IsAMD()) - { - __cpuid(CPUInfo, 0x80000000); - if (CPUInfo[0] >= 0x80000008) - { - __cpuid(CPUInfo, 0x80000008); - if (CPUInfo[2] & 0x0000F000) - { - numCoresPerPhysical = 1 << ((CPUInfo[2] & 0x0000F000) >> 12); - } - else - { - numCoresPerPhysical = (CPUInfo[2] & 0xFF) + 1; - } - } - } - } - - HANDLE hCurProcess(GetCurrentProcess()); - HANDLE hCurThread(GetCurrentThread()); - - const int c_maxLogicalProcessors(sizeof(DWORD_PTR) * 8); - unsigned char apicIds[c_maxLogicalProcessors] = { 0 }; - unsigned char items(0); - - DWORD_PTR processAffinity, systemAffinity; - GetProcessAffinityMask(hCurProcess, &processAffinity, &systemAffinity); - - if (systemAffinity == 1) - { - assert(numLogicalPerPhysical == 1); - apicIds[items++] = 0; - } - else - { - if (processAffinity != systemAffinity) - { - SetProcessAffinityMask(hCurProcess, systemAffinity); - } - - DWORD_PTR prevThreadAffinity(0); - for (DWORD_PTR threadAffinity = 1; threadAffinity && threadAffinity <= systemAffinity; threadAffinity <<= 1) - { - if (systemAffinity & threadAffinity) - { - if (!prevThreadAffinity) - { - assert(!items); - prevThreadAffinity = SetThreadAffinityMask(hCurThread, threadAffinity); - } - else - { - assert(items > 0); - SetThreadAffinityMask(hCurThread, threadAffinity); - } - - Sleep(0); - - int CPUInfo2[4]; - __cpuid(CPUInfo2, 0x00000001); - apicIds[items++] = (unsigned char) ((CPUInfo2[1] & 0xFF000000) >> 24); - } - } - - SetProcessAffinityMask(hCurProcess, processAffinity); - SetThreadAffinityMask(hCurThread, prevThreadAffinity); - Sleep(0); - } - - CApicExtractor apicExtractor(numLogicalPerPhysical, numCoresPerPhysical); - - totAvailToSystem = 0; - { - unsigned char pkgCoreIds[c_maxLogicalProcessors] = { 0 }; - for (unsigned int i(0); i < items; ++i) - { - unsigned int j(0); - for (; j < totAvailToSystem; ++j) - { - if (pkgCoreIds[j] == apicExtractor.PackageCoreId(apicIds[i])) - { - break; - } - } - if (j == totAvailToSystem) - { - pkgCoreIds[j] = apicExtractor.PackageCoreId(apicIds[i]); - ++totAvailToSystem; - } - } - } - - totAvailToProcess = 0; - { - unsigned char pkgCoreIds[c_maxLogicalProcessors] = { 0 }; - for (unsigned int i(0); i < items; ++i) - { - if (processAffinity & ((DWORD_PTR) 1 << i)) - { - unsigned int j(0); - for (; j < totAvailToProcess; ++j) - { - if (pkgCoreIds[j] == apicExtractor.PackageCoreId(apicIds[i])) - { - break; - } - } - if (j == totAvailToProcess) - { - pkgCoreIds[j] = apicExtractor.PackageCoreId(apicIds[i]); - ++totAvailToProcess; - } - } - } - } -} - -const char* Win32SysInspect::GetFeatureLevelAsString(Win32SysInspect::DXFeatureLevel featureLevel) -{ - switch (featureLevel) - { - case Win32SysInspect::DXFL_Undefined: - return "unknown"; - case Win32SysInspect::DXFL_9_1: - return "DX9 (SM 2.0)"; - case Win32SysInspect::DXFL_9_2: - return "DX9 (SM 2.0)"; - case Win32SysInspect::DXFL_9_3: - return "DX9 (SM 2.x)"; - case Win32SysInspect::DXFL_10_0: - return "DX10 (SM 4.0)"; - case Win32SysInspect::DXFL_10_1: - return "DX10.1 (SM 4.x)"; - case Win32SysInspect::DXFL_11_0: - default: - return "DX11 (SM 5.0)"; - } -} - -void Win32SysInspect::GetNumCPUCores(unsigned int& totAvailToSystem, unsigned int& totAvailToProcess) -{ - totAvailToSystem = 0; - totAvailToProcess = 0; - - GetNumCPUCoresGlpi(totAvailToSystem, totAvailToProcess); - - if (!totAvailToSystem) - { - GetNumCPUCoresApic(totAvailToSystem, totAvailToProcess); - } -} - - -static Win32SysInspect::DXFeatureLevel GetFeatureLevel(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_9_1: - return Win32SysInspect::DXFL_9_1; - case D3D_FEATURE_LEVEL_9_2: - return Win32SysInspect::DXFL_9_2; - case D3D_FEATURE_LEVEL_9_3: - return Win32SysInspect::DXFL_9_3; - case D3D_FEATURE_LEVEL_10_0: - return Win32SysInspect::DXFL_10_0; - case D3D_FEATURE_LEVEL_10_1: - return Win32SysInspect::DXFL_10_1; - case D3D_FEATURE_LEVEL_11_0: - default: - return Win32SysInspect::DXFL_11_0; - } -} - -static bool FindGPU(DXGI_ADAPTER_DESC1& adapterDesc, Win32SysInspect::DXFeatureLevel& featureLevel) -{ - memset(&adapterDesc, 0, sizeof(adapterDesc)); - featureLevel = Win32SysInspect::DXFL_Undefined; - - if (!IsVistaOrAbove()) - { - return false; - } - - typedef HRESULT (WINAPI * FP_CreateDXGIFactory1)(REFIID, void**); - FP_CreateDXGIFactory1 pCDXGIF = (FP_CreateDXGIFactory1) GetProcAddress(LoadLibraryA("dxgi.dll"), "CreateDXGIFactory1"); - - IDXGIFactory1* pFactory = 0; - if (pCDXGIF && SUCCEEDED(pCDXGIF(__uuidof(IDXGIFactory1), (void**) &pFactory)) && pFactory) - { - typedef HRESULT (WINAPI * FP_D3D11CreateDevice)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**); - FP_D3D11CreateDevice pD3D11CD = (FP_D3D11CreateDevice) GetProcAddress(LoadLibraryA("d3d11.dll"), "D3D11CreateDevice"); - - if (pD3D11CD) - { - unsigned int nAdapter = 0; - IDXGIAdapter1* pAdapter = 0; - while (pFactory->EnumAdapters1(nAdapter, &pAdapter) != DXGI_ERROR_NOT_FOUND) - { - if (pAdapter) - { - ID3D11Device* pDevice = 0; - D3D_FEATURE_LEVEL levels[] = {D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1}; - D3D_FEATURE_LEVEL deviceFeatureLevel = D3D_FEATURE_LEVEL_9_1; - HRESULT hr = pD3D11CD(pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, levels, sizeof(levels) / sizeof(levels[0]), D3D11_SDK_VERSION, &pDevice, &deviceFeatureLevel, NULL); - if (SUCCEEDED(hr) && pDevice) - { - IDXGIOutput* pOutput = 0; - const bool displaysConnected = SUCCEEDED(pAdapter->EnumOutputs(0, &pOutput)) && pOutput; - SAFE_RELEASE(pOutput); - - DXGI_ADAPTER_DESC1 ad; - pAdapter->GetDesc1(&ad); - - const Win32SysInspect::DXFeatureLevel fl = GetFeatureLevel(deviceFeatureLevel); - - if (featureLevel < fl && displaysConnected) - { - adapterDesc = ad; - featureLevel = fl; - } - } - - SAFE_RELEASE(pDevice); - SAFE_RELEASE(pAdapter); - } - ++nAdapter; - } - } - } - SAFE_RELEASE(pFactory); - return featureLevel != Win32SysInspect::DXFL_Undefined; -} - - -bool Win32SysInspect::IsDX11Supported() -{ - DXGI_ADAPTER_DESC1 adapterDesc = {}; - DXFeatureLevel featureLevel = Win32SysInspect::DXFL_Undefined; - return FindGPU(adapterDesc, featureLevel) && featureLevel >= DXFL_11_0; -} - - -bool Win32SysInspect::GetGPUInfo(char* pName, size_t bufferSize, unsigned int& vendorID, unsigned int& deviceID, unsigned int& totLocalVidMem, DXFeatureLevel& featureLevel) -{ - if (pName && bufferSize) - { - pName[0] = '\0'; - } - - vendorID = 0; - deviceID = 0; - totLocalVidMem = 0; - featureLevel = Win32SysInspect::DXFL_Undefined; - - DXGI_ADAPTER_DESC1 adapterDesc = {}; - const bool gpuFound = FindGPU(adapterDesc, featureLevel); - if (gpuFound) - { - vendorID = adapterDesc.VendorId; - deviceID = adapterDesc.DeviceId; - - if (pName && bufferSize) - { - sprintf_s(pName, bufferSize, "%s", CryStringUtils::WStrToUTF8(adapterDesc.Description).c_str()); - } - - totLocalVidMem = adapterDesc.DedicatedVideoMemory; - } - - return gpuFound; -} - - -class CGPURating -{ -public: - CGPURating(); - ~CGPURating(); - - int GetRating(unsigned int vendorId, unsigned int deviceId) const; - -private: - struct SGPUID - { - SGPUID(unsigned int vendorId, unsigned int deviceId) - : vendor(vendorId) - , device(deviceId) - { - } - - bool operator < (const SGPUID& rhs) const - { - if (vendor == rhs.vendor) - { - return device < rhs.device; - } - else - { - return vendor < rhs.vendor; - } - } - - unsigned int vendor; - unsigned int device; - }; - - typedef std::map GPURatingMap; - -private: - GPURatingMap m_gpuRatingMap; -}; - - -static size_t SafeReadLine(AZ::IO::IArchive* pPak, AZ::IO::HandleType fileHandle, char* buffer, size_t bufferSize) -{ - assert(buffer && bufferSize); - - memset(buffer, 0, bufferSize); - - size_t bytesRead = pPak->FRead(buffer, bufferSize - 1, fileHandle); - if (!bytesRead) - { - return 0; - } - - char* currentPosition = buffer; - size_t len = 0; - - bool done = false; - int slashRPosition = -1; - do - { - if (*currentPosition != '\r' && *currentPosition != '\n' && len < bufferSize - 1) - { - len++; - currentPosition++; - } - else - { - done = true; - if (*currentPosition == '\r') - { - slashRPosition = len; - } - } - } while (!done); - - // null terminate string - buffer[len] = '\0'; - - ////////////////////////////////////////// - //seek back to the end of the string - int seekback = bytesRead - len - 1; - - // handle CR/LF for file coming from different platforms - if (slashRPosition > -1 && bytesRead > slashRPosition && buffer[slashRPosition + 1] == '\n') - { - seekback--; - } - pPak->FSeek(fileHandle, -seekback, SEEK_CUR); - /////////////////////////////////////////// - - return len; -} - - -#define BUILDPATH_GPURATING(x) "config/gpu/" x - -CGPURating::CGPURating() -{ - auto pPak(gEnv->pCryPak); - - AZ::IO::ArchiveFileIterator h(pPak->FindFirst(BUILDPATH_GPURATING("*.txt"))); - if (h) - { - do - { - char filename[128]; - azsnprintf(filename, sizeof(filename), BUILDPATH_GPURATING("%.*s"), aznumeric_cast(h.m_filename.size()), h.m_filename.data()); - - AZ::IO::HandleType fileHandle = pPak->FOpen(filename, "rb"); - if (fileHandle != AZ::IO::InvalidHandle) - { - size_t lineNr(0); - while (!pPak->FEof(fileHandle)) - { - char line[1024]; - line[0] = '\0'; - size_t len(SafeReadLine(pPak, fileHandle, line, sizeof(line))); - ++lineNr; - - if (len > 2 && line[0] != '/' && line[1] != '/') - { - unsigned int vendorId(0), deviceId(0); - int rating(0); - if (_snscanf_s(line, sizeof(line), "%x,%x,%d", &vendorId, &deviceId, &rating) == 3) - { - GPURatingMap::iterator it(m_gpuRatingMap.find(SGPUID(vendorId, deviceId))); - if (it == m_gpuRatingMap.end()) - { - m_gpuRatingMap.insert(GPURatingMap::value_type(SGPUID(vendorId, deviceId), rating)); - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - "%s line %d contains a multiple defined GPU rating!", filename, lineNr); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - "%s line %d contains incomplete GPU rating!", filename, lineNr); - } - } - } - - pPak->FClose(fileHandle); - } - } while (h = pPak->FindNext(h)); - - pPak->FindClose(h); - } -} - - -CGPURating::~CGPURating() -{ -} - - -int CGPURating::GetRating(unsigned int vendorId, unsigned int deviceId) const -{ - GPURatingMap::const_iterator it(m_gpuRatingMap.find(SGPUID(vendorId, deviceId))); - if (it != m_gpuRatingMap.end()) - { - return (*it).second; - } - else - { - return 0; - } -} - - -int Win32SysInspect::GetGPURating([[maybe_unused]] unsigned int vendorId, [[maybe_unused]] unsigned int deviceId) -{ - return 0; // All GPUs unrated as the database is out of date - - //CGPURating gpuRatingDb; - //return gpuRatingDb.GetRating(vendorId, deviceId); -} - - -static int GetFinalSpecValue(int cpuRating, unsigned int totSysMemMB, int gpuRating, unsigned int totVidMemMB, ESystemConfigSpec maxConfigSpec) -{ - int sysMemRating = 1; - if (totSysMemMB >= Win32SysInspect::SafeMemoryThreshold(12228)) - { - sysMemRating = 3; - } - else if (totSysMemMB >= Win32SysInspect::SafeMemoryThreshold(8192)) - { - sysMemRating = 2; - } - - cpuRating = sysMemRating < cpuRating ? sysMemRating : cpuRating; - - // just a sanity check, GPU should reflect overall GPU perf including memory (higher rated GPUs usually come with enough memory) - if (totVidMemMB < Win32SysInspect::SafeMemoryThreshold(1024)) - { - gpuRating = 1; - } - - int finalRating = cpuRating < gpuRating ? cpuRating : gpuRating; - - return min(finalRating, (int) maxConfigSpec); -} - - -void CSystem::AutoDetectSpec(const bool detectResolution) -{ - CryLogAlways("Running machine spec auto detect (%d bit)...", sizeof(void*) << 3); - - char tempBuf[512]; - - // get OS - SPlatformInfo::EWinVersion winVer(SPlatformInfo::WinUndetected); - bool is64bit(false); - Win32SysInspect::GetOS(winVer, is64bit, tempBuf, sizeof(tempBuf)); - CryLogAlways("- %s", tempBuf); - - // get system memory - uint64 totSysMem(0); - GetSystemMemory(totSysMem); - CryLogAlways("- System memory"); - CryLogAlways("--- %d MB", totSysMem >> 20); - - // get CPU name - GetCPUName(tempBuf, sizeof(tempBuf)); - TrimExcessiveWhiteSpaces(tempBuf); - CryLogAlways("- %s", tempBuf); - - // get number of CPU cores - unsigned int numSysCores(1), numProcCores(1); - Win32SysInspect::GetNumCPUCores(numSysCores, numProcCores); - CryLogAlways("--- Number of available cores: %d (out of %d)", numProcCores, numSysCores); - - // get CPU rating - const int cpuRating = numProcCores >= 4 ? 3 : (numProcCores >= 3 ? 2 : 1); - - // get GPU info - unsigned int gpuVendorId(0), gpuDeviceId(0), totVidMem(0); - Win32SysInspect::DXFeatureLevel featureLevel(Win32SysInspect::DXFL_Undefined); - Win32SysInspect::GetGPUInfo(tempBuf, sizeof(tempBuf), gpuVendorId, gpuDeviceId, totVidMem, featureLevel); - - CryLogAlways("- %s (vendor = 0x%.4x, device = 0x%.4x)", tempBuf, gpuVendorId, gpuDeviceId); - CryLogAlways("--- Dedicated video memory: %d MB", totVidMem >> 20); - CryLogAlways("--- Feature level: %s", GetFeatureLevelAsString(featureLevel)); - - // get GPU rating - const int gpuRating = (totVidMem >> 20) >= Win32SysInspect::SafeMemoryThreshold(4096) ? 3 : ((totVidMem >> 20) >= Win32SysInspect::SafeMemoryThreshold(2048) ? 2 : 1); - - // get final rating - int finalSpecValue(GetFinalSpecValue(cpuRating, totSysMem >> 20, gpuRating, totVidMem >> 20, CONFIG_VERYHIGH_SPEC)); - CryLogAlways("- Final rating: Machine class %d", finalSpecValue); - - m_sys_GraphicsQuality->Set(finalSpecValue); - - if (detectResolution) - { - if ((m_rWidth->GetFlags() & VF_WASINCONFIG) == 0) - { - m_rWidth->Set(GetSystemMetrics(SM_CXFULLSCREEN)); - } - if ((m_rHeight->GetFlags() & VF_WASINCONFIG) == 0) - { - m_rHeight->Set(GetSystemMetrics(SM_CYFULLSCREEN)); - } - if ((m_rFullscreen->GetFlags() & VF_WASINCONFIG) == 0) - { - m_rFullscreen->Set(1); - } - } -} - - -#else - -#include "System.h" - -void CSystem::AutoDetectSpec(const bool detectResolution) -{ - AZ_UNUSED(detectResolution); -} - - -#endif diff --git a/Code/CryEngine/CrySystem/AutoDetectSpec.h b/Code/CryEngine/CrySystem/AutoDetectSpec.h deleted file mode 100644 index a710141668..0000000000 --- a/Code/CryEngine/CrySystem/AutoDetectSpec.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_AUTODETECTSPEC_H -#define CRYINCLUDE_CRYSYSTEM_AUTODETECTSPEC_H -#pragma once - - - -#if defined(WIN32) || defined(WIN64) - -// exposed AutoDetectSpec() helper functions for reuse in CrySystem -namespace Win32SysInspect -{ - enum DXFeatureLevel - { - DXFL_Undefined, - DXFL_9_1, - DXFL_9_2, - DXFL_9_3, - DXFL_10_0, - DXFL_10_1, - DXFL_11_0 - }; - - const char* GetFeatureLevelAsString(DXFeatureLevel featureLevel); - - void GetNumCPUCores(unsigned int& totAvailToSystem, unsigned int& totAvailToProcess); - bool IsDX11Supported(); - bool GetGPUInfo(char* pName, size_t bufferSize, unsigned int& vendorID, unsigned int& deviceID, unsigned int& totLocalVidMem, DXFeatureLevel& featureLevel); - int GetGPURating(unsigned int vendorId, unsigned int deviceId); - void GetOS(SPlatformInfo::EWinVersion& ver, bool& is64Bit, char* pName, size_t bufferSize); - bool IsVistaKB940105Required(); - - inline size_t SafeMemoryThreshold(size_t memMB) - { - return (memMB * 8) / 10; - } -} - -#endif // #if defined(WIN32) || defined(WIN64) - - -#endif // CRYINCLUDE_CRYSYSTEM_AUTODETECTSPEC_H diff --git a/Code/CryEngine/CrySystem/CMakeLists.txt b/Code/CryEngine/CrySystem/CMakeLists.txt index 3261526e8e..5a43051ed7 100644 --- a/Code/CryEngine/CrySystem/CMakeLists.txt +++ b/Code/CryEngine/CrySystem/CMakeLists.txt @@ -9,46 +9,17 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) add_subdirectory(XML) -# The following target is a 'C' file only library to work around an issue in cmake and VS generators that -# will append 'std=c++17' to both C and C++ compiler flags for clang. Do not add any .cpp files to this -# library. -ly_add_target( - NAME CrySystem.DLMalloc.C STATIC - NAMESPACE Legacy - FILES_CMAKE - crysystem_dlmalloc_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - PRIVATE - ${pal_dir} -) - - -ly_get_pal_tool_dirs(pal_tool_dirs ${CMAKE_CURRENT_LIST_DIR}/Platform) - ly_add_target( NAME CrySystem.Static STATIC NAMESPACE Legacy FILES_CMAKE crysystem_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake INCLUDE_DIRECTORIES PUBLIC . - ${pal_dir} - PRIVATE - ${common_dir} - ${pal_tool_dirs} BUILD_DEPENDENCIES - PUBLIC - Legacy::CrySystem.DLMalloc.C PRIVATE 3rdParty::expat 3rdParty::lz4 @@ -68,19 +39,11 @@ ly_add_source_properties( VALUES ${LY_PAL_TOOLS_DEFINES} ) -ly_add_source_properties( - SOURCES SystemCFG.cpp - PROPERTY COMPILE_DEFINITIONS - VALUES LY_BUILD=${LY_VERSION_BUILD_NUMBER} -) - ly_add_target( NAME CrySystem ${PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE} NAMESPACE Legacy FILES_CMAKE crysystem_shared_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake INCLUDE_DIRECTORIES PUBLIC . @@ -90,29 +53,3 @@ ly_add_target( AZ::AzCore Legacy::CryCommon ) - -################################################################################ -# Tests -################################################################################ -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - - ly_add_target( - NAME CrySystem.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Legacy - FILES_CMAKE - crysystem_test_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - Legacy::CryCommon - Legacy::CrySystem.Static - AZ::AzFramework - ) - ly_add_googletest( - NAME Legacy::CrySystem.Tests - ) -endif() - diff --git a/Code/CryEngine/CrySystem/CPUDetect.cpp b/Code/CryEngine/CrySystem/CPUDetect.cpp deleted file mode 100644 index 6d924a1514..0000000000 --- a/Code/CryEngine/CrySystem/CPUDetect.cpp +++ /dev/null @@ -1,1622 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "AutoDetectSpec.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CPUDETECT_CPP_SECTION_1 1 -#define CPUDETECT_CPP_SECTION_2 2 -#endif - -#if defined(WIN32) -#include -#elif defined(LINUX) || defined(APPLE) -#include // setrlimit, getrlimit -#endif - -#if defined(APPLE) -#include -#include // mach_thread_self -#include // Mac OS Thread affinity API -#include -#endif - -#if defined(LINUX) -#ifndef __GNU_SOURCE -#define __GNU_SOURCE -#endif -#include //already includes sched.h -#endif - -/* features */ -#define FPU_FLAG 0x0001 -#define SERIAL_FLAG 0x40000 -#define MMX_FLAG 0x800000 -#define ISSE_FLAG 0x2000000 - -#ifdef __GNUC__ -# define cpuid(op, eax, ebx, ecx, edx) __asm__("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (op) : "cc"); -#endif - -int g_CpuFlags; - -struct SAutoMaxPriority -{ - SAutoMaxPriority() - { - /* get a copy of the current thread and process priorities */ -#if defined(WIN32) - priority_class = GetPriorityClass(GetCurrentProcess()); - thread_priority = GetThreadPriority(GetCurrentThread()); -#elif defined(LINUX) || defined(APPLE) - nice_priority = getpriority(PRIO_PROCESS, 0); - success = nice_priority >= 0 && - pthread_getschedparam(pthread_self(), &thread_policy, &thread_sched_param) == 0; -#endif - - /* make this thread the highest possible priority */ -#if defined(WIN32) - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); -#elif defined(LINUX) || defined(APPLE) - if (success) - { - setpriority(PRIO_PROCESS, 0, MAX_NICE_PRIORITY); - - sched_param new_sched_param = thread_sched_param; - new_sched_param.sched_priority = sched_get_priority_max(thread_policy); - pthread_setschedparam(pthread_self(), thread_policy, &new_sched_param); - } -#endif - } - - ~SAutoMaxPriority() - { - /* restore the thread priority */ -#if defined(WIN32) - SetPriorityClass(GetCurrentProcess(), priority_class); - SetThreadPriority(GetCurrentThread(), thread_priority); -#elif defined(LINUX) || defined(APPLE) - if (success) - { - pthread_setschedparam(pthread_self(), thread_policy, &thread_sched_param); - setpriority(PRIO_PROCESS, 0, nice_priority); - } -#endif - } - -#if defined(WIN32) - uint32 priority_class; - int thread_priority; -#elif defined(LINUX) || defined(APPLE) - rlimit nice_limit; - int nice_priority; - int thread_policy; - sched_param thread_sched_param; - bool success; - enum - { - MAX_NICE_PRIORITY = 40 - }; -#endif -}; - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_ASM_VOLATILE_CPUID -static inline void __cpuid(int CPUInfo[4], int InfoType) -{ - asm volatile("cpuid" : "=a" (*CPUInfo), "=b" (*(CPUInfo + 1)), "=c" (*(CPUInfo + 2)), "=d" (*(CPUInfo + 3)) : "a" (InfoType)); -} -#endif - -bool IsAMD() -{ -// Broken out for validation support. -#if defined(WIN32) || (defined(LINUX) && !defined(ANDROID)) || defined(MAC) - #define AZ_SUPPORTS_AMD -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CPUDETECT_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(CPUDetect_cpp) -#endif - -#if defined(AZ_SUPPORTS_AMD) - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000000); - - char szCPU[13]; - memset(szCPU, 0, sizeof(szCPU)); - *(int*)&szCPU[0] = CPUInfo[1]; - *(int*)&szCPU[4] = CPUInfo[3]; - *(int*)&szCPU[8] = CPUInfo[2]; - - return (strcmp(szCPU, "AuthenticAMD") == 0); -#else - return false; -#endif -} - -bool IsIntel() -{ -#if defined(WIN32) || (defined(LINUX) && !defined(ANDROID)) || defined(MAC) - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000000); - - char szCPU[13]; - memset(szCPU, 0, sizeof(szCPU)); - *(int*)&szCPU[0] = CPUInfo[1]; - *(int*)&szCPU[4] = CPUInfo[3]; - *(int*)&szCPU[8] = CPUInfo[2]; - - return (strcmp(szCPU, "GenuineIntel") == 0); -#else - return false; -#endif -} - -bool Has64bitExtension() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HAS64BITEXT - int CPUInfo[4]; - __cpuid(CPUInfo, 0x80000001); // Argument "Processor Signature and AMD Features" - if (CPUInfo[3] & 0x20000000) // Bit 29 in edx is set if 64-bit address extension is supported - { - return true; - } - else - { - return false; - } -#elif defined(WIN64) || defined(LINUX64) || defined(MAC) - return true; -#else - return false; -#endif -} - -bool HTSupported() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HTSUPPORTED - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - if (CPUInfo[3] & 0x10000000) // Bit 28 in edx is set if HT is supported - { - return true; - } - else - { - return false; - } -#else - return false; -#endif -} - -uint8 LogicalProcPerPhysicalProc() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - // Bits 16-23 in ebx contain the number of logical processors per physical processor when execute cpuid with eax set to 1 - return (uint8) ((CPUInfo[1] & 0x00FF0000) >> 16); -#else - return 1; -#endif -} - -uint8 GetAPIC_ID() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - // Bits 24-31 in ebx contain the unique initial APIC ID for the processor this code is running on. Default value = 0xff if HT is not supported. - return (uint8) ((CPUInfo[1] & 0xFF000000) >> 24); -#else - return 0; -#endif -} - -void GetCPUName(char* pName) -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - if (pName) - { - int CPUInfo[4]; - __cpuid(CPUInfo, 0x80000000); - if (CPUInfo[0] >= 0x80000004) - { - __cpuid(CPUInfo, 0x80000002); - ((int*)pName)[0] = CPUInfo[0]; - ((int*)pName)[1] = CPUInfo[1]; - ((int*)pName)[2] = CPUInfo[2]; - ((int*)pName)[3] = CPUInfo[3]; - - __cpuid(CPUInfo, 0x80000003); - ((int*)pName)[4] = CPUInfo[0]; - ((int*)pName)[5] = CPUInfo[1]; - ((int*)pName)[6] = CPUInfo[2]; - ((int*)pName)[7] = CPUInfo[3]; - - __cpuid(CPUInfo, 0x80000004); - ((int*)pName)[8] = CPUInfo[0]; - ((int*)pName)[9] = CPUInfo[1]; - ((int*)pName)[10] = CPUInfo[2]; - ((int*)pName)[11] = CPUInfo[3]; - } - else - { - pName[0] = '\0'; - } - } -#else - if (pName) - { - pName[0] = '\0'; - } -#endif -} - -bool HasFPUOnChip() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - // Bit 0 in edx indicates presents of on chip FPU - return (CPUInfo[3] & 0x00000001) != 0; -#else - return false; -#endif -} - -void GetCPUSteppingModelFamily(int& stepping, int& model, int& family) -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - stepping = CPUInfo[0] & 0xF; // Bit 0-3 in eax specifies stepping - model = (CPUInfo[0] >> 4) & 0xF; // Bit 4-7 in eax specifies model - family = (CPUInfo[0] >> 8) & 0xF; // Bit 8-11 in eax specifies family -#else - stepping = 0; - model = 0; - family = 0; -#endif -} - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID -unsigned long GetCPUFeatureSet() -{ - unsigned long features = 0; - - int CPUInfo[4]; - - __cpuid(CPUInfo, 0); - const int nIds = CPUInfo[0]; - - __cpuid(CPUInfo, 0x80000000); - const unsigned int nExIds = CPUInfo[0]; - - if (nIds > 0) - { - __cpuid(CPUInfo, 0x00000001); - - if (CPUInfo[3] & (1 << 26)) - { - features |= CFI_SSE2; - } - if (CPUInfo[3] & (1 << 25)) - { - features |= CFI_SSE; - } - if (CPUInfo[2] & (1 << 0)) - { - features |= CFI_SSE3; - } - if (CPUInfo[2] & (1 << 29)) - { - features |= CFI_F16C; - } - if (CPUInfo[2] & (1 << 19)) - { - features |= CFI_SSE41; - } - } - - if (nExIds > 0x80000000) - { - __cpuid(CPUInfo, 0x80000001); - if (CPUInfo[3] & (1 << 31)) - { - features |= CFI_3DNOW; - } - } - - return features; -} -#endif - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEFINE_DETECT_PROCESSOR -static unsigned long __stdcall DetectProcessor(void* arg) -{ - const char hex_chars[16] = - { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - unsigned long signature = 0; - unsigned long cache_temp; - unsigned long cache_eax = 0; - unsigned long cache_ebx = 0; - unsigned long cache_ecx = 0; - unsigned long cache_edx = 0; - unsigned long features_edx = 0; - unsigned long serial_number[3]; - unsigned char cpu_type; - unsigned char fpu_type; - unsigned char CPUID_flag = 0; - unsigned char celeron_flag = 0; - unsigned char pentiumxeon_flag = 0; - unsigned char amd3d_flag = 0; - unsigned char name_flag = 0; - char vendor[13]; - vendor[0] = '\0'; - char name[49]; - name[0] = '\0'; - char* serial; - const char* cpu_string; - const char* cpu_extra_string; - const char* fpu_string; - const char* vendor_string; - SCpu* p = (SCpu*) arg; - - memset(p, 0, sizeof(*p)); - - if (IsAMD() && Has64bitExtension()) - { - p->meVendor = eCVendor_AMD; - p->mFeatures |= GetCPUFeatureSet(); - p->mbSerialPresent = false; - azstrcpy(p->mSerialNumber, AZ_ARRAY_SIZE(p->mSerialNumber), ""); - GetCPUSteppingModelFamily(p->mStepping, p->mModel, p->mFamily); - azstrcpy(p->mVendor, AZ_ARRAY_SIZE(p->mVendor), "AMD"); - GetCPUName(p->mCpuType); - azstrcpy(p->mFpuType, AZ_ARRAY_SIZE(p->mFpuType), HasFPUOnChip() ? "On-Chip" : "Unknown"); - p->mbPhysical = true; - - return 1; - } - else if (IsIntel() && Has64bitExtension()) - { - p->meVendor = eCVendor_Intel; - p->mFeatures |= GetCPUFeatureSet(); - p->mbSerialPresent = false; - azstrcpy(p->mSerialNumber, AZ_ARRAY_SIZE(p->mSerialNumber), ""); - GetCPUSteppingModelFamily(p->mStepping, p->mModel, p->mFamily); - azstrcpy(p->mVendor, AZ_ARRAY_SIZE(p->mVendor), "Intel"); - GetCPUName(p->mCpuType); - azstrcpy(p->mFpuType, AZ_ARRAY_SIZE(p->mFpuType), HasFPUOnChip() ? "On-Chip" : "Unknown"); - - p->mbPhysical = true; - - return 1; - } - - cpu_type = 0xF; - fpu_type = 3; - signature = 0; - - p->mFamily = cpu_type; - p->mModel = (signature >> 4) & 0xf; - p->mStepping = signature & 0xf; - - p->mFeatures = 0; - - p->mFeatures |= amd3d_flag ? CFI_3DNOW : 0; - p->mFeatures |= (features_edx & MMX_FLAG) ? CFI_MMX : 0; - p->mFeatures |= (features_edx & ISSE_FLAG) ? CFI_SSE : 0; - p->mbSerialPresent = ((features_edx & SERIAL_FLAG) != 0); - - if (features_edx & SERIAL_FLAG) - { - serial_number[0] = serial_number[1] = serial_number[2] = 0; - - /* format number */ - serial = p->mSerialNumber; - - serial[0] = hex_chars[(serial_number[2] >> 28) & 0x0f]; - serial[1] = hex_chars[(serial_number[2] >> 24) & 0x0f]; - serial[2] = hex_chars[(serial_number[2] >> 20) & 0x0f]; - serial[3] = hex_chars[(serial_number[2] >> 16) & 0x0f]; - - serial[4] = '-'; - - serial[5] = hex_chars[(serial_number[2] >> 12) & 0x0f]; - serial[6] = hex_chars[(serial_number[2] >> 8) & 0x0f]; - serial[7] = hex_chars[(serial_number[2] >> 4) & 0x0f]; - serial[8] = hex_chars[(serial_number[2] >> 0) & 0x0f]; - - serial[9] = '-'; - - serial[10] = hex_chars[(serial_number[1] >> 28) & 0x0f]; - serial[11] = hex_chars[(serial_number[1] >> 24) & 0x0f]; - serial[12] = hex_chars[(serial_number[1] >> 20) & 0x0f]; - serial[13] = hex_chars[(serial_number[1] >> 16) & 0x0f]; - - serial[14] = '-'; - - serial[15] = hex_chars[(serial_number[1] >> 12) & 0x0f]; - serial[16] = hex_chars[(serial_number[1] >> 8) & 0x0f]; - serial[17] = hex_chars[(serial_number[1] >> 4) & 0x0f]; - serial[18] = hex_chars[(serial_number[1] >> 0) & 0x0f]; - - serial[19] = '-'; - - serial[20] = hex_chars[(serial_number[0] >> 28) & 0x0f]; - serial[21] = hex_chars[(serial_number[0] >> 24) & 0x0f]; - serial[22] = hex_chars[(serial_number[0] >> 20) & 0x0f]; - serial[23] = hex_chars[(serial_number[0] >> 16) & 0x0f]; - - serial[24] = '-'; - - serial[25] = hex_chars[(serial_number[0] >> 12) & 0x0f]; - serial[26] = hex_chars[(serial_number[0] >> 8) & 0x0f]; - serial[27] = hex_chars[(serial_number[0] >> 4) & 0x0f]; - serial[28] = hex_chars[(serial_number[0] >> 0) & 0x0f]; - - serial[29] = 0; - } - - vendor_string = "Unknown"; - cpu_string = "Unknown"; - cpu_extra_string = ""; - fpu_string = "Unknown"; - - if (!CPUID_flag) - { - switch (cpu_type) - { - case 0: - cpu_string = "8086"; - break; - - case 2: - cpu_string = "80286"; - break; - - case 3: - cpu_string = "80386"; - switch (fpu_type) - { - case 2: - fpu_string = "80287"; - break; - - case 1: - fpu_string = "80387"; - break; - - default: - fpu_string = "None"; - break; - } - break; - - case 4: - if (fpu_type) - { - cpu_string = "80486DX, 80486DX2 or 80487SX"; - fpu_string = "on-chip"; - } - else - { - cpu_string = "80486SX"; - } - break; - } - } - else - { /* using CPUID instruction */ - if (!name_flag) - { - if (!strcmp(vendor, "GenuineIntel")) - { - vendor_string = "Intel"; - switch (cpu_type) - { - case 4: - switch (p->mModel) - { - case 0: - case 1: - cpu_string = "80486DX"; - break; - - case 2: - cpu_string = "80486SX"; - break; - - case 3: - cpu_string = "80486DX2"; - break; - - case 4: - cpu_string = "80486SL"; - break; - - case 5: - cpu_string = "80486SX2"; - break; - - case 7: - cpu_string = "Write-Back Enhanced 80486DX2"; - break; - - case 8: - cpu_string = "80486DX4"; - break; - - default: - cpu_string = "80486"; - } - break; - - case 5: - switch (p->mModel) - { - default: - case 1: - case 2: - case 3: - cpu_string = "Pentium"; - break; - - case 4: - cpu_string = "Pentium MMX"; - break; - } - break; - - case 6: - switch (p->mModel) - { - case 1: - cpu_string = "Pentium Pro"; - break; - - case 3: - cpu_string = "Pentium II"; - break; - - case 5: - case 7: - { - cache_temp = cache_eax & 0xFF000000; - if (cache_temp == 0x40000000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44000000) && (cache_temp <= 0x45000000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_eax & 0xFF0000; - if (cache_temp == 0x400000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x440000) && (cache_temp <= 0x450000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_eax & 0xFF00; - if (cache_temp == 0x4000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x4400) && (cache_temp <= 0x4500)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ebx & 0xFF000000; - if (cache_temp == 0x40000000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44000000) && (cache_temp <= 0x45000000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ebx & 0xFF0000; - if (cache_temp == 0x400000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x440000) && (cache_temp <= 0x450000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ebx & 0xFF00; - if (cache_temp == 0x4000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x4400) && (cache_temp <= 0x4500)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ebx & 0xFF; - if (cache_temp == 0x40) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44) && (cache_temp <= 0x45)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ecx & 0xFF000000; - if (cache_temp == 0x40000000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44000000) && (cache_temp <= 0x45000000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ecx & 0xFF0000; - if (cache_temp == 0x400000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x440000) && (cache_temp <= 0x450000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ecx & 0xFF00; - if (cache_temp == 0x4000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x4400) && (cache_temp <= 0x4500)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ecx & 0xFF; - if (cache_temp == 0x40) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44) && (cache_temp <= 0x45)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_edx & 0xFF000000; - if (cache_temp == 0x40000000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44000000) && (cache_temp <= 0x45000000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_edx & 0xFF0000; - if (cache_temp == 0x400000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x440000) && (cache_temp <= 0x450000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_edx & 0xFF00; - if (cache_temp == 0x4000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x4400) && (cache_temp <= 0x4500)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_edx & 0xFF; - if (cache_temp == 0x40) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44) && (cache_temp <= 0x45)) - { - pentiumxeon_flag = 1; - } - - if (celeron_flag) - { - cpu_string = "Celeron"; - } - else - { - if (pentiumxeon_flag) - { - if (p->mModel == 5) - { - cpu_string = "Pentium II Xeon"; - } - else - { - cpu_string = "Pentium III Xeon"; - } - } - else - { - if (p->mModel == 5) - { - cpu_string = "Pentium II"; - } - else - { - cpu_string = "Pentium III"; - } - } - } - } - break; - - case 6: - cpu_string = "Celeron"; - break; - - case 8: - cpu_string = "Pentium III"; - break; - } - break; - } - - if (signature & 0x1000) - { - cpu_extra_string = " OverDrive"; - } - else - if (signature & 0x2000) - { - cpu_extra_string = " dual upgrade"; - } - } - else - if (!strcmp(vendor, "CyrixInstead")) - { - vendor_string = "Cyrix"; - switch (p->mFamily) - { - case 4: - switch (p->mModel) - { - case 4: - cpu_string = "MediaGX"; - break; - } - break; - - case 5: - switch (p->mModel) - { - case 2: - cpu_string = "6x86"; - break; - - case 4: - cpu_string = "GXm"; - break; - } - break; - - case 6: - switch (p->mModel) - { - case 0: - cpu_string = "6x86MX"; - break; - } - break; - } - } - else - if (!strcmp(vendor, "AuthenticAMD")) - { - cry_strcpy(p->mVendor, "AMD"); - switch (p->mFamily) - { - case 4: - cpu_string = "Am486 or Am5x86"; - break; - - case 5: - switch (p->mModel) - { - case 0: - case 1: - case 2: - case 3: - cpu_string = "K5"; - break; - - case 4: - case 5: - case 6: - case 7: - cpu_string = "K6"; - break; - - case 8: - cpu_string = "K6-2"; - break; - - case 9: - cpu_string = "K6-III"; - break; - } - break; - - case 6: - cpu_string = "Athlon"; - break; - } - } - else - if (!strcmp(vendor, "CentaurHauls")) - { - vendor_string = "Centaur"; - switch (cpu_type) - { - case 5: - switch (p->mModel) - { - case 4: - cpu_string = "WinChip"; - break; - - case 8: - cpu_string = "WinChip2"; - break; - } - break; - } - } - else - if (!strcmp(vendor, "UMC UMC UMC ")) - { - vendor_string = "UMC"; - } - else - if (!strcmp(vendor, "NexGenDriven")) - { - vendor_string = "NexGen"; - } - } - else - { - vendor_string = vendor; - cpu_string = name; - } - - if (features_edx & FPU_FLAG) - { - fpu_string = "On-Chip"; - } - else - { - fpu_string = "Unknown"; - } - } - - stack_string sCpuType = stack_string(cpu_string) + cpu_extra_string; - - cry_strcpy(p->mCpuType, sCpuType.c_str()); - cry_strcpy(p->mFpuType, fpu_string); - cry_strcpy(p->mVendor, vendor_string); - - if (!azstricmp(vendor_string, "Intel")) - { - p->meVendor = eCVendor_Intel; - } - else - if (!azstricmp(vendor_string, "Cyrix")) - { - p->meVendor = eCVendor_Cyrix; - } - else - if (!azstricmp(vendor_string, "AMD")) - { - p->meVendor = eCVendor_AMD; - } - else - if (!azstricmp(vendor_string, "Centaur")) - { - p->meVendor = eCVendor_Centaur; - } - else - if (!azstricmp(vendor_string, "NexGen")) - { - p->meVendor = eCVendor_NexGen; - } - else - if (!azstricmp(vendor_string, "UMC")) - { - p->meVendor = eCVendor_UMC; - } - else - { - p->meVendor = eCVendor_Unknown; - } - - if (strstr(cpu_string, "8086")) - { - p->meModel = eCpu_8086; - } - else - if (strstr(cpu_string, "80286")) - { - p->meModel = eCpu_80286; - } - else - if (strstr(cpu_string, "80386")) - { - p->meModel = eCpu_80386; - } - else - if (strstr(cpu_string, "80486")) - { - p->meModel = eCpu_80486; - } - else - if (!azstricmp(cpu_string, "Pentium MMX") || !azstricmp(cpu_string, "Pentium")) - { - p->meModel = eCpu_Pentium; - } - else - if (!azstricmp(cpu_string, "Pentium Pro")) - { - p->meModel = eCpu_PentiumPro; - } - else - if (!azstricmp(cpu_string, "Pentium II")) - { - p->meModel = eCpu_Pentium2; - } - else - if (!azstricmp(cpu_string, "Pentium III")) - { - p->meModel = eCpu_Pentium3; - } - else - if (!azstricmp(cpu_string, "Pentium 4")) - { - p->meModel = eCpu_Pentium4; - } - else - if (!azstricmp(cpu_string, "Celeron")) - { - p->meModel = eCpu_Celeron; - } - else - if (!azstricmp(cpu_string, "Pentium II Xeon")) - { - p->meModel = eCpu_Pentium2Xeon; - } - else - if (!azstricmp(cpu_string, "Pentium III Xeon")) - { - p->meModel = eCpu_Pentium3Xeon; - } - else - if (!azstricmp(cpu_string, "MediaGX")) - { - p->meModel = eCpu_CyrixMediaGX; - } - else - if (!azstricmp(cpu_string, "6x86")) - { - p->meModel = eCpu_Cyrix6x86; - } - else - if (!azstricmp(cpu_string, "GXm")) - { - p->meModel = eCpu_CyrixGXm; - } - else - if (!azstricmp(cpu_string, "6x86MX")) - { - p->meModel = eCpu_Cyrix6x86MX; - } - else - if (!azstricmp(cpu_string, "Am486 or Am5x86")) - { - p->meModel = eCpu_Am5x86; - } - else - if (!azstricmp(cpu_string, "K5")) - { - p->meModel = eCpu_AmK5; - } - else - if (!azstricmp(cpu_string, "K6")) - { - p->meModel = eCpu_AmK6; - } - else - if (!azstricmp(cpu_string, "K6-2")) - { - p->meModel = eCpu_AmK6_2; - } - else - if (!azstricmp(cpu_string, "K6-III")) - { - p->meModel = eCpu_AmK6_3; - } - else - if (!azstricmp(cpu_string, "Athlon")) - { - p->meModel = eCpu_AmAthlon; - } - else - if (!azstricmp(cpu_string, "Duron")) - { - p->meModel = eCpu_AmDuron; - } - else - if (!azstricmp(cpu_string, "WinChip")) - { - p->meModel = eCpu_CenWinChip; - } - else - if (!azstricmp(cpu_string, "WinChip2")) - { - p->meModel = eCpu_CenWinChip2; - } - else - { - p->meModel = eCpu_Unknown; - } - - p->mbPhysical = true; - if (!strcmp(vendor_string, "GenuineIntel") && p->mStepping > 4 && HTSupported()) - { - p->mbPhysical = (GetAPIC_ID() & LogicalProcPerPhysicalProc() - 1) == 0; - } - - return 1; -} -#endif //AZ_LEGACY_CRYSYSTEM_TRAIT_DEFINE_DETECT_PROCESSOR - -#if defined(MAC) || (defined(LINUX) && !defined(ANDROID)) -static void* DetectProcessorThreadProc(void* pData) -{ - DetectProcessor(pData); - return NULL; -} -#endif // MAC LINUX - -// #define SQRT_TEST -#ifdef SQRT_TEST -/* ------------------------------------------------------------------------------ */ - -ILINE float CorrectInvSqrt(float fNum, float fInvSqrtEst) -{ - // Newton-Rhapson method for improving estimated inv sqrt. - // f(x) = x^(-1/2) - // f(n) = f(a) + (n-a)f'(a) - // = a^(-1/2) + (n-a)(-1/2)a^(-3/2) - // = a^(-1/2)*3/2 - na^(-3/2)/2 - // = e*3/2 - ne^3/2 - return fInvSqrtEst * (1.5f - fNum * fInvSqrtEst * fInvSqrtEst * 0.5f); -} - - -float Null(float f) { return f; } -float Inv(float f) { return 1.f / f; } - -float Square(float f) { return f * f; } -float InvSquare(float f) { return 1.f / (f * f); } - -float Sqrt(float f) { return sqrtf(f); } -float SqrtT(float f) { return sqrt_tpl(f); } -float SqrtFT(float f) { return sqrt_fast_tpl(f); } - -float InvSqrt(float f) { return 1.f / sqrtf(f); } -float ISqrtT(float f) { return isqrt_tpl(f); } -float ISqrtFT(float f) { return isqrt_fast_tpl(f); } - -float SSEInv(float f) -{ - __m128 s = _mm_rcp_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return r; -} -float SSESqrt(float f) -{ - __m128 s = _mm_sqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return r; -} -float SSEISqrt(float f) -{ - __m128 s = _mm_sqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return 1.f / r; -} -float SSERSqrt(float f) -{ - __m128 s = _mm_rsqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return r; -} -float SSERSqrtInv(float f) -{ - __m128 s = _mm_rcp_ss(_mm_rsqrt_ss(_mm_load_ss(&f))); - float r; - _mm_store_ss(&r, s); - return r; -} -float SSERSqrtNR(float f) -{ - __m128 s = _mm_rsqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return CorrectInvSqrt(f, r); -} -float SSERISqrtNR(float f) -{ - __m128 s = _mm_rsqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return 1.f / CorrectInvSqrt(f, r); -} - -inline float cryISqrtf(float fVal) -{ - unsigned int* n1 = (unsigned int*)&fVal; - unsigned int n = 0x5f3759df - (*n1 >> 1); - float* n2 = (float*)&n; - fVal = (1.5f - (fVal * 0.5f) * *n2 * *n2) * *n2; - return fVal; -} - -float cryISqrtNRf(float f) -{ - return CorrectInvSqrt(f, cryISqrtf(f)); -} - -inline float crySqrtf(float fVal) -{ - return 1.0f / cryISqrtf(fVal); -} - -/* ------------------------------------------------------------------------------ */ -struct SMathTest -{ - typedef int64 TTime; - static inline TTime GetTime() - { - return CryGetTicks(); - } - - static const int T = 100, N = 1000; - float fNullTime; - - float aTestVals[T]; - float aResVals[T]; - - typedef float (* FFloatFunc)(float f); - - float Timer(const char* sName, FFloatFunc func, FFloatFunc finv) - { - for (int i = 0; i < T; i++) - { - aResVals[i] = func(aTestVals[i]); - } - TTime tStart = GetTime(); - for (int r = 0; r < N; r++) - { - for (int i = 0; i < T; i++) - { - aResVals[i] = func(aTestVals[i]); - } - } - float fTime = (GetTime() - tStart) / float(N * T); - - // Error computation. - float fAvgErr = 0.f, fMaxErr = 0.f; - for (int i = 0; i < T; i++) - { - float fErr = abs(finv(aResVals[i]) / aTestVals[i] - 1.f); - fAvgErr += fErr; - fMaxErr = max(fMaxErr, fErr); - } - fAvgErr /= float(T); - - CryLogAlways("%-20s : %5.2f cycles, avg err %.2e, max err %.2e", sName, fTime - fNullTime, fAvgErr, fMaxErr); - - return fTime; - }; - - SMathTest() - { - for (int i = 0; i < T; i++) - { - aTestVals[i] = powf(cry_random(1.f, 2.f), cry_random(-30.f, 30.f)); - } - - CryLogAlways("--- Math Test ---"); - - fNullTime = 0.f; - fNullTime = Timer("(null)", &Null, &Null); - - CryLogAlways("-- Inverse methods"); - Timer("1/f", &Inv, &Inv); - Timer("rcpss", &SSEInv, &Inv); - - CryLogAlways("-- Sqrt methods"); - Timer("sqrtf()", &Sqrt, &Square); - Timer("sqrt_tpl()", &SqrtT, &Square); - Timer("sqrt_fast_tpl()", &SqrtFT, &Square); - Timer("crySqrt()", &crySqrtf, &Square); - - // Timer("sqrtss", &SSESqrt, &Square); - // Timer("rsqrtss,rcpss", &SSERSqrtInv, &Square); - Timer("1/rsqrtss,correction", &SSERISqrtNR, &Square); - - CryLogAlways("-- InvSqrt methods"); - Timer("1/sqrtf()", &InvSqrt, &InvSquare); - Timer("isqrt_tpl()", &ISqrtT, &InvSquare); - Timer("isqrt_fast_tpl()", &ISqrtFT, &InvSquare); - Timer("cryISqrt()", &cryISqrtf, &InvSquare); - - Timer("1/sqrtss", &SSEISqrt, &InvSquare); - // Timer("rsqrtss", &SSERSqrt, &InvSquare); - // Timer("rsqrtss,correction", &SSERSqrtNR, &InvSquare); - Timer("cryISqrt,correction", &cryISqrtNRf, &InvSquare); - - CryLogAlways("--------------------"); - } -}; - -#endif // SQRT_TEST - -#if defined(LINUX) -// collection of functions to read from /proc/cpuinfo - -static bool proc_read_str(char* buffer, char* output, size_t output_length) -{ - if (!buffer || !output || output_length <= 0) - { - return false; - } - while (*buffer && *buffer != ':') - { - ++buffer; - } - if (*buffer == ':') - { - buffer += 2; - cry_strcpy(output, output_length, buffer); - const int len = strlen(output); - if (len > 0 && output[len - 1] == '\n') - { - output[len - 1] = '\0'; - } - return true; - } - return false; -} - - -static bool proc_read_int(char* buffer, int& output) -{ - if (!buffer) - { - return false; - } - while (*buffer && *buffer != ':') - { - ++buffer; - } - if (*buffer == ':') - { - buffer += 2; - output = atoi(buffer); - return true; - } - return false; -} -#endif - -/* ------------------------------------------------------------------------------ */ -void CCpuFeatures::Detect(void) -{ - m_NumSystemProcessors = 1; - m_NumAvailProcessors = 0; - - ////////////////////////////////////////////////////////////////////////// -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASAFFINITYMASK - CryLogAlways(""); - - DWORD_PTR process_affinity_mask = 1; - - /* get the system info to derive the number of processors within the system. */ - - SYSTEM_INFO sys_info; - DWORD_PTR system_affinity_mask; - GetSystemInfo(&sys_info); - m_NumLogicalProcessors = m_NumSystemProcessors = sys_info.dwNumberOfProcessors; - m_NumAvailProcessors = 0; - GetProcessAffinityMask(GetCurrentProcess(), &process_affinity_mask, &system_affinity_mask); - - for (unsigned char c = 0; c < m_NumSystemProcessors; c++) - { - if (process_affinity_mask & ((DWORD_PTR)1 << c)) - { - m_NumAvailProcessors++; - SetProcessAffinityMask(GetCurrentProcess(), DWORD_PTR(1) << c); - DetectProcessor(&m_Cpu[c]); - m_Cpu[c].mAffinityMask = ((DWORD_PTR)1 << c); - } - } - - SetProcessAffinityMask(GetCurrentProcess(), process_affinity_mask); - - m_bOS_ISSE = false; - m_bOS_ISSE_EXCEPTIONS = false; -#elif defined(LINUX) - // Retrieve information from /proc/cpuinfo - FILE* cpu_info = fopen("/proc/cpuinfo", "r"); - if (!cpu_info) - { - m_NumLogicalProcessors = m_NumSystemProcessors = m_NumAvailProcessors = 1; - CryLogAlways("Could not open /proc/cpuinfo, defaulting values to 1."); - } - else - { - int nCores = 0; - int nCpu = -1; - int index = 0; - char buffer[512]; - while (!feof(cpu_info)) - { - if (nCpu >= MAX_CPU) - { - --nCpu; //Decrement so the sets after the while loop matches the number of CPUs examined - CryLogAlways("Found a higher than expected number of CPUs, defaulting to %d", MAX_CPU); - break; - } - - fgets(buffer, sizeof(buffer), cpu_info); - - if (buffer[0] == '\0' || buffer[0] == '\n') - { - continue; - } - - if (strncmp("processor", buffer, (index = strlen("processor"))) == 0) - { - ++nCpu; - } - else if (strncmp("vendor_id", buffer, (index = strlen("vendor_id"))) == 0) - { - proc_read_str(&buffer[index], m_Cpu[nCpu].mVendor, sizeof(m_Cpu[nCpu].mVendor)); - } - else if (strncmp("model name", buffer, (index = strlen("model name"))) == 0) - { - proc_read_str(&buffer[index], m_Cpu[nCpu].mCpuType, sizeof(m_Cpu[nCpu].mCpuType)); - } - else if (strncmp("cpu cores", buffer, (index = strlen("cpu cores"))) == 0 && nCores == 0) - { - proc_read_int(&buffer[index], nCores); - } - else if (strncmp("fpu", buffer, (index = strlen("fpu"))) == 0) - { - while (buffer[index] != ':' && index < 512) - { - ++index; - } - if (buffer[index] == ':') - { - if (strncmp(&buffer[index + 2], "yes", 3) == 0) - { - snprintf(m_Cpu[nCpu].mFpuType, sizeof(m_Cpu[nCpu].mFpuType), "On-Chip"); - } - else - { - snprintf(m_Cpu[nCpu].mFpuType, sizeof(m_Cpu[nCpu].mFpuType), "Unkown"); - } - } - } - else if (strncmp("cpu family", buffer, (index = strlen("cpu family"))) == 0) - { - proc_read_int(&buffer[index], m_Cpu[nCpu].mFamily); - } - else if (strncmp("model", buffer, (index = strlen("model"))) == 0) - { - proc_read_int(&buffer[index], m_Cpu[nCpu].mModel); - } - else if (strncmp("stepping", buffer, (index = strlen("stepping"))) == 0) - { - proc_read_int(&buffer[index], m_Cpu[nCpu].mStepping); - } - else if (strncmp("flags", buffer, (index = strlen("flags"))) == 0) - { - if (strstr(buffer + index, "mmx")) - { - m_Cpu[nCpu].mFeatures |= CFI_MMX; - } - - if (strstr(buffer + index, "sse")) - { - m_Cpu[nCpu].mFeatures |= CFI_SSE; - } - - if (strstr(buffer + index, "sse2")) - { - m_Cpu[nCpu].mFeatures |= CFI_SSE2; - } - } - } - m_NumLogicalProcessors = m_NumAvailProcessors = nCpu + 1; - m_NumSystemProcessors = nCores; - } - - -#elif defined(APPLE) - size_t len; - unsigned int ncpu; - - len = sizeof(ncpu); - if (sysctlbyname ("hw.physicalcpu_max", &ncpu, &len, NULL, 0) == 0) - { - m_NumSystemProcessors = ncpu; - } - else - { - CryLogAlways("Failed to detect the number of available processors, defaulting to 1"); - m_NumSystemProcessors = 1; - } - - if (sysctlbyname ("hw.logicalcpu_max", &ncpu, &len, NULL, 0) == 0) - { - m_NumAvailProcessors = m_NumLogicalProcessors = ncpu; - } - else - { - CryLogAlways("Failed to detect the number of available logical processors, defaulting to 1"); - m_NumAvailProcessors = m_NumLogicalProcessors = 1; - } - uint64_t cpu_freq; - len = sizeof(cpu_freq); - if (sysctlbyname ("hw.cpufrequency_max", &cpu_freq, &len, NULL, 0) != 0) - { - CryLogAlways("Failed to detect cpu frequency , defaulting to 0"); - cpu_freq = 0; - } - - // On macs, the processors are always the same model, so we can easily - // calculate once and apply the settings for all. - SCpu cpuInfo; -#if !defined(IOS) - DetectProcessor(&cpuInfo); -#endif - for (int c = 0; c < m_NumAvailProcessors; c++) - { - m_Cpu[c] = cpuInfo; - } - -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CPUDETECT_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(CPUDetect_cpp) -#endif - - -#if defined(WIN32) || defined(WIN64) - CryLogAlways("Total number of logical processors: %d", m_NumSystemProcessors); - CryLogAlways("Number of available logical processors: %d", m_NumAvailProcessors); - - unsigned int numSysCores(1), numProcessCores(1); - Win32SysInspect::GetNumCPUCores(numSysCores, numProcessCores); - m_NumSystemProcessors = numSysCores; - m_NumAvailProcessors = numProcessCores; - CryLogAlways("Total number of system cores: %d", m_NumSystemProcessors); - CryLogAlways("Number of cores available to process: %d", m_NumAvailProcessors); - -#else - CryLogAlways("Number of system processors: %d", m_NumSystemProcessors); - CryLogAlways("Number of available processors: %d", m_NumAvailProcessors); -#endif - - if (m_NumAvailProcessors > MAX_CPU) - { - m_NumAvailProcessors = MAX_CPU; - } - - for (int i = 0; i < m_NumAvailProcessors; i++) - { - SCpu* p = &m_Cpu[i]; - - CryLogAlways(" "); - CryLogAlways("Processor %d:", i); - CryLogAlways(" CPU: %s %s", p->mVendor, p->mCpuType); - CryLogAlways(" Family: %d, Model: %d, Stepping: %d", p->mFamily, p->mModel, p->mStepping); - CryLogAlways(" FPU: %s", p->mFpuType); - CryLogAlways(" 3DNow!: %s", (p->mFeatures & CFI_3DNOW) ? "present" : "not present"); - CryLogAlways(" MMX: %s", (p->mFeatures & CFI_MMX) ? "present" : "not present"); - CryLogAlways(" SSE: %s", (p->mFeatures & CFI_SSE) ? "present" : "not present"); - CryLogAlways(" SSE2: %s", (p->mFeatures & CFI_SSE2) ? "present" : "not present"); - CryLogAlways(" SSE3: %s", (p->mFeatures & CFI_SSE3) ? "present" : "not present"); - CryLogAlways(" SSE4.1: %s", (p->mFeatures& CFI_SSE41) ? "present" : "not present"); - if (p->mbSerialPresent) - { - CryLogAlways(" Serial number: %s", p->mSerialNumber); - } - else - { - CryLogAlways(" Serial number not present or disabled"); - } - } - -#ifdef SQRT_TEST - SMathTest test; -#endif - - CryLogAlways(" "); - - //m_NumPhysicsProcessors = m_NumSystemProcessors; - for (int i = m_NumPhysicsProcessors = 0; i < m_NumAvailProcessors; i++) - { - if (m_Cpu[i].mbPhysical) - { - ++m_NumPhysicsProcessors; - } - } - - // Set the cpu flags global variable - g_CpuFlags = 0; - if (hasMMX()) - { - g_CpuFlags |= CPUF_MMX; - } - if (hasSSE()) - { - g_CpuFlags |= CPUF_SSE; - } - if (hasSSE2()) - { - g_CpuFlags |= CPUF_SSE2; - } - if (hasSSE3()) - { - g_CpuFlags |= CPUF_SSE3; - } - if (hasSSE41()) - { - g_CpuFlags |= CPUF_SSE41; - } - if (has3DNow()) - { - g_CpuFlags |= CPUF_3DNOW; - } - if (hasF16C()) - { - g_CpuFlags |= CPUF_F16C; - } -} - diff --git a/Code/CryEngine/CrySystem/CPUDetect.h b/Code/CryEngine/CrySystem/CPUDetect.h deleted file mode 100644 index e2851d5f23..0000000000 --- a/Code/CryEngine/CrySystem/CPUDetect.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_CPUDETECT_H -#define CRYINCLUDE_CRYSYSTEM_CPUDETECT_H -#pragma once - - -//------------------------------------------------------- -/// Cpu class -//------------------------------------------------------- -#if defined(WIN64) || defined(LINUX) - #define MAX_CPU 96 -#else - #define MAX_CPU 32 -#endif - -/// Cpu Features -#define CFI_FPUEMULATION 0x01 -#define CFI_MMX 0x02 -#define CFI_3DNOW 0x04 -#define CFI_SSE 0x08 -#define CFI_SSE2 0x10 -#define CFI_SSE3 0x20 -#define CFI_F16C 0x40 -#define CFI_SSE41 0x80 - -/// Type of Cpu Vendor. -enum ECpuVendor -{ - eCVendor_Unknown, - eCVendor_Intel, - eCVendor_Cyrix, - eCVendor_AMD, - eCVendor_Centaur, - eCVendor_NexGen, - eCVendor_UMC, - eCVendor_M68K -}; - -/// Type of Cpu Model. -enum ECpuModel -{ - eCpu_Unknown, - - eCpu_8086, - eCpu_80286, - eCpu_80386, - eCpu_80486, - eCpu_Pentium, - eCpu_PentiumPro, - eCpu_Pentium2, - eCpu_Pentium3, - eCpu_Pentium4, - eCpu_Pentium2Xeon, - eCpu_Pentium3Xeon, - eCpu_Celeron, - eCpu_CeleronA, - - eCpu_Am5x86, - eCpu_AmK5, - eCpu_AmK6, - eCpu_AmK6_2, - eCpu_AmK6_3, - eCpu_AmK6_3D, - eCpu_AmAthlon, - eCpu_AmDuron, - - eCpu_CyrixMediaGX, - eCpu_Cyrix6x86, - eCpu_CyrixGXm, - eCpu_Cyrix6x86MX, - - eCpu_CenWinChip, - eCpu_CenWinChip2, -}; - -struct SCpu -{ - ECpuVendor meVendor; - ECpuModel meModel; - unsigned long mFeatures; - bool mbSerialPresent; - char mSerialNumber[30]; - int mFamily; - int mModel; - int mStepping; - char mVendor[64]; - char mCpuType[64]; - char mFpuType[64]; - bool mbPhysical; // false for hyperthreaded - DWORD_PTR mAffinityMask; - - // constructor - SCpu() - : meVendor(eCVendor_Unknown) - , meModel(eCpu_Unknown) - , mFeatures(0) - , mbSerialPresent(false) - , mFamily(0) - , mModel(0) - , mStepping(0) - , mbPhysical(true) - , mAffinityMask(0) - { - memset(mSerialNumber, 0, sizeof(mSerialNumber)); - memset(mVendor, 0, sizeof(mVendor)); - memset(mCpuType, 0, sizeof(mCpuType)); - memset(mFpuType, 0, sizeof(mFpuType)); - } -}; - -class CCpuFeatures -{ -private: - int m_NumLogicalProcessors; - int m_NumSystemProcessors; - int m_NumAvailProcessors; - int m_NumPhysicsProcessors; - bool m_bOS_ISSE; - bool m_bOS_ISSE_EXCEPTIONS; -public: - - SCpu m_Cpu[MAX_CPU]; - -public: - CCpuFeatures() - { - m_NumLogicalProcessors = 0; - m_NumSystemProcessors = 0; - m_NumAvailProcessors = 0; - m_NumPhysicsProcessors = 0; - m_bOS_ISSE = 0; - m_bOS_ISSE_EXCEPTIONS = 0; - ZeroMemory(m_Cpu, sizeof(m_Cpu)); - } - - void Detect(void); - bool hasSSE() { return (m_Cpu[0].mFeatures & CFI_SSE) != 0; } - bool hasSSE2() { return (m_Cpu[0].mFeatures & CFI_SSE2) != 0; } - bool hasSSE3() { return (m_Cpu[0].mFeatures & CFI_SSE3) != 0; } - bool hasSSE41() { return (m_Cpu[0].mFeatures & CFI_SSE41) != 0; } - bool has3DNow() { return (m_Cpu[0].mFeatures & CFI_3DNOW) != 0; } - bool hasMMX() { return (m_Cpu[0].mFeatures & CFI_MMX) != 0; } - bool hasF16C() { return (m_Cpu[0].mFeatures & CFI_F16C) != 0; } - - unsigned int GetLogicalCPUCount() { return m_NumLogicalProcessors; } - unsigned int GetPhysCPUCount() { return m_NumPhysicsProcessors; } - unsigned int GetCPUCount() { return m_NumAvailProcessors; } - DWORD_PTR GetCPUAffinityMask(unsigned int iCPU) { assert(iCPU < MAX_CPU); return iCPU < GetCPUCount() ? m_Cpu[iCPU].mAffinityMask : 0; } - DWORD_PTR GetPhysCPUAffinityMask(unsigned int iCPU) - { - if (iCPU > GetPhysCPUCount()) - { - return 0; - } - int i; - for (i = 0; (int)iCPU >= 0; i++) - { - if (m_Cpu[i].mbPhysical) - { - --iCPU; - } - } - PREFAST_ASSUME(i > 0 && i < MAX_CPU); - return m_Cpu[i - 1].mAffinityMask; - } -}; - -#endif // CRYINCLUDE_CRYSYSTEM_CPUDETECT_H diff --git a/Code/CryEngine/CrySystem/ClientHandler.cpp b/Code/CryEngine/CrySystem/ClientHandler.cpp deleted file mode 100644 index a708d876f9..0000000000 --- a/Code/CryEngine/CrySystem/ClientHandler.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "ClientHandler.h" - -ClientHandler::ClientHandler(const char* bucket, int affinity, int clientTimeout) - : HandlerBase(bucket, affinity) -{ - m_clientTimeout = clientTimeout; - Reset(); -} - -void ClientHandler::Reset() -{ - m_srvLock.reset(0); - for (int i = 0; i < MAX_CLIENTS_NUM; i++) - { - std::unique_ptr srv(new SSyncLock(m_serverLockName, i, false)); - - // first get the client lock up! - if (!srv->IsValid()) - { - //try to create client lock - m_clientLock.reset(new SSyncLock(m_clientLockName, i, true)); - if (m_clientLock->IsValid()) - { - break; - } - else - { - m_clientLock.reset(0); - } - } - } -} - -bool ClientHandler::ServerIsValid() -{ - if (!m_srvLock.get()) - { - if (m_clientLock.get() && m_clientLock->IsValid()) - { - m_srvLock.reset(new SSyncLock(m_serverLockName, m_clientLock->number, false)); - if (m_srvLock->IsValid()) - { - SetAffinity(); - //got synched - return true; - } - m_srvLock.reset(0); - } - return false; - } - return m_srvLock->IsValid(); -} - -bool ClientHandler::Sync() -{ - if (ServerIsValid()) - { - m_clientLock->Signal();//signal that we're done and - if (m_srvLock->Wait(m_clientTimeout))//wait for server - { - //bla bla, track waiting - return true; - } - else - { - Reset(); - } - } - return false; -} - -#endif // defined(MAP_LOADING_SLICING) diff --git a/Code/CryEngine/CrySystem/ClientHandler.h b/Code/CryEngine/CrySystem/ClientHandler.h deleted file mode 100644 index ce325270ad..0000000000 --- a/Code/CryEngine/CrySystem/ClientHandler.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_CLIENTHANDLER_H -#define CRYINCLUDE_CRYSYSTEM_CLIENTHANDLER_H -#pragma once - -#include "HandlerBase.h" -#include "SyncLock.h" - -struct ClientHandler - : public HandlerBase -{ - ClientHandler(const char* bucket, int affinity, int clientTimeout); - - void Reset(); - bool ServerIsValid(); - bool Sync(); - -private: - int m_clientTimeout; - std::unique_ptr m_clientLock; - std::unique_ptr m_srvLock; -}; - -#endif diff --git a/Code/CryEngine/CrySystem/Components/MathConversionTests.cpp b/Code/CryEngine/CrySystem/Components/MathConversionTests.cpp deleted file mode 100644 index 2ee2bc71f2..0000000000 --- a/Code/CryEngine/CrySystem/Components/MathConversionTests.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" -#include - -#include -#include -#include - -//namespace MathConversionUnitTests -//{ -const float kEpsilon = 0.01f; - -bool IsNearlyEqual(const AZ::Vector3& az, const Vec3& ly) -{ - return fcmp(az.GetX(), ly.x, kEpsilon) - && fcmp(az.GetY(), ly.y, kEpsilon) - && fcmp(az.GetZ(), ly.z, kEpsilon); -} - -bool IsNearlyEqual(const AZ::Quaternion& az, const Quat& ly) -{ - return fcmp(az.GetX(), ly.v.x, kEpsilon) - && fcmp(az.GetY(), ly.v.y, kEpsilon) - && fcmp(az.GetZ(), ly.v.z, kEpsilon) - && fcmp(az.GetW(), ly.w, kEpsilon); -} - -bool IsNearlyEqual(const AZ::Transform& az, const Matrix34& ly) -{ - float azFloats[12]; - const AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromTransform(az); - matrix3x4.StoreToRowMajorFloat12(azFloats); - - const float* lyFloats = ly.GetData(); - - for (int i = 0; i < 12; ++i) - { - if (!fcmp(azFloats[i], lyFloats[i], kEpsilon)) - { - return false; - } - } - return true; -} - -bool IsNearlyEqual(const AZ::Transform& az, const QuatT& ly) -{ - return IsNearlyEqual(az.GetTranslation(), ly.t) - && IsNearlyEqual(az.GetRotation(), ly.q); -} - -TEST(MathConversionTests, BasicConversions) -{ - { // check vector3 comparisons - AZ::Vector3 az(1.f, 2.f, 3.f); - Vec3 ly(1.f, 2.f, 3.f); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // reverse XYZ - ly = Vec3(3.f, 2.f, 1.f); - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - - // off by 0.1 - ly = Vec3(1.1f, 2.1f, 3.1f); - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - } - - { // check vector3 conversions - Vec3 ly1(1.f, 2.f, 3.f); - AZ::Vector3 az = LYVec3ToAZVec3(ly1); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - - Vec3 ly2 = AZVec3ToLYVec3(az); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - EXPECT_TRUE(ly1.IsEquivalent(ly2)); - } - - { // check quaternion comparisons - AZ::Quaternion az(AZ::Quaternion::CreateIdentity()); - Quat ly(IDENTITY); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - az = AZ::Quaternion(1.f, 2.f, 3.f, 4.f); - ly = Quat(4.f, 1.f, 2.f, 3.f); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // w in wrong place - ly = Quat(1.f, 2.f, 3.f, 4.f); - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - } - - { // check quaternion conversions - Quat ly1(4.f, 1.f, 2.f, 3.f); - AZ::Quaternion az = LYQuaternionToAZQuaternion(ly1); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - - Quat ly2 = AZQuaternionToLYQuaternion(az); - EXPECT_TRUE(IsNearlyEqual(az, ly2)); - EXPECT_TRUE(Quat::IsEquivalent(ly1, ly2)); - } - - { // check transform comparisons - AZ::Transform az = AZ::Transform::Identity(); - Matrix34 ly = Matrix34::CreateIdentity(); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // rotating pi/2 will get us a non-symmetric matrix. - // good for testing that we're not confusing rows & columns - float rotation = gf_PI / 2.f; - - ly = Matrix34::CreateRotationX(rotation, Vec3(1.f, 2.f, 3.f)); - az = AZ::Transform::CreateRotationX(rotation); - az.SetTranslation(1.f, 2.f, 3.f); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // rotate around different axis - ly = Matrix34::CreateRotationY(rotation, Vec3(1.f, 2.f, 3.f)); - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - } - - { // check transform conversions - Matrix34 ly1 = Matrix34::CreateRotationXYZ(Ang3(0.1f, 0.5f, 0.9f), Vec3(1.f, 2.f, 3.f)); - AZ::Transform az = LYTransformToAZTransform(ly1); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - - Matrix34 ly2 = AZTransformToLYTransform(az); - EXPECT_TRUE(IsNearlyEqual(az, ly2)); - EXPECT_TRUE(Matrix34::IsEquivalent(ly1, ly2)); - } - - { // check QuatT comparisons - AZ::Transform az = AZ::Transform::Identity(); - QuatT ly(IDENTITY); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - az = AZ::Transform::CreateRotationX(AZ::Constants::HalfPi); - az.SetTranslation(1.f, 2.f, 3.f); - ly.q.SetRotationX(AZ::Constants::HalfPi); - ly.t.Set(1.f, 2.f, 3.f); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // off by 0.1 - ly.t.z += 0.1f; - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - } - - { // check QuatT conversions - QuatT ly1(Quat::CreateRotationX(AZ::Constants::HalfPi), Vec3(5.f, 6.f, 7.f)); - AZ::Transform az = LYQuatTToAZTransform(ly1); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - - QuatT ly2 = AZTransformToLYQuatT(az); - EXPECT_TRUE(IsNearlyEqual(az, ly2)); - EXPECT_TRUE(QuatT::IsEquivalent(ly1, ly2)); - } -} -//} // namespace MathConversionUnitTests diff --git a/Code/CryEngine/CrySystem/CompressedFile.cpp b/Code/CryEngine/CrySystem/CompressedFile.cpp deleted file mode 100644 index 9166466e3d..0000000000 --- a/Code/CryEngine/CrySystem/CompressedFile.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "CryZlib.h" - -bool CSystem::CompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize, int level) -{ - uLongf destLen = outputSize; - Bytef* dest = static_cast(output); - uLong sourceLen = inputSize; - const Bytef* source = static_cast(input); - bool ok = Z_OK == compress2(dest, &destLen, source, sourceLen, level); - outputSize = destLen; - return ok; -} - -bool CSystem::DecompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize) -{ - uLongf destLen = outputSize; - Bytef* dest = static_cast(output); - uLong sourceLen = inputSize; - const Bytef* source = static_cast(input); - bool ok = Z_OK == uncompress(dest, &destLen, source, sourceLen); - outputSize = destLen; - return ok; -} diff --git a/Code/CryEngine/CrySystem/CryAsyncMemcpy.cpp b/Code/CryEngine/CrySystem/CryAsyncMemcpy.cpp deleted file mode 100644 index b2aaea1634..0000000000 --- a/Code/CryEngine/CrySystem/CryAsyncMemcpy.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include - -namespace -{ - static void cryAsyncMemcpy_Int( - void* dst - , const void* src - , size_t size - , int nFlags - , volatile int* sync) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::System); - - cryMemcpy(dst, src, size, nFlags); - if (sync) - { - CryInterlockedDecrement(sync); - } - } -} - -#if !defined(CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM) -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpy( -#else -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpyDelegate( -#endif - void* dst - , const void* src - , size_t size - , int nFlags - , volatile int* sync) -{ - AZ::Job* job = AZ::CreateJobFunction( - [dst, src, size, nFlags, sync]() - { - cryAsyncMemcpy_Int(dst, src, size, nFlags, sync); - }, - true); // Auto-delete - job->Start(); -} - - - diff --git a/Code/CryEngine/CrySystem/CryDLMalloc.c b/Code/CryEngine/CrySystem/CryDLMalloc.c deleted file mode 100644 index bcb835b0d5..0000000000 --- a/Code/CryEngine/CrySystem/CryDLMalloc.c +++ /dev/null @@ -1,6645 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#define DEFAULT_GRANULARITY (64 * 1024) //this gets #undef and redefined in the .inl this has to come before that - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CRYDLMALLOC_C_SECTION_1 1 -#define CRYDLMALLOC_C_SECTION_2 2 - -#include "../../Framework/AzCore/AzCore/PlatformRestrictedFileDef.h" -#define AZ_RESTRICTED_SECTION CRYDLMALLOC_C_SECTION_1 -#include AZ_RESTRICTED_FILE(CryDLMalloc_c) -#elif defined(_WIN32) || defined(LINUX) || defined(APPLE) -#define TRAIT_ENABLE_DLMALLOC 1 -#endif - -#if defined(BUCKET_SIMULATOR) || TRAIT_ENABLE_DLMALLOC -/* - This is a version (aka dlmalloc) of malloc/free/realloc written by - Doug Lea and released to the public domain, as explained at - http://creativecommons.org/licenses/publicdomain. Send questions, - comments, complaints, performance data, etc to dl@cs.oswego.edu - -* Version 2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at - ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - -* Quickstart - - This library is all in one file to simplify the most common usage: - ftp it, compile it (-O3), and link it into another program. All of - the compile-time options default to reasonable values for use on - most platforms. You might later want to step through various - compile-time and dynamic tuning options. - - For convenience, an include file for code using this malloc is at: - ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.4.h - You don't really need this .h file unless you call functions not - defined in your system include files. The .h file contains only the - excerpts from this file needed for using this malloc on ANSI C/C++ - systems, so long as you haven't changed compile-time options about - naming and tuning parameters. If you do, then you can create your - own malloc.h that does include all settings by cutting at the point - indicated below. Note that you may already by default be using a C - library containing a malloc that is based on some version of this - malloc (for example in linux). You might still want to use the one - in this file to customize settings or to avoid overheads associated - with library versions. - -* Vital statistics: - - Supported pointer/size_t representation: 4 or 8 bytes - size_t MUST be an unsigned type of the same width as - pointers. (If you are using an ancient system that declares - size_t as a signed type, or need it to be a different width - than pointers, you can use a previous release of this malloc - (e.g. 2.7.2) supporting these.) - - Alignment: 8 bytes (default) - This suffices for nearly all current machines and C compilers. - However, you can define MALLOC_ALIGNMENT to be wider than this - if necessary (up to 128bytes), at the expense of using more space. - - Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) - 8 or 16 bytes (if 8byte sizes) - Each malloced chunk has a hidden word of overhead holding size - and status information, and additional cross-check word - if FOOTERS is defined. - - Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) - 8-byte ptrs: 32 bytes (including overhead) - - Even a request for zero bytes (i.e., malloc(0)) returns a - pointer to something of the minimum allocatable size. - The maximum overhead wastage (i.e., number of extra bytes - allocated than were requested in malloc) is less than or equal - to the minimum size, except for requests >= mmap_threshold that - are serviced via mmap(), where the worst case wastage is about - 32 bytes plus the remainder from a system page (the minimal - mmap unit); typically 4096 or 8192 bytes. - - Security: static-safe; optionally more or less - The "security" of malloc refers to the ability of malicious - code to accentuate the effects of errors (for example, freeing - space that is not currently malloc'ed or overwriting past the - ends of chunks) in code that calls malloc. This malloc - guarantees not to modify any memory locations below the base of - heap, i.e., static variables, even in the presence of usage - errors. The routines additionally detect most improper frees - and reallocs. All this holds as long as the static bookkeeping - for malloc itself is not corrupted by some other means. This - is only one aspect of security -- these checks do not, and - cannot, detect all possible programming errors. - - If FOOTERS is defined nonzero, then each allocated chunk - carries an additional check word to verify that it was malloced - from its space. These check words are the same within each - execution of a program using malloc, but differ across - executions, so externally crafted fake chunks cannot be - freed. This improves security by rejecting frees/reallocs that - could corrupt heap memory, in addition to the checks preventing - writes to statics that are always on. This may further improve - security at the expense of time and space overhead. (Note that - FOOTERS may also be worth using with MSPACES.) - - By default detected errors cause the program to abort (calling - "abort()"). You can override this to instead proceed past - errors by defining PROCEED_ON_ERROR. In this case, a bad free - has no effect, and a malloc that encounters a bad address - caused by user overwrites will ignore the bad address by - dropping pointers and indices to all known memory. This may - be appropriate for programs that should continue if at all - possible in the face of programming errors, although they may - run out of memory because dropped memory is never reclaimed. - - If you don't like either of these options, you can define - CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything - else. And if if you are sure that your program using malloc has - no errors or vulnerabilities, you can define INSECURE to 1, - which might (or might not) provide a small performance improvement. - - Thread-safety: NOT thread-safe unless USE_LOCKS defined - When USE_LOCKS is defined, each public call to malloc, free, - etc is surrounded with either a pthread mutex or a win32 - spinlock (depending on WIN32). This is not especially fast, and - can be a major bottleneck. It is designed only to provide - minimal protection in concurrent environments, and to provide a - basis for extensions. If you are using malloc in a concurrent - program, consider instead using nedmalloc - (http://www.nedprod.com/programs/portable/nedmalloc/) or - ptmalloc (See http://www.malloc.de), which are derived - from versions of this malloc. - - System requirements: Any combination of MORECORE and/or MMAP/MUNMAP - This malloc can use unix sbrk or any emulation (invoked using - the CALL_MORECORE macro) and/or mmap/munmap or any emulation - (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system - memory. On most unix systems, it tends to work best if both - MORECORE and MMAP are enabled. On Win32, it uses emulations - based on VirtualAlloc. It also uses common C library functions - like memset. - - Compliance: I believe it is compliant with the Single Unix Specification - (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably - others as well. - -* Overview of algorithms - - This is not the fastest, most space-conserving, most portable, or - most tunable malloc ever written. However it is among the fastest - while also being among the most space-conserving, portable and - tunable. Consistent balance across these factors results in a good - general-purpose allocator for malloc-intensive programs. - - In most ways, this malloc is a best-fit allocator. Generally, it - chooses the best-fitting existing chunk for a request, with ties - broken in approximately least-recently-used order. (This strategy - normally maintains low fragmentation.) However, for requests less - than 256bytes, it deviates from best-fit when there is not an - exactly fitting available chunk by preferring to use space adjacent - to that used for the previous small request, as well as by breaking - ties in approximately most-recently-used order. (These enhance - locality of series of small allocations.) And for very large requests - (>= 256Kb by default), it relies on system memory mapping - facilities, if supported. (This helps avoid carrying around and - possibly fragmenting memory used only for large chunks.) - - All operations (except malloc_stats and mallinfo) have execution - times that are bounded by a constant factor of the number of bits in - a size_t, not counting any clearing in calloc or copying in realloc, - or actions surrounding MORECORE and MMAP that have times - proportional to the number of non-contiguous regions returned by - system allocation routines, which is often just 1. In real-time - applications, you can optionally suppress segment traversals using - NO_SEGMENT_TRAVERSAL, which assures bounded execution even when - system allocators return non-contiguous spaces, at the typical - expense of carrying around more memory and increased fragmentation. - - The implementation is not very modular and seriously overuses - macros. Perhaps someday all C compilers will do as good a job - inlining modular code as can now be done by brute-force expansion, - but now, enough of them seem not to. - - Some compilers issue a lot of warnings about code that is - dead/unreachable only on some platforms, and also about intentional - uses of negation on unsigned types. All known cases of each can be - ignored. - - For a longer but out of date high-level description, see - http://gee.cs.oswego.edu/dl/html/malloc.html - -* MSPACES - If MSPACES is defined, then in addition to malloc, free, etc., - this file also defines mspace_malloc, mspace_free, etc. These - are versions of malloc routines that take an "mspace" argument - obtained using create_mspace, to control all internal bookkeeping. - If ONLY_MSPACES is defined, only these versions are compiled. - So if you would like to use this allocator for only some allocations, - and your system malloc for others, you can compile with - ONLY_MSPACES and then do something like... - static mspace mymspace = create_mspace(0,0); // for example - #define mymalloc(bytes) mspace_malloc(mymspace, bytes) - - (Note: If you only need one instance of an mspace, you can instead - use "USE_DL_PREFIX" to relabel the global malloc.) - - You can similarly create thread-local allocators by storing - mspaces as thread-locals. For example: - static __thread mspace tlms = 0; - void* tlmalloc(size_t bytes) { - if (tlms == 0) tlms = create_mspace(0, 0); - return mspace_malloc(tlms, bytes); - } - void tlfree(void* mem) { mspace_free(tlms, mem); } - - Unless FOOTERS is defined, each mspace is completely independent. - You cannot allocate from one and free to another (although - conformance is only weakly checked, so usage errors are not always - caught). If FOOTERS is defined, then each chunk carries around a tag - indicating its originating mspace, and frees are directed to their - originating spaces. - - ------------------------- Compile-time options --------------------------- - -Be careful in setting #define values for numerical constants of type -size_t. On some systems, literal values are not automatically extended -to size_t precision unless they are explicitly casted. You can also -use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. - -WIN32 default: defined if _WIN32 defined - Defining WIN32 sets up defaults for MS environment and compilers. - Otherwise defaults are for unix. Beware that there seem to be some - cases where this malloc might not be a pure drop-in replacement for - Win32 malloc: Random-looking failures from Win32 GDI API's (eg; - SetDIBits()) may be due to bugs in some video driver implementations - when pixel buffers are malloc()ed, and the region spans more than - one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) - default granularity, pixel buffers may straddle virtual allocation - regions more often than when using the Microsoft allocator. You can - avoid this by using VirtualAlloc() and VirtualFree() for all pixel - buffers rather than using malloc(). If this is not possible, - recompile this malloc with a larger DEFAULT_GRANULARITY. - -MALLOC_ALIGNMENT default: (size_t)8 - Controls the minimum alignment for malloc'ed chunks. It must be a - power of two and at least 8, even on machines for which smaller - alignments would suffice. It may be defined as larger than this - though. Note however that code and data structures are optimized for - the case of 8-byte alignment. - -MSPACES default: 0 (false) - If true, compile in support for independent allocation spaces. - This is only supported if HAVE_MMAP is true. - -ONLY_MSPACES default: 0 (false) - If true, only compile in mspace versions, not regular versions. - -USE_LOCKS default: 0 (false) - Causes each call to each public routine to be surrounded with - pthread or WIN32 mutex lock/unlock. (If set true, this can be - overridden on a per-mspace basis for mspace versions.) If set to a - non-zero value other than 1, locks are used, but their - implementation is left out, so lock functions must be supplied manually, - as described below. - -USE_SPIN_LOCKS default: 1 iff USE_LOCKS and on x86 using gcc or MSC - If true, uses custom spin locks for locking. This is currently - supported only for x86 platforms using gcc or recent MS compilers. - Otherwise, posix locks or win32 critical sections are used. - -FOOTERS default: 0 - If true, provide extra checking and dispatching by placing - information in the footers of allocated chunks. This adds - space and time overhead. - -INSECURE default: 0 - If true, omit checks for usage errors and heap space overwrites. - -USE_DL_PREFIX default: NOT defined - Causes compiler to prefix all public routines with the string 'dl'. - This can be useful when you only want to use this malloc in one part - of a program, using your regular system malloc elsewhere. - -ABORT default: defined as abort() - Defines how to abort on failed checks. On most systems, a failed - check cannot die with an "assert" or even print an informative - message, because the underlying print routines in turn call malloc, - which will fail again. Generally, the best policy is to simply call - abort(). It's not very useful to do more than this because many - errors due to overwriting will show up as address faults (null, odd - addresses etc) rather than malloc-triggered checks, so will also - abort. Also, most compilers know that abort() does not return, so - can better optimize code conditionally calling it. - -PROCEED_ON_ERROR default: defined as 0 (false) - Controls whether detected bad addresses cause them to bypassed - rather than aborting. If set, detected bad arguments to free and - realloc are ignored. And all bookkeeping information is zeroed out - upon a detected overwrite of freed heap space, thus losing the - ability to ever return it from malloc again, but enabling the - application to proceed. If PROCEED_ON_ERROR is defined, the - static variable malloc_corruption_error_count is compiled in - and can be examined to see if errors have occurred. This option - generates slower code than the default abort policy. - -DEBUG default: NOT defined - The DEBUG setting is mainly intended for people trying to modify - this code or diagnose problems when porting to new platforms. - However, it may also be able to better isolate user errors than just - using runtime checks. The assertions in the check routines spell - out in more detail the assumptions and invariants underlying the - algorithms. The checking is fairly extensive, and will slow down - execution noticeably. Calling malloc_stats or mallinfo with DEBUG - set will attempt to check every non-mmapped allocated and free chunk - in the course of computing the summaries. - -ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) - Debugging assertion failures can be nearly impossible if your - version of the assert macro causes malloc to be called, which will - lead to a cascade of further failures, blowing the runtime stack. - ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), - which will usually make debugging easier. - -MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 - The action to take before "return 0" when malloc fails to be able to - return memory because there is none available. - -HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES - True if this system supports sbrk or an emulation of it. - -MORECORE default: sbrk - The name of the sbrk-style system routine to call to obtain more - memory. See below for guidance on writing custom MORECORE - functions. The type of the argument to sbrk/MORECORE varies across - systems. It cannot be size_t, because it supports negative - arguments, so it is normally the signed type of the same width as - size_t (sometimes declared as "intptr_t"). It doesn't much matter - though. Internally, we only call it with arguments less than half - the max value of a size_t, which should work across all reasonable - possibilities, although sometimes generating compiler warnings. - -MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE - If true, take advantage of fact that consecutive calls to MORECORE - with positive arguments always return contiguous increasing - addresses. This is true of unix sbrk. It does not hurt too much to - set it true anyway, since malloc copes with non-contiguities. - Setting it false when definitely non-contiguous saves time - and possibly wasted space it would take to discover this though. - -MORECORE_CANNOT_TRIM default: NOT defined - True if MORECORE cannot release space back to the system when given - negative arguments. This is generally necessary only if you are - using a hand-crafted MORECORE function that cannot handle negative - arguments. - -NO_SEGMENT_TRAVERSAL default: 0 - If non-zero, suppresses traversals of memory segments - returned by either MORECORE or CALL_MMAP. This disables - merging of segments that are contiguous, and selectively - releasing them to the OS if unused, but bounds execution times. - -HAVE_MMAP default: 1 (true) - True if this system supports mmap or an emulation of it. If so, and - HAVE_MORECORE is not true, MMAP is used for all system - allocation. If set and HAVE_MORECORE is true as well, MMAP is - primarily used to directly allocate very large blocks. It is also - used as a backup strategy in cases where MORECORE fails to provide - space from system. Note: A single call to MUNMAP is assumed to be - able to unmap memory that may have be allocated using multiple calls - to MMAP, so long as they are adjacent. - -HAVE_MREMAP default: 1 on linux, else 0 - If true realloc() uses mremap() to re-allocate large blocks and - extend or shrink allocation spaces. - -MMAP_CLEARS default: 1 except on WINCE. - True if mmap clears memory so calloc doesn't need to. This is true - for standard unix mmap using /dev/zero and on WIN32 except for WINCE. - -USE_BUILTIN_FFS default: 0 (i.e., not used) - Causes malloc to use the builtin ffs() function to compute indices. - Some compilers may recognize and intrinsify ffs to be faster than the - supplied C version. Also, the case of x86 using gcc is special-cased - to an asm instruction, so is already as fast as it can be, and so - this setting has no effect. Similarly for Win32 under recent MS compilers. - (On most x86s, the asm version is only slightly faster than the C version.) - -malloc_getpagesize default: derive from system includes, or 4096. - The system page size. To the extent possible, this malloc manages - memory from the system in page-size units. This may be (and - usually is) a function rather than a constant. This is ignored - if WIN32, where page size is determined using getSystemInfo during - initialization. - -USE_DEV_RANDOM default: 0 (i.e., not used) - Causes malloc to use /dev/random to initialize secure magic seed for - stamping footers. Otherwise, the current time is used. - -NO_MALLINFO default: 0 - If defined, don't compile "mallinfo". This can be a simple way - of dealing with mismatches between system declarations and - those in this file. - -MALLINFO_FIELD_TYPE default: size_t - The type of the fields in the mallinfo struct. This was originally - defined as "int" in SVID etc, but is more usefully defined as - size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set - -REALLOC_ZERO_BYTES_FREES default: not defined - This should be set if a call to realloc with zero bytes should - be the same as a call to free. Some people think it should. Otherwise, - since this malloc returns a unique pointer for malloc(0), so does - realloc(p, 0). - -LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H -LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H -LACKS_STDLIB_H default: NOT defined unless on WIN32 - Define these if your system does not have these header files. - You might need to manually insert some of the declarations they provide. - -DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, - system_info.dwAllocationGranularity in WIN32, - otherwise 64K. - Also settable using mallopt(M_GRANULARITY, x) - The unit for allocating and deallocating memory from the system. On - most systems with contiguous MORECORE, there is no reason to - make this more than a page. However, systems with MMAP tend to - either require or encourage larger granularities. You can increase - this value to prevent system allocation functions to be called so - often, especially if they are slow. The value must be at least one - page and must be a power of two. Setting to 0 causes initialization - to either page size or win32 region size. (Note: In previous - versions of malloc, the equivalent of this option was called - "TOP_PAD") - -DEFAULT_TRIM_THRESHOLD default: 2MB - Also settable using mallopt(M_TRIM_THRESHOLD, x) - The maximum amount of unused top-most memory to keep before - releasing via malloc_trim in free(). Automatic trimming is mainly - useful in long-lived programs using contiguous MORECORE. Because - trimming via sbrk can be slow on some systems, and can sometimes be - wasteful (in cases where programs immediately afterward allocate - more large chunks) the value should be high enough so that your - overall system performance would improve by releasing this much - memory. As a rough guide, you might set to a value close to the - average size of a process (program) running on your system. - Releasing this much memory would allow such a process to run in - memory. Generally, it is worth tuning trim thresholds when a - program undergoes phases where several large chunks are allocated - and released in ways that can reuse each other's storage, perhaps - mixed with phases where there are no such chunks at all. The trim - value must be greater than page size to have any useful effect. To - disable trimming completely, you can set to MAX_SIZE_T. Note that the trick - some people use of mallocing a huge space and then freeing it at - program startup, in an attempt to reserve system memory, doesn't - have the intended effect under automatic trimming, since that memory - will immediately be returned to the system. - -DEFAULT_MMAP_THRESHOLD default: 256K - Also settable using mallopt(M_MMAP_THRESHOLD, x) - The request size threshold for using MMAP to directly service a - request. Requests of at least this size that cannot be allocated - using already-existing space will be serviced via mmap. (If enough - normal freed space already exists it is used instead.) Using mmap - segregates relatively large chunks of memory so that they can be - individually obtained and released from the host system. A request - serviced through mmap is never reused by any other request (at least - not directly; the system may just so happen to remap successive - requests to the same locations). Segregating space in this way has - the benefits that: Mmapped space can always be individually released - back to the system, which helps keep the system level memory demands - of a long-lived program low. Also, mapped memory doesn't become - `locked' between other chunks, as can happen with normally allocated - chunks, which means that even trimming via malloc_trim would not - release them. However, it has the disadvantage that the space - cannot be reclaimed, consolidated, and then used to service later - requests, as happens with normal chunks. The advantages of mmap - nearly always outweigh disadvantages for "large" chunks, but the - value of "large" may vary across systems. The default is an - empirically derived value that works well in most systems. You can - disable mmap by setting to MAX_SIZE_T. - -MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP - The number of consolidated frees between checks to release - unused segments when freeing. When using non-contiguous segments, - especially with multiple mspaces, checking only for topmost space - doesn't always suffice to trigger trimming. To compensate for this, - free() will, with a period of MAX_RELEASE_CHECK_RATE (or the - current number of segments, if greater) try to release unused - segments to the OS when freeing chunks that result in - consolidation. The best value for this parameter is a compromise - between slowing down frees with relatively costly checks that - rarely trigger versus holding on to unused memory. To effectively - disable, set to MAX_SIZE_T. This may lead to a very slight speed - improvement at the expense of carrying around more memory. -*/ - -/* Version identifier to allow people to support multiple versions */ - -#ifndef DLMALLOC_VERSION -#define DLMALLOC_VERSION 20804 -#endif /* DLMALLOC_VERSION */ - - -#define MAX_RELEASE_CHECK_RATE 255 -#define REALLOC_ZERO_BYTES_FREES -#define USE_DL_PREFIX 1 - -#define mspace_create_overhead dlmspace_create_overhead -#define create_mspace dlcreate_mspace -#define destroy_mspace dldestroy_mspace -#define create_mspace_with_base dlcreate_mspace_with_base -#define mspace_track_large_chunks dlmspace_track_large_chunks -#define mspace_malloc dlmspace_malloc -#define mspace_free dlmspace_free -#define mspace_realloc dlmspace_realloc -#define mspace_calloc dlmspace_calloc -#define mspace_memalign dlmspace_memalign -#define mspace_independent_calloc dlmspace_independent_calloc -#define mspace_independent_comalloc dlmspace_independent_comalloc -#define mspace_footprint dlmspace_footprint -#define mspace_max_footprint dlmspace_max_footprint -#define mspace_mallinfo dlmspace_mallinfo -#define mspace_usable_size dlmspace_usable_size -#define mspace_malloc_stats dlmspace_malloc_stats -#define mspace_get_used_space dlmspace_get_used_space -#define mspace_trim dlmspace_trim -#define mspace_mallopt dlmspace_mallopt - -// Avoid x64 warnings with size_t converted to int -#pragma warning(disable : 4267) -#pragma warning(disable : 6239) -#pragma warning(disable : 6297) -#pragma warning(disable : 28182) - -// Conditional expression is constant -#pragma warning(disable : 4127) - -#ifdef BUCKET_SIMULATOR - -#define HAVE_MORECORE 0 -#define MORECORE SimSBrk -#define DEFAULT_MMAP_THRESHOLD (1024 * 1024) -#define DEFAULT_TRIM_THRESHOLD (256 * 1024) - -#include -#include -#include -#include /* For size_t */ -#include - -static void* s_sbrkBase; -static void* s_sbrkEnd; -static void* s_sbrkMax; - -extern volatile int dlmallocmapped; - -void* SimSBrk(ptrdiff_t size) -{ - void* ret = NULL; - - if (!s_sbrkBase) - { - s_sbrkBase = VirtualAlloc(NULL, 64 * 1024 * 1024, MEM_RESERVE, PAGE_READWRITE); - s_sbrkEnd = s_sbrkBase; - s_sbrkMax = (LPVOID) ((INT_PTR) s_sbrkBase + 64 * 1024 * 1024); - } - - if (s_sbrkEnd) - { - if (size > 0) - { - INT_PTR end = (INT_PTR) s_sbrkEnd; - INT_PTR newEnd = end + size; - - if (newEnd <= (INT_PTR) s_sbrkMax) - { - ret = VirtualAlloc(s_sbrkEnd, size, MEM_COMMIT, PAGE_READWRITE); - if (ret) - { - s_sbrkEnd = (LPVOID) newEnd; - CryInterlockedAdd(&dlmallocmapped, (LONG) size); - } - } - } - else if (size < 0) - { - INT_PTR end = (INT_PTR) s_sbrkEnd; - INT_PTR newEnd = end + size; - - if (newEnd >= (INT_PTR) s_sbrkBase) - { - VirtualFree((LPVOID) newEnd, -size, MEM_DECOMMIT); - CryInterlockedAdd(&dlmallocmapped, (LONG) size); - } - } - else - { - ret = s_sbrkEnd; - } - } - - if (!ret) - { - ret = (void*) -1; - errno = ENOMEM; - } - - return ret; -} -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#elif defined(_WIN32) - -#define HAVE_MMAP 1 -#define HAVE_MORECORE (!HAVE_MMAP) -#define USE_LOCKS 0 -#define FOOTERS 0 -#define ONLY_MSPACES 1 -#define DEFAULT_MMAP_THRESHOLD (1024 * 1024) -#define DEFAULT_TRIM_THRESHOLD (256 * 1024) - -#define PROT_READ 0 -#define PROT_WRITE 0 -#define MAP_PRIVATE 0 -#define MAP_ANONYMOUS 1 - -#define MALLOC_ALIGNMENT 16 - -#define malloc_getpagesize (64 * 1024) - -#include -#include - -#elif defined(LINUX) || defined(APPLE) -#include -#define HAVE_MMAP 1 -#define HAVE_MORECORE (!HAVE_MMAP) -#define USE_LOCKS 0 -#define FOOTERS 0 -#define ONLY_MSPACES 1 -#define DEFAULT_MMAP_THRESHOLD (16 * 1024 * 1024) -#define DEFAULT_TRIM_THRESHOLD (16 * 1024 * 1024) - -#if !defined(ANDROID) && !defined(LINUX_CROSS_COMPILE) -#define PROT_READ 0 -#define PROT_WRITE 0 -#define MAP_PRIVATE 0 -#define MAP_ANONYMOUS 1 -#endif - -#define MALLOC_ALIGNMENT 16 - -#define malloc_getpagesize (64 * 1024) - -#include - -// ( || ) is always a non-zero constant. -#pragma warning(disable:6285) - -// Potential comparison of a constant with another constant -#pragma warning(disable:6326) - -// Dereferencing NULL pointer -#pragma warning(disable:6011) - -#endif - -#ifndef WIN32 -#ifdef _WIN32 -#define WIN32 1 -#endif /* _WIN32 */ -#ifdef _WIN32_WCE -#define LACKS_FCNTL_H -#define WIN32 1 -#endif /* _WIN32_WCE */ -#endif /* WIN32 */ - -#ifdef WIN32 -#include -#define HAVE_MMAP 1 -#ifndef HAVE_MORECORE -#define HAVE_MORECORE 0 -#endif -#define LACKS_UNISTD_H -#define LACKS_SYS_PARAM_H -#define LACKS_SYS_MMAN_H -#define LACKS_STRING_H -#define LACKS_STRINGS_H -#define LACKS_SYS_TYPES_H -#define LACKS_ERRNO_H -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION -#endif /* MALLOC_FAILURE_ACTION */ -#ifdef _WIN32_WCE /* WINCE reportedly does not clear */ -#define MMAP_CLEARS 0 -#else -#define MMAP_CLEARS 1 -#endif /* _WIN32_WCE */ -#endif /* WIN32 */ - -#if defined(DARWIN) || defined(_DARWIN) -/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ -#ifndef HAVE_MORECORE -#define HAVE_MORECORE 0 -#define HAVE_MMAP 1 -/* OSX allocators provide 16 byte alignment */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)16U) -#endif -#endif /* HAVE_MORECORE */ -#endif /* DARWIN */ - -#ifndef LACKS_SYS_TYPES_H -#include /* For size_t */ -#endif /* LACKS_SYS_TYPES_H */ - -#if (defined(__GNUC__) && ((defined(__i386__) || defined(__x86_64__)))) || (defined(_MSC_VER)) -#define SPIN_LOCKS_AVAILABLE 1 -#else -#define SPIN_LOCKS_AVAILABLE 0 -#endif - -/* The maximum possible size_t value has all bits set */ -#define MAX_SIZE_T (~(size_t)0) - -#ifndef ONLY_MSPACES -#define ONLY_MSPACES 0 /* define to a value */ -#else -#define ONLY_MSPACES 1 -#endif /* ONLY_MSPACES */ -#ifndef MSPACES -#if ONLY_MSPACES -#define MSPACES 1 -#else /* ONLY_MSPACES */ -#define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)8U) -#endif /* MALLOC_ALIGNMENT */ -#ifndef FOOTERS -#define FOOTERS 0 -#endif /* FOOTERS */ -#ifndef ABORT -#define ABORT abort() -#endif /* ABORT */ -#ifndef ABORT_ON_ASSERT_FAILURE -#define ABORT_ON_ASSERT_FAILURE 1 -#endif /* ABORT_ON_ASSERT_FAILURE */ -#ifndef PROCEED_ON_ERROR -#define PROCEED_ON_ERROR 0 -#endif /* PROCEED_ON_ERROR */ -#ifndef USE_LOCKS -#define USE_LOCKS 0 -#endif /* USE_LOCKS */ -#ifndef USE_SPIN_LOCKS -#if USE_LOCKS && SPIN_LOCKS_AVAILABLE -#define USE_SPIN_LOCKS 1 -#else -#define USE_SPIN_LOCKS 0 -#endif /* USE_LOCKS && SPIN_LOCKS_AVAILABLE. */ -#endif /* USE_SPIN_LOCKS */ -#ifndef INSECURE -#define INSECURE 0 -#endif /* INSECURE */ -#ifndef HAVE_MMAP -#define HAVE_MMAP 1 -#endif /* HAVE_MMAP */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 1 -#endif /* MMAP_CLEARS */ -#ifndef HAVE_MREMAP -#ifdef linux -#define HAVE_MREMAP 1 -#else /* linux */ -#define HAVE_MREMAP 0 -#endif /* linux */ -#endif /* HAVE_MREMAP */ -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION errno = ENOMEM; -#endif /* MALLOC_FAILURE_ACTION */ -#ifndef HAVE_MORECORE -#if ONLY_MSPACES -#define HAVE_MORECORE 0 -#else /* ONLY_MSPACES */ -#define HAVE_MORECORE 1 -#endif /* ONLY_MSPACES */ -#endif /* HAVE_MORECORE */ -#if !HAVE_MORECORE -#define MORECORE_CONTIGUOUS 0 -#else /* !HAVE_MORECORE */ -#define MORECORE_DEFAULT sbrk -#ifndef MORECORE_CONTIGUOUS -#define MORECORE_CONTIGUOUS 1 -#endif /* MORECORE_CONTIGUOUS */ -#endif /* HAVE_MORECORE */ -#ifndef DEFAULT_GRANULARITY -#if (MORECORE_CONTIGUOUS || defined(WIN32)) -#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ -#else /* MORECORE_CONTIGUOUS */ -#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) -#endif /* MORECORE_CONTIGUOUS */ -#endif /* DEFAULT_GRANULARITY */ -#ifndef DEFAULT_TRIM_THRESHOLD -#ifndef MORECORE_CANNOT_TRIM -#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) -#else /* MORECORE_CANNOT_TRIM */ -#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T -#endif /* MORECORE_CANNOT_TRIM */ -#endif /* DEFAULT_TRIM_THRESHOLD */ -#ifndef DEFAULT_MMAP_THRESHOLD -#if HAVE_MMAP -#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) -#else /* HAVE_MMAP */ -#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* DEFAULT_MMAP_THRESHOLD */ -#ifndef MAX_RELEASE_CHECK_RATE -#if HAVE_MMAP -#define MAX_RELEASE_CHECK_RATE 4095 -#else -#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* MAX_RELEASE_CHECK_RATE */ -#ifndef USE_BUILTIN_FFS -#define USE_BUILTIN_FFS 0 -#endif /* USE_BUILTIN_FFS */ -#ifndef USE_DEV_RANDOM -#define USE_DEV_RANDOM 0 -#endif /* USE_DEV_RANDOM */ -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ -#ifndef NO_SEGMENT_TRAVERSAL -#define NO_SEGMENT_TRAVERSAL 0 -#endif /* NO_SEGMENT_TRAVERSAL */ - -/* - mallopt tuning options. SVID/XPG defines four standard parameter - numbers for mallopt, normally defined in malloc.h. None of these - are used in this malloc, so setting them has no effect. But this - malloc does support the following options. -*/ - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - -// --------- Traits -------------- - -#if !defined(AZ_RESTRICTED_PLATFORM) - #if defined(_MSC_VER) - #define TRAIT_HAS_BITSCANFORWARD 1 - #define TRAIT_HAS_BITSCANREVERSE 1 - #endif - #if defined(WIN32) - #define TRAIT_HAS_WIN32_MMAP 1 - #endif - #if defined(WIN32) || defined(WIN64) - #define TRAIT_HAS_GETSYSTEMINFO 1 - #endif - #if defined(_WIN32) - #define TRAIT_USE_QUERYPERFORMANCECOUNTER 1 - #endif -#endif - -/* ------------------------ Mallinfo declarations ------------------------ */ - -#if !NO_MALLINFO -/* - This version of malloc supports the standard SVID/XPG mallinfo - routine that returns a struct containing usage properties and - statistics. It should work on any system that has a - /usr/include/malloc.h defining struct mallinfo. The main - declaration needed is the mallinfo struct that is returned (by-copy) - by mallinfo(). The malloinfo struct contains a bunch of fields that - are not even meaningful in this version of malloc. These fields are - are instead filled by mallinfo() with other numbers that might be of - interest. - - HAVE_USR_INCLUDE_MALLOC_H should be set if you have a - /usr/include/malloc.h file that includes a declaration of struct - mallinfo. If so, it is included; else a compliant version is - declared below. These must be precisely the same for mallinfo() to - work. The original SVID version of this struct, defined on most - systems with mallinfo, declares all fields as ints. But some others - define as unsigned long. If your system defines the fields using a - type of different width than listed here, you MUST #include your - system version and #define HAVE_USR_INCLUDE_MALLOC_H. -*/ - -/* #define HAVE_USR_INCLUDE_MALLOC_H */ - -#ifdef HAVE_USR_INCLUDE_MALLOC_H -#include "/usr/include/malloc.h" -#else /* HAVE_USR_INCLUDE_MALLOC_H */ -#ifndef STRUCT_MALLINFO_DECLARED -#define STRUCT_MALLINFO_DECLARED 1 -struct mallinfo -{ - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; -#endif /* STRUCT_MALLINFO_DECLARED */ -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ -#endif /* NO_MALLINFO */ - -/* - Try to persuade compilers to inline. The most critical functions for - inlining are defined as macros, so these aren't used for them. -*/ - -#ifndef FORCEINLINE - #if defined(__GNUC__) -#define FORCEINLINE __inline __attribute__ ((always_inline)) - #elif defined(_MSC_VER) - #define FORCEINLINE __forceinline - #endif -#endif -#ifndef NOINLINE - #if defined(__GNUC__) - #define NOINLINE __attribute__ ((noinline)) - #elif defined(_MSC_VER) - #define NOINLINE __declspec(noinline) - #else - #define NOINLINE - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#ifndef FORCEINLINE - #define FORCEINLINE inline -#endif -#endif /* __cplusplus */ -#ifndef FORCEINLINE - #define FORCEINLINE -#endif - -typedef void* (* dlmmap_handler)(void*, size_t); -typedef int (* dlmunmap_handler)(void*, void*, size_t); - -#if !ONLY_MSPACES - -/* ------------------- Declarations of public routines ------------------- */ - -#ifndef USE_DL_PREFIX -#define dlcalloc calloc -#define dlfree free -#define dlmalloc malloc -#define dlmemalign memalign -#define dlrealloc realloc -#define dlvalloc valloc -#define dlpvalloc pvalloc -#define dlmallinfo mallinfo -#define dlmallopt mallopt -#define dlmalloc_trim malloc_trim -#define dlmalloc_stats malloc_stats -#define dlmalloc_usable_size malloc_usable_size -#define dlmalloc_footprint malloc_footprint -#define dlmalloc_max_footprint malloc_max_footprint -#define dlindependent_calloc independent_calloc -#define dlindependent_comalloc independent_comalloc -#endif /* USE_DL_PREFIX */ - - -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ -void* dlmalloc(size_t); - -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cause the current program to abort. -*/ -void dlfree(void*); - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -void* dlcalloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ - -void* dlrealloc(void*, size_t); - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -void* dlmemalign(size_t, size_t); - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* dlvalloc(size_t); - -/* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. To workaround the fact that mallopt is specified to use int, - not size_t parameters, the value -1 is specially treated as the - maximum unsigned size_t value. - - SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt. See below for details. Briefly, supported - parameters are as follows (listed defaults are for "typical" - configurations). - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ -int dlmallopt(int, int); - -/* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ -size_t dlmalloc_footprint(void); - -/* - malloc_max_footprint(); - Returns the maximum number of bytes obtained from the system. This - value will be greater than current footprint if deallocated space - has been reclaimed by the system. The peak number of bytes allocated - by malloc, realloc etc., is less than this value. Unlike mallinfo, - this function returns only a precomputed result, so can be called - frequently to monitor memory consumption. Even if locks are - otherwise defined, this function does not use them, so results might - not be up to date. -*/ -size_t dlmalloc_max_footprint(void); - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ -struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ - -/* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use regular calloc and assign pointers into this - space to represent elements. (In this case though, you cannot - independently free elements.) - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -void** dlindependent_calloc(size_t, size_t, void**); - -/* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use a single regular malloc, and assign pointers at - particular offsets in the aggregate space. (In this case though, you - cannot independently free elements.) - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -void** dlindependent_comalloc(size_t, size_t*, void**); - - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* dlpvalloc(size_t); - -/* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ -int dlmalloc_trim(size_t); - -/* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. -*/ -void dlmalloc_stats(void); -void dlmalloc_stats_ret(size_t* sys, size_t* maxSys, size_t* used); - -#endif /* ONLY_MSPACES */ - -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ -size_t dlmalloc_usable_size(void*); - - -#if MSPACES - -/* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ -typedef void* mspace; - -/* - mspace_create_overhead returns the number of bytes used by an mspace for - internal tracking. Can be used with the capacity argument when creating - an mspace to allocate an exact amount of space upfront. -*/ -int mspace_create_overhead(void); - -/* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ -mspace create_mspace(size_t capacity, int locked, void* user, dlmmap_handler mmap, dlmunmap_handler munmap); - -/* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ -size_t destroy_mspace(mspace msp); - -/* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ -mspace create_mspace_with_base(void* base, size_t capacity, int locked); - -/* - mspace_track_large_chunks controls whether requests for large chunks - are allocated in their own untracked mmapped regions, separate from - others in this mspace. By default large chunks are not tracked, - which reduces fragmentation. However, such chunks are not - necessarily released to the system upon destroy_mspace. Enabling - tracking by setting to true may increase fragmentation, but avoids - leakage when relying on destroy_mspace to release all memory - allocated using this space. The function returns the previous - setting. -*/ -int mspace_track_large_chunks(mspace msp, int enable); - - -/* - mspace_malloc behaves as malloc, but operates within - the given space. -*/ -void* mspace_malloc(mspace msp, size_t bytes); - -/* - mspace_free behaves as free, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_free is not actually needed. - free may be called instead of mspace_free because freed chunks from - any space are handled by their originating spaces. -*/ -void mspace_free(mspace msp, void* mem); - -/* - mspace_realloc behaves as realloc, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_realloc is not actually - needed. realloc may be called instead of mspace_realloc because - realloced chunks from any space are handled by their originating - spaces. -*/ -void* mspace_realloc(mspace msp, void* mem, size_t newsize); - -/* - mspace_calloc behaves as calloc, but operates within - the given space. -*/ -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); - -/* - mspace_memalign behaves as memalign, but operates within - the given space. -*/ -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); - -/* - mspace_independent_calloc behaves as independent_calloc, but - operates within the given space. -*/ -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]); - -/* - mspace_independent_comalloc behaves as independent_comalloc, but - operates within the given space. -*/ -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]); - -/* - mspace_footprint() returns the number of bytes obtained from the - system for this space. -*/ -size_t mspace_footprint(mspace msp); - -/* - mspace_max_footprint() returns the peak number of bytes obtained from the - system for this space. -*/ -size_t mspace_max_footprint(mspace msp); - - -#if !NO_MALLINFO -/* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ -struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - -/* - malloc_usable_size(void* p) behaves the same as malloc_usable_size; -*/ -size_t mspace_usable_size(void* mem); - -/* - mspace_malloc_stats behaves as malloc_stats, but reports - properties of the given space. -*/ -void mspace_malloc_stats(mspace msp); - -/* - mspace_trim behaves as malloc_trim, but - operates within the given space. -*/ -int mspace_trim(mspace msp, size_t pad); - -/* - An alias for mallopt. -*/ -int mspace_mallopt(int, int); - -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif /* __cplusplus */ - -/* - ======================================================================== - To make a fully customizable malloc.h header file, cut everything - above this line, put into file malloc.h, edit to suit, and #include it - on the next line, as well as in programs that use this malloc. - ======================================================================== -*/ - -/* #include "malloc.h" */ - -/*------------------------------ internal #includes ---------------------- */ - -#ifdef WIN32 -#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ -#endif /* WIN32 */ - -#include /* for printing in malloc_stats */ - -#ifndef LACKS_ERRNO_H -#include /* for MALLOC_FAILURE_ACTION */ -#endif /* LACKS_ERRNO_H */ -#if FOOTERS || DEBUG -#include /* for magic initialization */ -#endif /* FOOTERS */ -#ifndef LACKS_STDLIB_H -#include /* for abort() */ -#endif /* LACKS_STDLIB_H */ -#ifdef DEBUG -#if ABORT_ON_ASSERT_FAILURE -#undef assert -#define assert(x) if (!(x)) ABORT -#else /* ABORT_ON_ASSERT_FAILURE */ -#include -#endif /* ABORT_ON_ASSERT_FAILURE */ -#else /* DEBUG */ -#ifndef assert -#define assert(x) -#endif -#define DEBUG 0 -#endif /* DEBUG */ -#ifndef LACKS_STRING_H -#include /* for memset etc */ -#endif /* LACKS_STRING_H */ -#if USE_BUILTIN_FFS -#ifndef LACKS_STRINGS_H -#include /* for ffs */ -#endif /* LACKS_STRINGS_H */ -#endif /* USE_BUILTIN_FFS */ -#if HAVE_MMAP -#ifndef LACKS_SYS_MMAN_H -/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */ -#if (defined(linux) && !defined(__USE_GNU)) -#define __USE_GNU 1 -#include /* for mmap */ -#undef __USE_GNU -#else -#include /* for mmap */ -#endif /* linux */ -#endif /* LACKS_SYS_MMAN_H */ -#ifndef LACKS_FCNTL_H -#include -#endif /* LACKS_FCNTL_H */ -#endif /* HAVE_MMAP */ -#ifndef LACKS_UNISTD_H -#include /* for sbrk, sysconf */ -#else /* LACKS_UNISTD_H */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(_WIN32) -extern void* sbrk(ptrdiff_t); -#endif /* FreeBSD etc */ -#endif /* LACKS_UNISTD_H */ - -/* Declarations for locking */ -#if USE_LOCKS -#ifndef WIN32 -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CRYDLMALLOC_C_SECTION_2 -#include AZ_RESTRICTED_FILE(CryDLMalloc_c) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -#include -#endif -#if defined (__SVR4) && defined (__sun) /* solaris */ -#include -#endif /* solaris */ -#else -#ifndef _M_AMD64 -/* These are already defined on AMD64 builds */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -LONG __cdecl _InterlockedCompareExchange(LONG volatile* Dest, LONG Exchange, LONG Comp); -LONG __cdecl _InterlockedExchange(LONG volatile* Target, LONG Value); -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _M_AMD64 */ -#pragma intrinsic (_InterlockedCompareExchange) -#pragma intrinsic (_InterlockedExchange) -#define interlockedcompareexchange _InterlockedCompareExchange -#define interlockedexchange _InterlockedExchange -#endif /* Win32 */ -#endif /* USE_LOCKS */ - -/* Declarations for bit scanning on win32 */ -#if defined(_MSC_VER) && _MSC_VER >= 1300 -#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -unsigned char _BitScanForward(unsigned long* index, unsigned long mask); -unsigned char _BitScanReverse(unsigned long* index, unsigned long mask); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define BitScanForward _BitScanForward -#define BitScanReverse _BitScanReverse -#pragma intrinsic(_BitScanForward) -#pragma intrinsic(_BitScanReverse) -#endif /* BitScanForward */ -#endif /* defined(_MSC_VER) */ - -#ifndef WIN32 -#ifndef malloc_getpagesize -# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ -# ifndef _SC_PAGE_SIZE -# define _SC_PAGE_SIZE _SC_PAGESIZE -# endif -# endif -# ifdef _SC_PAGE_SIZE -# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) -# else -# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) -extern size_t getpagesize(); -# define malloc_getpagesize getpagesize() -# else -# ifdef WIN32 /* use supplied emulation of getpagesize */ -# define malloc_getpagesize getpagesize() -# else -# ifndef LACKS_SYS_PARAM_H -# include -# endif -# ifdef EXEC_PAGESIZE -# define malloc_getpagesize EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define malloc_getpagesize NBPG -# else -# define malloc_getpagesize (NBPG * CLSIZE) -# endif -# else -# ifdef NBPC -# define malloc_getpagesize NBPC -# else -# ifdef PAGESIZE -# define malloc_getpagesize PAGESIZE -# else /* just guess */ -# define malloc_getpagesize ((size_t)4096U) -# endif -# endif -# endif -# endif -# endif -# endif -# endif -#endif -#endif - - - -/* ------------------- size_t and alignment properties -------------------- */ - -/* The byte and bit size of a size_t */ -#define SIZE_T_SIZE (sizeof(size_t)) -#define SIZE_T_BITSIZE (sizeof(size_t) << 3) - -/* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some platforms */ -#define SIZE_T_ZERO ((size_t)0) -#define SIZE_T_ONE ((size_t)1) -#define SIZE_T_TWO ((size_t)2) -#define SIZE_T_FOUR ((size_t)4) -#define TWO_SIZE_T_SIZES (SIZE_T_SIZE << 1) -#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE << 2) -#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES + TWO_SIZE_T_SIZES) -#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) - -/* The bit mask value corresponding to MALLOC_ALIGNMENT */ -#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) - -/* True if address a has acceptable alignment */ -#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) - -/* the number of bytes to offset an address to align it */ -#define align_offset(A) \ - ((((size_t)(A) &CHUNK_ALIGN_MASK) == 0) ? 0 : \ - ((MALLOC_ALIGNMENT - ((size_t)(A) &CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) - -/* -------------------------- MMAP preliminaries ------------------------- */ - -/* - If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and - checks to fail so compiler optimizer can delete code rather than - using so many "#if"s. -*/ - - -/* MORECORE and MMAP must return MFAIL on failure */ -#define MFAIL ((void*)(MAX_SIZE_T)) -#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ - -#if HAVE_MMAP - -#if !TRAIT_HAS_WIN32_MMAP -#define MUNMAP_DEFAULT(a, s) munmap((a), (s)) -#define MMAP_PROT (PROT_READ | PROT_WRITE) -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -#define MAP_ANONYMOUS MAP_ANON -#endif /* MAP_ANON */ -#ifdef MAP_ANONYMOUS -#define MMAP_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS) -#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) -#else /* MAP_ANONYMOUS */ -/* - Nearly all versions of mmap support MAP_ANONYMOUS, so the following - is unlikely to be needed, but is supplied just in case. -*/ -#define MMAP_FLAGS (MAP_PRIVATE) -static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ -#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ - (dev_zero_fd = open("/dev/zero", O_RDWR), \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) -#endif /* MAP_ANONYMOUS */ - -#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) - -#else /* TRAIT_HAS_WIN32_MMAP */ - -/* Win32 MMAP via VirtualAlloc */ -static FORCEINLINE void* win32mmap(size_t size) -{ - void* ptr = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - return (ptr != 0) ? ptr : MFAIL; -} - -/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static FORCEINLINE void* win32direct_mmap(size_t size) -{ - void* ptr = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, - PAGE_READWRITE); - return (ptr != 0) ? ptr : MFAIL; -} - -/* This function supports releasing coalesed segments */ -static FORCEINLINE int win32munmap(void* ptr, size_t size) -{ - MEMORY_BASIC_INFORMATION minfo; - char* cptr = (char*)ptr; - while (size) - { - if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) - { - return -1; - } - if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || - minfo.State != MEM_COMMIT || minfo.RegionSize > size) - { - return -1; - } - if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) - { - return -1; - } - cptr += minfo.RegionSize; - size -= minfo.RegionSize; - } - return 0; -} - -#define MMAP_DEFAULT(s) win32mmap(s) -#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) -#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) -#endif /* TRAIT_HAS_WIN32_MMAP */ -#endif /* HAVE_MMAP */ - -#if HAVE_MREMAP -#ifndef WIN32 -#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) -#endif /* WIN32 */ -#endif /* HAVE_MREMAP */ - - -/** - * Define CALL_MORECORE - */ -#if HAVE_MORECORE - #ifdef MORECORE - #define CALL_MORECORE(S) MORECORE(S) - #else /* MORECORE */ - #define CALL_MORECORE(S) MORECORE_DEFAULT(S) - #endif /* MORECORE */ -#else /* HAVE_MORECORE */ - #define CALL_MORECORE(S) MFAIL -#endif /* HAVE_MORECORE */ - -/** - * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP - */ -#if HAVE_MMAP - #define USE_MMAP_BIT (SIZE_T_ONE) - - #ifdef MMAP - #define CALL_MMAP(s) MMAP(s) - #else /* MMAP */ - #define CALL_MMAP(s) MMAP_DEFAULT(s) - #endif /* MMAP */ - #ifdef MUNMAP - #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) - #else /* MUNMAP */ - #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) - #endif /* MUNMAP */ - #ifdef DIRECT_MMAP - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) - #else /* DIRECT_MMAP */ - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) - #endif /* DIRECT_MMAP */ -#else /* HAVE_MMAP */ - #define USE_MMAP_BIT (SIZE_T_ZERO) - - #define MMAP(s) MFAIL - #define MUNMAP(a, s) (-1) - #define DIRECT_MMAP(s) MFAIL - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) - #define CALL_MMAP(s) MMAP(s) - #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) -#endif /* HAVE_MMAP */ - -/** - * Define CALL_MREMAP - */ -#if HAVE_MMAP && HAVE_MREMAP - #ifdef MREMAP - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) - #else /* MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) - #endif /* MREMAP */ -#else /* HAVE_MMAP && HAVE_MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL -#endif /* HAVE_MMAP && HAVE_MREMAP */ - -/* mstate bit set if continguous morecore disabled or failed */ -#define USE_NONCONTIGUOUS_BIT (4U) - -/* segment bit set in create_mspace_with_base */ -#define EXTERN_BIT (8U) - - -/* --------------------------- Lock preliminaries ------------------------ */ - -/* - When locks are defined, there is one global lock, plus - one per-mspace lock. - - The global lock_ensures that mparams.magic and other unique - mparams values are initialized only once. It also protects - sequences of calls to MORECORE. In many cases sys_alloc requires - two calls, that should not be interleaved with calls by other - threads. This does not protect against direct calls to MORECORE - by other threads not using this lock, so there is still code to - cope the best we can on interference. - - Per-mspace locks surround calls to malloc, free, etc. To enable use - in layered extensions, per-mspace locks are reentrant. - - Because lock-protected regions generally have bounded times, it is - OK to use the supplied simple spinlocks in the custom versions for - x86. Spinlocks are likely to improve performance for lightly - contended applications, but worsen performance under heavy - contention. - - If USE_LOCKS is > 1, the definitions of lock routines here are - bypassed, in which case you will need to define the type MLOCK_T, - and at least INITIAL_LOCK, ACQUIRE_LOCK, RELEASE_LOCK and possibly - TRY_LOCK (which is not used in this malloc, but commonly needed in - extensions.) You must also declare a - static MLOCK_T malloc_global_mutex = { initialization values };. - -*/ - -#if USE_LOCKS == 1 - -#if USE_SPIN_LOCKS && SPIN_LOCKS_AVAILABLE -#ifndef WIN32 - -/* Custom pthread-style spin locks on x86 and x64 for gcc */ -struct pthread_mlock_t -{ - volatile unsigned int l; - unsigned int c; - pthread_t threadid; -}; -#define MLOCK_T struct pthread_mlock_t -#define CURRENT_THREAD pthread_self() -#define INITIAL_LOCK(sl) ((sl)->threadid = 0, (sl)->l = (sl)->c = 0, 0) -#define ACQUIRE_LOCK(sl) pthread_acquire_lock(sl) -#define RELEASE_LOCK(sl) pthread_release_lock(sl) -#define TRY_LOCK(sl) pthread_try_lock(sl) -#define SPINS_PER_YIELD 63 - -static MLOCK_T malloc_global_mutex = { 0, 0, 0}; - -static FORCEINLINE int pthread_acquire_lock (MLOCK_T* sl) -{ - int spins = 0; - volatile unsigned int* lp = &sl->l; - for (;; ) - { - if (*lp != 0) - { - if (sl->threadid == CURRENT_THREAD) - { - ++sl->c; - return 0; - } - } - else - { - /* place args to cmpxchgl in locals to evade oddities in some gccs */ - int cmp = 0; - int val = 1; - int ret; - __asm__ __volatile__ ("lock; cmpxchgl %1, %2" - : "=a" (ret) - : "r" (val), "m" (*(lp)), "0" (cmp) - : "memory", "cc"); - if (!ret) - { - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 0; - } - } - if ((++spins & SPINS_PER_YIELD) == 0) - { -#if defined (__SVR4) && defined (__sun) /* solaris */ - thr_yield(); -#else -#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) - sched_yield(); -#else /* no-op yield on unknown systems */ - ; -#endif /* __linux__ || __FreeBSD__ || __APPLE__ */ -#endif /* solaris */ - } - } -} - -static FORCEINLINE void pthread_release_lock (MLOCK_T* sl) -{ - volatile unsigned int* lp = &sl->l; - assert(*lp != 0); - assert(sl->threadid == CURRENT_THREAD); - if (--sl->c == 0) - { - sl->threadid = 0; - int prev = 0; - int ret; - __asm__ __volatile__ ("lock; xchgl %0, %1" - : "=r" (ret) - : "m" (*(lp)), "0" (prev) - : "memory"); - } -} - -static FORCEINLINE int pthread_try_lock (MLOCK_T* sl) -{ - volatile unsigned int* lp = &sl->l; - if (*lp != 0) - { - if (sl->threadid == CURRENT_THREAD) - { - ++sl->c; - return 1; - } - } - else - { - int cmp = 0; - int val = 1; - int ret; - __asm__ __volatile__ ("lock; cmpxchgl %1, %2" - : "=a" (ret) - : "r" (val), "m" (*(lp)), "0" (cmp) - : "memory", "cc"); - if (!ret) - { - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 1; - } - } - return 0; -} - - -#else /* WIN32 */ -/* Custom win32-style spin locks on x86 and x64 for MSC */ -struct win32_mlock_t -{ - volatile long l; - unsigned int c; - long threadid; -}; - -#define MLOCK_T struct win32_mlock_t -#define CURRENT_THREAD GetCurrentThreadId() -#define INITIAL_LOCK(sl) ((sl)->threadid = 0, (sl)->l = (sl)->c = 0, 0) -#define ACQUIRE_LOCK(sl) win32_acquire_lock(sl) -#define RELEASE_LOCK(sl) win32_release_lock(sl) -#define TRY_LOCK(sl) win32_try_lock(sl) -#define SPINS_PER_YIELD 63 - -static MLOCK_T malloc_global_mutex = { 0, 0, 0}; - -static FORCEINLINE int win32_acquire_lock (MLOCK_T* sl) -{ - int spins = 0; - for (;; ) - { - if (sl->l != 0) - { - if (sl->threadid == CURRENT_THREAD) - { - ++sl->c; - return 0; - } - } - else - { - if (!interlockedexchange(&sl->l, 1)) - { - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 0; - } - } - if ((++spins & SPINS_PER_YIELD) == 0) - { - SleepEx(0, FALSE); - } - } -} - -static FORCEINLINE void win32_release_lock (MLOCK_T* sl) -{ - assert(sl->threadid == CURRENT_THREAD); - assert(sl->l != 0); - if (--sl->c == 0) - { - sl->threadid = 0; - interlockedexchange (&sl->l, 0); - } -} - -static FORCEINLINE int win32_try_lock (MLOCK_T* sl) -{ - if (sl->l != 0) - { - if (sl->threadid == CURRENT_THREAD) - { - ++sl->c; - return 1; - } - } - else - { - if (!interlockedexchange(&sl->l, 1)) - { - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 1; - } - } - return 0; -} - -#endif /* WIN32 */ -#else /* USE_SPIN_LOCKS */ - -#ifndef WIN32 -/* pthreads-based locks */ - -#define MLOCK_T pthread_mutex_t -#define CURRENT_THREAD pthread_self() -#define INITIAL_LOCK(sl) pthread_init_lock(sl) -#define ACQUIRE_LOCK(sl) pthread_mutex_lock(sl) -#define RELEASE_LOCK(sl) pthread_mutex_unlock(sl) -#define TRY_LOCK(sl) (!pthread_mutex_trylock(sl)) - -static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* Cope with old-style linux recursive lock initialization by adding */ -/* skipped internal declaration from pthread.h */ -#ifdef linux -#ifndef PTHREAD_MUTEX_RECURSIVE -extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t * __attr, - int __kind)); -#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP -#define pthread_mutexattr_settype(x, y) pthread_mutexattr_setkind_np(x, y) -#endif -#endif - -static int pthread_init_lock (MLOCK_T* sl) -{ - pthread_mutexattr_t attr; - if (pthread_mutexattr_init(&attr)) - { - return 1; - } - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) - { - return 1; - } - if (pthread_mutex_init(sl, &attr)) - { - return 1; - } - if (pthread_mutexattr_destroy(&attr)) - { - return 1; - } - return 0; -} - -#else /* WIN32 */ -/* Win32 critical sections */ -#define MLOCK_T CRITICAL_SECTION -#define CURRENT_THREAD GetCurrentThreadId() -#define INITIAL_LOCK(s) (!InitializeCriticalSectionAndSpinCount((s), 0x80000000 | 4000)) -#define ACQUIRE_LOCK(s) (EnterCriticalSection(sl), 0) -#define RELEASE_LOCK(s) LeaveCriticalSection(sl) -#define TRY_LOCK(s) TryEnterCriticalSection(sl) -#define NEED_GLOBAL_LOCK_INIT - -static MLOCK_T malloc_global_mutex; -static volatile long malloc_global_mutex_status; - -/* Use spin loop to initialize global lock */ -static void init_malloc_global_mutex() -{ - for (;; ) - { - long stat = malloc_global_mutex_status; - if (stat > 0) - { - return; - } - /* transition to < 0 while initializing, then to > 0) */ - if (stat == 0 && - interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) - { - InitializeCriticalSection(&malloc_global_mutex); - interlockedexchange(&malloc_global_mutex_status, 1); - return; - } - SleepEx(0, FALSE); - } -} - -#endif /* WIN32 */ -#endif /* USE_SPIN_LOCKS */ -#endif /* USE_LOCKS == 1 */ - -/* ----------------------- User-defined locks ------------------------ */ - -#if USE_LOCKS > 1 -/* Define your own lock implementation here */ -/* #define INITIAL_LOCK(sl) ... */ -/* #define ACQUIRE_LOCK(sl) ... */ -/* #define RELEASE_LOCK(sl) ... */ -/* #define TRY_LOCK(sl) ... */ -/* static MLOCK_T malloc_global_mutex = ... */ -#endif /* USE_LOCKS > 1 */ - -/* ----------------------- Lock-based state ------------------------ */ - -#if USE_LOCKS -#define USE_LOCK_BIT (2U) -#else /* USE_LOCKS */ -#define USE_LOCK_BIT (0U) -#define INITIAL_LOCK(l) -#endif /* USE_LOCKS */ - -#if USE_LOCKS -#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK -#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); -#endif -#ifndef RELEASE_MALLOC_GLOBAL_LOCK -#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); -#endif -#else /* USE_LOCKS */ -#define ACQUIRE_MALLOC_GLOBAL_LOCK() -#define RELEASE_MALLOC_GLOBAL_LOCK() -#endif /* USE_LOCKS */ - - -/* ----------------------- Chunk representations ------------------------ */ - -/* - (The following includes lightly edited explanations by Colin Plumb.) - - The malloc_chunk declaration below is misleading (but accurate and - necessary). It declares a "view" into memory allowing access to - necessary fields at known offsets from a given base. - - Chunks of memory are maintained using a `boundary tag' method as - originally described by Knuth. (See the paper by Paul Wilson - ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such - techniques.) Sizes of free chunks are stored both in the front of - each chunk and at the end. This makes consolidating fragmented - chunks into bigger chunks fast. The head fields also hold bits - representing whether chunks are free or in use. - - Here are some pictures to make it clearer. They are "exploded" to - show that the state of a chunk can be thought of as extending from - the high 31 bits of the head field of its header through the - prev_foot and PINUSE_BIT bit of the following chunk header. - - A chunk that's in use looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk (if P = 0) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 1| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - +- -+ - | | - +- -+ - | : - +- size - sizeof(size_t) available payload bytes -+ - : | - chunk-> +- -+ - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| - | Size of next chunk (may or may not be in use) | +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - And if it's free, it looks like this: - - chunk-> +- -+ - | User payload (must be in use, or we would have merged!) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 0| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Next pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Prev pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- size - sizeof(struct chunk) unused bytes -+ - : | - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| - | Size of next chunk (must be in use, or we would have merged)| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- User payload -+ - : | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |0| - +-+ - Note that since we always merge adjacent free chunks, the chunks - adjacent to a free chunk must be in use. - - Given a pointer to a chunk (which can be derived trivially from the - payload pointer) we can, in O(1) time, find out whether the adjacent - chunks are free, and if so, unlink them from the lists that they - are on and merge them with the current chunk. - - Chunks always begin on even word boundaries, so the mem portion - (which is returned to the user) is also on an even word boundary, and - thus at least double-word aligned. - - The P (PINUSE_BIT) bit, stored in the unused low-order bit of the - chunk size (which is always a multiple of two words), is an in-use - bit for the *previous* chunk. If that bit is *clear*, then the - word before the current chunk size contains the previous chunk - size, and can be used to find the front of the previous chunk. - The very first chunk allocated always has this bit set, preventing - access to non-existent (or non-owned) memory. If pinuse is set for - any given chunk, then you CANNOT determine the size of the - previous chunk, and might even get a memory addressing fault when - trying to do so. - - The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of - the chunk size redundantly records whether the current chunk is - inuse (unless the chunk is mmapped). This redundancy enables usage - checks within free and realloc, and reduces indirection when freeing - and consolidating chunks. - - Each freshly allocated chunk must have both cinuse and pinuse set. - That is, each allocated chunk borders either a previously allocated - and still in-use chunk, or the base of its memory arena. This is - ensured by making all allocations from the the `lowest' part of any - found chunk. Further, no free chunk physically borders another one, - so each free chunk is known to be preceded and followed by either - inuse chunks or the ends of memory. - - Note that the `foot' of the current chunk is actually represented - as the prev_foot of the NEXT chunk. This makes it easier to - deal with alignments etc but can be very confusing when trying - to extend or adapt this code. - - The exceptions to all this are - - 1. The special chunk `top' is the top-most available chunk (i.e., - the one bordering the end of available memory). It is treated - specially. Top is never included in any bin, is used only if - no other chunk is available, and is released back to the - system if it is very large (see M_TRIM_THRESHOLD). In effect, - the top chunk is treated as larger (and thus less well - fitting) than any other available chunk. The top chunk - doesn't update its trailing size field since there is no next - contiguous chunk that would have to index off it. However, - space is still allocated for it (TOP_FOOT_SIZE) to enable - separation or merging when space is extended. - - 3. Chunks allocated via mmap, have both cinuse and pinuse bits - cleared in their head fields. Because they are allocated - one-by-one, each must carry its own prev_foot field, which is - also used to hold the offset this chunk has within its mmapped - region, which is needed to preserve alignment. Each mmapped - chunk is trailed by the first two fields of a fake next-chunk - for sake of usage checks. - -*/ - -struct malloc_chunk -{ - size_t prev_foot;/* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct malloc_chunk* fd; /* double links -- used only if free. */ - struct malloc_chunk* bk; -}; - -typedef struct malloc_chunk mchunk; -typedef struct malloc_chunk* mchunkptr; -typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ -typedef unsigned int binmap_t; /* Described below */ -typedef unsigned int flag_t; /* The type of various bit flag sets */ - -/* ------------------- Chunks sizes and alignments ----------------------- */ - -#define MCHUNK_SIZE (sizeof(mchunk)) - -#if FOOTERS -#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -#else /* FOOTERS */ -#define CHUNK_OVERHEAD (SIZE_T_SIZE) -#endif /* FOOTERS */ - -/* MMapped chunks need a second word of overhead ... */ -#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -/* ... and additional padding for fake next-chunk at foot */ -#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) - -/* The smallest size we can malloc is an aligned minimal chunk */ -#define MIN_CHUNK_SIZE \ - ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) -#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) -/* chunk associated with aligned address A */ -#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) - -/* Bounds on request (not chunk) sizes. */ -#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) -#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) - -/* pad request bytes into a usable size */ -#define pad_request(req) \ - (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* pad request, checking for minimum (but not maximum) */ -#define request2size(req) \ - (((req) < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(req)) - - -/* ------------------ Operations on head and foot fields ----------------- */ - -/* - The head field of a chunk is or'ed with PINUSE_BIT when previous - adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in - use, unless mmapped, in which case both bits are cleared. - - FLAG4_BIT is not used by this malloc, but might be useful in extensions. -*/ - -#define PINUSE_BIT (SIZE_T_ONE) -#define CINUSE_BIT (SIZE_T_TWO) -#define FLAG4_BIT (SIZE_T_FOUR) -#define INUSE_BITS (PINUSE_BIT | CINUSE_BIT) -#define FLAG_BITS (PINUSE_BIT | CINUSE_BIT | FLAG4_BIT) - -/* Head value for fenceposts */ -#define FENCEPOST_HEAD (INUSE_BITS | SIZE_T_SIZE) - -/* extraction of fields from head words */ -#define cinuse(p) ((p)->head & CINUSE_BIT) -#define pinuse(p) ((p)->head & PINUSE_BIT) -#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) -#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) - -#define chunksize(p) ((p)->head & ~(FLAG_BITS)) - -#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) - -/* Treat space at ptr +/- offset as a chunk */ -#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) -#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) - -/* Ptr to next or previous physical malloc_chunk. */ -#define next_chunk(p) ((mchunkptr)(((char*)(p)) + ((p)->head & ~FLAG_BITS))) -#define prev_chunk(p) ((mchunkptr)(((char*)(p)) - ((p)->prev_foot))) - -/* extract next chunk's pinuse bit */ -#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) - -/* Get/set size at footer */ -#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) -#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) - -/* Set size, pinuse bit, and foot */ -#define set_size_and_pinuse_of_free_chunk(p, s) \ - ((p)->head = (s | PINUSE_BIT), set_foot(p, s)) - -/* Set size, pinuse bit, foot, and clear next pinuse */ -#define set_free_with_pinuse(p, s, n) \ - (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) - -/* Get the internal overhead associated with chunk p */ -#define overhead_for(p) \ - (is_mmapped(p) ? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) - -/* Return true if malloced space is not necessarily cleared */ -#if MMAP_CLEARS -#define calloc_must_clear(p) (!is_mmapped(p)) -#else /* MMAP_CLEARS */ -#define calloc_must_clear(p) (1) -#endif /* MMAP_CLEARS */ - -/* ---------------------- Overlaid data structures ----------------------- */ - -/* - When chunks are not in use, they are treated as nodes of either - lists or trees. - - "Small" chunks are stored in circular doubly-linked lists, and look - like this: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space (may be 0 bytes long) . - . . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Larger chunks are kept in a form of bitwise digital trees (aka - tries) keyed on chunksizes. Because malloc_tree_chunks are only for - free chunks greater than 256 bytes, their size doesn't impose any - constraints on user chunk sizes. Each node looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to left child (child[0]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to right child (child[1]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to parent | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | bin index of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Each tree holding treenodes is a tree of unique chunk sizes. Chunks - of the same size are arranged in a circularly-linked list, with only - the oldest chunk (the next to be used, in our FIFO ordering) - actually in the tree. (Tree members are distinguished by a non-null - parent pointer.) If a chunk with the same size an an existing node - is inserted, it is linked off the existing node using pointers that - work in the same way as fd/bk pointers of small chunks. - - Each tree contains a power of 2 sized range of chunk sizes (the - smallest is 0x100 <= x < 0x180), which is is divided in half at each - tree level, with the chunks in the smaller half of the range (0x100 - <= x < 0x140 for the top nose) in the left subtree and the larger - half (0x140 <= x < 0x180) in the right subtree. This is, of course, - done by inspecting individual bits. - - Using these rules, each node's left subtree contains all smaller - sizes than its right subtree. However, the node at the root of each - subtree has no particular ordering relationship to either. (The - dividing line between the subtree sizes is based on trie relation.) - If we remove the last chunk of a given size from the interior of the - tree, we need to replace it with a leaf node. The tree ordering - rules permit a node to be replaced by any leaf below it. - - The smallest chunk in a tree (a common operation in a best-fit - allocator) can be found by walking a path to the leftmost leaf in - the tree. Unlike a usual binary tree, where we follow left child - pointers until we reach a null, here we follow the right child - pointer any time the left one is null, until we reach a leaf with - both child pointers null. The smallest chunk in the tree will be - somewhere along that path. - - The worst case number of steps to add, find, or remove a node is - bounded by the number of bits differentiating chunks within - bins. Under current bin calculations, this ranges from 6 up to 21 - (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case - is of course much better. -*/ - -struct malloc_tree_chunk -{ - /* The first four fields must be compatible with malloc_chunk */ - size_t prev_foot; - size_t head; - struct malloc_tree_chunk* fd; - struct malloc_tree_chunk* bk; - - struct malloc_tree_chunk* child[2]; - struct malloc_tree_chunk* parent; - bindex_t index; -}; - -typedef struct malloc_tree_chunk tchunk; -typedef struct malloc_tree_chunk* tchunkptr; -typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ - -/* A little helper macro for trees */ -#define leftmost_child(t) ((t)->child[0] != 0 ? (t)->child[0] : (t)->child[1]) - -/* ----------------------------- Segments -------------------------------- */ - -/* - Each malloc space may include non-contiguous segments, held in a - list headed by an embedded malloc_segment record representing the - top-most space. Segments also include flags holding properties of - the space. Large chunks that are directly allocated by mmap are not - included in this list. They are instead independently created and - destroyed without otherwise keeping track of them. - - Segment management mainly comes into play for spaces allocated by - MMAP. Any call to MMAP might or might not return memory that is - adjacent to an existing segment. MORECORE normally contiguously - extends the current space, so this space is almost always adjacent, - which is simpler and faster to deal with. (This is why MORECORE is - used preferentially to MMAP when both are available -- see - sys_alloc.) When allocating using MMAP, we don't use any of the - hinting mechanisms (inconsistently) supported in various - implementations of unix mmap, or distinguish reserving from - committing memory. Instead, we just ask for space, and exploit - contiguity when we get it. It is probably possible to do - better than this on some systems, but no general scheme seems - to be significantly better. - - Management entails a simpler variant of the consolidation scheme - used for chunks to reduce fragmentation -- new adjacent memory is - normally prepended or appended to an existing segment. However, - there are limitations compared to chunk consolidation that mostly - reflect the fact that segment processing is relatively infrequent - (occurring only when getting memory from system) and that we - don't expect to have huge numbers of segments: - - * Segments are not indexed, so traversal requires linear scans. (It - would be possible to index these, but is not worth the extra - overhead and complexity for most programs on most platforms.) - * New segments are only appended to old ones when holding top-most - memory; if they cannot be prepended to others, they are held in - different segments. - - Except for the top-most segment of an mstate, each segment record - is kept at the tail of its segment. Segments are added by pushing - segment records onto the list headed by &mstate.seg for the - containing mstate. - - Segment flags control allocation/merge/deallocation policies: - * If EXTERN_BIT set, then we did not allocate this segment, - and so should not try to deallocate or merge with others. - (This currently holds only for the initial segment passed - into create_mspace_with_base.) - * If USE_MMAP_BIT set, the segment may be merged with - other surrounding mmapped segments and trimmed/de-allocated - using munmap. - * If neither bit is set, then the segment was obtained using - MORECORE so can be merged with surrounding MORECORE'd segments - and deallocated/trimmed using MORECORE with negative arguments. -*/ - -struct malloc_segment -{ - char* base; /* base address */ - size_t size; /* allocated size */ - struct malloc_segment* next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ -}; - -#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) -#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) - -typedef struct malloc_segment msegment; -typedef struct malloc_segment* msegmentptr; - -/* ---------------------------- malloc_state ----------------------------- */ - -/* - A malloc_state holds all of the bookkeeping for a space. - The main fields are: - - Top - The topmost chunk of the currently active segment. Its size is - cached in topsize. The actual size of topmost space is - topsize+TOP_FOOT_SIZE, which includes space reserved for adding - fenceposts and segment records if necessary when getting more - space from the system. The size at which to autotrim top is - cached from mparams in trim_check, except that it is disabled if - an autotrim fails. - - Designated victim (dv) - This is the preferred chunk for servicing small requests that - don't have exact fits. It is normally the chunk split off most - recently to service another small request. Its size is cached in - dvsize. The link fields of this chunk are not maintained since it - is not kept in a bin. - - SmallBins - An array of bin headers for free chunks. These bins hold chunks - with sizes less than MIN_LARGE_SIZE bytes. Each bin contains - chunks of all the same size, spaced 8 bytes apart. To simplify - use in double-linked lists, each bin header acts as a malloc_chunk - pointing to the real first node, if it exists (else pointing to - itself). This avoids special-casing for headers. But to avoid - waste, we allocate only the fd/bk pointers of bins, and then use - repositioning tricks to treat these as the fields of a chunk. - - TreeBins - Treebins are pointers to the roots of trees holding a range of - sizes. There are 2 equally spaced treebins for each power of two - from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything - larger. - - Bin maps - There is one bit map for small bins ("smallmap") and one for - treebins ("treemap). Each bin sets its bit when non-empty, and - clears the bit when empty. Bit operations are then used to avoid - bin-by-bin searching -- nearly all "search" is done without ever - looking at bins that won't be selected. The bit maps - conservatively use 32 bits per map word, even if on 64bit system. - For a good description of some of the bit-based techniques used - here, see Henry S. Warren Jr's book "Hacker's Delight" (and - supplement at http://hackersdelight.org/). Many of these are - intended to reduce the branchiness of paths through malloc etc, as - well as to reduce the number of memory locations read or written. - - Segments - A list of segments headed by an embedded malloc_segment record - representing the initial space. - - Address check support - The least_addr field is the least address ever obtained from - MORECORE or MMAP. Attempted frees and reallocs of any address less - than this are trapped (unless INSECURE is defined). - - Magic tag - A cross-check field that should always hold same value as mparams.magic. - - Flags - Bits recording whether to use MMAP, locks, or contiguous MORECORE - - Statistics - Each space keeps track of current and maximum system memory - obtained via MORECORE or MMAP. - - Trim support - Fields holding the amount of unused topmost memory that should trigger - timming, and a counter to force periodic scanning to release unused - non-topmost segments. - - Locking - If USE_LOCKS is defined, the "mutex" lock is acquired and released - around every public call using this mspace. - - Extension support - A void* pointer and a size_t field that can be used to help implement - extensions to this malloc. -*/ - -/* Bin types, widths and sizes */ -#define NSMALLBINS (32U) -#define NTREEBINS (32U) -#define SMALLBIN_SHIFT (3U) -#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) -#define TREEBIN_SHIFT (8U) -#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) -#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) -#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) - -struct malloc_state -{ - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char* least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t release_checks; - size_t magic; - mchunkptr smallbins[(NSMALLBINS + 1) * 2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - flag_t mflags; -#if USE_LOCKS - MLOCK_T mutex; /* locate lock among fields that rarely change */ -#endif /* USE_LOCKS */ - msegment seg; - void* extp; /* Unused but available for extensions */ - size_t exts; - dlmmap_handler mmap; - dlmunmap_handler munmap; -}; - -typedef struct malloc_state* mstate; - -/* ------------- Global malloc_state and malloc_params ------------------- */ - -/* - malloc_params holds global properties, including those that can be - dynamically set using mallopt. There is a single instance, mparams, - initialized in init_mparams. Note that the non-zeroness of "magic" - also serves as an initialization flag. -*/ - -struct malloc_params -{ - volatile size_t magic; - size_t page_size; - size_t granularity; - size_t mmap_threshold; - size_t trim_threshold; - flag_t default_mflags; -}; - -static struct malloc_params mparams; - -/* Ensure mparams initialized */ -#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams()) - -#if !ONLY_MSPACES - -/* The global malloc_state used for all non-"mspace" calls */ -static struct malloc_state _gm_; -#define gm (&_gm_) -#define is_global(M) ((M) == &_gm_) - -#endif /* !ONLY_MSPACES */ - -#define is_initialized(M) ((M)->top != 0) - -/* -------------------------- system alloc setup ------------------------- */ - -/* Operations on mflags */ - -#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) -#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) -#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) - -#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) -#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) -#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) - -#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) -#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) - -#define set_lock(M, L) \ - ((M)->mflags = (L) ? \ - ((M)->mflags | USE_LOCK_BIT) : \ - ((M)->mflags & ~USE_LOCK_BIT)) - -/* page-align a size */ -#define page_align(S) \ - (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) - -/* granularity-align a size */ -#define granularity_align(S) \ - (((S) + (mparams.granularity - SIZE_T_ONE)) \ - & ~(mparams.granularity - SIZE_T_ONE)) - - -/* For mmap, use granularity alignment on windows, else page-align */ -#ifdef WIN32 -#define mmap_align(S) granularity_align(S) -#else -#define mmap_align(S) page_align(S) -#endif - -/* For sys_alloc, enough padding to ensure can malloc request on success */ -#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) - -#define is_page_aligned(S) \ - (((size_t)(S) &(mparams.page_size - SIZE_T_ONE)) == 0) -#define is_granularity_aligned(S) \ - (((size_t)(S) &(mparams.granularity - SIZE_T_ONE)) == 0) - -/* True if segment S holds address A */ -#define segment_holds(S, A) \ - ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) - -/* Return segment holding given address */ -static msegmentptr segment_holding(mstate m, char* addr) -{ - msegmentptr sp = &m->seg; - for (;; ) - { - if (addr >= sp->base && addr < sp->base + sp->size) - { - return sp; - } - if ((sp = sp->next) == 0) - { - return 0; - } - } -} - -/* Return true if segment contains a segment link */ -static int has_segment_link(mstate m, msegmentptr ss) -{ - msegmentptr sp = &m->seg; - for (;; ) - { - if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) - { - return 1; - } - if ((sp = sp->next) == 0) - { - return 0; - } - } -} - -#ifndef MORECORE_CANNOT_TRIM -#define should_trim(M, s) ((s) > (M)->trim_check) -#else /* MORECORE_CANNOT_TRIM */ -#define should_trim(M, s) (0) -#endif /* MORECORE_CANNOT_TRIM */ - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE \ - (align_offset(chunk2mem(0)) + pad_request(sizeof(struct malloc_segment)) + MIN_CHUNK_SIZE) - - -/* ------------------------------- Hooks -------------------------------- */ - -/* - PREACTION should be defined to return 0 on success, and nonzero on - failure. If you are not using locking, you can redefine these to do - anything you like. -*/ - -#if USE_LOCKS - -#define PREACTION(M) ((use_lock(M)) ? ACQUIRE_LOCK(&(M)->mutex) : 0) -#define POSTACTION(M) { if (use_lock(M)) {RELEASE_LOCK(&(M)->mutex); } \ -} -#else /* USE_LOCKS */ - -#ifndef PREACTION -#define PREACTION(M) (0) -#endif /* PREACTION */ - -#ifndef POSTACTION -#define POSTACTION(M) -#endif /* POSTACTION */ - -#endif /* USE_LOCKS */ - -/* - CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. - USAGE_ERROR_ACTION is triggered on detected bad frees and - reallocs. The argument p is an address that might have triggered the - fault. It is ignored by the two predefined actions, but might be - useful in custom actions that try to help diagnose errors. -*/ - -#if PROCEED_ON_ERROR - -/* A count of the number of corruption errors causing resets */ -int malloc_corruption_error_count; - -/* default corruption action */ -static void reset_on_error(mstate m); - -#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) -#define USAGE_ERROR_ACTION(m, p) - -#else /* PROCEED_ON_ERROR */ - -#ifndef CORRUPTION_ERROR_ACTION -#define CORRUPTION_ERROR_ACTION(m) ABORT -#endif /* CORRUPTION_ERROR_ACTION */ - -#ifndef USAGE_ERROR_ACTION -#define USAGE_ERROR_ACTION(m, p) ABORT -#endif /* USAGE_ERROR_ACTION */ - -#endif /* PROCEED_ON_ERROR */ - -/* -------------------------- Debugging setup ---------------------------- */ - -#if !DEBUG - -#define check_free_chunk(M, P) -#define check_inuse_chunk(M, P) -#define check_malloced_chunk(M, P, N) -#define check_mmapped_chunk(M, P) -#define check_malloc_state(M) -#define check_top_chunk(M, P) - -#else /* DEBUG */ -#define check_free_chunk(M, P) do_check_free_chunk(M, P) -#define check_inuse_chunk(M, P) do_check_inuse_chunk(M, P) -#define check_top_chunk(M, P) do_check_top_chunk(M, P) -#define check_malloced_chunk(M, P, N) do_check_malloced_chunk(M, P, N) -#define check_mmapped_chunk(M, P) do_check_mmapped_chunk(M, P) -#define check_malloc_state(M) do_check_malloc_state(M) - -static void do_check_any_chunk(mstate m, mchunkptr p); -static void do_check_top_chunk(mstate m, mchunkptr p); -static void do_check_mmapped_chunk(mstate m, mchunkptr p); -static void do_check_inuse_chunk(mstate m, mchunkptr p); -static void do_check_free_chunk(mstate m, mchunkptr p); -static void do_check_malloced_chunk(mstate m, void* mem, size_t s); -static void do_check_tree(mstate m, tchunkptr t); -static void do_check_treebin(mstate m, bindex_t i); -static void do_check_smallbin(mstate m, bindex_t i); -static void do_check_malloc_state(mstate m); -static int bin_find(mstate m, mchunkptr x); -static size_t traverse_and_check(mstate m); -#endif /* DEBUG */ - -/* ---------------------------- Indexing Bins ---------------------------- */ - -#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) -#define small_index(s) ((s) >> SMALLBIN_SHIFT) -#define small_index2size(i) ((i) << SMALLBIN_SHIFT) -#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) - -/* addressing by index. See above about smallbin repositioning */ -#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i) << 1]))) -#define treebin_at(M, i) (&((M)->treebins[i])) - -/* assign tree index for size S to variable I. Use x86 asm if possible */ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_tree_index(S, I) \ - { \ - unsigned int X = S >> TREEBIN_SHIFT; \ - if (X == 0) { \ - I = 0; } \ - else if (X > 0xFFFF) { \ - I = NTREEBINS - 1; } \ - else { \ - unsigned int K; \ - __asm__("bsrl\t%1, %0\n\t" : "=r" (K) : "g" (X)); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ - } \ - } - -#elif defined (__INTEL_COMPILER) -#define compute_tree_index(S, I) \ - { \ - size_t X = S >> TREEBIN_SHIFT; \ - if (X == 0) { \ - I = 0; } \ - else if (X > 0xFFFF) { \ - I = NTREEBINS - 1; } \ - else { \ - unsigned int K = _bit_scan_reverse (X); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ - } \ - } - -#elif TRAIT_HAS_BITSCANREVERSE -#define compute_tree_index(S, I) \ - { \ - size_t X = S >> TREEBIN_SHIFT; \ - if (X == 0) { \ - I = 0; } \ - else if (X > 0xFFFF) { \ - I = NTREEBINS - 1; } \ - else { \ - unsigned int K; \ - _BitScanReverse((DWORD*) &K, X); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ - } \ - } - -#else /* GNUC */ -#define compute_tree_index(S, I) \ - { \ - size_t X = S >> TREEBIN_SHIFT; \ - if (X == 0) { \ - I = 0; } \ - else if (X > 0xFFFF) { \ - I = NTREEBINS - 1; } \ - else { \ - unsigned int Y = (unsigned int)X; \ - unsigned int N = ((Y - 0x100) >> 16) & 8; \ - unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4; \ - N += K; \ - N += K = (((Y <<= K) - 0x4000) >> 16) & 2; \ - K = 14 - N + ((Y <<= K) >> 15); \ - I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1)); \ - } \ - } -#endif /* GNUC */ - -/* Bit representing maximum resolved size in a treebin at i */ -#define bit_for_tree_index(i) \ - (i == NTREEBINS - 1) ? (SIZE_T_BITSIZE - 1) : (((i) >> 1) + TREEBIN_SHIFT - 2) - -/* Shift placing maximum resolved bit in a treebin at i as sign bit */ -#define leftshift_for_tree_index(i) \ - ((i == NTREEBINS - 1) ? 0 : \ - ((SIZE_T_BITSIZE - SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) - -/* The size of the smallest chunk held in bin with index i */ -#define minsize_for_tree_index(i) \ - ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ - (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) - - -/* ------------------------ Operations on bin maps ----------------------- */ - -/* bit corresponding to given index */ -#define idx2bit(i) ((binmap_t)(1) << (i)) - -/* Mark/Clear bits with given index */ -#define mark_smallmap(M, i) ((M)->smallmap |= idx2bit(i)) -#define clear_smallmap(M, i) ((M)->smallmap &= ~idx2bit(i)) -#define smallmap_is_marked(M, i) ((M)->smallmap & idx2bit(i)) - -#define mark_treemap(M, i) ((M)->treemap |= idx2bit(i)) -#define clear_treemap(M, i) ((M)->treemap &= ~idx2bit(i)) -#define treemap_is_marked(M, i) ((M)->treemap & idx2bit(i)) - -/* isolate the least set bit of a bitmap */ -#define least_bit(x) ((x) & - (x)) - -/* mask with all bits to left of least bit of x on */ -#define left_bits(x) ((x << 1) | -(x << 1)) - -/* mask with all bits to left of or equal to least bit of x on */ -#define same_or_left_bits(x) ((x) | -(x)) - -/* index corresponding to given bit. Use x86 asm if possible */ - -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_bit2idx(X, I) \ - { \ - unsigned int J; \ - __asm__("bsfl\t%1, %0\n\t" : "=r" (J) : "g" (X)); \ - I = (bindex_t)J; \ - } - -#elif defined (__INTEL_COMPILER) -#define compute_bit2idx(X, I) \ - { \ - unsigned int J; \ - J = _bit_scan_forward (X); \ - I = (bindex_t)J; \ - } - -#elif TRAIT_HAS_BITSCANFORWARD -#define compute_bit2idx(X, I) \ - { \ - unsigned int J; \ - _BitScanForward((DWORD*) &J, X); \ - I = (bindex_t)J; \ - } - -#elif USE_BUILTIN_FFS -#define compute_bit2idx(X, I) I = ffs(X) - 1 - -#else -#define compute_bit2idx(X, I) \ - { \ - unsigned int Y = X - 1; \ - unsigned int K = Y >> (16 - 4) & 16; \ - unsigned int N = K; Y >>= K; \ - N += K = Y >> (8 - 3) & 8; Y >>= K; \ - N += K = Y >> (4 - 2) & 4; Y >>= K; \ - N += K = Y >> (2 - 1) & 2; Y >>= K; \ - N += K = Y >> (1 - 0) & 1; Y >>= K; \ - I = (bindex_t)(N + Y); \ - } -#endif /* GNUC */ - - -/* ----------------------- Runtime Check Support ------------------------- */ - -/* - For security, the main invariant is that malloc/free/etc never - writes to a static address other than malloc_state, unless static - malloc_state itself has been corrupted, which cannot occur via - malloc (because of these checks). In essence this means that we - believe all pointers, sizes, maps etc held in malloc_state, but - check all of those linked or offsetted from other embedded data - structures. These checks are interspersed with main code in a way - that tends to minimize their run-time cost. - - When FOOTERS is defined, in addition to range checking, we also - verify footer fields of inuse chunks, which can be used guarantee - that the mstate controlling malloc/free is intact. This is a - streamlined version of the approach described by William Robertson - et al in "Run-time Detection of Heap-based Overflows" LISA'03 - http://www.usenix.org/events/lisa03/tech/robertson.html The footer - of an inuse chunk holds the xor of its mstate and a random seed, - that is checked upon calls to free() and realloc(). This is - (probablistically) unguessable from outside the program, but can be - computed by any code successfully malloc'ing any chunk, so does not - itself provide protection against code that has already broken - security through some other means. Unlike Robertson et al, we - always dynamically check addresses of all offset chunks (previous, - next, etc). This turns out to be cheaper than relying on hashes. -*/ - -#if !INSECURE -/* Check if address a is at least as high as any from MORECORE or MMAP */ -#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) -/* Check if address of next chunk n is higher than base chunk p */ -#define ok_next(p, n) ((char*)(p) < (char*)(n)) -/* Check if p has inuse status */ -#define ok_inuse(p) is_inuse(p) -/* Check if p has its pinuse bit on */ -#define ok_pinuse(p) pinuse(p) - -#else /* !INSECURE */ -#define ok_address(M, a) (1) -#define ok_next(b, n) (1) -#define ok_inuse(p) (1) -#define ok_pinuse(p) (1) -#endif /* !INSECURE */ - -#if (FOOTERS && !INSECURE) -/* Check if (alleged) mstate m has expected magic field */ -#define ok_magic(M) ((M)->magic == mparams.magic) -#else /* (FOOTERS && !INSECURE) */ -#define ok_magic(M) (1) -#endif /* (FOOTERS && !INSECURE) */ - - -/* In gcc, use __builtin_expect to minimize impact of checks */ -#if !INSECURE -#if defined(__GNUC__) && __GNUC__ >= 3 -#define RTCHECK(e) __builtin_expect(e, 1) -#else /* GNUC */ -#define RTCHECK(e) (e) -#endif /* GNUC */ -#else /* !INSECURE */ -#define RTCHECK(e) (1) -#endif /* !INSECURE */ - -/* macros to set up inuse chunks with or without footers */ - -#if !FOOTERS - -#define mark_inuse_foot(M, p, s) - -/* Macros for setting head/foot of non-mmapped chunks */ - -/* Set cinuse bit and pinuse bit of next chunk */ -#define set_inuse(M, p, s) \ - ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ -#define set_inuse_and_pinuse(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set size, cinuse and pinuse bit of this chunk */ -#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT)) - -#else /* FOOTERS */ - -/* Set foot of inuse chunk to be xor of mstate and seed */ -#define mark_inuse_foot(M, p, s) \ - (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) - -#define get_mstate_for(p) \ - ((mstate)(((mchunkptr)((char*)(p) + \ - (chunksize(p))))->prev_foot ^ mparams.magic)) - -#define set_inuse(M, p, s) \ - ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#define set_inuse_and_pinuse(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#endif /* !FOOTERS */ - -/* ---------------------------- setting mparams -------------------------- */ - -/* Initialize mparams */ -int init_mparams(void) -{ -#ifdef NEED_GLOBAL_LOCK_INIT - if (malloc_global_mutex_status <= 0) - { - init_malloc_global_mutex(); - } -#endif - - ACQUIRE_MALLOC_GLOBAL_LOCK(); - if (mparams.magic == 0) - { - size_t magic; - size_t psize; - size_t gsize; - -#if TRAIT_HAS_GETSYSTEMINFO - { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - psize = system_info.dwPageSize; - gsize = ((DEFAULT_GRANULARITY != 0) ? - DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); - } -#else - psize = malloc_getpagesize; - gsize = ((DEFAULT_GRANULARITY != 0) ? DEFAULT_GRANULARITY : psize); -#endif //#if TRAIT_HAS_GETSYSTEMINFO - - /* Sanity-check configuration: - size_t must be unsigned and as wide as pointer type. - ints must be at least 4 bytes. - alignment must be at least 8. - Alignment, min chunk size, and page size must all be powers of 2. - */ - if ((sizeof(size_t) != sizeof(char*)) || - (MAX_SIZE_T < MIN_CHUNK_SIZE) || - (sizeof(int) < 4) || - (MALLOC_ALIGNMENT < (size_t)8U) || - ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT - SIZE_T_ONE)) != 0) || - ((MCHUNK_SIZE & (MCHUNK_SIZE - SIZE_T_ONE)) != 0) || - ((gsize & (gsize - SIZE_T_ONE)) != 0) || - ((psize & (psize - SIZE_T_ONE)) != 0)) - { - ABORT; - } - - mparams.granularity = gsize; - mparams.page_size = psize; - mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; - mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; -#if MORECORE_CONTIGUOUS - mparams.default_mflags = USE_LOCK_BIT | USE_MMAP_BIT; -#else /* MORECORE_CONTIGUOUS */ - mparams.default_mflags = USE_LOCK_BIT | USE_MMAP_BIT | USE_NONCONTIGUOUS_BIT; -#endif /* MORECORE_CONTIGUOUS */ - -#if !ONLY_MSPACES - /* Set up lock for main malloc area */ - gm->mflags = mparams.default_mflags; - INITIAL_LOCK(&gm->mutex); -#endif - - { -#if USE_DEV_RANDOM - int fd; - unsigned char buf[sizeof(size_t)]; - /* Try to use /dev/urandom, else fall back on using time */ - if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && - read(fd, buf, sizeof(buf)) == sizeof(buf)) - { - magic = *((size_t*) buf); - close(fd); - } - else -#endif /* USE_DEV_RANDOM */ -#if TRAIT_USE_QUERYPERFORMANCECOUNTER - { - // GetTickCount not available on Metro style apps - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - magic = (size_t)(li.QuadPart ^ (size_t)0x55555555U); - } -#elif defined(WIN32) - magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); -#else - magic = (size_t)(time(0) ^ (size_t)0x55555555U); -#endif - magic |= (size_t)8U; /* ensure nonzero */ - magic &= ~(size_t)7U; /* improve chances of fault for bad values */ - mparams.magic = magic; - } - } - - RELEASE_MALLOC_GLOBAL_LOCK(); - return 1; -} - -/* support for mallopt */ -static int change_mparam(int param_number, int value) -{ - size_t val; - ensure_initialization(); - val = (value == -1) ? MAX_SIZE_T : (size_t)value; - switch (param_number) - { - case M_TRIM_THRESHOLD: - mparams.trim_threshold = val; - return 1; - case M_GRANULARITY: - if (val >= mparams.page_size && ((val & (val - 1)) == 0)) - { - mparams.granularity = val; - return 1; - } - else - { - return 0; - } - case M_MMAP_THRESHOLD: - mparams.mmap_threshold = val; - return 1; - default: - return 0; - } -} - -#if DEBUG -/* ------------------------- Debugging Support --------------------------- */ - -/* Check properties of any chunk, whether free, inuse, mmapped etc */ -static void do_check_any_chunk(mstate m, mchunkptr p) -{ - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); -} - -/* Check properties of top chunk */ -static void do_check_top_chunk(mstate m, mchunkptr p) -{ - msegmentptr sp = segment_holding(m, (char*)p); - size_t sz = p->head & ~INUSE_BITS;/* third-lowest bit can be set! */ - assert(sp != 0); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(sz == m->topsize); - assert(sz > 0); - assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); - assert(pinuse(p)); - assert(!pinuse(chunk_plus_offset(p, sz))); -} - -/* Check properties of (inuse) mmapped chunks */ -static void do_check_mmapped_chunk(mstate m, mchunkptr p) -{ - size_t sz = chunksize(p); - size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); - assert(is_mmapped(p)); - assert(use_mmap(m)); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(!is_small(sz)); - assert((len & (mparams.page_size - SIZE_T_ONE)) == 0); - assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); - assert(chunk_plus_offset(p, sz + SIZE_T_SIZE)->head == 0); -} - -/* Check properties of inuse chunks */ -static void do_check_inuse_chunk(mstate m, mchunkptr p) -{ - do_check_any_chunk(m, p); - assert(is_inuse(p)); - assert(next_pinuse(p)); - /* If not pinuse and not mmapped, previous chunk has OK offset */ - assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); - if (is_mmapped(p)) - { - do_check_mmapped_chunk(m, p); - } -} - -/* Check properties of free chunks */ -static void do_check_free_chunk(mstate m, mchunkptr p) -{ - size_t sz = chunksize(p); - mchunkptr next = chunk_plus_offset(p, sz); - do_check_any_chunk(m, p); - assert(!is_inuse(p)); - assert(!next_pinuse(p)); - assert (!is_mmapped(p)); - if (p != m->dv && p != m->top) - { - if (sz >= MIN_CHUNK_SIZE) - { - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(is_aligned(chunk2mem(p))); - assert(next->prev_foot == sz); - assert(pinuse(p)); - assert (next == m->top || is_inuse(next)); - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } - else /* markers are always of size SIZE_T_SIZE */ - { - assert(sz == SIZE_T_SIZE); - } - } -} - -/* Check properties of malloced chunks at the point they are malloced */ -static void do_check_malloced_chunk(mstate m, void* mem, size_t s) -{ - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); - size_t sz = p->head & ~INUSE_BITS; - do_check_inuse_chunk(m, p); - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(sz >= MIN_CHUNK_SIZE); - assert(sz >= s); - /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ - assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); - } -} - -/* Check a tree and its subtrees. */ -static void do_check_tree(mstate m, tchunkptr t) -{ - tchunkptr head = 0; - tchunkptr u = t; - bindex_t tindex = t->index; - size_t tsize = chunksize(t); - bindex_t idx; - compute_tree_index(tsize, idx); - assert(tindex == idx); - assert(tsize >= MIN_LARGE_SIZE); - assert(tsize >= minsize_for_tree_index(idx)); - assert((idx == NTREEBINS - 1) || (tsize < minsize_for_tree_index((idx + 1)))); - - do /* traverse through chain of same-sized nodes */ - { - do_check_any_chunk(m, ((mchunkptr)u)); - assert(u->index == tindex); - assert(chunksize(u) == tsize); - assert(!is_inuse(u)); - assert(!next_pinuse(u)); - assert(u->fd->bk == u); - assert(u->bk->fd == u); - if (u->parent == 0) - { - assert(u->child[0] == 0); - assert(u->child[1] == 0); - } - else - { - assert(head == 0); /* only one node on chain has parent */ - head = u; - assert(u->parent != u); - assert (u->parent->child[0] == u || - u->parent->child[1] == u || - *((tbinptr*)(u->parent)) == u); - if (u->child[0] != 0) - { - assert(u->child[0]->parent == u); - assert(u->child[0] != u); - do_check_tree(m, u->child[0]); - } - if (u->child[1] != 0) - { - assert(u->child[1]->parent == u); - assert(u->child[1] != u); - do_check_tree(m, u->child[1]); - } - if (u->child[0] != 0 && u->child[1] != 0) - { - assert(chunksize(u->child[0]) < chunksize(u->child[1])); - } - } - u = u->fd; - } while (u != t); - assert(head != 0); -} - -/* Check all the chunks in a treebin. */ -static void do_check_treebin(mstate m, bindex_t i) -{ - tbinptr* tb = treebin_at(m, i); - tchunkptr t = *tb; - int empty = (m->treemap & (1U << i)) == 0; - if (t == 0) - { - assert(empty); - } - if (!empty) - { - do_check_tree(m, t); - } -} - -/* Check all the chunks in a smallbin. */ -static void do_check_smallbin(mstate m, bindex_t i) -{ - sbinptr b = smallbin_at(m, i); - mchunkptr p = b->bk; - unsigned int empty = (m->smallmap & (1U << i)) == 0; - if (p == b) - { - assert(empty); - } - if (!empty) - { - for (; p != b; p = p->bk) - { - size_t size = chunksize(p); - mchunkptr q; - /* each chunk claims to be free */ - do_check_free_chunk(m, p); - /* chunk belongs in bin */ - assert(small_index(size) == i); - assert(p->bk == b || chunksize(p->bk) == chunksize(p)); - /* chunk is followed by an inuse chunk */ - q = next_chunk(p); - if (q->head != FENCEPOST_HEAD) - { - do_check_inuse_chunk(m, q); - } - } - } -} - -/* Find x in a bin. Used in other check functions. */ -static int bin_find(mstate m, mchunkptr x) -{ - size_t size = chunksize(x); - if (is_small(size)) - { - bindex_t sidx = small_index(size); - sbinptr b = smallbin_at(m, sidx); - if (smallmap_is_marked(m, sidx)) - { - mchunkptr p = b; - do - { - if (p == x) - { - return 1; - } - } while ((p = p->fd) != b); - } - } - else - { - bindex_t tidx; - compute_tree_index(size, tidx); - if (treemap_is_marked(m, tidx)) - { - tchunkptr t = *treebin_at(m, tidx); - size_t sizebits = size << leftshift_for_tree_index(tidx); - while (t != 0 && chunksize(t) != size) - { - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - sizebits <<= 1; - } - if (t != 0) - { - tchunkptr u = t; - do - { - if (u == (tchunkptr)x) - { - return 1; - } - } while ((u = u->fd) != t); - } - } - } - return 0; -} - -/* Traverse each chunk and check it; return total */ -static size_t traverse_and_check(mstate m) -{ - size_t sum = 0; - if (is_initialized(m)) - { - msegmentptr s = &m->seg; - sum += m->topsize + TOP_FOOT_SIZE; - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - mchunkptr lastq = 0; - assert(pinuse(q)); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) - { - sum += chunksize(q); - if (is_inuse(q)) - { - assert(!bin_find(m, q)); - do_check_inuse_chunk(m, q); - } - else - { - assert(q == m->dv || bin_find(m, q)); - assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ - do_check_free_chunk(m, q); - } - lastq = q; - q = next_chunk(q); - } - s = s->next; - } - } - return sum; -} - -/* Check all properties of malloc_state. */ -static void do_check_malloc_state(mstate m) -{ - bindex_t i; - size_t total; - /* check bins */ - for (i = 0; i < NSMALLBINS; ++i) - { - do_check_smallbin(m, i); - } - for (i = 0; i < NTREEBINS; ++i) - { - do_check_treebin(m, i); - } - - if (m->dvsize != 0) /* check dv chunk */ - { - do_check_any_chunk(m, m->dv); - assert(m->dvsize == chunksize(m->dv)); - assert(m->dvsize >= MIN_CHUNK_SIZE); - assert(bin_find(m, m->dv) == 0); - } - - if (m->top != 0) /* check top chunk */ - { - do_check_top_chunk(m, m->top); - /*assert(m->topsize == chunksize(m->top)); redundant */ - assert(m->topsize > 0); - assert(bin_find(m, m->top) == 0); - } - - total = traverse_and_check(m); - assert(total <= m->footprint); - assert(m->footprint <= m->max_footprint); -} -#endif /* DEBUG */ - -/* ----------------------------- statistics ------------------------------ */ - -#if !NO_MALLINFO -static struct mallinfo internal_mallinfo(mstate m) -{ - struct mallinfo nm = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - ensure_initialization(); - if (!PREACTION(m)) - { - check_malloc_state(m); - if (is_initialized(m)) - { - size_t nfree = SIZE_T_ONE; /* top always free */ - size_t mfree = m->topsize + TOP_FOOT_SIZE; - size_t sum = mfree; - msegmentptr s = &m->seg; - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) - { - size_t sz = chunksize(q); - sum += sz; - if (!is_inuse(q)) - { - mfree += sz; - ++nfree; - } - q = next_chunk(q); - } - s = s->next; - } - - nm.arena = sum; - nm.ordblks = nfree; - nm.hblkhd = m->footprint - sum; - nm.usmblks = m->max_footprint; - nm.uordblks = m->footprint - mfree; - nm.fordblks = mfree; - nm.keepcost = m->topsize; - } - - POSTACTION(m); - } - return nm; -} -#endif /* !NO_MALLINFO */ - -static void internal_malloc_stats(mstate m) -{ - ensure_initialization(); - if (!PREACTION(m)) - { - size_t maxfp = 0; - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if (is_initialized(m)) - { - msegmentptr s = &m->seg; - maxfp = m->max_footprint; - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); - - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) - { - if (!is_inuse(q)) - { - used -= chunksize(q); - } - q = next_chunk(q); - } - s = s->next; - } - } - - fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); - fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); - fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); - - POSTACTION(m); - } -} - -static void internal_malloc_stats_ret(mstate m, size_t* sysOut, size_t* maxSysOut, size_t* usedOut) -{ - ensure_initialization(); - if (!PREACTION(m)) - { - size_t maxfp = 0; - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if (is_initialized(m)) - { - msegmentptr s = &m->seg; - maxfp = m->max_footprint; - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); - - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) - { - if (!is_inuse(q)) - { - used -= chunksize(q); - } - q = next_chunk(q); - } - s = s->next; - } - } - - (*sysOut) = fp; - (*maxSysOut) = maxfp; - (*usedOut) = used; - - POSTACTION(m); - } -} - -/* ----------------------- Operations on smallbins ----------------------- */ - -/* - Various forms of linking and unlinking are defined as macros. Even - the ones for trees, which are very long but have very short typical - paths. This is ugly but reduces reliance on inlining support of - compilers. -*/ - -/* Link a free chunk into a smallbin */ -#define insert_small_chunk(M, P, S) { \ - bindex_t I = small_index(S); \ - mchunkptr B = smallbin_at(M, I); \ - mchunkptr F = B; \ - assert(S >= MIN_CHUNK_SIZE); \ - if (!smallmap_is_marked(M, I)) { \ - mark_smallmap(M, I); } \ - else if (RTCHECK(ok_address(M, B->fd))) { \ - F = B->fd; } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - B->fd = P; \ - F->bk = P; \ - P->fd = F; \ - P->bk = B; \ -} - -/* Unlink a chunk from a smallbin */ -#define unlink_small_chunk(M, P, S) { \ - mchunkptr F = P->fd; \ - mchunkptr B = P->bk; \ - bindex_t I = small_index(S); \ - assert(P != B); \ - assert(P != F); \ - assert(chunksize(P) == small_index2size(I)); \ - if (F == B) { \ - clear_smallmap(M, I); } \ - else if (RTCHECK((F == smallbin_at(M, I) || ok_address(M, F)) && \ - (B == smallbin_at(M, I) || ok_address(M, B)))) { \ - F->bk = B; \ - B->fd = F; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ -} - -/* Unlink the first chunk from a smallbin */ -#define unlink_first_small_chunk(M, B, P, I) { \ - mchunkptr F = P->fd; \ - assert(P != B); \ - assert(P != F); \ - assert(chunksize(P) == small_index2size(I)); \ - if (B == F) { \ - clear_smallmap(M, I); } \ - else if (RTCHECK(ok_address(M, F))) { \ - B->fd = F; \ - F->bk = B; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ -} - - - -/* Replace dv node, binning the old one */ -/* Used only when dvsize known to be small */ -#define replace_dv(M, P, S) { \ - size_t DVS = M->dvsize; \ - if (DVS != 0) { \ - mchunkptr DV = M->dv; \ - assert(is_small(DVS)); \ - insert_small_chunk(M, DV, DVS); \ - } \ - M->dvsize = S; \ - M->dv = P; \ -} - -/* ------------------------- Operations on trees ------------------------- */ - -/* Insert chunk into tree */ -#define insert_large_chunk(M, X, S) { \ - tbinptr* H; \ - bindex_t I; \ - compute_tree_index(S, I); \ - H = treebin_at(M, I); \ - X->index = I; \ - X->child[0] = X->child[1] = 0; \ - if (!treemap_is_marked(M, I)) { \ - mark_treemap(M, I); \ - * H = X; \ - X->parent = (tchunkptr)H; \ - X->fd = X->bk = X; \ - } \ - else { \ - tchunkptr T = * H; \ - size_t K = S << leftshift_for_tree_index(I); \ - for (;; ) { \ - if (chunksize(T) != S) { \ - tchunkptr* C = & (T->child[(K >> (SIZE_T_BITSIZE - SIZE_T_ONE))& 1]); \ - K <<= 1; \ - if (* C != 0) { \ - T = * C; } \ - else if (RTCHECK(ok_address(M, C))) { \ - * C = X; \ - X->parent = T; \ - X->fd = X->bk = X; \ - break; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - break; \ - } \ - } \ - else { \ - tchunkptr F = T->fd; \ - if (RTCHECK(ok_address(M, T) && ok_address(M, F))) { \ - T->fd = F->bk = X; \ - X->fd = F; \ - X->bk = T; \ - X->parent = 0; \ - break; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - break; \ - } \ - } \ - } \ - } \ -} - -/* - Unlink steps: - - 1. If x is a chained node, unlink it from its same-sized fd/bk links - and choose its bk node as its replacement. - 2. If x was the last node of its size, but not a leaf node, it must - be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent - of x. We could use any other leaf, but this is easy to locate and - tends to counteract removal of leftmosts elsewhere, and so keeps - paths shorter than minimally guaranteed. This doesn't loop much - because on average a node in a tree is near the bottom. - 3. If x is the base of a chain (i.e., has parent links) relink - x's parent and children to x's replacement (or null if none). -*/ - -#define unlink_large_chunk(M, X) { \ - tchunkptr XP = X->parent; \ - tchunkptr R; \ - if (X->bk != X) { \ - tchunkptr F = X->fd; \ - R = X->bk; \ - if (RTCHECK(ok_address(M, F))) { \ - F->bk = R; \ - R->fd = F; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } \ - else { \ - tchunkptr* RP; \ - if (((R = *(RP = & (X->child[1]))) != 0) || \ - ((R = *(RP = & (X->child[0]))) != 0)) { \ - tchunkptr* CP; \ - while ((*(CP = & (R->child[1])) != 0) || \ - (*(CP = & (R->child[0])) != 0)) { \ - R = *(RP = CP); \ - } \ - if (RTCHECK(ok_address(M, RP))) { \ - * RP = 0; } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } \ - } \ - if (XP != 0) { \ - tbinptr* H = treebin_at(M, X->index); \ - if (X == * H) { \ - if ((* H = R) == 0) { \ - clear_treemap(M, X->index); } \ - } \ - else if (RTCHECK(ok_address(M, XP))) { \ - if (XP->child[0] == X) { \ - XP->child[0] = R; } \ - else{ \ - XP->child[1] = R; } \ - } \ - else{ \ - CORRUPTION_ERROR_ACTION(M); } \ - if (R != 0) { \ - if (RTCHECK(ok_address(M, R))) { \ - tchunkptr C0, C1; \ - R->parent = XP; \ - if ((C0 = X->child[0]) != 0) { \ - if (RTCHECK(ok_address(M, C0))) { \ - R->child[0] = C0; \ - C0->parent = R; \ - } \ - else{ \ - CORRUPTION_ERROR_ACTION(M); } \ - } \ - if ((C1 = X->child[1]) != 0) { \ - if (RTCHECK(ok_address(M, C1))) { \ - R->child[1] = C1; \ - C1->parent = R; \ - } \ - else{ \ - CORRUPTION_ERROR_ACTION(M); } \ - } \ - } \ - else{ \ - CORRUPTION_ERROR_ACTION(M); } \ - } \ - } \ -} - -/* Relays to large vs small bin operations */ - -#define insert_chunk(M, P, S) \ - if (is_small(S)) { insert_small_chunk(M, P, S) } \ - else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } - -#define unlink_chunk(M, P, S) \ - if (is_small(S)) { unlink_small_chunk(M, P, S) } \ - else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } - - -/* Relays to internal calls to malloc/free from realloc, memalign etc */ - -#if ONLY_MSPACES -#define internal_malloc(m, b) mspace_malloc(m, b) -#define internal_free(m, mem) mspace_free(m, mem); -#else /* ONLY_MSPACES */ -#if MSPACES -#define internal_malloc(m, b) \ - (m == gm) ? dlmalloc(b) : mspace_malloc(m, b) -#define internal_free(m, mem) \ - if (m == gm) { dlfree(mem); } else{ mspace_free(m, mem); } -#else /* MSPACES */ -#define internal_malloc(m, b) dlmalloc(b) -#define internal_free(m, mem) dlfree(mem) -#endif /* MSPACES */ -#endif /* ONLY_MSPACES */ - -/* ----------------------- Direct-mmapping chunks ----------------------- */ - -/* - Directly mmapped chunks are set up with an offset to the start of - the mmapped region stored in the prev_foot field of the chunk. This - allows reconstruction of the required argument to MUNMAP when freed, - and also allows adjustment of the returned chunk to meet alignment - requirements (especially in memalign). -*/ - -/* Malloc using mmap */ -static void* mmap_alloc(mstate m, size_t nb) -{ - size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - if (mmsize > nb) /* Check for wrap around 0 */ - { - char* mm = (char*)((*m->mmap)(m->extp, mmsize)); - if (mm != CMFAIL) - { - size_t offset = align_offset(chunk2mem(mm)); - size_t psize = mmsize - offset - MMAP_FOOT_PAD; - mchunkptr p = (mchunkptr)(mm + offset); - p->prev_foot = offset; - p->head = psize; - mark_inuse_foot(m, p, psize); - chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(p, psize + SIZE_T_SIZE)->head = 0; - - if (m->least_addr == 0 || mm < m->least_addr) - { - m->least_addr = mm; - } - if ((m->footprint += mmsize) > m->max_footprint) - { - m->max_footprint = m->footprint; - } - assert(is_aligned(chunk2mem(p))); - check_mmapped_chunk(m, p); - return chunk2mem(p); - } - } - return 0; -} - -/* Realloc using mmap */ -static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) -{ - size_t oldsize = chunksize(oldp); - if (is_small(nb)) /* Can't shrink mmap regions below small size */ - { - return 0; - } - /* Keep old chunk if big enough but not too big */ - if (oldsize >= nb + SIZE_T_SIZE && - (oldsize - nb) <= (mparams.granularity << 1)) - { - return oldp; - } - else - { - size_t offset = oldp->prev_foot; - size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; - size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - char* cp = (char*)CALL_MREMAP((char*)oldp - offset, - oldmmsize, newmmsize, 1); - if (cp != CMFAIL) - { - mchunkptr newp = (mchunkptr)(cp + offset); - size_t psize = newmmsize - offset - MMAP_FOOT_PAD; - newp->head = psize; - mark_inuse_foot(m, newp, psize); - chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(newp, psize + SIZE_T_SIZE)->head = 0; - - if (cp < m->least_addr) - { - m->least_addr = cp; - } - if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) - { - m->max_footprint = m->footprint; - } - check_mmapped_chunk(m, newp); - return newp; - } - } - return 0; -} - -/* -------------------------- mspace management -------------------------- */ - -/* Initialize top chunk and its size */ -static void init_top(mstate m, mchunkptr p, size_t psize) -{ - /* Ensure alignment */ - size_t offset = align_offset(chunk2mem(p)); - p = (mchunkptr)((char*)p + offset); - psize -= offset; - - m->top = p; - m->topsize = psize; - p->head = psize | PINUSE_BIT; - /* set size of fake trailing chunk holding overhead space only once */ - chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; - m->trim_check = mparams.trim_threshold; /* reset on each update */ -} - -/* Initialize bins for a new mstate that is otherwise zeroed out */ -static void init_bins(mstate m) -{ - /* Establish circular links for smallbins */ - bindex_t i; - for (i = 0; i < NSMALLBINS; ++i) - { - sbinptr bin = smallbin_at(m, i); - bin->fd = bin->bk = bin; - } -} - -#if PROCEED_ON_ERROR - -/* default corruption action */ -static void reset_on_error(mstate m) -{ - int i; - ++malloc_corruption_error_count; - /* Reinitialize fields to forget about all memory */ - m->smallbins = m->treebins = 0; - m->dvsize = m->topsize = 0; - m->seg.base = 0; - m->seg.size = 0; - m->seg.next = 0; - m->top = m->dv = 0; - for (i = 0; i < NTREEBINS; ++i) - { - *treebin_at(m, i) = 0; - } - init_bins(m); -} -#endif /* PROCEED_ON_ERROR */ - -/* Allocate chunk and prepend remainder with chunk in successor base. */ -static void* prepend_alloc(mstate m, char* newbase, char* oldbase, - size_t nb) -{ - mchunkptr p = align_as_chunk(newbase); - mchunkptr oldfirst = align_as_chunk(oldbase); - size_t psize = (char*)oldfirst - (char*)p; - mchunkptr q = chunk_plus_offset(p, nb); - size_t qsize = psize - nb; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - - assert((char*)oldfirst > (char*)q); - assert(pinuse(oldfirst)); - assert(qsize >= MIN_CHUNK_SIZE); - - /* consolidate remainder with first chunk of old base */ - if (oldfirst == m->top) - { - size_t tsize = m->topsize += qsize; - m->top = q; - q->head = tsize | PINUSE_BIT; - check_top_chunk(m, q); - } - else if (oldfirst == m->dv) - { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } - else - { - if (!is_inuse(oldfirst)) - { - size_t nsize = chunksize(oldfirst); - unlink_chunk(m, oldfirst, nsize); - oldfirst = chunk_plus_offset(oldfirst, nsize); - qsize += nsize; - } - set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); - check_free_chunk(m, q); - } - - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); -} - -/* Add a segment to hold a new noncontiguous region */ -static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) -{ - /* Determine locations and sizes of segment, fenceposts, old top */ - char* old_top = (char*)m->top; - msegmentptr oldsp = segment_holding(m, old_top); - char* old_end = oldsp->base + oldsp->size; - size_t ssize = pad_request(sizeof(struct malloc_segment)); - char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - size_t offset = align_offset(chunk2mem(rawsp)); - char* asp = rawsp + offset; - char* csp = (asp < (old_top + MIN_CHUNK_SIZE)) ? old_top : asp; - mchunkptr sp = (mchunkptr)csp; - msegmentptr ss = (msegmentptr)(chunk2mem(sp)); - mchunkptr tnext = chunk_plus_offset(sp, ssize); - mchunkptr p = tnext; - int nfences = 0; - - /* reset top to new space */ - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - - /* Set up segment record */ - assert(is_aligned(ss)); - set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); - *ss = m->seg; /* Push current record */ - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmapped; - m->seg.next = ss; - - /* Insert trailing fenceposts */ - for (;; ) - { - mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); - p->head = FENCEPOST_HEAD; - ++nfences; - if ((char*)(&(nextp->head)) < old_end) - { - p = nextp; - } - else - { - break; - } - } - assert(nfences >= 2); - - /* Insert the rest of old top into a bin as an ordinary free chunk */ - if (csp != old_top) - { - mchunkptr q = (mchunkptr)old_top; - size_t psize = csp - old_top; - mchunkptr tn = chunk_plus_offset(q, psize); - set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); - } - - check_top_chunk(m, m->top); -} - -/* -------------------------- System allocation -------------------------- */ - -/* Get memory from system using MORECORE or MMAP */ -static void* sys_alloc(mstate m, size_t nb) -{ - char* tbase = CMFAIL; - size_t tsize = 0; - flag_t mmap_flag = 0; - - ensure_initialization(); - - /* Directly map large chunks, but only if already initialized */ - if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) - { - void* mem = mmap_alloc(m, nb); - if (mem != 0) - { - return mem; - } - } - - /* - Try getting memory in any of three ways (in most-preferred to - least-preferred order): - 1. A call to MORECORE that can normally contiguously extend memory. - (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or - or main space is mmapped or a previous contiguous call failed) - 2. A call to MMAP new space (disabled if not HAVE_MMAP). - Note that under the default settings, if MORECORE is unable to - fulfill a request, and HAVE_MMAP is true, then mmap is - used as a noncontiguous system allocator. This is a useful backup - strategy for systems with holes in address spaces -- in this case - sbrk cannot contiguously expand the heap, but mmap may be able to - find space. - 3. A call to MORECORE that cannot usually contiguously extend memory. - (disabled if not HAVE_MORECORE) - - In all cases, we need to request enough bytes from system to ensure - we can malloc nb bytes upon success, so pad with enough space for - top_foot, plus alignment-pad to make sure we don't lose bytes if - not on boundary, and round this up to a granularity unit. - */ - - if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) - { - char* br = CMFAIL; - msegmentptr ss = (m->top == 0) ? 0 : segment_holding(m, (char*)m->top); - size_t asize = 0; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - - if (ss == 0) /* First time through or recovery */ - { - char* base = (char*)CALL_MORECORE(0); - if (base != CMFAIL) - { - asize = granularity_align(nb + SYS_ALLOC_PADDING); - /* Adjust to end on a page boundary */ - if (!is_page_aligned(base)) - { - asize += (page_align((size_t)base) - (size_t)base); - } - /* Can't call MORECORE if size is negative when treated as signed */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == base) - { - tbase = base; - tsize = asize; - } - } - } - else - { - /* Subtract out existing available top space from MORECORE request. */ - asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); - /* Use mem here only if it did continuously extend old space */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == ss->base + ss->size) - { - tbase = br; - tsize = asize; - } - } - - if (tbase == CMFAIL) /* Cope with partial failure */ - { - if (br != CMFAIL) /* Try to use/extend the space we did get */ - { - if (asize < HALF_MAX_SIZE_T && - asize < nb + SYS_ALLOC_PADDING) - { - size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize); - if (esize < HALF_MAX_SIZE_T) - { - char* end = (char*)CALL_MORECORE(esize); - if (end != CMFAIL) - { - asize += esize; - } - else /* Can't use; try to release */ - { - (void) CALL_MORECORE(-asize); - br = CMFAIL; - } - } - } - } - if (br != CMFAIL) /* Use the space we did get */ - { - tbase = br; - tsize = asize; - } - else - { - disable_contiguous(m); /* Don't try contiguous path in the future */ - } - } - - RELEASE_MALLOC_GLOBAL_LOCK(); - } - - if (HAVE_MMAP && tbase == CMFAIL) /* Try MMAP */ - { - size_t rsize = granularity_align(nb + SYS_ALLOC_PADDING); - if (rsize > nb) /* Fail if wraps around zero */ - { - char* mp = (char*)((*m->mmap)(m->extp, rsize)); - if (mp != CMFAIL) - { - tbase = mp; - tsize = rsize; - mmap_flag = USE_MMAP_BIT; - } - } - } - - if (HAVE_MORECORE && tbase == CMFAIL) /* Try noncontiguous MORECORE */ - { - size_t asize = granularity_align(nb + SYS_ALLOC_PADDING); - if (asize < HALF_MAX_SIZE_T) - { - char* br = CMFAIL; - char* end = CMFAIL; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - br = (char*)(CALL_MORECORE(asize)); - end = (char*)(CALL_MORECORE(0)); - RELEASE_MALLOC_GLOBAL_LOCK(); - if (br != CMFAIL && end != CMFAIL && br < end) - { - size_t ssize = end - br; - if (ssize > nb + TOP_FOOT_SIZE) - { - tbase = br; - tsize = ssize; - } - } - } - } - - if (tbase != CMFAIL) - { - if ((m->footprint += tsize) > m->max_footprint) - { - m->max_footprint = m->footprint; - } - - if (!is_initialized(m)) /* first-time initialization */ - { - if (m->least_addr == 0 || tbase < m->least_addr) - { - m->least_addr = tbase; - } - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmap_flag; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - init_bins(m); -#if !ONLY_MSPACES - if (is_global(m)) - { - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - } - else -#endif - { - /* Offset top by embedded malloc_state */ - mchunkptr mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); - } - } - - else - { - /* Try to merge with an existing segment */ - msegmentptr sp = &m->seg; - /* Only consider most recent segment if traversal suppressed */ - while (sp != 0 && tbase != sp->base + sp->size) - { - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - } - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & USE_MMAP_BIT) == mmap_flag && - segment_holds(sp, m->top)) /* append */ - { - sp->size += tsize; - init_top(m, m->top, m->topsize + tsize); - } - else - { - if (tbase < m->least_addr) - { - m->least_addr = tbase; - } - sp = &m->seg; - while (sp != 0 && sp->base != tbase + tsize) - { - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - } - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & USE_MMAP_BIT) == mmap_flag) - { - char* oldbase = sp->base; - sp->base = tbase; - sp->size += tsize; - return prepend_alloc(m, tbase, oldbase, nb); - } - else - { - add_segment(m, tbase, tsize, mmap_flag); - } - } - } - - if (nb < m->topsize) /* Allocate from new or extended top space */ - { - size_t rsize = m->topsize -= nb; - mchunkptr p = m->top; - mchunkptr r = m->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - check_top_chunk(m, m->top); - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); - } - } - - MALLOC_FAILURE_ACTION; - return 0; -} - -/* ----------------------- system deallocation -------------------------- */ - -/* Unmap and unlink any mmapped segments that don't contain used chunks */ -static size_t release_unused_segments(mstate m) -{ - size_t released = 0; - int nsegs = 0; - msegmentptr pred = &m->seg; - msegmentptr sp = pred->next; - while (sp != 0) - { - char* base = sp->base; - size_t size = sp->size; - msegmentptr next = sp->next; - ++nsegs; - if (is_mmapped_segment(sp) && !is_extern_segment(sp)) - { - mchunkptr p = align_as_chunk(base); - size_t psize = chunksize(p); - /* Can unmap if first chunk holds entire segment and not pinned */ - if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) - { - tchunkptr tp = (tchunkptr)p; - assert(segment_holds(sp, (char*)sp)); - if (p == m->dv) - { - m->dv = 0; - m->dvsize = 0; - } - else - { - unlink_large_chunk(m, tp); - } - if ((*m->munmap)(m->extp, base, size) == 0) - { - released += size; - m->footprint -= size; - /* unlink obsoleted record */ - sp = pred; - sp->next = next; - } - else /* back out if cannot unmap */ - { - insert_large_chunk(m, tp, psize); - } - } - } - if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ - { - break; - } - pred = sp; - sp = next; - } - /* Reset check counter */ - m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE) ? - nsegs : MAX_RELEASE_CHECK_RATE); - return released; -} - -static int sys_trim(mstate m, size_t pad) -{ - size_t released = 0; - ensure_initialization(); - if (pad < MAX_REQUEST && is_initialized(m)) - { - pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ - - if (m->topsize > pad) - { - /* Shrink top space in granularity-size units, keeping at least one */ - size_t unit = mparams.granularity; - size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - - SIZE_T_ONE) * unit; - msegmentptr sp = segment_holding(m, (char*)m->top); - - if (!is_extern_segment(sp)) - { - if (is_mmapped_segment(sp)) - { - if (HAVE_MMAP && - sp->size >= extra && - 1 /*!has_segment_link(m, sp)*/) /* can't shrink if pinned */ - { - size_t newsize = sp->size - extra; - /* Prefer mremap, fall back to munmap */ - if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || - ((*m->munmap)(m->extp, sp->base + newsize, extra) == 0)) - { - released = extra; - } - } - } - else if (HAVE_MORECORE) - { - if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ - { - extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; - } - ACQUIRE_MALLOC_GLOBAL_LOCK(); - { - /* Make sure end of memory is where we last set it. */ - char* old_br = (char*)(CALL_MORECORE(0)); - if (old_br == sp->base + sp->size) - { - char* rel_br = (char*)(CALL_MORECORE(-extra)); - char* new_br = (char*)(CALL_MORECORE(0)); - if (rel_br != CMFAIL && new_br < old_br) - { - released = old_br - new_br; - } - } - } - RELEASE_MALLOC_GLOBAL_LOCK(); - } - } - - if (released != 0) - { - sp->size -= released; - m->footprint -= released; - init_top(m, m->top, m->topsize - released); - check_top_chunk(m, m->top); - } - } - - /* Unmap any unused mmapped segments */ - if (HAVE_MMAP) - { - released += release_unused_segments(m); - } - - /* On failure, disable autotrim to avoid repeated failed future calls */ - if (released == 0 && m->topsize > m->trim_check) - { - m->trim_check = MAX_SIZE_T; - } - } - - return (released != 0) ? 1 : 0; -} - - -/* ---------------------------- malloc support --------------------------- */ - -/* allocate a large request from the best fitting chunk in a treebin */ -static void* tmalloc_large(mstate m, size_t nb) -{ - tchunkptr v = 0; - size_t rsize = -nb; /* Unsigned negation */ - tchunkptr t; - bindex_t idx; - compute_tree_index(nb, idx); - if ((t = *treebin_at(m, idx)) != 0) - { - /* Traverse tree for this bin looking for node with size == nb */ - size_t sizebits = nb << leftshift_for_tree_index(idx); - tchunkptr rst = 0; /* The deepest untaken right subtree */ - for (;; ) - { - tchunkptr rt; - size_t trem = chunksize(t) - nb; - if (trem < rsize) - { - v = t; - if ((rsize = trem) == 0) - { - break; - } - } - rt = t->child[1]; - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - if (rt != 0 && rt != t) - { - rst = rt; - } - if (t == 0) - { - t = rst; /* set t to least subtree holding sizes > nb */ - break; - } - sizebits <<= 1; - } - } - if (t == 0 && v == 0) /* set t to root of next non-empty treebin */ - { - binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; - if (leftbits != 0) - { - bindex_t i; - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - t = *treebin_at(m, i); - } - } - - while (t != 0) /* find smallest of tree or subtree */ - { - size_t trem = chunksize(t) - nb; - if (trem < rsize) - { - rsize = trem; - v = t; - } - t = leftmost_child(t); - } - - /* If dv is a better fit, return 0 so malloc will use it */ - if (v != 0 && rsize < (size_t)(m->dvsize - nb)) - { - if (RTCHECK(ok_address(m, v))) /* split */ - { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) - { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - { - set_inuse_and_pinuse(m, v, (rsize + nb)); - } - else - { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); - } - return chunk2mem(v); - } - } - CORRUPTION_ERROR_ACTION(m); - } - return 0; -} - -/* allocate a small request from the best fitting chunk in a treebin */ -static void* tmalloc_small(mstate m, size_t nb) -{ - tchunkptr t, v; - size_t rsize; - bindex_t i; - binmap_t leastbit = least_bit(m->treemap); - compute_bit2idx(leastbit, i); - v = t = *treebin_at(m, i); - rsize = chunksize(t) - nb; - - while ((t = leftmost_child(t)) != 0) - { - size_t trem = chunksize(t) - nb; - if (trem < rsize) - { - rsize = trem; - v = t; - } - } - - if (RTCHECK(ok_address(m, v))) - { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) - { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - { - set_inuse_and_pinuse(m, v, (rsize + nb)); - } - else - { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); - } - return chunk2mem(v); - } - } - - CORRUPTION_ERROR_ACTION(m); -#if PROCEED_ON_ERROR - return 0; -#endif -} - -/* --------------------------- realloc support --------------------------- */ - -static void* internal_realloc(mstate m, void* oldmem, size_t bytes) -{ - if (bytes >= MAX_REQUEST) - { - MALLOC_FAILURE_ACTION; - return 0; - } - if (!PREACTION(m)) - { - mchunkptr oldp = mem2chunk(oldmem); - size_t oldsize = chunksize(oldp); - mchunkptr next = chunk_plus_offset(oldp, oldsize); - mchunkptr newp = 0; - void* extra = 0; - - /* Try to either shrink or extend into top. Else malloc-copy-free */ - - if (RTCHECK(ok_address(m, oldp) && ok_inuse(oldp) && - ok_next(oldp, next) && ok_pinuse(next))) - { - size_t nb = request2size(bytes); - if (is_mmapped(oldp)) - { - newp = mmap_resize(m, oldp, nb); - } - else if (oldsize >= nb) /* already big enough */ - { - size_t rsize = oldsize - nb; - newp = oldp; - if (rsize >= MIN_CHUNK_SIZE) - { - mchunkptr remainder = chunk_plus_offset(newp, nb); - set_inuse(m, newp, nb); - set_inuse_and_pinuse(m, remainder, rsize); - extra = chunk2mem(remainder); - } - } - else if (next == m->top && oldsize + m->topsize > nb) - { - /* Expand into top */ - size_t newsize = oldsize + m->topsize; - size_t newtopsize = newsize - nb; - mchunkptr newtop = chunk_plus_offset(oldp, nb); - set_inuse(m, oldp, nb); - newtop->head = newtopsize | PINUSE_BIT; - m->top = newtop; - m->topsize = newtopsize; - newp = oldp; - } - } - else - { - USAGE_ERROR_ACTION(m, oldmem); - POSTACTION(m); -#if PROCEED_ON_ERROR - return 0; -#endif - } -#if DEBUG - if (newp != 0) - { - check_inuse_chunk(m, newp); /* Check requires lock */ - } -#endif - - POSTACTION(m); - - if (newp != 0) - { - if (extra != 0) - { - internal_free(m, extra); - } - return chunk2mem(newp); - } - else - { - void* newmem = internal_malloc(m, bytes); - if (newmem != 0) - { - size_t oc = oldsize - overhead_for(oldp); - memcpy(newmem, oldmem, (oc < bytes) ? oc : bytes); - internal_free(m, oldmem); - } - return newmem; - } - } - return 0; -} - -/* --------------------------- memalign support -------------------------- */ - -static void* internal_memalign(mstate m, size_t alignment, size_t bytes) -{ - if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ - { - return internal_malloc(m, bytes); - } - if (alignment < MIN_CHUNK_SIZE)/* must be at least a minimum chunk size */ - { - alignment = MIN_CHUNK_SIZE; - } - if ((alignment & (alignment - SIZE_T_ONE)) != 0)/* Ensure a power of 2 */ - { - size_t a = MALLOC_ALIGNMENT << 1; - while (a < alignment) - { - a <<= 1; - } - alignment = a; - } - - if (bytes >= MAX_REQUEST - alignment) - { - if (m != 0) /* Test isn't needed but avoids compiler warning */ - { - MALLOC_FAILURE_ACTION; - } - } - else - { - size_t nb = request2size(bytes); - size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; - char* mem = (char*)internal_malloc(m, req); - if (mem != 0) - { - void* leader = 0; - void* trailer = 0; - mchunkptr p = mem2chunk(mem); - - if (PREACTION(m)) - { - return 0; - } - if ((((size_t)(mem)) % alignment) != 0) /* misaligned */ - { - /* - Find an aligned spot inside chunk. Since we need to give - back leading space in a chunk of at least MIN_CHUNK_SIZE, if - the first calculation places us at a spot with less than - MIN_CHUNK_SIZE leader, we can move to the next aligned spot. - We've allocated enough total room so that this is always - possible. - */ - char* br = (char*)mem2chunk((size_t)(((size_t)(mem + - alignment - - SIZE_T_ONE)) & - - alignment)); - char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE) ? - br : br + alignment; - mchunkptr newp = (mchunkptr)pos; - size_t leadsize = pos - (char*)(p); - size_t newsize = chunksize(p) - leadsize; - - if (is_mmapped(p)) /* For mmapped chunks, just adjust offset */ - { - newp->prev_foot = p->prev_foot + leadsize; - newp->head = newsize; - } - else /* Otherwise, give back leader, use the rest */ - { - set_inuse(m, newp, newsize); - set_inuse(m, p, leadsize); - leader = chunk2mem(p); - } - p = newp; - } - - /* Give back spare room at the end */ - if (!is_mmapped(p)) - { - size_t size = chunksize(p); - if (size > nb + MIN_CHUNK_SIZE) - { - size_t remainder_size = size - nb; - mchunkptr remainder = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, remainder, remainder_size); - trailer = chunk2mem(remainder); - } - } - - assert (chunksize(p) >= nb); - assert((((size_t)(chunk2mem(p))) % alignment) == 0); - check_inuse_chunk(m, p); - POSTACTION(m); - if (leader != 0) - { - internal_free(m, leader); - } - if (trailer != 0) - { - internal_free(m, trailer); - } - return chunk2mem(p); - } - } - return 0; -} - -/* ------------------------ comalloc/coalloc support --------------------- */ - -static void** ialloc(mstate m, - size_t n_elements, - size_t* sizes, - int opts, - void* chunks[]) -{ - /* - This provides common support for independent_X routines, handling - all of the combinations that can result. - - The opts arg has: - bit 0 set if all elements are same size (using sizes[0]) - bit 1 set if elements should be zeroed - */ - - size_t element_size; /* chunksize of each element, if all same */ - size_t contents_size;/* total size of elements */ - size_t array_size; /* request size of pointer array */ - void* mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size;/* remaining bytes while splitting */ - void** marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - flag_t was_enabled; /* to disable mmap */ - size_t size; - size_t i; - - ensure_initialization(); - /* compute array length, if needed */ - if (chunks != 0) - { - if (n_elements == 0) - { - return chunks; /* nothing to do */ - } - marray = chunks; - array_size = 0; - } - else - { - /* if empty req, must still return chunk representing empty array */ - if (n_elements == 0) - { - return (void**)internal_malloc(m, 0); - } - marray = 0; - array_size = request2size(n_elements * (sizeof(void*))); - } - - /* compute total element size */ - if (opts & 0x1) /* all-same-size */ - { - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } - else /* add up all the sizes */ - { - element_size = 0; - contents_size = 0; - for (i = 0; i != n_elements; ++i) - { - contents_size += request2size(sizes[i]); - } - } - - size = contents_size + array_size; - - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - mem = internal_malloc(m, size - CHUNK_OVERHEAD); - if (was_enabled) - { - enable_mmap(m); - } - if (mem == 0) - { - return 0; - } - - if (PREACTION(m)) - { - return 0; - } - p = mem2chunk(mem); - remainder_size = chunksize(p); - - assert(!is_mmapped(p)); - - if (opts & 0x2) /* optionally clear the elements */ - { - memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if (marray == 0) - { - size_t array_chunk_size; - array_chunk = chunk_plus_offset(p, contents_size); - array_chunk_size = remainder_size - contents_size; - marray = (void**) (chunk2mem(array_chunk)); - set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); - remainder_size = contents_size; - } - - /* split out elements */ - for (i = 0;; ++i) - { - marray[i] = chunk2mem(p); - if (i != n_elements - 1) - { - if (element_size != 0) - { - size = element_size; - } - else - { - size = request2size(sizes[i]); - } - remainder_size -= size; - set_size_and_pinuse_of_inuse_chunk(m, p, size); - p = chunk_plus_offset(p, size); - } - else /* the final element absorbs any overallocation slop */ - { - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - break; - } - } - -#if DEBUG - if (marray != chunks) - { - /* final element must have exactly exhausted chunk */ - if (element_size != 0) - { - assert(remainder_size == element_size); - } - else - { - assert(remainder_size == request2size(sizes[i])); - } - check_inuse_chunk(m, mem2chunk(marray)); - } - for (i = 0; i != n_elements; ++i) - { - check_inuse_chunk(m, mem2chunk(marray[i])); - } - -#endif /* DEBUG */ - - POSTACTION(m); - return marray; -} - - -/* -------------------------- public routines ---------------------------- */ - -#if !ONLY_MSPACES - -void* dlmalloc(size_t bytes) -{ - /* - Basic algorithm: - If a small request (< 256 bytes minus per-chunk overhead): - 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) - 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. - 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. - 4. If it is big enough, use the top chunk. - 5. If available, get memory from system and use it - Otherwise, for a large request: - 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. - 2. If better fitting than any binned chunk, use the dv chunk. - 3. If it is big enough, use the top chunk. - 4. If request size >= mmap threshold, try to directly mmap this chunk. - 5. If available, get memory from system and use it - - The ugly goto's here ensure that postaction occurs along all paths. - */ - -#if USE_LOCKS - ensure_initialization(); /* initialize in sys_alloc if not using locks */ -#endif - - if (!PREACTION(gm)) - { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) - { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = gm->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) /* Remainderless fit to a smallbin. */ - { - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(gm, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(gm, b, p, idx); - set_inuse_and_pinuse(gm, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb > gm->dvsize) - { - if (smallbits != 0) /* Use chunk in next nonempty smallbin */ - { - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(gm, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(gm, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - { - set_inuse_and_pinuse(gm, p, small_index2size(i)); - } - else - { - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(gm, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) - { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - { - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - } - else - { - nb = pad_request(bytes); - if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) - { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - - if (nb <= gm->dvsize) - { - size_t rsize = gm->dvsize - nb; - mchunkptr p = gm->dv; - if (rsize >= MIN_CHUNK_SIZE) /* split dv */ - { - mchunkptr r = gm->dv = chunk_plus_offset(p, nb); - gm->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - } - else /* exhaust dv */ - { - size_t dvs = gm->dvsize; - gm->dvsize = 0; - gm->dv = 0; - set_inuse_and_pinuse(gm, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb < gm->topsize) /* Split top */ - { - size_t rsize = gm->topsize -= nb; - mchunkptr p = gm->top; - mchunkptr r = gm->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - mem = chunk2mem(p); - check_top_chunk(gm, gm->top); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - mem = sys_alloc(gm, nb); - -postaction: - POSTACTION(gm); - return mem; - } - - return 0; -} - -void dlfree(void* mem) -{ - /* - Consolidate freed chunks with preceeding or succeeding bordering - free chunks, if they exist, and then place in a bin. Intermixed - with special cases for top, dv, mmapped chunks, and usage errors. - */ - - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - if (!ok_magic(fm)) - { - USAGE_ERROR_ACTION(fm, p); - return; - } -#else /* FOOTERS */ -#define fm gm -#endif /* FOOTERS */ - if (!PREACTION(fm)) - { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) - { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) - { - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) - { - psize += prevsize + MMAP_FOOT_PAD; - if ((*fm->munmap)(fm->extp, (char*)p - prevsize, psize) == 0) - { - fm->footprint -= psize; - } - goto postaction; - } - else - { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) /* consolidate backward */ - { - if (p != fm->dv) - { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) - { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - { - goto erroraction; - } - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) - { - if (!cinuse(next)) /* consolidate forward */ - { - if (next == fm->top) - { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) - { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - { - sys_trim(fm, 0); - } - goto postaction; - } - else if (next == fm->dv) - { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else - { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) - { - fm->dvsize = psize; - goto postaction; - } - } - } - else - { - set_free_with_pinuse(p, psize, next); - } - - if (is_small(psize)) - { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else - { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - { - release_unused_segments(fm); - } - } - goto postaction; - } - } -erroraction: - USAGE_ERROR_ACTION(fm, p); -postaction: - POSTACTION(fm); - } - } -#if !FOOTERS -#undef fm -#endif /* FOOTERS */ -} - -void* dlcalloc(size_t n_elements, size_t elem_size) -{ - void* mem; - size_t req = 0; - if (n_elements != 0) - { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - { - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - } - mem = dlmalloc(req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - { - memset(mem, 0, req); - } - return mem; -} - -void* dlrealloc(void* oldmem, size_t bytes) -{ - if (oldmem == 0) - { - return dlmalloc(bytes); - } -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) - { - dlfree(oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else - { -#if !FOOTERS - mstate m = gm; -#else /* FOOTERS */ - mstate m = get_mstate_for(mem2chunk(oldmem)); - if (!ok_magic(m)) - { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - return internal_realloc(m, oldmem, bytes); - } -} - -void* dlmemalign(size_t alignment, size_t bytes) -{ - return internal_memalign(gm, alignment, bytes); -} - -void** dlindependent_calloc(size_t n_elements, size_t elem_size, - void* chunks[]) -{ - size_t sz = elem_size; /* serves as 1-element array */ - return ialloc(gm, n_elements, &sz, 3, chunks); -} - -void** dlindependent_comalloc(size_t n_elements, size_t sizes[], - void* chunks[]) -{ - return ialloc(gm, n_elements, sizes, 0, chunks); -} - -void* dlvalloc(size_t bytes) -{ - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, bytes); -} - -void* dlpvalloc(size_t bytes) -{ - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); -} - -int dlmalloc_trim(size_t pad) -{ - int result = 0; - ensure_initialization(); - if (!PREACTION(gm)) - { - result = sys_trim(gm, pad); - POSTACTION(gm); - } - return result; -} - -size_t dlmalloc_footprint(void) -{ - return gm->footprint; -} - -size_t dlmalloc_max_footprint(void) -{ - return gm->max_footprint; -} - -#if !NO_MALLINFO -struct mallinfo dlmallinfo(void) -{ - return internal_mallinfo(gm); -} -#endif /* NO_MALLINFO */ - -void dlmalloc_stats() -{ - internal_malloc_stats(gm); -} - -void dlmalloc_stats_ret(size_t* sys, size_t* maxSys, size_t* used) -{ - internal_malloc_stats_ret(gm, sys, maxSys, used); -} - -int dlmallopt(int param_number, int value) -{ - return change_mparam(param_number, value); -} - -void dlPrintStats(void) -{ - struct mallinfo info = dlmallinfo(); - fprintf(stdout, "Non-MMap:%d\nFreeChunks:%d\nMMap Space:%d\nTotal Space:%d\nAlloc Space:%d\nFree Space:%d\nReleasable:%d\n", - (int)info.arena, (int)info.ordblks, (int)info.hblkhd, (int)info.usmblks, (int)info.uordblks, (int)info.fordblks, (int)info.keepcost); - - ensure_initialization(); - if (!PREACTION(gm)) - { - check_malloc_state(gm); - if (is_initialized(gm)) - { - msegmentptr s = &gm->seg; - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != gm->top && q->head != FENCEPOST_HEAD) - { - size_t sz = chunksize(q); - if (!is_inuse(q)) - { - fprintf(stdout, "Free: %p %d\n", q, (int)sz); - } - else - { - fprintf(stdout, "InUse: %p %d\n", q, (int)sz); - } - q = next_chunk(q); - } - s = s->next; - } - } - } -} -#endif /* !ONLY_MSPACES */ - -size_t dlmalloc_usable_size(void* mem) -{ - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); - if (is_inuse(p)) - { - return chunksize(p) - overhead_for(p); - } - } - return 0; -} - -/* ----------------------------- user mspaces ---------------------------- */ - -#if MSPACES - -static mstate init_user_mstate(char* tbase, size_t tsize, void* user, dlmmap_handler mmap, dlmunmap_handler munmap) -{ - size_t msize = pad_request(sizeof(struct malloc_state)); - mchunkptr mn; - mchunkptr msp = align_as_chunk(tbase); - mstate m = (mstate)(chunk2mem(msp)); - memset(m, 0, msize); - INITIAL_LOCK(&m->mutex); - msp->head = (msize | INUSE_BITS); - m->seg.base = m->least_addr = tbase; - m->seg.size = m->footprint = m->max_footprint = tsize; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - m->mflags = mparams.default_mflags; - m->extp = user; - m->exts = 0; - m->mmap = mmap; - m->munmap = munmap; - disable_contiguous(m); - init_bins(m); - mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); - check_top_chunk(m, m->top); - return m; -} - -static void* mmap_default(void* u, size_t sz) -{ - (void)u; - return CALL_MMAP(sz); -} - -static int munmap_default(void* u, void* p, size_t s) -{ - (void)u; - return CALL_MUNMAP(p, s); -} - -static void* mmap_missing(void* u, size_t sz) -{ - (void)u; - (void)sz; - return (void*) -1; -} - -static int munmap_missing(void* u, void* p, size_t s) -{ - (void)u; - (void)p; - (void)s; - return -1; -} - -int mspace_create_overhead(void) -{ - size_t msize = pad_request(sizeof(struct malloc_state)); - return msize + TOP_FOOT_SIZE; -} - -mspace create_mspace(size_t capacity, int locked, void* user, dlmmap_handler mmap, dlmunmap_handler munmap) -{ - mstate m = 0; - size_t msize; - ensure_initialization(); - msize = pad_request(sizeof(struct malloc_state)); - - if (!mmap) - { - mmap = mmap_default; - } - if (!munmap) - { - munmap = munmap_default; - } - - if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) - { - size_t rs = ((capacity == 0) ? mparams.granularity : - (capacity + TOP_FOOT_SIZE + msize)); - size_t tsize = granularity_align(rs); - char* tbase = (char*)((*mmap)(user, tsize)); - if (tbase != CMFAIL) - { - m = init_user_mstate(tbase, tsize, user, mmap, munmap); - m->seg.sflags = USE_MMAP_BIT; - set_lock(m, locked); - } - } - return (mspace)m; -} - -mspace create_mspace_with_base(void* base, size_t capacity, int locked) -{ - mstate m = 0; - size_t msize; - ensure_initialization(); - msize = pad_request(sizeof(struct malloc_state)); - if (capacity > msize + TOP_FOOT_SIZE && - capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) - { - m = init_user_mstate((char*)base, capacity, NULL, mmap_missing, munmap_missing); - m->seg.sflags = EXTERN_BIT; - set_lock(m, locked); - } - return (mspace)m; -} - -int mspace_track_large_chunks(mspace msp, int enable) -{ - int ret = 0; - mstate ms = (mstate)msp; - if (!PREACTION(ms)) - { - if (!use_mmap(ms)) - { - ret = 1; - } - if (!enable) - { - enable_mmap(ms); - } - else - { - disable_mmap(ms); - } - POSTACTION(ms); - } - return ret; -} - -size_t destroy_mspace(mspace msp) -{ - size_t freed = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - msegmentptr sp = &ms->seg; - while (sp != 0) - { - char* base = sp->base; - size_t size = sp->size; - flag_t flag = sp->sflags; - sp = sp->next; - if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) && - (*ms->munmap)(ms->extp, base, size) == 0) - { - freed += size; - } - } - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } - return freed; -} - -/* - mspace versions of routines are near-clones of the global - versions. This is not so nice but better than the alternatives. -*/ - - -void* mspace_malloc(mspace msp, size_t bytes) -{ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - if (!PREACTION(ms)) - { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) - { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = ms->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) /* Remainderless fit to a smallbin. */ - { - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(ms, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(ms, b, p, idx); - set_inuse_and_pinuse(ms, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb > ms->dvsize) - { - if (smallbits != 0) /* Use chunk in next nonempty smallbin */ - { - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(ms, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(ms, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - { - set_inuse_and_pinuse(ms, p, small_index2size(i)); - } - else - { - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(ms, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) - { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - { - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - } - else - { - nb = pad_request(bytes); - if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) - { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - - if (nb <= ms->dvsize) - { - size_t rsize = ms->dvsize - nb; - mchunkptr p = ms->dv; - if (rsize >= MIN_CHUNK_SIZE) /* split dv */ - { - mchunkptr r = ms->dv = chunk_plus_offset(p, nb); - ms->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - } - else /* exhaust dv */ - { - size_t dvs = ms->dvsize; - ms->dvsize = 0; - ms->dv = 0; - set_inuse_and_pinuse(ms, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb < ms->topsize) /* Split top */ - { - size_t rsize = ms->topsize -= nb; - mchunkptr p = ms->top; - mchunkptr r = ms->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - mem = chunk2mem(p); - check_top_chunk(ms, ms->top); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - mem = sys_alloc(ms, nb); - -postaction: - POSTACTION(ms); - return mem; - } - - return 0; -} - -void mspace_free(mspace msp, void* mem) -{ - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - msp = msp; /* placate people compiling -Wunused */ -#else /* FOOTERS */ - mstate fm = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(fm)) - { - USAGE_ERROR_ACTION(fm, p); - return; - } - if (!PREACTION(fm)) - { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) - { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) - { - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) - { - psize += prevsize + MMAP_FOOT_PAD; - if ((*fm->munmap)(fm->extp, (char*)p - prevsize, psize) == 0) - { - fm->footprint -= psize; - } - goto postaction; - } - else - { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) /* consolidate backward */ - { - if (p != fm->dv) - { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) - { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - { - goto erroraction; - } - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) - { - if (!cinuse(next)) /* consolidate forward */ - { - if (next == fm->top) - { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) - { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - { - sys_trim(fm, 0); - } - goto postaction; - } - else if (next == fm->dv) - { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else - { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) - { - fm->dvsize = psize; - goto postaction; - } - } - } - else - { - set_free_with_pinuse(p, psize, next); - } - - if (is_small(psize)) - { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else - { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - { - release_unused_segments(fm); - } - } - goto postaction; - } - } -erroraction: - USAGE_ERROR_ACTION(fm, p); -postaction: - POSTACTION(fm); - } - } -} - -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) -{ - void* mem; - size_t req = 0; - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - if (n_elements != 0) - { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - { - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - } - mem = internal_malloc(ms, req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - { - memset(mem, 0, req); - } - return mem; -} - -void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) -{ - if (oldmem == 0) - { - return mspace_malloc(msp, bytes); - } -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) - { - mspace_free(msp, oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else - { -#if FOOTERS - mchunkptr p = mem2chunk(oldmem); - mstate ms = get_mstate_for(p); -#else /* FOOTERS */ - mstate ms = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - return internal_realloc(ms, oldmem, bytes); - } -} - -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) -{ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - return internal_memalign(ms, alignment, bytes); -} - -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]) -{ - size_t sz = elem_size; /* serves as 1-element array */ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - return ialloc(ms, n_elements, &sz, 3, chunks); -} - -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]) -{ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - return ialloc(ms, n_elements, sizes, 0, chunks); -} - -int mspace_trim(mspace msp, size_t pad) -{ - int result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - if (!PREACTION(ms)) - { - result = sys_trim(ms, pad); - POSTACTION(ms); - } - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } - return result; -} - -void mspace_malloc_stats(mspace msp) -{ - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - internal_malloc_stats(ms); - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } -} - -size_t mspace_footprint(mspace msp) -{ - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - result = ms->footprint; - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } - return result; -} - - -size_t mspace_max_footprint(mspace msp) -{ - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - result = ms->max_footprint; - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } - return result; -} - - -#if !NO_MALLINFO -struct mallinfo mspace_mallinfo(mspace msp) -{ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); - } - return internal_mallinfo(ms); -} - -size_t mspace_get_used_space(mspace msp) -{ - struct mallinfo info = mspace_mallinfo(msp); - return info.uordblks; -} -#endif /* NO_MALLINFO */ - -size_t mspace_usable_size(void* mem) -{ - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); - if (is_inuse(p)) - { - return chunksize(p) - overhead_for(p); - } - } - return 0; -} - -int mspace_mallopt(int param_number, int value) -{ - return change_mparam(param_number, value); -} - -#endif /* MSPACES */ - - -/* -------------------- Alternative MORECORE functions ------------------- */ - -/* - Guidelines for creating a custom version of MORECORE: - - * For best performance, MORECORE should allocate in multiples of pagesize. - * MORECORE may allocate more memory than requested. (Or even less, - but this will usually result in a malloc failure.) - * MORECORE must not allocate memory when given argument zero, but - instead return one past the end address of memory from previous - nonzero call. - * For best performance, consecutive calls to MORECORE with positive - arguments should return increasing addresses, indicating that - space has been contiguously extended. - * Even though consecutive calls to MORECORE need not return contiguous - addresses, it must be OK for malloc'ed chunks to span multiple - regions in those cases where they do happen to be contiguous. - * MORECORE need not handle negative arguments -- it may instead - just return MFAIL when given negative arguments. - Negative arguments are always multiples of pagesize. MORECORE - must not misinterpret negative args as large positive unsigned - args. You can suppress all such calls from even occurring by defining - MORECORE_CANNOT_TRIM, - - As an example alternative MORECORE, here is a custom allocator - kindly contributed for pre-OSX macOS. It uses virtually but not - necessarily physically contiguous non-paged memory (locked in, - present and won't get swapped out). You can use it by uncommenting - this section, adding some #includes, and setting up the appropriate - defines above: - - #define MORECORE osMoreCore - - There is also a shutdown routine that should somehow be called for - cleanup upon program exit. - - #define MAX_POOL_ENTRIES 100 - #define MINIMUM_MORECORE_SIZE (64 * 1024U) - static int next_os_pool; - void *our_os_pools[MAX_POOL_ENTRIES]; - - void *osMoreCore(int size) - { - void *ptr = 0; - static void *sbrk_top = 0; - - if (size > 0) - { - if (size < MINIMUM_MORECORE_SIZE) - size = MINIMUM_MORECORE_SIZE; - if (CurrentExecutionLevel() == kTaskLevel) - ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); - if (ptr == 0) - { - return (void *) MFAIL; - } - // save ptrs so they can be freed during cleanup - our_os_pools[next_os_pool] = ptr; - next_os_pool++; - ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); - sbrk_top = (char *) ptr + size; - return ptr; - } - else if (size < 0) - { - // we don't currently support shrink behavior - return (void *) MFAIL; - } - else - { - return sbrk_top; - } - } - - // cleanup any allocated memory pools - // called as last thing before shutting down driver - - void osCleanupMem(void) - { - void **ptr; - - for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) - if (*ptr) - { - PoolDeallocate(*ptr); - *ptr = 0; - } - } - -*/ - - -/* ----------------------------------------------------------------------- -History: - V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) - * Use zeros instead of prev foot for is_mmapped - * Add mspace_track_large_chunks; thanks to Jean Brouwers - * Fix set_inuse in internal_realloc; thanks to Jean Brouwers - * Fix insufficient sys_alloc padding when using 16byte alignment - * Fix bad error check in mspace_footprint - * Adaptations for ptmalloc; thanks to Wolfram Gloger. - * Reentrant spin locks; thanks to Earl Chew and others - * Win32 improvements; thanks to Niall Douglas and Earl Chew - * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options - * Extension hook in malloc_state - * Various small adjustments to reduce warnings on some compilers - * Various configuration extensions/changes for more platforms. Thanks - to all who contributed these. - - V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) - * Add max_footprint functions - * Ensure all appropriate literals are size_t - * Fix conditional compilation problem for some #define settings - * Avoid concatenating segments with the one provided - in create_mspace_with_base - * Rename some variables to avoid compiler shadowing warnings - * Use explicit lock initialization. - * Better handling of sbrk interference. - * Simplify and fix segment insertion, trimming and mspace_destroy - * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x - * Thanks especially to Dennis Flanagan for help on these. - - V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) - * Fix memalign brace error. - - V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) - * Fix improper #endif nesting in C++ - * Add explicit casts needed for C++ - - V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) - * Use trees for large bins - * Support mspaces - * Use segments to unify sbrk-based and mmap-based system allocation, - removing need for emulation on most platforms without sbrk. - * Default safety checks - * Optional footer checks. Thanks to William Robertson for the idea. - * Internal code refactoring - * Incorporate suggestions and platform-specific changes. - Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, - Aaron Bachmann, Emery Berger, and others. - * Speed up non-fastbin processing enough to remove fastbins. - * Remove useless cfree() to avoid conflicts with other apps. - * Remove internal memcpy, memset. Compilers handle builtins better. - * Remove some options that no one ever used and rename others. - - V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - * Fix malloc_state bitmap array misdeclaration - - V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) - * Allow tuning of FIRST_SORTED_BIN_SIZE - * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. - * Better detection and support for non-contiguousness of MORECORE. - Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger - * Bypass most of malloc if no frees. Thanks To Emery Berger. - * Fix freeing of old top non-contiguous chunk im sysmalloc. - * Raised default trim and map thresholds to 256K. - * Fix mmap-related #defines. Thanks to Lubos Lunak. - * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. - * Branch-free bin calculation - * Default trim and mmap thresholds now 256K. - - V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) - * Introduce independent_comalloc and independent_calloc. - Thanks to Michael Pachos for motivation and help. - * Make optional .h file available - * Allow > 2GB requests on 32bit systems. - * new WIN32 sbrk, mmap, munmap, lock code from . - Thanks also to Andreas Mueller , - and Anonymous. - * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for - helping test this.) - * memalign: check alignment arg - * realloc: don't try to shift chunks backwards, since this - leads to more fragmentation in some programs and doesn't - seem to help in any others. - * Collect all cases in malloc requiring system memory into sysmalloc - * Use mmap as backup to sbrk - * Place all internal state in malloc_state - * Introduce fastbins (although similar to 2.5.1) - * Many minor tunings and cosmetic improvements - * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK - * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS - Thanks to Tony E. Bennett and others. - * Include errno.h to support default failure action. - - V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) - * return null for negative arguments - * Added Several WIN32 cleanups from Martin C. Fong - * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' - (e.g. WIN32 platforms) - * Cleanup header file inclusion for WIN32 platforms - * Cleanup code to avoid Microsoft Visual C++ compiler complaints - * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing - memory allocation routines - * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) - * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to - usage of 'assert' in non-WIN32 code - * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to - avoid infinite loop - * Always call 'fREe()' rather than 'free()' - - V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) - * Fixed ordering problem with boundary-stamping - - V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) - * Added pvalloc, as recommended by H.J. Liu - * Added 64bit pointer support mainly from Wolfram Gloger - * Added anonymously donated WIN32 sbrk emulation - * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen - * malloc_extend_top: fix mask error that caused wastage after - foreign sbrks - * Add linux mremap support code from HJ Liu - - V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) - * Integrated most documentation with the code. - * Add support for mmap, with help from - Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Use last_remainder in more cases. - * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold - * Eliminate block-local decls to simplify tracing and debugging. - * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. - * Rely on page size for units instead of SBRK_UNIT to - avoid surprises about sbrk alignment conventions. - * Add mallinfo, mallopt. Thanks to Raymond Nijssen - (raymond@es.ele.tue.nl) for the suggestion. - * Add `pad' argument to malloc_trim and top_pad mallopt parameter. - * More precautions for cases where other routines call sbrk, - courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Added macros etc., allowing use in linux libc from - H.J. Lu (hjl@gnu.ai.mit.edu) - * Inverted this history list - - V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) - * Re-tuned and fixed to behave more nicely with V2.6.0 changes. - * Removed all preallocation code since under current scheme - the work required to undo bad preallocations exceeds - the work saved in good cases for most test programs. - * No longer use return list or unconsolidated bins since - no scheme using them consistently outperforms those that don't - given above changes. - * Use best fit for very large chunks to prevent some worst-cases. - * Added some support for debugging - - V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) - * Removed footers when chunks are in use. Thanks to - Paul Wilson (wilson@cs.texas.edu) for the suggestion. - - V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) - * Added malloc_trim, with help from Wolfram Gloger - (wmglo@Dent.MED.Uni-Muenchen.DE). - - V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) - - V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) - * realloc: try to expand in both directions - * malloc: swap order of clean-bin strategy; - * realloc: only conditionally expand backwards - * Try not to scavenge used bins - * Use bin counts as a guide to preallocation - * Occasionally bin return list chunks in first scan - * Add a few optimizations from colin@nyx10.cs.du.edu - - V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) - * faster bin computation & slightly different binning - * merged all consolidations to one part of malloc proper - (eliminating old malloc_find_space & malloc_clean_bin) - * Scan 2 returns chunks (not just 1) - * Propagate failure in realloc if malloc returns 0 - * Add stuff to allow compilation on non-ANSI compilers - from kpv@research.att.com - - V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) - * removed potential for odd address access in prev_chunk - * removed dependency on getpagesize.h - * misc cosmetics and a bit more internal documentation - * anticosmetics: mangled names in macros to evade debugger strangeness - * tested on sparc, hp-700, dec-mips, rs6000 - with gcc & native cc (hp, dec only) allowing - Detlefs & Zorn comparison study (in SIGPLAN Notices.) - - Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) - * Based loosely on libg++-1.2X malloc. (It retains some of the overall - structure of old version, but most details differ.) - -*/ - -#endif diff --git a/Code/CryEngine/CrySystem/CrySystem.rc b/Code/CryEngine/CrySystem/CrySystem.rc deleted file mode 100644 index f3412468f5..0000000000 --- a/Code/CryEngine/CrySystem/CrySystem.rc +++ /dev/null @@ -1,91 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "Amazon.com, Inc." - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." - VALUE "ProductName", "Lumberyard" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // German (Germany) resources -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED -#endif // English (United States) resources diff --git a/Code/CryEngine/CrySystem/CryWaterMark.h b/Code/CryEngine/CrySystem/CryWaterMark.h deleted file mode 100644 index 4272b63aab..0000000000 --- a/Code/CryEngine/CrySystem/CryWaterMark.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Header for adding a watermark to an exe, which can then be set -// by the external CryWaterMark program. To use, simply write: -// -// WATERMARKDATA(__blah); -// -// anywhere in the global scope in the program - - -#ifndef CRYINCLUDE_CRYSYSTEM_CRYWATERMARK_H -#define CRYINCLUDE_CRYSYSTEM_CRYWATERMARK_H -#pragma once - - -#define NUMMARKWORDS 10 -#define WATERMARKDATA(name) unsigned int name[] = { 0xDEBEFECA, 0xFABECEDA, 0xADABAFBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -// (the name is such that you can have multiple watermarks in one exe, don't use -// names like "watermark" just incase you accidentally give out an exe with -// debug information). - -#endif // CRYINCLUDE_CRYSYSTEM_CRYWATERMARK_H diff --git a/Code/CryEngine/CrySystem/HandlerBase.cpp b/Code/CryEngine/CrySystem/HandlerBase.cpp deleted file mode 100644 index 6e1b7fdc77..0000000000 --- a/Code/CryEngine/CrySystem/HandlerBase.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "HandlerBase.h" - -const char* SERVER_LOCK_NAME = "SynchronizeGameServer"; -const char* CLIENT_LOCK_NAME = "SynchronizeGameClient"; - -HandlerBase::HandlerBase(const char* bucket, int affinity) -{ - m_serverLockName.Format("%s_%s", SERVER_LOCK_NAME, bucket); - m_clientLockName.Format("%s_%s", CLIENT_LOCK_NAME, bucket); - if (affinity != 0) - { - m_affinity = uint32(1) << (affinity - 1); - } - else - { - m_affinity = -1; - } - m_prevAffinity = 0; -} - -HandlerBase::~HandlerBase() -{ - if (m_prevAffinity) - { - if (SyncSetAffinity(m_prevAffinity)) - { - CryLogAlways("Restored affinity to %d", m_prevAffinity); - } - else - { - CryLogAlways("Failed to restore affinity to %d", m_prevAffinity); - } - } -} - -void HandlerBase::SetAffinity() -{ - if (m_prevAffinity) //already set - { - return; - } - if (uint32 p = SyncSetAffinity(m_affinity)) - { - CryLogAlways("Changed affinity to %d", m_affinity); - m_prevAffinity = p; - } - else - { - CryLogAlways("Failed to change affinity to %d", m_affinity); - } -} - -#if defined(LINUX) - -uint32 HandlerBase::SyncSetAffinity(uint32 cpuMask)//put -1 -{ - if (cpuMask != 0) - { - cpu_set_t cpuSet; - uint32 affinity = 0; - if (!sched_getaffinity(getpid(), sizeof cpuSet, &cpuSet)) - { - for (int cpu = 0; cpu < sizeof(cpuMask) * 8; ++cpu) - { - if (CPU_ISSET(cpu, &cpuSet)) - { - affinity |= 1 << cpu; - } - } - } - if (affinity) - { - CPU_ZERO(&cpuSet); - for (int cpu = 0; cpu < sizeof(cpuMask) * 8; ++cpu) - { - if (cpuMask & (1 << cpu)) - { - CPU_SET(cpu, &cpuSet); - } - } - - if (!sched_setaffinity(getpid(), sizeof(cpuSet), &cpuSet)) - { - return affinity; - } - } - } - return 0; -} - -#elif AZ_LEGACY_CRYSYSTEM_TRAIT_USE_HANDLER_SYNC_AFFINITY - -uint32 HandlerBase::SyncSetAffinity(uint32 cpuMask)//put -1 -{ - uint32 p = (uint32)SetThreadAffinityMask(GetCurrentThread(), cpuMask); - if (p == 0) - { - CryLogAlways("Error updating affinity mask to %d", cpuMask); - } - return p; -} - -#else - -uint32 HandlerBase::SyncSetAffinity(uint32 cpuMask)//put -1 -{ - CryLogAlways("Updating thread affinity not supported on this platform"); - return 0; -} - -#endif - -#endif // defined(MAP_LOADING_SLICING) diff --git a/Code/CryEngine/CrySystem/HandlerBase.h b/Code/CryEngine/CrySystem/HandlerBase.h deleted file mode 100644 index 67e7a828a6..0000000000 --- a/Code/CryEngine/CrySystem/HandlerBase.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_HANDLERBASE_H -#define CRYINCLUDE_CRYSYSTEM_HANDLERBASE_H - -#pragma once - -const int MAX_CLIENTS_NUM = 100; - -struct HandlerBase -{ - HandlerBase(const char* bucket, int affinity); - ~HandlerBase(); - - void SetAffinity(); - uint32 SyncSetAffinity(uint32 cpuMask); - - string m_serverLockName; - string m_clientLockName; - uint32 m_affinity; - uint32 m_prevAffinity; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_HANDLERBASE_H diff --git a/Code/CryEngine/CrySystem/IOSConsole.h b/Code/CryEngine/CrySystem/IOSConsole.h deleted file mode 100644 index 8bd2a8779e..0000000000 --- a/Code/CryEngine/CrySystem/IOSConsole.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for iOS, reports back to the main interface - -#pragma once - -#include -#include - -class CIOSConsole - : public ISystemUserCallback - , public IOutputPrintSink - , public ITextModeConsole -{ - CIOSConsole(const CIOSConsole&); - CIOSConsole& operator = (const CIOSConsole&); - - bool m_isInitialized; -public: - static CryCriticalSectionNonRecursive s_lock; -public: - CIOSConsole(); - ~CIOSConsole(); - - // Interface IOutputPrintSink ///////////////////////////////////////////// - DLL_EXPORT virtual void Print(const char* line); - - // Interface ISystemUserCallback ////////////////////////////////////////// - virtual bool OnError(const char* errorString); - virtual bool OnSaveDocument() { return false; } - virtual void OnProcessSwitch() { } - virtual void OnInitProgress(const char* sProgressMsg); - virtual void OnInit(ISystem*); - virtual void OnShutdown(); - virtual void OnUpdate(); - virtual void GetMemoryUsage(ICrySizer* pSizer); - void SetRequireDedicatedServer(bool) {} - void SetHeader(const char*) {} - // Interface ITextModeConsole ///////////////////////////////////////////// - virtual Vec2_tpl BeginDraw(); - virtual void PutText(int x, int y, const char* msg); - virtual void EndDraw(); -}; diff --git a/Code/CryEngine/CrySystem/IOSConsole.mm b/Code/CryEngine/CrySystem/IOSConsole.mm deleted file mode 100644 index 6058ea8a44..0000000000 --- a/Code/CryEngine/CrySystem/IOSConsole.mm +++ /dev/null @@ -1,94 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#if defined(IOS) -#include "IOSConsole.h" - - - -CIOSConsole::CIOSConsole(): -m_isInitialized(false) -{ - -} - -CIOSConsole::~CIOSConsole() -{ - -} - -// Interface IOutputPrintSink ///////////////////////////////////////////// -void CIOSConsole::Print(const char *line) -{ - printf("MSG: %s\n", line); -} -// Interface ISystemUserCallback ////////////////////////////////////////// -bool CIOSConsole::OnError(const char *errorString) -{ - printf("ERR: %s\n", errorString); - return true; -} - -void CIOSConsole::OnInitProgress(const char *sProgressMsg) -{ - (void) sProgressMsg; - // Do Nothing -} -void CIOSConsole::OnInit(ISystem *pSystem) -{ - if (!m_isInitialized) - { - IConsole* pConsole = pSystem->GetIConsole(); - if (pConsole != 0) - { - pConsole->AddOutputPrintSink(this); - } - m_isInitialized = true; - } -} -void CIOSConsole::OnShutdown() -{ - if (m_isInitialized) - { - // remove outputprintsink - m_isInitialized = false; - } -} -void CIOSConsole::OnUpdate() -{ - // Do Nothing -} -void CIOSConsole::GetMemoryUsage(ICrySizer *pSizer) -{ - size_t size = sizeof(*this); - - - - pSizer->AddObject(this, size); -} - -// Interface ITextModeConsole ///////////////////////////////////////////// -Vec2_tpl CIOSConsole::BeginDraw() -{ - return Vec2_tpl(0,0); -} -void CIOSConsole::PutText( int x, int y, const char * msg ) -{ - printf("PUT: %s\n", msg); -} -void CIOSConsole::EndDraw() { - // Do Nothing -} -#endif // IOS diff --git a/Code/CryEngine/CrySystem/LZ4Decompressor.cpp b/Code/CryEngine/CrySystem/LZ4Decompressor.cpp deleted file mode 100644 index a4b8a2b8e6..0000000000 --- a/Code/CryEngine/CrySystem/LZ4Decompressor.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : lz4 hc decompress wrapper - - -#include "CrySystem_precompiled.h" -#include -#include "LZ4Decompressor.h" - -bool CLZ4Decompressor::DecompressData(const char* pIn, char* pOut, const uint outputSize) const -{ - return LZ4_decompress_fast(pIn, pOut, outputSize) >= 0; -} - -void CLZ4Decompressor::Release() -{ - delete this; -} diff --git a/Code/CryEngine/CrySystem/LZ4Decompressor.h b/Code/CryEngine/CrySystem/LZ4Decompressor.h deleted file mode 100644 index 20652a8e78..0000000000 --- a/Code/CryEngine/CrySystem/LZ4Decompressor.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : lz4 hc decompress wrapper - - -#ifndef CRYINCLUDE_CRYSYSTEM_LZ4DECOMPRESSOR_H -#define CRYINCLUDE_CRYSYSTEM_LZ4DECOMPRESSOR_H -#pragma once - - -#include "ILZ4Decompressor.h" - -class CLZ4Decompressor - : public ILZ4Decompressor -{ -public: - virtual bool DecompressData(const char* pIn, char* pOut, const uint outputSize) const; - virtual void Release(); - -private: - virtual ~CLZ4Decompressor() {} -}; - -#endif // CRYINCLUDE_CRYSYSTEM_LZ4DECOMPRESSOR_H diff --git a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp index 8d9c0dd8e8..68fc4b558a 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp @@ -260,16 +260,6 @@ void CLevelSystem::Rescan(const char* levelsFolder) { if (levelsFolder) { - if (const ICmdLineArg* pModArg = m_pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "MOD")) - { - if (m_pSystem->IsMODValid(pModArg->GetValue())) - { - m_levelsFolder.format("Mods/%s/%s", pModArg->GetValue(), levelsFolder); - m_levelInfos.clear(); - ScanFolder(0, true); - } - } - m_levelsFolder = levelsFolder; } diff --git a/Code/CryEngine/CrySystem/Log.cpp b/Code/CryEngine/CrySystem/Log.cpp index 63aee4422f..c37e12cebd 100644 --- a/Code/CryEngine/CrySystem/Log.cpp +++ b/Code/CryEngine/CrySystem/Log.cpp @@ -417,7 +417,7 @@ void CLog::LogV(const ELogType type, const char* szFormat, va_list args) LogV(type, 0, szFormat, args); } -void CLog::LogV(const ELogType type, int flags, const char* szFormat, va_list args) +void CLog::LogV(const ELogType type, [[maybe_unused]]int flags, const char* szFormat, va_list args) { // this is here in case someone called LogV directly, with an invalid formatter. if (!CheckLogFormatter(szFormat)) @@ -595,28 +595,6 @@ void CLog::LogV(const ELogType type, int flags, const char* szFormat, va_list ar GetISystem()->GetIRemoteConsole()->AddLogError(szString); break; } - - ////////////////////////////////////////////////////////////////////////// - if (type == eWarningAlways || type == eWarning || type == eError || type == eErrorAlways) - { - IValidator* pValidator = m_pSystem->GetIValidator(); - if (pValidator && (flags & VALIDATOR_FLAG_SKIP_VALIDATOR) == 0) - { - CryAutoCriticalSection scope_lock(m_logCriticalSection); - - SValidatorRecord record; - record.text = szBuffer; - record.module = VALIDATOR_MODULE_SYSTEM; - record.severity = VALIDATOR_WARNING; - record.assetScope = GetAssetScopeString(); - record.flags = flags; - if (type == eError || type == eErrorAlways) - { - record.severity = VALIDATOR_ERROR; - } - pValidator->Report(record); - } - } } //will log the text both to the end of file and console diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec.cpp b/Code/CryEngine/CrySystem/MobileDetectSpec.cpp deleted file mode 100644 index 342537daeb..0000000000 --- a/Code/CryEngine/CrySystem/MobileDetectSpec.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include -#include - -#include "MobileDetectSpec.h" - -namespace MobileSysInspect -{ - struct GpuApiPair - { - AZStd::string gpuDescription; - AZStd::string apiDescription; - }; - - AZStd::vector> deviceSpecMapping; - AZStd::vector> gpuSpecMapping; - const float LOW_SPEC_RAM = 1.0f; - const float MEDIUM_SPEC_RAM = 2.0f; - const float HIGH_SPEC_RAM = 3.0f; - - bool GetSpecForGPUAndAPI(const AZStd::string& gpuName, const AZStd::string& apiDescription, AZStd::string& specName) - { - for (const auto& descriptionSpecPair : gpuSpecMapping) - { - const GpuApiPair& currentPair = descriptionSpecPair.first; - AZStd::regex currentRegex(currentPair.gpuDescription.c_str()); - if (!AZStd::regex_search(gpuName, currentRegex)) - { - continue; - } - - currentRegex.assign(currentPair.apiDescription.c_str()); - if (!currentRegex.Empty() && !AZStd::regex_search(apiDescription, currentRegex)) - { - continue; - } - - specName = descriptionSpecPair.second; - return true; - } - - return false; - } - - namespace Internal - { - void LoadDeviceSpecMapping_impl(const char* filename) - { - XmlNodeRef xmlNode = GetISystem()->LoadXmlFromFile(filename); - - if (!xmlNode) - { - return; - } - - const int fileCount = xmlNode->getChildCount(); - - for (int i = 0; i < fileCount; ++i) - { - XmlNodeRef fileNode = xmlNode->getChild(i); - AZStd::string file = fileNode->getAttr("file"); - - if (!file.empty()) - { - const int mappingCount = fileNode->getChildCount(); - - deviceSpecMapping.reserve(mappingCount); - - for (int j = 0; j < mappingCount; ++j) - { - XmlNodeRef modelNode = fileNode->getChild(j); - AZStd::string model = modelNode->getAttr("model"); - - if (!model.empty()) - { - deviceSpecMapping.push_back(AZStd::make_pair(model, file)); - } - } - } - } - } - - void LoadGpuSpecMapping_impl(const char* filename) - { - XmlNodeRef xmlNode = GetISystem()->LoadXmlFromFile(filename); - - if (!xmlNode) - { - return; - } - - const int fileCount = xmlNode->getChildCount(); - - for (int i = 0; i < fileCount; ++i) - { - XmlNodeRef fileNode = xmlNode->getChild(i); - AZStd::string file = fileNode->getAttr("file"); - - if (!file.empty()) - { - const int mappingCount = fileNode->getChildCount(); - - gpuSpecMapping.reserve(mappingCount); - - for (int j = 0; j < mappingCount; ++j) - { - XmlNodeRef modelNode = fileNode->getChild(j); - GpuApiPair gpuApiPair; - gpuApiPair.gpuDescription = modelNode->getAttr("gpuName"); - gpuApiPair.apiDescription = modelNode->getAttr("apiVersion"); - - if (!gpuApiPair.gpuDescription.empty() || !gpuApiPair.apiDescription.empty()) - { - gpuSpecMapping.push_back(AZStd::make_pair(gpuApiPair, file)); - } - } - } - } - } - - bool GetSpecForModelName(const AZStd::string& modelName, AZStd::string& specName) - { - for (const auto& descriptionSpecPair : deviceSpecMapping) - { - AZStd::regex currentRegex(descriptionSpecPair.first.c_str()); - if (AZStd::regex_search(modelName, currentRegex)) - { - specName = descriptionSpecPair.second; - return true; - } - } - - return false; - } - - } // namespace Internal -} // namespace MobileSysInspect diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec.h b/Code/CryEngine/CrySystem/MobileDetectSpec.h deleted file mode 100644 index bbb15d301a..0000000000 --- a/Code/CryEngine/CrySystem/MobileDetectSpec.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "AzCore/std/containers/unordered_map.h" - -namespace MobileSysInspect -{ - extern const float LOW_SPEC_RAM; - extern const float MEDIUM_SPEC_RAM; - extern const float HIGH_SPEC_RAM; - - void LoadDeviceSpecMapping(); - bool GetAutoDetectedSpecName(AZStd::string &buffer); - bool GetSpecForGPUAndAPI(const AZStd::string& gpuName, const AZStd::string& apiDescription, AZStd::string& specName); - const float GetDeviceRamInGB(); - - namespace Internal - { - void LoadDeviceSpecMapping_impl(const char* fileName); - void LoadGpuSpecMapping_impl(const char* filename); - bool GetSpecForModelName(const AZStd::string& modelName, AZStd::string& specName); - } -} diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec_Android.cpp b/Code/CryEngine/CrySystem/MobileDetectSpec_Android.cpp deleted file mode 100644 index 181200d383..0000000000 --- a/Code/CryEngine/CrySystem/MobileDetectSpec_Android.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include -#include - -#include "MobileDetectSpec.h" - -namespace MobileSysInspect -{ - void LoadDeviceSpecMapping() - { - Internal::LoadDeviceSpecMapping_impl("@assets@/config/gpu/android_models.xml"); - Internal::LoadGpuSpecMapping_impl("@assets@/config/gpu/android_gpus.xml"); - } - - // Returns true if device is found in the device spec mapping - bool GetAutoDetectedSpecName(AZStd::string &buffer) - { - static constexpr const char* s_javaFieldName = "MODEL"; - AZ::Android::JNI::Object obj("android/os/Build"); - obj.RegisterStaticField(s_javaFieldName, "Ljava/lang/String;"); - AZStd::string name = obj.GetStaticStringField(s_javaFieldName); - - return Internal::GetSpecForModelName(name, buffer); - } - - const float GetDeviceRamInGB() - { - static constexpr const char* s_javaFuntionNameGetDeviceRamInGB = "GetDeviceRamInGB"; - AZ::Android::JNI::Object obj("com/amazon/lumberyard/AndroidDeviceManager"); - obj.RegisterStaticMethod(s_javaFuntionNameGetDeviceRamInGB, "()F"); - return obj.InvokeStaticFloatMethod(s_javaFuntionNameGetDeviceRamInGB); - } -} diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp b/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp deleted file mode 100644 index dc0a28490d..0000000000 --- a/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include - -#include "MobileDetectSpec.h" -#include - -namespace MobileSysInspect -{ - void LoadDeviceSpecMapping() - { - Internal::LoadDeviceSpecMapping_impl("@assets@/config/gpu/ios_models.xml"); - } - - // Returns true if device is found in the device spec mapping - bool GetAutoDetectedSpecName(AZStd::string &buffer) - { - AZStd::string name = SystemUtilsApple::GetMachineName(); - - return Internal::GetSpecForModelName(name, buffer); - } - - const float GetDeviceRamInGB() - { - // not supported on this platform - return 0.0f; - } -} diff --git a/Code/CryEngine/CrySystem/PhysRenderer.cpp b/Code/CryEngine/CrySystem/PhysRenderer.cpp deleted file mode 100644 index a17fcb7063..0000000000 --- a/Code/CryEngine/CrySystem/PhysRenderer.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : impelemnation of a simple dedicated renderer for the physics subsystem - - -#include "CrySystem_precompiled.h" - diff --git a/Code/CryEngine/CrySystem/PhysRenderer.h b/Code/CryEngine/CrySystem/PhysRenderer.h deleted file mode 100644 index bbcca4626e..0000000000 --- a/Code/CryEngine/CrySystem/PhysRenderer.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : declaration of a simple dedicated renderer for the physics subsystem - - -#ifndef CRYINCLUDE_CRYSYSTEM_PHYSRENDERER_H -#define CRYINCLUDE_CRYSYSTEM_PHYSRENDERER_H -#pragma once - - -#endif // CRYINCLUDE_CRYSYSTEM_PHYSRENDERER_H diff --git a/Code/CryEngine/CrySystem/Platform/Android/platform_android.cmake b/Code/CryEngine/CrySystem/Platform/Android/platform_android.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Android/platform_android.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Code/CryEngine/CrySystem/Platform/Android/platform_android_files.cmake b/Code/CryEngine/CrySystem/Platform/Android/platform_android_files.cmake deleted file mode 100644 index ce1124fe07..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Android/platform_android_files.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../MobileDetectSpec_Android.cpp - ../../MobileDetectSpec.cpp - ../../MobileDetectSpec.h - ../../ThermalInfoAndroid.h - ../../ThermalInfoAndroid.cpp -) diff --git a/Code/CryEngine/CrySystem/Platform/Linux/platform_linux.cmake b/Code/CryEngine/CrySystem/Platform/Linux/platform_linux.cmake deleted file mode 100644 index 971c8ad67f..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Linux/platform_linux.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files - -set(LY_BUILD_DEPENDENCIES - PRIVATE - m -) diff --git a/Code/CryEngine/CrySystem/Platform/Linux/platform_linux_files.cmake b/Code/CryEngine/CrySystem/Platform/Linux/platform_linux_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Linux/platform_linux_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake b/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake b/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake deleted file mode 100644 index 4d5680a30d..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake +++ /dev/null @@ -1,10 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# diff --git a/Code/CryEngine/CrySystem/Platform/Windows/platform_windows.cmake b/Code/CryEngine/CrySystem/Platform/Windows/platform_windows.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Windows/platform_windows.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Code/CryEngine/CrySystem/Platform/Windows/platform_windows_files.cmake b/Code/CryEngine/CrySystem/Platform/Windows/platform_windows_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Windows/platform_windows_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios.cmake b/Code/CryEngine/CrySystem/Platform/iOS/platform_ios.cmake deleted file mode 100644 index f607478131..0000000000 --- a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(LY_COMPILE_OPTIONS - PRIVATE - -xobjective-c++ -) - -find_library(UI_KIT_FRAMEWORK UIKit) - -set(LY_BUILD_DEPENDENCIES - PRIVATE - ${UI_KIT_FRAMEWORK} -) diff --git a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake b/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake deleted file mode 100644 index bbe61fb488..0000000000 --- a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../MobileDetectSpec_Ios.cpp - ../../MobileDetectSpec.cpp - ../../MobileDetectSpec.h -) - - diff --git a/Code/CryEngine/CrySystem/SSAPI.DLL b/Code/CryEngine/CrySystem/SSAPI.DLL deleted file mode 100644 index b1f3d6cfce..0000000000 --- a/Code/CryEngine/CrySystem/SSAPI.DLL +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:45dfbb9836e8a8ac4ed5b427528dadf9134618e6977a1eb67af067e0eaadc185 -size 561936 diff --git a/Code/CryEngine/CrySystem/Sampler.cpp b/Code/CryEngine/CrySystem/Sampler.cpp deleted file mode 100644 index b6866ba6cd..0000000000 --- a/Code/CryEngine/CrySystem/Sampler.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "Sampler.h" - -#if defined(WIN32) - -#include -#include -#include - -#define MAX_SYMBOL_LENGTH 512 - -////////////////////////////////////////////////////////////////////////// -// Makes thread. -////////////////////////////////////////////////////////////////////////// -class CSamplingThread -{ -public: - CSamplingThread(CSampler* pSampler) - { - m_hThread = NULL; - m_pSampler = pSampler; - m_bStop = false; - m_samplePeriodMs = pSampler->GetSamplePeriod(); - - m_hProcess = GetCurrentProcess(); - m_hSampledThread = GetCurrentThread(); - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &m_hSampledThread, 0, FALSE, DUPLICATE_SAME_ACCESS); - } - - // Start thread. - void Start(); - void Stop(); - -protected: - virtual ~CSamplingThread() {}; - static DWORD WINAPI ThreadFunc(void* pThreadParam); - void Run(); // Derived classes must override this. - - HANDLE m_hProcess; - HANDLE m_hThread; - HANDLE m_hSampledThread; - DWORD m_ThreadId; - - CSampler* m_pSampler; - bool m_bStop; - int m_samplePeriodMs; -}; - -////////////////////////////////////////////////////////////////////////// -void CSamplingThread::Start() -{ - m_hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, &m_ThreadId); -} - -////////////////////////////////////////////////////////////////////////// -void CSamplingThread::Stop() -{ - m_bStop = true; -} - -////////////////////////////////////////////////////////////////////////// -DWORD CSamplingThread::ThreadFunc(void* pThreadParam) -{ - CSamplingThread* thread = (CSamplingThread*)pThreadParam; - thread->Run(); - // Auto destruct thread class. - delete thread; - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CSamplingThread::Run() -{ - //SetThreadPriority( m_hThread,THREAD_PRIORITY_HIGHEST ); - SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL); - while (!m_bStop) - { - SuspendThread(m_hSampledThread); - - CONTEXT context; - context.ContextFlags = CONTEXT_CONTROL; - - uint64 ip = 0; - if (GetThreadContext(m_hSampledThread, &context)) - { -#ifdef CONTEXT_i386 - ip = context.Eip; -#else - ip = context.Rip; -#endif - } - ResumeThread(m_hSampledThread); - - if (!m_pSampler->AddSample(ip)) - { - break; - } - - Sleep(m_samplePeriodMs); - } -} - -////////////////////////////////////////////////////////////////////////// -CSampler::CSampler() -{ - m_pSamplingThread = NULL; - SetMaxSamples(2000); - m_bSamplingFinished = false; - m_bSampling = false; - m_samplePeriodMs = 1; //1ms -} - -////////////////////////////////////////////////////////////////////////// -CSampler::~CSampler() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::SetMaxSamples(int nMaxSamples) -{ - m_rawSamples.reserve(nMaxSamples); - m_nMaxSamples = nMaxSamples; -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::Start() -{ - if (m_bSampling) - { - return; - } - - CryLogAlways("Staring Sampling with interval %dms, max samples: %d ...", m_samplePeriodMs, m_nMaxSamples); - - m_bSampling = true; - m_bSamplingFinished = false; - m_pSamplingThread = new CSamplingThread(this); - m_rawSamples.clear(); - m_functionSamples.clear(); - - m_pSamplingThread->Start(); -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::Stop() -{ - if (m_bSamplingFinished) - { - } - if (m_bSampling) - { - m_pSamplingThread->Stop(); - } - m_bSampling = false; - m_pSamplingThread = 0; -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::Update() -{ - if (m_bSamplingFinished) - { - ProcessSampledData(); - m_bSamplingFinished = false; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CSampler::AddSample(uint64 ip) -{ - if ((int)m_rawSamples.size() >= m_nMaxSamples) - { - m_bSamplingFinished = true; - m_bSampling = false; - m_pSamplingThread = 0; - return false; - } - m_rawSamples.push_back(ip); - return true; -} - -inline bool CompareFunctionSamples(const CSampler::SFunctionSample& s1, const CSampler::SFunctionSample& s2) -{ - return s1.nSamples < s2.nSamples; -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::ProcessSampledData() -{ - CryLogAlways("Processing collected samples..."); - - uint32 i; - // Count duplicates. - std::map counts; - std::map::iterator cit; - for (i = 0; i < m_rawSamples.size(); i++) - { - uint32 ip = (uint32)m_rawSamples[i]; - cit = counts.find(ip); - if (cit != counts.end()) - { - cit->second++; - } - else - { - counts[ip] = 0; - } - } - - std::map funcCounts; - - AZ::Debug::SymbolStorage::StackLine func, file, module; - int line; - void* baseAddr; - string funcName; - for (i = 0; i < m_rawSamples.size(); i++) - { - // lookup module name here, and aggregate the results - AZ::Debug::SymbolStorage::FindFunctionFromIP((void*)m_rawSamples[i], &func, &file, &module, line, baseAddr); - - // Developer note: this file was using the module name instead of the function name. There was stub code - // to use the function name instead that. This function was updated to use FindFunctionFromIP(), but - // continues to use the module instead of the function. - funcName = module; - funcCounts[funcName] += 1; - } - - { - // Combine function samples. - std::map::iterator it; - for (it = funcCounts.begin(); it != funcCounts.end(); ++it) - { - SFunctionSample fs; - fs.function = it->first; - fs.nSamples = it->second; - m_functionSamples.push_back(fs); - } - } - - // Sort vector by number of samples. - std::sort(m_functionSamples.begin(), m_functionSamples.end(), CompareFunctionSamples); - - LogSampledData(); -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::LogSampledData() -{ - int nTotalSamples = m_rawSamples.size(); - - // Log sample info. - CryLogAlways("========================================================================="); - CryLogAlways("= Profiler Output"); - CryLogAlways("========================================================================="); - - float fOnePercent = (float)nTotalSamples / 100; - - float fPercentTotal = 0; - int nSampleSum = 0; - for (uint32 i = 0; i < m_functionSamples.size(); i++) - { - // Calculate percentage. - float fPercent = m_functionSamples[i].nSamples / fOnePercent; - const char* func = m_functionSamples[i].function; - CryLogAlways("%6.2f%% (%4d samples) : %s", fPercent, m_functionSamples[i].nSamples, func); - fPercentTotal += fPercent; - nSampleSum += m_functionSamples[i].nSamples; - } - CryLogAlways("Samples: %d / %d (%.2f%%)", nSampleSum, nTotalSamples, fPercentTotal); - CryLogAlways("========================================================================="); -} - - -#endif // defined(WIN32) diff --git a/Code/CryEngine/CrySystem/Sampler.h b/Code/CryEngine/CrySystem/Sampler.h deleted file mode 100644 index b2c61013a2..0000000000 --- a/Code/CryEngine/CrySystem/Sampler.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SAMPLER_H -#define CRYINCLUDE_CRYSYSTEM_SAMPLER_H -#pragma once - -#ifdef WIN32 - -class CSamplingThread; - -////////////////////////////////////////////////////////////////////////// -// Sampler class is running a second thread which is at regular intervals -// eg 1ms samples main thread and stores current IP in the samples buffers. -// After sampling finishes it can resolve collected IP buffer info to -// the function names and calculated where most of the execution time spent. -////////////////////////////////////////////////////////////////////////// -class CSampler -{ -public: - struct SFunctionSample - { - string function; - uint32 nSamples; // Number of samples per function. - }; - - CSampler(); - ~CSampler(); - - void Start(); - void Stop(); - void Update(); - - // Adds a new sample to the ip buffer, return false if no more samples can be added. - bool AddSample(uint64 ip); - void SetMaxSamples(int nMaxSamples); - - int GetSamplePeriod() const { return m_samplePeriodMs; } - void SetSamplePeriod(int millis) { m_samplePeriodMs = millis; } - -private: - void ProcessSampledData(); - void LogSampledData(); - - // Buffer for IP samples. - std::vector m_rawSamples; - std::vector m_functionSamples; - int m_nMaxSamples; - bool m_bSampling; - bool m_bSamplingFinished; - - int m_samplePeriodMs; - - CSamplingThread* m_pSamplingThread; -}; - -#else //WIN32 - -// Dummy sampler. -class CSampler -{ -public: - void Start() {} - void Stop() {} - void Update() {} - void SetMaxSamples(int) {} - void SetSamplePeriod(int) {} -}; - -#endif // WIN32 - -#endif // CRYINCLUDE_CRYSYSTEM_SAMPLER_H diff --git a/Code/CryEngine/CrySystem/ServerHandler.cpp b/Code/CryEngine/CrySystem/ServerHandler.cpp deleted file mode 100644 index 85b3192650..0000000000 --- a/Code/CryEngine/CrySystem/ServerHandler.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "ServerHandler.h" - -ServerHandler::ServerHandler(const char* bucket, int affinity, int serverTimeout) - : HandlerBase(bucket, affinity) -{ - m_serverTimeout = serverTimeout; - DoScan(); -} - -void ServerHandler::DoScan() -{ - std::set gotIndices; - for (int i = 0; i < m_srvLocks.size(); ++i) - { - gotIndices.insert(m_srvLocks[i]->number); - } - for (int i = 0; i < MAX_CLIENTS_NUM; ++i) - { - if (gotIndices.find(i) == gotIndices.end()) - { - std::unique_ptr lock(new SSyncLock(m_clientLockName, i, false)); - if (lock->IsValid()) - { - std::unique_ptr srv(new SSyncLock(m_serverLockName, i, true)); - if (srv->IsValid()) - { - m_srvLocks.push_back(std::move(srv)); - m_clientLocks.push_back(std::move(lock)); - CryLogAlways("Client %d bound", i); - } - else - { - CryLogAlways("Failed to bind client %d", i); - } - } - } - } - if (!m_clientLocks.empty()) - { - SetAffinity(); - } - m_lastScan = gEnv->pTimer->GetAsyncTime(); -} - -bool ServerHandler::Sync() -{ - if ((gEnv->pTimer->GetAsyncTime() - m_lastScan).GetSeconds() > 1.0f) - { - DoScan(); - } - for (int i = 0; i < m_srvLocks.size(); ) - { - m_srvLocks[i]->Signal(); - if (!m_clientLocks[i]->Wait(m_serverTimeout))//actually if not waited, let's kill it! - { - CryLogAlways("Dropped client %d", m_clientLocks[i]->number); - m_clientLocks[i]->Own(m_clientLockName); - m_clientLocks.erase(m_clientLocks.begin() + i); - m_srvLocks.erase(m_srvLocks.begin() + i); - continue; - } - ++i; - } - return false;//!m_clientLocks.empty(); -} - -#endif // defined(MAP_LOADING_SLICING) diff --git a/Code/CryEngine/CrySystem/ServerHandler.h b/Code/CryEngine/CrySystem/ServerHandler.h deleted file mode 100644 index 37a870efee..0000000000 --- a/Code/CryEngine/CrySystem/ServerHandler.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SERVERHANDLER_H -#define CRYINCLUDE_CRYSYSTEM_SERVERHANDLER_H -#pragma once - -#include "HandlerBase.h" -#include "SyncLock.h" - -struct ServerHandler - : public HandlerBase -{ - ServerHandler(const char* bucket, int affinity, int serverTimeout); - - void DoScan(); - bool Sync(); - -private: - int m_serverTimeout; - std::vector > m_clientLocks; - std::vector > m_srvLocks; - CTimeValue m_lastScan; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_SERVERHANDLER_H diff --git a/Code/CryEngine/CrySystem/ServerThrottle.cpp b/Code/CryEngine/CrySystem/ServerThrottle.cpp deleted file mode 100644 index c183f1a4fc..0000000000 --- a/Code/CryEngine/CrySystem/ServerThrottle.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ServerThrottle.h" -#include "TimeValue.h" -#include "ISystem.h" -#include "ITimer.h" -#include "IConsole.h" - -#if defined(WIN32) -static float ftdiff(const FILETIME& b, const FILETIME& a) -{ - uint64 aa = *reinterpret_cast(&a); - uint64 bb = *reinterpret_cast(&b); - return (bb - aa) * 1e-7f; -} - -class CCPUMonitor -{ -public: - CCPUMonitor(ISystem* pSystem, int nCPUs) - : m_lastUpdate(0.0f) - , m_pTimer(pSystem->GetITimer()) - , m_nCPUs(nCPUs) - { - FILETIME notNeeded; - GetProcessTimes(GetCurrentProcess(), ¬Needed, ¬Needed, &m_lastKernel, &m_lastUser); - } - - float* Update() - { - CTimeValue frameTime = gEnv->pTimer->GetFrameStartTime(); - if (frameTime - m_lastUpdate > 5.0f) - { - m_lastUpdate = frameTime; - - static float result = 0.0f; - - FILETIME kernel, user, cur; - FILETIME notNeeded; - GetSystemTimeAsFileTime(&cur); - GetProcessTimes(GetCurrentProcess(), ¬Needed, ¬Needed, &kernel, &user); - - float sKernel = ftdiff(kernel, m_lastKernel); - float sUser = ftdiff(user, m_lastUser); - float sCur = ftdiff(cur, m_lastTime); - - result = 100 * (sKernel + sUser) / sCur / m_nCPUs; - - m_lastTime = cur; - m_lastKernel = kernel; - m_lastUser = user; - - return &result; - } - return 0; - } - -private: - ITimer* m_pTimer; - CTimeValue m_lastUpdate; - FILETIME m_lastKernel, m_lastUser, m_lastTime; - int m_nCPUs; -}; -#else -class CCPUMonitor -{ -public: - CCPUMonitor(ISystem*, int) {} - - float* Update() { return 0; } -}; -#endif - -CServerThrottle::CServerThrottle(ISystem* pSys, int nCPUs) -{ - m_pCPUMonitor.reset(new CCPUMonitor(pSys, nCPUs)); - m_pDedicatedMaxRate = pSys->GetIConsole()->GetCVar("sv_DedicatedMaxRate"); - m_pDedicatedCPU = pSys->GetIConsole()->GetCVar("sv_DedicatedCPUPercent"); - m_pDedicatedCPUVariance = pSys->GetIConsole()->GetCVar("sv_DedicatedCPUVariance"); - - m_minFPS = 20; - m_maxFPS = 60; - m_nSteps = 8; - m_nCurStep = 0; - - if (m_pDedicatedCPU->GetFVal() >= 1.0f) - { - SetStep(m_nSteps / 2, 0); - } -} - -CServerThrottle::~CServerThrottle() -{ -} - -void CServerThrottle::Update() -{ - float tgtCPU = m_pDedicatedCPU->GetFVal(); - if (tgtCPU < 1) - { - return; - } - if (float* pCPU = m_pCPUMonitor->Update()) - { - float varCPU = m_pDedicatedCPUVariance->GetFVal(); - if (tgtCPU < 5) - { - tgtCPU = 5; - } - else if (tgtCPU > 95) - { - tgtCPU = 95; - } - float minCPU = std::max(tgtCPU - varCPU, tgtCPU / 2.0f); - float maxCPU = std::min(tgtCPU + varCPU, (100.0f + tgtCPU) / 2.0f); - - if (*pCPU > maxCPU) - { - SetStep(m_nCurStep - 1, pCPU); - } - else if (*pCPU < minCPU) - { - SetStep(m_nCurStep + 1, pCPU); - } - } -} - -void CServerThrottle::SetStep(int step, float* pDueToCPU) -{ - if (step < 0) - { - step = 0; - } - else if (step > m_nSteps) - { - step = m_nSteps; - } - if (step != m_nCurStep) - { - float fps = step * (m_maxFPS - m_minFPS) / m_nSteps + m_minFPS; - m_pDedicatedMaxRate->Set(fps); - if (pDueToCPU) - { - CryLog("ServerThrottle: Set framerate to %.1f fps [due to cpu being %d%%]", fps, int(*pDueToCPU + 0.5f)); - } - else - { - CryLog("ServerThrottle: Set framerate to %.1f fps", fps); - } - m_nCurStep = step; - } -} diff --git a/Code/CryEngine/CrySystem/ServerThrottle.h b/Code/CryEngine/CrySystem/ServerThrottle.h deleted file mode 100644 index ce658f4d2e..0000000000 --- a/Code/CryEngine/CrySystem/ServerThrottle.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Handle raising/lowering the frame rate on server -// based upon CPU usage - - -#ifndef CRYINCLUDE_CRYSYSTEM_SERVERTHROTTLE_H -#define CRYINCLUDE_CRYSYSTEM_SERVERTHROTTLE_H -#pragma once - - -struct ISystem; - -class CCPUMonitor; - -class CServerThrottle -{ -public: - CServerThrottle(ISystem* pSys, int nCPUs); - ~CServerThrottle(); - void Update(); - -private: - std::unique_ptr m_pCPUMonitor; - - void SetStep(int step, float* dueToCPU); - - float m_minFPS; - float m_maxFPS; - int m_nSteps; - int m_nCurStep; - ICVar* m_pDedicatedMaxRate; - ICVar* m_pDedicatedCPU; - ICVar* m_pDedicatedCPUVariance; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_SERVERTHROTTLE_H diff --git a/Code/CryEngine/CrySystem/SyncLock.cpp b/Code/CryEngine/CrySystem/SyncLock.cpp deleted file mode 100644 index 4fb30e2ee2..0000000000 --- a/Code/CryEngine/CrySystem/SyncLock.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "SyncLock.h" - -SSyncLock::SSyncLock(const char* name, int id, bool own) -{ - stack_string ss; - ss.Format("%s_%d", name, id); - - Open(ss); - if (own) - { - if (!IsValid()) - { - Create(ss); - number = id; - } - else - { - Close(); - } - } - else - { - number = id; - } -} - -SSyncLock::SSyncLock(const char* name, int minId, int maxId) -{ - ev = 0; - stack_string ss; - for (int i = minId; i < maxId; ++i) - { - ss.Format("%s_%d", name, i); - if (Open(ss)) - { - Close(); - continue; - } - if (Create(ss)) - { - number = i; - } - break; - } -} - -SSyncLock::~SSyncLock() -{ - Close(); -} - -void SSyncLock::Own(const char* name) -{ - o_name.Format("%s_%d", name, number); -} - -#if defined(LINUX) || defined(APPLE) - -bool SSyncLock::Open(const char* name) -{ - ev = sem_open(name, 0); - if (ev != SEM_FAILED) - { - CryLogAlways("Opened semaphore %p %s", ev, name); - } - return IsValid(); -} - -bool SSyncLock::Create(const char* name) -{ - ev = sem_open(name, O_CREAT | O_EXCL, 0777, 0); - if (ev != SEM_FAILED) - { - CryLogAlways("Created semaphore %p %s", ev, name); - } - else - { - CryLogAlways("Failed to create semaphore %s %d", name, errno); - } - return IsValid(); -} - -void SSyncLock::Signal() -{ - if (ev) - { - sem_post(ev); - } -} - -bool SSyncLock::Wait(int ms) -{ - if (!ev) - { - return false; - } - - timespec t = { 0 }; -#if defined(LINUX) - clock_gettime(CLOCK_REALTIME, &t); -#elif defined(APPLE) - // On OSX/iOS there is no sem_timedwait() - // We use repeated sem_trywait() instead - if (sem_trywait(ev) == 0) - { - return true; - } -#endif - - static const long NANOSECS_IN_MSEC = 1000000L; - static const long NANOSECS_IN_SEC = 1000000000L; - - t.tv_sec += ms / 1000; - t.tv_nsec += (ms % 1000) * NANOSECS_IN_MSEC; - if (t.tv_nsec > NANOSECS_IN_SEC) - { - t.tv_nsec -= NANOSECS_IN_SEC; - ++t.tv_sec; - } -#if defined(LINUX) - return sem_timedwait(ev, &t) == 0; //ETIMEDOUT for timeout -#elif defined (APPLE) - // t = time left, interval = max time between tries, elapsed = actual time elapsed during a try - const int num_ms_interval = 50; // poll time, in ms - const timespec interval = { 0, NANOSECS_IN_MSEC * num_ms_interval }; - while (t.tv_sec >= 0 || t.tv_nsec > interval.tv_nsec) - { - timespec remaining; - timespec elapsed = interval; - if (nanosleep(&interval, &remaining) == -1) - { - elapsed.tv_nsec -= remaining.tv_nsec; - } - t.tv_nsec -= elapsed.tv_nsec; - if (t.tv_nsec < 0L) - { - t.tv_nsec += NANOSECS_IN_SEC; - t.tv_sec -= 1; - } - if (sem_trywait(ev) == 0) - { - return true; - } - } - nanosleep(&t, NULL); - return sem_trywait(ev) == 0; -#else -#error Not implemented -#endif -} - -void SSyncLock::Close() -{ - if (ev) - { - sem_close(ev); - ev = nullptr; - if (!o_name.empty()) - { - sem_unlink(o_name); - } - } -} - -#else // defined(LINUX) || defined(APPLE) - -bool SSyncLock::Open(const char* name) -{ - ev = OpenEvent(SYNCHRONIZE, FALSE, name); - if (ev) - { - CryLogAlways("Opened event %p %s", ev, name); - } - return IsValid(); -} - -bool SSyncLock::Create(const char* name) -{ - ev = CreateEvent(NULL, FALSE, FALSE, name); - if (ev) - { - CryLogAlways("Created event %p %s", ev, name); - } - else - { - CryLogAlways("Failed to create event %s", name); - } - return IsValid(); -} - -bool SSyncLock::Wait(int ms) -{ - // CryLogAlways("Waiting %p", ev); - DWORD res = WaitForSingleObject(ev, ms); - if (res != WAIT_OBJECT_0) - { - CryLogAlways("WFS result %d", res); - } - return res == WAIT_OBJECT_0; -} - -void SSyncLock::Signal() -{ - //CryLogAlways("Signaled %p", ev); - if (!SetEvent(ev)) - { - CryLogAlways("Error signalling!"); - } -} - -void SSyncLock::Close() -{ - if (ev) - { - CryLogAlways("Closed event %p", ev); - CloseHandle(ev); - ev = 0; - } -} - -#endif // defined(LINUX) || defined(APPLE) - -bool SSyncLock::IsValid() const -{ - return ev != 0; -} - -#endif // defined(MAP_LOADING_SLICING) diff --git a/Code/CryEngine/CrySystem/SyncLock.h b/Code/CryEngine/CrySystem/SyncLock.h deleted file mode 100644 index 5e22797a6b..0000000000 --- a/Code/CryEngine/CrySystem/SyncLock.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SYNCLOCK_H -#define CRYINCLUDE_CRYSYSTEM_SYNCLOCK_H - -#pragma once - -#if defined(LINUX) || defined(APPLE) -#include -#endif - -struct SSyncLock -{ -#if defined(LINUX) || defined(APPLE) - typedef sem_t* HandleType; -#else - typedef HANDLE HandleType; -#endif - - SSyncLock(const char* name, int id, bool own); - SSyncLock(const char* name, int minId, int maxId); - ~SSyncLock(); - - void Own(const char* name); - bool Open(const char* name); - bool Create(const char* name); - void Signal(); - bool Wait(int ms); - void Close(); - bool IsValid() const; - - HandleType ev; - int number; - string o_name; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_SYNCLOCK_H diff --git a/Code/CryEngine/CrySystem/System.cpp b/Code/CryEngine/CrySystem/System.cpp index b105ec2f27..6fcbc32b72 100644 --- a/Code/CryEngine/CrySystem/System.cpp +++ b/Code/CryEngine/CrySystem/System.cpp @@ -135,25 +135,16 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include "XML/xml.h" #include "XML/ReadWriteXMLSink.h" -#include "PhysRenderer.h" - #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" #include "SystemEventDispatcher.h" -#include "ServerThrottle.h" #include "HMDBus.h" -#include "IZLibCompressor.h" -#include "IZlibDecompressor.h" -#include "ILZ4Decompressor.h" -#include "IZStdDecompressor.h" #include "zlib.h" #include "RemoteConsole/RemoteConsole.h" #include #include -#include "CryWaterMark.h" -WATERMARKDATA(_m); #include #include @@ -170,10 +161,6 @@ WATERMARKDATA(_m); #include #endif -#if USE_STEAM -#include "Steamworks/public/steam/steam_api.h" -#endif - #include #include @@ -185,11 +172,6 @@ VTuneFunction VTPause = NULL; // Define global cvars. SSystemCVars g_cvars; -#include "ITextModeConsole.h" - -////////////////////////////////////////////////////////////////////////// -#include "Validator.h" - #include #include @@ -308,16 +290,9 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_rFullscreen = NULL; m_sysNoUpdate = NULL; m_pProcess = NULL; - - m_pValidator = NULL; m_pCmdLine = NULL; - m_pDefaultValidator = NULL; m_pLevelSystem = NULL; m_pViewSystem = NULL; - m_pIZLibCompressor = NULL; - m_pIZLibDecompressor = NULL; - m_pILZ4Decompressor = NULL; - m_pIZStdDecompressor = nullptr; m_pLocalizationManager = NULL; #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_2 @@ -332,14 +307,12 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_sys_memory_debug = NULL; m_sysWarnings = NULL; m_sysKeyboard = NULL; - m_sys_GraphicsQuality = NULL; m_sys_firstlaunch = NULL; m_sys_enable_budgetmonitoring = NULL; m_sys_preload = NULL; // m_sys_filecache = NULL; m_gpu_particle_physics = NULL; - m_pCpu = NULL; m_bInitializedSuccessfully = false; m_bRelaunch = false; @@ -371,7 +344,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_pXMLUtils = new CXmlUtils(this); - m_pTextModeConsole = NULL; if (!AZ::AllocatorInstance::IsReady()) { @@ -390,7 +362,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_eRuntimeState = ESYSTEM_EVENT_LEVEL_UNLOAD; m_bHasRenderedErrorMessage = false; - m_bIsSteamInitialized = false; m_pDataProbe = nullptr; #if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_MESSAGE_HANDLER @@ -509,14 +480,6 @@ void CSystem::ShutDown() GetIRemoteConsole()->Stop(); } - // clean up properly the console - if (m_pTextModeConsole) - { - m_pTextModeConsole->OnShutdown(); - } - - SAFE_DELETE(m_pTextModeConsole); - if (m_sys_firstlaunch) { m_sys_firstlaunch->Set("0"); @@ -566,10 +529,6 @@ void CSystem::ShutDown() { ((CXConsole*)m_env.pConsole)->FreeRenderResources(); } - SAFE_RELEASE(m_pIZLibCompressor); - SAFE_RELEASE(m_pIZLibDecompressor); - SAFE_RELEASE(m_pILZ4Decompressor); - SAFE_RELEASE(m_pIZStdDecompressor); SAFE_RELEASE(m_pViewSystem); SAFE_RELEASE(m_pLevelSystem); @@ -596,7 +555,6 @@ void CSystem::ShutDown() SAFE_RELEASE(m_sysWarnings); SAFE_RELEASE(m_sysKeyboard); - SAFE_RELEASE(m_sys_GraphicsQuality); SAFE_RELEASE(m_sys_firstlaunch); SAFE_RELEASE(m_sys_enable_budgetmonitoring); @@ -608,13 +566,8 @@ void CSystem::ShutDown() SAFE_RELEASE(m_sys_min_step); SAFE_RELEASE(m_sys_max_step); - SAFE_DELETE(m_pDefaultValidator); - m_pValidator = nullptr; - SAFE_DELETE(m_pLocalizationManager); - SAFE_DELETE(m_pCpu); - delete m_pCmdLine; m_pCmdLine = 0; @@ -941,13 +894,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) //update time subsystem m_Time.UpdateOnFrameStart(); - ////////////////////////////////////////////////////////////////////// - // update rate limiter for dedicated server - if (m_pServerThrottle.get()) - { - m_pServerThrottle->Update(); - } - ////////////////////////////////////////////////////////////////////// //update console system if (m_env.pConsole) @@ -1277,21 +1223,6 @@ void CSystem::WarningV(EValidatorModule module, EValidatorSeverity severity, int m_env.pLog->LogWithType(ltype, flags | VALIDATOR_FLAG_SKIP_VALIDATOR, "%s", szBuffer); } - //if(file) - //m_env.pLog->LogWithType( ltype, " ... caused by file '%s'",file); - - if (m_pValidator && (flags & VALIDATOR_FLAG_SKIP_VALIDATOR) == 0) - { - SValidatorRecord record; - record.file = file; - record.text = szBuffer; - record.module = module; - record.severity = severity; - record.flags = flags; - record.assetScope = m_env.pLog->GetAssetScopeString(); - m_pValidator->Report(record); - } - if (bDbgBreak && g_cvars.sys_error_debugbreak) { AZ::Debug::Trace::Break(); @@ -1412,12 +1343,6 @@ void CSystem::ExecuteCommandLine(bool deferred) m_executedCommandLine = true; - // auto detect system spec (overrides profile settings) - if (m_pCmdLine->FindArg(eCLAT_Pre, "autodetect")) - { - AutoDetectSpec(false); - } - // execute command line arguments e.g. +g_gametype ASSAULT +map "testy" ICmdLine* pCmdLine = GetICmdLine(); @@ -1446,50 +1371,6 @@ void CSystem::ExecuteCommandLine(bool deferred) //gEnv->pConsole->ExecuteString("sys_RestoreSpec test*"); // to get useful debugging information about current spec settings to the log file } -ITextModeConsole* CSystem::GetITextModeConsole() -{ - if (m_bDedicatedServer) - { - return m_pTextModeConsole; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -ESystemConfigSpec CSystem::GetConfigSpec(bool bClient) -{ - if (bClient) - { - if (m_sys_GraphicsQuality) - { - return (ESystemConfigSpec)m_sys_GraphicsQuality->GetIVal(); - } - return CONFIG_VERYHIGH_SPEC; // highest spec. - } - else - { - return m_nServerConfigSpec; - } -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::SetConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient) -{ - if (bClient) - { - if (m_sys_GraphicsQuality) - { - SetConfigPlatform(platform); - m_sys_GraphicsQuality->Set(static_cast(spec)); - } - } - else - { - m_nServerConfigSpec = spec; - } -} - ////////////////////////////////////////////////////////////////////////// ESystemConfigSpec CSystem::GetMaxConfigSpec() const { @@ -1539,49 +1420,6 @@ void CProfilingSystem::VTunePause() #endif } -bool CSystem::SteamInit() -{ -#if USE_STEAM - if (m_bIsSteamInitialized) - { - return true; - } - - AZStd::string_view exePath; - AZ::ComponentApplicationBus::BroadcastResult(exePath, &AZ::ComponentApplicationRequests::GetExecutableFolder); - - //////////////////////////////////////////////////////////////////////////// - // ** DEVELOPMENT ONLY ** - creates the appropriate steam_appid.txt file needed to call SteamAPI_Init() -#if !defined(RELEASE) - AZStd::string appidPath = AZStd::string::format("%.*s/steam_appid.txt", aznumeric_cast(exePath.size()), exePath.data()); - azfopen(&pSteamAppID, appidPath.c_str(), "wt"); - fprintf(pSteamAppID, "%d", g_cvars.sys_steamAppId); - fclose(pSteamAppID); -#endif // !defined(RELEASE) - // ** END DEVELOPMENT ONLY ** - //////////////////////////////////////////////////////////////////////////// - - if (!SteamAPI_Init()) - { - CryLog("[STEAM] SteamApi_Init failed"); - return false; - } - - //////////////////////////////////////////////////////////////////////////// - // ** DEVELOPMENT ONLY ** - deletes the appropriate steam_appid.txt file as it's no longer needed -#if !defined(RELEASE) - remove(appidPath.c_str()); -#endif // !defined(RELEASE) - // ** END DEVELOPMENT ONLY ** - //////////////////////////////////////////////////////////////////////////// - - m_bIsSteamInitialized = true; - return true; -#else - return false; -#endif -} - ////////////////////////////////////////////////////////////////////// void CSystem::OnLanguageCVarChanged(ICVar* language) { diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index 2e272c2f9e..631d84d934 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -23,12 +23,10 @@ #include "CmdLine.h" #include "CryName.h" -#include "CPUDetect.h" #include #include "RenderBus.h" #include -#include #include @@ -38,8 +36,6 @@ namespace AzFramework } struct IConsoleCmdArgs; -class CServerThrottle; -struct IZLibCompressor; class CWatchdogThread; #if defined(AZ_RESTRICTED_PLATFORM) @@ -50,18 +46,6 @@ class CWatchdogThread; #define SYSTEM_H_SECTION_4 4 #endif -#if defined(ANDROID) -#define USE_ANDROIDCONSOLE -#elif defined(MAC) // || defined(LINUX) -#define USE_UNIXCONSOLE -#elif defined(IOS) -#define USE_IOSCONSOLE -#elif defined(WIN32) || defined(WIN64) -#define USE_WINDOWSCONSOLE -#else -#define USE_NULLCONSOLE -#endif - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_H_SECTION_1 #include AZ_RESTRICTED_FILE(System_h) @@ -185,20 +169,12 @@ typedef void* WIN_HMODULE; typedef void* WIN_HMODULE; #endif -#if !defined(CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM) -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync); -#else -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpyDelegate(void* dst, const void* src, size_t size, int nFlags, volatile int* sync); -#endif - - //forward declarations namespace Audio { struct IAudioSystem; struct IMusicSystem; } // namespace Audio -struct SDefaultValidator; struct IDataProbe; #define PHSYICS_OBJECT_ENTITY 0 @@ -232,7 +208,6 @@ struct SSystemCVars int sys_no_crash_dialog; int sys_no_error_report_window; int sys_dump_aux_threads; - int sys_WER; int sys_dump_type; int sys_ai; int sys_entitysystem; @@ -255,12 +230,6 @@ struct SSystemCVars int sys_FilesystemCaseSensitivity; int sys_deferAudioUpdateOptim; -#if USE_STEAM -#ifndef RELEASE - int sys_steamAppId; -#endif // RELEASE - int sys_useSteamCloudForPlatformSaving; -#endif // USE_STEAM AZ::IO::ArchiveVars archiveVars; @@ -343,16 +312,11 @@ public: virtual void DoWorkDuringOcclusionChecks(); virtual bool NeedDoWorkDuringOcclusionChecks() { return m_bNeedDoWorkDuringOcclusionChecks; } - //Called when the renderer finishes rendering the scene - void OnScene3DEnd() override; - //////////////////////////////////////////////////////////////////////// // CrySystemRequestBus interface implementation ISystem* GetCrySystem() override; //////////////////////////////////////////////////////////////////////// - virtual bool SteamInit(); - void Relaunch(bool bRelaunch); bool IsRelaunch() const { return m_bRelaunch; }; @@ -374,17 +338,11 @@ public: ICryFont* GetICryFont(){ return m_env.pCryFont; } ILog* GetILog(){ return m_env.pLog; } ICmdLine* GetICmdLine(){ return m_pCmdLine; } - IValidator* GetIValidator() { return m_pValidator; }; INameTable* GetINameTable() { return m_env.pNameTable; }; IViewSystem* GetIViewSystem(); ILevelSystem* GetILevelSystem(); ISystemEventDispatcher* GetISystemEventDispatcher() { return m_pSystemEventDispatcher; } - ITextModeConsole* GetITextModeConsole(); IProfilingSystem* GetIProfilingSystem() { return &m_ProfilingSystem; } - IZLibCompressor* GetIZLibCompressor() { return m_pIZLibCompressor; } - IZLibDecompressor* GetIZLibDecompressor() { return m_pIZLibDecompressor; } - ILZ4Decompressor* GetLZ4Decompressor() { return m_pILZ4Decompressor; } - IZStdDecompressor* GetZStdDecompressor() { return m_pIZStdDecompressor; } ////////////////////////////////////////////////////////////////////////// // retrieves the perlin noise singleton instance CPNoise3* GetNoiseGen(); @@ -406,45 +364,6 @@ public: void SetViewCamera(CCamera& Camera){ m_ViewCamera = Camera; } CCamera& GetViewCamera() { return m_ViewCamera; } - virtual int GetCPUFlags() - { - int Flags = 0; - if (!m_pCpu) - { - return Flags; - } - if (m_pCpu->hasMMX()) - { - Flags |= CPUF_MMX; - } - if (m_pCpu->hasSSE()) - { - Flags |= CPUF_SSE; - } - if (m_pCpu->hasSSE2()) - { - Flags |= CPUF_SSE2; - } - if (m_pCpu->has3DNow()) - { - Flags |= CPUF_3DNOW; - } - if (m_pCpu->hasF16C()) - { - Flags |= CPUF_F16C; - } - - return Flags; - } - virtual int GetLogicalCPUCount() - { - if (m_pCpu) - { - return m_pCpu->GetLogicalCPUCount(); - } - return 0; - } - void IgnoreUpdates(bool bIgnore) { m_bIgnoreUpdates = bIgnore; }; void SetIProcess(IProcess* process); @@ -455,8 +374,6 @@ public: void SleepIfNeeded(); - virtual void DisplayErrorMessage(const char* acMessage, float fTime, const float* pfColor = 0, bool bHardError = true); - virtual void FatalError(const char* format, ...) PRINTF_PARAMS(2, 3); virtual void ReportBug(const char* format, ...) PRINTF_PARAMS(2, 3); // Validator Warning. @@ -471,8 +388,6 @@ public: ////////////////////////////////////////////////////////////////////////// virtual void SaveConfiguration(); virtual void LoadConfiguration(const char* sFilename, ILoadConfigurationEntrySink* pSink = 0, bool warnIfMissing = true); - virtual ESystemConfigSpec GetConfigSpec(bool bClient = true); - virtual void SetConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient); virtual ESystemConfigSpec GetMaxConfigSpec() const; virtual ESystemConfigPlatform GetConfigPlatform() const; virtual void SetConfigPlatform(ESystemConfigPlatform platform); @@ -567,24 +482,7 @@ public: virtual bool GetForceNonDevMode() const; virtual bool WasInDevMode() const { return m_bWasInDevMode; }; virtual bool IsDevMode() const { return m_bInDevMode && !GetForceNonDevMode(); } - virtual bool IsMODValid(const char* szMODName) const - { - if (!szMODName || strstr(szMODName, ".") || strstr(szMODName, "\\")) - { - return (false); - } - return (true); - } - virtual void AutoDetectSpec(bool detectResolution); - virtual void AsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync) - { -#if !defined(CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM) - cryAsyncMemcpy(dst, src, size, nFlags, sync); -#else - cryAsyncMemcpyDelegate(dst, src, size, nFlags, sync); -#endif - } virtual void SetConsoleDrawEnabled(bool enabled) { m_bDrawConsole = enabled; } virtual void SetUIDrawEnabled(bool enabled) { m_bDrawUI = enabled; } @@ -594,18 +492,11 @@ public: //! recreates the variable if necessary ICVar* attachVariable (const char* szVarName, int* pContainer, const char* szComment, int dwFlags = 0); - CCpuFeatures* GetCPUFeatures() { return m_pCpu; }; - const CTimeValue& GetLastTickTime(void) const { return m_lastTickTime; } const ICVar* GetDedicatedMaxRate(void) const { return m_svDedicatedMaxRate; } std::shared_ptr CreateLocalFileIO(); - // Gets the dimensions (in pixels) of the primary physical display. - // Returns true if this info is available, returns false otherwise. - bool GetPrimaryPhysicalDisplayDimensions(int& o_widthPixels, int& o_heightPixels); - bool IsTablet(); - private: // ------------------------------------------------------ // System environment. @@ -623,13 +514,10 @@ private: // ------------------------------------------------------ bool m_bPreviewMode; //!< If running in Preview mode. bool m_bDedicatedServer; //!< If running as Dedicated server. bool m_bIgnoreUpdates; //!< When set to true will ignore Update and Render calls, - IValidator* m_pValidator; //!< Pointer to validator interface. bool m_bForceNonDevMode; //!< true when running on a cheat protected server or a client that is connected to it (not used in singlplayer) bool m_bWasInDevMode; //!< Set to true if was in dev mode. bool m_bInDevMode; //!< Set to true if was in dev mode. bool m_bGameFolderWritable;//!< True when verified that current game folder have write access. - SDefaultValidator* m_pDefaultValidator; //!< - CCpuFeatures* m_pCpu; //!< CPU features int m_ttMemStatSS; //!< Time to memstat screenshot bool m_bDrawConsole; //!< Set to true if OK to draw the console. bool m_bDrawUI; //!< Set to true if OK to draw UI. @@ -661,18 +549,6 @@ private: // ------------------------------------------------------ //! System to manage views. IViewSystem* m_pViewSystem; - //! System to access zlib compressor - IZLibCompressor* m_pIZLibCompressor; - - //! System to access zlib decompressor - IZLibDecompressor* m_pIZLibDecompressor; - - //! System to access lz4 hc decompressor - ILZ4Decompressor* m_pILZ4Decompressor; - - //! System access to zstd decompressor - IZStdDecompressor* m_pIZStdDecompressor; - // XML Utils interface. class CXmlUtils* m_pXMLUtils; @@ -736,7 +612,6 @@ private: // ------------------------------------------------------ ICVar* m_sysWarnings; //!< might be 0, "sys_warnings" - Treat warning as errors. ICVar* m_cvSSInfo; //!< might be 0, "sys_SSInfo" 0/1 - get file sourcesafe info ICVar* m_svDedicatedMaxRate; - ICVar* m_sys_GraphicsQuality; ICVar* m_sys_firstlaunch; ICVar* m_sys_asset_processor; ICVar* m_sys_load_files_to_memory; @@ -777,8 +652,6 @@ private: // ------------------------------------------------------ ESystemConfigSpec m_nMaxConfigSpec; ESystemConfigPlatform m_ConfigPlatform; - std::unique_ptr m_pServerThrottle; - CProfilingSystem m_ProfilingSystem; // Pause mode. @@ -803,9 +676,6 @@ public: virtual const SFileVersion& GetProductVersion(); virtual const SFileVersion& GetBuildVersion(); - bool CompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize, int level); - bool DecompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize); - bool InitVTuneProfiler(); void OpenBasicPaks(); @@ -856,7 +726,6 @@ public: protected: // ------------------------------------------------------------- CCmdLine* m_pCmdLine; - ITextModeConsole* m_pTextModeConsole; string m_currentLanguageAudio; string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_es3.cfg or system_android_opengl.cfg or system_windows_pc.cfg @@ -878,15 +747,7 @@ protected: // ------------------------------------------------------------- ESystemEvent m_eRuntimeState; bool m_bIsAsserting; - friend struct SDefaultValidator; - friend struct SCryEngineFoldersLoader; - // friend void ScreenshotCmd( IConsoleCmdArgs *pParams ); - - bool m_bIsSteamInitialized; - std::vector m_windowMessageHandlers; bool m_initedOSAllocator = false; bool m_initedSysAllocator = false; - - AZStd::unique_ptr m_thermalInfoHandler; }; diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index 239f670453..afc5bd9144 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -12,7 +12,7 @@ // Original file Copyright Crytek GMBH or its affiliates, used under license. #include "CrySystem_precompiled.h" -#include "SystemInit.h" +#include "System.h" #if defined(AZ_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) #undef AZ_RESTRICTED_SECTION @@ -95,17 +95,8 @@ #include "XConsole.h" #include "Log.h" #include "XML/xml.h" -#include "PhysRenderer.h" #include "LocalizedStringManager.h" #include "SystemEventDispatcher.h" -#include "Validator.h" -#include "ServerThrottle.h" -#include "SystemCFG.h" -#include "AutoDetectSpec.h" -#include "ZLibCompressor.h" -#include "ZLibDecompressor.h" -#include "ZStdDecompressor.h" -#include "LZ4Decompressor.h" #include "LevelSystem/LevelSystem.h" #include "LevelSystem/SpawnableLevelSystem.h" #include "ViewSystem/ViewSystem.h" @@ -114,29 +105,10 @@ #include #include -#if USE_STEAM -#include "Steamworks/public/steam/steam_api.h" -#include "Steamworks/public/steam/isteamremotestorage.h" -#endif - -#if defined(IOS) -#include "IOSConsole.h" -#endif - #if defined(ANDROID) #include - #include "AndroidConsole.h" -#if !defined(AZ_RELEASE_BUILD) - #include "ThermalInfoAndroid.h" -#endif // !defined(AZ_RELEASE_BUILD) #endif -#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS) -#include "MobileDetectSpec.h" -#endif - -#include "WindowsConsole.h" - #if defined(EXTERNAL_CRASH_REPORTING) #include #endif @@ -150,10 +122,6 @@ # include #endif -#ifdef WIN32 -extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers); -#endif - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_14 #include AZ_RESTRICTED_FILE(SystemInit_cpp) @@ -196,12 +164,6 @@ void CryEngineSignalHandler(int signal) #endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER -#if defined(USE_UNIXCONSOLE) -#if defined(LINUX) && !defined(ANDROID) -CUNIXConsole* pUnixConsole; -#endif -#endif // USE_UNIXCONSOLE - ////////////////////////////////////////////////////////////////////////// #define DEFAULT_LOG_FILENAME "@log@/Log.txt" @@ -333,26 +295,6 @@ static void CmdCrashTest(IConsoleCmdArgs* pArgs) } AZ_POP_DISABLE_WARNING -#if USE_STEAM -////////////////////////////////////////////////////////////////////////// -static void CmdWipeSteamCloud(IConsoleCmdArgs* pArgs) -{ - if (!gEnv->pSystem->SteamInit()) - { - return; - } - - int32 fileCount = SteamRemoteStorage()->GetFileCount(); - for (int i = 0; i < fileCount; i++) - { - int32 size = 0; - const char* name = SteamRemoteStorage()->GetFileNameAndSize(i, &size); - bool success = SteamRemoteStorage()->FileDelete(name); - CryLog("Deleting file: %s - success: %d", name, success); - } -} -#endif - ////////////////////////////////////////////////////////////////////////// struct SysSpecOverrideSink : public ILoadConfigurationEntrySink @@ -466,275 +408,6 @@ static ESystemConfigPlatform GetDevicePlatform() #endif } -static void GetSpecConfigFileToLoad(ICVar* pVar, AZStd::string& cfgFile, ESystemConfigPlatform platform) -{ - switch (platform) - { - case CONFIG_PC: - cfgFile = "pc"; - break; - case CONFIG_ANDROID: - cfgFile = "android"; - break; - case CONFIG_IOS: - cfgFile = "ios"; - break; -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, jasper) -#endif -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, provo) -#endif -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, salem) -#endif - case CONFIG_OSX_METAL: - cfgFile = "osx_metal"; - break; - case CONFIG_OSX_GL: - // Spec level is hardcoded for these platforms - cfgFile = ""; - return; - default: - AZ_Assert(false, "Platform not supported"); - return; - } - - switch (pVar->GetIVal()) - { - case CONFIG_AUTO_SPEC: - // Spec level is set for autodetection - cfgFile = ""; - break; - case CONFIG_LOW_SPEC: - cfgFile += "_low.cfg"; - break; - case CONFIG_MEDIUM_SPEC: - cfgFile += "_medium.cfg"; - break; - case CONFIG_HIGH_SPEC: - cfgFile += "_high.cfg"; - break; - case CONFIG_VERYHIGH_SPEC: -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_4 -#include AZ_RESTRICTED_FILE(SystemInit_cpp) -#endif - cfgFile += "_veryhigh.cfg"; - break; - default: - AZ_Assert(false, "Invalid value for r_GraphicsQuality"); - break; - } -} - -static void LoadDetectedSpec(ICVar* pVar) -{ - CDebugAllowFileAccess ignoreInvalidFileAccess; - SysSpecOverrideSink sysSpecOverrideSink; - ILoadConfigurationEntrySink* pSysSpecOverrideSinkConsole = nullptr; - -#if !defined(CONSOLE) - SysSpecOverrideSinkConsole sysSpecOverrideSinkConsole; - pSysSpecOverrideSinkConsole = &sysSpecOverrideSinkConsole; -#endif - - // g_sysSpecChanged = true; - static int no_recursive = false; - if (no_recursive) - { - return; - } - no_recursive = true; - - int spec = pVar->GetIVal(); - ESystemConfigPlatform platform = GetDevicePlatform(); - if (gEnv->IsEditor()) - { - ESystemConfigPlatform configPlatform = GetISystem()->GetConfigPlatform(); - // Check if the config platform is set first. - if (configPlatform != CONFIG_INVALID_PLATFORM) - { - platform = configPlatform; - } - } - - AZStd::string configFile; - GetSpecConfigFileToLoad(pVar, configFile, platform); - if (configFile.length()) - { - GetISystem()->LoadConfiguration(configFile.c_str(), platform == CONFIG_PC ? &sysSpecOverrideSink : pSysSpecOverrideSinkConsole); - } - else - { - // Automatically sets graphics quality - spec level autodetected for ios/android, hardcoded for all other platforms - - switch (platform) - { - case CONFIG_PC: - { - // TODO: add support for autodetection - pVar->Set(CONFIG_VERYHIGH_SPEC); - GetISystem()->LoadConfiguration("pc_veryhigh.cfg", &sysSpecOverrideSink); - break; - } - case CONFIG_ANDROID: - { -#if defined(AZ_PLATFORM_ANDROID) - AZStd::string file; - if (MobileSysInspect::GetAutoDetectedSpecName(file)) - { - if (file == "android_low.cfg") - { - pVar->Set(CONFIG_LOW_SPEC); - } - if (file == "android_medium.cfg") - { - pVar->Set(CONFIG_MEDIUM_SPEC); - } - if (file == "android_high.cfg") - { - pVar->Set(CONFIG_HIGH_SPEC); - } - if (file == "android_veryhigh.cfg") - { - pVar->Set(CONFIG_VERYHIGH_SPEC); - } - GetISystem()->LoadConfiguration(file.c_str(), pSysSpecOverrideSinkConsole); - } - else - { - float totalRAM = MobileSysInspect::GetDeviceRamInGB(); - if (totalRAM < MobileSysInspect::LOW_SPEC_RAM) - { - pVar->Set(CONFIG_LOW_SPEC); - GetISystem()->LoadConfiguration("android_low.cfg", pSysSpecOverrideSinkConsole); - } - else if (totalRAM < MobileSysInspect::MEDIUM_SPEC_RAM) - { - pVar->Set(CONFIG_MEDIUM_SPEC); - GetISystem()->LoadConfiguration("android_medium.cfg", pSysSpecOverrideSinkConsole); - } - else if (totalRAM < MobileSysInspect::HIGH_SPEC_RAM) - { - pVar->Set(CONFIG_HIGH_SPEC); - GetISystem()->LoadConfiguration("android_high.cfg", pSysSpecOverrideSinkConsole); - } - else - { - pVar->Set(CONFIG_VERYHIGH_SPEC); - GetISystem()->LoadConfiguration("android_veryhigh.cfg", pSysSpecOverrideSinkConsole); - } - } -#endif - break; - } - case CONFIG_IOS: - { -#if defined(AZ_PLATFORM_IOS) - AZStd::string file; - if (MobileSysInspect::GetAutoDetectedSpecName(file)) - { - if (file == "ios_low.cfg") - { - pVar->Set(CONFIG_LOW_SPEC); - } - if (file == "ios_medium.cfg") - { - pVar->Set(CONFIG_MEDIUM_SPEC); - } - if (file == "ios_high.cfg") - { - pVar->Set(CONFIG_HIGH_SPEC); - } - if (file == "ios_veryhigh.cfg") - { - pVar->Set(CONFIG_VERYHIGH_SPEC); - } - GetISystem()->LoadConfiguration(file.c_str(), pSysSpecOverrideSinkConsole); - } - else - { - pVar->Set(CONFIG_MEDIUM_SPEC); - GetISystem()->LoadConfiguration("ios_medium.cfg", pSysSpecOverrideSinkConsole); - } -#endif - break; - } -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_5 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, jasper) -#endif -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_5 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, provo) -#endif -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_5 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, salem) -#endif - - case CONFIG_OSX_GL: - { - pVar->Set(CONFIG_HIGH_SPEC); - GetISystem()->LoadConfiguration("osx_gl.cfg", pSysSpecOverrideSinkConsole); - break; - } - case CONFIG_OSX_METAL: - { - pVar->Set(CONFIG_HIGH_SPEC); - GetISystem()->LoadConfiguration("osx_metal_high.cfg", pSysSpecOverrideSinkConsole); - break; - } - default: - AZ_Assert(false, "Platform not supported"); - break; - } - } - - // make sure editor specific settings are not changed - if (gEnv->IsEditor()) - { - GetISystem()->LoadConfiguration("editor.cfg"); - } - - // override cvars just loaded based on current API version/GPU - - GetISystem()->SetConfigSpec(static_cast(spec), platform, false); - - no_recursive = false; -} - -////////////////////////////////////////////////////////////////////////// -struct SCryEngineLanguageConfigLoader - : public ILoadConfigurationEntrySink -{ - CSystem* m_pSystem; - string m_language; - string m_pakFile; - - SCryEngineLanguageConfigLoader(CSystem* pSystem) { m_pSystem = pSystem; } - void Load(const char* sCfgFilename) - { - CSystemConfiguration cfg(sCfgFilename, m_pSystem, this); // Parse folders config file. - } - virtual void OnLoadConfigurationEntry(const char* szKey, const char* szValue, [[maybe_unused]] const char* szGroup) - { - if (azstricmp(szKey, "Language") == 0) - { - m_language = szValue; - } - else if (azstricmp(szKey, "PAK") == 0) - { - m_pakFile = szValue; - } - } - virtual void OnLoadConfigurationEntry_End() {} -}; - ////////////////////////////////////////////////////////////////////////// #if !defined(AZ_MONOLITHIC_BUILD) @@ -1392,96 +1065,6 @@ string GetUniqueLogFileName(string logFileName) return logFileName; } - -#if defined(WIN32) || defined(WIN64) -static wstring GetErrorStringUnsupportedCPU() -{ - static const wchar_t s_EN[] = L"Unsupported CPU detected. CPU needs to support SSE, SSE2, SSE3 and SSE4.1."; - static const wchar_t s_FR[] = { 0 }; - static const wchar_t s_RU[] = { 0 }; - static const wchar_t s_ES[] = { 0 }; - static const wchar_t s_DE[] = { 0 }; - static const wchar_t s_IT[] = { 0 }; - - const size_t fullLangID = (size_t) GetKeyboardLayout(0); - const size_t primLangID = fullLangID & 0x3FF; - const wchar_t* pFmt = s_EN; - - /*switch (primLangID) - { - case 0x07: // German - pFmt = s_DE; - break; - case 0x0a: // Spanish - pFmt = s_ES; - break; - case 0x0c: // French - pFmt = s_FR; - break; - case 0x10: // Italian - pFmt = s_IT; - break; - case 0x19: // Russian - pFmt = s_RU; - break; - case 0x09: // English - default: - break; - }*/ - wchar_t msg[1024]; - msg[0] = L'\0'; - msg[sizeof(msg) / sizeof(msg[0]) - 1] = L'\0'; - azsnwprintf(msg, sizeof(msg) / sizeof(msg[0]) - 1, pFmt); - return msg; -} -#endif - -static bool CheckCPURequirements([[maybe_unused]] CCpuFeatures* pCpu, [[maybe_unused]] CSystem* pSystem) -{ -#if defined(WIN32) || defined(WIN64) - if (!gEnv->IsDedicated()) - { - if (!(pCpu->hasSSE() && pCpu->hasSSE2() && pCpu->hasSSE3() && pCpu->hasSSE41())) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Unsupported CPU! Need SSE, SSE2, SSE3 and SSE4.1 instructions to be available."); - -#if !defined(_RELEASE) - const bool allowPrompts = pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "noprompt") == 0; -#else - const bool allowPrompts = true; -#endif // !defined(_RELEASE) - if (allowPrompts) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Asking user if they wish to continue..."); - const int mbRes = MessageBoxW(0, GetErrorStringUnsupportedCPU().c_str(), L"Open 3D Engine", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_DEFAULT_DESKTOP_ONLY); - if (mbRes == IDCANCEL) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to cancel startup."); - return false; - } - } - else - { -#if !defined(_RELEASE) - const bool obeyCPUCheck = pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "anycpu") == 0; -#else - const bool obeyCPUCheck = true; -#endif // !defined(_RELEASE) - if (obeyCPUCheck) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "No prompts allowed and unsupported CPU check active. Treating unsupported CPU as error and exiting."); - return false; - } - } - - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to continue despite unsupported CPU!"); - } - } -#endif - return true; -} - - class AzConsoleToCryConsoleBinder final { public: @@ -1692,16 +1275,6 @@ AZ_POP_DISABLE_WARNING } } - if (!startupParams.pValidator) - { - m_pDefaultValidator = new SDefaultValidator(this); - m_pValidator = m_pDefaultValidator; - } - else - { - m_pValidator = startupParams.pValidator; - } - #if !defined(_RELEASE) if (!m_bDedicatedServer) { @@ -1717,79 +1290,6 @@ AZ_POP_DISABLE_WARNING gEnv->SetIsDedicated(m_bDedicatedServer); #endif -#if !defined(CONSOLE) -#if !defined(_RELEASE) - bool isDaemonMode = (m_pCmdLine->FindArg(eCLAT_Pre, "daemon") != 0); -#endif // !defined(_RELEASE) - -#if defined(USE_DEDICATED_SERVER_CONSOLE) - -#if !defined(_RELEASE) - bool isSimpleConsole = (m_pCmdLine->FindArg(eCLAT_Pre, "simple_console") != 0); - - if (!(isDaemonMode || isSimpleConsole)) -#endif // !defined(_RELEASE) - { -#if defined(USE_UNIXCONSOLE) - CUNIXConsole* pConsole = new CUNIXConsole(); -#if defined(LINUX) - pUnixConsole = pConsole; -#endif -#elif defined(USE_IOSCONSOLE) - CIOSConsole* pConsole = new CIOSConsole(); -#elif defined(USE_WINDOWSCONSOLE) - CWindowsConsole* pConsole = new CWindowsConsole(); -#elif defined(USE_ANDROIDCONSOLE) - CAndroidConsole* pConsole = new CAndroidConsole(); -#else - CNULLConsole* pConsole = new CNULLConsole(false); -#endif - m_pTextModeConsole = static_cast(pConsole); - - if (m_pUserCallback == nullptr && m_bDedicatedServer) - { - char headerString[128]; - m_pUserCallback = pConsole; - pConsole->SetRequireDedicatedServer(true); - - azstrcpy( - headerString, - AZ_ARRAY_SIZE(headerString), - "Open 3D Engine - " -#if defined(LINUX) - "Linux " -#elif defined(MAC) - "MAC " -#elif defined(IOS) - "iOS " -#endif - "Dedicated Server" - " - Version "); - - char* str = headerString + strlen(headerString); - GetProductVersion().ToString(str, sizeof(headerString) - (str - headerString)); - pConsole->SetHeader(headerString); - } - } -#if !defined(_RELEASE) - else -#endif -#endif - -#if !(defined(USE_DEDICATED_SERVER_CONSOLE) && defined(_RELEASE)) - { - CNULLConsole* pConsole = new CNULLConsole(isDaemonMode); - m_pTextModeConsole = pConsole; - - if (m_pUserCallback == nullptr && m_bDedicatedServer) - { - m_pUserCallback = pConsole; - } - } -#endif - -#endif // !defined(CONSOLE) - { EBUS_EVENT(CrySystemEventBus, OnCrySystemPreInitialize, *this, startupParams); @@ -1909,9 +1409,6 @@ AZ_POP_DISABLE_WARNING // Need to load the engine.pak that includes the config files needed during initialization m_env.pCryPak->OpenPack("@assets@", "Engine.pak"); -#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS) - MobileSysInspect::LoadDeviceSpecMapping(); -#endif InitFileSystem_LoadEngineFolders(startupParams); @@ -1920,16 +1417,6 @@ AZ_POP_DISABLE_WARNING GetIRemoteConsole()->Update(); #endif - // CPU features detection. - m_pCpu = new CCpuFeatures; - m_pCpu->Detect(); - - // Check hard minimum CPU requirements - if (!CheckCPURequirements(m_pCpu, this)) - { - return false; - } - InlineInitializationProcessing("CSystem::Init Load Engine Folders"); ////////////////////////////////////////////////////////////////////////// @@ -1998,14 +1485,6 @@ AZ_POP_DISABLE_WARNING InlineInitializationProcessing("CSystem::Init LoadConfigurations"); -#ifdef WIN32 - if ((g_cvars.sys_WER)) - { - SetUnhandledExceptionFilter(CryEngineExceptionFilterWER); - } -#endif - - ////////////////////////////////////////////////////////////////////////// // Localization ////////////////////////////////////////////////////////////////////////// @@ -2014,10 +1493,6 @@ AZ_POP_DISABLE_WARNING } InlineInitializationProcessing("CSystem::Init InitLocalizations"); -#if !defined(AZ_RELEASE_BUILD) && defined(AZ_PLATFORM_ANDROID) - m_thermalInfoHandler = AZStd::make_unique(); -#endif - ////////////////////////////////////////////////////////////////////////// // Open basic pak files after intro movie playback started ////////////////////////////////////////////////////////////////////////// @@ -2129,30 +1604,6 @@ AZ_POP_DISABLE_WARNING InlineInitializationProcessing("CSystem::Init View System"); - ////////////////////////////////////////////////////////////////////////// - // Zlib compressor - m_pIZLibCompressor = new CZLibCompressor(); - - InlineInitializationProcessing("CSystem::Init ZLibCompressor"); - - ////////////////////////////////////////////////////////////////////////// - // Zlib decompressor - m_pIZLibDecompressor = new CZLibDecompressor(); - - InlineInitializationProcessing("CSystem::Init ZLibDecompressor"); - - ////////////////////////////////////////////////////////////////////////// - // LZ4 decompressor - m_pILZ4Decompressor = new CLZ4Decompressor(); - - InlineInitializationProcessing("CSystem::Init LZ4Decompressor"); - - ////////////////////////////////////////////////////////////////////////// - // ZStd decompressor - m_pIZStdDecompressor = new CZStdDecompressor(); - - InlineInitializationProcessing("CSystem::Init ZStdDecompressor"); - if (m_env.pLyShine) { m_env.pLyShine->PostInit(); @@ -2192,9 +1643,6 @@ AZ_POP_DISABLE_WARNING LoadConfiguration("client.cfg", &CVarsClientConfigSink); } - // All CVars should be registered by this point, we must now flush the cvar groups - LoadDetectedSpec(m_sys_GraphicsQuality); - //Connect to the render bus AZ::RenderNotificationsBus::Handler::BusConnect(); @@ -2268,153 +1716,6 @@ void CmdSetAwsLogLevel(IConsoleCmdArgs* pArgs) } } -static void SysRestoreSpecCmd(IConsoleCmdArgs* pParams) -{ - assert(pParams); - - if (pParams->GetArgCount() == 2) - { - const char* szArg = pParams->GetArg(1); - - ICVar* pCVar = gEnv->pConsole->GetCVar("sys_spec_Full"); - - if (!pCVar) - { - gEnv->pLog->LogWithType(ILog::eInputResponse, "sys_RestoreSpec: no action"); // e.g. running Editor in shder compile mode - return; - } - - ICVar::EConsoleLogMode mode = ICVar::eCLM_Off; - - if (azstricmp(szArg, "test") == 0) - { - mode = ICVar::eCLM_ConsoleAndFile; - } - else if (azstricmp(szArg, "test*") == 0) - { - mode = ICVar::eCLM_FileOnly; - } - else if (azstricmp(szArg, "info") == 0) - { - mode = ICVar::eCLM_FullInfo; - } - - if (mode != ICVar::eCLM_Off) - { - bool bFileOrConsole = (mode == ICVar::eCLM_FileOnly || mode == ICVar::eCLM_FullInfo); - - if (bFileOrConsole) - { - gEnv->pLog->LogToFile(" "); - } - else - { - CryLog(" "); - } - - int iSysSpec = pCVar->GetRealIVal(); - - if (iSysSpec == -1) - { - iSysSpec = ((CSystem*)gEnv->pSystem)->GetMaxConfigSpec(); - - if (bFileOrConsole) - { - gEnv->pLog->LogToFile(" sys_spec = Custom (assuming %d)", iSysSpec); - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, " $3sys_spec = $6Custom (assuming %d)", iSysSpec); - } - } - else - { - if (bFileOrConsole) - { - gEnv->pLog->LogToFile(" sys_spec = %d", iSysSpec); - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, " $3sys_spec = $6%d", iSysSpec); - } - } - - pCVar->DebugLog(iSysSpec, mode); - - if (bFileOrConsole) - { - gEnv->pLog->LogToFile(" "); - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, " "); - } - - return; - } - else if (strcmp(szArg, "apply") == 0) - { - const char* szPrefix = "sys_spec_"; - - ESystemConfigSpec originalSpec = CONFIG_AUTO_SPEC; - ESystemConfigPlatform originalPlatform = GetDevicePlatform(); - - if (gEnv->IsEditor()) - { - originalSpec = gEnv->pSystem->GetConfigSpec(true); - } - - std::vector cmds; - - cmds.resize(gEnv->pConsole->GetSortedVars(0, 0, szPrefix)); - gEnv->pConsole->GetSortedVars(&cmds[0], cmds.size(), szPrefix); - - gEnv->pLog->LogWithType(IMiniLog::eInputResponse, " "); - - std::vector::const_iterator it, end = cmds.end(); - - for (it = cmds.begin(); it != end; ++it) - { - const char* szName = *it; - - if (azstricmp(szName, "sys_spec_Full") == 0) - { - continue; - } - - pCVar = gEnv->pConsole->GetCVar(szName); - assert(pCVar); - - if (!pCVar) - { - continue; - } - - bool bNeeded = pCVar->GetIVal() != pCVar->GetRealIVal(); - - gEnv->pLog->LogWithType(IMiniLog::eInputResponse, " $3%s = $6%d ... %s", - szName, pCVar->GetIVal(), - bNeeded ? "$4restored" : "valid"); - - if (bNeeded) - { - pCVar->Set(pCVar->GetIVal()); - } - } - - gEnv->pLog->LogWithType(IMiniLog::eInputResponse, " "); - - if (gEnv->IsEditor()) - { - gEnv->pSystem->SetConfigSpec(originalSpec, originalPlatform, true); - } - return; - } - } - - gEnv->pLog->LogWithType(ILog::eInputResponse, "ERROR: sys_RestoreSpec invalid arguments"); -} - void CmdDrillToFile(IConsoleCmdArgs* pArgs) { if (azstricmp(pArgs->GetArg(0), "DrillerStop") == 0) @@ -2551,14 +1852,6 @@ void CSystem::CreateSystemVars() "1 - enable optimisation\n" "Default is 1"); -#if USE_STEAM -#ifndef RELEASE - REGISTER_CVAR2("sys_steamAppId", &g_cvars.sys_steamAppId, 0, VF_NULL, "steam appId used for development testing"); - REGISTER_COMMAND("sys_wipeSteamCloud", CmdWipeSteamCloud, VF_CHEAT, "Delete all files from steam cloud for this user"); -#endif // RELEASE - REGISTER_CVAR2("sys_useSteamCloudForPlatformSaving", &g_cvars.sys_useSteamCloudForPlatformSaving, 0, VF_NULL, "Use steam cloud for save games and profile on PC (instead of the user folder)"); -#endif - m_sysNoUpdate = REGISTER_INT("sys_noupdate", 0, VF_CHEAT, "Toggles updating of system with sys_script_debugger.\n" "Usage: sys_noupdate [0/1]\n" @@ -2622,9 +1915,6 @@ void CSystem::CreateSystemVars() #else const uint32 nJobSystemDefaultCoreNumber = 4; #endif - m_sys_GraphicsQuality = REGISTER_INT_CB("r_GraphicsQuality", 0, VF_ALWAYSONCHANGE, - "Specifies the system cfg spec. 1=low, 2=med, 3=high, 4=very high)", - LoadDetectedSpec); m_sys_firstlaunch = REGISTER_INT("sys_firstlaunch", 0, 0, "Indicates that the game was run for the first time."); @@ -2731,14 +2021,6 @@ void CSystem::CreateSystemVars() REGISTER_CVAR2("sys_update_profile_time", &g_cvars.sys_update_profile_time, 1.0f, 0, "Time to keep updates timings history for."); REGISTER_CVAR2("sys_no_crash_dialog", &g_cvars.sys_no_crash_dialog, m_bNoCrashDialog, VF_NULL, "Whether to disable the crash dialog window"); REGISTER_CVAR2("sys_no_error_report_window", &g_cvars.sys_no_error_report_window, m_bNoErrorReportWindow, VF_NULL, "Whether to disable the error report list"); -#if defined(_RELEASE) - if (!gEnv->IsDedicated()) - { - REGISTER_CVAR2("sys_WER", &g_cvars.sys_WER, 1, 0, "Enables Windows Error Reporting"); - } -#else - REGISTER_CVAR2("sys_WER", &g_cvars.sys_WER, 0, 0, "Enables Windows Error Reporting"); -#endif #ifdef USE_HTTP_WEBSOCKETS REGISTER_CVAR2("sys_simple_http_base_port", &g_cvars.sys_simple_http_base_port, 1880, VF_REQUIRE_APP_RESTART, @@ -2820,11 +2102,6 @@ void CSystem::CreateSystemVars() REGISTER_STRING_CB("g_language", "", VF_NULL, "Defines which language pak is loaded", CSystem::OnLanguageCVarChanged); REGISTER_STRING_CB("g_languageAudio", "", VF_NULL, "Will automatically match g_language setting unless specified otherwise", CSystem::OnLanguageAudioCVarChanged); - REGISTER_COMMAND("sys_RestoreSpec", &SysRestoreSpecCmd, 0, - "Restore or test the cvar settings of game specific spec settings,\n" - "'test*' and 'info' log to the log file only\n" - "Usage: sys_RestoreSpec [test|test*|apply|info]"); - #if defined(WIN32) REGISTER_CVAR2("sys_display_threads", &g_cvars.sys_display_threads, 0, 0, "Displays Thread info"); #elif defined(AZ_RESTRICTED_PLATFORM) diff --git a/Code/CryEngine/CrySystem/SystemInit.h b/Code/CryEngine/CrySystem/SystemInit.h deleted file mode 100644 index 55eecb97db..0000000000 --- a/Code/CryEngine/CrySystem/SystemInit.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SYSTEMINIT_H -#define CRYINCLUDE_CRYSYSTEM_SYSTEMINIT_H -#pragma once - - -#include "System.h" - -#if defined(AZ_PLATFORM_ANDROID) - #include "AndroidConsole.h" - -// let the java code know the native renderer is taking over now -extern "C" DLL_EXPORT void OnEngineRendererTakeover(bool engineSplashActive); -#endif - -#include "UnixConsole.h" - -#if defined(USE_UNIXCONSOLE) -#if defined(LINUX) && !defined(ANDROID) -extern __attribute__((visibility("default"))) CUNIXConsole* pUnixConsole; -#endif -#endif // USE_UNIXCONSOLE - -#endif // CRYINCLUDE_CRYSYSTEM_SYSTEMINIT_H diff --git a/Code/CryEngine/CrySystem/SystemRender.cpp b/Code/CryEngine/CrySystem/SystemRender.cpp deleted file mode 100644 index 2314f593b7..0000000000 --- a/Code/CryEngine/CrySystem/SystemRender.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : CryENGINE system core - - -#include "CrySystem_precompiled.h" -#include "System.h" - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -#endif - -#if defined(AZ_PLATFORM_IOS) -#import -#endif - -#include -#include -#include -#include "Log.h" -#include "XConsole.h" -#include -#include "PhysRenderer.h" -#include - -#include "ITextModeConsole.h" -#include -#include - -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define SYSTEMRENDERER_CPP_SECTION_1 1 -#define SYSTEMRENDERER_CPP_SECTION_2 2 -#endif - -#if defined(AZ_PLATFORM_ANDROID) -#include -#endif - -///////////////////////////////////////////////////////////////////////////////// -bool CSystem::GetPrimaryPhysicalDisplayDimensions([[maybe_unused]] int& o_widthPixels, [[maybe_unused]] int& o_heightPixels) -{ -#if defined(AZ_PLATFORM_WINDOWS) - o_widthPixels = GetSystemMetrics(SM_CXSCREEN); - o_heightPixels = GetSystemMetrics(SM_CYSCREEN); - return true; -#elif defined(AZ_PLATFORM_ANDROID) - return AZ::Android::Utils::GetWindowSize(o_widthPixels, o_heightPixels); -#else - return false; -#endif -} - - -bool CSystem::IsTablet() -{ -//TODO: Add support for Android tablets -#if defined(AZ_PLATFORM_IOS) - return [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad; -#else - return false; -#endif -} - -void CSystem::OnScene3DEnd() -{ - //Render Console - if (m_bDrawConsole && gEnv->pConsole) - { - gEnv->pConsole->Draw(); - } -} - -////////////////////////////////////////////////////////////////////////// - -void CSystem::DisplayErrorMessage(const char* acMessage, - [[maybe_unused]] float fTime, - const float* pfColor, - bool bHardError) -{ - SErrorMessage message; - message.m_Message = acMessage; - if (pfColor) - { - memcpy(message.m_Color, pfColor, 4 * sizeof(float)); - } - else - { - message.m_Color[0] = 1.0f; - message.m_Color[1] = 0.0f; - message.m_Color[2] = 0.0f; - message.m_Color[3] = 1.0f; - } - message.m_HardFailure = bHardError; -#ifdef _RELEASE - message.m_fTimeToShow = fTime; -#else - message.m_fTimeToShow = 1.0f; -#endif - m_ErrorMessages.push_back(message); -} diff --git a/Code/CryEngine/CrySystem/SystemWin32.cpp b/Code/CryEngine/CrySystem/SystemWin32.cpp index c40b0f7c7b..c974365bfc 100644 --- a/Code/CryEngine/CrySystem/SystemWin32.cpp +++ b/Code/CryEngine/CrySystem/SystemWin32.cpp @@ -53,7 +53,6 @@ #include "XConsole.h" #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" -#include "AutoDetectSpec.h" #if defined(WIN32) __pragma(comment(lib, "wininet.lib")) diff --git a/Code/CryEngine/CrySystem/Tests/Test_CLog.cpp b/Code/CryEngine/CrySystem/Tests/Test_CLog.cpp deleted file mode 100644 index e792ba095f..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_CLog.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" - -#include -#include - -#include -#include - -#include // for max path decl -#include -#include -#include -#include - -namespace CLogUnitTests -{ - using ::testing::NiceMock; - using ::testing::_; - using ::testing::Return; - - // for fuzzing test, how much work to do? Not much, as this must be fast. - const int NumTrialsToPerform = 16000; - - class CLogUnitTests - : public ::testing::Test - { - public: - - using CryPrimitivesAllocatorScope = AZ::AllocatorScope; - - void SetUp() override - { - m_primitiveAllocators.ActivateAllocators(); - - m_priorEnv = gEnv; - m_priorFileIO = AZ::IO::FileIOBase::GetInstance(); - m_priorDirectFileIO = AZ::IO::FileIOBase::GetDirectInstance(); - - m_data = AZStd::make_unique(); - m_data->m_stubEnv.pSystem = &m_data->m_system; - - gEnv = &m_data->m_stubEnv; - - // for FileIO, you must set the instance to null before changing it. - // this is a way to tell the singleton system that you mean to replace a singleton and its - // not a mistake. - AZ::IO::FileIOBase::SetInstance(nullptr); - AZ::IO::FileIOBase::SetInstance(&m_data->m_fileIOMock); - AZ::IO::FileIOBase::SetDirectInstance(nullptr); - AZ::IO::FileIOBase::SetDirectInstance(&m_data->m_fileIOMock); - - ON_CALL(m_data->m_system, GetIRemoteConsole()) - .WillByDefault( - Return(&m_data->m_remoteConsoleMock)); - - AZ::IO::MockFileIOBase::InstallDefaultReturns(m_data->m_fileIOMock); - } - - void TearDown() override - { - AZ::IO::FileIOBase::SetInstance(nullptr); - AZ::IO::FileIOBase::SetInstance(m_priorFileIO); - AZ::IO::FileIOBase::SetDirectInstance(nullptr); - AZ::IO::FileIOBase::SetDirectInstance(m_priorDirectFileIO); - - m_data.reset(); - - // restore state. - gEnv = m_priorEnv; - m_primitiveAllocators.DeactivateAllocators(); - } - - struct DataMembers - { - SSystemGlobalEnvironment m_stubEnv; - NiceMock m_system; - NiceMock m_fileIOMock; - NiceMock m_remoteConsoleMock; - }; - - AZStd::unique_ptr m_data; - SSystemGlobalEnvironment* m_priorEnv = nullptr; - ISystem* m_priorSystem = nullptr; - AZ::IO::FileIOBase* m_priorFileIO = nullptr; - AZ::IO::FileIOBase* m_priorDirectFileIO = nullptr; - CryPrimitivesAllocatorScope m_primitiveAllocators; - }; - - TEST_F(CLogUnitTests, LogAlways_InvalidString_Asserts) - { - AZ_TEST_START_TRACE_SUPPRESSION; - CLog testLog(&m_data->m_system); - testLog.LogAlways(nullptr); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - - TEST_F(CLogUnitTests, LogAlways_EmptyString_IgnoresWithoutCrashing) - { - CLog testLog(&m_data->m_system); - testLog.LogAlways(""); - } - - TEST_F(CLogUnitTests, LogAlways_NormalString_NoFileName_DoesNotCrash) - { - CLog testLog(&m_data->m_system); - testLog.LogAlways("test"); - } - - TEST_F(CLogUnitTests, LogAlways_SetFileName_Empty_DoesNotCrash) - { - CLog testLog(&m_data->m_system); - testLog.SetFileName("", false); - testLog.LogAlways("test"); - } - -#if AZ_TRAIT_DISABLE_LOG_ALWAYS_FUZZ_TEST - TEST_F(CLogUnitTests, DISABLED_LogAlways_FuzzTest) -#else - TEST_F(CLogUnitTests, LogAlways_FuzzTest) -#endif // AZ_TRAIT_DISABLE_LOG_ALWAYS_FUZZ_TEST - { - CLog testLog(&m_data->m_system); - AZStd::string randomJunkName; - - randomJunkName.resize(128, '\0'); - - // expect the mock to repeatedly get called. If we fail this expectation - // it means the code is early-outing somewhere and we are not getting coverage. - EXPECT_CALL(m_data->m_fileIOMock, Write(_, _, _, _)) - .WillRepeatedly( - Return(AZ::IO::Result(AZ::IO::ResultCode::Success))); - - // don't rely on randomness in unit tests, they need to be repeatable. - // the following random generator is not seeded by the time, but by a constant (default 1234). - AZ::SimpleLcgRandom randGen; - - for (int trialNumber = 0; trialNumber < NumTrialsToPerform; ++trialNumber) - { - for (int randomChar = 0; randomChar < randomJunkName.size(); ++randomChar) - { - // note that this is intentionally allowing null characters to generate. - // note that this also puts characters AFTER the null, if a null appears in the mddle. - // so that if there are off by one errors they could include cruft afterwards. - - if (randomChar > trialNumber % randomJunkName.size()) - { - // choose this point for the nulls to begin. It makes sure we test every size of string. - randomJunkName[randomChar] = 0; - } - else - { - randomJunkName[randomChar] = (char)(randGen.GetRandom() % 256); // this will trigger invalid UTF8 decoding too - } - } - testLog.LogAlways("%s", randomJunkName.c_str()); - } - } - - TEST_F(CLogUnitTests, LogAlways_SetFileName_Correct_DoesNotCrash_WritesToFile) - { - CLog testLog(&m_data->m_system); - testLog.SetFileName("logfile.log", false); - - // EXPECT a call to the file system - if we dont get a call here, it means something went wrong. - // it also expects exactly one call to write. One call to log should be one call to write, - // or else performance will suffer. - - EXPECT_CALL(m_data->m_fileIOMock, Write(_, _, _, _)) - .WillOnce( - Return(AZ::IO::Result(AZ::IO::ResultCode::Success))); - - testLog.LogAlways("test"); - } -} // end namespace CLogUnitTests - - diff --git a/Code/CryEngine/CrySystem/Tests/Test_CommandRegistration.cpp b/Code/CryEngine/CrySystem/Tests/Test_CommandRegistration.cpp deleted file mode 100644 index d54ba87446..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_CommandRegistration.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" - -#include - -#include - -#include -#include -#include -#include - -#include - -namespace UnitTests -{ - class RemoteConsoleMock - : public IRemoteConsole - { - public: - MOCK_METHOD0(RegisterConsoleVariables, void()); - MOCK_METHOD0(UnregisterConsoleVariables, void()); - MOCK_METHOD0(Start, void()); - MOCK_METHOD0(Stop, void()); - MOCK_CONST_METHOD0(IsStarted, bool()); - MOCK_METHOD1(AddLogMessage, void(const char*)); - MOCK_METHOD1(AddLogWarning, void(const char*)); - MOCK_METHOD1(AddLogError, void(const char*)); - MOCK_METHOD0(Update, void()); - MOCK_METHOD2(RegisterListener, void(IRemoteConsoleListener*, const char*)); - MOCK_METHOD1(UnregisterListener, void(IRemoteConsoleListener*)); - }; - - struct TestTraceMessageCapture - : public AZ::Debug::TraceMessageBus::Handler - { - using Callback = AZStd::function; - Callback m_callback; - - TestTraceMessageCapture() - { - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - } - - ~TestTraceMessageCapture() - { - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - - bool OnError(const char* window, const char* message) override - { - if (m_callback) - { - m_callback(window, message); - } - return false; - } - - bool OnWarning(const char* window, const char* message) override - { - if (m_callback) - { - m_callback(window, message); - } - return false; - } - }; - - using SystemAllocatorScope = AZ::AllocatorScope; - - struct CommandRegistrationUnitTests - : public ::testing::Test - , public SystemAllocatorScope - { - CommandRegistrationUnitTests() - { - EXPECT_CALL(m_system, GetIRemoteConsole()) - .WillRepeatedly(::testing::Return(&m_remoteConsole)); - } - - void SetUp() override - { - SystemAllocatorScope::ActivateAllocators(); - - memset(&m_stubEnv, 0, sizeof(SSystemGlobalEnvironment)); - m_stubEnv.pSystem = &m_system; - m_priorEnv = gEnv; - gEnv = &m_stubEnv; - - // now it safe to set up the console - m_console = AZStd::make_unique(); - m_stubEnv.pConsole = m_console.get(); - - EXPECT_CALL(m_system, GetIConsole()) - .WillRepeatedly(::testing::Return(m_stubEnv.pConsole)); - } - - void TearDown() override - { - m_console.reset(); - gEnv = m_priorEnv; - SystemAllocatorScope::DeactivateAllocators(); - } - - ::testing::NiceMock m_system; - ::testing::NiceMock m_remoteConsole; - AZStd::unique_ptr m_console; - SSystemGlobalEnvironment m_stubEnv; - SSystemGlobalEnvironment* m_priorEnv = nullptr; - }; - - TEST_F(CommandRegistrationUnitTests, RegisterUnregisterTest) - { - using namespace AzFramework; - - { - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "foo", "", 0, [](const AZStd::vector&) -> CommandResult - { - return CommandResult::Success; - }); - EXPECT_TRUE(result); - } - - { - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "foo"); - EXPECT_TRUE(result); - } - } - - TEST_F(CommandRegistrationUnitTests, RegisterUnregisterNegativeTest) - { - using namespace AzFramework; - - // register too many times - { - auto fnFoo = [](const AZStd::vector&) -> CommandResult - { - return CommandResult::Success; - }; - - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "foo", "", 0, fnFoo); - EXPECT_TRUE(result); - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "foo", "", 0, fnFoo); - EXPECT_FALSE(result); - } - - // unregister too many times - { - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "foo"); - EXPECT_TRUE(result); - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "foo"); - EXPECT_FALSE(result); - } - - // a null callback should fail - { - AZ_TEST_START_TRACE_SUPPRESSION; - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "shouldfail", "", 0, nullptr); - EXPECT_FALSE(result); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - - // a null identifier should fail - { - AZ_TEST_START_TRACE_SUPPRESSION; - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "", "", 0, nullptr); - EXPECT_FALSE(result); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - } - - TEST_F(CommandRegistrationUnitTests, DoCallback) - { - using namespace AzFramework; - - int count = 0; - - { - auto fnCommand = [&count](const AZStd::vector&) -> CommandResult - { - ++count; - return CommandResult::Success; - }; - - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "bar", "bar docs", CommandFlags::Development, fnCommand); - EXPECT_TRUE(result); - } - - const bool bSilentMode = true; - const bool bDeferExecution = false; - m_console->ExecuteString("bar", bSilentMode, bDeferExecution); - EXPECT_EQ(1, count); - - { - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "bar"); - EXPECT_TRUE(result); - } - } - - TEST_F(CommandRegistrationUnitTests, DoCallbackNegativeTests) - { - using namespace AzFramework; - - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "bar", "", 0, [](const AZStd::vector& args) - { - if (args.size() > 1) - { - return CommandResult::ErrorWrongNumberOfArguments; - } - return CommandResult::Error; - }); - EXPECT_TRUE(result); - - const bool bSilentMode = true; - const bool bDeferExecution = false; - - // general error - { - int found = 0; - TestTraceMessageCapture capture; - capture.m_callback = [&found](const char* window, const char* message) - { - if (azstrnicmp(window, "console", AZ_ARRAY_SIZE("console") - 1) == 0) - { - if (azstrnicmp(message, "Command returned a generic error\n", AZ_ARRAY_SIZE("Command returned a generic error\n") - 1) == 0) - { - ++found; - } - } - }; - m_console->ExecuteString("bar", bSilentMode, bDeferExecution); - EXPECT_EQ(1, found); - } - - // too many args - { - int found = 0; - TestTraceMessageCapture capture; - capture.m_callback = [&found](const char* window, const char* message) - { - if (azstrnicmp(window, "console", AZ_ARRAY_SIZE("console") - 1) == 0) - { - if (azstrnicmp(message, "Command does not have the right number of arguments (send = 4)\n", AZ_ARRAY_SIZE("Command does not have the right number of arguments (send = 4)\n") - 1) == 0) - { - ++found; - } - } - }; - m_console->ExecuteString("bar 1 2 3", bSilentMode, bDeferExecution); - EXPECT_EQ(1, found); - } - - // clean up - { - result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "bar"); - EXPECT_TRUE(result); - } - } - -} // namespace UnitTests - - diff --git a/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp b/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp deleted file mode 100644 index 26d12ffd8c..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include - -TEST(StringTests, CUT_Strings) -{ - bool bOk; - char bf[4]; - - // cry_strcpy() - - bOk = cry_strcpy(0, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 0, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 1, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 1, 0, 1); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 1, ""); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 1, "", 1); - EXPECT_TRUE(!bOk); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 0, ""); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 0, "", 1); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 1, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 1, 0, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty"); - EXPECT_TRUE(!bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 3); - EXPECT_TRUE(!bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 2); - EXPECT_TRUE(bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 1); - EXPECT_TRUE(bOk && !memcmp(bf, "q\000cd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 0); - EXPECT_TRUE(bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwerty"); - EXPECT_TRUE(!bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwerty", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwerty", 3); - EXPECT_TRUE(bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwerty", 2); - EXPECT_TRUE(bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwe"); - EXPECT_TRUE(bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwe", 4); - EXPECT_TRUE(bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qw", 3); - EXPECT_TRUE(bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, sizeof(bf), "q"); - EXPECT_TRUE(bOk && !memcmp(bf, "q\000cd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, sizeof(bf), "q", 2); - EXPECT_TRUE(bOk && !memcmp(bf, "q\000cd", 4)); - - // cry_strcat() - - bOk = cry_strcat(0, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 0, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 1, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 1, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 1, ""); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 1, "", 1); - EXPECT_TRUE(!bOk); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 0, "xy"); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 0, "xy", 3); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 0, "xy", 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, "xyz"); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, "xyz", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, "xyz", 1); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, "xyz", 0); - EXPECT_TRUE(bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, 0, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, 3, "xyz"); - EXPECT_TRUE(!bOk && !memcmp(bf, "ax\000d", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, 3, "xyz", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "ax\000d", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, 3, "xyz", 2); - EXPECT_TRUE(!bOk && !memcmp(bf, "ax\000d", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, 3, "xyz", 1); - EXPECT_TRUE(bOk && !memcmp(bf, "ax\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, "xyz"); - EXPECT_TRUE(!bOk && !memcmp(bf, "abc\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, "xyz", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "abc\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, "xyz", 1); - EXPECT_TRUE(!bOk && !memcmp(bf, "abc\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, "xyz", 0); - EXPECT_TRUE(bOk && !memcmp(bf, "abc\000", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, "xyz"); - EXPECT_TRUE(!bOk && !memcmp(bf, "abx\000", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, "xyz", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "abx\000", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, "xyz", 1); - EXPECT_TRUE(bOk && !memcmp(bf, "abx\000", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, "xyz", 0); - EXPECT_TRUE(bOk && !memcmp(bf, "ab\000d", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, 0, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "ab\000d", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, 0, 1); - EXPECT_TRUE(!bOk && !memcmp(bf, "ab\000d", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, sizeof(bf), "xy"); - EXPECT_TRUE(bOk && !memcmp(bf, "axy\000", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, sizeof(bf), "xy", 3); - EXPECT_TRUE(bOk && !memcmp(bf, "axy\000", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, sizeof(bf), "xy", 1); - EXPECT_TRUE(bOk && !memcmp(bf, "ax\000d", 4)); -} - -using CryPrimitivesAllocatorScope = AZ::AllocatorScope; - -class CryPrimitives - : public ::testing::Test -{ -public: - void SetUp() override - { - m_memory.ActivateAllocators(); - } - - void TearDown() override - { - m_memory.DeactivateAllocators(); - } - - CryPrimitivesAllocatorScope m_memory; -}; - -TEST_F(CryPrimitives, CUT_CryString) -{ - ////////////////////////////////////////////////////////////////////////// - // Based on MS documentation of find_last_of - string strTestFindLastOfOverload1("abcd-1234-abcd-1234"); - string strTestFindLastOfOverload2("ABCD-1234-ABCD-1234"); - string strTestFindLastOfOverload3("456-EFG-456-EFG"); - string strTestFindLastOfOverload4("12-ab-12-ab"); - - const char* cstr2 = "B1"; - const char* cstr2b = "D2"; - const char* cstr3a = "5E"; - string str4a("ba3"); - string str4b("a2"); - - size_t nPosition(string::npos); - - nPosition = strTestFindLastOfOverload1.find_last_of('d', 14); - EXPECT_TRUE(nPosition == 13); - - - nPosition = strTestFindLastOfOverload2.find_last_of(cstr2, 12); - EXPECT_TRUE(nPosition == 11); - - - nPosition = strTestFindLastOfOverload2.find_last_of(cstr2b); - EXPECT_TRUE(nPosition == 16); - - - nPosition = strTestFindLastOfOverload3.find_last_of(cstr3a, 8, 2); - EXPECT_TRUE(nPosition == 4); - - - nPosition = strTestFindLastOfOverload4.find_last_of(str4a, 8); - EXPECT_TRUE(nPosition == 4); - - - nPosition = strTestFindLastOfOverload4.find_last_of(str4b); - EXPECT_TRUE(nPosition == 9); - - ////////////////////////////////////////////////////////////////////////// - // Based on MS documentation of find_last_not_of - string strTestFindLastNotOfOverload1("dddd-1dd4-abdd"); - string strTestFindLastNotOfOverload2("BBB-1111"); - string strTestFindLastNotOfOverload3("444-555-GGG"); - string strTestFindLastNotOfOverload4("12-ab-12-ab"); - - const char* cstr2NF = "B1"; - const char* cstr3aNF = "45G"; - const char* cstr3bNF = "45G"; - - string str4aNF("b-a"); - string str4bNF("12"); - - nPosition = strTestFindLastNotOfOverload1.find_last_not_of('d', 7); - EXPECT_TRUE(nPosition == 5); - - nPosition = strTestFindLastNotOfOverload1.find_last_not_of("d"); - EXPECT_TRUE(nPosition == 11); - - nPosition = strTestFindLastNotOfOverload2.find_last_not_of(cstr2NF, 6); - EXPECT_TRUE(nPosition == 3); - - nPosition = strTestFindLastNotOfOverload3.find_last_not_of(cstr3aNF); - EXPECT_TRUE(nPosition == 7); - - nPosition = strTestFindLastNotOfOverload3.find_last_not_of(cstr3bNF, 6, 3);//nPosition - 1 ); - EXPECT_TRUE(nPosition == 3); - - nPosition = strTestFindLastNotOfOverload4.find_last_not_of(str4aNF, 5); - EXPECT_TRUE(nPosition == 1); - - nPosition = strTestFindLastNotOfOverload4.find_last_not_of(str4bNF); - EXPECT_TRUE(nPosition == 10); -} - - -TEST_F(CryPrimitives, CUT_FixedString) -{ - CryStackStringT str1; - CryStackStringT str2; - CryStackStringT str3; - CryStackStringT str4; - CryStackStringT str5; - CryStackStringT wstr1; - CryStackStringT wstr2; - CryFixedStringT<100> fixedString100; - CryFixedStringT<200> fixedString200; - - typedef CryStackStringT T; - T* pStr = new T; - *pStr = "adads"; - delete pStr; - - str1 = "abcd"; - EXPECT_EQ(str1, "abcd"); - - str2 = "efg"; - EXPECT_EQ(str2, "efg"); - - str2 = str1; - EXPECT_EQ(str2, "abcd"); - - str1 += "XY"; - EXPECT_EQ(str1, "abcdXY"); - - str2 += "efghijk"; - EXPECT_EQ(str2, "abcdefghijk"); - - str1.replace("bc", ""); - EXPECT_EQ(str1, "adXY"); - - str1.replace("XY", "1234"); - EXPECT_EQ(str1, "ad1234"); - - str1.replace("1234", "1234567890"); - EXPECT_EQ(str1, "ad1234567890"); - - str1.reserve(200); - EXPECT_EQ(str1, "ad1234567890"); - EXPECT_TRUE(str1.capacity() == 200); - - str1.reserve(0); - EXPECT_EQ(str1, "ad1234567890"); - EXPECT_TRUE(str1.capacity() == str1.length()); - - str1.erase(7); // doesn't change capacity - EXPECT_EQ(str1, "ad12345"); - - str4.assign("abc"); - EXPECT_EQ(str4, "abc"); - str4.reserve(9); - EXPECT_TRUE(str4.capacity() >= 9); // capacity is always >= MAX_SIZE-1 - str4.reserve(0); - EXPECT_TRUE(str4.capacity() >= 9); // capacity is always >= MAX_SIZE-1 - - size_t idx = str1.find("123"); - EXPECT_TRUE(idx == 2); - - idx = str1.find("123", 3); - EXPECT_TRUE(idx == str1.npos); - - wstr1 = L"abc"; - EXPECT_EQ(wstr1, L"abc"); - EXPECT_TRUE(wstr1.compare(L"aBc") > 0); - EXPECT_TRUE(wstr1.compare(L"babc") < 0); - EXPECT_TRUE(wstr1.compareNoCase(L"aBc") == 0); - - str1.Format("This is a %s %ls with %d params", "mixed", L"string", 3); - str2.Format("This is a %ls %s with %d params", L"mixed", "string", 3); - EXPECT_EQ(str1, "This is a mixed string with 3 params"); - EXPECT_EQ(str1, str2); - - wstr1.Format(L"This is a %ls %hs with %d params", L"mixed", "string", 3); - wstr2.Format(L"This is a %hs %ls with %d params", "mixed", L"string", 3); - EXPECT_EQ(wstr1, L"This is a mixed string with 3 params"); - - str5.FormatFast("%s", "12345"); - EXPECT_EQ("1234", str5); - - // we expect here that the string gets cut since it doesn't fit into the string buffer - str5.FormatFast("%s", "012345"); - EXPECT_EQ("0123", str5); -} - -TEST_F(CryPrimitives, CUT_DynArray) -{ - LegacyDynArray a; - a.push_back(3); - a.insert(&a[0], 1, 1); - a.insert(&a[1], 1, 2); - a.insert(&a[0], 1, 0); - - for (int i = 0; i < 4; i++) - { - EXPECT_TRUE(a[i] == i); - } - - const int nStrs = 11; - string Strs[nStrs] = { "nought", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" }; - LegacyDynArray s; - for (int i = 0; i < nStrs; i += 2) - { - s.push_back(Strs[i]); - } - for (int i = 1; i < nStrs; i += 2) - { - s.insert(i, Strs[i]); - } - for (int i = 0; i < nStrs; i++) - { - EXPECT_TRUE(s[i] == Strs[i]); - } - - LegacyDynArray s2 = s; - s.erase(5, 2); - EXPECT_TRUE(s.size() == nStrs - 2); - - s.insert(&s[3], &Strs[5], &Strs[8]); - - s2 = s2(3, 4); - EXPECT_TRUE(s2.size() == 4); -} diff --git a/Code/CryEngine/CrySystem/Tests/Test_Localization.cpp b/Code/CryEngine/CrySystem/Tests/Test_Localization.cpp deleted file mode 100644 index ad3972fffe..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_Localization.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include -#include "LocalizedStringManager.h" -#include -#include -#include -#include - -#include - -class SystemEventDispatcherMock - : public ISystemEventDispatcher -{ -public: - virtual ~SystemEventDispatcherMock() {} - MOCK_METHOD1(RegisterListener, bool(ISystemEventListener* pListener)); - MOCK_METHOD1(RemoveListener, bool(ISystemEventListener* pListener)); - MOCK_METHOD3(OnSystemEvent, void(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)); - MOCK_METHOD0(Update, void()); -}; - -using namespace testing; -using ::testing::NiceMock; - -using SystemAllocatorScope = AZ::AllocatorScope; - -class SystemFixture - : public ::testing::Test - , public SystemAllocatorScope -{ -public: - SystemFixture() - { - EXPECT_CALL(m_system, GetISystemEventDispatcher()) - .WillRepeatedly(Return(&m_dispatcher)); - - EXPECT_CALL(m_console, GetCVar(_)) - .WillRepeatedly(Return(&m_cvarMock)); - - EXPECT_CALL(m_cryPak, FindFirst(_, _, _)) - .WillRepeatedly(Return(AZ::IO::ArchiveFileIterator{})); - - EXPECT_CALL(m_cryPak, GetLocalizationFolder()) - .WillRepeatedly(Return("french")); - - EXPECT_CALL(m_cvarMock, GetFlags()) - .WillRepeatedly(Return(VF_WASINCONFIG)); - } - - void SetUp() override - { - SystemAllocatorScope::ActivateAllocators(); - - memset(&m_stubEnv, 0, sizeof(SSystemGlobalEnvironment)); - m_stubEnv.pConsole = &m_console; - m_stubEnv.pSystem = &m_system; - m_stubEnv.pCryPak = &m_cryPak; - m_stubEnv.pLog = nullptr; - m_priorEnv = gEnv; - gEnv = &m_stubEnv; - } - - void TearDown() override - { - gEnv = m_priorEnv; - - SystemAllocatorScope::DeactivateAllocators(); - } - - NiceMock m_system; - NiceMock m_dispatcher; - NiceMock m_console; - NiceMock m_cryPak; - NiceMock m_cvarMock; - SSystemGlobalEnvironment m_stubEnv; - SSystemGlobalEnvironment* m_priorEnv = nullptr; -}; - -class UnitTestCLocalizedStringsManager : public CLocalizedStringsManager -{ -public: - UnitTestCLocalizedStringsManager(ISystem* pSystem) : CLocalizedStringsManager(pSystem) - { - } - - bool LocalizeLabel(const char* sLabel, string& outLocalizedString, bool bEnglish = false) override - { - m_capturedLabels.push_back(sLabel); - return CLocalizedStringsManager::LocalizeLabel(sLabel, outLocalizedString, bEnglish); - } - - std::vector m_capturedLabels; - - friend class GTEST_TEST_CLASS_NAME_(SystemFixture, LocalizeStringInternal_WhitespaceCharacters_CorrectlyTokenizes); -}; - -// this test makes sure that whitespace characters such as tab work (not just space) and are considered to be separators. -TEST_F(SystemFixture, LocalizeStringInternal_SpecificWhitespaceCharacters_CorrectlyTokenizes) -{ - UnitTestCLocalizedStringsManager manager(&m_system); - manager.SetLanguage("french"); - - string outString; - manager.LocalizeString_s("@hello\t@world", outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - manager.m_capturedLabels.clear(); - - manager.LocalizeString_s("@hello\n@world", outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - manager.m_capturedLabels.clear(); - - manager.LocalizeString_s("@hello\r@world", outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - manager.m_capturedLabels.clear(); - - manager.LocalizeString_s("@hello @world", outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - manager.m_capturedLabels.clear(); -} - - -// this test makes sure that multiple whitespace characters in a row don't themselves count as tokens or change the output in undesirable ways. -TEST_F(SystemFixture, LocalizeStringInternal_ManyWhitespaceCharacters_CorrectlyTokenizes) -{ - UnitTestCLocalizedStringsManager manager(&m_system); - manager.SetLanguage("french"); - - string outString; - const char* testString = "@hello\n\r\t \t\r\n@world\n\r\t "; - manager.LocalizeString_ch(testString, outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - - // since there are no localizations available it should not have gobbled up whitespace or altered it. - EXPECT_STREQ(outString, testString); -} diff --git a/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp b/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp deleted file mode 100644 index e384893e10..0000000000 --- a/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include -#include -#include -#include - -namespace UnitTests -{ - class CSystemUnitTests - : public ::testing::Test - { - public: - void SetUp() override - { - SSystemInitParams startupParams; - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - m_system = new CSystem(startupParams.pSharedEnvironment); - } - - void TearDown() override - { - delete m_system; - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - } - - - CSystem* m_system = nullptr; - }; - - TEST_F(CSystemUnitTests, ApplicationLogInstanceUnitTests) - { - const char dummyString[] = "dummy"; - const char testString[] = "test"; - EXPECT_EQ(m_system->GetApplicationLogInstance(dummyString), 0); - EXPECT_EQ(m_system->GetApplicationLogInstance(testString), 0); -#if AZ_TRAIT_OS_USE_WINDOWS_MUTEX - EXPECT_EQ(m_system->GetApplicationLogInstance(dummyString), 1); -#endif - } -} diff --git a/Code/CryEngine/CrySystem/Tests/test_Main.cpp b/Code/CryEngine/CrySystem/Tests/test_Main.cpp deleted file mode 100644 index 5ae78cabbf..0000000000 --- a/Code/CryEngine/CrySystem/Tests/test_Main.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include -#include -#include - -class CrySystemTestEnvironment - : public AZ::Test::ITestEnvironment - , public ::UnitTest::TraceBusRedirector -{ -public: - virtual ~CrySystemTestEnvironment() - {} - -protected: - void SetupEnvironment() override - { - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - ::UnitTest::TraceBusRedirector::BusConnect(); - } - - void TeardownEnvironment() override - { - ::UnitTest::TraceBusRedirector::BusDisconnect(); - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - } -}; - -AZ_UNIT_TEST_HOOK(new CrySystemTestEnvironment) diff --git a/Code/CryEngine/CrySystem/Tests/test_MaterialUtils.cpp b/Code/CryEngine/CrySystem/Tests/test_MaterialUtils.cpp deleted file mode 100644 index 99077e41e8..0000000000 --- a/Code/CryEngine/CrySystem/Tests/test_MaterialUtils.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "CrySystem_precompiled.h" -#include - -#include -#include -#include "MaterialUtils.h" - -#include - - -TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestBasics) -{ - char tempBuffer[AZ_MAX_PATH_LEN] = { 0 }; - // call to ensure that it handles nullptr without crashing - MaterialUtils::UnifyMaterialName(nullptr); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(tempBuffer[0] == 0); -} - -TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestExtensions) -{ - char tempBuffer[AZ_MAX_PATH_LEN]; - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "blahblah.mtl"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "blahblah") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "blahblah.mat.mat.abc.test.mtl"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "blahblah.mat.mat.abc.test") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "test/.mat.mat/blahblah.mat.mat.abc.test.mtl"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "test/.mat.mat/blahblah.mat.mat.abc.test") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, ".mat.mat.blahblah.mat.mat.abc.test.mtl"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, ".mat.mat.blahblah.mat.mat.abc.test") == 0); -} - -TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestPrefixes) -{ - char tempBuffer[AZ_MAX_PATH_LEN]; - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, ".\\blahblah.mat"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "blahblah") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "./materials/blahblah.mat.mat.abc.test"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, ".\\engine\\materials\\blahblah.mat.mat.abc.test"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "engine/materials/blahblah.mat.mat.abc.test"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "materials/blahblah.mat"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah") == 0); -} - -TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestGameName) -{ - char tempBuffer[AZ_MAX_PATH_LEN]; - - auto projectName = AZ::Utils::GetProjectName(); - azsnprintf(tempBuffer, AZ_MAX_PATH_LEN, ".\\%s\\materials\\blahblah.mat.mat.abc.test", projectName.c_str()); - - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0); -} diff --git a/Code/CryEngine/CrySystem/Timer.h b/Code/CryEngine/CrySystem/Timer.h index 8778405067..33cfbd6087 100644 --- a/Code/CryEngine/CrySystem/Timer.h +++ b/Code/CryEngine/CrySystem/Timer.h @@ -31,7 +31,7 @@ public: // interface ITimer ---------------------------------------------------------- - // TODO: Review m_time usage in System.cpp / SystemRender.cpp + // TODO: Review m_time usage in System.cpp // if it wants Game Time / UI Time or a new Render Time? virtual void ResetTimer(); diff --git a/Code/CryEngine/CrySystem/UnixConsole.cpp b/Code/CryEngine/CrySystem/UnixConsole.cpp deleted file mode 100644 index 5ec186b8b8..0000000000 --- a/Code/CryEngine/CrySystem/UnixConsole.cpp +++ /dev/null @@ -1,2518 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for UNIX systems based on curses ncurses - - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "UnixConsole.h" - -#if defined(USE_DEDICATED_SERVER_CONSOLE) - -#if defined(USE_UNIXCONSOLE) - -#if !defined(WIN32) -#include -#include -#include -#include -#if defined(MAC) -#include -#include -#else -#include -#endif // defined(MAC) -#if defined(LINUX) || defined(MAC) - #include -#endif -#endif -#include - -#define UNIXConsole_MORE_LEFT "<<" -#define UNIXConsole_MORE_RIGHT ">>" -#define UNIXConsole_MORE_COLOR (3) // Colorpair index -#define UNIXConsole_PROMPT "] " -#define UNIXConsole_PROMPT_COLOR (2) // Colorpair index -#define UNIXConsole_WRAP_CHAR '\\' -#define UNIXConsole_WRAP_COLOR (4) -#define UNIXConsole_MIN_WIDTH (10) -#define UNIXConsole_MAX_LINES (1000) -#define UNIXConsole_MAX_HISTORY (100) - -#if defined(LINUX) || defined(MAC) -// Should find a better test for ncurses... -#define NCURSES 1 -#endif - -#if defined(WIN32) -#define snprintf _snprintf -#endif - -// macro which check if we should process console function -// used for disable console on Linux -#define IS_SHOW_CONSOLE if (!m_bShowConsole) {return; } -#define IS_SHOW_CONSOLE_RET(ret) if (!m_bShowConsole) {return ret; } - - -CryCriticalSectionNonRecursive CUNIXConsole::m_cleanupLock; - -class CUNIXConsoleInputThread - : public CrySimpleThread<> -{ - CUNIXConsole& m_UNIXConsole; -#if !defined(WIN32) - int m_IntrPipe[2]; -#else - HANDLE m_IntrEvent; -#endif - bool m_Cancelled; - -public: - CUNIXConsoleInputThread(CUNIXConsole& UNIXConsole) - : m_UNIXConsole(UNIXConsole) - , m_Cancelled(false) - { -#if !defined(WIN32) - pipe(m_IntrPipe); -#else - m_IntrEvent = CreateEvent(NULL, true, false, NULL); -#endif - } - - ~CUNIXConsoleInputThread() - { -#if !defined(WIN32) - close(m_IntrPipe[0]); - close(m_IntrPipe[1]); -#else - CloseHandle(m_IntrEvent); -#endif - } - - virtual void Run(); - virtual void Cancel() { m_Cancelled = true; Interrupt(); } - void Interrupt() - { -#if !defined(WIN32) - write(m_IntrPipe[1], "", 1); -#else - SetEvent(m_IntrEvent); -#endif - } -}; - -class CUNIXConsoleSignalHandler -{ - friend class CUNIXConsole; - - static CUNIXConsole* m_pUNIXConsole; - static void Handler(int signum); -}; - -CUNIXConsole::CUNIXConsole() - : m_HistoryIndex(-1) - , m_PromptResponse(0) - , m_pSystem(NULL) - , m_pConsole(NULL) - , m_pTimer(NULL) - , m_OnUpdateCalled(false) - , m_LastUpdateTime(0.0f) - , m_svMap(NULL) - , m_svGameRules(NULL) - , m_Width(~0) - , m_Height(~0) - , m_HeaderHeight(1) - , m_StatusHeight(1) - , m_CmdHeight(2) - , m_Color(DEFAULT_COLOR) - , m_DefaultColorPair(-1) - , m_EnableColor(true) - , m_WindowResized(false) - , m_OnShutdownCalled(false) - , m_Initialized(false) - , m_RequireDedicatedServer(false) - , m_ScrollUp(0) - , m_InputThread(NULL) - , m_CursorPosition(0) - , m_ScrollPosition(0) - , m_fsMode(false) - , m_bShowConsole(true) -{ -} - -CUNIXConsole::~CUNIXConsole() -{ - Cleanup(); - m_Lock.Lock(); -} - -void CUNIXConsole::SetRequireDedicatedServer(bool value) -{ - assert(!m_Initialized); - m_RequireDedicatedServer = value; -} - -#if defined(WIN32) || defined(WIN64) -void ResizeConBufAndWindow(HANDLE hConsole, SHORT xSize, SHORT ySize) -{ - CONSOLE_SCREEN_BUFFER_INFO csbi; /* hold current console buffer info */ - BOOL bSuccess; - SMALL_RECT srWindowRect; /* hold the new console size */ - COORD coordScreen; - - bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi); - /* get the largest size we can size the console window to */ - coordScreen = GetLargestConsoleWindowSize(hConsole); - /* define the new console window size and scroll position */ - srWindowRect.Right = (SHORT) (min(xSize, coordScreen.X) - 1); - srWindowRect.Bottom = (SHORT) (min(ySize, coordScreen.Y) - 1); - srWindowRect.Left = srWindowRect.Top = (SHORT) 0; - /* define the new console buffer size */ - coordScreen.X = xSize; - coordScreen.Y = ySize; - /* if the current buffer is larger than what we want, resize the */ - /* console window first, then the buffer */ - if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y > (DWORD) xSize * ySize) - { - bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect); - bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen); - bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect); - bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen); - } - /* if the current buffer is smaller than what we want, resize the */ - /* buffer first, then the console window */ - if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y < (DWORD) xSize * ySize) - { - bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen); - bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect); - } - /* if the current buffer *is* the size we want, don't do anything! */ - return; -} - -BOOL WINAPI CtrlHandler(DWORD evt) -{ - switch (evt) - { - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - return TRUE; - case CTRL_CLOSE_EVENT: - gEnv->pSystem->Quit(); - return TRUE; - } - return FALSE; -} -#endif - -void CUNIXConsole::Init(const char* headerString) -{ - assert(!m_Initialized); - - if (headerString != NULL) - { - m_HeaderString = headerString; - } - -#if defined(WIN32) || defined(WIN64) - // Allocate a console for the process. We don't care if this is successful - // or not, because failure indicates that the process already has a - // console, which is fine. - AllocConsole(); - HANDLE hConsOut = GetStdHandle(STD_OUTPUT_HANDLE); - ResizeConBufAndWindow(hConsOut, 120, 60); - SetConsoleCtrlHandler(CtrlHandler, TRUE); -#endif - - // Initialize curses. - initscr(); - cbreak(); - noecho(); - nonl(); - intrflush(stdscr, FALSE); - keypad(stdscr, TRUE); - scrollok(stdscr, TRUE); - idcok(stdscr, TRUE); - idlok(stdscr, TRUE); - nodelay(stdscr, TRUE); - - // Enable color output. - if (m_EnableColor) - { - if (start_color() != OK) - { - m_EnableColor = false; - } - } - - if (m_EnableColor) - { -#if defined(NCURSES) - // Setup the color table. - short colorPair = 0; - attr_t attr; - attr_get(&attr, &colorPair, NULL); - m_DefaultColorPair = colorPair; - m_ColorPair[0] = m_DefaultColorPair; - m_ColorPair[1] = m_DefaultColorPair; - short color_fg = 0, color_bg = 0; - pair_content(m_DefaultColorPair, &color_fg, &color_bg); - short pair = 0; - init_pair(++pair, COLOR_BLUE, color_bg); - m_ColorPair[2] = pair; - init_pair(++pair, COLOR_GREEN, color_bg); - m_ColorPair[3] = pair; - init_pair(++pair, COLOR_RED, color_bg); - m_ColorPair[4] = pair; - init_pair(++pair, COLOR_CYAN, color_bg); - m_ColorPair[5] = pair; - init_pair(++pair, COLOR_YELLOW, COLOR_BLACK); - m_ColorPair[6] = pair; - init_pair(++pair, COLOR_MAGENTA, color_bg); - m_ColorPair[7] = pair; - init_pair(++pair, COLOR_RED, color_bg); - m_ColorPair[8] = pair; - init_pair(++pair, COLOR_BLACK, COLOR_WHITE); - m_ColorPair[9] = pair; -#else - // Color output supported only for ncurses. - m_EnableColor = false; - m_DefaultColorPair = 0; -#endif - } - else - { - m_DefaultColorPair = 0; - } - - // Set the screen size and draw the initial screen. - SetSize(COLS, LINES); - - m_syslogStats.Init(); - - m_Initialized = true; -} - -void CUNIXConsole::Cleanup() -{ - m_cleanupLock.Lock(); - if (m_Initialized) - { - // Kill the input thread. - if (m_InputThread != NULL) - { - m_InputThread->Cancel(); - m_InputThread->WaitForThread(); - delete m_InputThread; - m_InputThread = NULL; - } - - // Curses cleanup. - clear(); - endwin(); - - m_Initialized = false; - } - m_cleanupLock.Unlock(); -} - -void CUNIXConsole::SetSize(unsigned width, unsigned height) -{ - bool repaint = false; - - assert(IsLocked()); - if (width != m_Width) - { - m_Width = width; - FixCursorPosition(); - repaint = true; - } - if (height != m_Height) - { - m_Height = height; - repaint = true; - } - if (repaint) - { - Repaint(); - } -} - -bool CUNIXConsole::IsTooSmall() -{ - assert(IsLocked()); - if (m_Height < m_HeaderHeight + m_StatusHeight + m_CmdHeight + 1) - { - return true; - } - if (m_Width < UNIXConsole_MIN_WIDTH) - { - return true; - } - return false; -} - -void CUNIXConsole::CheckResize() -{ - assert(IsLocked()); -#if defined(NCURSES) - int lines, cols; - - IS_SHOW_CONSOLE - - if (m_WindowResized) - { - m_WindowResized = false; - // Get the new window size from the terminal driver. - winsize ws; - memset(&ws, 0, sizeof ws); - ioctl(1, TIOCGWINSZ, &ws); - lines = ws.ws_row; - cols = ws.ws_col; - if (m_Width != lines || m_Height != cols) - { - resizeterm(lines, cols); - SetSize(cols, lines); - Repaint(); - } - } -#endif -} - -void CUNIXConsole::NewLine() -{ - char lineBuf[3] = "\1X"; - bool doScroll = !m_LineBuffer.empty(); - - assert(IsLocked()); - lineBuf[1] = m_Color + '0'; - - if (m_LineBuffer.size() == UNIXConsole_MAX_LINES) - { - m_LineBuffer.pop_front(); - } - m_LineBuffer.push_back(lineBuf); - - if (doScroll) - { - ScrollLog(); - } - else - { - unsigned row = m_Height - m_CmdHeight - m_StatusHeight - 1; - move(row, 0); - } - if (m_ScrollUp > 0) - { - const string& lastDisplayLine - = m_LineBuffer[m_LineBuffer.size() - m_ScrollUp - 1]; - DrawLogLine(lastDisplayLine); - } -} - -void CUNIXConsole::ContinueLine() -{ - IS_SHOW_CONSOLE - - if (m_LineBuffer.empty()) - { - NewLine(); - return; - } - const string& lastLine = *m_LineBuffer.rbegin(); - unsigned column = DrawLogLine(lastLine, true /* noOutput */); - SetColorRaw(m_Color); - const unsigned row = m_Height - m_CmdHeight - m_StatusHeight - 1; - move(row, column); -} - -void CUNIXConsole::SetColor(int color) -{ - assert(IsLocked()); - m_Color = color; - SetColorRaw(color); - if (m_LineBuffer.empty()) - { - m_LineBuffer.push_back(""); - } - const TLineBuffer::const_reverse_iterator it = m_LineBuffer.rbegin(); - string& lastLine = const_cast(*it); - lastLine.push_back(1); - lastLine.push_back('0' + color); -} - -void CUNIXConsole::SetColorRaw(int color) -{ - attr_t colorAttr = 0; - - assert(IsLocked()); - if (color == DEFAULT_COLOR) - { - color = 0; - } - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(m_ColorPair[color]); - } - switch (color) - { - case 0: - attrset(A_NORMAL | colorAttr); - break; - case 1: - attrset(A_REVERSE | colorAttr); - break; - case 2: - case 3: - attrset(A_NORMAL | colorAttr); - break; - case 4: - attrset(A_BOLD | colorAttr); - break; - case 5: - attrset(A_NORMAL | colorAttr); - break; - case 6: - attrset(A_BOLD | colorAttr); - break; - case 7: - case 8: - case 9: - attrset(A_NORMAL | colorAttr); - break; - default: - abort(); - } -} - -void CUNIXConsole::Put(int c) -{ - assert(IsLocked()); - - // Get the last buffer line. - if (m_LineBuffer.empty()) - { - NewLine(); - } - const TLineBuffer::const_reverse_iterator it = m_LineBuffer.rbegin(); - string& lastLine = const_cast(*it); - assert(c >= 0x20); - - // Wrap the line if required. - unsigned row = m_Height - m_CmdHeight - m_StatusHeight - 1; - unsigned column = 0; - GetLineHeight(lastLine, &column); - assert(column <= m_Width); - lastLine.push_back(char(c)); - - if (m_ScrollUp == 0) - { - // Output the line wrap character. - if (column == m_Width - 1) - { - move(row, m_Width - 1); - attr_t colorAttr = 0; - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_WRAP_COLOR); - } - attrset(A_NORMAL | colorAttr); - addch(UNIXConsole_WRAP_CHAR); - ScrollLog(); - move(row, 0); - } - - // Output the character. - SetColorRaw(m_Color); - addch(c); - } -} - -void CUNIXConsole::Put(const char* s) -{ - assert(IsLocked()); - while (*s) - { - if (*s == '\n') - { - NewLine(); - } - else - { - Put(*s); - } - ++s; - } -} - -unsigned CUNIXConsole::GetLineLength(const string& line) -{ - unsigned length = 0; - - for (string::const_iterator it = line.begin(), itEnd = line.end(); - it != itEnd; - ++it) - { - char c = *it; - if (c == 1) - { - ++it; - assert(it != itEnd); - continue; - } - ++length; - } - return length; -} - -char CUNIXConsole::GetLastCharacter(const string& line, int* color) -{ - char c0 = 0, c1 = 0; - char lastChar = 0; - - if (!line.empty()) - { - for (int i = line.size() - 1; i >= 0; i--) - { - c1 = c0; - c0 = line[i]; - if (c0 == 1) - { - assert(lastChar); - if (color) - { - *color = c1 - '0'; - } - return lastChar; - } - else if (c0 && c1 != 1 && !lastChar) - { - lastChar = c0; - } - } - } - - *color = DEFAULT_COLOR; - if (lastChar) - { - return lastChar; - } - assert(c0 && c0 != 1); - return c0; -} - -unsigned CUNIXConsole::GetLineHeight(const string& line, unsigned* column) -{ - unsigned lineLength = GetLineLength(line); - unsigned height = 1; - - assert(IsLocked()); - while (lineLength > m_Width) - { - lineLength -= m_Width - 1; - ++height; - } - if (column != NULL) - { - *column = lineLength; - } - return height; -} - -void CUNIXConsole::ScrollLog() -{ - if (m_fsMode) - { - return; - } - - // Scroll the log window. We'll do that by defining a software scrolling - // region. The constructor has set scrollok() and idlok(), so the output - // routing will use the hardware scrolling region (if available). - unsigned top = m_HeaderHeight; - unsigned bottom = m_Height - m_CmdHeight - m_StatusHeight; - - assert(IsLocked()); - // Some curses implementations (pdcurses) require the current position to - // be within the defined scrolling region. - move(top, 0); - if (setscrreg(top, bottom) == OK) - { - move(bottom, 0); - addch('\n'); - setscrreg(0, m_Height - 1); - DrawStatus(1); - } - else - { - // Scrolling regions not supported. We'll scroll the entire window and - // the repaint everything except for the log window. - scroll(stdscr); - move(bottom - 1, 0); - attrset(A_NORMAL); - clrtobot(); - DrawHeader(); - DrawStatus(); - DrawCmd(); - } - move(bottom - 1, 0); -} - -bool CUNIXConsole::FixCursorPosition() -{ - IS_SHOW_CONSOLE_RET(false) - - bool repaint = false; - - assert(IsLocked()); - - // Clip the cursor position. - if (m_CursorPosition > (int)m_InputLine.size()) - { - m_CursorPosition = m_InputLine.size(); - } - - // Trivial scroll position fixes. - if (m_CursorPosition < (int)m_Width / 2 && m_ScrollPosition > 0) - { - m_ScrollPosition = 0; - repaint = true; - } - else if (m_CursorPosition < m_ScrollPosition) - { - m_ScrollPosition = m_CursorPosition - m_Width / 4; - repaint = true; - } - - assert(m_ScrollPosition <= m_CursorPosition); - // The method may be called after the cursor has been moved to the - // right, so we may have to scroll the input line. - int displayLenth = m_Width * m_CmdHeight; - displayLenth -= strlen(UNIXConsole_PROMPT); - // If the cursor is at the end of the input line, then we only must leave - // one space for the cursor itself, otherwise we must leave space for the - // right scroll indicator. - if (m_CursorPosition == m_InputLine.size()) - { - displayLenth -= 1; - } - else - { - displayLenth -= strlen(UNIXConsole_MORE_RIGHT); - } - if (m_ScrollPosition < m_CursorPosition - displayLenth) - { - m_ScrollPosition = m_CursorPosition - displayLenth; - repaint = true; - } - - return repaint; -} - -void CUNIXConsole::OnEdit() -{ - assert(IsLocked()); - m_SavedInputLine.clear(); - m_HistoryIndex = -1; - if (m_pConsole != NULL) - { - m_pConsole->ResetAutoCompletion(); - } -} - -void CUNIXConsole::KeyEnter() -{ - bool redrawAll = false; - bool pushCommand = false; - - assert(IsLocked()); - - // Scroll the log window to the bottom. - if (m_ScrollUp > 0) - { - m_ScrollUp = 0; - redrawAll = true; - } - - // Process the input line. - while (!m_InputLine.empty() && m_InputLine[0] == '\\') - { - m_InputLine.erase(0, 1); - } - if (!m_InputLine.empty()) - { - pushCommand = true; - -#if defined(UC_ENABLE_MAGIC_COMMANDS) - // Enable some magic commands intercepted by the console. All magic - // commands start with an '@' character. - { - const char* const command = m_InputLine.c_str(); - if (!azstricmp(command, "@quit")) - { - // We're called from the input thread, hence we can't join it. We - // have to prevent Cleanup() (called via atexit()) from trying to - // join. - CUNIXConsoleInputThread* inputThread = m_InputThread; - m_InputThread = NULL; - Unlock(); - if (m_pSystem != NULL) - { - m_pSystem->Quit(); - inputThread->Exit(); - } - exit(0); - // Not reached. - abort(); - } - // Add other magic commands here. - } -#endif - } - - if (pushCommand) - { - { - m_CommandQueue.push_back(m_InputLine); - } - } - - if (!m_InputLine.empty()) - { - m_CommandHistory.push_back(m_InputLine); - while (m_CommandHistory.size() > UNIXConsole_MAX_HISTORY) - { - m_CommandHistory.pop_front(); - } - m_HistoryIndex = -1; - m_InputLine.clear(); - m_SavedInputLine.clear(); - m_CursorPosition = 0; - m_ScrollPosition = 0; - if (!redrawAll) - { - DrawCmd(); - refresh(); - } - } - - if (redrawAll) - { - Repaint(); - } -} -void CUNIXConsole::KeyUp() -{ - const int historySize = m_CommandHistory.size(); - - assert(IsLocked()); - if (m_HistoryIndex < historySize - 1) - { - if (m_HistoryIndex == -1) - { - m_SavedInputLine = m_InputLine; - } - m_HistoryIndex += 1; - m_InputLine = m_CommandHistory[historySize - m_HistoryIndex - 1]; - m_CursorPosition = m_InputLine.size(); - FixCursorPosition(); - DrawCmd(); - refresh(); - } -} - -void CUNIXConsole::KeyDown() -{ - const int historySize = m_CommandHistory.size(); - - assert(IsLocked()); - if (m_HistoryIndex > -1) - { - m_HistoryIndex -= 1; - if (m_HistoryIndex == -1) - { - m_InputLine = m_SavedInputLine; - m_SavedInputLine.clear(); - } - else - { - m_InputLine = m_CommandHistory[historySize - m_HistoryIndex - 1]; - } - m_CursorPosition = m_InputLine.size(); - FixCursorPosition(); - DrawCmd(); - refresh(); - } -} - -void CUNIXConsole::KeyLeft() -{ - assert(IsLocked()); - if (m_CursorPosition > 0) - { - m_CursorPosition -= 1; - DrawCmd(!FixCursorPosition()); - } -} - -void CUNIXConsole::KeyRight() -{ - assert(IsLocked()); - if (m_CursorPosition < (int)m_InputLine.size()) - { - m_CursorPosition += 1; - DrawCmd(!FixCursorPosition()); - } -} - -void CUNIXConsole::KeyHome(bool ctrl) -{ - assert(IsLocked()); - if (ctrl) - { - const int logHeight = GetLogHeight(); - int maxUp = m_LineBuffer.size() - logHeight; - if (m_ScrollUp != maxUp) - { - m_ScrollUp = maxUp; - Repaint(); - } - } - else if (m_CursorPosition != 0) - { - m_CursorPosition = 0; - DrawCmd(!FixCursorPosition()); - } -} - -void CUNIXConsole::KeyEnd(bool ctrl) -{ - assert(IsLocked()); - if (ctrl) - { - const int logHeight = GetLogHeight(); - int maxUp = m_LineBuffer.size() - logHeight; - if (m_ScrollUp != 0) - { - m_ScrollUp = 0; - Repaint(); - } - } - else if (m_CursorPosition < (int)m_InputLine.size()) - { - m_CursorPosition = m_InputLine.size(); - DrawCmd(!FixCursorPosition()); - } -} - -void CUNIXConsole::KeyBackspace() -{ - assert(IsLocked()); - if (m_CursorPosition > 0) - { - m_InputLine.erase(m_CursorPosition - 1, 1); - m_CursorPosition -= 1; - FixCursorPosition(); - OnEdit(); - DrawCmd(); - } -} - -void CUNIXConsole::KeyDelete() -{ - assert(IsLocked()); - if (m_CursorPosition < (int)m_InputLine.size()) - { - m_InputLine.erase(m_CursorPosition, 1); - FixCursorPosition(); - OnEdit(); - DrawCmd(); - } -} - -void CUNIXConsole::KeyDeleteWord() -{ - assert(IsLocked()); - if (m_CursorPosition > 0) - { - const char* const inputLine = m_InputLine.c_str(); - const char* p = inputLine + m_CursorPosition - 1; - - while (p > inputLine && *p == ' ') - { - --p; - } - while (p > inputLine && *p != ' ') - { - --p; - } - m_InputLine.erase(p - inputLine, m_CursorPosition); - m_CursorPosition = (uint32)(p - inputLine); - FixCursorPosition(); - OnEdit(); - DrawCmd(); - - /* Old std::string based code, kept for reference. - size_t wordIndex; - wordIndex = m_InputLine.find_last_of(" ", m_CursorPosition - 1); - if (wordIndex != string::npos) - { - wordIndex = m_InputLine.find_last_not_of(" ", wordIndex); - if (wordIndex != string::npos) - wordIndex += 1; - } - if (wordIndex == string::npos) - { - m_InputLine.erase(0, m_CursorPosition); - m_CursorPosition = 0; - } - else - { - m_InputLine.erase(wordIndex, m_CursorPosition - wordIndex); - m_CursorPosition = wordIndex; - } - FixCursorPosition(); - OnEdit(); - DrawCmd(); - */ - } -} - -void CUNIXConsole::KeyKill() -{ - assert(IsLocked()); - if (m_CursorPosition < (int)m_InputLine.size()) - { - m_InputLine.resize(m_CursorPosition); - FixCursorPosition(); - OnEdit(); - DrawCmd(); - } -} - -void CUNIXConsole::KeyRepaint() -{ - assert(IsLocked()); - Repaint(); -} - -void CUNIXConsole::KeyTab() -{ - const char* result; - - assert(IsLocked()); - if (m_OnShutdownCalled) - { - return; - } - string Tmp(m_InputLine); - Unlock(); - result = m_pConsole->ProcessCompletion(Tmp.c_str()); - Lock(); - if (result != NULL) - { - if (result[0] == '\\') - { - ++result; - } - m_InputLine = result; - m_CursorPosition = m_InputLine.size(); - FixCursorPosition(); - m_SavedInputLine.clear(); - m_HistoryIndex = -1; - DrawCmd(); - refresh(); - } -} - -void CUNIXConsole::KeyPgUp(bool ctrl) -{ - const int logHeight = GetLogHeight(); - // int logStep = logHeight - 2; - int logStep = ctrl ? 10 : 1; - int maxUp = m_LineBuffer.size() - logHeight; - int prevScrollUp = m_ScrollUp; - - assert(IsLocked()); - if (logStep < 1) - { - logStep = 1; - } - if (maxUp < 0) - { - maxUp = 0; - } - m_ScrollUp += logStep; - if (m_ScrollUp > maxUp) - { - m_ScrollUp = maxUp; - } - if (m_ScrollUp != prevScrollUp) - { - Repaint(); - } -} - -void CUNIXConsole::KeyPgDown(bool ctrl) -{ - const int logHeight = GetLogHeight(); - // int logStep = logHeight - 2; - int logStep = ctrl ? 10 : 1; - int prevScrollUp = m_ScrollUp; - - assert(IsLocked()); - if (logStep < 1) - { - logStep = 1; - } - if (m_ScrollUp > 0) - { - m_ScrollUp -= logStep; - } - if (m_ScrollUp < 0) - { - m_ScrollUp = 0; - } - if (m_ScrollUp != prevScrollUp) - { - Repaint(); - } -} - -void CUNIXConsole::Key(int c) -{ - assert(IsLocked()); - assert(c >= 0x20 && c <= 0xff); - assert(m_CursorPosition <= (int)m_InputLine.size()); - m_InputLine.insert(m_CursorPosition, 1, (char)c); - m_CursorPosition += 1; - FixCursorPosition(); - OnEdit(); - DrawCmd(); - refresh(); -} - -void CUNIXConsole::Repaint() -{ - IS_SHOW_CONSOLE - - assert(IsLocked()); - clear(); - DrawHeader(); - if (m_fsMode) - { - DrawFullscreen(); - } - else - { - DrawLog(); - } - DrawStatus(); - DrawCmd(); - refresh(); -} - -void CUNIXConsole::Flush() -{ - IS_SHOW_CONSOLE - - assert(IsLocked()); - refresh(); -} - -void CUNIXConsole::InputIdle() -{ - IS_SHOW_CONSOLE - - if (m_pTimer == NULL) - { - return; - } - - Lock(); - - CTimeValue now = m_pTimer->GetAsyncTime(); - float timePassed = (now - m_LastUpdateTime).GetSeconds(); - - // If more than 0.2 sec have passed since the last OnUpdate() call, then - // we'll start painting dots to the status line. - if (timePassed > 0.2f) - { - int nDots = (int)(timePassed + 0.5) / 3; - if (nDots > (int) m_Width - 2) - { - nDots = (int)m_Width - 2; - } - if (m_ProgressStatus.length() != nDots) - { - m_ProgressStatus.clear(); - m_ProgressStatus.append(nDots, '.'); - DrawStatus(); - DrawCmd(true); - refresh(); - } - } - - Unlock(); -} - -// get at least n spaces -static char* GetSpaces(int n) -{ - static char* spaceBuffer = 0; - static int spaceBufferSz = 0; - - if (n > spaceBufferSz) - { - spaceBufferSz = MAX(spaceBufferSz * 2, n); - delete[] spaceBuffer; - spaceBuffer = new char[spaceBufferSz]; - memset(spaceBuffer, ' ', spaceBufferSz); - } - - return spaceBuffer; -} - -void CUNIXConsole::DrawHeader() -{ - IS_SHOW_CONSOLE - - const char* const headerString = m_HeaderString.c_str(); - int headerLength = m_HeaderString.size(); - int padLeft = 0, padRight = 0; - const char* term = termname(); - - assert(IsLocked()); - - if (m_HeaderHeight == 0) - { - return; - } - - if (headerLength >= (int)m_Width) - { - padLeft = 0; - padRight = 0; - headerLength = m_Width; - } - else - { - padLeft = (m_Width - headerLength) / 2; - padRight = m_Width - headerLength - padLeft; - } - move(m_HeaderHeight - 1, 0); -#if defined(LINUX) - // For the Linux console ncurses reports the A_UNDERLINE is supported, even - // thought it is not. We'll do an explicit test for the terminal type - // "linux" (i.e. Linux console). - if ((termattrs() & A_UNDERLINE) && strcasecmp(term, "linux")) - { - attrset(A_UNDERLINE); - } - else -#endif - { - if (m_EnableColor) - { - attrset(A_BOLD | COLOR_PAIR(m_ColorPair[2] /* blue */)); - } - else - { - attrset(A_REVERSE); - } - } - scrollok(stdscr, FALSE); - addnstr(GetSpaces(padLeft), padLeft); - addnstr(headerString, headerLength); - addnstr(GetSpaces(padRight), padRight); - scrollok(stdscr, TRUE); - attrset(A_NORMAL); -} - -// Output a single log line. -// If the noOutput flag is set to 'true', then no output is written to the -// screen and no cursor movements are performed. -// The method returns the current output column (i.e. the output column for -// the next charater to be written to the log window). -// Note: Even it the noOutput flag is set, the method will update the m_Color -// field of the UNIX console. -unsigned CUNIXConsole::DrawLogLine(const string& line, bool noOutput) -{ - IS_SHOW_CONSOLE_RET(0) - - const unsigned row = m_Height - m_CmdHeight - m_StatusHeight - 1; - unsigned column = 0; - - if (!noOutput) - { - assert(IsLocked()); - move(row, column); - attrset(A_NORMAL); - } - for (string::const_iterator it = line.begin(), itEnd = line.end(); it != itEnd; ) - { - char c = *it++; - if (column == m_Width - 1) - { - if (!noOutput) - { - attr_t colorAttr = 0; - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_WRAP_COLOR); - } - attrset(A_NORMAL | colorAttr); - addch(UNIXConsole_WRAP_CHAR); - ScrollLog(); - move(row, 0); - SetColorRaw(m_Color); - } - column = 0; - } - if (c == 1) - { - assert(it != itEnd); - int color = *it - '0'; - m_Color = color; - ++it; - if (!noOutput) - { - SetColorRaw(color); - } - continue; - } - if (!noOutput) - { - addch(c); - } - ++column; - } - return column; -} - -// The scrollUp parameter indicates how many log lines to scroll up from the -// bottom. -void CUNIXConsole::DrawLog() -{ - IS_SHOW_CONSOLE - - unsigned scrollUp = m_ScrollUp; - - assert(IsLocked()); - - if (IsTooSmall()) - { - return; - } - if (m_LineBuffer.empty()) - { - return; - } - - // DrawLog is called only on refresh and on window resize, so performance is - // not an issue. We'll simply repaint by re-sending the log lines from the - // scroll buffer. - int nLines = m_LineBuffer.size(); - int lastLine = nLines - 1 - (int)scrollUp; - int firstLine = lastLine - GetLogHeight(); - - if (firstLine < 0) - { - firstLine = 0; - } - for (int i = firstLine; i <= lastLine; ++i) - { - const string& line = m_LineBuffer[i]; - if (i > firstLine) - { - ScrollLog(); - } - DrawLogLine(line); - } -} - -void CUNIXConsole::DrawStatus(int maxLines) -{ - IS_SHOW_CONSOLE - - unsigned row = m_Height - m_CmdHeight - m_StatusHeight; - const char* statusLeft = NULL; - const char* statusRight = NULL; - char bufferLeft[256]; - char bufferRight[256]; - - assert(IsLocked()); - - if (IsTooSmall() || maxLines == 0 || m_StatusHeight == 0) - { - return; - } - else if (maxLines == -1) - { - maxLines = m_StatusHeight; - } - - // If we're scrolled, then the right size shows a scroll indicator. - if (m_ScrollUp > 0) - { - const int logHeight = GetLogHeight(); - int logBottomLine = (int)m_LineBuffer.size() - m_ScrollUp; - assert(logBottomLine >= 0); - float percent = 100.f * (float)logBottomLine / m_LineBuffer.size(); - if (m_ScrollUp == m_LineBuffer.size() - logHeight) - { - cry_strcpy(bufferRight, "| SCROLL:TOP "); - } - else - { - snprintf( - bufferRight, - sizeof bufferRight, - "| SCROLL:%.1f%% ", - percent); - bufferRight[sizeof(bufferRight) - 1] = 0; - } - statusRight = bufferRight; - } - - if (!m_Prompt.empty()) - { - // No status display when a user prompt is active. - } - else if (!m_ProgressStatus.empty()) - { - snprintf(bufferLeft, sizeof bufferLeft, " %s", m_ProgressStatus.c_str()); - bufferLeft[sizeof bufferLeft - 1] = 0; - statusLeft = bufferLeft; - } - else if (m_OnUpdateCalled) - { - // Standard status display. - // Map name and game rules on the left. - // Current update rate and player count on the right. - const char* mapName = m_svMap->GetString(); - const char* gameRules = m_svGameRules->GetString(); - snprintf(bufferLeft, sizeof bufferLeft, - " map:%s rules:%s", - mapName, - gameRules); - bufferLeft[sizeof bufferLeft - 1] = 0; - statusLeft = bufferLeft; - float updateRate = 0.f; - static float displayUpdateRate = 0.f; - if (m_pTimer != NULL) - { - updateRate = m_pTimer->GetFrameRate(); -#if 0 - // Avoid jumping numbers in the update rate display. Per update the - // displayed update rate changes by at most maxDeltaRate. - const static float maxDeltaRate = 10.0f; - if (updateRate - displayUpdateRate > maxDeltaRate) - { - displayUpdateRate += maxDeltaRate; - } - else if (updateRate - displayUpdateRate < -maxDeltaRate) - { - displayUpdateRate -= maxDeltaRate; - } - else - { - displayUpdateRate = updateRate; - } -#else - // Display the update rate as reported by the timer. - displayUpdateRate = updateRate; -#endif - } - else - { - displayUpdateRate = 0.f; - } - if (statusRight == NULL) - { - char* pBufferRight = bufferRight; - char* const pBufferRightEnd = bufferRight + sizeof bufferRight; - azstrcpy(pBufferRight, AZ_ARRAY_SIZE(bufferRight), "| "); - pBufferRight += strlen(pBufferRight); - int numPlayers = 0; - - if (pBufferRight < pBufferRightEnd) - { - if (m_pConsole != NULL) - { - pBufferRight += snprintf( - pBufferRight, - pBufferRightEnd - pBufferRight, - "upd:%.1fms(%.2f..%.2f) " \ - "rate:%.1f/s", - m_updStats.avgUpdateTime, m_updStats.minUpdateTime, m_updStats.maxUpdateTime, - displayUpdateRate); - } - else - { - cry_strcpy(pBufferRight, pBufferRightEnd - pBufferRight, "BUSY "); - } - } - bufferRight[sizeof bufferRight - 1] = 0; - statusRight = bufferRight; - } - } - else - { - // No status display (blank). This branch is taken on the very first draw - // operation of the UNIX console. - } - if (statusLeft == NULL) - { - statusLeft = ""; - } - if (statusRight == NULL) - { - statusRight = ""; - } - - int leftWidth = strlen(statusLeft); - int rightWidth = strlen(statusRight); - int pad = 0; - - if (leftWidth + rightWidth > (int)m_Width) - { - pad = 0; - if (rightWidth > (int)m_Width) - { - leftWidth = 0; - rightWidth = m_Width; - } - else - { - leftWidth = m_Width - rightWidth; - } - } - else - { - pad = m_Width - leftWidth - rightWidth; - } - - move(row, 0); - attrset(A_REVERSE | A_BOLD); - scrollok(stdscr, FALSE); - for (int i = 0; i < leftWidth; ++i) - { - addch(statusLeft[i]); - } - for (int i = 0; i < pad; ++i) - { - addch(' '); - } - for (int i = 0; i < rightWidth; ++i) - { - addch(statusRight[i]); - } - scrollok(stdscr, TRUE); - attrset(A_NORMAL); -} - -void CUNIXConsole::DrawFullscreen() -{ - IS_SHOW_CONSOLE - - scrollok(stdscr, FALSE); - - int maxy = 1; - for (DynArray::iterator iter = m_drawCmds.begin(); iter != m_drawCmds.end(); ++iter) - { - maxy = max(maxy, iter->y); - } - - int scrolly = min(maxy - 1, m_ScrollUp); - - for (DynArray::iterator iter = m_drawCmds.begin(); iter != m_drawCmds.end(); ++iter) - { - switch (iter->op) - { - case eCDO_PutText: - { - int y = iter->y - scrolly; - if (y < 0 || y > (int)m_Height - 4) - { - break; - } - if (iter->x < 0 || iter->x > (int)m_Width) - { - break; - } - int len = strlen(iter->text); - if (iter->x + len > (int)m_Width) - { - len = m_Width - iter->x; - } - move(y + 1, iter->x); - for (int i = 0; i < len; i++) - { - addch(iter->text[i]); - } - } - } - } - scrollok(stdscr, TRUE); -} - -void CUNIXConsole::DrawCmd(bool cursorOnly) -{ - IS_SHOW_CONSOLE - - unsigned row = m_Height - m_CmdHeight; - unsigned column = 0; - attr_t colorAttr = 0; - const unsigned promptWidth = strlen(UNIXConsole_PROMPT); - const unsigned moreLeftWidth = strlen(UNIXConsole_MORE_LEFT); - const unsigned moreRightWidth = strlen(UNIXConsole_MORE_RIGHT); - - assert(IsLocked()); - - // If the window is too small, then don't draw anything. - if (IsTooSmall() - || m_CmdHeight == 0 - || m_Width < promptWidth + moreLeftWidth + moreRightWidth) - { - return; - } - - if (!m_Prompt.empty()) - { - DrawCmdPrompt(); - return; - } - - if (!cursorOnly) - { - scrollok(stdscr, FALSE); - - // Draw the command prompt. - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_PROMPT_COLOR); - } - attrset(A_BOLD | colorAttr); - move(row, 0); - for (const char* p = UNIXConsole_PROMPT; *p; ++p) - { - addch(*p); - ++column; - } - - // Draw the left scroll indicator (if scrolled). - if (m_ScrollPosition > 0) - { - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_MORE_COLOR); - } - attrset(A_NORMAL | colorAttr); - for (const char* p = UNIXConsole_MORE_LEFT; *p; ++p) - { - addch(*p); - ++column; - } - } - - // Draw the input line. We'll draw to the end of the command window - // (leaving the last cell blank) and the overdraw the more indicator (if - // required). - string::const_iterator it = m_InputLine.begin(); - string::const_iterator itEnd = m_InputLine.end(); - if (m_ScrollPosition > 0) - { - for (int i = m_ScrollPosition + strlen(UNIXConsole_MORE_LEFT); - i > 0; - --i, ++it) - { - ; - } - } - attrset(A_NORMAL); - bool lineTruncated = false; - for (; it != itEnd; ++it) - { - char c = *it; - if (row == m_Height - 1 && column == m_Width - 1) - { - lineTruncated = true; - break; - } - if (column == m_Width) - { - row += 1; - column = 0; - assert(row < m_Height); - move(row, column); - } - addch(c); - ++column; - } - - // Draw the right scroll indicator (if required). - if (lineTruncated) - { - move(m_Height - 1, m_Width - moreRightWidth); - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_MORE_COLOR); - } - attrset(A_NORMAL | colorAttr); - for (const char* p = UNIXConsole_MORE_RIGHT; *p; ++p) - { - addch(*p); - ++column; - } - } - else - { - attrset(A_NORMAL); - clrtobot(); - move(m_Height - 1, m_Width - 1); - addch(' '); - } - - scrollok(stdscr, TRUE); - } - - // Update the cursor position. - column = m_CursorPosition - m_ScrollPosition + promptWidth; - row = m_Height - m_CmdHeight; - if (column >= m_Width) - { - row += column / m_Width; - column %= m_Width; - } - move(row, column); - refresh(); -} - -void CUNIXConsole::DrawCmdPrompt() -{ - IS_SHOW_CONSOLE - - unsigned row = m_Height - m_CmdHeight; - unsigned column = 0; - - string::const_iterator it = m_Prompt.begin(); - string::const_iterator itEnd = m_Prompt.end(); - attrset(A_BOLD); - clrtobot(); - scrollok(stdscr, FALSE); - move(row, column); - for (; it != itEnd; ++it) - { - char c = *it; - if (row == m_Height - 1 && column == m_Width - 1) - { - break; - } - if (column == m_Width) - { - row += 1; - column = 0; - move(row, column); - } - addch(c); - ++column; - } - scrollok(stdscr, TRUE); - move(row, column); - refresh(); -} - -char CUNIXConsole::Prompt(const char* promptString, const char* responseChars) -{ - char response = 0; - - Lock(); - - while (m_PromptResponse != 0) - { - m_PromptCond.Wait(m_Lock); - } -#ifndef _NDEBUG - // This method is called from __assert_fail, so we better don't put any - // asserts in here... - if (!m_Prompt.empty() || !*promptString || !*responseChars) - { - abort(); - } - if (strlen(responseChars) + 1 > sizeof m_PromptResponseChars) - { - abort(); - } -#endif - m_Prompt = promptString; - cry_strcpy(m_PromptResponseChars, responseChars); - DrawCmd(); - while (m_PromptResponse == 0) - { - m_PromptCond.Wait(m_Lock); - } - response = m_PromptResponse; - m_PromptResponse = 0; - m_Prompt.clear(); - m_PromptResponseChars[0] = 0; - m_PromptCond.Notify(); - DrawCmd(); - - Unlock(); - - return response; -} - -bool CUNIXConsole::IsInputThread() -{ - CrySimpleThread<>* callerThread = CrySimpleThread<>::Self(); - - return callerThread == m_InputThread; -} - -void CUNIXConsole::PrintF(const char* format, ...) -{ - char lineBuffer[1024]; - va_list ap; - - va_start(ap, format); - vsnprintf(lineBuffer, sizeof lineBuffer, format, ap); - lineBuffer[sizeof lineBuffer - 1] = 0; - Print(lineBuffer); - va_end(ap); -} - -void CUNIXConsole::Print(const char* line) -{ - IS_SHOW_CONSOLE - - static string lastLine; - static bool firstCall = true; - const size_t lineLength = strlen(line); - size_t lineOffset = 0; - - Lock(); - - // Check if the last line is a true prefix of the specified text argument. - // It it is a prefix, then the output is added to the last line sent to the - // sink. - if (!firstCall - && lineLength > lastLine.size() - && !strncmp(line, lastLine.c_str(), lastLine.size())) - { - // Line continued. - lineOffset = lastLine.size(); - ContinueLine(); // Will set the correct color. - } - else - { - NewLine(); - SetColor(); - } - lastLine = line; - firstCall = false; - - for (size_t i = lineOffset; i < lineLength; ++i) - { - char c = line[i]; - switch (c) - { - case '\\': - if (i < lineLength - 1 && line[i + 1] == 'n') - { - // Sequence "\\n", treat as "\n". - NewLine(); - ++i; - continue; - } - break; - case '\n': - NewLine(); - continue; - case '\r': - ClearLine(); - continue; - case '\t': - // We'll do it like the graphical console, just add 4 spaces and don't - // care about TAB stops. - for (unsigned j = 0; j < 4; ++j) - { - Put(' '); - } - continue; - case '$': - if (i < lineLength - 1) - { - ++i; - char colorChar = line[i]; - if (isdigit(colorChar)) - { - SetColor(colorChar - '0'); - continue; - } - if (colorChar == 'o' || colorChar == 'O') - { - // Ignore. - continue; - } - } - break; - default: - break; - } - if (c < 0x20) - { - // Unrecognized control character. Ignore. - continue; - } - Put((unsigned char)c); - } - DrawCmd(true); - // Flush(); - - Unlock(); -} - -bool CUNIXConsole::OnError(const char* errorString) -{ - if (!m_Initialized) - { - return true; - } - - return true; -} - -void CUNIXConsole::OnInitProgress(const char* sProgressMsg) -{ - if (!m_Initialized) - { - return; - } - - Lock(); - m_ProgressStatus = sProgressMsg; - DrawStatus(); - DrawCmd(true); - Flush(); - Unlock(); -} - -void CUNIXConsole::OnInit(ISystem* pSystem) -{ - if (m_RequireDedicatedServer && !gEnv->IsDedicated()) - { - return; - } - - Lock(); - - if (!m_Initialized) - { - Init(); - } - - assert(m_pSystem == NULL); - m_pSystem = pSystem; - assert(m_pConsole == NULL); - m_pConsole = pSystem->GetIConsole(); - - // Add the output print sink to the system console. - if (m_pConsole != 0) - { - m_pConsole->AddOutputPrintSink(this); - } - - // Start the input thread. - m_InputThread = new CUNIXConsoleInputThread(*this); - m_InputThread->Start(); - - Unlock(); - -#if defined(NCURSES) - // Setup the signal handler. - struct sigaction action; - memset(&action, 0, sizeof action); - action.sa_handler = CUNIXConsoleSignalHandler::Handler; - sigfillset(&action.sa_mask); - CUNIXConsoleSignalHandler::m_pUNIXConsole = this; - sigaction(SIGWINCH, &action, NULL); - sigset_t mask; - memset(&mask, 0, sizeof mask); - sigemptyset(&mask); - sigaddset(&mask, SIGWINCH); - sigprocmask(SIG_UNBLOCK, &mask, NULL); -#endif -} - -void CUNIXConsole::OnShutdown() -{ - if (!m_Initialized) - { - return; - } - - Lock(); - assert(!m_OnShutdownCalled); - m_pConsole->RemoveOutputPrintSink(this); - m_OnShutdownCalled = true; - Unlock(); - - Cleanup(); -} - -void CUNIXConsole::OnUpdate() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - IS_SHOW_CONSOLE - - if (!m_Initialized) - { - return; - } - - bool updateStatus = false; - static CTimeValue lastStatusUpdate = 0.f; - - if (m_OnShutdownCalled) - { - return; - } - - Lock(); - - if (!m_OnUpdateCalled) - { - m_OnUpdateCalled = true; - assert(m_svMap == NULL); - assert(m_svGameRules == NULL); - m_svMap = m_pConsole->GetCVar("sv_map"); - m_svGameRules = m_pConsole->GetCVar("sv_gamerules"); - assert(m_pTimer == NULL); - m_pTimer = m_pSystem->GetITimer(); - } - - if (!m_ProgressStatus.empty()) - { - m_ProgressStatus.clear(); - updateStatus = true; - } - CTimeValue now = m_pTimer->GetAsyncTime(); - if ((now - lastStatusUpdate).GetSeconds() > 0.1f) - { - updateStatus = true; - } - m_LastUpdateTime = now; - - if (updateStatus) - { - DrawStatus(); - DrawCmd(true); - Flush(); - lastStatusUpdate = now; - } - - while (!m_CommandQueue.empty()) - { - const string& command = m_CommandQueue[0]; - Unlock(); - if (m_pConsole) - { - m_pConsole->ExecuteString(command.c_str()); - - // doing the check again in case m_pConsole was nulled while executing the command - if (m_pConsole) - { - m_pConsole->AddCommandToHistory(command.c_str()); - } - } - Lock(); - m_CommandQueue.pop_front(); - } - - m_pSystem->GetUpdateStats(m_updStats); - - bool fsMode = !m_drawCmds.empty(); - if (fsMode || fsMode != m_fsMode) - { - m_fsMode = fsMode; - Repaint(); - } - - Unlock(); -} - -void CUNIXConsole::GetMemoryUsage(ICrySizer* pSizer) -{ - size_t size = sizeof *this; - - Lock(); - - // We're using string (for various reasons), so our best guess of the - // size is the .size(). - size += m_HeaderString.size(); - size += m_LineBuffer.size() * sizeof(string); - for (TLineBuffer::const_iterator it = m_LineBuffer.begin(), - itEnd = m_LineBuffer.end(); - it != itEnd; - ++it) - { - size += it->size(); - } - size += m_CommandQueue.size() * sizeof(string); - for (TCommandQueue::const_iterator it = m_CommandQueue.begin(), - itEnd = m_CommandQueue.end(); - it != itEnd; - ++it) - { - size += it->size(); - } - size += m_CommandHistory.size() * sizeof(string); - for (TCommandHistory::const_iterator it = m_CommandHistory.begin(), - itEnd = m_CommandHistory.end(); - it != itEnd; - ++it) - { - size += it->size(); - } - if (m_InputThread != NULL) - { - size += sizeof *m_InputThread; - } - size += m_InputLine.size(); - size += m_SavedInputLine.size(); - size += m_ProgressStatus.size(); - - Unlock(); - - pSizer->AddObject(this, size); -} - -Vec2_tpl CUNIXConsole::BeginDraw() -{ - m_newCmds.resize(0); - return Vec2_tpl(80, 25 - 3); -} - -void CUNIXConsole::PutText(int x, int y, const char* msg) -{ - IS_SHOW_CONSOLE - - SConDrawCmd cmd; - cmd.op = eCDO_PutText; - cmd.x = x; - cmd.y = y; - cry_strcpy(cmd.text, msg); - m_newCmds.push_back(cmd); -} - -void CUNIXConsole::EndDraw() -{ - IS_SHOW_CONSOLE - - Lock(); - m_drawCmds.swap(m_newCmds); - Unlock(); -} - -void CUNIXConsoleInputThread::Run() -{ -#if !defined(WIN32) - fd_set rdfds; -#endif - bool interrupted = false; - - // The input thread selects stdin (0) and the interrupt pipe. The select() - // call has a timeout (typically 0.5 sec) and will call the InputIdle() - // method whenever the timer expires. - while (true) - { - interrupted = false; -#if !defined(WIN32) - FD_ZERO(&rdfds); - FD_SET(m_IntrPipe[0], &rdfds); - FD_SET(0, &rdfds); - timeval tv; - memset(&tv, 0, sizeof tv); - tv.tv_sec = 0; - tv.tv_usec = 100000; // 0.1 sec. - if (select(m_IntrPipe[0] + 1, &rdfds, NULL, NULL, &tv) != -1) - { - if (FD_ISSET(m_IntrPipe[0], &rdfds)) - { - char buf; - read(m_IntrPipe[0], &buf, 1); - interrupted = true; - } - else if (!FD_ISSET(0, &rdfds)) - { - // Both m_IntrPipe[0] and 0 are not ready, so this must be a timeout. - m_UNIXConsole.InputIdle(); - continue; - } - } - else - { - // Got interrupted by a signal. - assert(errno == EINTR); - interrupted = true; - } -#else - HANDLE handles[2]; - handles[0] = m_IntrEvent; - handles[1] = GetStdHandle(STD_INPUT_HANDLE); - DWORD result = WaitForMultipleObjects(2, handles, false, 10 /* 0.1 sec */); - switch (result) - { - case WAIT_OBJECT_0: - interrupted = true; - ResetEvent(m_IntrEvent); - break; - case WAIT_OBJECT_0 + 1: - break; - case WAIT_TIMEOUT: - m_UNIXConsole.InputIdle(); - continue; - case WAIT_FAILED: - assert(!"WaitForMultipleObjects() failed"); - } -#endif - if (interrupted) - { - if (m_Cancelled) - { - break; - } - m_UNIXConsole.Lock(); - m_UNIXConsole.CheckResize(); - m_UNIXConsole.Unlock(); - continue; - } - int c = getch(); - m_UNIXConsole.Lock(); - - // Handle prompt responses. - if (!m_UNIXConsole.m_Prompt.empty()) - { - bool acceptAll = false; - char response = 0; - if (strchr(m_UNIXConsole.m_PromptResponseChars, '@')) - { - acceptAll = true; - } - if (c == KEY_ENTER || c == '\r') - { - c = '\n'; - } - if (c == KEY_BACKSPACE || c == 0x7f) - { - c = '\010'; - } - if (c <= 0xff && strchr(m_UNIXConsole.m_PromptResponseChars, (char)c)) - { - response = (char)c; - } - else if (acceptAll && (isprint(c) || c == '\n')) - { - response = (char)c; - } - else - { - beep(); - m_UNIXConsole.Unlock(); - continue; - } - m_UNIXConsole.m_PromptResponse = response; - m_UNIXConsole.m_PromptCond.Notify(); - m_UNIXConsole.Unlock(); - continue; - } - - // if console is hided then pass only F10 key - if (!m_UNIXConsole.m_bShowConsole) - { - if (KEY_F(10) == c) - { - m_UNIXConsole.KeyF(10); - } - m_UNIXConsole.Unlock(); - continue; - } - - switch (c) - { - case ERR: - break; - case KEY_RESIZE: - // Window size changed. This key is received only if the ncurses - // library is configured to handle SIGWINCH and if no other SIGWINCH - // handler has been installed. - m_UNIXConsole.SetSize(COLS, LINES); - m_UNIXConsole.Repaint(); - break; - case KEY_ENTER: - case PADENTER: - case '\r': - case '\n': - m_UNIXConsole.KeyEnter(); - break; - case KEY_UP: - case '\020': // CTRL-P - m_UNIXConsole.KeyUp(); - break; - case KEY_DOWN: - case '\016': // CTRL-N - m_UNIXConsole.KeyDown(); - break; - case KEY_LEFT: - m_UNIXConsole.KeyLeft(); - break; - case KEY_RIGHT: - m_UNIXConsole.KeyRight(); - break; - case KEY_HOME: - case '\001': // CTRL-A - m_UNIXConsole.KeyHome(false); - break; - case CTL_HOME: - m_UNIXConsole.KeyHome(true); - break; - case KEY_END: - case '\005': // CTRL-E - m_UNIXConsole.KeyEnd(false); - break; - case CTL_END: - m_UNIXConsole.KeyEnd(true); - break; - case KEY_BACKSPACE: -#if defined(MAC) - // Mac OS X returns delete key instead of backspace - case 0x7f: -#else - case '\010': // CTRL-H -#endif - m_UNIXConsole.KeyBackspace(); - break; - case KEY_DC: - case KEY_SDC: - case '\004': // CTRL-D - m_UNIXConsole.KeyDelete(); - break; - case '\027': // CTRL-W - m_UNIXConsole.KeyDeleteWord(); - break; - case '\013': // CTRL-K - m_UNIXConsole.KeyKill(); - break; - case '\014': // CTRL-L - m_UNIXConsole.KeyRepaint(); - break; - case '\t': // TAB - m_UNIXConsole.KeyTab(); - break; - case KEY_NPAGE: - case '\006': // CTRL-F - m_UNIXConsole.KeyPgDown(false); - break; - case CTL_PGDN: - m_UNIXConsole.KeyPgDown(true); - break; - case KEY_PPAGE: - case '\002': // CTRL-B - m_UNIXConsole.KeyPgUp(false); - break; - case CTL_PGUP: - m_UNIXConsole.KeyPgUp(true); - break; - case KEY_F(10): - m_UNIXConsole.KeyF(10); - break; - case KEY_F(11): - m_UNIXConsole.KeyF(11); - break; - default: - if (c >= 0x20 && c <= 0xff) - { - m_UNIXConsole.Key(c); - } - break; - } - m_UNIXConsole.Unlock(); - } -} - -void CUNIXConsole::KeyF(int id) -{ -#ifdef LINUX - if (11 == id) - { - def_prog_mode(); - endwin(); - m_bShowConsole = false; - system("/bin/bash"); - reset_prog_mode(); - refresh(); - m_bShowConsole = true; - } - else if (10 == id) - { - if (m_bShowConsole) - { - def_prog_mode(); - endwin(); - m_bShowConsole = false; - } - else - { - reset_prog_mode(); - refresh(); - m_bShowConsole = true; - } - } -#endif -} - -CUNIXConsole* CUNIXConsoleSignalHandler::m_pUNIXConsole = NULL; - -void CUNIXConsoleSignalHandler::Handler(int signum) -{ -#if defined(NCURSES) - switch (signum) - { - case SIGWINCH: - m_pUNIXConsole->m_WindowResized = true; - m_pUNIXConsole->m_InputThread->Interrupt(); - break; - default: - break; - } -#endif -} - -#endif // USE_UNIXCONSOLE - -/////////////////////////////////////////////////////////////////////////////////////// -// -// simple light-weight console implementation -// -/////////////////////////////////////////////////////////////////////////////////////// -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(UnixConsole_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -CNULLConsole::CNULLConsole(bool isDaemonMode) - : m_isDaemon(isDaemonMode) -{ -} - -void CNULLConsole::Print(const char* inszText) -{ - if (m_isDaemon) - { - return; - } - -#if defined(WIN32) || defined(WIN64) - DWORD written; - char buf[1024]; - sprintf_s(buf, "%s\n", inszText); - WriteConsole(m_hOut, buf, strlen(buf), &written, NULL); -#elif defined(LINUX) || defined(MAC) - printf("%s\n", inszText); -#endif -} - -void CNULLConsole::OnInit(ISystem* pSystem) -{ - m_syslogStats.Init(); - - if (m_isDaemon) - { - return; - } - - IConsole* pConsole = pSystem->GetIConsole(); - pConsole->AddOutputPrintSink(this); - -#if defined(WIN32) || defined(WIN64) - AllocConsole(); - m_hOut = GetStdHandle(STD_OUTPUT_HANDLE); -#endif -} - -void CNULLConsole::OnUpdate() -{ -} - -void CNULLConsole::PutText([[maybe_unused]] int x, [[maybe_unused]] int y, [[maybe_unused]] const char* msg) -{ -} -#endif - -/////////////////////////////////////////////////////////////////////////////////////// -// -// Logging server internal statistics into syslog service -// -/////////////////////////////////////////////////////////////////////////////////////// -CSyslogStats::CSyslogStats() - : m_syslog_stats(0) - , m_syslog_period(SYSLOG_DEFAULT_PERIOD) -{ -} - -CSyslogStats::~CSyslogStats() -{ -#if (defined(LINUX) && !defined(ANDROID)) || defined(MAC) -#if defined(NCURSES) - closelog(); -#endif - if (gEnv->pConsole) - { - gEnv->pConsole->UnregisterVariable("syslog_stats"); - gEnv->pConsole->UnregisterVariable("syslog_period"); - } -#endif -} - -void CSyslogStats::Init() -{ -#if (defined(LINUX) && !defined(ANDROID)) || defined(MAC) -#if defined(NCURSES) -# if defined(LINUX) - openlog("LinuxLauncher", LOG_PID, LOG_USER); -# elif defined(MAC) - openlog("MacLauncher", LOG_PID, LOG_USER); -# endif -#endif // NCURSES - - if (gEnv->pConsole) - { - REGISTER_CVAR2("syslog_stats", &m_syslog_stats, 0, 0, "Start/Stop logging server info into syslog"); - REGISTER_CVAR2("syslog_period", &m_syslog_period, SYSLOG_DEFAULT_PERIOD, 0, "Syslog logging timeout period"); - } -#endif -} - -void CSyslogStats::Update([[maybe_unused]] float srvRate, [[maybe_unused]] int numPlayers) -{ -} - -#endif // defined(USE_DEDICATED_SERVER_CONSOLE) - -// vim:ts=2 - diff --git a/Code/CryEngine/CrySystem/UnixConsole.h b/Code/CryEngine/CrySystem/UnixConsole.h deleted file mode 100644 index 12b2852e69..0000000000 --- a/Code/CryEngine/CrySystem/UnixConsole.h +++ /dev/null @@ -1,573 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for UNIX systems, based on curses ncurses. - - -#pragma once - - -#include -#include - -#if defined(USE_DEDICATED_SERVER_CONSOLE) - -class CSyslogStats -{ -public: - CSyslogStats(); - ~CSyslogStats(); - - void Init(); - void Update(float srvRate, int numPlayers); - -private: - int m_syslog_stats; - int m_syslog_period; - CTimeValue m_syslogStartTime; - CTimeValue m_syslogCurrTime; - static const int SYSLOG_DEFAULT_PERIOD = 3000; // default timeout (sec) -}; - -#if defined(USE_UNIXCONSOLE) - -#if defined(WIN32) -// Avoid naming conflict with wincon.h. -#undef MOUSE_MOVED -#endif - -#include -#include - -// Avoid naming conflicts with pdcurses. -// Use werase(stdscr) instead of erase(). -#undef erase -// Use wclear(stdscr) instead of clear(). -#undef clear -// (MATT) Could not compile CONTAINER_VALUE etc templates for Vector{Map,Set} in ISerialise apparently because of the -// clear and erase macros. Changed order to undefine them straight after pdcurses. {2009/04/09} - -#include - - -// Define if you wish to enable the player count feature. -// Note: The player count feature can not be used when building -// Windows-style DLLs! -#if defined(LINUX) || defined(MAC) -#define UC_ENABLE_PLAYER_COUNT 1 -#else -#undef UC_ENABLE_PLAYER_COUNT -#endif - -// Define if you wish to enable magic console commands. -// These are commands starting with an '@' character, which are intercepted by -// the CUNIXConsole class and not passed to the system. -//#undef UC_ENABLE_MAGIC_COMMANDS -#define UC_ENABLE_MAGIC_COMMANDS 1 - -class CUNIXConsoleInputThread; -class CUNIXConsoleSignalHandler; - - -class CUNIXConsole - : public ISystemUserCallback - , public IOutputPrintSink - , public ITextModeConsole -{ - friend class CUNIXConsoleInputThread; - friend class CUNIXConsoleSignalHandler; - - static const int DEFAULT_COLOR = -1; - - typedef CryMutex ConsoleLock; - ConsoleLock m_Lock; - static CryCriticalSectionNonRecursive m_cleanupLock; - - enum EConDrawOp - { - eCDO_PutText, - }; - struct SConDrawCmd - { - EConDrawOp op; - int x, y; - char text[256]; - }; - DynArray m_drawCmds; - DynArray m_newCmds; - bool m_fsMode; - - CSyslogStats m_syslogStats; - bool m_bShowConsole; // hide or show console - - SSystemUpdateStats m_updStats; - - bool IsLocked() { return m_Lock.IsLocked(); } - - // The header string. - // - // Should be set by the launcher through SetHeader(). - string m_HeaderString; - - // The line buffer. - // - // We'll use the escape sequence "\1" followed by a digit to encode color - // changes. - typedef std::deque TLineBuffer; - TLineBuffer m_LineBuffer; - - // The command queue. - // - // Commands typed on the console are added to this command queue. It is - // processed by the OnUpdate() callback. - typedef std::deque TCommandQueue; - TCommandQueue m_CommandQueue; - - // The command history. - // - // The UNIX console is decoupled from the system console object through a - // command queue, so we can't use the history buffer from the system - // console. This is our own command history. - // - // The history index indicates the reverse index (counting from the end) - // into our command history. The special value -1 indicates that we're not - // currently showing a command from the history. - typedef std::deque TCommandHistory; - TCommandHistory m_CommandHistory; - int m_HistoryIndex; - - // Interactive prompt. - // - // If this is not empty, then this prompt is shown in the command area. The - // input thread will wait for one if the response characters. The response is - // stored to m_PromptResponse and m_PromptCond is notified. - string m_Prompt; - char m_PromptResponseChars[16]; // Null-terminated. - char m_PromptResponse; - CryConditionVariable m_PromptCond; - - ISystem* m_pSystem; - IConsole* m_pConsole; - ITimer* m_pTimer; // Initialized on the first call to OnUpdate(). - - // Flag indicating if OnUpdate() has been called. - // - // The initialization of the console variable pointers for 'sv_map' and - // 'sv_gamerules' is deferred until the first iteration of the update loop, - // because OnInit() is called too early for that. - bool m_OnUpdateCalled; - CTimeValue m_LastUpdateTime; - - ICVar* m_svMap; - ICVar* m_svGameRules; - - // Terminal window layout. - // - // The terminal window is split into 4 logical windows. Top to bottom, - // these windows are: - // - Header window. May be empty (height 0). - // - Log window. This is the area in the middle of the terminal showing the - // log messages. - // - Status window. This is a window below the log window showing things - // like current FPS or other status information. - // - Command window. This is a few lines (typically 1 or 2) at the - // bottom of the terminal window. The command prompt and command line - // editor is shown in the command window. - // - // The layout is implementated as a single curses window - the standard - // screen (stdscr). - - // The width and height of the terminal window. - unsigned m_Width, m_Height; - - // The height of the header window. - // The header window is displayed at the top of the terminal window. - // Typically 0 (no header) or 1 (single header line). - unsigned m_HeaderHeight; - - // The height of the status window. - // This is typically a single line between the log window and the command - // window, displayed in inverse video. - unsigned m_StatusHeight; - - // The height of the command window. - // This is typically a single line at the bottom of the screen. - unsigned m_CmdHeight; - - // The current text color. - int m_Color; - - // The default text color pair (read from curses when the app starts). - int m_DefaultColorPair; - - // Flag indicating if color output is enabled. - bool m_EnableColor; - - // Flag indicating that the window has been resized. - // Set by the SIGWINCH signal handler. - bool m_WindowResized; - - // Flag indicating that OnShutdown() has been called. - bool m_OnShutdownCalled; - - // Flag indicating if the console has been initialized (i.e. Init() has been - // called). - bool m_Initialized; - - // Flag indicating if the implied console initialization (performed by the - // OnInit() callback) requires a dedicated server. - // This flag is set through the public SetRequireDedicatedServer() method. - bool m_RequireDedicatedServer; - - // The number of (logical) lines scrolled up. - // 0 indicates that we're at the bottom of the log. - int m_ScrollUp; - - // Array of color pair handles. - // 0: default terminal color - // 1: default terminal color, reverse video - // 2: blue - // 3: green - // 4: red, bold font - // 5: cyan - // 6: yellow on black, bold font - // 7: magenta - // 8: red, normal text - // 9: black on white - short m_ColorPair[10]; - - // The keyboard input thread. - CUNIXConsoleInputThread* m_InputThread; - - // The current input line, cursor position, and horizontal scroll position. - string m_InputLine; - string m_SavedInputLine; - int m_CursorPosition; - int m_ScrollPosition; - - // The current progress status string. - // - // Set by the OnInitProgress() method and cleared by OnUpdate(). If this is - // not empty, then this is shown in the status line. - string m_ProgressStatus; - - // Set the size of the terminal window. - // - // This method is called when the UNIX console is created and whenever the - // size of the terminal window changes (i.e. SIGWINCH received). - // - // We're relying on the ncurses handler for SIGWINCH, so we'll call this - // method when getch() returns KEY_RESIZE. - void SetSize(unsigned width, unsigned height); - - // Check if the terminal window is too small for drawing. - bool IsTooSmall(); - - // Check if the window size has changed. - void CheckResize(); - - // Get the height of the log window. - unsigned GetLogHeight() - { - return m_Height - m_HeaderHeight - m_StatusHeight - m_CmdHeight; - } - - // Scroll the log window and start a new log line. - // - // Move the cursor position to the beginning of the new log line. - void NewLine(); - - // Continue the last log line. - // - // Move the cursor position to the first character following the last - // character logged and update the current color. - void ContinueLine(); - - // Clear the current output line. - // - // Move the cursor to the beginning of the current output line. - // - // Note: This is a bit fuzzy to implement because long wrapped lines are not - // easy to deal with. Instead I'll simply call NewLine() and maybe - // implement this later. - void ClearLine() { NewLine(); } - - // Set the output color. - // - // The color is one of the 10 color codes (0-9) used by the graphical - // console. If color output is enabled, then the corresponding terminal - // color is set. If color output is not enabled, then only the text - // attributes are changed. - // - // In addition to setting the color (if enabled), the method will set the - // following terminal attributes: - // 0, 1: Normal text (black, white) - // 4, 6: Bold text (red, yellow, typically indicates an error or warning) - // other: Underlined text - void SetColor(int color = DEFAULT_COLOR); - void SetColorRaw(int color); - - // Write a single character or a sequence of characters to the console, - // using the currently specified color. The specified character must be a - // printable character. - // - // Note: - // - The Put(const char *) method will interpret '\n' as a line separator an - // call NewLine() when encountered. All other characters must be - // printable characters. - // - Both Put() methods will _not_ update the cursor position before writing - // the character to the screen. It is up to the caller to update the - // cursor position (either by calling NewLine() or ContinueLine()). - void Put(int c); - void Put(const char* s); - - // Get the length of the line (number of displayed characters), not counting - // color change escapes. - static unsigned GetLineLength(const string& line); - - // Get the last printable character from the specified line. It is an error - // if the specified line contains no printable characters. If color is not - // NULL, then the selected color for the last character is stored to *color. - static char GetLastCharacter(const string& line, int* color); - - // Get the height of a line of text. - // - // The method returns the number of terminal lines to display the specified - // line (wrapped). If column is not NULL, then *column is set to the column - // indicating the end of the last wrapped terminal line. - unsigned GetLineHeight(const string& line, unsigned* column = NULL); - - // Scroll the log window one line. - void ScrollLog(); - - // Flush/repaint the screen. - void Flush(); - - // Called by the input thread when idle. - void InputIdle(); - - // Lock/unlock the UNIX console. - void Lock() { m_Lock.Lock(); } - void Unlock() { m_Lock.Unlock(); } - - // Fix the cursor position and scroll position after updating the command - // input line. Returns true if the command window must be repainted. - bool FixCursorPosition(); - - // Called when the command line has been edited. - void OnEdit(); - - // Keyboard input. - void KeyEnter(); - void KeyUp(); - void KeyDown(); - void KeyLeft(); - void KeyRight(); - void KeyHome(bool ctrl); - void KeyEnd(bool ctrl); - void KeyBackspace(); - void KeyDelete(); - void KeyDeleteWord(); - void KeyKill(); - void KeyRepaint(); - void KeyTab(); - void KeyPgUp(bool ctrl); - void KeyPgDown(bool ctrl); - void KeyF(int id); - void Key(int c); - - // Drawing. - void Repaint(); - void DrawHeader(); - unsigned DrawLogLine(const string&, bool noOutput = false); - void DrawLog(); - void DrawFullscreen(); - void DrawStatus(int maxLines = -1); - void DrawCmd(bool cursorOnly = false); - void DrawCmdPrompt(); - - CUNIXConsole(const CUNIXConsole&); - void operator = (const CUNIXConsole&); - -public: - CUNIXConsole(); - ~CUNIXConsole(); - - // Set or clear the RequireDedicatedServer flag. - // The implied initialization call performed by the - // ISystemUserCallback::OnInit() depends on this flag. - // Note: This method _must_ be called before Init() or OnInit() is called. - void SetRequireDedicatedServer(bool); - - // Initialize the console for use. - // - // This method must be called before any other method of the console is - // called. - // It is perfectly valid to instanciate a console and not use it (i.e. skip - // the Init() call). - // - // Note: If the ISystemUserCallback interface is used, then the call to - // Init() is optional. OnInit() will call Init() if it has not been called - // already. - void Init(const char* headerString = NULL); - - // Check if the console is initialized. - bool IsInitialized() { return m_Initialized; } - - // Cleanup function. - // This method is called by the destructor. - // If the instance has not been initialized (via Init() and/or OnInit()), - // then this method has no effect. - void Cleanup(); - - // Set the header string. - // Note: - // - Setting the header string does _not_ trigger a redraw. - // - This method may be called before Init() has been called. - void SetHeader(const char* headerString) - { - Lock(); - m_HeaderString = headerString; - Unlock(); - } - - // Issue a query-response prompt. - // - // promptString is the string to be shown as the query prompt. - // responseChars is a null-terminated string of valid response characters. - // Add '@' to the response characters if the user may type any character. - // - // The method blocks the caller until the user has typed a response. The - // return value is the response character typed by the user. - DLL_EXPORT char Prompt(const char* promptString, const char* responseChars); - - // Check if the calling thread is the input thread. - // - // This may be used to make sure that you're not calling Prompt() from the - // input thread - which will deadlock. - DLL_EXPORT bool IsInputThread(); - - // Print formatted. Calls Print(). - DLL_EXPORT void PrintF(const char* format, ...) PRINTF_PARAMS(2, 3); - - // Interface IOutputPrintSink ///////////////////////////////////////////// - DLL_EXPORT virtual void Print(const char* line); - - // Interface ISystemUserCallback ////////////////////////////////////////// - virtual bool OnError(const char* errorString); - virtual bool OnSaveDocument() { return false; } - virtual bool OnBackupDocument() { return false; } - virtual void OnProcessSwitch() { } - virtual void OnInitProgress(const char* sProgressMsg); - virtual void OnInit(ISystem*); - virtual void OnShutdown(); - virtual void OnUpdate(); - virtual void GetMemoryUsage(ICrySizer* pSizer); - - // Interface ITextModeConsole ///////////////////////////////////////////// - virtual Vec2_tpl BeginDraw(); - virtual void PutText(int x, int y, const char* msg); - virtual void EndDraw(); -}; - -#endif // USE_UNIXCONSOLE - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(UnixConsole_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -// simple light-weight console -class CNULLConsole - : public IOutputPrintSink - , public ISystemUserCallback - , public ITextModeConsole -{ -public: - CNULLConsole(bool isDaemonMode); - - /////////////////////////////////////////////////////////////////////////////////////// - // IOutputPrintSink - /////////////////////////////////////////////////////////////////////////////////////// - virtual void Print(const char* inszText); - - /////////////////////////////////////////////////////////////////////////////////////// - // ISystemUserCallback - /////////////////////////////////////////////////////////////////////////////////////// - /** this method is called at the earliest point the ISystem pointer can be used - the log might not be yet there - */ - virtual void OnSystemConnect([[maybe_unused]] ISystem* pSystem) {}; - /** Signals to User that engine error occured. - @return true to Halt execution or false to ignore this error. - */ - virtual bool OnError([[maybe_unused]] const char* szErrorString) { return false; }; - /** If working in Editor environment notify user that engine want to Save current document. - This happens if critical error have occured and engine gives a user way to save data and not lose it - due to crash. - */ - virtual bool OnSaveDocument() { return false; } - - /** If working in Editor environment and a critical error occurs notify the user to backup - the current document to prevent data loss due to crash. - */ - virtual bool OnBackupDocument() { return false; } - - /** Notify user that system wants to switch out of current process. - (For ex. Called when pressing ESC in game mode to go to Menu). - */ - virtual void OnProcessSwitch() {}; - - // Notify user, usually editor about initialization progress in system. - virtual void OnInitProgress([[maybe_unused]] const char* sProgressMsg) {}; - - // Initialization callback. This is called early in CSystem::Init(), before - // any of the other callback methods is called. - virtual void OnInit(ISystem*); - - // Shutdown callback. - virtual void OnShutdown() {}; - - // Notify user of an update iteration. Called in the update loop. - virtual void OnUpdate(); - - // to collect the memory information in the user program/application - virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) {}; - - /////////////////////////////////////////////////////////////////////////////////////// - // ITextModeConsole - /////////////////////////////////////////////////////////////////////////////////////// - virtual Vec2_tpl BeginDraw() { return Vec2_tpl(0, 0); }; - virtual void PutText(int x, int y, const char* msg); - virtual void EndDraw() {}; - - void SetRequireDedicatedServer(bool) - { - // Does nothing - } - void SetHeader(const char*) - { - //Does nothing - } -private: -#if defined(WIN32) || defined(WIN64) - HANDLE m_hOut; -#endif - bool m_isDaemon; - CSyslogStats m_syslogStats; -}; - -#endif - -#endif // defined(USE_DEDICATED_SERVER_CONSOLE) diff --git a/Code/CryEngine/CrySystem/Validator.h b/Code/CryEngine/CrySystem/Validator.h deleted file mode 100644 index 83dc0533f6..0000000000 --- a/Code/CryEngine/CrySystem/Validator.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_VALIDATOR_H -#define CRYINCLUDE_CRYSYSTEM_VALIDATOR_H - -#pragma once - -////////////////////////////////////////////////////////////////////////// -// Default validator implementation. -////////////////////////////////////////////////////////////////////////// -struct SDefaultValidator - : public IValidator -{ - CSystem* m_pSystem; - SDefaultValidator(CSystem* system) - : m_pSystem(system) {}; - virtual void Report(SValidatorRecord& record) - { - if (record.text) - { - static bool bNoMsgBoxOnWarnings = false; - if ((record.text[0] == '!') || (m_pSystem->m_sysWarnings && m_pSystem->m_sysWarnings->GetIVal() != 0)) - { - if (g_cvars.sys_no_crash_dialog) - { - return; - } - - if (bNoMsgBoxOnWarnings) - { - return; - } - -#ifdef WIN32 - string strMessage = record.text; - strMessage += "\n---------------------------------------------\nAbort - terminate application\nRetry - continue running the application\nIgnore - don't show this message box any more"; - switch (::MessageBox(NULL, strMessage.c_str(), "CryEngine Warning", MB_ABORTRETRYIGNORE | MB_DEFBUTTON2 | MB_ICONWARNING | MB_SYSTEMMODAL)) - { - case IDABORT: - m_pSystem->GetIConsole()->Exit ("User abort requested during showing the warning box with the following message: %s", record.text); - break; - case IDRETRY: - break; - case IDIGNORE: - bNoMsgBoxOnWarnings = true; - m_pSystem->m_sysWarnings->Set(0); - break; - } -#endif - } - } - } -}; - -#endif // CRYINCLUDE_CRYSYSTEM_VALIDATOR_H diff --git a/Code/CryEngine/CrySystem/WindowsConsole.cpp b/Code/CryEngine/CrySystem/WindowsConsole.cpp deleted file mode 100644 index c83606890e..0000000000 --- a/Code/CryEngine/CrySystem/WindowsConsole.cpp +++ /dev/null @@ -1,1153 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : CWindowsConsole member definitions - - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "WindowsConsole.h" - -#ifdef USE_WINDOWSCONSOLE - -#define WINDOWS_CONSOLE_WIDTH 128 -#define WINDOWS_CONSOLE_HEIGHT 50 -#define WINDOWS_CONSOLE_LOG_BUFFER_LINES 1024 -#define WINDOWS_CONSOLE_LOG_SCROLL_LINES 10 -#define WINDOWS_CONSOLE_TAB_SIZE 4 -#define WINDOWS_CONSOLE_CRYENGINE_BLACK 0x0 -#define WINDOWS_CONSOLE_CRYENGINE_WHITE 0x1 -#define WINDOWS_CONSOLE_CRYENGINE_BLUE 0x2 -#define WINDOWS_CONSOLE_CRYENGINE_GREEN 0x3 -#define WINDOWS_CONSOLE_CRYENGINE_RED 0x4 -#define WINDOWS_CONSOLE_CRYENGINE_CYAN 0x5 -#define WINDOWS_CONSOLE_CRYENGINE_YELLOW 0x6 -#define WINDOWS_CONSOLE_CRYENGINE_MAGENTA 0x7 -#define WINDOWS_CONSOLE_CRYENGINE_ORANGE 0x8 -#define WINDOWS_CONSOLE_CRYENGINE_GREY 0x9 -#define WINDOWS_CONSOLE_NATIVE_BLACK 0x0 -#define WINDOWS_CONSOLE_NATIVE_BROWN 0x6 -#define WINDOWS_CONSOLE_NATIVE_LIGHTGREY 0x7 -#define WINDOWS_CONSOLE_NATIVE_LIGHTBLUE 0x9 -#define WINDOWS_CONSOLE_NATIVE_LIGHTGREEN 0xA -#define WINDOWS_CONSOLE_NATIVE_LIGHTCYAN 0xB -#define WINDOWS_CONSOLE_NATIVE_LIGHTRED 0xC -#define WINDOWS_CONSOLE_NATIVE_LIGHTMAGENTA 0xD -#define WINDOWS_CONSOLE_NATIVE_YELLOW 0xE -#define WINDOWS_CONSOLE_NATIVE_WHITE 0xF -#define WINDOWS_CONSOLE_COLOR_MASK 0xF -#define WINDOWS_CONSOLE_BGCOLOR_SHIFT 4 - -const uint8 CWindowsConsole::s_colorTable[ WINDOWS_CONSOLE_NUM_CRYENGINE_COLORS ] = -{ - WINDOWS_CONSOLE_NATIVE_BLACK, - WINDOWS_CONSOLE_NATIVE_WHITE, - WINDOWS_CONSOLE_NATIVE_LIGHTBLUE, - WINDOWS_CONSOLE_NATIVE_LIGHTGREEN, - WINDOWS_CONSOLE_NATIVE_LIGHTRED, - WINDOWS_CONSOLE_NATIVE_LIGHTCYAN, - WINDOWS_CONSOLE_NATIVE_YELLOW, - WINDOWS_CONSOLE_NATIVE_LIGHTMAGENTA, - WINDOWS_CONSOLE_NATIVE_BROWN, - WINDOWS_CONSOLE_NATIVE_LIGHTGREY -}; - -CWindowsConsole::CWindowsConsole() - : m_lock() - , m_consoleScreenBufferSize() - , m_consoleWindow() - , m_inputBufferHandle(INVALID_HANDLE_VALUE) - , m_screenBufferHandle(INVALID_HANDLE_VALUE) - , m_logBuffer(0, 0, WINDOWS_CONSOLE_WIDTH, WINDOWS_CONSOLE_HEIGHT - 2, WINDOWS_CONSOLE_LOG_BUFFER_LINES, L' ', WINDOWS_CONSOLE_CRYENGINE_GREY, WINDOWS_CONSOLE_CRYENGINE_BLACK) - , m_fullScreenBuffer(0, 0, WINDOWS_CONSOLE_WIDTH, WINDOWS_CONSOLE_HEIGHT - 2, WINDOWS_CONSOLE_HEIGHT - 2, L' ', WINDOWS_CONSOLE_CRYENGINE_GREY, WINDOWS_CONSOLE_CRYENGINE_BLACK) - , m_statusBuffer(0, WINDOWS_CONSOLE_HEIGHT - 2, WINDOWS_CONSOLE_WIDTH, 1, 1, L' ', WINDOWS_CONSOLE_CRYENGINE_BLACK, WINDOWS_CONSOLE_CRYENGINE_GREY) - , m_commandBuffer(0, WINDOWS_CONSOLE_HEIGHT - 1, WINDOWS_CONSOLE_WIDTH, 1, 1, L' ', WINDOWS_CONSOLE_CRYENGINE_WHITE, WINDOWS_CONSOLE_CRYENGINE_BLACK) - , m_dirtyCellBuffers(0) - , m_commandQueue() - , m_commandPrompt("] ") - , m_commandPromptLength(m_commandPrompt.length()) - , m_command() - , m_commandCursor(0) - , m_logLine() - , m_progressString() - , m_header() - , m_updStats() - , m_pInputThread(NULL) - , m_pSystem(NULL) - , m_pConsole(NULL) - , m_pTimer(NULL) - , m_pCVarSvMap(NULL) - , m_pCVarSvMission(NULL) - , m_pCVarSvGameRules(NULL) - , m_lastStatusUpdate() - , m_lastUpdateTime() - , m_initialized(false) - , m_OnUpdateCalled(false) - , m_requireDedicatedServer(false) -{ -} - -CWindowsConsole::~CWindowsConsole() -{ - CleanUp(); -} - -Vec2_tpl< int > CWindowsConsole::BeginDraw() -{ - m_newCmds.resize(0); - return Vec2_tpl< int >(WINDOWS_CONSOLE_WIDTH, WINDOWS_CONSOLE_HEIGHT - 2); -} - -void CWindowsConsole::PutText(int x, int y, const char* pMsg) -{ - SConDrawCmd cmd; - - cmd.x = x; - cmd.y = y; - cry_strcpy(cmd.text, pMsg); - m_newCmds.push_back(cmd); -} - -void CWindowsConsole::EndDraw() -{ - Lock(); - m_drawCmds.swap(m_newCmds); - Unlock(); -} - -void CWindowsConsole::SetTitle(const char* title) -{ - m_title = title; - - if (m_title.empty()) - { - SetConsoleTitle(m_header.c_str()); - } - else - { - stack_string fullHeader = m_title + " - " + m_header; - SetConsoleTitle(fullHeader); - } -} - -void CWindowsConsole::Print(const char* pInszText) -{ - Lock(); - - bool isContinue = true; - const char* pInszTextPtr = pInszText; - const char* pLogLinePtr = m_logLine.c_str(); - - while (*pLogLinePtr && isContinue) - { - if (*pInszTextPtr != *pLogLinePtr) - { - isContinue = false; - } - - ++pInszTextPtr; - ++pLogLinePtr; - } - - // Do not treat lines as equal if the new line starts the same as the previous line - isContinue = isContinue && (*pInszTextPtr == 0 || m_logLine.empty()); - - if (!isContinue) - { - pInszTextPtr = pInszText; - m_logBuffer.NewLine(); - m_logLine.clear(); - } - - m_logLine.append(pInszTextPtr); - m_logBuffer.Print(pInszTextPtr); - m_dirtyCellBuffers |= eCBB_Log; - - Unlock(); -} - -bool CWindowsConsole::OnError([[maybe_unused]] const char* szErrorString) -{ - return true; -} - -bool CWindowsConsole::OnSaveDocument() -{ - return false; -} - -bool CWindowsConsole::OnBackupDocument() -{ - return false; -} - -void CWindowsConsole::OnProcessSwitch() -{ -} - -void CWindowsConsole::OnInitProgress(const char* sProgressMsg) -{ - if (m_initialized) - { - Lock(); - m_progressString = sProgressMsg; - DrawStatus(); - Unlock(); - } -} - -// the CtrlHandler will be called from a separate thread that only handles -// Ctrl messages. When the CLOSE event is sent, this function can just wait -// forever, as FreeConsole() will kill the thread. If this function returns -// immediately, windows will call TerminateProcess() and nothing will be cleaned up. -static BOOL WINAPI CtrlHandler(DWORD ctrlEvent) -{ - switch (ctrlEvent) - { - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - return TRUE; - case CTRL_CLOSE_EVENT: - if ( (gEnv != nullptr) && (gEnv->pSystem != nullptr) && (gEnv->pSystem->GetIConsole() != nullptr) ) - { - gEnv->pSystem->GetIConsole()->ExecuteString("quit", true, true); - Sleep(INFINITE); - return TRUE; - } - default: - break; - } - return FALSE; -} - -void CWindowsConsole::OnInit(ISystem* pSystem) -{ - if (m_requireDedicatedServer && !gEnv->IsDedicated()) - { - return; - } - - Lock(); - - if (!m_initialized) - { - assert(m_pSystem == NULL); - assert(m_pConsole == NULL); - - m_pSystem = pSystem; - m_pConsole = pSystem->GetIConsole(); - - AllocConsole(); - m_inputBufferHandle = GetStdHandle(STD_INPUT_HANDLE); - m_screenBufferHandle = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleMode(m_inputBufferHandle, ENABLE_WINDOW_INPUT); - m_consoleScreenBufferSize.X = WINDOWS_CONSOLE_WIDTH; - m_consoleScreenBufferSize.Y = WINDOWS_CONSOLE_HEIGHT; - m_consoleWindow.Left = 0; - m_consoleWindow.Top = 0; - m_consoleWindow.Right = WINDOWS_CONSOLE_WIDTH - 1; - m_consoleWindow.Bottom = WINDOWS_CONSOLE_HEIGHT - 1; - SetConsoleScreenBufferSize(m_screenBufferHandle, m_consoleScreenBufferSize); - SetConsoleWindowInfo(m_screenBufferHandle, TRUE, &m_consoleWindow); - SetConsoleTitle(m_header.c_str()); - - if (m_pConsole) - { - m_pConsole->AddOutputPrintSink(this); - } - - DrawCommand(); - - m_pInputThread = new CWindowsConsoleInputThread(*this); - m_pInputThread->Start(); - -#if !defined(NDEBUG) - BOOL handlerInstalled = -#endif - SetConsoleCtrlHandler(CtrlHandler, TRUE); - CRY_ASSERT(handlerInstalled); - - m_initialized = true; - } - - Unlock(); -} - -void CWindowsConsole::OnShutdown() -{ - CleanUp(); -} - -void CWindowsConsole::OnUpdate() -{ - if (m_initialized) - { - Lock(); - - bool updateStatus = false; - - if (!m_OnUpdateCalled) - { - assert(m_pCVarSvMap == NULL); - assert(m_pCVarSvGameRules == NULL); - assert(m_pTimer == NULL); - - m_pCVarSvMap = m_pConsole->GetCVar("sv_map"); - m_pCVarSvGameRules = m_pConsole->GetCVar("sv_gamerules"); - m_pTimer = m_pSystem->GetITimer(); - m_OnUpdateCalled = true; - - assert(m_pCVarSvMission == NULL); - m_pCVarSvMission = m_pConsole->GetCVar("sv_mission"); - } - - if (!m_progressString.empty()) - { - m_progressString.clear(); - updateStatus = true; - } - - CTimeValue now = m_pTimer->GetAsyncTime(); - - if ((now - m_lastStatusUpdate).GetSeconds() > 0.1F) - { - updateStatus = true; - } - - m_lastUpdateTime = now; - - m_pSystem->GetUpdateStats(m_updStats); - - if (updateStatus) - { - DrawStatus(); - m_lastStatusUpdate = now; - } - - while (m_commandQueue.size()) - { - const string& command = m_commandQueue[0]; - Unlock(); - // 'm_pConsole' will be set to NULL when executing 'quit' command - // Cache pointer in local variable to prevent crash when adding the last command to the history - IConsole* pConsole = m_pConsole; - pConsole->ExecuteString(command.c_str()); - pConsole->AddCommandToHistory(command.c_str()); - Lock(); - m_commandQueue.pop_front(); - } - - if (!m_drawCmds.empty()) - { - DrawFull(); - } - - Repaint(); - - Unlock(); - } -} - -void CWindowsConsole::OnConsoleInputEvent(INPUT_RECORD inputRecord) -{ - switch (inputRecord.EventType) - { - case KEY_EVENT: - OnKey(inputRecord.Event.KeyEvent); - break; - case WINDOW_BUFFER_SIZE_EVENT: - OnResize(inputRecord.Event.WindowBufferSizeEvent.dwSize); - break; - } -} - -void CWindowsConsole::OnKey(const KEY_EVENT_RECORD& event) -{ - if (event.bKeyDown) - { - for (uint32 i = 0; i < event.wRepeatCount; ++i) - { - switch (event.wVirtualKeyCode) - { - case VK_BACK: - OnBackspace(); - break; - case VK_TAB: - OnTab(); - break; - case VK_RETURN: - OnReturn(); - break; - case VK_PRIOR: - OnPgUp(); - break; - case VK_NEXT: - OnPgDn(); - break; - case VK_LEFT: - OnLeft(); - break; - case VK_UP: - OnUp(); - break; - case VK_RIGHT: - OnRight(); - break; - case VK_DOWN: - OnDown(); - break; - case VK_DELETE: - OnDelete(); - break; - default: - OnChar(event.uChar.AsciiChar); - break; - } - } - } -} - -void CWindowsConsole::OnResize(const COORD& size) -{ - if ((size.X != m_consoleScreenBufferSize.X) || (size.Y != m_consoleScreenBufferSize.Y)) - { - SetConsoleScreenBufferSize(m_screenBufferHandle, m_consoleScreenBufferSize); - SetConsoleWindowInfo(m_screenBufferHandle, TRUE, &m_consoleWindow); - } -} - -void CWindowsConsole::OnBackspace() -{ - if (m_commandCursor > 0) - { - m_command.erase(--m_commandCursor, 1); - m_pConsole->ResetAutoCompletion(); - DrawCommand(); - } -} - -void CWindowsConsole::OnTab() -{ - const char* pCompletion; - - pCompletion = m_pConsole->ProcessCompletion(m_command.c_str()); - - if (pCompletion) - { - m_command = pCompletion; - m_commandCursor = m_command.length(); - DrawCommand(); - } -} - -void CWindowsConsole::OnReturn() -{ - m_commandQueue.push_back(m_command); - m_command.clear(); - m_pConsole->ResetAutoCompletion(); - m_commandCursor = 0; - DrawCommand(); -} - -void CWindowsConsole::OnPgUp() -{ - if (m_logBuffer.Scroll(-WINDOWS_CONSOLE_LOG_SCROLL_LINES)) - { - m_dirtyCellBuffers |= eCBB_Log; - } -} - -void CWindowsConsole::OnPgDn() -{ - if (m_logBuffer.Scroll(WINDOWS_CONSOLE_LOG_SCROLL_LINES)) - { - m_dirtyCellBuffers |= eCBB_Log; - } -} - -void CWindowsConsole::OnLeft() -{ - if (m_commandCursor > 0) - { - --m_commandCursor; - m_commandBuffer.SetCursor(m_screenBufferHandle, m_commandCursor + m_commandPromptLength); - } -} - -void CWindowsConsole::OnUp() -{ - OnHistory(m_pConsole->GetHistoryElement(true)); -} - -void CWindowsConsole::OnRight() -{ - if (m_commandCursor < m_command.length()) - { - ++m_commandCursor; - m_commandBuffer.SetCursor(m_screenBufferHandle, m_commandCursor + m_commandPromptLength); - } -} - -void CWindowsConsole::OnDown() -{ - OnHistory(m_pConsole->GetHistoryElement(false)); -} - -void CWindowsConsole::OnDelete() -{ - if (m_commandCursor < m_command.length()) - { - m_command.erase(m_commandCursor, 1); - m_pConsole->ResetAutoCompletion(); - DrawCommand(); - } -} - -void CWindowsConsole::OnChar(CHAR ch) -{ - if ((ch >= ' ') && (ch <= '~')) - { - m_command.insert(m_commandCursor++, ch); - m_pConsole->ResetAutoCompletion(); - DrawCommand(); - } -} - -void CWindowsConsole::OnHistory(const char* pHistoryElement) -{ - if (pHistoryElement) - { - m_command = pHistoryElement; - } - else - { - m_command.clear(); - } - - m_commandCursor = m_command.length(); - DrawCommand(); -} - -void CWindowsConsole::DrawCommand() -{ - m_commandBuffer.Clear(); - m_commandBuffer.PutText(0, 0, m_commandPrompt.c_str()); - m_commandBuffer.PutText(m_commandPromptLength, 0, m_command); - m_commandBuffer.SetCursor(m_screenBufferHandle, m_commandCursor + m_commandPromptLength); - m_dirtyCellBuffers |= eCBB_Command; -} - -void CWindowsConsole::GetMemoryUsage(ICrySizer* pSizer) -{ - pSizer->Add(this); - pSizer->Add(m_command); - pSizer->Add(m_logLine); - pSizer->Add(m_pInputThread); - m_logBuffer.GetMemoryUsage(pSizer); - m_fullScreenBuffer.GetMemoryUsage(pSizer); - m_statusBuffer.GetMemoryUsage(pSizer); - m_commandBuffer.GetMemoryUsage(pSizer); -} - -void CWindowsConsole::SetRequireDedicatedServer(bool value) -{ - m_requireDedicatedServer = value; -} - -void CWindowsConsole::SetHeader(const char* pHeader) -{ - m_header = pHeader; - SetConsoleTitle(pHeader); -} - -void CWindowsConsole::InputIdle() -{ - if (m_pTimer) - { - CTimeValue now = m_pTimer->GetAsyncTime(); - float timePassed = (now - m_lastUpdateTime).GetSeconds(); - - if (timePassed > 0.2F) - { - int nDots = ( int )(timePassed + 0.5) / 3; - int nDotsMax = m_statusBuffer.Width() - 2; - - if (nDots > nDotsMax) - { - nDots = nDotsMax; - } - - if (m_progressString.length() != nDots) - { - m_progressString.clear(); - m_progressString.append(nDots, '.'); - DrawStatus(); - } - } - } - - Repaint(); -} - -void CWindowsConsole::Lock() -{ - m_lock.Lock(); -} - -void CWindowsConsole::Unlock() -{ - m_lock.Unlock(); -} - -bool CWindowsConsole::TryLock() -{ - return m_lock.TryLock(); -} - -void CWindowsConsole::Repaint() -{ - if (m_dirtyCellBuffers) - { - if (m_dirtyCellBuffers & eCBB_Full) - { - m_fullScreenBuffer.Blit(m_screenBufferHandle); - m_dirtyCellBuffers &= ~eCBB_Full; - } - else if (m_dirtyCellBuffers & eCBB_Log) - { - m_logBuffer.Blit(m_screenBufferHandle); - m_dirtyCellBuffers &= ~eCBB_Log; - } - - if (m_dirtyCellBuffers & eCBB_Status) - { - m_statusBuffer.Blit(m_screenBufferHandle); - m_dirtyCellBuffers &= ~eCBB_Status; - } - - if (m_dirtyCellBuffers & eCBB_Command) - { - m_commandBuffer.Blit(m_screenBufferHandle); - m_dirtyCellBuffers &= ~eCBB_Command; - } - } -} - -void CWindowsConsole::DrawStatus() -{ - const char* pStatusLeft = NULL; - const char* pStatusRight = NULL; - char bufferLeft[ 256 ]; - char bufferRight[ 256 ]; - - // If we're scrolled, then the right size shows a scroll indicator. - if (m_logBuffer.IsScrolledUp()) - { - m_logBuffer.FmtScrollStatus(sizeof bufferRight, bufferRight); - bufferRight[ sizeof bufferRight - 1 ] = 0; - pStatusRight = bufferRight; - } - - if (!m_progressString.empty()) - { - azsnprintf(bufferLeft, sizeof bufferLeft, " %s", m_progressString.c_str()); - bufferLeft [sizeof bufferLeft - 1 ] = 0; - pStatusLeft = bufferLeft; - } - else if (m_OnUpdateCalled) - { - // Standard status display. - // Map name and game rules on the left. - // Current update rate and player count on the right. - - const char* pMapName = m_pCVarSvMap->GetString(); - - const char* pMissionName = m_pCVarSvMission ? m_pCVarSvMission->GetString() : ""; - azsnprintf(bufferLeft, sizeof bufferLeft, " mission: %s map:%s", pMissionName, pMapName); - - bufferLeft[ sizeof bufferLeft - 1 ] = 0; - pStatusLeft = bufferLeft; - - if (!pStatusRight) - { - float updateRate = 0.f; - - if (m_pTimer != NULL) - { - updateRate = m_pTimer->GetFrameRate(); - } - else - { - updateRate = 0.f; - } - - char* pBufferRight = bufferRight; - char* const pBufferRightEnd = bufferRight + sizeof bufferRight; - - azstrcpy(pBufferRight, AZ_ARRAY_SIZE(bufferRight), "| "); - pBufferRight += strlen(pBufferRight); - - if (pBufferRight < pBufferRightEnd) - { - if (m_pConsole != NULL) - { - pBufferRight += azsnprintf( - pBufferRight, - pBufferRightEnd - pBufferRight, - "upd:%.1fms(%.2f..%.2f) " \ - "rate:%.1f/s", - m_updStats.avgUpdateTime, m_updStats.minUpdateTime, m_updStats.maxUpdateTime, - updateRate); - } - else - { - cry_strcpy(pBufferRight, pBufferRightEnd - pBufferRight, "BUSY "); - } - } - - bufferRight[ sizeof bufferRight - 1 ] = 0; - pStatusRight = bufferRight; - } - } - - if (pStatusLeft == NULL) - { - pStatusLeft = ""; - } - - if (pStatusRight == NULL) - { - pStatusRight = ""; - } - - int rightWidth = strlen(pStatusRight); - - m_statusBuffer.Clear(); - m_statusBuffer.PutText(0, 0, pStatusLeft); - m_statusBuffer.PutText(-rightWidth, 0, pStatusRight); - m_dirtyCellBuffers |= eCBB_Status; -} - -void CWindowsConsole::CleanUp() -{ - Lock(); - - if (m_initialized) - { - if (m_pInputThread) - { - m_pInputThread->Cancel(); - - // The input thread may continue to lock before it gets our cancel event, so - // we need to release the lock until we confirm that it has canceled its operations. - Unlock(); - m_pInputThread->WaitForThread(); - Lock(); - - delete m_pInputThread; - m_pInputThread = NULL; - } - - if (m_pConsole) - { - m_pConsole->RemoveOutputPrintSink(this); - } - - m_pSystem = NULL; - m_pConsole = NULL; - m_pTimer = NULL; - m_pCVarSvMap = NULL; - m_pCVarSvGameRules = NULL; - m_inputBufferHandle = INVALID_HANDLE_VALUE; - m_screenBufferHandle = INVALID_HANDLE_VALUE; - m_initialized = false; - } - - Unlock(); -} - -void CWindowsConsole::DrawFull() -{ - for (DynArray< SConDrawCmd >::iterator iter = m_drawCmds.begin(); iter != m_drawCmds.end(); ++iter) - { - m_fullScreenBuffer.PutText(iter->x, iter->y, iter->text); - } - - m_dirtyCellBuffers |= eCBB_Full; -} - -CWindowsConsole::CCellBuffer::CCellBuffer(SHORT x, short y, SHORT w, SHORT h, SHORT lines, WCHAR emptyChar, uint8 defaultFgColor, uint8 defaultBgColor) -{ - m_emptyCell.Char.UnicodeChar = emptyChar; - m_emptyCell.Attributes = s_colorTable[ defaultFgColor ] | (s_colorTable[ defaultBgColor ] << WINDOWS_CONSOLE_BGCOLOR_SHIFT); - m_attr = m_emptyCell.Attributes; - m_size.X = w; - m_size.Y = lines; - m_screenArea.Left = x; - m_screenArea.Top = y; - m_screenArea.Right = x + w - 1; - m_screenArea.Bottom = y + h - 1; - m_position.head = 0; - m_position.lines = 1; - m_position.wrap = 0; - m_position.offset = 0; - m_position.scroll = 0; - m_escape = false; - m_color = false; - m_buffer.resize(w * lines, m_emptyCell); -} - -CWindowsConsole::CCellBuffer::~CCellBuffer() -{ -} - -void CWindowsConsole::CCellBuffer::PutText(int x, int y, const char* pMsg) -{ - SPosition position; - - position.head = m_position.head; - position.offset = x; - position.lines = y; - position.scroll = 0; - position.wrap = 0; - - if (position.offset < 0) - { - position.offset += m_screenArea.Right - 1; - } - - if (position.lines < 0) - { - position.lines += m_screenArea.Bottom - 1; - } - - Print(pMsg, position); -} - -void CWindowsConsole::CCellBuffer::Print(const char* pInszText) -{ - Print(pInszText, m_position); -} - -void CWindowsConsole::CCellBuffer::ClearCells(TBuffer::iterator pDst, TBuffer::iterator pDstEnd) -{ - std::fill(pDst, pDstEnd, m_emptyCell); -} - -bool CWindowsConsole::CCellBuffer::Scroll(SHORT numLines) -{ - bool result = false; - SHORT newScroll = m_position.scroll + numLines; - SHORT maxScroll = m_position.lines - 1 - (m_screenArea.Bottom - m_screenArea.Top); - - if (newScroll > maxScroll) - { - newScroll = maxScroll; - } - - if (newScroll < 0) - { - newScroll = 0; - } - - if (newScroll != m_position.scroll) - { - m_position.scroll = newScroll; - result = true; - } - - return result; -} - -void CWindowsConsole::CCellBuffer::SetCursor(HANDLE hScreenBuffer, SHORT offset) -{ - COORD position; - - position.X = m_screenArea.Left + offset; - position.Y = m_screenArea.Top; - SetConsoleCursorPosition(hScreenBuffer, position); -} - -void CWindowsConsole::CCellBuffer::AddCharacter(WCHAR ch, SPosition& position) -{ - if (position.offset == m_size.X) - { - WrapLine(position); - } - - int32 index = (((position.head + position.lines + m_size.Y - 1) % m_size.Y) * m_size.X) + position.offset; - - CHAR_INFO& info = m_buffer[ index ]; - - info.Attributes = m_attr; - info.Char.UnicodeChar = ch; - ++position.offset; -} - -void CWindowsConsole::CCellBuffer::WrapLine(SPosition& position) -{ - ++position.wrap; - AdvanceLine(position); -} - -void CWindowsConsole::CCellBuffer::NewLine() -{ - NewLine(m_position); -} - -void CWindowsConsole::CCellBuffer::NewLine(SPosition& position) -{ - m_attr = m_emptyCell.Attributes; - position.wrap = 0; - AdvanceLine(position); -} - -void CWindowsConsole::CCellBuffer::ClearLine(SPosition& position) -{ - ClearCells(m_buffer.begin() + ((position.head + position.lines - position.wrap) % m_size.Y) * m_size.X, m_buffer.begin() + ((position.head + position.lines + 1) % m_size.Y) * m_size.X); - position.lines -= position.wrap; - position.wrap = 0; - position.offset = 0; -} - -void CWindowsConsole::CCellBuffer::Tab(SPosition& position) -{ - do - { - AddCharacter(' ', position); - } while (position.offset % WINDOWS_CONSOLE_TAB_SIZE); -} - -void CWindowsConsole::CCellBuffer::Blit(HANDLE hScreenBuffer) -{ - COORD src; - SMALL_RECT dst; - - src.X = 0; - src.Y = (m_position.head + m_position.scroll) % m_size.Y; - dst = m_screenArea; - WriteConsoleOutput(hScreenBuffer, &*m_buffer.begin(), m_size, src, &dst); - - if ((m_size.Y - src.Y) < (m_screenArea.Bottom - m_screenArea.Top + 1)) - { - src.Y = 0; - dst.Top = dst.Bottom + 1; - dst.Bottom = m_screenArea.Bottom; - WriteConsoleOutput(hScreenBuffer, &*m_buffer.begin(), m_size, src, &dst); - } -} - -void CWindowsConsole::CCellBuffer::AdvanceLine(SPosition& position) -{ - position.offset = 0; - - if (position.lines == m_size.Y) - { - position.head = (position.head + 1) % m_size.Y; - } - else - { - ++position.lines; - - if (position.lines > m_screenArea.Bottom - m_screenArea.Top + 1) - { - ++position.scroll; - } - } - - TBuffer::iterator start = m_buffer.begin() + ((position.head + position.lines + m_size.Y - 1) % m_size.Y) * m_size.X; - TBuffer::iterator end = start + m_size.X; - - ClearCells(start, end); -} - -void CWindowsConsole::CCellBuffer::SetFgColor(WORD color) -{ - m_attr = (m_attr & ~WINDOWS_CONSOLE_COLOR_MASK) | s_colorTable[ color ]; -} - -void CWindowsConsole::CCellBuffer::Print(const char* pInszText, SPosition& position) -{ - while (*pInszText) - { - switch (*pInszText) - { - case '$': - if (!m_escape) - { - m_color = true; - break; - } - case '\\': - m_escape = !m_escape; - if (m_escape) - { - break; - } - case 'n': - if (m_escape) - { - case '\n': - NewLine(position); - m_escape = false; - break; - } - case 'r': - if (m_escape) - { - case '\r': - ClearLine(position); - m_escape = false; - break; - } - case 't': - if (m_escape) - { - case '\t': - Tab(position); - m_escape = false; - break; - } - default: - if (m_color) - { - if (isdigit(*pInszText)) - { - SetFgColor(*pInszText - '0'); - } - - m_color = false; - } - else - { - if (m_escape && (*pInszText != '\\')) - { - AddCharacter('\\', position); - } - AddCharacter(*pInszText, position); - } - m_escape = false; - break; - } - - ++pInszText; - } -} - -void CWindowsConsole::CCellBuffer::GetMemoryUsage(ICrySizer* pSizer) -{ - pSizer->Add(m_buffer); -} - -bool CWindowsConsole::CCellBuffer::IsScrolledUp() -{ - return (m_position.lines - m_position.scroll) > (m_screenArea.Bottom - m_screenArea.Top + 1); -} - -void CWindowsConsole::CCellBuffer::FmtScrollStatus(uint32 size, char* pBuffer) -{ - if (m_position.scroll) - { - azsnprintf(pBuffer, size, "| SCROLL: %.1f%%", 100.0F * static_cast< float >(m_position.scroll) / static_cast< float >(m_position.lines - (m_screenArea.Bottom - m_screenArea.Top + 1))); - } - else - { - cry_strcpy(pBuffer, size, "| SCROLL:TOP "); - } -} - -void CWindowsConsole::CCellBuffer::Clear() -{ - ClearCells(m_buffer.begin(), m_buffer.end()); -} - -SHORT CWindowsConsole::CCellBuffer::Width() -{ - return m_screenArea.Right - m_screenArea.Left + 1; -} - - -CWindowsConsoleInputThread::CWindowsConsoleInputThread(CWindowsConsole& console) - : m_WindowsConsole(console) -{ - m_handles[ eWH_Event ] = CreateEvent(NULL, TRUE, FALSE, NULL); - m_handles[ eWH_Console ] = m_WindowsConsole.m_inputBufferHandle; -} - -CWindowsConsoleInputThread::~CWindowsConsoleInputThread() -{ - CloseHandle(m_handles[ eWH_Event ]); -} - -void CWindowsConsoleInputThread::Run() -{ - bool cancelled = false; - - do - { - DWORD inputRecordCount = 0; - DWORD waitResult; - - waitResult = WaitForMultipleObjects(eWH_NumWaitHandles, m_handles, FALSE, 100); - - switch (waitResult) - { - case WAIT_OBJECT_0 + eWH_Event: - - cancelled = true; - break; - - case WAIT_OBJECT_0 + eWH_Console: - - ReadConsoleInput(m_WindowsConsole.m_inputBufferHandle, m_inputRecords, WINDOWS_CONSOLE_MAX_INPUT_RECORDS, &inputRecordCount); - - // FALL THROUGH - - case WAIT_TIMEOUT: - - if (inputRecordCount || (m_WindowsConsole.m_dirtyCellBuffers && !m_WindowsConsole.m_OnUpdateCalled)) - { - m_WindowsConsole.Lock(); - - if (inputRecordCount) - { - PINPUT_RECORD pInputRecordEnd = m_inputRecords + inputRecordCount; - - for (PINPUT_RECORD pInputRecord = m_inputRecords; pInputRecord < pInputRecordEnd; ++pInputRecord) - { - m_WindowsConsole.OnConsoleInputEvent(*pInputRecord); - } - - m_WindowsConsole.DrawCommand(); - } - else - { - m_WindowsConsole.InputIdle(); - } - - m_WindowsConsole.Unlock(); - } - - break; - } - } while (!cancelled); -} - -void CWindowsConsoleInputThread::Cancel() -{ - SetEvent(m_handles[ eWH_Event ]); -} - -#endif // def USE_WINDOWSCONSOLE diff --git a/Code/CryEngine/CrySystem/WindowsConsole.h b/Code/CryEngine/CrySystem/WindowsConsole.h deleted file mode 100644 index cfecd06db2..0000000000 --- a/Code/CryEngine/CrySystem/WindowsConsole.h +++ /dev/null @@ -1,245 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : CWindowsConsole class definition - - -#ifndef CRYINCLUDE_CRYSYSTEM_WINDOWSCONSOLE_H -#define CRYINCLUDE_CRYSYSTEM_WINDOWSCONSOLE_H -#pragma once - - -#include -#include - -#if defined(USE_WINDOWSCONSOLE) - -class CWindowsConsole; -class CWindowsConsoleInputThread; - -#define WINDOWS_CONSOLE_MAX_INPUT_RECORDS 256 -#define WINDOWS_CONSOLE_NUM_CRYENGINE_COLORS 10 - -class CWindowsConsoleInputThread - : public CrySimpleThread<> -{ -public: - CWindowsConsoleInputThread(CWindowsConsole& console); - - ~CWindowsConsoleInputThread(); - - virtual void Run(); - virtual void Cancel(); - void Interrupt() - { - } - -private: - - enum EWaitHandle - { - eWH_Event, - eWH_Console, - eWH_NumWaitHandles - }; - - CWindowsConsole& m_WindowsConsole; - HANDLE m_handles[ eWH_NumWaitHandles ]; - INPUT_RECORD m_inputRecords[ WINDOWS_CONSOLE_MAX_INPUT_RECORDS ]; -}; - -class CWindowsConsole - : public ITextModeConsole - , public IOutputPrintSink - , public ISystemUserCallback -{ -public: - - CWindowsConsole(); - virtual ~CWindowsConsole(); - - // ITextModeConsole - virtual Vec2_tpl< int > BeginDraw(); - virtual void PutText(int x, int y, const char* pMsg); - virtual void EndDraw(); - virtual void SetTitle(const char* title); - - // ~ITextModeConsole - - // IOutputPrintSink - virtual void Print(const char* pInszText); - // ~IOutputPrintSink - - // ISystemUserCallback - virtual bool OnError(const char* szErrorString); - virtual bool OnSaveDocument(); - virtual bool OnBackupDocument(); - virtual void OnProcessSwitch(); - virtual void OnInitProgress(const char* sProgressMsg); - virtual void OnInit(ISystem* pSystem); - virtual void OnShutdown(); - virtual void OnUpdate(); - virtual void GetMemoryUsage(ICrySizer* pSizer); - // ~ISystemUserCallback - - void SetRequireDedicatedServer(bool value); - void SetHeader(const char* pHeader); - void InputIdle(); - -private: - - struct SConDrawCmd - { - int x; - int y; - char text[ 256 ]; - }; - - DynArray m_drawCmds; - DynArray m_newCmds; - - enum ECellBuffer - { - eCB_Log, - eCB_Full, - eCB_Status, - eCB_Command, - eCB_NumCellBuffers - }; - - enum ECellBufferBit - { - eCBB_Log = BIT(eCB_Log), - eCBB_Full = BIT(eCB_Full), - eCBB_Status = BIT(eCB_Status), - eCBB_Command = BIT(eCB_Command) - }; - - class CCellBuffer - { - public: - - CCellBuffer(SHORT x, short y, SHORT w, SHORT h, SHORT lines, WCHAR emptyChar, uint8 defaultFgColor, uint8 defaultBgColor); - ~CCellBuffer(); - - void PutText(int x, int y, const char* pMsg); - void Print(const char* pInszText); - void NewLine(); - void SetCursor(HANDLE hScreenBuffer, SHORT offset); - void SetFgColor(WORD color); - void Blit(HANDLE hScreenBuffer); - bool Scroll(SHORT numLines); - bool IsScrolledUp(); - void FmtScrollStatus(uint32 size, char* pBuffer); - void GetMemoryUsage(ICrySizer* pSizer); - void Clear(); - SHORT Width(); - - private: - - struct SPosition - { - SHORT head; - SHORT lines; - SHORT wrap; - SHORT offset; - SHORT scroll; - }; - - typedef std::vector< CHAR_INFO > TBuffer; - - void Print(const char* pInszText, SPosition& position); - void AddCharacter(WCHAR ch, SPosition& position); - void NewLine(SPosition& position); - void ClearLine(SPosition& position); - void Tab(SPosition& position); - void WrapLine(SPosition& position); - void AdvanceLine(SPosition& position); - void ClearCells(TBuffer::iterator pDst, TBuffer::iterator pDstEnd); - - TBuffer m_buffer; - CHAR_INFO m_emptyCell; - WORD m_attr; - COORD m_size; - SMALL_RECT m_screenArea; - SPosition m_position; - bool m_escape; - bool m_color; - }; - - void Lock(); - void Unlock(); - bool TryLock(); - void OnConsoleInputEvent(INPUT_RECORD inputRecord); - void OnKey(const KEY_EVENT_RECORD& event); - void OnResize(const COORD& size); - void OnBackspace(); - void OnTab(); - void OnReturn(); - void OnPgUp(); - void OnPgDn(); - void OnLeft(); - void OnUp(); - void OnRight(); - void OnDown(); - void OnDelete(); - void OnHistory(const char* pHistoryElement); - void OnChar(CHAR ch); - void DrawFull(); - void DrawStatus(); - void DrawCommand(); - void Repaint(); - void CleanUp(); - - CryCriticalSection m_lock; - COORD m_consoleScreenBufferSize; - SMALL_RECT m_consoleWindow; - HANDLE m_inputBufferHandle; - HANDLE m_screenBufferHandle; - CCellBuffer m_logBuffer; - CCellBuffer m_fullScreenBuffer; - CCellBuffer m_statusBuffer; - CCellBuffer m_commandBuffer; - uint32 m_dirtyCellBuffers; - std::deque< CryStringT< char > > m_commandQueue; - CryStringT< char > m_commandPrompt; - uint32 m_commandPromptLength; - CryStringT< char > m_command; - uint32 m_commandCursor; - CryStringT< char > m_logLine; - CryStringT< char > m_progressString; - CryStringT< char > m_header; - SSystemUpdateStats m_updStats; - CWindowsConsoleInputThread* m_pInputThread; - ISystem* m_pSystem; - IConsole* m_pConsole; - ITimer* m_pTimer; - ICVar* m_pCVarSvMap; - ICVar* m_pCVarSvMission; - CryStringT< char > m_title; - - ICVar* m_pCVarSvGameRules; - CTimeValue m_lastStatusUpdate; - CTimeValue m_lastUpdateTime; - bool m_initialized; - bool m_OnUpdateCalled; - bool m_requireDedicatedServer; - - static const uint8 s_colorTable[ WINDOWS_CONSOLE_NUM_CRYENGINE_COLORS ]; - - friend class CWindowsConsoleInputThread; -}; - -#endif // USE_WINDOWSCONSOLE - -#endif // CRYINCLUDE_CRYSYSTEM_WINDOWSCONSOLE_H diff --git a/Code/CryEngine/CrySystem/WindowsErrorReporting.cpp b/Code/CryEngine/CrySystem/WindowsErrorReporting.cpp deleted file mode 100644 index bd6f0c3ee2..0000000000 --- a/Code/CryEngine/CrySystem/WindowsErrorReporting.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Support for Windows Error Reporting (WER) - - -#include "CrySystem_precompiled.h" - -#ifdef WIN32 - -#include "System.h" -#include -#include -#include "errorrep.h" -#include "ISystem.h" - -#include - -static WCHAR szPath[MAX_PATH + 1]; -static WCHAR szFR[] = L"\\System32\\FaultRep.dll"; - -WCHAR* GetFullPathToFaultrepDll(void) -{ - UINT rc = GetSystemWindowsDirectoryW(szPath, ARRAYSIZE(szPath)); - if (rc == 0 || rc > ARRAYSIZE(szPath) - ARRAYSIZE(szFR) - 1) - { - return NULL; - } - - wcscat_s(szPath, szFR); - return szPath; -} - - -typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, - CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam - ); - -////////////////////////////////////////////////////////////////////////// -LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExceptionPointers, const char* szDumpPath, MINIDUMP_TYPE DumpType) -{ - // note: In debug mode, this dll is loaded on startup anyway, so this should not incur an additional load unless it crashes - // very early during startup. - - fflush(nullptr); // according to MSDN on fflush, calling fflush on null flushes all buffers. - HMODULE hndDBGHelpDLL = LoadLibraryA("DBGHELP.DLL"); - - if (!hndDBGHelpDLL) - { - CryLogAlways("Failed to record DMP file: Could not open DBGHELP.DLL"); - return EXCEPTION_CONTINUE_SEARCH; - } - - MINIDUMPWRITEDUMP dumpFnPtr = (MINIDUMPWRITEDUMP)::GetProcAddress(hndDBGHelpDLL, "MiniDumpWriteDump"); - if (!dumpFnPtr) - { - CryLogAlways("Failed to record DMP file: Unable to find MiniDumpWriteDump in DBGHELP.DLL"); - return EXCEPTION_CONTINUE_SEARCH; - } - - HANDLE hFile = ::CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - CryLogAlways("Failed to record DMP file: could not open file '%s' for writing - error code: %d", szDumpPath, GetLastError()); - return EXCEPTION_CONTINUE_SEARCH; - } - - _MINIDUMP_EXCEPTION_INFORMATION ExInfo; - ExInfo.ThreadId = ::GetCurrentThreadId(); - ExInfo.ExceptionPointers = pExceptionPointers; - ExInfo.ClientPointers = NULL; - - BOOL bOK = dumpFnPtr(GetCurrentProcess(), GetCurrentProcessId(), hFile, DumpType, &ExInfo, NULL, NULL); - ::CloseHandle(hFile); - - if (bOK) - { - CryLogAlways("Successfully recorded DMP file: '%s'", szDumpPath); - return EXCEPTION_EXECUTE_HANDLER; // SUCCESS! you can execute your handlers now - } - else - { - CryLogAlways("Failed to record DMP file: '%s' - error code: %d", szDumpPath, GetLastError()); - } - - return EXCEPTION_CONTINUE_SEARCH; -} - -/* -struct AutoSetCryEngineExceptionFilter -{ - AutoSetCryEngineExceptionFilter() - { - WCHAR * psz = GetFullPathToFaultrepDll(); - SetUnhandledExceptionFilter(CryEngineExceptionFilterWER); - } -}; -AutoSetCryEngineExceptionFilter g_AutoSetCryEngineExceptionFilter; -*/ - -////////////////////////////////////////////////////////////////////////// -LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers) -{ - if (g_cvars.sys_WER > 1) - { - char szScratch [_MAX_PATH]; - const char* szDumpPath = gEnv->pCryPak->AdjustFileName("@log@/CE2Dump.dmp", szScratch, AZ_ARRAY_SIZE(szScratch), 0); - - MINIDUMP_TYPE mdumpValue = (MINIDUMP_TYPE)(MiniDumpNormal); - if (g_cvars.sys_WER > 1) - { - mdumpValue = (MINIDUMP_TYPE)(g_cvars.sys_WER - 2); - } - - return CryEngineExceptionFilterMiniDump(pExceptionPointers, szDumpPath, mdumpValue); - } - - LONG lRet = EXCEPTION_CONTINUE_SEARCH; - WCHAR* psz = GetFullPathToFaultrepDll(); - if (psz) - { - HMODULE hFaultRepDll = LoadLibraryW(psz); - if (hFaultRepDll) - { - pfn_REPORTFAULT pfn = (pfn_REPORTFAULT)GetProcAddress(hFaultRepDll, "ReportFault"); - if (pfn) - { - pfn(pExceptionPointers, 0); - lRet = EXCEPTION_EXECUTE_HANDLER; - } - FreeLibrary(hFaultRepDll); - } - } - return lRet; -} - - -#endif // WIN32 - diff --git a/Code/CryEngine/CrySystem/ZLibCompressor.cpp b/Code/CryEngine/CrySystem/ZLibCompressor.cpp deleted file mode 100644 index 94d327940c..0000000000 --- a/Code/CryEngine/CrySystem/ZLibCompressor.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "CryZlib.h" -#include "ZLibCompressor.h" -#include "TypeInfo_impl.h" -#include - -// keep these in sync with the enums in IZLibCompressor.h -static const int k_stratMap[] = {Z_DEFAULT_STRATEGY, Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE}; -static const int k_methodMap[] = {Z_DEFLATED}; -static const int k_flushMap[] = {Z_NO_FLUSH, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, Z_FULL_FLUSH}; - -struct CZLibDeflateStream - : public IZLibDeflateStream -{ -protected: - virtual ~CZLibDeflateStream(); - -protected: - z_stream m_compressStream; - int m_zSize; - int m_zPeak; - int m_level; - int m_windowBits; - int m_memLevel; - int m_zlibFlush; - int m_bytesInput; - int m_bytesOutput; - EZLibStrategy m_strategy; - EZLibMethod m_method; - EZDeflateState m_curState; - bool m_streamOpened; - - - static voidpf ZAlloc( - voidpf pInOpaque, - uInt inItems, - uInt inSize); - static void ZFree( - voidpf pInOpaque, - voidpf pInAddress); - - EZDeflateState RunDeflate(); - -public: - CZLibDeflateStream( - int inLevel, - EZLibMethod inMethod, - int inWindowBits, - int inMemLevel, - EZLibStrategy inStrategy, - EZLibFlush inFlushMethod); - - virtual void SetOutputBuffer( - char* pInBuffer, - int inSize); - virtual int GetBytesOutput(); - - virtual void Input( - const char* pInSource, - int inSourceSize); - virtual void EndInput(); - - virtual EZDeflateState GetState(); - - virtual void GetStats( - SStats* pOutStats); - - virtual void Release(); -}; - -inline static int Lookup(int inIndex, const int* pInValues, [[maybe_unused]] int inMaxValues) -{ - CRY_ASSERT_MESSAGE(inIndex >= 0 && inIndex < inMaxValues, "CZLibDeflateStream mapping invalid"); - return pInValues[inIndex]; -} - -IZLibDeflateStream* CZLibCompressor::CreateDeflateStream(int inLevel, EZLibMethod inMethod, int inWindowBits, int inMemLevel, EZLibStrategy inStrategy, EZLibFlush inFlushMethod) -{ - return new CZLibDeflateStream(inLevel, inMethod, inWindowBits, inMemLevel, inStrategy, inFlushMethod); -} - -void CZLibCompressor::Release() -{ - delete this; -} - -void CZLibCompressor::MD5Init(SMD5Context* pIOCtx) -{ - COMPILE_TIME_ASSERT(sizeof(*pIOCtx) == sizeof(MD5Context)); - - ::MD5Init((MD5Context*)pIOCtx); -} - -void CZLibCompressor::MD5Update(SMD5Context* pIOCtx, const char* pInBuff, unsigned int len) -{ - ::MD5Update((MD5Context*)pIOCtx, (unsigned char*)pInBuff, len); -} - -void CZLibCompressor::MD5Final(SMD5Context* pIOCtx, char outDigest[16]) -{ - ::MD5Final((unsigned char*)outDigest, (MD5Context*)pIOCtx); -} - -CZLibCompressor::~CZLibCompressor() -{ -} - -CZLibDeflateStream::CZLibDeflateStream( - int inLevel, - EZLibMethod inMethod, - int inWindowBits, - int inMemLevel, - EZLibStrategy inStrategy, - EZLibFlush inFlushMethod) - : m_zSize(0) - , m_zPeak(0) - , m_level(inLevel) - , m_windowBits(inWindowBits) - , m_memLevel(inMemLevel) - , m_bytesInput(0) - , m_bytesOutput(0) - , m_strategy(inStrategy) - , m_method(inMethod) - , m_curState(eZDefState_AwaitingInput) - , m_streamOpened(false) -{ - memset(&m_compressStream, 0, sizeof(m_compressStream)); - m_zlibFlush = Lookup(inFlushMethod, k_flushMap, ARRAY_COUNT(k_flushMap)); -} - -CZLibDeflateStream::~CZLibDeflateStream() -{ -} - -void CZLibDeflateStream::Release() -{ - if (m_streamOpened) - { - int err = deflateEnd(&m_compressStream); - if (err != Z_OK) - { - CryLog("zlib deflateEnd() error %d returned when closing stream", err); - } - } - delete this; -} - -void CZLibDeflateStream::SetOutputBuffer( - char* pInBuffer, - int inSize) -{ - m_bytesOutput += m_compressStream.total_out; - - m_compressStream.next_out = (byte*)pInBuffer; - m_compressStream.avail_out = inSize; - m_compressStream.total_out = 0; -} - -void CZLibDeflateStream::GetStats( - IZLibDeflateStream::SStats* pOutStats) -{ - pOutStats->bytesInput = m_bytesInput; - pOutStats->bytesOutput = m_bytesOutput + m_compressStream.total_out; - pOutStats->curMemoryUsed = m_zSize; - pOutStats->peakMemoryUsed = m_zPeak; -} - -int CZLibDeflateStream::GetBytesOutput() -{ - return m_compressStream.total_out; -} - -void CZLibDeflateStream::Input( - const char* pInSource, - int inSourceSize) -{ - CRY_ASSERT_MESSAGE(m_curState == eZDefState_AwaitingInput, "CZLibDeflateStream::Input() called when stream is not awaiting input"); - - m_compressStream.next_in = (Bytef*)pInSource; - m_compressStream.avail_in = inSourceSize; - m_bytesInput += inSourceSize; -} - -void CZLibDeflateStream::EndInput() -{ - CRY_ASSERT_MESSAGE(m_curState == eZDefState_AwaitingInput, "CZLibDeflateStream::EndInput() called when stream is not awaiting input"); - - m_zlibFlush = Z_FINISH; -} - -voidpf CZLibDeflateStream::ZAlloc( - voidpf pInOpaque, - uInt inItems, - uInt inSize) -{ - CZLibDeflateStream* pStr = reinterpret_cast(pInOpaque); - - int size = inItems * inSize; - - int* ptr = (int*) CryModuleMalloc(sizeof(int) + size); - if (ptr) - { - *ptr = inItems * inSize; - ptr += 1; - - int newSize = pStr->m_zSize + size; - pStr->m_zSize = newSize; - if (newSize > pStr->m_zPeak) - { - pStr->m_zPeak = newSize; - } - } - return ptr; -} - -void CZLibDeflateStream::ZFree( - voidpf pInOpaque, - voidpf pInAddress) -{ - int* pPtr = reinterpret_cast(pInAddress); - if (pPtr) - { - CZLibDeflateStream* pStr = reinterpret_cast(pInOpaque); - pStr->m_zSize -= pPtr[-1]; - CryModuleFree(pPtr - 1); - } -} - -EZDeflateState CZLibDeflateStream::RunDeflate() -{ - bool runDeflate = false; - bool inputAvailable = (m_compressStream.avail_in > 0) || (m_zlibFlush == Z_FINISH); - bool outputAvailable = (m_compressStream.avail_out > 0); - - switch (m_curState) - { - case eZDefState_AwaitingInput: - case eZDefState_ConsumeOutput: - if (inputAvailable && outputAvailable) - { - runDeflate = true; - } - else if (inputAvailable || !outputAvailable) - { - m_curState = eZDefState_ConsumeOutput; - } - else - { - m_curState = eZDefState_AwaitingInput; - } - break; - - case eZDefState_Finished: - break; - - case eZDefState_Deflating: - CRY_ASSERT_MESSAGE(0, "Shouldn't be trying to run deflate whilst a deflate is in progress"); - break; - - case eZDefState_Error: - break; - - default: - CRY_ASSERT_MESSAGE(0, "unknown state"); - break; - } - - if (runDeflate) - { - if (!m_streamOpened) - { - m_streamOpened = true; - - // initialising with deflateInit2 requires that the next_in be initialised - m_compressStream.zalloc = &CZLibDeflateStream::ZAlloc; - m_compressStream.zfree = &CZLibDeflateStream::ZFree; - m_compressStream.opaque = this; - - int error = deflateInit2(&m_compressStream, m_level, Lookup(m_method, k_methodMap, ARRAY_COUNT(k_methodMap)), m_windowBits, m_memLevel, Lookup(m_strategy, k_stratMap, ARRAY_COUNT(k_stratMap))); - if (error != Z_OK) - { - m_curState = eZDefState_Error; - CryLog("zlib deflateInit2() error, err %d", error); - } - } - - if (m_curState != eZDefState_Error) - { - int error = deflate(&m_compressStream, m_zlibFlush); - - if (error == Z_STREAM_END) - { - // end of stream has been generated, only produced if we pass Z_FINISH into deflate - m_curState = eZDefState_Finished; - } - else if ((error == Z_OK && m_compressStream.avail_out == 0) || (error == Z_BUF_ERROR && m_compressStream.avail_out == 0)) - { - // output buffer has been filled - // data should be available for consumption by caller - m_curState = eZDefState_ConsumeOutput; - } - else if (m_compressStream.avail_in == 0) - { - // ran out of input data - // data may be available for consumption - but we need more input right now - m_curState = eZDefState_AwaitingInput; - } - else - { - // some sort of error has occurred - m_curState = eZDefState_Error; - CryLog("zlib deflate() error, err %d", error); - } - } - } - - return m_curState; -} - -EZDeflateState CZLibDeflateStream::GetState() -{ - return RunDeflate(); -} diff --git a/Code/CryEngine/CrySystem/ZLibCompressor.h b/Code/CryEngine/CrySystem/ZLibCompressor.h deleted file mode 100644 index 4c026d965f..0000000000 --- a/Code/CryEngine/CrySystem/ZLibCompressor.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_ZLIBCOMPRESSOR_H -#define CRYINCLUDE_CRYSYSTEM_ZLIBCOMPRESSOR_H -#pragma once - - -#include "IZLibCompressor.h" - -class CZLibCompressor - : public IZLibCompressor -{ -protected: - virtual ~CZLibCompressor(); - -public: - virtual IZLibDeflateStream* CreateDeflateStream(int inLevel, EZLibMethod inMethod, int inWindowBits, int inMemLevel, EZLibStrategy inStrategy, EZLibFlush inFlushMethod); - virtual void Release(); - - virtual void MD5Init(SMD5Context* pIOCtx); - virtual void MD5Update(SMD5Context* pIOCtx, const char* pInBuff, unsigned int len); - virtual void MD5Final(SMD5Context * pIOCtx, char outDigest[16]); -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ZLIBCOMPRESSOR_H diff --git a/Code/CryEngine/CrySystem/ZLibDecompressor.cpp b/Code/CryEngine/CrySystem/ZLibDecompressor.cpp deleted file mode 100644 index d75baf2c69..0000000000 --- a/Code/CryEngine/CrySystem/ZLibDecompressor.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : zlib inflate wrapper - - -#include "CrySystem_precompiled.h" - -#include "CryZlib.h" -#include "ZLibDecompressor.h" - -class CZLibInflateStream - : public IZLibInflateStream -{ -public: - CZLibInflateStream() - : m_bStreamOpened(false) - , m_zlibFlush(0) - , m_currentState(eZInfState_AwaitingInput) - , m_bytesInput(0) - , m_bytesOutput(0) - , m_zSize(0) - , m_zPeak(0) {} - - virtual void Release(); - - virtual void SetOutputBuffer(char* pInBuffer, unsigned int inSize); - virtual unsigned int GetBytesOutput(); - virtual void Input(const char* pInSource, unsigned int inSourceSize); - virtual void EndInput(); - virtual EZInflateState GetState(); - virtual void GetStats(IZLibInflateStream::SStats* pOutStats); - -private: - virtual ~CZLibInflateStream() {} - - EZInflateState RunInflate(); - - static voidpf ZAlloc(voidpf pInOpaque, uInt inItems, uInt inSize); - static void ZFree(voidpf pInOpaque, voidpf pInAddress); - - z_stream m_decompressStream; - bool m_bStreamOpened; - int m_zlibFlush; - EZInflateState m_currentState; - unsigned int m_bytesInput; - unsigned int m_bytesOutput; - unsigned int m_zSize; - unsigned int m_zPeak; -}; - -IZLibInflateStream* CZLibDecompressor::CreateInflateStream() -{ - return new CZLibInflateStream(); -} - -void CZLibDecompressor::Release() -{ - delete this; -} - -void CZLibInflateStream::Release() -{ - if (m_bStreamOpened) - { - int err = inflateEnd(&m_decompressStream); - if (err != Z_OK) - { - CryLog("zlib inflateEnd() error %d returned when closing stream", err); - } - } - - delete this; -} - -void CZLibInflateStream::SetOutputBuffer(char* pInBuffer, unsigned int inSize) -{ - m_bytesOutput += m_decompressStream.total_out; - - m_decompressStream.next_out = (byte*)pInBuffer; - m_decompressStream.avail_out = inSize; - m_decompressStream.total_out = 0; -} - -void CZLibInflateStream::GetStats(IZLibInflateStream::SStats* pOutStats) -{ - pOutStats->bytesInput = m_bytesInput; - pOutStats->bytesOutput = m_bytesOutput + m_decompressStream.total_out; - pOutStats->curMemoryUsed = m_zSize; - pOutStats->peakMemoryUsed = m_zPeak; -} - -unsigned int CZLibInflateStream::GetBytesOutput() -{ - return m_decompressStream.total_out; -} - -void CZLibInflateStream::Input(const char* pInSource, unsigned int inSourceSize) -{ - CRY_ASSERT_MESSAGE(m_currentState == eZInfState_AwaitingInput, "CZLibInflateStream::Input() called when stream is not awaiting input or has finished"); - - m_decompressStream.next_in = (Bytef*)pInSource; - m_decompressStream.avail_in = inSourceSize; - m_bytesInput += inSourceSize; -} - -void CZLibInflateStream::EndInput() -{ - CRY_ASSERT_MESSAGE(m_currentState == eZInfState_AwaitingInput, "CZLibInflateStream::EndInput() called when stream is not awaiting input"); - - m_zlibFlush = Z_FINISH; -} - -voidpf CZLibInflateStream::ZAlloc(voidpf pInOpaque, uInt inItems, uInt inSize) -{ - CZLibInflateStream* pStr = reinterpret_cast(pInOpaque); - - const unsigned int size = inItems * inSize; - - int* pPtr = (int*)CryModuleMalloc(sizeof(int) + size); - - if (pPtr) - { - *pPtr = inItems * inSize; - pPtr += 1; - - const unsigned int newSize = pStr->m_zSize + size; - pStr->m_zSize = newSize; - if (newSize > pStr->m_zPeak) - { - pStr->m_zPeak = newSize; - } - } - - return pPtr; -} - -void CZLibInflateStream::ZFree(voidpf pInOpaque, voidpf pInAddress) -{ - int* pPtr = reinterpret_cast(pInAddress); - - if (pPtr) - { - CZLibInflateStream* pStr = reinterpret_cast(pInOpaque); - pStr->m_zSize -= pPtr[-1]; - CryModuleFree(pPtr - 1); - } -} - -EZInflateState CZLibInflateStream::RunInflate() -{ - bool runInflate = false; - bool inputAvailable = (m_decompressStream.avail_in > 0) || (m_zlibFlush == Z_FINISH); - bool outputAvailable = (m_decompressStream.avail_out > 0); - - switch (m_currentState) - { - case eZInfState_AwaitingInput: - case eZInfState_ConsumeOutput: - if (inputAvailable && outputAvailable) - { - runInflate = true; - } - else if (inputAvailable || !outputAvailable) - { - m_currentState = eZInfState_ConsumeOutput; - } - else - { - m_currentState = eZInfState_AwaitingInput; - } - break; - - case eZInfState_Inflating: - CRY_ASSERT_MESSAGE(false, "Shouldn't be trying to run inflate whilst a inflate is in progress"); - break; - - case eZInfState_Error: - break; - - default: - CRY_ASSERT_MESSAGE(false, "unknown state"); - break; - } - - if (runInflate) - { - if (!m_bStreamOpened) - { - m_bStreamOpened = true; - - // initializing with inflateInit2 requires that the next_in be initialized - m_decompressStream.zalloc = &CZLibInflateStream::ZAlloc; - m_decompressStream.zfree = &CZLibInflateStream::ZFree; - m_decompressStream.opaque = this; - - const int error = inflateInit2(&m_decompressStream, -MAX_WBITS); - if (error != Z_OK) - { - m_currentState = eZInfState_Error; - CryLog("zlib inflateInit2() error, err %d", error); - } - } - - if (m_currentState != eZInfState_Error) - { - int error = inflate(&m_decompressStream, m_zlibFlush); - - if (error == Z_STREAM_END) - { - // end of stream has been generated, only produced if we pass Z_FINISH into inflate - m_currentState = eZInfState_Finished; - } - else if ((error == Z_OK && m_decompressStream.avail_out == 0) || (error == Z_BUF_ERROR && m_decompressStream.avail_out == 0)) - { - // output buffer has been filled - // data should be available for consumption by caller - m_currentState = eZInfState_ConsumeOutput; - } - else if (m_decompressStream.avail_in == 0) - { - // ran out of input data - // data may be available for consumption - but we need more input right now - m_currentState = eZInfState_AwaitingInput; - } - else - { - // some sort of error has occurred - m_currentState = eZInfState_Error; - CryLog("zlib inflate() error, err %d", error); - } - } - } - - return m_currentState; -} - -EZInflateState CZLibInflateStream::GetState() -{ - return RunInflate(); -} diff --git a/Code/CryEngine/CrySystem/ZLibDecompressor.h b/Code/CryEngine/CrySystem/ZLibDecompressor.h deleted file mode 100644 index 0a3ca0669f..0000000000 --- a/Code/CryEngine/CrySystem/ZLibDecompressor.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : zlib inflate wrapper - - -#ifndef CRYINCLUDE_CRYSYSTEM_ZLIBDECOMPRESSOR_H -#define CRYINCLUDE_CRYSYSTEM_ZLIBDECOMPRESSOR_H -#pragma once - - -#include "IZlibDecompressor.h" - -class CZLibDecompressor - : public IZLibDecompressor -{ -public: - virtual IZLibInflateStream* CreateInflateStream(); - virtual void Release(); - -private: - virtual ~CZLibDecompressor() {} -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ZLIBDECOMPRESSOR_H diff --git a/Code/CryEngine/CrySystem/ZStdDecompressor.cpp b/Code/CryEngine/CrySystem/ZStdDecompressor.cpp deleted file mode 100644 index 0de76b82f8..0000000000 --- a/Code/CryEngine/CrySystem/ZStdDecompressor.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "CrySystem_precompiled.h" -#include -#include "ZStdDecompressor.h" - -bool CZStdDecompressor::DecompressData(const char* pIn, const uint inputSize, char* pOut, const uint outputSize) -{ - size_t result = ZSTD_decompress(pOut, outputSize, pIn, inputSize); - return !ZSTD_isError(result); -} - -void CZStdDecompressor::Release() -{ - delete this; -} diff --git a/Code/CryEngine/CrySystem/ZStdDecompressor.h b/Code/CryEngine/CrySystem/ZStdDecompressor.h deleted file mode 100644 index 200e5fe350..0000000000 --- a/Code/CryEngine/CrySystem/ZStdDecompressor.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - - -#include "IZStdDecompressor.h" - -class CZStdDecompressor - : public IZStdDecompressor -{ -public: - bool DecompressData(const char* pIn, const uint inputSize, char* pOut, const uint outputSize) override; - void Release() override; - -protected: - ~CZStdDecompressor() override = default; -}; - diff --git a/Code/CryEngine/CrySystem/ZipFile.h b/Code/CryEngine/CrySystem/ZipFile.h deleted file mode 100644 index e0c42088a3..0000000000 --- a/Code/CryEngine/CrySystem/ZipFile.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_ZIPFILE_H -#define CRYINCLUDE_CRYSYSTEM_ZIPFILE_H -#pragma once - - -#endif // CRYINCLUDE_CRYSYSTEM_ZIPFILE_H diff --git a/Code/CryEngine/CrySystem/ZipFileFormat_info.h b/Code/CryEngine/CrySystem/ZipFileFormat_info.h deleted file mode 100644 index d3fd4a3f54..0000000000 --- a/Code/CryEngine/CrySystem/ZipFileFormat_info.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_ZIPFILEFORMAT_INFO_H -#define CRYINCLUDE_CRYSYSTEM_ZIPFILEFORMAT_INFO_H -#pragma once - -#include "ZipFileFormat.h" - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Waddress-of-packed-member" -#endif - -STRUCT_INFO_BEGIN(ZipFile::CDREnd) -VAR_INFO(lSignature) -VAR_INFO(nDisk) -VAR_INFO(nCDRStartDisk) -VAR_INFO(numEntriesOnDisk) -VAR_INFO(numEntriesTotal) -VAR_INFO(lCDRSize) -VAR_INFO(lCDROffset) -VAR_INFO(nCommentLength) -STRUCT_INFO_END(ZipFile::CDREnd) - -STRUCT_INFO_BEGIN(ZipFile::DataDescriptor) -VAR_INFO(lCRC32) -VAR_INFO(lSizeCompressed) -VAR_INFO(lSizeUncompressed) -STRUCT_INFO_END(ZipFile::DataDescriptor) - -STRUCT_INFO_BEGIN(ZipFile::CDRFileHeader) -VAR_INFO(lSignature) -VAR_INFO(nVersionMadeBy) -VAR_INFO(nVersionNeeded) -VAR_INFO(nFlags) -VAR_INFO(nMethod) -VAR_INFO(nLastModTime) -VAR_INFO(nLastModDate) -VAR_INFO(desc) -VAR_INFO(nFileNameLength) -VAR_INFO(nExtraFieldLength) -VAR_INFO(nFileCommentLength) -VAR_INFO(nDiskNumberStart) -VAR_INFO(nAttrInternal) -VAR_INFO(lAttrExternal) -VAR_INFO(lLocalHeaderOffset) -STRUCT_INFO_END(ZipFile::CDRFileHeader) - -STRUCT_INFO_BEGIN(ZipFile::LocalFileHeader) -VAR_INFO(lSignature) -VAR_INFO(nVersionNeeded) -VAR_INFO(nFlags) -VAR_INFO(nMethod) -VAR_INFO(nLastModTime) -VAR_INFO(nLastModDate) -VAR_INFO(desc) -VAR_INFO(nFileNameLength) -VAR_INFO(nExtraFieldLength) -STRUCT_INFO_END(ZipFile::LocalFileHeader) - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif - -#endif // CRYINCLUDE_CRYSYSTEM_ZIPFILEFORMAT_INFO_H diff --git a/Code/CryEngine/CrySystem/crash_face.bmp b/Code/CryEngine/CrySystem/crash_face.bmp deleted file mode 100644 index 887e5111c9..0000000000 --- a/Code/CryEngine/CrySystem/crash_face.bmp +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ced9f21365ad5a4159f31f602be10a00becf389fa289694026425e7a6bc73077 -size 9272 diff --git a/Code/CryEngine/CrySystem/crysystem_android_files.cmake b/Code/CryEngine/CrySystem/crysystem_android_files.cmake deleted file mode 100644 index 9164dce432..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_android_files.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - MobileDetectSpec_Android.cpp - MobileDetectSpec.cpp - MobileDetectSpec.h - ThermalInfoAndroid.h - ThermalInfoAndroid.cpp -) diff --git a/Code/CryEngine/CrySystem/crysystem_dlmalloc_files.cmake b/Code/CryEngine/CrySystem/crysystem_dlmalloc_files.cmake deleted file mode 100644 index 9f94bf6cff..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_dlmalloc_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - CryDLMalloc.c -) diff --git a/Code/CryEngine/CrySystem/crysystem_files.cmake b/Code/CryEngine/CrySystem/crysystem_files.cmake index 6eff1ee8e2..6a56339b85 100644 --- a/Code/CryEngine/CrySystem/crysystem_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_files.cmake @@ -10,41 +10,20 @@ # set(FILES - AutoDetectSpec.cpp AZCrySystemInitLogSink.cpp - ClientHandler.cpp CmdLine.cpp CmdLineArg.cpp - CompressedFile.cpp ConsoleBatchFile.cpp ConsoleHelpGen.cpp - CryAsyncMemcpy.cpp - HandlerBase.cpp Log.cpp - SystemRender.cpp - PhysRenderer.cpp - ServerHandler.cpp - ServerThrottle.cpp - SyncLock.cpp System.cpp SystemCFG.cpp SystemEventDispatcher.cpp SystemInit.cpp SystemWin32.cpp Timer.cpp - UnixConsole.cpp - WindowsConsole.cpp XConsole.cpp XConsoleVariable.cpp - AutoDetectSpec.h - ClientHandler.h - HandlerBase.h - PhysRenderer.h - ServerHandler.h - ServerThrottle.h - SyncLock.h - UnixConsole.h - SystemInit.h XML/ReadWriteXMLSink.h AZCrySystemInitLogSink.h AZCoreLogSink.h @@ -52,17 +31,13 @@ set(FILES CmdLineArg.h ConsoleBatchFile.h ConsoleHelpGen.h - CryWaterMark.h Log.h - resource.h SimpleStringPool.h CrySystem_precompiled.h System.h SystemCFG.h SystemEventDispatcher.h Timer.h - Validator.h - WindowsConsole.h XConsole.h XConsoleVariable.h XML/SerializeXMLReader.cpp @@ -78,24 +53,14 @@ set(FILES XML/XmlUtils.h XML/ReadXMLSink.cpp XML/WriteXMLSource.cpp - ZipFile.h - ZipFileFormat_info.h - Sampler.cpp - Sampler.h LocalizedStringManager.cpp LocalizedStringManager.h - ZLibCompressor.cpp - ZLibCompressor.h Huffman.cpp Huffman.h RemoteConsole/RemoteConsole.cpp RemoteConsole/RemoteConsole.h RemoteConsole/RemoteConsole_impl.inl RemoteConsole/RemoteConsole_none.inl - ZLibDecompressor.h - ZLibDecompressor.cpp - LZ4Decompressor.h - LZ4Decompressor.cpp LevelSystem/LevelSystem.cpp LevelSystem/LevelSystem.h LevelSystem/SpawnableLevelSystem.cpp @@ -106,10 +71,5 @@ set(FILES ViewSystem/View.h ViewSystem/ViewSystem.cpp ViewSystem/ViewSystem.h - ZStdDecompressor.h - ZStdDecompressor.cpp CrySystem_precompiled.cpp - CPUDetect.cpp - CPUDetect.h - WindowsErrorReporting.cpp ) diff --git a/Code/CryEngine/CrySystem/crysystem_ios_files.cmake b/Code/CryEngine/CrySystem/crysystem_ios_files.cmake deleted file mode 100644 index eca0f5142c..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_ios_files.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - MobileDetectSpec_Ios.cpp - MobileDetectSpec.cpp - MobileDetectSpec.h -) diff --git a/Code/CryEngine/CrySystem/crysystem_mac_files.cmake b/Code/CryEngine/CrySystem/crysystem_mac_files.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_mac_files.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - diff --git a/Code/CryEngine/CrySystem/crysystem_test_files.cmake b/Code/CryEngine/CrySystem/crysystem_test_files.cmake deleted file mode 100644 index d8f6887da6..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_test_files.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - Components/MathConversionTests.cpp - Tests/Test_CLog.cpp - Tests/Test_CommandRegistration.cpp - Tests/Test_CryPrimitives.cpp - Tests/test_CrySystem.cpp - Tests/Test_Localization.cpp - Tests/test_Main.cpp - Tests/test_MaterialUtils.cpp - DllMain.cpp -) diff --git a/Code/CryEngine/CrySystem/resource.h b/Code/CryEngine/CrySystem/resource.h deleted file mode 100644 index a5970a6475..0000000000 --- a/Code/CryEngine/CrySystem/resource.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#define VS_VERSION_INFO 1 -#define IDD_CRITICAL_ERROR 101 -#define IDB_CONFIRM_SAVE 102 -#define IDB_DONT_SAVE 103 -#define IDD_CONFIRM_SAVE_LEVEL 127 -#define IDB_CRASH_FACE 128 -#define IDD_EXCEPTION 245 -#define IDC_CALLSTACK 1001 -#define IDC_EXCEPTION_CODE 1002 -#define IDC_EXCEPTION_ADDRESS 1003 -#define IDC_EXCEPTION_MODULE 1004 -#define IDC_EXCEPTION_DESC 1005 -#define IDB_EXIT 1008 -#define IDB_IGNORE 1010 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 129 -#define _APS_NEXT_COMMAND_VALUE 40072 -#define _APS_NEXT_CONTROL_VALUE 1003 -#define _APS_NEXT_SYMED_VALUE 104 -#endif -#endif diff --git a/Code/CryEngine/CryCommon/ThermalInfo.h b/Code/Framework/AzFramework/AzFramework/Thermal/ThermalInfo.h similarity index 100% rename from Code/CryEngine/CryCommon/ThermalInfo.h rename to Code/Framework/AzFramework/AzFramework/Thermal/ThermalInfo.h diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake index f73e67b94e..8cff479ec8 100644 --- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake +++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake @@ -296,6 +296,7 @@ set(FILES Spawnable/SpawnableSystemComponent.cpp Terrain/TerrainDataRequestBus.h Terrain/TerrainDataRequestBus.cpp + Thermal/ThermalInfo.h Platform/PlatformDefaults.h Windowing/WindowBus.h Windowing/NativeWindow.cpp diff --git a/Code/Framework/AzFramework/Platform/Android/AzFramework/Application/Application_Android.cpp b/Code/Framework/AzFramework/Platform/Android/AzFramework/Application/Application_Android.cpp index cc1b0b8035..cb003dd130 100644 --- a/Code/Framework/AzFramework/Platform/Android/AzFramework/Application/Application_Android.cpp +++ b/Code/Framework/AzFramework/Platform/Android/AzFramework/Application/Application_Android.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -95,6 +96,7 @@ namespace AzFramework private: AndroidEventDispatcher* m_eventDispatcher; ApplicationLifecycleEvents::Event m_lastEvent; + AZStd::unique_ptr m_thermalInfoHandler; AZStd::atomic m_requestResponseReceived; AZStd::unique_ptr m_lumberyardActivity; @@ -125,6 +127,10 @@ namespace AzFramework AndroidLifecycleEvents::Bus::Handler::BusConnect(); AndroidAppRequests::Bus::Handler::BusConnect(); PermissionRequestResultNotification::Bus::Handler::BusConnect(); + +#if !defined(AZ_RELEASE_BUILD) + m_thermalInfoHandler = AZStd::make_unique(); +#endif } //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/ThermalInfoAndroid.cpp b/Code/Framework/AzFramework/Platform/Android/AzFramework/Thermal/ThermalInfo_Android.cpp similarity index 99% rename from Code/CryEngine/CrySystem/ThermalInfoAndroid.cpp rename to Code/Framework/AzFramework/Platform/Android/AzFramework/Thermal/ThermalInfo_Android.cpp index 0c69a728fa..9a2100e1bd 100644 --- a/Code/CryEngine/CrySystem/ThermalInfoAndroid.cpp +++ b/Code/Framework/AzFramework/Platform/Android/AzFramework/Thermal/ThermalInfo_Android.cpp @@ -11,7 +11,7 @@ */ #if !defined(AZ_RELEASE_BUILD) -#include "ThermalInfoAndroid.h" +#include "ThermalInfo_Android.h" #include #include diff --git a/Code/CryEngine/CrySystem/ThermalInfoAndroid.h b/Code/Framework/AzFramework/Platform/Android/AzFramework/Thermal/ThermalInfo_Android.h similarity index 95% rename from Code/CryEngine/CrySystem/ThermalInfoAndroid.h rename to Code/Framework/AzFramework/Platform/Android/AzFramework/Thermal/ThermalInfo_Android.h index 07d1b86f68..2781d2cf52 100644 --- a/Code/CryEngine/CrySystem/ThermalInfoAndroid.h +++ b/Code/Framework/AzFramework/Platform/Android/AzFramework/Thermal/ThermalInfo_Android.h @@ -13,7 +13,7 @@ #pragma once #if !defined(AZ_RELEASE_BUILD) -#include +#include class ThermalInfoAndroidHandler : public ThermalInfoRequestsBus::Handler { diff --git a/Code/Framework/AzFramework/Platform/Android/platform_android_files.cmake b/Code/Framework/AzFramework/Platform/Android/platform_android_files.cmake index 38d07ec9f5..3721632fbb 100644 --- a/Code/Framework/AzFramework/Platform/Android/platform_android_files.cmake +++ b/Code/Framework/AzFramework/Platform/Android/platform_android_files.cmake @@ -36,4 +36,6 @@ set(FILES AzFramework/Process/ProcessCommon.h AzFramework/Process/ProcessWatcher_Android.cpp AzFramework/Process/ProcessCommunicator_Android.cpp + AzFramework/Thermal/ThermalInfo_Android.cpp + AzFramework/Thermal/ThermalInfo_Android.h ) diff --git a/Code/Sandbox/Editor/GameEngine.cpp b/Code/Sandbox/Editor/GameEngine.cpp index 2112d00d64..c338a2e28d 100644 --- a/Code/Sandbox/Editor/GameEngine.cpp +++ b/Code/Sandbox/Editor/GameEngine.cpp @@ -424,7 +424,6 @@ AZ::Outcome CGameEngine::Init( sip.pLogCallback = &m_logFile; sip.sLogFileName = "@log@/Editor.log"; sip.pUserCallback = m_pSystemUserCallback; - sip.pValidator = GetIEditor()->GetErrorReport(); // Assign validator from Editor. if (sInCmdLine) { diff --git a/Code/Sandbox/Editor/GraphicsSettingsDialog.cpp b/Code/Sandbox/Editor/GraphicsSettingsDialog.cpp index 516e723d6b..593abeeddc 100644 --- a/Code/Sandbox/Editor/GraphicsSettingsDialog.cpp +++ b/Code/Sandbox/Editor/GraphicsSettingsDialog.cpp @@ -779,36 +779,6 @@ bool GraphicsSettingsDialog::CVarChanged(AZStd::any val, const char* cvarName, i m_cVarTracker[cvarName].fileVals[specLevel].editedValue = val; } - // If changing cvar from the platform cfg file currently running, set cvar - if (GetISystem()->GetConfigPlatform() == m_currentPlatform && GetISystem()->GetConfigSpec() == specLevel + 1) - { - if (ICVar* cvar = gEnv->pConsole->GetCVar(cvarName)) - { - int type = cvar->GetType(); - if (type == CVAR_INT) - { - int newValue; - if (AZStd::any_numeric_cast(&val, newValue)) - { - cvar->Set(newValue); - } - } - else if (type == CVAR_FLOAT) - { - float newValue; - if (AZStd::any_numeric_cast(&val, newValue)) - { - cvar->Set(newValue); - } - } - else - { - AZStd::string* currValue = AZStd::any_cast(&val); - cvar->Set(currValue->c_str()); - } - } - } - // Checking if the newly edited value is equal to the overwritten value cvarInfo = AZStd::make_pair(azcvarName, m_cVarTracker[cvarName]); if (CheckCVarStatesForDiff(&cvarInfo, specLevel, EDITED_OVERWRITTEN_COMPARE)) diff --git a/Code/Sandbox/Editor/IEditorImpl.cpp b/Code/Sandbox/Editor/IEditorImpl.cpp index 4b3c494413..0c8398050c 100644 --- a/Code/Sandbox/Editor/IEditorImpl.cpp +++ b/Code/Sandbox/Editor/IEditorImpl.cpp @@ -1584,16 +1584,9 @@ void CEditorImpl::AddUIEnums() m_pUIEnumsDatabase->SetEnumStrings("ShadowMinResPercent", types); } -void CEditorImpl::SetEditorConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform) +void CEditorImpl::SetEditorConfigSpec(ESystemConfigSpec spec, [[maybe_unused]]ESystemConfigPlatform platform) { gSettings.editorConfigSpec = spec; - if (m_pSystem->GetConfigSpec(true) != spec || m_pSystem->GetConfigPlatform() != platform) - { - m_pSystem->SetConfigSpec(spec, platform, true); - gSettings.editorConfigSpec = m_pSystem->GetConfigSpec(true); - GetObjectManager()->SendEvent(EVENT_CONFIG_SPEC_CHANGE); - AzToolsFramework::EditorEvents::Bus::Broadcast(&AzToolsFramework::EditorEvents::OnEditorSpecChange); - } } ESystemConfigSpec CEditorImpl::GetEditorConfigSpec() const diff --git a/Code/Sandbox/Editor/Util/PathUtil.cpp b/Code/Sandbox/Editor/Util/PathUtil.cpp index 9f713eb0f3..6efc06c79e 100644 --- a/Code/Sandbox/Editor/Util/PathUtil.cpp +++ b/Code/Sandbox/Editor/Util/PathUtil.cpp @@ -272,21 +272,6 @@ namespace Path return str; } - //! Set the current mod NAME for editing purposes. After doing this the above functions will take this into account - //! name only, please! - void SetModName(const char* input) - { - if ( - (!input) || - ((gEnv) && (gEnv->pSystem) && (!gEnv->pSystem->IsMODValid(input))) // we can only validate - ) - { - AZ_Warning("PathUtil", false, "Invalid mod name supplied to SetModName: %s - ignored.", input ? input : "(NULL)"); - return; - } - g_currentModName = input; - } - //! Get the root folder (in source control or other writable assets) where you should save root data. AZStd::string GetEditingRootFolder() { diff --git a/scripts/build/package/Platform/Windows/package_filelists/atom.json b/scripts/build/package/Platform/Windows/package_filelists/atom.json index ad2df7691e..e18e191882 100644 --- a/scripts/build/package/Platform/Windows/package_filelists/atom.json +++ b/scripts/build/package/Platform/Windows/package_filelists/atom.json @@ -138,7 +138,6 @@ "3dsmax/**": "#include", "7za.exe": "#include", "7za_legal_notice.txt": "#include", - "CrySCompileServer/**": "#include", "PakShaders/**": "#include", "Python/**": "#include", "Redistributables": { From 9b9ae22d235c7b45ab2c04e0a973970796366f60 Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Fri, 14 May 2021 14:53:32 -0700 Subject: [PATCH 220/225] Update Prism Python bindings interface Add GetProjects, GetProjectTemplates, GetGems, GetProject and GetGem. CreateProject and UpdateProject and the engine functions are not implemented yet --- .../ProjectManager/Source/EngineInfo.cpp | 21 ++ Code/Tools/ProjectManager/Source/EngineInfo.h | 29 ++ .../Source/GemCatalog/GemCatalogScreen.cpp | 9 + .../Source/GemCatalog/GemInfo.cpp | 6 + .../Source/GemCatalog/GemInfo.h | 3 + .../ProjectManager/Source/ProjectInfo.cpp | 5 + .../Tools/ProjectManager/Source/ProjectInfo.h | 4 +- .../Source/ProjectTemplateInfo.cpp | 26 ++ .../Source/ProjectTemplateInfo.h | 37 +++ .../ProjectManager/Source/PythonBindings.cpp | 258 +++++++++++++++++- .../ProjectManager/Source/PythonBindings.h | 31 ++- .../Source/PythonBindingsInterface.h | 75 ++++- .../project_manager_files.cmake | 4 + 13 files changed, 489 insertions(+), 19 deletions(-) create mode 100644 Code/Tools/ProjectManager/Source/EngineInfo.cpp create mode 100644 Code/Tools/ProjectManager/Source/EngineInfo.h create mode 100644 Code/Tools/ProjectManager/Source/ProjectTemplateInfo.cpp create mode 100644 Code/Tools/ProjectManager/Source/ProjectTemplateInfo.h diff --git a/Code/Tools/ProjectManager/Source/EngineInfo.cpp b/Code/Tools/ProjectManager/Source/EngineInfo.cpp new file mode 100644 index 0000000000..8043a498ff --- /dev/null +++ b/Code/Tools/ProjectManager/Source/EngineInfo.cpp @@ -0,0 +1,21 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include "EngineInfo.h" + +namespace O3DE::ProjectManager +{ + EngineInfo::EngineInfo(const QString& path) + : m_path(path) + { + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/EngineInfo.h b/Code/Tools/ProjectManager/Source/EngineInfo.h new file mode 100644 index 0000000000..ada6e73a15 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/EngineInfo.h @@ -0,0 +1,29 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#endif + +namespace O3DE::ProjectManager +{ + class EngineInfo + { + public: + EngineInfo() = default; + EngineInfo(const QString& path); + + QString m_path; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp index 9f3d3b6e23..c62674122f 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace O3DE::ProjectManager { @@ -78,6 +79,14 @@ namespace O3DE::ProjectManager false)); } // End: Temporary gem test data + auto result = PythonBindingsInterface::Get()->GetGems(); + if (result.IsSuccess()) + { + for (auto gemInfo : result.GetValue()) + { + m_gemModel->AddGem(gemInfo); + } + } } ProjectManagerScreen GemCatalogScreen::GetScreenEnum() diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.cpp index b11c7a7a2c..7ba4021205 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.cpp @@ -22,4 +22,10 @@ namespace O3DE::ProjectManager , m_isAdded(isAdded) { } + + bool GemInfo::IsValid() const + { + return !m_path.isEmpty() && !m_uuid.IsNull(); + } + } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h index 4766187d2a..098b67dbf5 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h @@ -35,8 +35,11 @@ namespace O3DE::ProjectManager }; Q_DECLARE_FLAGS(Platforms, Platform) + GemInfo() = default; GemInfo(const QString& name, const QString& creator, const QString& summary, Platforms platforms, bool isAdded); + bool IsValid() const; + QString m_path; QString m_name; QString m_displayName; diff --git a/Code/Tools/ProjectManager/Source/ProjectInfo.cpp b/Code/Tools/ProjectManager/Source/ProjectInfo.cpp index 77bcb6f1b2..4dc6eaa38b 100644 --- a/Code/Tools/ProjectManager/Source/ProjectInfo.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectInfo.cpp @@ -25,4 +25,9 @@ namespace O3DE::ProjectManager , m_isNew(isNew) { } + + bool ProjectInfo::IsValid() const + { + return !m_path.isEmpty() && !m_projectId.IsNull(); + } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectInfo.h b/Code/Tools/ProjectManager/Source/ProjectInfo.h index 04ae358c14..d86991e76e 100644 --- a/Code/Tools/ProjectManager/Source/ProjectInfo.h +++ b/Code/Tools/ProjectManager/Source/ProjectInfo.h @@ -26,7 +26,9 @@ namespace O3DE::ProjectManager ProjectInfo(const QString& path, const QString& projectName, const QString& productName, const AZ::Uuid projectId, const QString& imagePath, const QString& backgroundImagePath, bool isNew); - // From o3de_manifest.json and o3de_projects.json + bool IsValid() const; + + // from o3de_manifest.json and o3de_projects.json QString m_path; // From project.json diff --git a/Code/Tools/ProjectManager/Source/ProjectTemplateInfo.cpp b/Code/Tools/ProjectManager/Source/ProjectTemplateInfo.cpp new file mode 100644 index 0000000000..32c3146510 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectTemplateInfo.cpp @@ -0,0 +1,26 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include "ProjectTemplateInfo.h" + +namespace O3DE::ProjectManager +{ + ProjectTemplateInfo::ProjectTemplateInfo(const QString& path) + : m_path(path) + { + } + + bool ProjectTemplateInfo::IsValid() const + { + return !m_path.isEmpty() && !m_name.isEmpty(); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectTemplateInfo.h b/Code/Tools/ProjectManager/Source/ProjectTemplateInfo.h new file mode 100644 index 0000000000..0477968050 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectTemplateInfo.h @@ -0,0 +1,37 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#endif + +namespace O3DE::ProjectManager +{ + class ProjectTemplateInfo + { + public: + ProjectTemplateInfo() = default; + ProjectTemplateInfo(const QString& path); + + bool IsValid() const; + + QString m_displayName; + QString m_name; + QString m_path; + QString m_summary; + QStringList m_canonicalTags; + QStringList m_userTags; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index cc14e9e4de..cc5348fd22 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -12,12 +12,11 @@ #include + // Qt defines slots, which interferes with the use here. #pragma push_macro("slots") #undef slots -#include #include -#include #include #include #pragma pop_macro("slots") @@ -51,6 +50,9 @@ namespace Platform } // namespace Platform +#define Py_To_String(obj) obj.cast().c_str() +#define Py_To_String_Optional(dict, key, default_string) dict.contains(key) ? Py_To_String(dict[key]) : default_string + namespace O3DE::ProjectManager { PythonBindings::PythonBindings(const AZ::IO::PathView& enginePath) @@ -109,10 +111,13 @@ namespace O3DE::ProjectManager result = PyRun_SimpleString(AZStd::string::format("sys.path.append('%s')", m_enginePath.c_str()).c_str()); AZ_Warning("ProjectManagerWindow", result != -1, "Append to sys path failed"); + // import required modules + m_registration = pybind11::module::import("cmake.Tools.registration"); + return result == 0 && !PyErr_Occurred(); } catch ([[maybe_unused]] const std::exception& e) { - AZ_Warning("python", false, "Py_Initialize() failed with %s", e.what()); + AZ_Warning("ProjectManagerWindow", false, "Py_Initialize() failed with %s", e.what()); return false; } } @@ -125,31 +130,256 @@ namespace O3DE::ProjectManager } else { - AZ_Warning("python", false, "Did not finalize since Py_IsInitialized() was false"); + AZ_Warning("ProjectManagerWindow", false, "Did not finalize since Py_IsInitialized() was false"); } return !PyErr_Occurred(); } - void PythonBindings::ExecuteWithLock(AZStd::function executionCallback) + bool PythonBindings::ExecuteWithLock(AZStd::function executionCallback) { AZStd::lock_guard lock(m_lock); pybind11::gil_scoped_release release; pybind11::gil_scoped_acquire acquire; - executionCallback(); + + try + { + executionCallback(); + return true; + } + catch ([[maybe_unused]] const std::exception& e) + { + AZ_Warning("PythonBindings", false, "Python exception %s", e.what()); + return false; + } } - ProjectInfo PythonBindings::GetCurrentProject() + AZ::Outcome PythonBindings::GetEngineInfo() { - ProjectInfo project; + return AZ::Failure(); + } - ExecuteWithLock([&] { - auto currentProjectTool = pybind11::module::import("cmake.Tools.current_project"); - auto getCurrentProject = currentProjectTool.attr("get_current_project"); - auto currentProject = getCurrentProject(m_enginePath.c_str()); + bool PythonBindings::SetEngineInfo([[maybe_unused]] const EngineInfo& engineInfo) + { + return false; + } - project.m_path = currentProject.cast().c_str(); + AZ::Outcome PythonBindings::GetGem(const QString& path) + { + GemInfo gemInfo = GemInfoFromPath(pybind11::str(path.toStdString())); + if (gemInfo.IsValid()) + { + return AZ::Success(AZStd::move(gemInfo)); + } + else + { + return AZ::Failure(); + } + } + + AZ::Outcome> PythonBindings::GetGems() + { + QVector gems; + + bool result = ExecuteWithLock([&] { + // external gems + for (auto path : m_registration.attr("get_gems")()) + { + gems.push_back(GemInfoFromPath(path)); + } + + // gems from the engine + for (auto path : m_registration.attr("get_engine_gems")()) + { + gems.push_back(GemInfoFromPath(path)); + } }); - return project; + if (!result) + { + return AZ::Failure(); + } + else + { + return AZ::Success(AZStd::move(gems)); + } + } + + AZ::Outcome PythonBindings::CreateProject([[maybe_unused]] const ProjectTemplateInfo& projectTemplate,[[maybe_unused]] const ProjectInfo& projectInfo) + { + return AZ::Failure(); + } + + AZ::Outcome PythonBindings::GetProject(const QString& path) + { + ProjectInfo projectInfo = ProjectInfoFromPath(pybind11::str(path.toStdString())); + if (projectInfo.IsValid()) + { + return AZ::Success(AZStd::move(projectInfo)); + } + else + { + return AZ::Failure(); + } + } + + GemInfo PythonBindings::GemInfoFromPath(pybind11::handle path) + { + GemInfo gemInfo; + gemInfo.m_path = Py_To_String(path); + + auto data = m_registration.attr("get_gem_data")(pybind11::none(), path); + if (pybind11::isinstance(data)) + { + try + { + // required + gemInfo.m_name = Py_To_String(data["Name"]); + gemInfo.m_uuid = AZ::Uuid(Py_To_String(data["Uuid"])); + + // optional + gemInfo.m_displayName = Py_To_String_Optional(data, "DisplayName", gemInfo.m_name); + gemInfo.m_summary = Py_To_String_Optional(data, "Summary", ""); + gemInfo.m_version = Py_To_String_Optional(data, "Version", ""); + + if (data.contains("Dependencies")) + { + for (auto dependency : data["Dependencies"]) + { + gemInfo.m_dependingGemUuids.push_back(AZ::Uuid(Py_To_String(dependency["Uuid"]))); + } + } + if (data.contains("Tags")) + { + for (auto tag : data["Tags"]) + { + gemInfo.m_features.push_back(Py_To_String(tag)); + } + } + } + catch ([[maybe_unused]] const std::exception& e) + { + AZ_Warning("PythonBindings", false, "Failed to get GemInfo for gem %s", Py_To_String(path)); + } + } + + return gemInfo; + } + + ProjectInfo PythonBindings::ProjectInfoFromPath(pybind11::handle path) + { + ProjectInfo projectInfo; + projectInfo.m_path = Py_To_String(path); + + auto projectData = m_registration.attr("get_project_data")(pybind11::none(), path); + if (pybind11::isinstance(projectData)) + { + try + { + // required fields + projectInfo.m_productName = Py_To_String(projectData["product_name"]); + projectInfo.m_projectName = Py_To_String(projectData["project_name"]); + projectInfo.m_projectId = AZ::Uuid(Py_To_String(projectData["project_id"])); + } + catch ([[maybe_unused]] const std::exception& e) + { + AZ_Warning("PythonBindings", false, "Failed to get ProjectInfo for project %s", Py_To_String(path)); + } + } + + return projectInfo; + } + + AZ::Outcome> PythonBindings::GetProjects() + { + QVector projects; + + bool result = ExecuteWithLock([&] { + // external projects + for (auto path : m_registration.attr("get_projects")()) + { + projects.push_back(ProjectInfoFromPath(path)); + } + + // projects from the engine + for (auto path : m_registration.attr("get_engine_projects")()) + { + projects.push_back(ProjectInfoFromPath(path)); + } + }); + + if (!result) + { + return AZ::Failure(); + } + else + { + return AZ::Success(AZStd::move(projects)); + } + } + + bool PythonBindings::UpdateProject([[maybe_unused]] const ProjectInfo& projectInfo) + { + return false; + } + + ProjectTemplateInfo PythonBindings::ProjectTemplateInfoFromPath(pybind11::handle path) + { + ProjectTemplateInfo templateInfo; + templateInfo.m_path = Py_To_String(path); + + auto data = m_registration.attr("get_template_data")(pybind11::none(), path); + if (pybind11::isinstance(data)) + { + try + { + // required + templateInfo.m_displayName = Py_To_String(data["display_name"]); + templateInfo.m_name = Py_To_String(data["template_name"]); + templateInfo.m_summary = Py_To_String(data["summary"]); + + // optional + if (data.contains("canonical_tags")) + { + for (auto tag : data["canonical_tags"]) + { + templateInfo.m_canonicalTags.push_back(Py_To_String(tag)); + } + } + if (data.contains("user_tags")) + { + for (auto tag : data["user_tags"]) + { + templateInfo.m_canonicalTags.push_back(Py_To_String(tag)); + } + } + } + catch ([[maybe_unused]] const std::exception& e) + { + AZ_Warning("PythonBindings", false, "Failed to get ProjectTemplateInfo for %s", Py_To_String(path)); + } + } + + return templateInfo; + } + + AZ::Outcome> PythonBindings::GetProjectTemplates() + { + QVector templates; + + bool result = ExecuteWithLock([&] { + for (auto path : m_registration.attr("get_project_templates")()) + { + templates.push_back(ProjectTemplateInfoFromPath(path)); + } + }); + + if (!result) + { + return AZ::Failure(); + } + else + { + return AZ::Success(AZStd::move(templates)); + } } } diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.h b/Code/Tools/ProjectManager/Source/PythonBindings.h index ac55fffe80..9183ca2424 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.h +++ b/Code/Tools/ProjectManager/Source/PythonBindings.h @@ -15,6 +15,14 @@ #include #include +// Qt defines slots, which interferes with the use here. +#pragma push_macro("slots") +#undef slots +#include +#include +#pragma pop_macro("slots") + + namespace O3DE::ProjectManager { class PythonBindings @@ -26,16 +34,35 @@ namespace O3DE::ProjectManager ~PythonBindings() override; // PythonBindings overrides - ProjectInfo GetCurrentProject() override; + // Engine + AZ::Outcome GetEngineInfo() override; + bool SetEngineInfo(const EngineInfo& engineInfo) override; + + // Gem + AZ::Outcome GetGem(const QString& path) override; + AZ::Outcome> GetGems() override; + + // Project + AZ::Outcome CreateProject(const ProjectTemplateInfo& projectTemplate, const ProjectInfo& projectInfo) override; + AZ::Outcome GetProject(const QString& path) override; + AZ::Outcome> GetProjects() override; + bool UpdateProject(const ProjectInfo& projectInfo) override; + + // ProjectTemplate + AZ::Outcome> GetProjectTemplates() override; private: AZ_DISABLE_COPY_MOVE(PythonBindings); - void ExecuteWithLock(AZStd::function executionCallback); + bool ExecuteWithLock(AZStd::function executionCallback); + GemInfo GemInfoFromPath(pybind11::handle path); + ProjectInfo ProjectInfoFromPath(pybind11::handle path); + ProjectTemplateInfo ProjectTemplateInfoFromPath(pybind11::handle path); bool StartPython(); bool StopPython(); AZ::IO::FixedMaxPath m_enginePath; AZStd::recursive_mutex m_lock; + pybind11::handle m_registration; }; } diff --git a/Code/Tools/ProjectManager/Source/PythonBindingsInterface.h b/Code/Tools/ProjectManager/Source/PythonBindingsInterface.h index 78c3625415..f696ea958d 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindingsInterface.h +++ b/Code/Tools/ProjectManager/Source/PythonBindingsInterface.h @@ -15,9 +15,12 @@ #include #include #include +#include +#include #include #include +#include namespace O3DE::ProjectManager { @@ -31,8 +34,76 @@ namespace O3DE::ProjectManager IPythonBindings() = default; virtual ~IPythonBindings() = default; - //! Get the current project - virtual ProjectInfo GetCurrentProject() = 0; + + // Engine + + /** + * Get info about the engine + * @return an outcome with EngineInfo on success + */ + virtual AZ::Outcome GetEngineInfo() = 0; + + /** + * Set info about the engine + * @param engineInfo an EngineInfo object + */ + virtual bool SetEngineInfo(const EngineInfo& engineInfo) = 0; + + + // Gems + + /** + * Get info about a Gem + * @param path the absolute path to the Gem + * @return an outcome with GemInfo on success + */ + virtual AZ::Outcome GetGem(const QString& path) = 0; + + /** + * Get info about all known Gems + * @return an outcome with GemInfos on success + */ + virtual AZ::Outcome> GetGems() = 0; + + + // Projects + + /** + * Create a project + * @param projectTemplate the project template to use + * @param projectInfo the project info to use + * @return an outcome with ProjectInfo on success + */ + virtual AZ::Outcome CreateProject(const ProjectTemplateInfo& projectTemplate, const ProjectInfo& projectInfo) = 0; + + /** + * Get info about a project + * @param path the absolute path to the project + * @return an outcome with ProjectInfo on success + */ + virtual AZ::Outcome GetProject(const QString& path) = 0; + + /** + * Get info about all known projects + * @return an outcome with ProjectInfos on success + */ + virtual AZ::Outcome> GetProjects() = 0; + + /** + * Update a project + * @param projectInfo the info to use to update the project + * @return true on success, false on failure + */ + virtual bool UpdateProject(const ProjectInfo& projectInfo) = 0; + + + // Project Templates + + /** + * Get info about all known project templates + * @return an outcome with ProjectTemplateInfos on success + */ + virtual AZ::Outcome> GetProjectTemplates() = 0; }; using PythonBindingsInterface = AZ::Interface; diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 86a538f9db..3249d293ad 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -18,11 +18,15 @@ set(FILES Source/ScreensCtrl.h Source/ScreensCtrl.cpp Source/ScreenWidget.h + Source/EngineInfo.h + Source/EngineInfo.cpp Source/FirstTimeUseScreen.h Source/FirstTimeUseScreen.cpp Source/FirstTimeUseScreen.ui Source/ProjectManagerWindow.h Source/ProjectManagerWindow.cpp + Source/ProjectTemplateInfo.h + Source/ProjectTemplateInfo.cpp Source/ProjectManagerWindow.ui Source/PythonBindings.h Source/PythonBindings.cpp From bb3142278e2bb90049f5ccb06a846a49724a190e Mon Sep 17 00:00:00 2001 From: karlberg Date: Fri, 14 May 2021 15:03:11 -0700 Subject: [PATCH 221/225] Fixes an example comment error in multiplayer component jinjas --- .../Code/Source/AutoGen/AutoComponent_Common.jinja | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Common.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Common.jinja index d187a151fd..4279c26cf2 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Common.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Common.jinja @@ -282,14 +282,14 @@ namespace {{ Component.attrib['Namespace'] }} void {{ ControllerName }}::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) { } -{% if NetworkInputCount > 0 %} +{% if NetworkInputCount > 0 %} void {{ ControllerName }}::ProcessInput([[maybe_unused]] Multiplayer::NetworkInput& input, [[maybe_unused]] float deltaTime) { } +{% endif %} {% endif %} } -{% endif %} */ {% else %} // NOTE: From 61c24ee265f4f7d8fdf69785ac900f7ed88da214 Mon Sep 17 00:00:00 2001 From: karlberg Date: Fri, 14 May 2021 15:22:57 -0700 Subject: [PATCH 222/225] Removing tab in cmake file --- Gems/Multiplayer/Code/multiplayer_files.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Multiplayer/Code/multiplayer_files.cmake b/Gems/Multiplayer/Code/multiplayer_files.cmake index 7b335854fa..8dd7c07689 100644 --- a/Gems/Multiplayer/Code/multiplayer_files.cmake +++ b/Gems/Multiplayer/Code/multiplayer_files.cmake @@ -37,7 +37,7 @@ set(FILES Source/Multiplayer_precompiled.h Source/MultiplayerSystemComponent.cpp Source/MultiplayerSystemComponent.h - Source/MultiplayerStats.cpp + Source/MultiplayerStats.cpp Source/AutoGen/AutoComponent_Header.jinja Source/AutoGen/AutoComponent_Source.jinja Source/AutoGen/AutoComponent_Common.jinja From 0b35d278336b73402cab4855c965ae0e333c2e94 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Sat, 15 May 2021 16:16:49 -0500 Subject: [PATCH 223/225] Added support to the AZ Console to be notified when the Settings Registry modifies a particular path (#691) * Updated the SettingsRegistry CommandLineArgumentSettings delimiter function to no longer work on a character basis, but on a line basis. This provides more control by the user to determine how to the argument into the JSON pointer and JSON value parts Added function o the Settings Registry to specify the JSON Apply Patch settings to use when performing a JSON Patch/Merge Patch operation Fixed the SettingsRegistryImpl::CommandLineArgument function to properly set unsigned 64-bit values into the SettingsRegistry by checking the ERRNO of strtoll and strtoull * Updated the reporting of the JSON Patching operations to supply a JSON pointer of the patched element to the Issue Reporting callback when the patch operation is successful. This allows using the Issue Reporting callback as a notification system when field is updated during a patch operation * Added support to the AZ Console to be able to run Console Commands based on notifications from the Settings Registry when a field underneath the "/Amazon/AzCore/Runtime/ConsoleCommands" object is modified. This takes advantage of the Settings Registry RegisterNotifier API to determine when a field is modified as well as the JSON Merger JsonApplyPatchSettings Issue Reporting Callback to determine when a field is modified or updated. As a Side Note also fixed an issue with the AZ Console incorrectly converting unsigned 64-bit types using strtoll * Making the Console constructor which accepts an AZ::SettingsRegistryInterface explicit * Updating string format calls which use *.s for formatting string_views, to use the AZ_STRING_ARG macro * Addressed typos in comments around the SettingsRegistry AZ Console functions * Fixed the SettingsRegistryTest that look for an empty value * clang 6.0.0 constexpr build fix. For some reason clang cannot make a constexpr AZStd::string_view out of a constexpr AZStd::fixed_string despite there being a valid constexpr operator AZStd::string_view * Mac build fix * SettingsRegistryTest.MergeSettingsFolder_ConflictingSpecializations_ReportsErrorAndReturnsFalse test fix on Mac * Updated the LoadSettingsFile test to validate running a console with 0 arguments Replace the static_cast in the ConsoleTypeHelpers.inl code to convert a str to long long with an aznumeric_cast * Added printf logging to the ConsoleCommandKeyNotificationHandler to determine if the console commands are being performed on the Jenkins Linux node * Fixed Dangling string_view reference in the ConsoleCommandKeyNotificationHandler that was causing command execution from a file to fail. Renamed the second TestFreeFunc function in the ConsoleTests.cpp to validate thath the first TestFreeFunc function is being tested * Updated the Component Application AZ Console to use the SettingsRegistry as the backend when loading config and Settings Rgistry json files --- .../AzCore/Component/ComponentApplication.cpp | 2 +- .../AzCore/AzCore/Console/Console.cpp | 214 +++++++++++--- .../Framework/AzCore/AzCore/Console/Console.h | 6 + .../AzCore/Console/ConsoleTypeHelpers.inl | 10 +- .../AzCore/AzCore/Console/IConsole.h | 10 + .../AzCore/Serialization/Json/JsonMerger.cpp | 60 +++- .../AzCore/Serialization/Json/JsonMerger.h | 5 + .../AzCore/Settings/SettingsRegistry.cpp | 24 ++ .../AzCore/AzCore/Settings/SettingsRegistry.h | 32 ++- .../AzCore/Settings/SettingsRegistryImpl.cpp | 160 +++++------ .../AzCore/Settings/SettingsRegistryImpl.h | 10 +- .../Settings/SettingsRegistryMergeUtils.cpp | 49 +--- .../UnitTest/Mocks/MockSettingsRegistry.h | 3 + .../AzCore/Tests/Console/ConsoleTests.cpp | 265 +++++++++++++++++- .../SettingsRegistryConsoleUtilsTests.cpp | 12 +- .../AzCore/Tests/SettingsRegistryTests.cpp | 42 +-- .../AzFramework/Application/Application.cpp | 2 - 17 files changed, 659 insertions(+), 247 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp index c93f825a2c..8a170f5d89 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp @@ -477,7 +477,7 @@ namespace AZ m_console = AZ::Interface::Get(); if (m_console == nullptr) { - m_console = aznew AZ::Console(); + m_console = aznew AZ::Console(*m_settingsRegistry); AZ::Interface::Register(m_console); m_ownsConsole = true; m_console->LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead()); diff --git a/Code/Framework/AzCore/AzCore/Console/Console.cpp b/Code/Framework/AzCore/AzCore/Console/Console.cpp index 788a127830..3cb33b564a 100644 --- a/Code/Framework/AzCore/AzCore/Console/Console.cpp +++ b/Code/Framework/AzCore/AzCore/Console/Console.cpp @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -43,6 +45,12 @@ namespace AZ { } + Console::Console(AZ::SettingsRegistryInterface& settingsRegistryInterface) + : Console() + { + RegisterCommandInvokerWithSettingsRegistry(settingsRegistryInterface); + } + Console::~Console() { // on console destruction relink the console functors back to the deferred head @@ -111,51 +119,51 @@ namespace AZ void Console::ExecuteConfigFile(AZStd::string_view configFileName) { - IO::FixedMaxPath filePathFixed = configFileName; - if (AZ::IO::FileIOBase* fileIOBase = AZ::IO::FileIOBase::GetInstance()) + auto settingsRegistry = AZ::SettingsRegistry::Get(); + // If the config file is a settings registry file use the SettingsRegistryInterface MergeSettingsFile function + // otherwise use the SettingsRegistryMergeUtils MergeSettingsToRegistry_ConfigFile function to merge an INI-style + // file to the settings registry + AZ::IO::PathView configFile(configFileName); + if (configFile.Extension() == ".setreg") { - fileIOBase->ResolvePath(filePathFixed, configFileName); + settingsRegistry->MergeSettingsFile(configFile.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch); } - - IO::SystemFile file; - if (!file.Open(filePathFixed.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_ONLY)) + else if (configFile.Extension() == ".setregpatch") { - AZLOG_ERROR("Failed to load '%s'. File could not be opened.", filePathFixed.c_str()); - return; + settingsRegistry->MergeSettingsFile(configFile.Native(), AZ::SettingsRegistryInterface::Format::JsonPatch); } - const IO::SizeType length = file.Length(); - if (length == 0) + else { - AZLOG_ERROR("Failed to load '%s'. File is empty.", filePathFixed.c_str()); - return; - } - file.Seek(0, IO::SystemFile::SF_SEEK_BEGIN); - AZStd::string fileBuffer; - fileBuffer.resize(length); - IO::SizeType bytesRead = file.Read(length, fileBuffer.data()); - file.Close(); - // Resize again just in case bytesRead is less than length for some reason - fileBuffer.resize(bytesRead); - - AZLOG_INFO("Loading config file %s", filePathFixed.c_str()); - - AZStd::vector separatedCommands; - auto BreakCommandsByLine = [&separatedCommands](AZStd::string_view token) - { - separatedCommands.emplace_back(token); - }; - StringFunc::TokenizeVisitor(fileBuffer, BreakCommandsByLine, "\n\r"); - - for (const auto& commandView : separatedCommands) - { - ConsoleCommandContainer commandArgsView; - auto ConvertCommandStringToArray = [&commandArgsView](AZStd::string_view token) + AZ::SettingsRegistryMergeUtils::ConfigParserSettings configParserSettings; + configParserSettings.m_registryRootPointerPath = "/Amazon/AzCore/Runtime/ConsoleCommands"; + configParserSettings.m_commandLineSettings.m_delimiterFunc = [](AZStd::string_view line) { - commandArgsView.emplace_back(token); + SettingsRegistryInterface::CommandLineArgumentSettings::JsonPathValue pathValue; + AZStd::string_view parsedLine = line; + + // Splits the line based on the or + if (auto path = AZ::StringFunc::TokenizeNext(parsedLine, "=:"); path.has_value()) + { + pathValue.m_path = AZ::StringFunc::StripEnds(*path); + pathValue.m_value = AZ::StringFunc::StripEnds(parsedLine); + } + // If the value is empty, then the line either contained an equal sign followed only by whitespace or the line was empty + // 1. line="testInit=", pathValue.m_path="testInit", pathValue.m_value="" + // 2. line="testInit 1", pathValue.m_path="testInit 1", pathValue.m_value="" + // Therefore the path is split the path on whitespace in order to retrieve a value + if (pathValue.m_value.empty()) + { + parsedLine = pathValue.m_path; + if (auto path = AZ::StringFunc::TokenizeNext(parsedLine, " \t"); path.has_value()) + { + pathValue.m_path = AZ::StringFunc::StripEnds(*path); + pathValue.m_value = AZ::StringFunc::StripEnds(parsedLine); + } + + } + return pathValue; }; - constexpr AZStd::string_view commandSeparators = " ="; - StringFunc::TokenizeVisitor(commandView, ConvertCommandStringToArray, commandSeparators); - PerformCommand(commandArgsView, ConsoleSilentMode::NotSilent, ConsoleInvokedFrom::AzConsole, ConsoleFunctorFlags::Null, ConsoleFunctorFlags::Null); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ConfigFile(*settingsRegistry, configFile.Native(), configParserSettings); } } @@ -447,4 +455,134 @@ namespace AZ return result; } + + struct ConsoleCommandKeyNotificationHandler + { + ConsoleCommandKeyNotificationHandler(AZ::SettingsRegistryInterface& registry, Console& console) + : m_settingsRegistry(registry) + , m_console(console) + { + } + + // Responsible for using the Json Serialization Issue Callback system + // to determine when a JSON Patch or JSON Merge Patch modifies a value + // at a path underneath the IConsole::ConsoleRootCommandKey JSON pointer + JsonSerializationResult::ResultCode operator()(AZStd::string_view message, + JsonSerializationResult::ResultCode result, AZStd::string_view path) + { + AZ::IO::PathView consoleRootCommandKey{ IConsole::ConsoleRootCommandKey, AZ::IO::PosixPathSeparator }; + AZ::IO::PathView inputKey{ path, AZ::IO::PosixPathSeparator }; + if (result.GetTask() == JsonSerializationResult::Tasks::Merge + && result.GetProcessing() == JsonSerializationResult::Processing::Completed + && inputKey.IsRelativeTo(consoleRootCommandKey)) + { + if (auto type = m_settingsRegistry.GetType(path); type != SettingsRegistryInterface::Type::NoType) + { + operator()(path, type); + } + } + + // This is the default issue reporting, that logs using the warning category + if (result.GetProcessing() != JsonSerializationResult::Processing::Completed) + { + scratchBuffer.append(message.begin(), message.end()); + scratchBuffer.append("\n Reason: "); + result.AppendToString(scratchBuffer, path); + scratchBuffer.append("."); + AZ_Warning("JSON Serialization", false, "%s", scratchBuffer.c_str()); + + scratchBuffer.clear(); + } + return result; + } + + void operator()(AZStd::string_view path, SettingsRegistryInterface::Type type) + { + using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString; + + AZ::IO::PathView consoleRootCommandKey{ IConsole::ConsoleRootCommandKey, AZ::IO::PosixPathSeparator }; + AZ::IO::PathView inputKey{ path, AZ::IO::PosixPathSeparator }; + if (inputKey.IsRelativeTo(consoleRootCommandKey)) + { + FixedValueString command = inputKey.LexicallyRelative(consoleRootCommandKey).Native(); + ConsoleCommandContainer commandArgs; + // Argument string which stores the value from the Settings Registry long enough + // to pass into the PerformCommand. The ConsoleCommandContainer stores string_views + // and therefore doesn't own the memory. + FixedValueString commandArgString; + + if (type == SettingsRegistryInterface::Type::String) + { + if (m_settingsRegistry.Get(commandArgString, path)) + { + auto ConvertCommandArgumentToArray = [&commandArgs](AZStd::string_view token) + { + commandArgs.emplace_back(token); + }; + constexpr AZStd::string_view commandSeparators = " \t\n\r"; + StringFunc::TokenizeVisitor(commandArgString, ConvertCommandArgumentToArray, commandSeparators); + } + } + else if (type == SettingsRegistryInterface::Type::Boolean) + { + bool commandArgBool{}; + if (m_settingsRegistry.Get(commandArgBool, path)) + { + commandArgString = commandArgBool ? "true" : "false"; + commandArgs.emplace_back(commandArgString); + } + } + else if (type == SettingsRegistryInterface::Type::Integer) + { + // Try converting to a signed 64-bit number first and then an unsigned 64-bit number + AZ::s64 commandArgInt{}; + AZ::u64 commandArgUInt{}; + if (m_settingsRegistry.Get(commandArgInt, path)) + { + AZStd::to_string(commandArgString, commandArgInt); + commandArgs.emplace_back(commandArgString); + } + else if (m_settingsRegistry.Get(commandArgUInt, path)) + { + AZStd::to_string(commandArgString, commandArgUInt); + commandArgs.emplace_back(commandArgString); + } + } + else if (type == SettingsRegistryInterface::Type::FloatingPoint) + { + double commandArgFloat{}; + if (m_settingsRegistry.Get(commandArgFloat, path)) + { + AZStd::to_string(commandArgString, commandArgFloat); + commandArgs.emplace_back(commandArgString); + } + } + CVarFixedString commandTrace(command); + for (AZStd::string_view commandArg : commandArgs) + { + commandTrace.push_back(' '); + commandTrace += commandArg; + } + + m_console.PerformCommand(command, commandArgs, ConsoleSilentMode::NotSilent, ConsoleInvokedFrom::AzConsole, ConsoleFunctorFlags::Null, ConsoleFunctorFlags::Null); + } + } + + AZ::Console& m_console; + AZ::SettingsRegistryInterface& m_settingsRegistry; + AZStd::string scratchBuffer; + }; + + void Console::RegisterCommandInvokerWithSettingsRegistry(AZ::SettingsRegistryInterface& settingsRegistry) + { + // Make sure the there is a JSON object at the path of AZ::IConsole::ConsoleRootCommandKey + // So that JSON Patch is able to add values underneath that object (JSON Patch doesn't create intermediate objects) + settingsRegistry.MergeSettings(R"({ "Amazon": { "AzCore": { "Runtime": { "ConsoleCommands": {} } }}})", + SettingsRegistryInterface::Format::JsonMergePatch); + m_consoleCommandKeyHandler = settingsRegistry.RegisterNotifier(ConsoleCommandKeyNotificationHandler{ settingsRegistry, *this }); + + JsonApplyPatchSettings applyPatchSettings; + applyPatchSettings.m_reporting = ConsoleCommandKeyNotificationHandler{ settingsRegistry, *this }; + settingsRegistry.SetApplyPatchSettings(applyPatchSettings); + } } diff --git a/Code/Framework/AzCore/AzCore/Console/Console.h b/Code/Framework/AzCore/AzCore/Console/Console.h index 1c9c6897f6..ba614824fe 100644 --- a/Code/Framework/AzCore/AzCore/Console/Console.h +++ b/Code/Framework/AzCore/AzCore/Console/Console.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -29,6 +30,9 @@ namespace AZ AZ_CLASS_ALLOCATOR(Console, AZ::OSAllocator, 0); Console(); + //! Constructor overload which registers a notifier with the Settings Registry that will execute + //! a console command whenever a key is set under the AZ::IConsole::ConsoleCommandRootKey JSON object + explicit Console(AZ::SettingsRegistryInterface& settingsRegistry); ~Console() override; //! IConsole interface @@ -67,6 +71,7 @@ namespace AZ void RegisterFunctor(ConsoleFunctorBase* functor) override; void UnregisterFunctor(ConsoleFunctorBase* functor) override; void LinkDeferredFunctors(ConsoleFunctorBase*& deferredHead) override; + void RegisterCommandInvokerWithSettingsRegistry(AZ::SettingsRegistryInterface& settingsRegistry) override; //! @} private: @@ -96,6 +101,7 @@ namespace AZ ConsoleFunctorBase* m_head; using CommandMap = AZStd::unordered_map>; CommandMap m_commands; + AZ::SettingsRegistryInterface::NotifyEventHandler m_consoleCommandKeyHandler; friend class ConsoleFunctorBase; }; diff --git a/Code/Framework/AzCore/AzCore/Console/ConsoleTypeHelpers.inl b/Code/Framework/AzCore/AzCore/Console/ConsoleTypeHelpers.inl index 0257564d43..18ed27e517 100644 --- a/Code/Framework/AzCore/AzCore/Console/ConsoleTypeHelpers.inl +++ b/Code/Framework/AzCore/AzCore/Console/ConsoleTypeHelpers.inl @@ -148,7 +148,15 @@ namespace AZ { AZ::CVarFixedString convertCandidate{ arguments.front() }; char* endPtr = nullptr; - MAX_TYPE value = static_cast(strtoll(convertCandidate.c_str(), &endPtr, 0)); + MAX_TYPE value; + if constexpr (AZStd::is_unsigned_v) + { + value = aznumeric_cast(strtoull(convertCandidate.c_str(), &endPtr, 0)); + } + else + { + value = aznumeric_cast(strtoll(convertCandidate.c_str(), &endPtr, 0)); + } if (endPtr == convertCandidate.c_str()) { diff --git a/Code/Framework/AzCore/AzCore/Console/IConsole.h b/Code/Framework/AzCore/AzCore/Console/IConsole.h index 9f5ede7f4c..b976f3a9db 100644 --- a/Code/Framework/AzCore/AzCore/Console/IConsole.h +++ b/Code/Framework/AzCore/AzCore/Console/IConsole.h @@ -22,8 +22,10 @@ namespace AZ { + class SettingsRegistryInterface; class CommandLine; + //! @class IConsole //! A simple console class for providing text based variable and process interaction. class IConsole @@ -33,6 +35,8 @@ namespace AZ using FunctorVisitor = AZStd::function; + inline static constexpr AZStd::string_view ConsoleRootCommandKey = "/Amazon/AzCore/Runtime/ConsoleCommands"; + IConsole() = default; virtual ~IConsole() = default; @@ -145,6 +149,12 @@ namespace AZ //! Returns the AZ::Event<> invoked whenever a console command could not be found. DispatchCommandNotFoundEvent& GetDispatchCommandNotFoundEvent(); + //! Register a notification event handler with the Settings Registry + //! That is responsible for updating console commands whenever + //! a key is found underneath the "/Amazon/AzCore/Runtime/ConsoleCommands" JSON entry + //! @param Settings Registry reference to register notifier with + virtual void RegisterCommandInvokerWithSettingsRegistry(AZ::SettingsRegistryInterface& settingsRegistry) = 0; + AZ_DISABLE_COPY_MOVE(IConsole); protected: diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp index e359888da7..de9aa70362 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp @@ -11,13 +11,17 @@ */ #include +#include #include #include #include +#include #include namespace AZ { + using ReporterString = AZStd::fixed_string<1024>; + JsonSerializationResult::ResultCode JsonMerger::ApplyPatch(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonApplyPatchSettings& settings) @@ -105,8 +109,7 @@ namespace AZ } else { - AZ::OSString message = AZ::OSString::format(R"(Unknown operation "%.*s".)", - aznumeric_cast(operationName.length()), operationName.data()); + auto message = ReporterString::format(R"(Unknown operation "%.*s".)", AZ_STRING_ARG(operationName)); return settings.m_reporting(message.c_str(), ResultCode(Tasks::Merge, Outcomes::Unknown), element); } @@ -131,6 +134,14 @@ namespace AZ JsonSerializationResult::ResultCode JsonMerger::ApplyMergePatch(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonApplyPatchSettings& settings) + { + StackedString element(StackedString::Format::JsonPointer); + return ApplyMergePatchInternal(target, allocator, patch, settings, element); + } + + JsonSerializationResult::ResultCode JsonMerger::ApplyMergePatchInternal(rapidjson::Value& target, + rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, + JsonApplyPatchSettings& settings, StackedString& element) { using namespace JsonSerializationResult; @@ -150,14 +161,18 @@ namespace AZ { if (targetField != target.MemberEnd()) { - result.Combine(ApplyMergePatch(targetField->value, allocator, field.value, settings)); + ScopedStackedString fieldNameScope{ element, + AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + result.Combine(ApplyMergePatchInternal(targetField->value, allocator, field.value, settings, element)); } else { rapidjson::Value name; name.CopyFrom(field.name, allocator, true); rapidjson::Value value; - result.Combine(ApplyMergePatch(value, allocator, field.value, settings)); + ScopedStackedString fieldNameScope{ element, + AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + result.Combine(ApplyMergePatchInternal(value, allocator, field.value, settings, element)); target.AddMember(AZStd::move(name), AZStd::move(value), allocator); } } @@ -165,7 +180,14 @@ namespace AZ { if (targetField != target.MemberEnd()) { + ScopedStackedString fieldNameScope{ element, + AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + AZStd::string_view jsonPath = element.Get(); + target.RemoveMember(targetField); + result.Combine(settings.m_reporting(ReporterString::format( + R"(Successfully removed member from "%.*s" using JSON Merge Patch)", AZ_STRING_ARG(jsonPath)), + ResultCode(Tasks::Merge, Outcomes::Success), element)); } } else @@ -173,6 +195,12 @@ namespace AZ if (targetField != target.MemberEnd()) { targetField->value.CopyFrom(field.value, allocator, true); + + ScopedStackedString fieldNameScope{ element, AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + AZStd::string_view jsonPath = element.Get(); + result.Combine(settings.m_reporting(ReporterString::format( + R"(Successfully updated JSON field "%.*s" using JSON Merge Patch)", AZ_STRING_ARG(jsonPath)), + ResultCode(Tasks::Merge, Outcomes::Success), element)); } else { @@ -181,6 +209,12 @@ namespace AZ name.CopyFrom(field.name, allocator, true); value.CopyFrom(field.value, allocator, true); target.AddMember(AZStd::move(name), AZStd::move(value), allocator); + + ScopedStackedString fieldNameScope{ element, AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + AZStd::string_view jsonPath = element.Get(); + result.Combine(settings.m_reporting(ReporterString::format( + R"(Successfully added JSON field "%.*s" using JSON Merge Patch)", AZ_STRING_ARG(jsonPath)), + ResultCode(Tasks::Merge, Outcomes::Success), element)); } } } @@ -190,7 +224,7 @@ namespace AZ target.CopyFrom(patch, allocator, true); } result.Combine(settings.m_reporting("Successfully applied patch to target using JSON Merge Patch.", - ResultCode(Tasks::Merge, Outcomes::Success), StackedString(StackedString::Format::JsonPointer))); + ResultCode(Tasks::Merge, Outcomes::Success), element)); return result; } @@ -268,9 +302,11 @@ namespace AZ const rapidjson::Pointer::Token* const tokens = path.GetTokens(); if (path.GetTokenCount() == 0) { + rapidjson::StringBuffer pointerPathString; + path.Stringify(pointerPathString); target = AZStd::move(newValue); return settings.m_reporting(R"(Successfully applied "add" operation.)", - ResultCode(Tasks::Merge, Outcomes::Success), element); + ResultCode(Tasks::Merge, Outcomes::Success), pointerPathString.GetString()); } rapidjson::Pointer parent = rapidjson::Pointer(tokens, path.GetTokenCount() - 1); @@ -342,8 +378,10 @@ namespace AZ ResultCode(Tasks::Merge, Outcomes::TypeMismatch), element); } + rapidjson::StringBuffer pointerPathString; + path.Stringify(pointerPathString); return settings.m_reporting(R"(Successfully applied "add" operation.)", - ResultCode(Tasks::Merge, Outcomes::Success), element); + ResultCode(Tasks::Merge, Outcomes::Success), pointerPathString.GetString()); } JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Remove(rapidjson::Value& target, const rapidjson::Pointer& path, @@ -393,8 +431,10 @@ namespace AZ ResultCode(Tasks::Merge, Outcomes::TypeMismatch), element); } + rapidjson::StringBuffer pointerPathString; + path.Stringify(pointerPathString); return settings.m_reporting(R"(Successfully applied "remove" operation.)", - ResultCode(Tasks::Merge, Outcomes::Success), element); + ResultCode(Tasks::Merge, Outcomes::Success), pointerPathString.GetString()); } JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Replace(rapidjson::Value& target, @@ -420,8 +460,10 @@ namespace AZ memberValue->CopyFrom(value->value, allocator); + rapidjson::StringBuffer pointerPathString; + path.Stringify(pointerPathString); return settings.m_reporting(R"(Successfully applied "replace" operation.)", - ResultCode(Tasks::Merge, Outcomes::Success), element); + ResultCode(Tasks::Merge, Outcomes::Success), pointerPathString.GetString()); } JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Move(rapidjson::Value& target, diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.h index a33bac117b..127897c6ff 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.h @@ -42,6 +42,11 @@ namespace AZ rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonApplyPatchSettings& settings); + //! Implementation of the JSON Merge Patch algorithm: https://tools.ietf.org/html/rfc7386 + static JsonSerializationResult::ResultCode ApplyMergePatchInternal(rapidjson::Value& target, + rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, + JsonApplyPatchSettings& settings, StackedString& element); + //! Function to create JSON Merge Patches: https://tools.ietf.org/html/rfc7386 static JsonSerializationResult::ResultCode CreateMergePatch(rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source, diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp index 609eb03a2c..f6b804494e 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp @@ -88,4 +88,28 @@ namespace AZ { return index < m_names.size() ? m_names[index] : AZStd::string_view(); } + + SettingsRegistryInterface::CommandLineArgumentSettings::CommandLineArgumentSettings() + { + m_delimiterFunc = [](AZStd::string_view line) -> JsonPathValue + { + constexpr AZStd::string_view CommandLineArgumentDelimiters{ "=:" }; + JsonPathValue pathValue; + pathValue.m_value = line; + + // Splits the line on the first delimiter and stores that in the pathValue.m_path variable + // The StringFunc::TokenizeNext function updates the pathValue.m_value parameter in place + // to contain all the text after the first delimiter + // So if pathValue.m_value="foo = Hello Ice Cream=World:17", the call to TokenizeNext would + // split the value as follows + // pathValue.m_path = "foo" + // pathValue.m_value = "Hello Ice Cream=World:17" + if (auto path = AZ::StringFunc::TokenizeNext(pathValue.m_value, CommandLineArgumentDelimiters); path.has_value()) + { + pathValue.m_path = AZ::StringFunc::StripEnds(*path); + } + pathValue.m_value = AZ::StringFunc::StripEnds(pathValue.m_value); + return pathValue; + }; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h index 768841cc09..2d9b0d83e5 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h @@ -26,6 +26,7 @@ namespace AZ { + struct JsonApplyPatchSettings; //! The Settings Registry is the central storage for global settings. Having application-wide settings //! stored in a central location allows different tools such as command lines, consoles, configuration //! files, etc. to work in a universal way. @@ -260,21 +261,20 @@ namespace AZ virtual bool Remove(AZStd::string_view path) = 0; //! Structure which contains configuration settings for how to parse a single command line argument - //! It supports supplying a functor for determining if a character is a delimiter + //! It supports supplying a functor for splitting a line into JSON path and JSON value struct CommandLineArgumentSettings { - inline static constexpr AZStd::string_view CommandLineArgumentDelimiters{ "=:"}; - CommandLineArgumentSettings() + struct JsonPathValue { - m_delimiterFunc = [](const char delimiter) -> bool - { - return CommandLineArgumentDelimiters.find_first_of(delimiter) != AZStd::string_view::npos; - }; - } - - //! Callback function which is invoked to determine whether a delimiter has been found - //! return value of true indicates that a delimiter has been found - using DelimiterFunc = AZStd::function; + AZStd::string_view m_path; + AZStd::string_view m_value; + }; + + CommandLineArgumentSettings(); + + //! Callback function which is invoked to determine how to split a command line argument + //! into a JSON path and a JSON value + using DelimiterFunc = AZStd::function; DelimiterFunc m_delimiterFunc; }; //! Merges a single command line argument into the settings registry. Command line arguments @@ -322,6 +322,14 @@ namespace AZ //! @return True if the registry folder was successfully merged, otherwise false. virtual bool MergeSettingsFolder(AZStd::string_view path, const Specializations& specializations, AZStd::string_view platform = {}, AZStd::string_view rootKey = "", AZStd::vector* scratchBuffer = nullptr) = 0; + + //! Stores the settings structure which is used when merging settings to the Settings Registry + //! using JSON Merge Patch or JSON Merge Patch. + //! The settings contain an issue reporting callback which can be used to track patching process. + //! Potential application of the reporting callback could be to update a UI whenever a key receives an updated value + //! @param applyPatchSettings The ApplyPatchSettings which are using during JSON Merging + virtual void SetApplyPatchSettings(const AZ::JsonApplyPatchSettings& applyPatchSettings) = 0; + virtual void GetApplyPatchSettings(AZ::JsonApplyPatchSettings& applyPatchSettings) = 0; }; inline SettingsRegistryInterface::Visitor::~Visitor() = default; diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp index 9ea76817af..2421c75be3 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -419,9 +420,6 @@ namespace AZ bool SettingsRegistryImpl::MergeCommandLineArgument(AZStd::string_view argument, AZStd::string_view rootKey, const CommandLineArgumentSettings& commandLineSettings) { - const char* front = argument.begin(); - const char* back = argument.end(); - if (!commandLineSettings.m_delimiterFunc) { AZ_Error("SettingsRegistry", false, @@ -429,87 +427,40 @@ namespace AZ aznumeric_cast(argument.size()), argument.data()); return false; } - const char* split = AZStd::find_if(front, back, commandLineSettings.m_delimiterFunc); - if (split == front || // There is no key - split == (back-1) || // There is no value - split == back) // Split character not found. + + auto [key, value] = commandLineSettings.m_delimiterFunc(argument); + if (key.empty()) { + // They key where to set the JSON value cannot be empty + // The value of the JSON can be though + // This is so that a key can be set to empty string using "/KeyPath=" return false; } - const char* keyStart = front; - while (std::isspace(*keyStart)) // This is safe because it will eventually stop on = + // Prepend the rootKey as an anchor to the argument key + SettingsRegistryInterface::FixedValueString keyPath{ rootKey.ends_with('/') + ? rootKey.substr(0, rootKey.size() - 1) + : rootKey }; + // Append the JSON reference token prefix of '/' to the keyPath + if (!key.starts_with('/')) { - keyStart++; + keyPath.push_back('/'); } - if (keyStart == split) // Key is just white spaces + if ((key.size() + keyPath.size()) > keyPath.max_size()) { + // The key portion is longer than the FixedValueString max size that can be stored + // This limitation is arbitrary, if an AZStd::string is used or if the C++17 std::to_chars + // function is used, there wouldn't need to be a limitation return false; } - const char* keyEnd = split; - while (std::isspace(*--keyEnd)); - keyEnd++; + keyPath += key; + key = keyPath; - char buffer[MaxJsonPathLength]; - AZStd::string_view key; - bool keyHasDivider = *keyStart == '/'; - if (!rootKey.empty()) + if (value.empty()) { - bool rootKeyHasDivider = (rootKey[rootKey.length() - 1]) == '/'; - size_t count; - if (!rootKeyHasDivider && !keyHasDivider) - { - count = azsnprintf(buffer, AZ_ARRAY_SIZE(buffer), "%.*s/%.*s", - aznumeric_cast(rootKey.length()), rootKey.data(), - aznumeric_cast(keyEnd - keyStart), keyStart); - } - else if (rootKeyHasDivider && keyHasDivider) - { - count = azsnprintf(buffer, AZ_ARRAY_SIZE(buffer), "%.*s%.*s", - aznumeric_cast(rootKey.length()) - 1, rootKey.data(), - aznumeric_cast(keyEnd - keyStart), keyStart); - } - else - { - count = azsnprintf(buffer, AZ_ARRAY_SIZE(buffer), "%.*s%.*s", - aznumeric_cast(rootKey.length()), rootKey.data(), - aznumeric_cast(keyEnd - keyStart), keyStart); - } - if (count >= AZ_ARRAY_SIZE(buffer) - 1) - { - return false; - } - key = AZStd::string_view(buffer, count); - } - else if (!keyHasDivider) - { - size_t count = azsnprintf(buffer, AZ_ARRAY_SIZE(buffer), "/%.*s", - aznumeric_cast(keyEnd - keyStart), keyStart); - if (count >= AZ_ARRAY_SIZE(buffer) - 1) - { - return false; - } - key = AZStd::string_view(buffer, count); - } - else - { - key = AZStd::string_view(keyStart, keyEnd); + return Set(key, value); } - const char* valueStart = split + 1; - while (std::isspace(*valueStart) && valueStart < back) - { - valueStart++; - } - if (valueStart == back) - { - return false; // The value is empty - } - const char* valueEnd = back; - while (std::isspace(*(--valueEnd))); - valueEnd++; - - AZStd::string_view value(valueStart, valueEnd); if (value == "true") { return Set(key, true); @@ -519,23 +470,35 @@ namespace AZ return Set(key, false); } - if (value.length() - 1 >= MaxCommandLineArgumentLength) + SettingsRegistryInterface::FixedValueString valueString; + if (value.size() > valueString.max_size()) { + // The value portion is longer than the FixedValueString max size that can be stored + // This limitation is arbitrary, if an AZStd::string is used or if the C++17 std::to_chars + // function is used, there wouldn't need to be a limitation return false; } - char argumentString[MaxCommandLineArgumentLength]; - snprintf(argumentString, AZ_ARRAY_SIZE(argument), "%.*s", aznumeric_cast(value.length()), value.data()); - char* argumentStringEnd = argumentString + value.length(); + valueString = value; + const char* valueStringEnd = valueString.c_str() + valueString.size(); + errno = 0; char* convertEnd = nullptr; - s64 intValue = strtoll(argumentString, &convertEnd, 0); - if (convertEnd == argumentStringEnd) + s64 intValue = strtoll(valueString.c_str(), &convertEnd, 0); + if (errno != ERANGE && convertEnd == valueStringEnd) { return Set(key, intValue); } + errno = 0; convertEnd = nullptr; - double floatingPointValue = strtod(argumentString, &convertEnd); - if (convertEnd == argumentStringEnd) + u64 uintValue = strtoull(valueString.c_str(), &convertEnd, 0); + if (errno != ERANGE && convertEnd == valueStringEnd) + { + return Set(key, uintValue); + } + errno = 0; + convertEnd = nullptr; + double floatingPointValue = strtod(valueString.c_str(), &convertEnd); + if (errno != ERANGE && convertEnd == valueStringEnd) { return Set(key, floatingPointValue); } @@ -611,7 +574,7 @@ namespace AZ } else { - if (MaxFilePathLength < path.length() + 1) + if (AZ::IO::MaxPathLength < path.length() + 1) { AZ_Error("Settings Registry", false, R"(Path "%.*s" is too long. Either make sure that the provided path is terminated or use a shorter path.)", @@ -623,10 +586,8 @@ namespace AZ .AddMember(StringRef("Path"), AZStd::move(pathValue), m_settings.GetAllocator()); return false; } - char filePath[MaxFilePathLength]; - azstrncpy(filePath, AZ_ARRAY_SIZE(filePath), path.data(), path.length()); - filePath[path.length()] = 0; - result = MergeSettingsFileInternal(filePath, format, rootKey, *scratchBuffer); + AZ::IO::FixedMaxPathString filePath(path); + result = MergeSettingsFileInternal(filePath.c_str(), format, rootKey, *scratchBuffer); } scratchBuffer->clear(); @@ -660,7 +621,7 @@ namespace AZ additionalSpaceRequired += AZ_ARRAY_SIZE(PlatformFolder) + platform.length() + 2; // +2 for the two slashes. } - if (path.length() + additionalSpaceRequired > MaxFilePathLength) + if (path.length() + additionalSpaceRequired > AZ::IO::MaxPathLength) { AZ_Error("Settings Registry", false, "Folder path for the Setting Registry is too long: %.*s", static_cast(path.size()), path.data()); @@ -673,7 +634,7 @@ namespace AZ RegistryFileList fileList; scratchBuffer->clear(); - AZStd::fixed_string folderPath{ path }; + AZ::IO::FixedMaxPathString folderPath{ path }; constexpr AZStd::string_view pathSeparators{ AZ_CORRECT_AND_WRONG_DATABASE_SEPARATOR }; if (pathSeparators.find_first_of(folderPath.back()) == AZStd::string_view::npos) { @@ -926,7 +887,7 @@ namespace AZ // Sort by the name first so the registry file gets applied with all its specializations. if (lhs.m_tags[0] != rhs.m_tags[0]) { - return strcmp(lhs.m_relativePath, rhs.m_relativePath) < 0; + return lhs.m_relativePath < rhs.m_relativePath; } // Then sort by size first so the files with the fewest specializations get applied first. @@ -956,14 +917,14 @@ namespace AZ } collisionFound = true; - AZ_Error("Settings Registry", false, R"(Two registry files point to the same specialization: "%s" and "%s")", - lhs.m_relativePath, rhs.m_relativePath); + AZ_Error("Settings Registry", false, R"(Two registry files in "%.*s" point to the same specialization: "%s" and "%s")", + AZ_STRING_ARG(folderPath), lhs.m_relativePath.c_str(), rhs.m_relativePath.c_str()); historyPointer.Create(m_settings, m_settings.GetAllocator()).SetObject() .AddMember(StringRef("Error"), StringRef("Too many files in registry folder."), m_settings.GetAllocator()) .AddMember(StringRef("Path"), Value(folderPath.data(), aznumeric_caster(folderPath.length()), m_settings.GetAllocator()), m_settings.GetAllocator()) - .AddMember(StringRef("File1"), Value(lhs.m_relativePath, m_settings.GetAllocator()), m_settings.GetAllocator()) - .AddMember(StringRef("File2"), Value(rhs.m_relativePath, m_settings.GetAllocator()), m_settings.GetAllocator()); + .AddMember(StringRef("File1"), Value(lhs.m_relativePath.c_str(), m_settings.GetAllocator()), m_settings.GetAllocator()) + .AddMember(StringRef("File2"), Value(rhs.m_relativePath.c_str(), m_settings.GetAllocator()), m_settings.GetAllocator()); return false; } @@ -1036,9 +997,9 @@ namespace AZ // thats the name tag. AZStd::sort(AZStd::next(output.m_tags.begin()), output.m_tags.end()); - if (filePathSize < AZ_ARRAY_SIZE(output.m_relativePath)) + if (filePathSize < output.m_relativePath.max_size()) { - azstrcpy(output.m_relativePath, AZ_ARRAY_SIZE(output.m_relativePath), filename); + output.m_relativePath = filename; return true; } else @@ -1145,7 +1106,7 @@ namespace AZ JsonSerializationResult::ResultCode mergeResult(JsonSerializationResult::Tasks::Merge); if (rootKey.empty()) { - mergeResult = JsonSerialization::ApplyPatch(m_settings, m_settings.GetAllocator(), jsonPatch, mergeApproach); + mergeResult = JsonSerialization::ApplyPatch(m_settings, m_settings.GetAllocator(), jsonPatch, mergeApproach, m_applyPatchSettings); } else { @@ -1153,7 +1114,7 @@ namespace AZ if (root.IsValid()) { Value& rootValue = root.Create(m_settings, m_settings.GetAllocator()); - mergeResult = JsonSerialization::ApplyPatch(rootValue, m_settings.GetAllocator(), jsonPatch, mergeApproach); + mergeResult = JsonSerialization::ApplyPatch(rootValue, m_settings.GetAllocator(), jsonPatch, mergeApproach, m_applyPatchSettings); } else { @@ -1180,4 +1141,13 @@ namespace AZ return true; } + + void SettingsRegistryImpl::SetApplyPatchSettings(const AZ::JsonApplyPatchSettings& applyPatchSettings) + { + m_applyPatchSettings = applyPatchSettings; + } + void SettingsRegistryImpl::GetApplyPatchSettings(AZ::JsonApplyPatchSettings& applyPatchSettings) + { + applyPatchSettings = m_applyPatchSettings; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.h index 0cd5da131a..a80c12534b 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -35,9 +36,6 @@ namespace AZ AZ_CLASS_ALLOCATOR(SettingsRegistryImpl, AZ::OSAllocator, 0); AZ_RTTI(AZ::SettingsRegistryImpl, "{E9C34190-F888-48CA-83C9-9F24B4E21D72}", AZ::SettingsRegistryInterface); - static constexpr size_t MaxFilePathLength = AZ_MAX_PATH_LEN; - static constexpr size_t MaxJsonPathLength = 1024; - static constexpr size_t MaxCommandLineArgumentLength = 1024; static constexpr size_t MaxRegistryFolderEntries = 128; SettingsRegistryImpl(); @@ -80,11 +78,14 @@ namespace AZ bool MergeSettingsFolder(AZStd::string_view path, const Specializations& specializations, AZStd::string_view platform, AZStd::string_view rootKey = "", AZStd::vector* scratchBuffer = nullptr) override; + void SetApplyPatchSettings(const AZ::JsonApplyPatchSettings& applyPatchSettings) override; + void GetApplyPatchSettings(AZ::JsonApplyPatchSettings& applyPatchSettings) override; + private: using TagList = AZStd::fixed_vector; struct RegistryFile { - char m_relativePath[MaxFilePathLength]{ 0 }; + AZ::IO::FixedMaxPathString m_relativePath; TagList m_tags; bool m_isPatch{ false }; bool m_isPlatformFile{ false }; @@ -109,5 +110,6 @@ namespace AZ rapidjson::Document m_settings; JsonSerializerSettings m_serializationSettings; JsonDeserializerSettings m_deserializationSettings; + JsonApplyPatchSettings m_applyPatchSettings; }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp index bd73162498..82bf1db484 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp @@ -340,46 +340,6 @@ namespace AZ::SettingsRegistryMergeUtils return sectionName; } - // Encodes a key, value delimited line such that the entire "key" can be stored as a single - // JSON Pointer key by escaping the tilde(~) and forward slash(/) - template - static AZStd::fixed_string EncodeLineForJsonPointer(AZStd::string_view token, - const AZ::SettingsRegistryInterface::CommandLineArgumentSettings::DelimiterFunc& delimiterFunc) - { - if (!delimiterFunc) - { - // Since the delimiter function is not valid, return the token unchanged - return AZStd::fixed_string{ token }; - } - // Iterate over the line and escape the '~' and '/' values - AZStd::fixed_string encodedToken; - size_t chIndex = 0; - for (; chIndex < token.size(); ++chIndex) - { - const char ch = token[chIndex]; - if (delimiterFunc(ch)) - { - // If the delimiter is found, this indicates that the end of the key has been found - break; - } - switch (ch) - { - case '~': - encodedToken += "~0"; - break; - case '/': - encodedToken += "~1"; - break; - default: - encodedToken += ch; - } - } - - // Copy over the rest of the post delimited line to the encoded token - encodedToken.append(token.data() + chIndex, token.data() + token.size()); - return encodedToken; - } - void QuerySpecializationsFromRegistry(SettingsRegistryInterface& registry, SettingsRegistryInterface::Specializations& specializations) { // Append any specializations stored in the registry @@ -499,14 +459,7 @@ namespace AZ::SettingsRegistryMergeUtils } } - // Check if the "key" portion of the line has '~' or '/' as the SettingsRegistry uses JSON Pointer - // to set the "value" portion. Those characters need to be escaped with ~0 and ~1 respectively - // to allow them to be embedded in a single json key - // Iterate over the line and escape the '~' and '/' values - AZStd::fixed_string escapedLine = EncodeLineForJsonPointer(line, - configParserSettings.m_commandLineSettings.m_delimiterFunc); - - registry.MergeCommandLineArgument(escapedLine, currentJsonPointerPath, configParserSettings.m_commandLineSettings); + registry.MergeCommandLineArgument(line, currentJsonPointerPath, configParserSettings.m_commandLineSettings); // Skip past the newline character if found frontIter = lineEndIter + (foundNewLine ? 1 : 0); diff --git a/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockSettingsRegistry.h b/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockSettingsRegistry.h index f4abbd9867..447b38e553 100644 --- a/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockSettingsRegistry.h +++ b/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockSettingsRegistry.h @@ -54,6 +54,9 @@ namespace AZ MOCK_METHOD5( MergeSettingsFolder, bool(AZStd::string_view, const Specializations&, AZStd::string_view, AZStd::string_view, AZStd::vector*)); + + MOCK_METHOD1(SetApplyPatchSettings, void(const JsonApplyPatchSettings&)); + MOCK_METHOD1(GetApplyPatchSettings, void(JsonApplyPatchSettings&)); }; } // namespace AZ diff --git a/Code/Framework/AzCore/Tests/Console/ConsoleTests.cpp b/Code/Framework/AzCore/Tests/Console/ConsoleTests.cpp index e56ae53646..5f3debca90 100644 --- a/Code/Framework/AzCore/Tests/Console/ConsoleTests.cpp +++ b/Code/Framework/AzCore/Tests/Console/ConsoleTests.cpp @@ -13,24 +13,25 @@ #include #include #include - +#include +#include namespace AZ { using namespace UnitTest; - AZ_CVAR(bool, testBool, false, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(char, testChar, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(int8_t, testInt8, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(int16_t, testInt16, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(int32_t, testInt32, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(int64_t, testInt64, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(uint8_t, testUInt8, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(bool, testBool, false, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(char, testChar, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(int8_t, testInt8, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(int16_t, testInt16, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(int32_t, testInt32, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(int64_t, testInt64, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(uint8_t, testUInt8, 0, nullptr, ConsoleFunctorFlags::Null, ""); AZ_CVAR(uint16_t, testUInt16, 0, nullptr, ConsoleFunctorFlags::Null, ""); AZ_CVAR(uint32_t, testUInt32, 0, nullptr, ConsoleFunctorFlags::Null, ""); AZ_CVAR(uint64_t, testUInt64, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(float, testFloat, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(double, testDouble, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(float, testFloat, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(double, testDouble, 0, nullptr, ConsoleFunctorFlags::Null, ""); AZ_CVAR(AZ::CVarFixedString, testString, "default", nullptr, ConsoleFunctorFlags::Null, ""); @@ -189,7 +190,7 @@ namespace AZ TEST_F(ConsoleTests, CVar_GetSetTest_Vector2) { - testVec2 = AZ::Vector2{ 0.0f, 0.0f}; + testVec2 = AZ::Vector2{ 0.0f, 0.0f }; TestCVarHelper(testVec2, "testVec2", "testVec2 1 1", "testVec2 asdf", AZ::Vector2(100, 100), AZ::Vector2(0, 0), AZ::Vector2(1, 1)); } @@ -350,3 +351,245 @@ namespace AZ } } } + + +namespace ConsoleSettingsRegistryTests +{ + //! ConfigFile MergeUtils Test + struct ConfigFileParams + { + AZStd::string_view m_testConfigFileName; + AZStd::string_view m_testConfigContents; + }; + class ConsoleSettingsRegistryFixture + : public UnitTest::ScopedAllocatorSetupFixture + , public ::testing::WithParamInterface + { + public: + void SetUp() override + { + m_registry = AZStd::make_unique(); + // Store off the old global settings registry to restore after each test + m_oldSettingsRegistry = AZ::SettingsRegistry::Get(); + if (m_oldSettingsRegistry != nullptr) + { + AZ::SettingsRegistry::Unregister(m_oldSettingsRegistry); + } + AZ::SettingsRegistry::Register(m_registry.get()); + + // Create a TestFile in the Test Directory + m_testFolder = AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / "ConsoleTestFolder"; + auto configFileParams = GetParam(); + CreateTestFile(m_testFolder / configFileParams.m_testConfigFileName, configFileParams.m_testConfigContents); + } + + void TearDown() override + { + // Remove the Test Directory + DeleteFolderRecursive(m_testFolder); + + // Restore the old global settings registry + AZ::SettingsRegistry::Unregister(m_registry.get()); + if (m_oldSettingsRegistry != nullptr) + { + AZ::SettingsRegistry::Register(m_oldSettingsRegistry); + m_oldSettingsRegistry = {}; + } + m_registry.reset(); + } + + void TestClassFunc(const AZ::ConsoleCommandContainer& someStrings) + { + m_stringArgCount = someStrings.size(); + } + + AZ_CONSOLEFUNC(ConsoleSettingsRegistryFixture, TestClassFunc, AZ::ConsoleFunctorFlags::Null, ""); + + static void DeleteFolderRecursive(const AZ::IO::PathView& path) + { + auto callback = [&path](AZStd::string_view filename, bool isFile) -> bool + { + if (isFile) + { + auto filePath = AZ::IO::FixedMaxPath(path) / filename; + AZ::IO::SystemFile::Delete(filePath.c_str()); + } + else + { + if (filename != "." && filename != "..") + { + auto folderPath = AZ::IO::FixedMaxPath(path) / filename; + DeleteFolderRecursive(folderPath); + } + } + return true; + }; + auto searchPath = AZ::IO::FixedMaxPath(path) / "*"; + AZ::IO::SystemFile::FindFiles(searchPath.c_str(), callback); + AZ::IO::SystemFile::DeleteDir(AZ::IO::FixedMaxPathString(path.Native()).c_str()); + } + + static bool CreateTestFile(const AZ::IO::FixedMaxPath& testPath, AZStd::string_view content) + { + AZ::IO::SystemFile file; + if (!file.Open(testPath.c_str(), AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE + | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY)) + { + AZ_Assert(false, "Unable to open test file for writing: %s", testPath.c_str()); + return false; + } + + if (file.Write(content.data(), content.size()) != content.size()) + { + AZ_Assert(false, "Unable to write content to test file: %s", testPath.c_str()); + return false; + } + + return true; + } + + protected: + size_t m_stringArgCount{}; + AZStd::unique_ptr m_registry; + AZ::IO::FixedMaxPath m_testFolder; + + private: + AZ::SettingsRegistryInterface* m_oldSettingsRegistry{}; + }; + + static bool s_consoleFreeFunctionInvoked = false; + static void TestSettingsRegistryFreeFunc(const AZ::ConsoleCommandContainer& someStrings) + { + EXPECT_TRUE(someStrings.empty()); + s_consoleFreeFunctionInvoked = true; + } + + AZ_CONSOLEFREEFUNC(TestSettingsRegistryFreeFunc, AZ::ConsoleFunctorFlags::Null, ""); + + TEST_P(ConsoleSettingsRegistryFixture, Console_AbleToLoadSettingsFile_Successfully) + { + AZ::Console testConsole(*m_registry); + testConsole.LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead()); + AZ::Interface::Register(&testConsole); + AZ_CVAR_SCOPED(int32_t, testInit, 0, nullptr, AZ::ConsoleFunctorFlags::Null, ""); + s_consoleFreeFunctionInvoked = false; + testInit = {}; + AZ::testChar = {}; + AZ::testBool = {}; + AZ::testInt8 = {}; + AZ::testInt16 = {}; + AZ::testInt32 = {}; + AZ::testInt64 = {}; + AZ::testUInt8 = {}; + AZ::testUInt16 = {}; + AZ::testUInt32 = {}; + AZ::testUInt64 = {}; + AZ::testFloat= {}; + AZ::testDouble = {}; + AZ::testString = {}; + + auto configFileParams = GetParam(); + auto testFilePath = m_testFolder / configFileParams.m_testConfigFileName; + EXPECT_TRUE(AZ::IO::SystemFile::Exists(testFilePath.c_str())); + testConsole.ExecuteConfigFile(testFilePath.Native()); + EXPECT_TRUE(s_consoleFreeFunctionInvoked); + EXPECT_EQ(3, testInit); + EXPECT_TRUE(static_cast(AZ::testBool)); + EXPECT_EQ('Q', AZ::testChar); + EXPECT_EQ(24, AZ::testInt8); + EXPECT_EQ(-32, AZ::testInt16); + EXPECT_EQ(41, AZ::testInt32); + EXPECT_EQ(-51, AZ::testInt64); + EXPECT_EQ(3, AZ::testUInt8); + EXPECT_EQ(5, AZ::testUInt16); + EXPECT_EQ(6, AZ::testUInt32); + EXPECT_EQ(0xFFFF'FFFF'FFFF'FFFF, AZ::testUInt64); + EXPECT_FLOAT_EQ(1.0f, AZ::testFloat); + EXPECT_DOUBLE_EQ(2, AZ::testDouble); + EXPECT_STREQ("Stable", static_cast(AZ::testString).c_str()); + EXPECT_EQ(3, m_stringArgCount); + AZ::Interface::Unregister(&testConsole); + } + + + static constexpr AZStd::string_view UserINIStyleContent = + R"( + testInit = 3 + testBool true + testChar Q + testInt8 24 + testInt16 -32 + testInt32 41 + testInt64 -51 + testUInt8 3 + testUInt16 5 + testUInt32 6 + testUInt64 18446744073709551615 + testFloat 1.0 + testDouble 2 + testString Stable + ConsoleSettingsRegistryFixture.testClassFunc Foo Bar Baz + TestSettingsRegistryFreeFunc + )"; + + static constexpr AZStd::string_view UserJsonMergePatchContent = + R"( + { + "Amazon": { + "AzCore": { + "Runtime": { + "ConsoleCommands": { + "testInit": 3, + "testBool": true, + "testChar": "Q", + "testInt8": 24, + "testInt16": -32, + "testInt32": 41, + "testInt64": -51, + "testUInt8": 3, + "testUInt16": 5, + "testUInt32": 6, + "testUInt64": 18446744073709551615, + "testFloat": 1.0, + "testDouble": 2, + "testString": "Stable", + "ConsoleSettingsRegistryFixture.testClassFunc": "Foo Bar Baz", + "TestSettingsRegistryFreeFunc": "" + } + } + } + } + } + )"; + static constexpr AZStd::string_view UserJsonPatchContent = + R"( + [ + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInit", "value": 3 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testBool", "value": true }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testChar", "value": "Q" }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt8", "value": 24 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt16", "value": -32 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt32", "value": 41 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt64", "value": -51 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt8", "value": 3 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt16", "value": 5 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt32", "value": 6 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt64", "value": 18446744073709551615 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testFloat", "value": 1.0 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testDouble", "value": 2 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testString", "value": "Stable" }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/ConsoleSettingsRegistryFixture.testClassFunc", "value": "Foo Bar Baz" }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/TestSettingsRegistryFreeFunc", "value": "" } + ] + )"; + + INSTANTIATE_TEST_CASE_P( + ExecuteCommandFromSettingsFile, + ConsoleSettingsRegistryFixture, + ::testing::Values( + ConfigFileParams{"user.cfg", UserINIStyleContent}, + ConfigFileParams{"user.setreg", UserJsonMergePatchContent}, + ConfigFileParams{"user.setregpatch", UserJsonPatchContent} + ) + ); +} diff --git a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryConsoleUtilsTests.cpp b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryConsoleUtilsTests.cpp index fb9b1a4aa4..c18e83ab63 100644 --- a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryConsoleUtilsTests.cpp +++ b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryConsoleUtilsTests.cpp @@ -55,7 +55,7 @@ namespace SettingsRegistryConsoleUtilsTests { constexpr const char* settingsKey = "/TestKey"; constexpr const char* expectedValue = "TestValue"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) }; EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistrySet, { settingsKey, expectedValue })); @@ -69,7 +69,7 @@ namespace SettingsRegistryConsoleUtilsTests { constexpr const char* settingsKey = "/TestKey"; constexpr const char* expectedValue = "TestValue"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); // Scopes the console functor handle so that it destructs and unregisters the console functors { @@ -89,7 +89,7 @@ namespace SettingsRegistryConsoleUtilsTests constexpr const char* settingsKey2 = "/TestKey2"; constexpr const char* expectedValue = R"(TestValue)"; constexpr const char* expectedValue2 = R"(Hello World)"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) }; @@ -109,7 +109,7 @@ namespace SettingsRegistryConsoleUtilsTests constexpr const char* settingsKey2 = "/TestKey2"; constexpr const char* expectedValue = R"(TestValue)"; constexpr const char* expectedValue2 = R"(Hello World)"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); // Add settings to settings registry EXPECT_TRUE(m_registry->Set(settingsKey, expectedValue)); @@ -137,7 +137,7 @@ namespace SettingsRegistryConsoleUtilsTests constexpr const char* settingsKey2 = "/TestKey2"; constexpr const char* expectedValue = R"(TestValue)"; constexpr const char* expectedValue2 = R"(Hello World)"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) }; @@ -195,7 +195,7 @@ namespace SettingsRegistryConsoleUtilsTests constexpr const char* SettingsKey2 = "TestKey2"; constexpr const char* ExpectedValue = R"(TestValue)"; constexpr const char* ExpectedValue2 = R"(Hello World)"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) }; diff --git a/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp b/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp index f7651664bd..fc07db5b52 100644 --- a/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp +++ b/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp @@ -1228,27 +1228,33 @@ namespace SettingsRegistryTests TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyIsTooLong_ReturnsFalse) { - AZStd::string argument = AZStd::string::format("Te%*cst=Value", aznumeric_cast(AZ::SettingsRegistryImpl::MaxJsonPathLength), ' '); + constexpr int LongKeySize = 1024; + AZStd::string argument = AZStd::string::format("Te%*cst=Value", LongKeySize, ' '); EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, {}, {})); } TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyIsTooLongWithDivider_ReturnsFalse) { - AZStd::string argument = AZStd::string::format("/Te%*cst=Value", aznumeric_cast(AZ::SettingsRegistryImpl::MaxJsonPathLength), ' '); + constexpr int LongKeySize = 1024; + AZStd::string argument = AZStd::string::format("/Te%*cst=Value", LongKeySize, ' '); EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, "/Path", {})); } TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsTooLong_ReturnsFalse) { - AZStd::string argument = AZStd::string::format("Test=Val%*cue", aznumeric_cast(AZ::SettingsRegistryImpl::MaxCommandLineArgumentLength), ' '); + constexpr int LongValueSize = 1024; + AZStd::string argument = AZStd::string::format("Test=Val%*cue", LongValueSize, ' '); EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, {}, {})); EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/Test")); } - TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingValue_ReturnsFalse) + TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingValue_ReturnsEmptyString) { - EXPECT_FALSE(m_registry->MergeCommandLineArgument("Test=", {}, {})); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/Test")); + EXPECT_TRUE(m_registry->MergeCommandLineArgument("Test=", {}, {})); + EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType("/Test")); + AZ::SettingsRegistryInterface::FixedValueString value; + EXPECT_TRUE(m_registry->Get(value, "/Test")); + EXPECT_TRUE(value.empty()); } TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingKey_ReturnsFalse) @@ -1271,9 +1277,13 @@ namespace SettingsRegistryTests EXPECT_FALSE(m_registry->MergeCommandLineArgument(" =Value", {}, {})); } - TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsSpaces_ReturnsFalse) + TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsSpaces_ReturnsEmptyString) { - EXPECT_FALSE(m_registry->MergeCommandLineArgument("Key= ", {}, {})); + EXPECT_TRUE(m_registry->MergeCommandLineArgument("Key= ", {}, {})); + EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType("/Key")); + AZ::SettingsRegistryInterface::FixedValueString value; + EXPECT_TRUE(m_registry->Get(value, "/Key")); + EXPECT_TRUE(value.empty()); } TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyAndValueAreSpaces_ReturnsFalse) @@ -1367,9 +1377,8 @@ namespace SettingsRegistryTests TEST_F(SettingsRegistryTest, MergeSettingsFile_PathAsSubStringThatsTooLong_ReturnsFalse) { - char path[AZ::SettingsRegistryImpl::MaxFilePathLength + 1]; - memset(path, '1', sizeof(path)); - AZStd::string_view subPath(path, AZ::SettingsRegistryImpl::MaxFilePathLength); + constexpr AZStd::fixed_string path(AZ::IO::MaxPathLength + 1, '1'); + const AZStd::string_view subPath(path); AZ_TEST_START_TRACE_SUPPRESSION; bool result = m_registry->MergeSettingsFile(subPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch, {}, nullptr); @@ -1719,8 +1728,7 @@ namespace SettingsRegistryTests TEST_F(SettingsRegistryTest, MergeSettingsFolder_PathTooLong_ReportsErrorAndReturnsFalse) { - char path[AZ::SettingsRegistryImpl::MaxFilePathLength + 1]{}; - memset(path, 'a', AZ_ARRAY_SIZE(path)); + constexpr AZStd::fixed_string path(AZ::IO::MaxPathLength + 1, 'a'); AZ_TEST_START_TRACE_SUPPRESSION; bool result = m_registry->MergeSettingsFolder(path, { "editor", "test" }, {}, nullptr); @@ -1741,7 +1749,7 @@ namespace SettingsRegistryTests m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR); *m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder; bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {}, nullptr); - AZ_TEST_STOP_TRACE_SUPPRESSION(2); + EXPECT_GT(::UnitTest::TestRunner::Instance().StopAssertTests(), 0); EXPECT_FALSE(result); EXPECT_EQ(AZ::SettingsRegistryInterface::Type::Object, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/0")); // Folder and specialization settings. @@ -1751,11 +1759,5 @@ namespace SettingsRegistryTests EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/Path")); EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/File1")); EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/File2")); - - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::Object, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2")); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/Error")); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/Path")); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/File1")); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/File2")); } } // namespace SettingsRegistryTests diff --git a/Code/Framework/AzFramework/AzFramework/Application/Application.cpp b/Code/Framework/AzFramework/AzFramework/Application/Application.cpp index dc6ae684cf..e02892de4e 100644 --- a/Code/Framework/AzFramework/AzFramework/Application/Application.cpp +++ b/Code/Framework/AzFramework/AzFramework/Application/Application.cpp @@ -236,8 +236,6 @@ namespace AzFramework // Archive classes relies on the FileIOBase DirectInstance to close // files properly m_directFileIO.reset(); - - // The AZ::Console skips destruction and always leaks to allow it to be used in static memory } void Application::Start(const Descriptor& descriptor, const StartupParameters& startupParameters) From c6ea0c0a46c2d6df0bc20734440735349af073e3 Mon Sep 17 00:00:00 2001 From: karlberg Date: Sat, 15 May 2021 15:10:17 -0700 Subject: [PATCH 224/225] Various local prediction and input processing related fixes --- .../Serialization/HashSerializer.cpp | 4 +- .../LocalPredictionPlayerInputComponent.h | 3 +- .../Components/MultiplayerComponent.h | 1 + .../Multiplayer/Components/NetBindComponent.h | 1 + .../NetworkInput/IMultiplayerComponentInput.h | 1 + .../Source/AutoGen/AutoComponent_Header.jinja | 4 +- .../Source/AutoGen/AutoComponent_Source.jinja | 16 ++++ .../LocalPredictionPlayerInputComponent.cpp | 93 ++++++++----------- .../Source/Components/NetBindComponent.cpp | 8 ++ .../Source/MultiplayerSystemComponent.cpp | 1 + .../Code/Source/NetworkInput/NetworkInput.cpp | 5 +- .../Source/NetworkInput/NetworkInputArray.cpp | 11 --- .../Source/NetworkInput/NetworkInputArray.h | 4 - 13 files changed, 78 insertions(+), 74 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/Serialization/HashSerializer.cpp b/Code/Framework/AzNetworking/AzNetworking/Serialization/HashSerializer.cpp index c7f47cbc04..479299a87b 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Serialization/HashSerializer.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/Serialization/HashSerializer.cpp @@ -22,7 +22,9 @@ namespace AzNetworking AZ::HashValue32 HashSerializer::GetHash() const { // Just truncate the upper bits - return static_cast(m_hash); + const AZ::HashValue32 lower = static_cast(m_hash); + const AZ::HashValue32 upper = static_cast(m_hash >> 32); + return lower ^ upper; } SerializerMode HashSerializer::GetSerializerMode() const diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/Components/LocalPredictionPlayerInputComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/LocalPredictionPlayerInputComponent.h index 7a6105a7e3..c69623a9e9 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/Components/LocalPredictionPlayerInputComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/LocalPredictionPlayerInputComponent.h @@ -102,7 +102,8 @@ namespace Multiplayer AZ::TimeMs m_lastInputReceivedTimeMs = AZ::TimeMs{ 0 }; AZ::TimeMs m_lastCorrectionSentTimeMs = AZ::TimeMs{ 0 }; - ClientInputId m_clientInputId = ClientInputId{ 0 }; + ClientInputId m_clientInputId = ClientInputId{ 0 }; // Clients incrementing inputId + ClientInputId m_lastClientInputId = ClientInputId{ 0 }; // Last inputId processed by the server ClientInputId m_lastCorrectionInputId = ClientInputId{ 0 }; ClientInputId m_lastMigratedInputId = ClientInputId{ 0 }; // Used to resend inputs that were queued during a migration event HostFrameId m_serverMigrateFrameId = InvalidHostFrameId; diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h index 6f410dd97c..19689171c5 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h @@ -71,6 +71,7 @@ namespace Multiplayer NetworkEntityHandle GetEntityHandle(); void MarkDirty(); + virtual void SetOwningConnectionId(AzNetworking::ConnectionId connectionId) = 0; virtual NetComponentId GetNetComponentId() const = 0; virtual bool HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetEntityRole netEntityRole, NetworkEntityRpcMessage& rpcMessage) = 0; diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h index 257e7cab4b..41503396fb 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h @@ -72,6 +72,7 @@ namespace Multiplayer ConstNetworkEntityHandle GetEntityHandle() const; NetworkEntityHandle GetEntityHandle(); + void SetOwningConnectionId(AzNetworking::ConnectionId connectionId); void SetAllowAutonomy(bool value); MultiplayerComponentInputVector AllocateComponentInputs(); bool IsProcessingInput() const; diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h index 13faff3a7e..7af1bf3f60 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h @@ -30,6 +30,7 @@ namespace Multiplayer virtual ~IMultiplayerComponentInput() = default; virtual NetComponentId GetNetComponentId() const = 0; virtual bool Serialize(AzNetworking::ISerializer& serializer) = 0; + virtual IMultiplayerComponentInput& operator= (const IMultiplayerComponentInput&) { return *this; } }; using MultiplayerComponentInputVector = AZStd::vector>; diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja index 0d4e7146a0..8eede21452 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja @@ -329,6 +329,7 @@ namespace {{ Component.attrib['Namespace'] }} public: Multiplayer::NetComponentId GetNetComponentId() const override; bool Serialize(AzNetworking::ISerializer& serializer) override; + Multiplayer::IMultiplayerComponentInput& operator =(const Multiplayer::IMultiplayerComponentInput& rhs) override; {% call(Input) AutoComponentMacros.ParseNetworkInputs(Component) %} {{ Input.attrib['Type'] }} m_{{ LowerFirst(Input.attrib['Name']) }} = {{ Input.attrib['Type'] }}({{ Input.attrib['Init'] }}); @@ -439,6 +440,7 @@ namespace {{ Component.attrib['Namespace'] }} //! MultiplayerComponent interface //! @{ + void SetOwningConnectionId(AzNetworking::ConnectionId connectionId) override; Multiplayer::NetComponentId GetNetComponentId() const override; bool HandleRpcMessage(AzNetworking::IConnection* invokingConnection, Multiplayer::NetEntityRole remoteRole, Multiplayer::NetworkEntityRpcMessage& rpcMessage) override; bool SerializeStateDeltaMessage(Multiplayer::ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer) override; @@ -519,7 +521,7 @@ namespace {{ Component.attrib['Namespace'] }} //! Archetype Properties {{ DeclareArchetypePropertyVars(Component)|indent(8) }} {% call(Type, Name) AutoComponentMacros.ParseComponentServiceTypeAndName(Component) %} - {{ Type }}* {{ Name }} = nullptr; + {{ Type }}* {{ Name }} = nullptr; {% endcall %} static Multiplayer::NetComponentId s_netComponentId; diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 516e6a05e8..3b3fa817cd 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -1068,6 +1068,13 @@ namespace {{ Component.attrib['Namespace'] }} return serializer.IsValid(); } + Multiplayer::IMultiplayerComponentInput& {{ ComponentName }}NetworkInput::operator =([[maybe_unused]] const Multiplayer::IMultiplayerComponentInput& rhs) + { + AZ_Assert(s_netComponentId == rhs.GetNetComponentId(), "AttachNetSystemComponent was not called on the owning NetworkInput"); + *this = *static_cast(&rhs); + return *this; + } + {% endif %} {{ ControllerBaseName }}::{{ ControllerBaseName }}({{ ComponentName }}& parent) : MultiplayerController(parent) @@ -1278,6 +1285,15 @@ namespace {{ Component.attrib['Namespace'] }} {{ DefineRpcInvocations(Component, ComponentBaseName, 'Server', 'Authority', false)|indent(4) -}} {{ DefineRpcInvocations(Component, ComponentBaseName, 'Server', 'Authority', true)|indent(4) }} + void {{ ComponentBaseName }}::SetOwningConnectionId([[maybe_unused]] AzNetworking::ConnectionId connectionId) + { +{% for Property in Component.iter('NetworkProperty') %} +{% if Property.attrib['IsRewindable']|booleanTrue %} + m_{{ LowerFirst(Property.attrib['Name']) }}.SetOwningConnectionId(connectionId); +{% endif %} +{% endfor %} + } + Multiplayer::NetComponentId {{ ComponentBaseName }}::GetNetComponentId() const { return s_netComponentId; diff --git a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp index 46136fcde9..10a0d17e73 100644 --- a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp @@ -113,73 +113,57 @@ namespace Multiplayer [[maybe_unused]] const AzNetworking::PacketEncodingBuffer& clientState ) { - // After receiving the first input from the client, start the update event to check for slow hacking - if (!m_updateBankedTimeEvent.IsScheduled()) - { - m_updateBankedTimeEvent.Enqueue(sv_InputUpdateTimeMs, true); - } - if (invokingConnection == nullptr) { // Discard any input messages that were locally dispatched or sent by disconnected clients return; } + const ClientInputId clientInputId = inputArray[0].GetClientInputId(); + if (clientInputId <= m_lastClientInputId) + { + AZLOG(NET_Prediction, "Discarding old or out of order move input (current: %u, received %u)", + aznumeric_cast(m_lastClientInputId), aznumeric_cast(clientInputId)); + return; + } + + // After receiving the first input from the client, start the update event to check for slow hacking + if (!m_updateBankedTimeEvent.IsScheduled()) + { + m_updateBankedTimeEvent.Enqueue(sv_InputUpdateTimeMs, true); + } + const AZ::TimeMs currentTimeMs = AZ::GetElapsedTimeMs(); const double clientInputRateSec = static_cast(static_cast(cl_InputRateMs)) / 1000.0; m_lastInputReceivedTimeMs = currentTimeMs; // Keep track of last inputs received, also allows us to update frame ids m_lastInputReceived = inputArray; - - // Figure out which index from the input array we want - // we start at the oldest input that has not been processed - int32_t inputArrayIndex = -1; - for (int32_t i = NetworkInputArray::MaxElements - 1; i >= 0; --i) - { - // Find an input that is newer than the last one we processed - if (m_lastInputReceived[i].GetClientInputId() > GetLastInputId()) - { - inputArrayIndex = i; - break; - } - } - - if (inputArrayIndex < 0) - { - AZLOG - ( - NET_Prediction, - "Discarding old or out of order move input (current: %u, received %u)", - aznumeric_cast(GetLastInputId()), - aznumeric_cast(m_lastInputReceived[0].GetClientInputId()) - ); - return; - } - - bool lostInput = false; - if (GetLastInputId() < inputArray.GetPreviousInputId()) - { - // last move id processed is older than the previous input id, we missed some input packets - lostInput = true; - } - SetLastInputId(m_lastInputReceived[0].GetClientInputId()); // Set this variable in case of migration - while (inputArrayIndex >= 0) + while (m_lastClientInputId < clientInputId) { - NetworkInput& input = m_lastInputReceived[inputArrayIndex]; + ++m_lastClientInputId; + + // Figure out which index from the input array we want + // If we have skipped an id, check if it was sent to us in the array. If we have lost too many, just use the oldest one in the array + const uint32_t deltaFrameId = aznumeric_cast(clientInputId - m_lastClientInputId); // always >= 0 because of while loop check + const uint32_t inputArrayIdx = AZStd::min(deltaFrameId, NetworkInputArray::MaxElements - 1); + const bool lostInput = deltaFrameId >= NetworkInputArray::MaxElements; // For logging only + + NetworkInput &input = m_lastInputReceived[inputArrayIdx]; + input.SetClientInputId(m_lastClientInputId); // Anticheat, if we're receiving too many inputs, and fall outside our variable latency input window // Discard move input events, client may be speed hacking if (m_clientBankedTime < sv_MaxBankTimeWindowSec) { m_clientBankedTime = AZStd::min(m_clientBankedTime + clientInputRateSec, (double)sv_MaxBankTimeWindowSec); // clamp to boundary - { ScopedAlterTime scopedTime(input.GetHostFrameId(), input.GetHostTimeMs(), invokingConnection->GetConnectionId()); GetNetBindComponent()->ProcessInput(input, static_cast(clientInputRateSec)); } + if (lostInput) { AZLOG(NET_Prediction, "InputLost InputId=%u", aznumeric_cast(input.GetClientInputId())); @@ -193,7 +177,6 @@ namespace Multiplayer { AZLOG(NET_Prediction, "Dropped InputId=%u", aznumeric_cast(input.GetClientInputId())); } - --inputArrayIndex; } if (sv_EnableCorrections && (currentTimeMs - m_lastCorrectionSentTimeMs > sv_MinCorrectionTimeMs)) @@ -205,6 +188,14 @@ namespace Multiplayer const AZ::HashValue32 localAuthorityHash = hashSerializer.GetHash(); + AZLOG + ( + NET_Prediction, + "Hash values for ProcessInput: client=%u, server=%u", + aznumeric_cast(stateHash), + aznumeric_cast(localAuthorityHash) + ); + if (stateHash != localAuthorityHash) { // Produce correction for client @@ -542,21 +533,15 @@ namespace Multiplayer m_inputHistory.PopFront(); } - const size_t inputHistorySize = m_inputHistory.Size(); + const int64_t inputHistorySize = aznumeric_cast(m_inputHistory.Size()); // Form the rest of the input array using the n most recent elements in the history buffer // NOTE: inputArray[0] has already been initialized hence start at i = 1 - for (uint32_t i = 1; i < NetworkInputArray::MaxElements; ++i) + for (int64_t i = 1; i < aznumeric_cast(NetworkInputArray::MaxElements); ++i) { - if (i < inputHistorySize) - { - inputArray[i] = m_inputHistory[inputHistorySize - 1 - i]; - } - else // History is too small? - { - // Plug in the most recent input - inputArray[i] = input; - } + // Clamp to oldest element if history is too small + const int64_t historyIndex = AZStd::max(inputHistorySize - 1 - i, 0); + inputArray[i] = m_inputHistory[historyIndex]; } // Send the input to server (only when we are not migrating) diff --git a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp index 6449f57e8e..e48d0b0d09 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp @@ -152,6 +152,14 @@ namespace Multiplayer return m_netEntityHandle; } + void NetBindComponent::SetOwningConnectionId(AzNetworking::ConnectionId connectionId) + { + for (MultiplayerComponent* multiplayerComponent : m_multiplayerInputComponentVector) + { + multiplayerComponent->SetOwningConnectionId(connectionId); + } + } + void NetBindComponent::SetAllowAutonomy(bool value) { // This flag allows a player host to autonomously control their player entity, even though the entity is in an authority role diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index a10bbf8a1a..723fada6d1 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -448,6 +448,7 @@ namespace Multiplayer if (entityList.size() > 0) { controlledEntity = entityList[0]; + controlledEntity.GetNetBindComponent()->SetOwningConnectionId(connection->GetConnectionId()); } if (connection->GetUserData() == nullptr) // Only add user data if the connect event handler has not already done so diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp index 7b9cba5a93..ba87849047 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp @@ -9,7 +9,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ - +#pragma optimize ("", off) #include #include #include @@ -166,6 +166,7 @@ namespace Multiplayer void NetworkInput::CopyInternal(const NetworkInput& rhs) { m_inputId = rhs.m_inputId; + m_hostFrameId = rhs.m_hostFrameId; m_hostTimeMs = rhs.m_hostTimeMs; m_componentInputs.resize(rhs.m_componentInputs.size()); for (int32_t i = 0; i < rhs.m_componentInputs.size(); ++i) @@ -175,7 +176,7 @@ namespace Multiplayer { m_componentInputs[i] = AZStd::move(GetMultiplayerComponentRegistry()->AllocateComponentInput(rhsComponentId)); } - *m_componentInputs[i] = *rhs.m_componentInputs[i]; + *(m_componentInputs[i]) = *(rhs.m_componentInputs[i]); } m_wasAttached = rhs.m_wasAttached; } diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp index d95310e4b5..e736cd4da2 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.cpp @@ -48,16 +48,6 @@ namespace Multiplayer return m_inputs[index].m_networkInput; } - void NetworkInputArray::SetPreviousInputId(ClientInputId previousInputId) - { - m_previousInputId = previousInputId; - } - - ClientInputId NetworkInputArray::GetPreviousInputId() const - { - return m_previousInputId; - } - bool NetworkInputArray::Serialize(AzNetworking::ISerializer& serializer) { // Always serialize the full first element @@ -102,7 +92,6 @@ namespace Multiplayer } } } - serializer.Serialize(m_previousInputId, "PreviousInputId"); return true; } } diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h index b67ce79112..293fb18928 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInputArray.h @@ -33,9 +33,6 @@ namespace Multiplayer NetworkInput& operator[](uint32_t index); const NetworkInput& operator[](uint32_t index) const; - void SetPreviousInputId(ClientInputId previousInputId); - ClientInputId GetPreviousInputId() const; - bool Serialize(AzNetworking::ISerializer& serializer); private: @@ -49,6 +46,5 @@ namespace Multiplayer ConstNetworkEntityHandle m_owner; AZStd::array m_inputs; - ClientInputId m_previousInputId; }; } From e0ea9e6224e02dab83dc57914242533f12528ec3 Mon Sep 17 00:00:00 2001 From: karlberg Date: Sat, 15 May 2021 15:29:22 -0700 Subject: [PATCH 225/225] Removing debug code --- Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp index ba87849047..2589f52d87 100644 --- a/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkInput/NetworkInput.cpp @@ -9,7 +9,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#pragma optimize ("", off) + #include #include #include