From 762b3ee58288fb51b8d9c93e4af69da19b81993a Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Thu, 8 Jul 2021 00:24:52 -0700 Subject: [PATCH 01/37] Suspended ray tracing for DiffuseProbeGrids that are not visible, either off-screen or behind an occlusion culling plane Added a culling flag that indicates if the cullable object is currently visible in any view Signed-off-by: dmcdiar --- .../DiffuseProbeGrid.cpp | 17 ++++++++++ .../DiffuseProbeGrid.h | 3 ++ .../DiffuseProbeGridBlendDistancePass.cpp | 8 ++--- .../DiffuseProbeGridBlendIrradiancePass.cpp | 8 ++--- .../DiffuseProbeGridBorderUpdatePass.cpp | 8 ++--- .../DiffuseProbeGridClassificationPass.cpp | 9 +++--- .../DiffuseProbeGridFeatureProcessor.cpp | 32 +++++++++++++++++++ .../DiffuseProbeGridFeatureProcessor.h | 8 +++++ .../DiffuseProbeGridRayTracingPass.cpp | 10 +++--- .../DiffuseProbeGridRelocationPass.cpp | 10 +++--- .../DiffuseProbeGridRenderPass.cpp | 12 ++++++- .../Code/Include/Atom/RPI.Public/Culling.h | 4 +++ .../RPI/Code/Source/RPI.Public/Culling.cpp | 2 ++ 13 files changed, 104 insertions(+), 27 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp index 7e48f0e81f..888d7c57d8 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp @@ -245,6 +245,23 @@ namespace AZ m_bakedClassificationImage.get(); } + void DiffuseProbeGrid::ResetCullingVisibility() + { + m_cullable.m_isVisible = false; + } + + bool DiffuseProbeGrid::GetIsVisible() const + { + // we need to go through the DiffuseProbeGrid passes at least once in order to initialize + // the RenderObjectSrg, which means we need to be visible until the RenderObjectSrg is created + if (m_renderObjectSrg == nullptr) + { + return true; + } + + return m_cullable.m_isVisible; + } + uint32_t DiffuseProbeGrid::GetTotalProbeCount() const { return m_probeCountX * m_probeCountY * m_probeCountZ; diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h index 855b4732bd..7b36e0b2c5 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.h @@ -102,6 +102,9 @@ namespace AZ void DecrementRemainingRelocationIterations() { m_remainingRelocationIterations = AZStd::max(0, m_remainingRelocationIterations - 1); } void ResetRemainingRelocationIterations() { m_remainingRelocationIterations = DefaultNumRelocationIterations; } + void ResetCullingVisibility(); + bool GetIsVisible() const; + // compute total number of probes in the grid uint32_t GetTotalProbeCount() const; diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistancePass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistancePass.cpp index 60576dc3d3..2a150fdb4e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistancePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendDistancePass.cpp @@ -82,7 +82,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -106,7 +106,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe raytrace image { @@ -145,7 +145,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -162,7 +162,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItem for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetBlendDistanceSrg()->GetRHIShaderResourceGroup(); commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiancePass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiancePass.cpp index 516b3a3098..130e1864b1 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiancePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBlendIrradiancePass.cpp @@ -82,7 +82,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -106,7 +106,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe raytrace image { @@ -145,7 +145,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -162,7 +162,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItem for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetBlendIrradianceSrg()->GetRHIShaderResourceGroup(); commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdatePass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdatePass.cpp index 5d3cdfbc84..48da2de4d7 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdatePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridBorderUpdatePass.cpp @@ -95,7 +95,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -119,7 +119,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe irradiance image { @@ -148,7 +148,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see line ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -168,7 +168,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItems for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { uint32_t probeCountX; uint32_t probeCountY; diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridClassificationPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridClassificationPass.cpp index 09364ec7f2..0789b3b7da 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridClassificationPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridClassificationPass.cpp @@ -86,7 +86,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -110,7 +110,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe raytrace image { @@ -138,11 +138,12 @@ namespace AZ { RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() in ShaderResourceGroupData.cpp) diffuseProbeGrid->UpdateClassificationSrg(m_srgAsset); + diffuseProbeGrid->GetClassificationSrg()->Compile(); } } @@ -154,7 +155,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItems for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetClassificationSrg()->GetRHIShaderResourceGroup(); commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.cpp index 7cc9d5ef50..93d47af012 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.cpp @@ -175,6 +175,27 @@ namespace AZ } } + void DiffuseProbeGridFeatureProcessor::OnBeginPrepareRender() + { + for (auto& diffuseProbeGrid : m_realTimeDiffuseProbeGrids) + { + diffuseProbeGrid->ResetCullingVisibility(); + } + } + + void DiffuseProbeGridFeatureProcessor::OnEndPrepareRender() + { + // re-build the list of visible real-time diffuse probe grids + m_visibleRealTimeDiffuseProbeGrids.clear(); + for (auto& diffuseProbeGrid : m_realTimeDiffuseProbeGrids) + { + if (diffuseProbeGrid->GetIsVisible()) + { + m_visibleRealTimeDiffuseProbeGrids.push_back(diffuseProbeGrid); + } + } + } + DiffuseProbeGridHandle DiffuseProbeGridFeatureProcessor::AddProbeGrid(const AZ::Transform& transform, const AZ::Vector3& extents, const AZ::Vector3& probeSpacing) { AZStd::shared_ptr diffuseProbeGrid = AZStd::make_shared(); @@ -215,6 +236,17 @@ namespace AZ m_realTimeDiffuseProbeGrids.erase(itEntry); } + // remove from side list of visible real-time grids + itEntry = AZStd::find_if(m_visibleRealTimeDiffuseProbeGrids.begin(), m_visibleRealTimeDiffuseProbeGrids.end(), [&](AZStd::shared_ptr const& entry) + { + return (entry == probeGrid); + }); + + if (itEntry != m_visibleRealTimeDiffuseProbeGrids.end()) + { + m_visibleRealTimeDiffuseProbeGrids.erase(itEntry); + } + probeGrid = nullptr; } diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h index 4d045ec62d..9771c058ad 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h @@ -76,6 +76,9 @@ namespace AZ // retrieve the side list of probe grids that are using real-time (raytraced) mode DiffuseProbeGridVector& GetRealTimeProbeGrids() { return m_realTimeDiffuseProbeGrids; } + // retrieve the side list of probe grids that are using real-time (raytraced) mode and visible (on screen) + DiffuseProbeGridVector& GetVisibleRealTimeProbeGrids() { return m_visibleRealTimeDiffuseProbeGrids; } + private: AZ_DISABLE_COPY_MOVE(DiffuseProbeGridFeatureProcessor); @@ -96,6 +99,8 @@ namespace AZ void HandleAssetNotification(Data::Asset asset, DiffuseProbeGridTextureNotificationType notificationType); // RPI::SceneNotificationBus::Handler overrides + void OnBeginPrepareRender() override; + void OnEndPrepareRender() override; void OnRenderPipelinePassesChanged(RPI::RenderPipeline* renderPipeline) override; void OnRenderPipelineAdded(RPI::RenderPipelinePtr pipeline) override; void OnRenderPipelineRemoved(RPI::RenderPipeline* pipeline) override; @@ -110,6 +115,9 @@ namespace AZ // side list of diffuse probe grids that are in real-time mode (subset of m_diffuseProbeGrids) DiffuseProbeGridVector m_realTimeDiffuseProbeGrids; + // side list of diffuse probe grids that are in real-time mode and visible (subset of m_realTimeDiffuseProbeGrids) + DiffuseProbeGridVector m_visibleRealTimeDiffuseProbeGrids; + // position structure for the box vertices struct Position { diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingPass.cpp index c3192fc36e..86a03fe128 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRayTracingPass.cpp @@ -131,7 +131,7 @@ namespace AZ } DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -148,9 +148,9 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); RayTracingFeatureProcessor* rayTracingFeatureProcessor = scene->GetFeatureProcessor(); - frameGraph.SetEstimatedItemCount(aznumeric_cast(diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().size())); + frameGraph.SetEstimatedItemCount(aznumeric_cast(diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().size())); - for (const auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (const auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // TLAS { @@ -255,7 +255,7 @@ namespace AZ rayTracingFeatureProcessor->GetMeshInfoBuffer() && rayTracingFeatureProcessor->GetSubMeshCount()) { - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader // inputs (see line ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -303,7 +303,7 @@ namespace AZ m_rayTracingShaderTable) { // submit the DispatchRaysItem for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroups[] = { diffuseProbeGrid->GetRayTraceSrg()->GetRHIShaderResourceGroup(), diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRelocationPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRelocationPass.cpp index 9627b7d938..1b3b12b754 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRelocationPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRelocationPass.cpp @@ -86,7 +86,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty()) + if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids().empty()) { // no diffuse probe grids return; @@ -103,7 +103,7 @@ namespace AZ // create the Relocation Srgs for each DiffuseProbeGrid, and check to see if any grids need relocation bool needRelocation = false; - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { uint32_t rayTracingDataRevision = rayTracingFeatureProcessor->GetRevision(); if (rayTracingDataRevision != m_rayTracingDataRevision) @@ -134,7 +134,7 @@ namespace AZ RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // probe raytrace image { @@ -162,7 +162,7 @@ namespace AZ { RPI::Scene* scene = m_pipeline->GetScene(); DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() in ShaderResourceGroupData.cpp) @@ -182,7 +182,7 @@ namespace AZ DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor(); // submit the DispatchItems for each DiffuseProbeGrid - for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids()) + for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetVisibleRealTimeProbeGrids()) { const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetRelocationSrg()->GetRHIShaderResourceGroup(); commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup); diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.cpp index ebb9ad9eb1..776096d35e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.cpp @@ -94,7 +94,12 @@ namespace AZ { continue; } - + + if (!diffuseProbeGrid->GetIsVisible()) + { + continue; + } + // probe irradiance image { if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked) @@ -182,6 +187,11 @@ namespace AZ continue; } + if (!diffuseProbeGrid->GetIsVisible()) + { + continue; + } + // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs // (see ValidateSetImageView() of ShaderResourceGroupData.cpp) diffuseProbeGrid->UpdateRenderObjectSrg(); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Culling.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Culling.h index 72d0e3c69c..7f042e58cb 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Culling.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Culling.h @@ -91,6 +91,10 @@ namespace AZ }; LodData m_lodData; + //! Flag indicating if the object is visible in any view, meaning it passed the culling tests in the previous frame. + //! This flag must be manually cleared by the Cullable object every frame. + bool m_isVisible = false; + //! Flag indicating if the object is hidden, i.e., was specifically marked as //! something that shouldn't be rendered, regardless of its actual position relative to the camera bool m_isHidden = false; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp index cd1b0e925a..c78d8e8169 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp @@ -339,6 +339,7 @@ namespace AZ { numDrawPackets += AddLodDataToView(c->m_cullData.m_boundingSphere.GetCenter(), c->m_lodData, *m_jobData->m_view); ++numVisibleCullables; + c->m_isVisible = true; } } } @@ -374,6 +375,7 @@ namespace AZ { numDrawPackets += AddLodDataToView(c->m_cullData.m_boundingSphere.GetCenter(), c->m_lodData, *m_jobData->m_view); ++numVisibleCullables; + c->m_isVisible = true; } } } From 3f231075fec9b28a20716608dd9582ed7be82771 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 8 Jul 2021 08:53:19 -0700 Subject: [PATCH 02/37] Remove last of Great ScriptCanvas purge code, fix purity categorization handler connection control Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AzCore/Debug/StackTracer_Windows.cpp | 2 +- .../Code/Include/ScriptCanvas/Core/Node.cpp | 39 ------------------- .../Code/Include/ScriptCanvas/Core/Node.h | 6 --- .../Grammar/AbstractCodeModel.cpp | 29 +++++--------- .../Grammar/PrimitivesExecution.cpp | 8 ++-- .../Grammar/PrimitivesExecution.h | 6 +-- .../ScriptCanvas/Translation/GraphToLua.cpp | 10 +++-- 7 files changed, 23 insertions(+), 77 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index 9b2ccbe754..39f6c02bde 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -146,7 +146,7 @@ namespace AZ { AZStd::mutex g_dbgLoadingMutex; HANDLE g_currentProcess = 0; /// We deal with only one process for now. CRITICAL_SECTION g_csDbgHelpDll; /// All dbg help functions are single threaded, so we need to control the access. - AZStd::fixed_vector g_moduleInfo; + AZStd::fixed_vector g_moduleInfo; // reserve 4k of scratch space so that we can get some callstack information without any allocations and as little stack frame usage as possible. const size_t g_scratchSpaceSize = 2048; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index 8250eb1763..cb1887252c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -2949,45 +2949,6 @@ namespace ScriptCanvas } } - void Node::SetInput(const Datum& newInput, const SlotId& slotId) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - - ModifiableDatumView datumView; - FindModifiableDatumView(slotId, datumView); - - if (datumView.IsValid()) - { - datumView.AssignToDatum(newInput); - } - } - - void Node::SetInput(Datum&& newInput, const SlotId& slotId) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - - ModifiableDatumView datumView; - FindModifiableDatumView(slotId, datumView); - - if (datumView.IsValid()) - { - datumView.AssignToDatum(newInput); - } - } - - void Node::SetInput(Node& node, const SlotId& id, const Datum& input) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - node.SetInput(input, id); - } - - void Node::SetInput(Node& node, const SlotId& id, Datum&& input) - { - AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Node::SetInput"); - - node.SetInput(AZStd::move(input), id); - } - AZStd::string Node::GetDebugName() const { if (GetEntityId().IsValid()) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index 55379e29b9..bb598c01fd 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -841,9 +841,6 @@ namespace ScriptCanvas void SignalSlotsReordered(); - static void SetInput(Node& node, const SlotId& id, const Datum& input); - static void SetInput(Node& node, const SlotId& id, Datum&& input); - // Will ignore any references and return the Datum that the slot represents. void ModifyUnderlyingSlotDatum(const SlotId& id, ModifiableDatumView& datumView); @@ -995,9 +992,6 @@ protected: void SetOwningScriptCanvasId(ScriptCanvasId scriptCanvasId); void SetGraphEntityId(AZ::EntityId graphEntityId); - virtual void SetInput(const Datum& input, const SlotId& id); - virtual void SetInput(Datum&& input, const SlotId& id); - bool SlotExists(AZStd::string_view name, const SlotDescriptor& slotDescriptor) const; bool IsTargetInDataFlowPath(const ID& targetNodeId, AZStd::unordered_set& path) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 348c89f45f..293ad236d3 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -2422,17 +2422,17 @@ namespace ScriptCanvas ExecutionTreePtr start = OpenScope(nullptr, startNode, nullptr); start->SetSymbol(Symbol::FunctionDefinition); + m_start = start; // cache the function definition if (!m_subgraphStartCalls.empty()) { - m_start = start; - + // call OnGraphStart on all the member nodeables first for (auto node : m_subgraphStartCalls) { ExecutionTreePtr childStartCall = CreateChild(start, node, nullptr); childStartCall->SetSymbol(Symbol::FunctionCall); childStartCall->SetName(k_OnGraphStartFunctionName); - childStartCall->MarkStart(); + childStartCall->MarkStartCall(); auto lexicalScopeOutcome = node->GetFunctionCallLexicalScope(nullptr); @@ -2478,11 +2478,13 @@ namespace ScriptCanvas } } + // ExecutionTreePtr start is now either the last child start() call, or the beginning of the function block, + // either way, parsing can continue from the ExecutionTreePtr start. + if (!outSlots.empty()) { start->AddChild({ outSlots[0], {}, nullptr }); - start->MarkStart(); - + ParseExecutionMultipleOutSyntaxSugar(start, outNodes, outSlots); PostParseProcess(start); PostParseErrorDetect(start); @@ -2490,24 +2492,10 @@ namespace ScriptCanvas if (!IsErrorFree()) { start->Clear(); - - if (m_start) - { - m_start->Clear(); - } - + m_start->Clear(); AddError(AZ::EntityId{}, nullptr, ScriptCanvas::ParseErrors::StartNodeFailedToParse); return; } - - if (!m_start) - { - m_start = start; - } - } - else - { - // add warning or notification on useless start node? } if (m_start) @@ -4428,6 +4416,7 @@ namespace ScriptCanvas if (auto eventHandling = GetEBusEventHandling(node)) { auto variable = AZStd::make_shared(); + variable->m_isMember = true; variable->m_datum = Datum(eventHandling->m_handlerName); execution->MarkInputHasThisPointer(); execution->AddInput({ nullptr, variable, DebugDataSource::FromInternal() }); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp index 0984440bf4..011dfeda97 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp @@ -354,9 +354,9 @@ namespace ScriptCanvas return GetRoot()->m_isPure; } - bool ExecutionTree::IsStart() const + bool ExecutionTree::IsStartCall() const { - return m_isStart; + return m_isStartCall; } void ExecutionTree::MarkDebugEmptyStatement() @@ -403,9 +403,9 @@ namespace ScriptCanvas root->m_isLatent = true; } - void ExecutionTree::MarkStart() + void ExecutionTree::MarkStartCall() { - m_isStart = true; + m_isStartCall = true; } ExecutionChild& ExecutionTree::ModChild(size_t index) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h index c86f445a68..80d602ad17 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h @@ -199,7 +199,7 @@ namespace ScriptCanvas bool IsPure() const; - bool IsStart() const; + bool IsStartCall() const; void MarkDebugEmptyStatement(); @@ -215,7 +215,7 @@ namespace ScriptCanvas void MarkRootLatent(); - void MarkStart(); + void MarkStartCall(); ExecutionChild& ModChild(size_t index); @@ -286,7 +286,7 @@ namespace ScriptCanvas bool m_isPure = false; - bool m_isStart = false; + bool m_isStartCall = false; bool m_hasExplicitUserOutCalls = false; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp index 772fda4f7e..f945110674 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp @@ -806,7 +806,7 @@ namespace ScriptCanvas m_dotLua.Write("("); - if (execution->IsStart() && execution->IsPure()) + if (execution == m_model.GetStart() && execution->IsPure()) { m_dotLua.Write(Grammar::k_executionStateVariableName); @@ -1589,8 +1589,10 @@ namespace ScriptCanvas break; } - // #functions2 pure on graph start nodes with dependencies can only be added to the graph as variables -// if (execution->IsStart() && execution->IsPure()) + // #functions2 pure on graph start nodes with dependencies can only be added to the graph as variables, which is a work-flow we may never want to support + // as it effectively duplicates the Component-Entity-System. Technically, if this functionality is desired, one could just add another script component + // with the additional graph... +// if (execution->IsStartCall() && execution->IsPure()) // { // WriteFunctionCallInputOfChildStart(execution); // } @@ -1944,7 +1946,7 @@ namespace ScriptCanvas { const auto requirement = ParseConstructionRequirement(variable); - if (requirement == Grammar::VariableConstructionRequirement::None || (requirement != Grammar::VariableConstructionRequirement::Static && !execution->IsStart())) + if (requirement == Grammar::VariableConstructionRequirement::None || (requirement != Grammar::VariableConstructionRequirement::Static && !execution->IsStartCall())) { m_dotLua.WriteLineIndented("local %s = %s", variable->m_name.data(), ToValueString(variable->m_datum, m_configuration).data()); } From 8ef87dc99892255d2edaac06f4ea696f1695bd74 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 8 Jul 2021 12:11:31 -0700 Subject: [PATCH 03/37] Avoid looking for an entry in a map that doesn't exist (#1980) Signed-off-by: Chris Burel --- .../Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp index 99aed41502..5f195d1787 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp @@ -428,16 +428,16 @@ namespace AZ { const auto& jobParameters = request.m_jobDescription.m_jobParameters; - if (jobParameters.find(ShaderVariantLoadErrorParam) != jobParameters.end()) + if (jobParameters.contains(ShaderVariantLoadErrorParam)) { AZ_Error(ShaderVariantAssetBuilderName, false, "Error during CreateJobs: %s", jobParameters.at(ShaderVariantLoadErrorParam).c_str()); response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; return; } - if (jobParameters.find(ShouldExitEarlyFromProcessJobParam) != jobParameters.end()) + if (jobParameters.contains(ShouldExitEarlyFromProcessJobParam)) { - AZ_TracePrintf(ShaderVariantAssetBuilderName, "Doing nothing on behalf of [%s] because it's been overridden by game project.", jobParameters.at(ShaderVariantLoadErrorParam).c_str()); + AZ_TracePrintf(ShaderVariantAssetBuilderName, "Doing nothing on behalf of [%s] because it's been overridden by game project.", jobParameters.at(ShouldExitEarlyFromProcessJobParam).c_str()); response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; return; } From b63c9a87dbb7185c6714b0ba5094de8abe544d1e Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 8 Jul 2021 15:08:55 -0700 Subject: [PATCH 04/37] compile time null checks avaiable for method node Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Include/ScriptCanvas/Core/Node.cpp | 5 + .../Code/Include/ScriptCanvas/Core/Node.h | 3 + .../Grammar/AbstractCodeModel.cpp | 56 +- .../ScriptCanvas/Grammar/AbstractCodeModel.h | 4 +- .../ScriptCanvas/Libraries/Core/Method.cpp | 42 +- .../ScriptCanvas/Libraries/Core/Method.h | 5 +- .../Include/ScriptCanvas/Results/ErrorText.h | 1 + ...nitTest_ParseErrorOnKnownNull.scriptcanvas | 947 ++++++++++++++++++ .../Tests/ScriptCanvas_RuntimeInterpreted.cpp | 10 + 9 files changed, 1046 insertions(+), 27 deletions(-) create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index cb1887252c..c6c9330e51 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -2335,6 +2335,11 @@ namespace ScriptCanvas } } + bool Node::CanAcceptNullInput([[maybe_unused]] const Slot& executionSlot, [[maybe_unused]] const Slot& inputSlot) const + { + return true; + } + void Node::CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const { for (const Slot& slot : m_slots) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index bb598c01fd..614494883a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -479,7 +479,10 @@ namespace ScriptCanvas Node(const Node&); // Needed just for DLL linkage. Does not perform a copy Node& operator=(const Node&); // Needed just for DLL linkage. Does not perform a copy + virtual bool CanAcceptNullInput(const Slot& executionSlot, const Slot& inputSlot) const; + virtual void CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const; + virtual bool ContainsReferencesToVariables(const AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const; Graph* GetGraph() const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 293ad236d3..80d2977c6d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -670,6 +670,28 @@ namespace ScriptCanvas return AddVariable(Datum(type), rawName); } + void AbstractCodeModel::CheckForKnownNullDereference(ExecutionTreeConstPtr execution, const ExecutionInput& input, const Slot& inputSlot) + { + if (Data::IsValueType(inputSlot.GetDataType()) + || !execution->GetId().m_node + || !execution->GetId().m_slot + || (input.m_value && !input.m_value->m_datum.Empty())) + { + return; + } + + if (!input.m_value) + { + AddError(execution->GetId().m_node->GetEntityId(), nullptr, "Internal Error: CheckForKnownNullDereference called with input with no m_value"); + return; + } + + if (!execution->GetId().m_node->CanAcceptNullInput(*execution->GetId().m_slot, inputSlot)) + { + AddError(execution->GetId().m_node->GetEntityId(), nullptr, ParseErrors::NullInputKnown); + } + } + void AbstractCodeModel::CheckConversion(ConversionByIndex& conversion, VariableConstPtr source, size_t index, const Data::Type& targetType) { const Data::Type& sourceType = source->m_datum.GetType(); @@ -698,7 +720,7 @@ namespace ScriptCanvas } AZStd::string AbstractCodeModel::CheckUniqueInterfaceNames - (AZStd::string_view candidate + ( AZStd::string_view candidate , AZStd::string_view defaultName , AZStd::unordered_set& uniqueNames , const AZStd::unordered_set& nodelingsOut) @@ -4285,10 +4307,7 @@ namespace ScriptCanvas void AbstractCodeModel::ParseInputDatum(ExecutionTreePtr execution, const Slot& input) { - // \todo look for crossed lines in inferred functions, because sometimes, rather than the input - // being named of the result of the output that emitted it, it will be the name of the inferred function - // parameter ---> make a map of node output to function input names - AZ_Assert(execution->GetSymbol() != Symbol::FunctionDefinition, "Function definition input should have been handled already"); + AZ_Assert(execution->GetSymbol() != Symbol::FunctionDefinition, "Function definition input is not handled in AbstractCodeModel::ParseInputDatum"); auto nodes = execution->GetId().m_node->GetConnectedNodes(input); if (nodes.empty()) @@ -4298,17 +4317,6 @@ namespace ScriptCanvas execution->AddInput({ &input, variable, DebugDataSource::FromVariable(input.GetId(), input.GetDataType(), variable->m_sourceVariableId) }); CheckConversion(execution->ModConversions(), variable, execution->GetInputCount() - 1, input.GetDataType()); } - // This concept may never actually be possible -// else if (RequiresCreationFunction(input.GetDataType().GetType())) -// { -// AddError(execution, aznew NotYetImplemented( -// "1: finish input created by name when connected to other nodes" -// "2: add the name to the scope" -// "3: and check inputs be re-used, common constructors like zero/1, etc" -// "4: read the variable name if it is present instead of creating it" -// "5: check for entity references to self and other member slice variables" -// "6: mark the variable with RequiredCreationFunction()")); -// } else { auto variableDatum = input.FindDatum(); @@ -4345,26 +4353,30 @@ namespace ScriptCanvas } else { - // we don't support this, yet, but visually we could - // we could support both things, technically...auto-generated inputs, and defaults on the non-connected - // execution thread, or whatever makes possible sense - // \todo send enough information to reveal the data path in the editor - + // This isn't supported visually, yet, but technically, it could be. + // One could connect both latent execution and immediate execution to the same code execution path, + // but only one uses connected output, and the other uses defaults. + // It would require us to change the visualization of the shared path, based on which parent was clicked on in the editor. const auto& targetNode = *execution->GetId().m_node; const auto& targetSlot = input; for (auto sourceNodeAndSlot : nodes) { AddError(nullptr, aznew ScopedDataConnectionEvent - (execution->GetNodeId() + ( execution->GetNodeId() , targetNode , targetSlot , *sourceNodeAndSlot.first , *sourceNodeAndSlot.second)); } + + return; } } + + // Check for known null reads + CheckForKnownNullDereference(execution, execution->GetInput(execution->GetInputCount() - 1), input); } bool AbstractCodeModel::ParseInputThisPointer(ExecutionTreePtr execution) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h index 06854fdbfd..45e289739d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h @@ -207,8 +207,10 @@ namespace ScriptCanvas bool CheckCreateRoot(const Node& node); + void CheckForKnownNullDereference(ExecutionTreeConstPtr parent, const ExecutionInput& input, const Slot& inputSlot); + AZStd::string CheckUniqueInterfaceNames - (AZStd::string_view candidate + ( AZStd::string_view candidate , AZStd::string_view defaultName , AZStd::unordered_set& uniqueNames , const AZStd::unordered_set& nodelingsOut); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index 32b5e5741f..4eafa82331 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -25,6 +25,7 @@ namespace MethodCPP Unnamed2, PluralizeResults, AddedPrettyNameFieldToSerialization, + StoreInputSlotIdsToSupportNullCheck, // add your version above Current, }; @@ -110,6 +111,37 @@ namespace ScriptCanvas { namespace Core { + bool Method::CanAcceptNullInput([[maybe_unused]] const Slot& executionSlot, const Slot& inputSlot) const + { + if (m_method) + { + auto candidateID = inputSlot.GetId(); + auto slotIter = AZStd::find(m_inputSlots.begin(), m_inputSlots.end(), candidateID); + + if (slotIter != m_inputSlots.end()) + { + const size_t index = slotIter - m_inputSlots.begin(); + if (index < m_method->GetNumArguments()) + { + const auto* argument = m_method->GetArgument(index); + if (argument->m_traits & (AZ::BehaviorParameter::TR_REFERENCE | AZ::BehaviorParameter::TR_THIS_PTR)) + { + // references and this pointers cannot accept null input + return false; + } + + if (!(argument->m_traits & AZ::BehaviorParameter::TR_POINTER)) + { + // values cannot accept null input + return false; + } + } + } + } + + return true; + } + const AZ::BehaviorClass* Method::GetClass() const { return m_class; @@ -232,6 +264,11 @@ namespace ScriptCanvas if (addedSlot.IsValid()) { MethodHelper::SetSlotToDefaultValue(*this, addedSlot, config, argIndex); + m_inputSlots.push_back(addedSlot); + } + else + { + AZ_Warning("ScriptCanvas", false, "Failed to add method input slot to Method node: %s-%s", config.m_prettyClassName.c_str(), config.m_method.m_name.c_str()); } } } @@ -520,8 +557,8 @@ namespace ScriptCanvas if (m_method && m_method->HasResult()) { if (branchOnResultMethod.GetNumArguments() == 1 - && branchOnResultMethod.HasResult() - && Data::FromAZType(branchOnResultMethod.GetResult()->m_typeId) == Data::Type::Boolean()) + && branchOnResultMethod.HasResult() + && Data::FromAZType(branchOnResultMethod.GetResult()->m_typeId) == Data::Type::Boolean()) { AZ::Uuid methodResultType = m_method->GetResult()->m_typeId; AZ::Uuid branchOnResultMethodArgType = branchOnResultMethod.GetArgument(0)->m_typeId; @@ -797,6 +834,7 @@ namespace ScriptCanvas ->Field("className", &Method::m_className) ->Field("namespaces", &Method::m_namespaces) ->Field("resultSlotIDs", &Method::m_resultSlotIDs) + ->Field("inputSlots", &Method::m_inputSlots) ->Field("prettyClassName", &Method::m_classNamePretty) ; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h index db34da040c..3dec8e3e72 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h @@ -45,6 +45,8 @@ namespace ScriptCanvas size_t GenerateFingerprint() const override; + bool CanAcceptNullInput(const Slot& executionSlot, const Slot& inputSlot) const override; + bool GetBranchOnResultCheckName(AZStd::string& exposedName, Grammar::LexicalScope& lexicalScope) const; virtual bool GetCheckedOperationInfo(AZ::CheckedOperationInfo& checkedInfo, AZStd::string& exposedName, Grammar::LexicalScope& lexicalScope) const; @@ -149,8 +151,6 @@ namespace ScriptCanvas bool IsExpectingResult() const; - AZ_INLINE AZStd::vector& ModResultSlotIds() { return m_resultSlotIDs; } - virtual void OnInitializeOutputPost(const MethodOutputConfig&) {} virtual void OnInitializeOutputPre(MethodOutputConfig&) {} @@ -176,6 +176,7 @@ namespace ScriptCanvas NamespacePath m_namespaces; const AZ::BehaviorMethod* m_method = nullptr; const AZ::BehaviorClass* m_class = nullptr; + AZStd::vector m_inputSlots; AZStd::vector m_resultSlotIDs; AZStd::recursive_mutex m_mutex; // post-serialization bool m_warnOnMissingFunction = true; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h index 339c0fc3a1..928d1d7202 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h @@ -74,6 +74,7 @@ namespace ScriptCanvas constexpr const char* NotEnoughBranchesForReturn = "Not enough branches for defined out return values."; constexpr const char* NotEnoughInputForArithmeticOperator = "Not enough input for arithmetic operator"; constexpr const char* NullEntityInGraph = "Null entity pointer in graph"; + constexpr const char* NullInputKnown = "The input is known to be null, and the node does not accept it"; constexpr const char* ParseExecutionMultipleOutSyntaxSugarChildExecutionRemovedAndNotReplaced = "ParseExecutionMultipleOutSyntaxSugar: child execution node was removed, and not replaced."; constexpr const char* ParseExecutionMultipleOutSyntaxSugarMismatchOutSize = "ParseExecutionMultipleOutSyntaxSugar: mismatch in connect nodes vs source slots size"; constexpr const char* ParseExecutionMultipleOutSyntaxSugarNonNullChildExecutionFound = "ParseExecutionMultipleOutSyntaxSugar: non null child execution node"; diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas new file mode 100644 index 0000000000..4453617996 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas @@ -0,0 +1,947 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index 107bb32cd6..538dfd2ef0 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -85,6 +85,16 @@ public: } }; +TEST_F(ScriptCanvasTestFixture, VerifySCUnitTestsRun) +{ + EXPECT_FALSE(true); // just convincing myself that these unit tests run on jenkins +} + +TEST_F(ScriptCanvasTestFixture, ParseErrorOnKnownNull) +{ + ExpectParseError("LY_SC_UnitTest_ParseErrorOnKnownNull"); +} + TEST_F(ScriptCanvasTestFixture, UseBehaviorContextClassConstant) { RunUnitTestGraph("LY_SC_UnitTest_UseBehaviorContextClassConstant"); From fcc327e1ed34472739b87733d0722b2feab437f5 Mon Sep 17 00:00:00 2001 From: sharmajs-amzn <82233357+sharmajs-amzn@users.noreply.github.com> Date: Thu, 8 Jul 2021 15:21:31 -0700 Subject: [PATCH 05/37] adding stl assetinfo rule (#1972) Signed-off-by: sharmajs --- Registry/AssetProcessorPlatformConfig.setreg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Registry/AssetProcessorPlatformConfig.setreg b/Registry/AssetProcessorPlatformConfig.setreg index 2147842da7..29c54a50ab 100644 --- a/Registry/AssetProcessorPlatformConfig.setreg +++ b/Registry/AssetProcessorPlatformConfig.setreg @@ -76,7 +76,8 @@ "animsettings": "i_caf", "Animations/SkeletonList.xml": "i_caf", "cbc": "abc", - "fbx.assetinfo": "fbx" + "fbx.assetinfo": "fbx", + "stl.assetinfo": "stl" }, // ---- add any folders to scan here. The priority order is the order they appear here From b1ced46b621ef69f7bb9cdb0667e5b55dc615a08 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 8 Jul 2021 15:36:19 -0700 Subject: [PATCH 06/37] remove deliberate failure test Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index 538dfd2ef0..3946057780 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -85,11 +85,6 @@ public: } }; -TEST_F(ScriptCanvasTestFixture, VerifySCUnitTestsRun) -{ - EXPECT_FALSE(true); // just convincing myself that these unit tests run on jenkins -} - TEST_F(ScriptCanvasTestFixture, ParseErrorOnKnownNull) { ExpectParseError("LY_SC_UnitTest_ParseErrorOnKnownNull"); From 242b4923ae564cc7d829f93caa9c14bc02d74f02 Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Thu, 8 Jul 2021 15:51:53 -0700 Subject: [PATCH 07/37] Remove NewsBuilder project from Editor solution, as it is no longer used. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- Code/Editor/CMakeLists.txt | 1 - Code/Tools/CMakeLists.txt | 1 - Code/Tools/News/CMakeLists.txt | 31 -- Code/Tools/News/NewsBuilder/CMakeLists.txt | 38 -- .../News/NewsBuilder/EndpointManager.cpp | 212 -------- Code/Tools/News/NewsBuilder/EndpointManager.h | 77 --- .../Platform/Android/PAL_android.cmake | 8 - .../Platform/Linux/PAL_linux.cmake | 8 - .../NewsBuilder/Platform/Mac/PAL_mac.cmake | 8 - .../Platform/Windows/PAL_windows.cmake | 8 - .../NewsBuilder/Platform/iOS/PAL_ios.cmake | 8 - .../News/NewsBuilder/Qt/ArticleDetails.cpp | 295 ----------- .../News/NewsBuilder/Qt/ArticleDetails.h | 76 --- .../News/NewsBuilder/Qt/ArticleDetails.ui | 406 -------------- .../Qt/ArticleDetailsContainer.cpp | 88 ---- .../NewsBuilder/Qt/ArticleDetailsContainer.h | 59 --- .../NewsBuilder/Qt/ArticleDetailsContainer.ui | 100 ---- Code/Tools/News/NewsBuilder/Qt/AwsDialog.ui | 102 ---- .../Qt/BuilderArticleViewContainer.cpp | 157 ------ .../Qt/BuilderArticleViewContainer.h | 64 --- .../Qt/BuilderArticleViewContainer.ui | 57 -- .../News/NewsBuilder/Qt/EndpointEntryView.cpp | 58 -- .../News/NewsBuilder/Qt/EndpointEntryView.h | 51 -- .../News/NewsBuilder/Qt/EndpointEntryView.ui | 87 --- .../NewsBuilder/Qt/EndpointManagerView.cpp | 221 -------- .../News/NewsBuilder/Qt/EndpointManagerView.h | 52 -- .../NewsBuilder/Qt/EndpointManagerView.ui | 224 -------- Code/Tools/News/NewsBuilder/Qt/ImageItem.cpp | 54 -- Code/Tools/News/NewsBuilder/Qt/ImageItem.h | 46 -- Code/Tools/News/NewsBuilder/Qt/ImageItem.ui | 65 --- .../News/NewsBuilder/Qt/LogContainer.cpp | 51 -- Code/Tools/News/NewsBuilder/Qt/LogContainer.h | 37 -- .../Tools/News/NewsBuilder/Qt/LogContainer.ui | 131 ----- .../Tools/News/NewsBuilder/Qt/NewsBuilder.cpp | 243 --------- Code/Tools/News/NewsBuilder/Qt/NewsBuilder.h | 73 --- .../Tools/News/NewsBuilder/Qt/Newsbuilder.qrc | 5 - Code/Tools/News/NewsBuilder/Qt/Newsbuilder.ui | 326 ------------ .../News/NewsBuilder/Qt/QCustomMessageBox.cpp | 82 --- .../News/NewsBuilder/Qt/QCustomMessageBox.h | 60 --- .../News/NewsBuilder/Qt/QCustomMessageBox.ui | 84 --- .../Tools/News/NewsBuilder/Qt/SelectImage.cpp | 74 --- Code/Tools/News/NewsBuilder/Qt/SelectImage.h | 46 -- Code/Tools/News/NewsBuilder/Qt/SelectImage.ui | 106 ---- .../BuilderResourceManifest.cpp | 497 ------------------ .../BuilderResourceManifest.h | 125 ----- .../ResourceManagement/DeleteDescriptor.cpp | 39 -- .../ResourceManagement/DeleteDescriptor.h | 29 - .../ResourceManagement/ImageDescriptor.cpp | 50 -- .../ResourceManagement/ImageDescriptor.h | 24 - .../ResourceManagement/UploadDescriptor.cpp | 54 -- .../ResourceManagement/UploadDescriptor.h | 29 - .../NewsBuilder/Resources/NewsBuilder.qss | 44 -- .../NewsBuilder/Resources/missing-image.png | 3 - Code/Tools/News/NewsBuilder/S3Connector.cpp | 173 ------ Code/Tools/News/NewsBuilder/S3Connector.h | 65 --- Code/Tools/News/NewsBuilder/UidGenerator.cpp | 55 -- Code/Tools/News/NewsBuilder/UidGenerator.h | 27 - Code/Tools/News/NewsBuilder/main.cpp | 35 -- Code/Tools/News/NewsBuilder/news_builder.qrc | 5 - .../News/NewsBuilder/news_builder_files.cmake | 64 --- Code/Tools/News/NewsShared/ErrorCodes.h | 51 -- Code/Tools/News/NewsShared/LogType.h | 18 - .../News/NewsShared/Qt/ArticleErrorView.cpp | 23 - .../News/NewsShared/Qt/ArticleErrorView.h | 37 -- .../News/NewsShared/Qt/ArticleErrorView.ui | 239 --------- Code/Tools/News/NewsShared/Qt/ArticleView.cpp | 154 ------ Code/Tools/News/NewsShared/Qt/ArticleView.h | 93 ---- Code/Tools/News/NewsShared/Qt/ArticleView.ui | 244 --------- .../NewsShared/Qt/ArticleViewContainer.cpp | 266 ---------- .../News/NewsShared/Qt/ArticleViewContainer.h | 81 --- .../NewsShared/Qt/ArticleViewContainer.ui | 104 ---- .../News/NewsShared/Qt/KeepInTouchView.cpp | 82 --- .../News/NewsShared/Qt/KeepInTouchView.h | 53 -- .../News/NewsShared/Qt/KeepInTouchView.ui | 423 --------------- Code/Tools/News/NewsShared/Qt/NewsShared.qrc | 10 - .../News/NewsShared/Qt/PinnedArticleView.ui | 260 --------- .../ResourceManagement/ArticleDescriptor.cpp | 81 --- .../ResourceManagement/ArticleDescriptor.h | 51 -- .../ResourceManagement/Descriptor.cpp | 15 - .../ResourceManagement/Descriptor.h | 32 -- .../ResourceManagement/JsonDescriptor.cpp | 20 - .../ResourceManagement/JsonDescriptor.h | 28 - .../ResourceManagement/QtDownloadManager.cpp | 58 -- .../ResourceManagement/QtDownloadManager.h | 57 -- .../ResourceManagement/QtDownloader.cpp | 133 ----- .../ResourceManagement/QtDownloader.h | 66 --- .../ResourceManagement/Resource.cpp | 97 ---- .../NewsShared/ResourceManagement/Resource.h | 68 --- .../ResourceManagement/ResourceManifest.cpp | 349 ------------ .../ResourceManagement/ResourceManifest.h | 134 ----- .../News/NewsShared/Resources/ErrorImage.jpg | 3 - .../Resources/KeepInTouchBanner.jpg | 3 - .../NewsShared/Resources/icon_facebook.png | 3 - .../News/NewsShared/Resources/icon_twitch.png | 3 - .../NewsShared/Resources/icon_twitter.png | 3 - .../NewsShared/Resources/icon_youtube.png | 3 - Code/Tools/News/news_shared_files.cmake | 45 -- 97 files changed, 8688 deletions(-) delete mode 100644 Code/Tools/News/CMakeLists.txt delete mode 100644 Code/Tools/News/NewsBuilder/CMakeLists.txt delete mode 100644 Code/Tools/News/NewsBuilder/EndpointManager.cpp delete mode 100644 Code/Tools/News/NewsBuilder/EndpointManager.h delete mode 100644 Code/Tools/News/NewsBuilder/Platform/Android/PAL_android.cmake delete mode 100644 Code/Tools/News/NewsBuilder/Platform/Linux/PAL_linux.cmake delete mode 100644 Code/Tools/News/NewsBuilder/Platform/Mac/PAL_mac.cmake delete mode 100644 Code/Tools/News/NewsBuilder/Platform/Windows/PAL_windows.cmake delete mode 100644 Code/Tools/News/NewsBuilder/Platform/iOS/PAL_ios.cmake delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ArticleDetails.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ArticleDetails.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ArticleDetails.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/AwsDialog.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ImageItem.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ImageItem.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/ImageItem.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/LogContainer.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/LogContainer.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/LogContainer.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/NewsBuilder.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/NewsBuilder.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/Newsbuilder.qrc delete mode 100644 Code/Tools/News/NewsBuilder/Qt/Newsbuilder.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.ui delete mode 100644 Code/Tools/News/NewsBuilder/Qt/SelectImage.cpp delete mode 100644 Code/Tools/News/NewsBuilder/Qt/SelectImage.h delete mode 100644 Code/Tools/News/NewsBuilder/Qt/SelectImage.ui delete mode 100644 Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.cpp delete mode 100644 Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.h delete mode 100644 Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.cpp delete mode 100644 Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.h delete mode 100644 Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.cpp delete mode 100644 Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.h delete mode 100644 Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.cpp delete mode 100644 Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.h delete mode 100644 Code/Tools/News/NewsBuilder/Resources/NewsBuilder.qss delete mode 100644 Code/Tools/News/NewsBuilder/Resources/missing-image.png delete mode 100644 Code/Tools/News/NewsBuilder/S3Connector.cpp delete mode 100644 Code/Tools/News/NewsBuilder/S3Connector.h delete mode 100644 Code/Tools/News/NewsBuilder/UidGenerator.cpp delete mode 100644 Code/Tools/News/NewsBuilder/UidGenerator.h delete mode 100644 Code/Tools/News/NewsBuilder/main.cpp delete mode 100644 Code/Tools/News/NewsBuilder/news_builder.qrc delete mode 100644 Code/Tools/News/NewsBuilder/news_builder_files.cmake delete mode 100644 Code/Tools/News/NewsShared/ErrorCodes.h delete mode 100644 Code/Tools/News/NewsShared/LogType.h delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleErrorView.cpp delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleErrorView.h delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleErrorView.ui delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleView.cpp delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleView.h delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleView.ui delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleViewContainer.cpp delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleViewContainer.h delete mode 100644 Code/Tools/News/NewsShared/Qt/ArticleViewContainer.ui delete mode 100644 Code/Tools/News/NewsShared/Qt/KeepInTouchView.cpp delete mode 100644 Code/Tools/News/NewsShared/Qt/KeepInTouchView.h delete mode 100644 Code/Tools/News/NewsShared/Qt/KeepInTouchView.ui delete mode 100644 Code/Tools/News/NewsShared/Qt/NewsShared.qrc delete mode 100644 Code/Tools/News/NewsShared/Qt/PinnedArticleView.ui delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.cpp delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.h delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/Descriptor.cpp delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/Descriptor.h delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.cpp delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.h delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.cpp delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.h delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.cpp delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.h delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/Resource.cpp delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/Resource.h delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.cpp delete mode 100644 Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.h delete mode 100644 Code/Tools/News/NewsShared/Resources/ErrorImage.jpg delete mode 100644 Code/Tools/News/NewsShared/Resources/KeepInTouchBanner.jpg delete mode 100644 Code/Tools/News/NewsShared/Resources/icon_facebook.png delete mode 100644 Code/Tools/News/NewsShared/Resources/icon_twitch.png delete mode 100644 Code/Tools/News/NewsShared/Resources/icon_twitter.png delete mode 100644 Code/Tools/News/NewsShared/Resources/icon_youtube.png delete mode 100644 Code/Tools/News/news_shared_files.cmake diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt index 8a5f35fb92..5a846a267a 100644 --- a/Code/Editor/CMakeLists.txt +++ b/Code/Editor/CMakeLists.txt @@ -111,7 +111,6 @@ ly_add_target( AZ::AzCore AZ::AzToolsFramework Gem::LmbrCentral.Static - Legacy::NewsShared AZ::AWSNativeSDKInit AZ::AtomCore Gem::Atom_RPI.Edit diff --git a/Code/Tools/CMakeLists.txt b/Code/Tools/CMakeLists.txt index 6c025a0543..1bab1cee77 100644 --- a/Code/Tools/CMakeLists.txt +++ b/Code/Tools/CMakeLists.txt @@ -10,7 +10,6 @@ add_subdirectory(AssetProcessor) add_subdirectory(AWSNativeSDKInit) add_subdirectory(AzTestRunner) add_subdirectory(CrashHandler) -add_subdirectory(News) add_subdirectory(PythonBindingsExample) add_subdirectory(RemoteConsole) add_subdirectory(DeltaCataloger) diff --git a/Code/Tools/News/CMakeLists.txt b/Code/Tools/News/CMakeLists.txt deleted file mode 100644 index 78c5774ef0..0000000000 --- a/Code/Tools/News/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -add_subdirectory(NewsBuilder) - -if (NOT PAL_TRAIT_BUILD_HOST_TOOLS) - return() -endif() - -ly_add_target( - NAME NewsShared STATIC - NAMESPACE Legacy - AUTOMOC - AUTOUIC - AUTORCC - FILES_CMAKE - news_shared_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Core - 3rdParty::Qt::Network - 3rdParty::Qt::Widgets - AZ::AzQtComponents -) diff --git a/Code/Tools/News/NewsBuilder/CMakeLists.txt b/Code/Tools/News/NewsBuilder/CMakeLists.txt deleted file mode 100644 index 218f4e28f5..0000000000 --- a/Code/Tools/News/NewsBuilder/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - -include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) - -if (NOT PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED OR NOT PAL_TRAIT_BUILD_HOST_TOOLS) - return() -endif() - -ly_add_target( - NAME NewsBuilder EXECUTABLE - NAMESPACE Legacy - AUTOMOC - AUTOUIC - AUTORCC - FILES_CMAKE - news_builder_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Core - 3rdParty::Qt::Widgets - 3rdParty::AWSNativeSDK::Dependencies - 3rdParty::AWSNativeSDK::Core - 3rdParty::AWSNativeSDK::S3 - Legacy::NewsShared - AZ::AzCore - AZ::AzQtComponents - AZ::AzFramework -) diff --git a/Code/Tools/News/NewsBuilder/EndpointManager.cpp b/Code/Tools/News/NewsBuilder/EndpointManager.cpp deleted file mode 100644 index 0b2ea4dd5c..0000000000 --- a/Code/Tools/News/NewsBuilder/EndpointManager.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "EndpointManager.h" -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace News -{ - - Endpoint::Endpoint(QString name, QString awsProfile, QString url, QString bucket) - : m_name(name) - , m_awsProfile(awsProfile) - , m_url(url) - , m_bucket(bucket) - {} - - Endpoint::Endpoint(const QJsonObject& json) - : Endpoint(json["name"].toString(), - json["awsProfile"].toString(), - json["url"].toString(), - json["bucket"].toString()) - { - } - - Endpoint::~Endpoint() {} - - void Endpoint::Write(QJsonObject& json) const - { - json["name"] = m_name; - json["awsProfile"] = m_awsProfile; - json["url"] = m_url; - json["bucket"] = m_bucket; - } - - QString Endpoint::GetName() const - { - return m_name; - } - - void Endpoint::SetName(const QString& name) - { - m_name = QString(name); - } - - QString Endpoint::GetAwsProfile() const - { - return m_awsProfile; - } - - void Endpoint::SetAwsProfile(const QString& awsProfile) - { - m_awsProfile = QString(awsProfile); - } - - QString Endpoint::GetUrl() const - { - return m_url; - } - - void Endpoint::SetUrl(const QString& url) - { - m_url = QString(url); - } - - QString Endpoint::GetBucket() const - { - return m_bucket; - } - - void Endpoint::SetBucket(const QString& bucket) - { - m_bucket = bucket; - } - - EndpointManager::EndpointManager() - { - Load(); - } - - EndpointManager::~EndpointManager() - { - ClearEndpoints(); - } - - void EndpointManager::Load() - { - ClearEndpoints(); - QFile file("newsBuilderConfig.txt"); - if (file.open(QIODevice::ReadOnly)) - { - QTextStream in(&file); - QString str = in.readAll().trimmed(); - QByteArray array(str.toStdString().c_str()); - QJsonDocument doc(QJsonDocument::fromJson(array)); - QJsonObject json = doc.object(); - QJsonArray endpointArray = json["endpoints"].toArray(); - for (auto endpointDoc : endpointArray) - { - m_endpoints.append(new Endpoint(endpointDoc.toObject())); - } - int endpointIndex = json["currentEndpointIndex"].toInt(); - if (endpointIndex >= 0 && m_endpoints.count() > endpointIndex) - { - m_selectedEndpoint = m_endpoints[endpointIndex]; - } - else - { - m_selectedEndpoint = nullptr; - } - file.close(); - - SaveUrl(); - } - } - - void EndpointManager::Save() - { - QFile file("newsBuilderConfig.txt"); - if (file.open(QIODevice::WriteOnly)) - { - QJsonObject json; - QJsonArray endpointArray; - for (auto endpoint : m_endpoints) - { - QJsonObject endpointObject; - endpoint->Write(endpointObject); - endpointArray.append(endpointObject); - } - json["endpoints"] = endpointArray; - json["currentEndpointIndex"] = m_endpoints.indexOf(m_selectedEndpoint); - QTextStream out(&file); - QJsonDocument doc(json); - out << doc.toJson(QJsonDocument::Compact); - file.close(); - - SaveUrl(); - } - } - - void EndpointManager::SelectEndpoint(Endpoint* endpoint) - { - m_selectedEndpoint = endpoint; - } - - void EndpointManager::AddEndpoint(Endpoint* endpoint) - { - m_endpoints.append(endpoint); - } - - void EndpointManager::RemoveEndpoint(Endpoint* endpoint) - { - if (endpoint == m_selectedEndpoint) - { - m_selectedEndpoint = nullptr; - } - m_endpoints.removeAll(endpoint); - delete endpoint; - } - - Endpoint* EndpointManager::GetSelectedEndpoint() const - { - return m_selectedEndpoint; - } - - QList::const_iterator EndpointManager::begin() const - { - return m_endpoints.begin(); - } - - QList::const_iterator EndpointManager::end() const - { - return m_endpoints.end(); - } - - void EndpointManager::ClearEndpoints() - { - for (auto endpoint : m_endpoints) - { - delete endpoint; - } - m_endpoints.clear(); - } - - void EndpointManager::SaveUrl() const - { - if (!m_selectedEndpoint) - { - return; - } - // Editor looks for config file in /dev folder, so this file is placed in parent directory - QFile file(QCoreApplication::applicationDirPath() + "/newsConfig.txt"); - if (file.open(QIODevice::WriteOnly)) - { - QTextStream out(&file); - out << m_selectedEndpoint->GetUrl(); - file.close(); - } - } - -} diff --git a/Code/Tools/News/NewsBuilder/EndpointManager.h b/Code/Tools/News/NewsBuilder/EndpointManager.h deleted file mode 100644 index cc44951d16..0000000000 --- a/Code/Tools/News/NewsBuilder/EndpointManager.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -class QJsonObject; - -namespace News -{ - //! Endpoint represents a location of news data - class Endpoint - { - public: - Endpoint(QString name, QString awsProfile, QString url, QString bucket); - explicit Endpoint(const QJsonObject& json); - ~Endpoint(); - - void Write(QJsonObject& json) const; - - QString GetName() const; - void SetName(const QString& name); - - QString GetAwsProfile() const; - void SetAwsProfile(const QString& awsProfile); - - QString GetUrl() const; - void SetUrl(const QString& url); - - QString GetBucket() const; - void SetBucket(const QString& bucket); - - private: - //! name of endpoint to distinguish with others - QString m_name; - //! name of aws credentials file - QString m_awsProfile; - //! url location of news data (e.g. cloudfront url) - QString m_url; - //! name of s3 bucket where news data resides - QString m_bucket; - }; - - //! EndpointManager handles endpoint collection - class EndpointManager - { - public: - EndpointManager(); - ~EndpointManager(); - - //! Load endpoints file - void Load(); - //! Save endpoints file - void Save(); - void SelectEndpoint(Endpoint* endpoint); - void AddEndpoint(Endpoint* endpoint); - void RemoveEndpoint(Endpoint* endpoint); - Endpoint* GetSelectedEndpoint() const; - - QList::const_iterator begin() const; - QList::const_iterator end() const; - - private: - QList m_endpoints; - Endpoint* m_selectedEndpoint = nullptr; - - void ClearEndpoints(); - //! Saves news config file which is used by LY Editor to determine news location - void SaveUrl() const; - }; -} diff --git a/Code/Tools/News/NewsBuilder/Platform/Android/PAL_android.cmake b/Code/Tools/News/NewsBuilder/Platform/Android/PAL_android.cmake deleted file mode 100644 index 929d864fc4..0000000000 --- a/Code/Tools/News/NewsBuilder/Platform/Android/PAL_android.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE) diff --git a/Code/Tools/News/NewsBuilder/Platform/Linux/PAL_linux.cmake b/Code/Tools/News/NewsBuilder/Platform/Linux/PAL_linux.cmake deleted file mode 100644 index 929d864fc4..0000000000 --- a/Code/Tools/News/NewsBuilder/Platform/Linux/PAL_linux.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE) diff --git a/Code/Tools/News/NewsBuilder/Platform/Mac/PAL_mac.cmake b/Code/Tools/News/NewsBuilder/Platform/Mac/PAL_mac.cmake deleted file mode 100644 index 929d864fc4..0000000000 --- a/Code/Tools/News/NewsBuilder/Platform/Mac/PAL_mac.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE) diff --git a/Code/Tools/News/NewsBuilder/Platform/Windows/PAL_windows.cmake b/Code/Tools/News/NewsBuilder/Platform/Windows/PAL_windows.cmake deleted file mode 100644 index 180b7b9492..0000000000 --- a/Code/Tools/News/NewsBuilder/Platform/Windows/PAL_windows.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED TRUE) diff --git a/Code/Tools/News/NewsBuilder/Platform/iOS/PAL_ios.cmake b/Code/Tools/News/NewsBuilder/Platform/iOS/PAL_ios.cmake deleted file mode 100644 index 929d864fc4..0000000000 --- a/Code/Tools/News/NewsBuilder/Platform/iOS/PAL_ios.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE) diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.cpp b/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.cpp deleted file mode 100644 index 2872a714e8..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleDetails.h" -#include "SelectImage.h" -#include -#include "ResourceManagement/BuilderResourceManifest.h" -#include "ResourceManagement/ImageDescriptor.h" -#include "NewsShared/ErrorCodes.h" - -#include - -#include -#include -#include -#include - -#include "Qt/ui_ArticleDetails.h" - -namespace News -{ - - ArticleDetails::ArticleDetails(QWidget* parent, - Resource& resource, - BuilderResourceManifest& manifest) - : QWidget(parent) - , m_ui(new Ui::ArticleDetailsWidget) - , m_filename("") - , m_article(resource) - , m_manifest(manifest) - , m_imageIdOriginal("") - , m_imageId("") - { - m_ui->setupUi(this); - m_ui->uidLabel->setText(QString("Article: %1").arg(m_article.GetResource().GetId())); - - resizePreviewImage(); - - //! try to load image icon - auto pImageResource = m_manifest.FindById(m_article.GetImageId()); - if (pImageResource) - { - m_imageIdOriginal = pImageResource->GetId(); - SetImage(*pImageResource); - } - else - { - SetNoImage(); - } - - m_ui->titleText->setText(m_article.GetTitle()); - m_ui->descriptionText->setPlainText(m_article.GetBody()); - - connect(m_ui->fromFileButton, &QPushButton::clicked, this, &ArticleDetails::OpenImageFromFile); - connect(m_ui->fromResourceButton, &QPushButton::clicked, this, &ArticleDetails::OpenImageFromResource); - connect(m_ui->clearImageButton, &QPushButton::clicked, this, &ArticleDetails::ClearImage); - connect(m_ui->updateButton, &QPushButton::clicked, this, &ArticleDetails::UpdateArticle); - connect(m_ui->deleteButton, &QPushButton::clicked, this, &ArticleDetails::DeleteArticle); - connect(m_ui->cancelButton, &QPushButton::clicked, this, &ArticleDetails::Close); - connect(m_ui->upButton, &QPushButton::clicked, this, &ArticleDetails::MoveUp); - connect(m_ui->downButton, &QPushButton::clicked, this, &ArticleDetails::MoveDown); - } - - ArticleDetails::~ArticleDetails() {} - - void ArticleDetails::resizeEvent(QResizeEvent *event) - { - QWidget::resizeEvent(event); - resizePreviewImage(); - } - - void ArticleDetails::resizePreviewImage() - { - // Resize the imagePreview to keep the proportions - int newHeight = aznumeric_cast(m_imageRatio * width()); - m_ui->imagePreview->setFixedHeight(newHeight); - } - - ArticleDescriptor& ArticleDetails::GetArticle() - { - return m_article; - } - - QString ArticleDetails::GetId() const - { - return m_article.GetResource().GetId(); - } - - void ArticleDetails::OpenImageFromFile() - { - m_filename = QFileDialog::getOpenFileName(this, - "Open Image", ".", "Image Files (*.png *.jpg *.bmp)"); - SetImage(m_filename); - } - - void ArticleDetails::OpenImageFromResource() - { - m_pSelectImage = new SelectImage(m_manifest); - if (m_pSelectImage->exec() == QDialog::DialogCode::Accepted) - { - auto pSelectedResource = m_pSelectImage->GetSelected(); - if (!pSelectedResource) - { - QMessageBox msgBox(QMessageBox::Critical, - "Error", - "No resource pSelectedResource", - QMessageBox::Ok, - this); - msgBox.exec(); - return; - } - SetImage(*pSelectedResource); - } - delete m_pSelectImage; - } - - //! once the Update button is clicked, article resource is updated in this function - void ArticleDetails::UpdateArticle() - { - //! this flag remains false if no new changes are detected, thus avoiding unnecessary - //! re-uploading unchanged resources - bool updated = false; - - m_imageId = LoadImage(); - if (m_imageId.compare(m_imageIdOriginal) != 0) - { - m_article.SetImageId(m_imageId); - m_filename = ""; - m_imageIdOriginal = m_imageId; - m_ui->imagePathLabel->setText(QString("Image: %1").arg(m_imageId)); - updated = true; - } - - QString newTitle = m_ui->titleText->text(); - if (m_article.GetTitle().compare(newTitle)) - { - m_article.SetTitle(newTitle); - updated = true; - } - QString newBody = m_ui->descriptionText->toPlainText(); - if (m_article.GetBody().compare(newBody) != 0) - { - m_article.SetBody(newBody); - updated = true; - } - - QString newStyle = m_ui->articleStyleButtonGroup->checkedButton()->property("style").toString(); - if (m_article.GetArticleStyle() != newStyle) - { - m_article.SetArticleStyle(newStyle); - updated = true; - } - - if (updated) - { - m_article.Update(); - m_manifest.UpdateResource(&m_article.GetResource()); - emit logSignal(QString("Article %1 updated") - .arg(m_article.GetResource().GetId()), LogOk); - } - else - { - emit logSignal("Nothing to update", LogWarning); - } - emit updateArticleSignal(); - } - - //! try to load an image either from filename or from another resource, - //! update resource manifest accordingly - QString ArticleDetails::LoadImage() const - { - if (!m_filename.isEmpty()) - { - if (!m_imageIdOriginal.isEmpty()) - { - m_manifest.FreeResource(m_imageIdOriginal); - } - auto pResource = m_manifest.AddImage(m_filename); - if (pResource) - { - return pResource->GetId(); - } - return ""; - } - - if (m_imageId.compare(m_imageIdOriginal) != 0) - { - if (!m_imageIdOriginal.isEmpty()) - { - m_manifest.FreeResource(m_imageIdOriginal); - } - if (!m_imageId.isEmpty()) - { - m_manifest.UseResource(m_imageId); - } - return m_imageId; - } - - return m_imageIdOriginal; - } - - void ArticleDetails::SetImage(Resource& resource) - { - m_ui->imagePathLabel->setText(QString("Image: %1").arg(resource.GetId())); - - QPixmap pixmap; - if (pixmap.loadFromData(resource.GetData())) - { - m_ui->imagePreview->setPixmap(pixmap); - m_imageId = resource.GetId(); - } - else - { - SetNoImage(); - emit logSignal(QString("Failed to load image: %1.").arg(m_imageId)); - } - } - - void ArticleDetails::SetImage([[maybe_unused]] QString& filename) - { - m_ui->imagePathLabel->setText(QString("Image: %1").arg(m_filename)); - - QPixmap pixmap; - if (pixmap.load(m_filename)) - { - m_ui->imagePreview->setPixmap(pixmap); - } - else - { - SetNoImage(); - emit logSignal(QString("Failed to load image: %1.").arg(m_filename)); - } - } - - void ArticleDetails::SetNoImage() const - { - m_ui->imagePreview->setPixmap(QPixmap(":/images/Resources/missing-image.png")); - m_ui->imagePathLabel->setText("no image"); - } - - void ArticleDetails::ClearImage() - { - m_imageId = ""; - m_filename = ""; - SetNoImage(); - } - - void ArticleDetails::DeleteArticle() - { - if (!m_article.GetImageId().isEmpty()) - { - m_manifest.FreeResource(m_article.GetImageId()); - } - m_manifest.FreeResource(m_article.GetResource().GetId()); - emit deleteArticleSignal(); - } - - void ArticleDetails::Close() - { - emit closeArticleSignal(); - } - - void ArticleDetails::MoveUp() - { - ErrorCode error; - if (!m_manifest.UpdateArticleOrder(m_article.GetResource().GetId(), 1, error)) - { - emit logSignal(GetErrorMessage(error)); - } - else - { - emit orderChangedSignal(m_article.GetResource().GetId(), 1); - } - } - - void ArticleDetails::MoveDown() - { - ErrorCode error; - if (!m_manifest.UpdateArticleOrder(m_article.GetResource().GetId(), 0, error)) - { - emit logSignal(GetErrorMessage(error)); - } - else - { - emit orderChangedSignal(m_article.GetResource().GetId(), 0); - } - } - -#include "Qt/moc_ArticleDetails.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.h b/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.h deleted file mode 100644 index 7f8d482e3f..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - - -#if !defined(Q_MOC_RUN) -#include -#include "ResourceManagement/BuilderResourceManifest.h" - -#include -#endif - -namespace Ui -{ - class ArticleDetailsWidget; -} - -namespace News { - class SelectImage; - class ResourceManifest; - class Resource; - - //! Control that allows to modify all parameters of a single article - class ArticleDetails - : public QWidget - { - Q_OBJECT - - public: - ArticleDetails(QWidget* parent, - Resource& resource, - BuilderResourceManifest& manifest); - ~ArticleDetails(); - ArticleDescriptor& GetArticle(); - QString GetId() const; - - Q_SIGNALS: - void logSignal(QString text, LogType logType = LogInfo); - void deleteArticleSignal(); - void updateArticleSignal(); - void closeArticleSignal(); - void orderChangedSignal(QString id, bool direction); - - private: - QScopedPointer m_ui; - QString m_filename; - ArticleDescriptor m_article; - BuilderResourceManifest& m_manifest; - SelectImage* m_pSelectImage; - QString m_imageIdOriginal; - QString m_imageId; - float m_imageRatio = 184.0f / 430.0f; - - void resizeEvent(QResizeEvent *event) override; - void resizePreviewImage(); - - void OpenImageFromFile(); - void OpenImageFromResource(); - QString LoadImage() const; - void SetImage(Resource& resource); - void SetImage(QString& filename); - void SetNoImage() const; - void ClearImage(); - - void UpdateArticle(); - void DeleteArticle(); - void Close(); - void MoveUp(); - void MoveDown(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.ui b/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.ui deleted file mode 100644 index 92970f1130..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetails.ui +++ /dev/null @@ -1,406 +0,0 @@ - - - ArticleDetailsWidget - - - - 0 - 0 - 250 - 420 - - - - - 0 - 0 - - - - - 100 - 420 - - - - - 640 - 16777215 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 100 - 100 - - - - - 16777215 - 16777215 - - - - - - - :/images/Resources/missing-image.png - - - false - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - 100 - 100 - - - - - - - - - 16777215 - 140 - - - - - 0 - - - - - Image: - - - true - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 16777215 - 16777215 - - - - Clear - - - - - - - - 16777215 - 16777215 - - - - Library... - - - - - - - - 16777215 - 16777215 - - - - Load... - - - - - - - - - - - - - - - - 1280 - 1280 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 16777215 - 20 - - - - Article: 0 - - - - - - - 0 - - - 0 - - - 3 - - - 0 - - - 3 - - - - - Default Style - - - true - - - default - - - articleStyleButtonGroup - - - - - - - Pinned Style - - - pinned - - - articleStyleButtonGroup - - - - - - - - - Title: - - - - - - - true - - - - - - - - - - 0 - - - - - Description: - - - - - - - - - - 0 - - - - - 0 - - - - - Delete - - - - - - - Cancel - - - - - - - Save - - - - - - - - - 0 - - - - - - 16777215 - 16777215 - - - - Move Up - - - - - - - - 16777215 - 16777215 - - - - Move Down - - - - - - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - - - - - - -
diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.cpp b/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.cpp deleted file mode 100644 index 586978a562..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleDetailsContainer.h" -#include "ResourceManagement/BuilderResourceManifest.h" -#include "ArticleDetails.h" -#include "Qt/ui_ArticleDetailsContainer.h" - -namespace News -{ - - ArticleDetailsContainer::ArticleDetailsContainer( - QWidget* parent, - BuilderResourceManifest& manifest) - : QWidget(parent) - , m_ui(new Ui::ArticleDetailsContainerWidget) - , m_manifest(manifest) - , m_articleDetails(nullptr) - { - m_ui->setupUi(this); - } - - ArticleDetailsContainer::~ArticleDetailsContainer() {} - - //! When article is selected, old articleDetails control is removed, new one is created - void ArticleDetailsContainer::SelectArticle(const QString& id) - { - closeArticleSlot(); - - if (!id.isEmpty()) - { - auto article = m_manifest.FindById(id); - if (article) - { - m_articleDetails = new ArticleDetails( - m_ui->scrollAreaWidgetContents, - *article, - m_manifest); - m_ui->scrollAreaWidgetContents->layout()->addWidget(m_articleDetails); - connect(m_articleDetails, &ArticleDetails::updateArticleSignal, - this, &ArticleDetailsContainer::updateArticleSlot); - connect(m_articleDetails, &ArticleDetails::deleteArticleSignal, - this, &ArticleDetailsContainer::deleteArticleSlot); - connect(m_articleDetails, &ArticleDetails::closeArticleSignal, - this, &ArticleDetailsContainer::closeArticleSlot); - connect(m_articleDetails, SIGNAL(logSignal(QString, LogType)), - this, SIGNAL(logSignal(QString, LogType))); - connect(m_articleDetails, SIGNAL(orderChangedSignal(QString, bool)), - this, SIGNAL(orderChangedSignal(QString, bool))); - m_selectedId = id; - } - } - } - - void ArticleDetailsContainer::Reset() - { - SelectArticle(m_selectedId); - } - - void ArticleDetailsContainer::updateArticleSlot() - { - emit updateArticleSignal(m_articleDetails->GetId()); - } - - void ArticleDetailsContainer::deleteArticleSlot() - { - emit deleteArticleSignal(m_articleDetails->GetId()); - closeArticleSlot(); - } - - void ArticleDetailsContainer::closeArticleSlot() - { - if (m_articleDetails) - { - emit closeArticleSignal(m_selectedId); - delete m_articleDetails; - m_articleDetails = nullptr; - m_selectedId = ""; - } - } - -#include "Qt/moc_ArticleDetailsContainer.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.h b/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.h deleted file mode 100644 index 1df42198c3..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#endif - -namespace Ui -{ - class ArticleDetailsContainerWidget; -} - -namespace News -{ - class ArticleDetails; - class BuilderResourceManifest; - class SelectImage; - class ResourceManifest; - class Resource; - - //! Control that manages articleDetails control - class ArticleDetailsContainer - : public QWidget - { - Q_OBJECT - - public: - ArticleDetailsContainer(QWidget* parent, BuilderResourceManifest& manifest); - ~ArticleDetailsContainer(); - - void SelectArticle(const QString& id); - void Reset(); - -Q_SIGNALS: - void logSignal(QString text, LogType logType = LogInfo); - void updateArticleSignal(QString id); - void deleteArticleSignal(QString id); - void closeArticleSignal(QString id); - void orderChangedSignal(QString id, bool direction); - - private: - QScopedPointer m_ui; - BuilderResourceManifest& m_manifest; - ArticleDetails* m_articleDetails = nullptr; - QString m_selectedId; - - private Q_SLOTS: - void updateArticleSlot(); - void deleteArticleSlot(); - void closeArticleSlot(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.ui b/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.ui deleted file mode 100644 index 7652fa114d..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ArticleDetailsContainer.ui +++ /dev/null @@ -1,100 +0,0 @@ - - - ArticleDetailsContainerWidget - - - - 0 - 0 - 250 - 386 - - - - - 0 - 0 - - - - - 250 - 0 - - - - - 640 - 16777215 - - - - ArticleDetailsContainer - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Qt::ScrollBarAlwaysOff - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - 0 - 0 - 248 - 384 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/AwsDialog.ui b/Code/Tools/News/NewsBuilder/Qt/AwsDialog.ui deleted file mode 100644 index f58243ed8d..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/AwsDialog.ui +++ /dev/null @@ -1,102 +0,0 @@ - - - Dialog - - - - 0 - 0 - 176 - 137 - - - - - 0 - 0 - - - - Dialog - - - - - - - - - - AWS Key Id: - - - - - - - - - - - - - - AWS Secret Key: - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - Dialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.cpp b/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.cpp deleted file mode 100644 index bf77a89895..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "BuilderArticleViewContainer.h" -#include "ResourceManagement/BuilderResourceManifest.h" -#include "ArticleDetails.h" -#include -#include -#include -#include "Qt/ui_BuilderArticleViewContainer.h" - -#include - -#include "QCustomMessageBox.h" - -namespace News -{ - - BuilderArticleViewContainer::BuilderArticleViewContainer( - QWidget* parent, - BuilderResourceManifest& manifest) - : QWidget(parent) - , m_ui(new Ui::BuilderArticleViewContainerWidget) - , m_container(new ArticleViewContainer(this, manifest)) - , m_manifest(manifest) - { - m_ui->setupUi(this); - - m_ui->ArticleViewContainerRoot->layout()->addWidget(m_container); - connect(m_container, SIGNAL(articleSelectedSignal(QString)), - this, SLOT(articleSelectedSlot(QString))); - } - - BuilderArticleViewContainer::~BuilderArticleViewContainer(){} - - void BuilderArticleViewContainer::AddArticle() - { - auto pArticleResource = static_cast(m_manifest).AddArticle(); - if (pArticleResource) - { - m_container->AddArticleView(ArticleDescriptor(*pArticleResource)); - SelectArticle(pArticleResource->GetId()); - } - } - - void BuilderArticleViewContainer::SelectArticle(QString id) - { - if (m_selectedArticleId.compare(id) == 0) - { - return; - } - - UnselectArticle(); - m_selectedArticleId = id; - auto article = m_container->FindById(id); - if (article) - { - m_container->ScrollToView(article); - emit articleSelectedSignal(id); - - // Add class and refresh style - AzQtComponents::Style::addClass(article, m_selectedArticleClass); - article->style()->unpolish(qApp); - article->style()->polish(qApp); - } - } - - void BuilderArticleViewContainer::Sync() - { - emit logSignal("Starting sync"); - - m_manifest.Sync(); - } - - void BuilderArticleViewContainer::UpdateArticle(QString& id) const - { - auto view = m_container->FindById(id); - if (view) - { - view->Update(); - m_container->ForceRefreshArticleView(view); - } - } - - void BuilderArticleViewContainer::DeleteArticle(QString& id) const - { - auto view = m_container->FindById(id); - if (view) - { - m_container->DeleteArticleView(view); - } - } - - //possibly support multiple selection in future? - void BuilderArticleViewContainer::CloseArticle(QString& id) - { - if (m_selectedArticleId == id) - { - UnselectArticle(); - } - } - - void BuilderArticleViewContainer::UpdateArticleOrder(QString& id, bool direction) const - { - auto view = m_container->FindById(id); - if (view) - { - m_container->UpdateArticleOrder(view, direction); - } - } - - void BuilderArticleViewContainer::PopulateArticles() - { - m_container->PopulateArticles(); - - if (!m_selectedArticleId.isEmpty()) - { - SelectArticle(m_selectedArticleId); - } - } - - void BuilderArticleViewContainer::AddErrorMessage() const - { - m_container->AddErrorMessage(); - } - - void BuilderArticleViewContainer::UnselectArticle() - { - if (m_selectedArticleId.isEmpty()) - { - return; - } - auto article = m_container->FindById(m_selectedArticleId); - - // Remove class and refresh style - if (article) - { - AzQtComponents::Style::removeClass(article, m_selectedArticleClass); - article->style()->unpolish(qApp); - article->style()->polish(qApp); - } - - m_selectedArticleId = ""; - } - - void BuilderArticleViewContainer::articleSelectedSlot(QString id) - { - SelectArticle(id); - } - -#include "Qt/moc_BuilderArticleViewContainer.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.h b/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.h deleted file mode 100644 index 94712ca768..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#endif - -namespace Ui -{ - class BuilderArticleViewContainerWidget; -} - -namespace News -{ - class ArticleViewContainer; - class BuilderResourceManifest; - - //! BuilderArticleViewContainer is a Builder container for ArticleViewContainer. - /*! - It is a wrapper with additional builder functionality for displaying articles - */ - class BuilderArticleViewContainer - : public QWidget - { - Q_OBJECT - public: - BuilderArticleViewContainer(QWidget* parent, BuilderResourceManifest& manifest); - ~BuilderArticleViewContainer(); - - void UpdateArticle(QString& id) const; - void DeleteArticle(QString& id) const; - void CloseArticle(QString& id); - void UpdateArticleOrder(QString& id, bool direction) const; - void PopulateArticles(); - void AddErrorMessage() const; - void AddArticle(); - -Q_SIGNALS: - void logSignal(QString text, LogType logType = LogInfo); - void articleSelectedSignal(QString id); - - private: - QScopedPointer m_ui; - ArticleViewContainer* m_container; - QString m_selectedArticleId; - QString m_selectedArticleClass = "SelectedArticle"; - BuilderResourceManifest& m_manifest; - - void Sync(); - void SelectArticle(QString id); - void UnselectArticle(); - - - private Q_SLOTS: - void articleSelectedSlot(QString id); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.ui b/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.ui deleted file mode 100644 index dafac9b9ff..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/BuilderArticleViewContainer.ui +++ /dev/null @@ -1,57 +0,0 @@ - - - BuilderArticleViewContainerWidget - - - - 0 - 0 - 250 - 500 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.cpp b/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.cpp deleted file mode 100644 index 5e698eea97..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "EndpointEntryView.h" -#include "Qt/ui_EndpointEntryView.h" -#include -#include - -namespace News -{ - - const char* EndpointEntryView::SELECTED_CSS = - "background-color: rgb(60, 100, 60);\ncolor: white;"; - const char* EndpointEntryView::UNSELECTED_CSS = - "background-color: rgb(60, 60, 60);\ncolor: white;"; - - EndpointEntryView::EndpointEntryView(QWidget* parent, Endpoint* pEndpoint) - : QWidget(parent) - , m_ui(new Ui::EndpointEntryViewWidget) - , m_pEndpoint(pEndpoint) - { - m_ui->setupUi(this); - - m_ui->labelName->setText(pEndpoint->GetName()); - - connect(m_ui->labelName, &AzQtComponents::ExtendedLabel::clicked, this, &EndpointEntryView::selectSlot); - connect(m_ui->buttonDelete, &QToolButton::clicked, this, &EndpointEntryView::deleteSlot); - } - - EndpointEntryView::~EndpointEntryView() {} - - void EndpointEntryView::SetSelected(bool selected) - { - setStyleSheet(selected ? SELECTED_CSS : UNSELECTED_CSS); - } - - Endpoint* EndpointEntryView::GetEndpoint() const - { - return m_pEndpoint; - } - - void EndpointEntryView::selectSlot() - { - emit selectSignal(this); - } - - void EndpointEntryView::deleteSlot() - { - emit deleteSignal(this); - } - -#include "Qt/moc_EndpointEntryView.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.h b/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.h deleted file mode 100644 index c8b014c167..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class EndpointEntryViewWidget; -} - -namespace News -{ - class Endpoint; - - //! Qt widget representing a single endpoint entry - class EndpointEntryView - : public QWidget - { - Q_OBJECT - public: - EndpointEntryView(QWidget* parent, Endpoint* pEndpoint); - ~EndpointEntryView(); - - void SetSelected(bool selected); - - Endpoint* GetEndpoint() const; - - Q_SIGNALS: - void selectSignal(EndpointEntryView* pEndpointView); - void deleteSignal(EndpointEntryView* pEndpointView); - - private: - static const char* SELECTED_CSS; - static const char* UNSELECTED_CSS; - - QScopedPointer m_ui; - Endpoint* m_pEndpoint = nullptr; - - private Q_SLOTS: - void selectSlot(); - void deleteSlot(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.ui b/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.ui deleted file mode 100644 index 309fcd5662..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointEntryView.ui +++ /dev/null @@ -1,87 +0,0 @@ - - - EndpointEntryViewWidget - - - - 0 - 0 - 356 - 23 - - - - - 0 - 23 - - - - - 16777215 - 23 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - TextLabel - - - Qt::AlignCenter - - - - - - - - 25 - 0 - - - - - 25 - 16777215 - - - - background-color: red; - - - X - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - -
diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.cpp b/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.cpp deleted file mode 100644 index e28245b895..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "EndpointManagerView.h" -#include "EndpointManager.h" -#include "EndpointEntryView.h" -#include "Qt/ui_EndpointManagerView.h" -#include "Qt/QCustomMessageBox.h" -#include "ResourceManagement/BuilderResourceManifest.h" - -#include - -namespace News -{ - - EndpointManagerView::EndpointManagerView(QWidget* parent, - BuilderResourceManifest& manifest) - : QDialog(parent) - , m_ui(new Ui::EndpointManagerViewWidget) - , m_pManager(manifest.GetEndpointManager()) - , m_manifest(manifest) - { - m_ui->setupUi(this); - - for (auto endpoint : *m_pManager) - { - auto endpointView = AddEndpointEntry(endpoint); - if (m_pManager->GetSelectedEndpoint() == endpoint) - { - selectEndpointSlot(endpointView); - } - } - - connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - connect(m_ui->buttonAdd, &QPushButton::clicked, this, &EndpointManagerView::addEndpointSlot); - } - - EndpointManagerView::~EndpointManagerView() {} - - EndpointEntryView* EndpointManagerView::AddEndpointEntry(Endpoint* pEndpoint) - { - auto endpointView = new EndpointEntryView(m_ui->endpointListContents, pEndpoint); - auto layout = static_cast(m_ui->endpointListContents->layout()); - layout->insertWidget(layout->count() - 2, endpointView); - m_endpoints.append(endpointView); - connect(endpointView, SIGNAL(selectSignal(EndpointEntryView*)), - this, SLOT(selectEndpointSlot(EndpointEntryView*))); - connect(endpointView, SIGNAL(deleteSignal(EndpointEntryView*)), - this, SLOT(deleteEndpointSlot(EndpointEntryView*))); - // this lets us modify newly-added widget in the same function - qApp->processEvents(); - return endpointView; - } - - void EndpointManagerView::Update() const - { - if (m_pSelectedEndpoint) - { - auto pEndpoint = m_pSelectedEndpoint->GetEndpoint(); - pEndpoint->SetName(m_ui->nameText->text()); - pEndpoint->SetAwsProfile(m_ui->awsProfileText->text()); - pEndpoint->SetUrl(m_ui->urlText->text()); - pEndpoint->SetBucket(m_ui->bucketText->text()); - m_pManager->SelectEndpoint(m_pSelectedEndpoint->GetEndpoint()); - } - m_pManager->Save(); - } - - void EndpointManagerView::accept() - { - enum SyncResponse - { - Merge, ReplaceLocal, ReplaceRemote, Cancel - }; - enum YesNoResponse - { - Yes, No - }; - - QCustomMessageBox msgBox( - QCustomMessageBox::Question, - tr("Pull data from Endpoint"), - tr("You are changing an endpoint. " - "What would you like to do with the data on the current endpoint?\n\n" - "Merge - merge resources from the endpoint\n" - "Replace Local - overwrite local resources with endpoint resources\n" - "Replace Endpoint - overwrite endpoint resources with local resources\n" - "Cancel - undo endpoint selection" - ), - this); - msgBox.AddButton(tr("Merge"), Merge); - msgBox.AddButton(tr("Replace Local"), ReplaceLocal); - msgBox.AddButton(tr("Replace Endpoint"), ReplaceRemote); - msgBox.AddButton(tr("Cancel"), Cancel); - - switch (msgBox.exec()) - { - case Merge: - { - m_manifest.SetSyncType(SyncType::Merge); - m_manifest.PersistLocalResources(); - } - break; - case ReplaceLocal: - { - if (m_manifest.HasChanges()) - { - QCustomMessageBox msgBoxWarning( - QCustomMessageBox::Critical, - tr("Unsaved changes"), - tr("Local resources were modified but not published." - "Changing endpoints will cause unpublished work to be lost.\n\n" - "Would you like to proceed?"), - this); - msgBoxWarning.AddButton(tr("Yes"), Yes); - msgBoxWarning.AddButton(tr("No"), No); - if (msgBoxWarning.exec() == No) - { - return; - } - } - m_manifest.SetSyncType(SyncType::Merge); - m_manifest.Reset(); - } - break; - case ReplaceRemote: - { - QCustomMessageBox msgBoxWarning2( - QCustomMessageBox::Critical, - tr("Warning"), - tr("This operation will IRREVERSABLY replace ALL resources on ") + - m_pSelectedEndpoint->GetEndpoint()->GetName() + - tr(" endpoint with local data.\n\n" - "Are you sure you'd like to proceed?"), - this); - msgBoxWarning2.AddButton(tr("Yes"), Yes); - msgBoxWarning2.AddButton(tr("No"), No); - if (msgBoxWarning2.exec() == No) - { - return; - } - m_manifest.SetSyncType(SyncType::Overwrite); - m_manifest.PersistLocalResources(); - } - break; - case Cancel: - return; - } - - Update(); - - QDialog::accept(); - } - - void EndpointManagerView::addEndpointSlot() - { - auto pEndpoint = new Endpoint( - QObject::tr("New endpoint"), - QObject::tr("Enter AWS profile name"), - QObject::tr("Enter root URL"), - QObject::tr("Enter s3 bucket name")); - m_pManager->AddEndpoint(pEndpoint); - auto endpointView = AddEndpointEntry(pEndpoint); - selectEndpointSlot(endpointView); - } - - void EndpointManagerView::selectEndpointSlot(EndpointEntryView* pEndpointView) - { - m_pSelectedEndpoint = pEndpointView; - - for (auto view : m_endpoints) - { - view->SetSelected(view == pEndpointView); - } - - if (pEndpointView) - { - auto pEndpoint = pEndpointView->GetEndpoint(); - m_ui->nameText->setText(pEndpoint->GetName()); - m_ui->awsProfileText->setText(pEndpoint->GetAwsProfile()); - m_ui->urlText->setText(pEndpoint->GetUrl()); - m_ui->bucketText->setText(pEndpoint->GetBucket()); - } - else - { - m_ui->nameText->setText(""); - m_ui->awsProfileText->setText(""); - m_ui->urlText->setText(""); - m_ui->bucketText->setText(""); - } - } - - void EndpointManagerView::deleteEndpointSlot(EndpointEntryView* pEndpointView) - { - m_pManager->RemoveEndpoint(pEndpointView->GetEndpoint()); - m_endpoints.removeAll(pEndpointView); - - if (pEndpointView == m_pSelectedEndpoint) - { - if (m_endpoints.count() > 0) - { - selectEndpointSlot(m_endpoints[0]); - } - else - { - selectEndpointSlot(nullptr); - } - } - - delete pEndpointView; - } - - -#include "Qt/moc_EndpointManagerView.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.h b/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.h deleted file mode 100644 index c6362a06af..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class EndpointManagerViewWidget; -} - -namespace News -{ - class BuilderResourceManifest; - class Endpoint; - class EndpointEntryView; - class EndpointManager; - - //! Qt dialog for managing endpoints - class EndpointManagerView - : public QDialog - { - Q_OBJECT - public: - EndpointManagerView(QWidget* parent, - BuilderResourceManifest& manifest); - ~EndpointManagerView(); - - private: - QScopedPointer m_ui; - EndpointManager* m_pManager = nullptr; - EndpointEntryView* m_pSelectedEndpoint = nullptr; - QList m_endpoints; - BuilderResourceManifest& m_manifest; - - EndpointEntryView* AddEndpointEntry(Endpoint* pEndpoint); - void Update() const; - - private Q_SLOTS: - void accept() override; - void addEndpointSlot(); - void selectEndpointSlot(EndpointEntryView* pEndpoint); - void deleteEndpointSlot(EndpointEntryView* pEndpoint); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.ui b/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.ui deleted file mode 100644 index 5295e30616..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/EndpointManagerView.ui +++ /dev/null @@ -1,224 +0,0 @@ - - - EndpointManagerViewWidget - - - - 0 - 0 - 400 - 350 - - - - - 400 - 350 - - - - - 400 - 350 - - - - Change Endpoint - - - Qt::LeftToRight - - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOff - - - true - - - - - 0 - 0 - 363 - 189 - - - - - - - + - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - Name: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 250 - 0 - - - - - - - - - - - - AWS Profile Name: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 250 - 0 - - - - - - - - - - - - URL: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 250 - 0 - - - - - - - - - - - - S3 Bucket - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 250 - 0 - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/ImageItem.cpp b/Code/Tools/News/NewsBuilder/Qt/ImageItem.cpp deleted file mode 100644 index 1566b8309d..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ImageItem.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ImageItem.h" -#include "NewsShared/ResourceManagement/Resource.h" - -#include "Qt/ui_ImageItem.h" - -namespace News -{ - - const char* ImageItem::SELECTED_CSS = - "border: 4px solid; border-color: white; background-color: rgb(45, 45, 45);"; - const char* ImageItem::UN_SELECTED_CSS = - "background-color: rgb(45, 45, 45);"; - - ImageItem::ImageItem(Resource& resource) - : QWidget() - , m_ui(new Ui::ImageItemWidget) - , m_resource(resource) - { - m_ui->setupUi(this); - - QPixmap pixmap; - pixmap.loadFromData(m_resource.GetData()); - m_ui->ImageLabel->setPixmap(pixmap); - - connect(m_ui->ImageLabel, &AzQtComponents::ExtendedLabel::clicked, this, &ImageItem::imageClickedSlot); - } - - void ImageItem::imageClickedSlot() - { - emit selectSignal(this); - } - - ImageItem::~ImageItem() {} - - void ImageItem::SetSelect(bool selected) const - { - m_ui->ImageLabel->setStyleSheet(selected ? SELECTED_CSS : UN_SELECTED_CSS); - } - - Resource& ImageItem::GetResource() const - { - return m_resource; - } - -#include "Qt/moc_ImageItem.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/ImageItem.h b/Code/Tools/News/NewsBuilder/Qt/ImageItem.h deleted file mode 100644 index ba883bc736..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ImageItem.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class ImageItemWidget; -} - -namespace News { - class Resource; - - //! A clickable image in selectImage control - class ImageItem - : public QWidget - { - Q_OBJECT - public: - explicit ImageItem(Resource& resource); - ~ImageItem(); - - void SetSelect(bool selected) const; - Resource& GetResource() const; - - Q_SIGNALS: - void selectSignal(ImageItem* imageItem); - - private: - QScopedPointer m_ui; - const static char* SELECTED_CSS; - const static char* UN_SELECTED_CSS; - - Resource& m_resource; - private Q_SLOTS: - void imageClickedSlot(); - }; -} diff --git a/Code/Tools/News/NewsBuilder/Qt/ImageItem.ui b/Code/Tools/News/NewsBuilder/Qt/ImageItem.ui deleted file mode 100644 index 9aef880c10..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/ImageItem.ui +++ /dev/null @@ -1,65 +0,0 @@ - - - ImageItemWidget - - - - 0 - 0 - 200 - 200 - - - - - 200 - 200 - - - - - 200 - 200 - - - - Form - - - - 20 - - - 20 - - - 20 - - - 20 - - - - - - - - - 160 - 90 - - - - - - - - - AzQtComponents::ExtendedLabel1 - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - -
diff --git a/Code/Tools/News/NewsBuilder/Qt/LogContainer.cpp b/Code/Tools/News/NewsBuilder/Qt/LogContainer.cpp deleted file mode 100644 index 5efda641db..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/LogContainer.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "LogContainer.h" - -#include "Qt/ui_LogContainer.h" - -namespace News -{ - - LogContainer::LogContainer(QWidget* parent) - : QWidget(parent) - , m_ui(new Ui::LogContainerWidget) - { - m_ui->setupUi(this); - } - - LogContainer::~LogContainer() {} - - void LogContainer::AddLog(QString text, LogType logType) const { - QString color; - switch (logType) - { - case LogOk: - color = "green"; - break; - case LogInfo: - color = "white"; - break; - case LogError: - color = "red"; - break; - case LogWarning: - color = "yellow"; - break; - default: - color = "white"; - break; - } - auto fullText = QString("%2
").arg(color).arg(text); - m_ui->logText->setTextFormat(Qt::RichText); - m_ui->logText->setText(QString("%2%1").arg(m_ui->logText->text()).arg(fullText)); - } - -#include "Qt/moc_LogContainer.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/LogContainer.h b/Code/Tools/News/NewsBuilder/Qt/LogContainer.h deleted file mode 100644 index 8f46f3b406..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/LogContainer.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#endif - -namespace Ui -{ - class LogContainerWidget; -} - -namespace News -{ - //! A control for displaying log - class LogContainer - : public QWidget - { - Q_OBJECT - - public: - explicit LogContainer(QWidget* parent); - ~LogContainer(); - - void AddLog(QString text, LogType logType) const; - - private: - QScopedPointer m_ui; - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/LogContainer.ui b/Code/Tools/News/NewsBuilder/Qt/LogContainer.ui deleted file mode 100644 index 3757f52480..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/LogContainer.ui +++ /dev/null @@ -1,131 +0,0 @@ - - - LogContainerWidget - - - - 0 - 0 - 547 - 125 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - LogContainer - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - true - - - - - 0 - 0 - 545 - 123 - - - - - 0 - 0 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - background-color: rgb(45, 45, 45); - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - false - - - Qt::TextBrowserInteraction - - - - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.cpp b/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.cpp deleted file mode 100644 index 5cbb510dd6..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include "NewsBuilder.h" -#include "Qt/ArticleDetails.h" -#include "Qt/BuilderArticleViewContainer.h" -#include "NewsShared/Qt/ArticleViewContainer.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "ResourceManagement/BuilderResourceManifest.h" -#include "ArticleDetailsContainer.h" -#include "LogContainer.h" -#include "EndpointManagerView.h" -#include "EndpointManager.h" -#include "Qt/QCustomMessageBox.h" - -#include -#include - -AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - -#include -#include -#include -#include - -#include "Qt/ui_Newsbuilder.h" - -namespace News -{ - NewsBuilder::NewsBuilder(QWidget* parent, const AZ::IO::PathView& engineRootPath) - : QMainWindow(parent) - , m_ui(new Ui::NewsBuilderClass()) - , m_manifest(new BuilderResourceManifest( - std::bind(&NewsBuilder::SyncSuccess, this), - std::bind(&NewsBuilder::SyncFail, this, std::placeholders::_1), - std::bind(&NewsBuilder::SyncUpdate, this, std::placeholders::_1, std::placeholders::_2))) - , m_articleDetailsContainer(new ArticleDetailsContainer(this, *m_manifest)) - , m_articleViewContainer(new BuilderArticleViewContainer(this, *m_manifest)) - , m_logContainer(new LogContainer(this)) - { - - AzQtComponents::StyleManager* m_styleSheet = new AzQtComponents::StyleManager(this); - m_styleSheet->initialize(qApp, engineRootPath); - - m_ui->setupUi(this); - - QDir rootDir = QString::fromUtf8(engineRootPath.Native().data(), aznumeric_cast(engineRootPath.Native().size())); - const auto pathOnDisk = rootDir.absoluteFilePath("Code/Tools/News/NewsBuilder/Resources"); - const auto qrcPath = QStringLiteral(":/NewsBuilder"); - AzQtComponents::StyleManager::addSearchPaths("newsbuilder", pathOnDisk, qrcPath, engineRootPath); - - AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral("newsbuilder:NewsBuilder.qss")); - - UpdateEndpointLabel(); - - m_ui->articleViewContainerRoot->layout()->addWidget(m_articleViewContainer); - m_ui->articleDetailsContainerRoot->layout()->addWidget(m_articleDetailsContainer); - m_ui->dockWidgetContents->layout()->addWidget(m_logContainer); - - connect(m_articleViewContainer, SIGNAL(articleSelectedSignal(QString)), - this, SLOT(selectArticleSlot(QString))); - connect(m_articleViewContainer, SIGNAL(logSignal(QString, LogType)), - this, SLOT(addLogSlot(QString, LogType))); - - connect(m_articleDetailsContainer, &ArticleDetailsContainer::updateArticleSignal, - this, &NewsBuilder::updateArticleSlot); - connect(m_articleDetailsContainer, &ArticleDetailsContainer::deleteArticleSignal, - this, &NewsBuilder::deleteArticleSlot); - connect(m_articleDetailsContainer, &ArticleDetailsContainer::orderChangedSignal, - this, &NewsBuilder::orderChangedSlot); - connect(m_articleDetailsContainer, &ArticleDetailsContainer::closeArticleSignal, - this, &NewsBuilder::closeArticleSlot); - connect(m_articleDetailsContainer, SIGNAL(logSignal(QString, LogType)), - this, SLOT(addLogSlot(QString, LogType))); - - m_manifest->SetSyncType(SyncType::Merge); - m_manifest->Sync(); - - // Sync Console pane with View menu - connect(m_ui->actionConsole, &QAction::triggered, this, &NewsBuilder::OnViewLogWindow); - connect(m_ui->dockWidget, &QDockWidget::visibilityChanged, this, &NewsBuilder::OnViewVisibilityChanged); - } - - NewsBuilder::~NewsBuilder() {} - - void NewsBuilder::selectArticleSlot(const QString& id) const - { - m_articleDetailsContainer->SelectArticle(id); - } - - void NewsBuilder::addLogSlot(QString text, LogType logType) const - { - AddLog(text, logType); - } - - void NewsBuilder::addArticleToBottomSlot() const - { - m_articleViewContainer->AddArticle(); - } - - void NewsBuilder::updateArticleSlot(QString id) const - { - m_articleViewContainer->UpdateArticle(id); - } - - void NewsBuilder::deleteArticleSlot(QString id) const - { - m_articleViewContainer->DeleteArticle(id); - } - - void NewsBuilder::closeArticleSlot(QString id) const - { - m_articleViewContainer->CloseArticle(id); - } - - void NewsBuilder::orderChangedSlot(QString id, bool direction) const - { - m_articleViewContainer->UpdateArticleOrder(id, direction); - } - - void NewsBuilder::openSlot() - { - EndpointManagerView endpointManagerView( - m_ui->centralWidget, - *m_manifest); - if (endpointManagerView.exec() == QDialog::Accepted) - { - m_manifest->Sync(); - } - UpdateEndpointLabel(); - } - - void NewsBuilder::publishSlot() - { - if (!m_manifest->HasChanges()) - { - QCustomMessageBox msgBox( - QCustomMessageBox::Information, - tr("Nothing to publish"), - tr("No local changes were made, nothing to publish."), - this); - msgBox.AddButton(tr("Good"), 0); - msgBox.exec(); - return; - } - - enum Response - { - Yes, No - }; - - QCustomMessageBox msgBox( - QCustomMessageBox::Critical, - tr("Publish resources"), - tr("You are about to overwrite the current Open 3D Engine Welcome Message. Are you sure you want to publish?"), - this); - msgBox.AddButton("Yes", Yes); - msgBox.AddButton("No", No); - if (msgBox.exec() == Yes) - { - m_manifest->SetSyncType(SyncType::Verify); - m_manifest->Sync(); - } - } - - void NewsBuilder::OnViewVisibilityChanged([[maybe_unused]] bool visibility) - { - UpdateViewMenu(); - } - - void NewsBuilder::UpdateViewMenu() - { - if (m_ui->actionConsole->isChecked() != m_ui->dockWidget->isVisible()) - { - QSignalBlocker signalBlocker(m_ui->actionConsole); - m_ui->actionConsole->setChecked(m_ui->dockWidget->isVisible()); - } - } - - void NewsBuilder::OnViewLogWindow() - { - if (m_ui->dockWidget) - { - m_ui->dockWidget->toggleViewAction()->trigger(); - } - } - - void NewsBuilder::UpdateEndpointLabel() - { - auto pEndpoint = m_manifest->GetEndpointManager()->GetSelectedEndpoint(); - if (pEndpoint) - { - this->setWindowTitle("News Builder (" + pEndpoint->GetName() + ")"); - } - else - { - this->setWindowTitle("News Builder (No endpoint selected)"); - } - } - - void NewsBuilder::AddLog(QString text, LogType logType) const - { - m_logContainer->AddLog(text, logType); - } - - void NewsBuilder::SyncUpdate(const QString& message, LogType logType) const - { - AddLog(message, logType); - } - - void NewsBuilder::SyncFail(ErrorCode error) - { - const char* errorMessage = GetErrorMessage(error); - AddLog(tr("Sync failed: %1").arg(errorMessage), LogError); - QCustomMessageBox msgBoxSyncFail( - QCustomMessageBox::Critical, - tr("Sync failed"), - errorMessage, - this); - msgBoxSyncFail.AddButton("Ok", 0); - msgBoxSyncFail.exec(); - - m_articleViewContainer->PopulateArticles(); - m_articleDetailsContainer->Reset(); - } - - void NewsBuilder::SyncSuccess() const - { - AddLog("Sync completed", LogOk); - m_articleViewContainer->PopulateArticles(); - m_articleDetailsContainer->Reset(); - } -#include "Qt/moc_NewsBuilder.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.h b/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.h deleted file mode 100644 index 61e25bda1b..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/NewsBuilder.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include - -#include "NewsShared/LogType.h" -#include "NewsShared/ErrorCodes.h" - -#include -#endif - -class QSignalMapper; -class QPushButton; - -namespace Ui -{ - class NewsBuilderClass; -} - -namespace News -{ - class BuilderArticleViewContainer; - class LogContainer; - class BuilderResourceManifest; - class ArticleDetailsContainer; - - //! A central control of News Builder. - class NewsBuilder - : public QMainWindow - { - Q_OBJECT - - public: - explicit NewsBuilder(QWidget* parent, const AZ::IO::PathView& engineRootPath); - ~NewsBuilder(); - - private: - QScopedPointer m_ui; - BuilderResourceManifest* m_manifest = nullptr; - ArticleDetailsContainer* m_articleDetailsContainer = nullptr; - BuilderArticleViewContainer* m_articleViewContainer = nullptr; - LogContainer* m_logContainer = nullptr; - - void UpdateEndpointLabel(); - void AddLog(QString text, LogType logType = LogInfo) const; - - void SyncUpdate(const QString& message, LogType logType) const; - void SyncFail(ErrorCode error); - void SyncSuccess() const; - - void OnViewVisibilityChanged(bool visibility); - void UpdateViewMenu(); - void OnViewLogWindow(); - - private Q_SLOTS: - void selectArticleSlot(const QString& id) const; - void addLogSlot(QString text, LogType logType) const; - void addArticleToBottomSlot() const; - void updateArticleSlot(QString id) const; - void deleteArticleSlot(QString id) const; - void closeArticleSlot(QString id) const; - void orderChangedSlot(QString id, bool direction) const; - void openSlot(); - void publishSlot(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.qrc b/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.qrc deleted file mode 100644 index 768281fb12..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - ../Resources/missing-image.png - - diff --git a/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.ui b/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.ui deleted file mode 100644 index 55e7fe5b68..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/Newsbuilder.ui +++ /dev/null @@ -1,326 +0,0 @@ - - - NewsBuilderClass - - - - 0 - 0 - 800 - 540 - - - - - 0 - 480 - - - - - 1024 - 16777215 - - - - News Builder - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 800 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 480 - 0 - - - - - 16777215 - 16777215 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 0 - - - 5 - - - 5 - - - 5 - - - 5 - - - - - - - - - - - - - 0 - 0 - 800 - 21 - - - - - File - - - - - - - Article - - - - - - View - - - - - - - - - - - 0 - 0 - - - - - 63 - 66 - - - - QDockWidget::DockWidgetClosable - - - Qt::BottomDockWidgetArea - - - Console - - - 8 - - - - - 5 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - Change Endpoint - - - false - - - - - Publish Resources - - - false - - - - - Add to Bottom - - - - - Delete Selected - - - - - true - - - Console - - - - - - - AzQtComponents::StyledDockWidget - QDockWidget -
AzQtComponents/Components/StyledDockWidget.h
- 1 -
-
- - - - - - actionOpen - triggered() - NewsBuilderClass - openSlot() - - - -1 - -1 - - - 399 - 269 - - - - - actionPublish - triggered() - NewsBuilderClass - publishSlot() - - - -1 - -1 - - - 399 - 269 - - - - - actionAdd_New - triggered() - NewsBuilderClass - addArticleToBottomSlot() - - - -1 - -1 - - - 399 - 269 - - - - -
diff --git a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.cpp b/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.cpp deleted file mode 100644 index 1b92f91e42..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "QCustomMessageBox.h" -#include "Qt/ui_QCustomMessageBox.h" - -#include -#include -#include - -namespace News -{ - - QCustomMessageBox::QCustomMessageBox( - Icon icon, - const QString& title, - const QString& text, - QWidget* parent) - : QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint) - , m_ui(new Ui::CustomMessageBoxDialog) - { - m_ui->setupUi(this); - - m_signalMapper = new QSignalMapper(this); - - this->setWindowTitle(title); - m_ui->labelText->setText(text); - - QStyle* style = QApplication::style(); - QIcon tmpIcon; - switch (icon) - { - case Information: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation); - break; - case Warning: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning); - break; - case Critical: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical); - break; - case Question: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion); - default: - break; - } - if (!tmpIcon.isNull()) - { - QLabel* iconLabel = new QLabel(this); - iconLabel->setPixmap(tmpIcon.pixmap(64, 64)); - m_ui->bodyLayout->insertWidget(0, iconLabel); - } - - connect(m_signalMapper, SIGNAL(mapped(int)), - this, SLOT(clickedSlot(int))); - } - - QCustomMessageBox::~QCustomMessageBox() - { - delete m_signalMapper; - } - - void QCustomMessageBox::AddButton(const QString& name, int result) - { - auto button = new QPushButton(name, this); - connect(button, SIGNAL(clicked()), m_signalMapper, SLOT(map())); - m_signalMapper->setMapping(button, result); - m_ui->buttonLayout->layout()->addWidget(button); - } - - void QCustomMessageBox::clickedSlot(int result) - { - done(result); - } - -#include "Qt/moc_QCustomMessageBox.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.h b/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.h deleted file mode 100644 index 6cd6771514..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -class QSignalMapper; - -namespace Ui -{ - class CustomMessageBoxDialog; -} - -namespace News -{ - class ArticleDetails; - class BuilderResourceManifest; - class SelectImage; - class ResourceManifest; - class Resource; - - //! Allows to add custom buttons which is not well-supported by default QMessageBox - class QCustomMessageBox - : public QDialog - { - Q_OBJECT - - public: - enum Icon { - NoIcon = 0, - Information = 1, - Warning = 2, - Critical = 3, - Question = 4 - }; - - QCustomMessageBox( - Icon, - const QString& title, - const QString& text, - QWidget* parent); - ~QCustomMessageBox(); - - void AddButton(const QString& name, int result); - - private: - QScopedPointer m_ui; - QSignalMapper* m_signalMapper = nullptr; - - private Q_SLOTS: - void clickedSlot(int result); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.ui b/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.ui deleted file mode 100644 index c1fb5f40bf..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/QCustomMessageBox.ui +++ /dev/null @@ -1,84 +0,0 @@ - - - CustomMessageBoxDialog - - - - 0 - 0 - 102 - 43 - - - - - 0 - 0 - - - - Message Title - - - - - - - - - - - Message text - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - 0 - - - - - Qt::Horizontal - - - - 40 - 0 - - - - - - - - 10 - - - - - - - Qt::Horizontal - - - - 40 - 0 - - - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/Qt/SelectImage.cpp b/Code/Tools/News/NewsBuilder/Qt/SelectImage.cpp deleted file mode 100644 index 7a9e427f4b..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/SelectImage.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "SelectImage.h" -#include "ImageItem.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "ResourceManagement/BuilderResourceManifest.h" - -#include "Qt/ui_SelectImage.h" - -namespace News -{ - - const int SelectImage::MAX_COLS = 2; - - SelectImage::SelectImage(const ResourceManifest& manifest) - : QDialog() - , m_ui(new Ui::SelectImageDialog) - , m_manifest(manifest) - { - m_ui->setupUi(this); - - auto layout = static_cast(m_ui->scrollAreaContents->layout()); - layout->setAlignment(Qt::AlignTop | Qt::AlignLeft); - int row = 0; - int col = 0; - //! read all image resources and populate the container - for (auto pResource : m_manifest) - { - if (pResource->GetType().compare("image") == 0) - { - auto imageItem = new ImageItem(*pResource); - connect(imageItem, &ImageItem::selectSignal, this, &SelectImage::ImageSelected); - layout->addWidget(imageItem, row, col, Qt::AlignLeft); - m_images.append(imageItem); - col++; - if (col >= MAX_COLS) - { - col = 0; - row++; - } - } - } - - connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - } - - SelectImage::~SelectImage() {} - - Resource* SelectImage::GetSelected() const - { - return m_pSelected; - } - - void SelectImage::ImageSelected(ImageItem* imageItem) - { - for (auto image : m_images) - { - image->SetSelect(image == imageItem); - } - if (imageItem) - { - m_pSelected = &imageItem->GetResource(); - } - } - -#include "Qt/moc_SelectImage.cpp" - -} diff --git a/Code/Tools/News/NewsBuilder/Qt/SelectImage.h b/Code/Tools/News/NewsBuilder/Qt/SelectImage.h deleted file mode 100644 index 5fc80cfe5a..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/SelectImage.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class SelectImageDialog; -} - -namespace News { - class ImageItem; - class Resource; - class ResourceManifest; - - //! Allows to select existing images for multiple messages without re-uploading same one - class SelectImage - : public QDialog - { - Q_OBJECT - public: - explicit SelectImage(const ResourceManifest& manifest); - ~SelectImage(); - - void Select(); - void Close(); - Resource* GetSelected() const; - - private: - const static int MAX_COLS; - QScopedPointer m_ui; - const ResourceManifest& m_manifest; - QList m_images; - Resource* m_pSelected = nullptr; - - void ImageSelected(ImageItem* imageItem); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/Qt/SelectImage.ui b/Code/Tools/News/NewsBuilder/Qt/SelectImage.ui deleted file mode 100644 index 55b27bfb7f..0000000000 --- a/Code/Tools/News/NewsBuilder/Qt/SelectImage.ui +++ /dev/null @@ -1,106 +0,0 @@ - - - SelectImageDialog - - - Qt::ApplicationModal - - - - 0 - 0 - 439 - 406 - - - - Select Image - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::LeftToRight - - - Qt::ScrollBarAlwaysOff - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - 0 - 0 - 437 - 379 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 2 - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.cpp b/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.cpp deleted file mode 100644 index 0a845216fe..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "BuilderResourceManifest.h" -#include "NewsShared/ResourceManagement/QtDownloadManager.h" -#include "NewsBuilder/S3Connector.h" -#include "UidGenerator.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "NewsBuilder/ResourceManagement/UploadDescriptor.h" -#include "NewsBuilder/ResourceManagement/DeleteDescriptor.h" -#include "NewsShared/ResourceManagement/ArticleDescriptor.h" -#include "NewsBuilder/ResourceManagement/ImageDescriptor.h" -#include "EndpointManager.h" - -#include -#include - -#include -#include - -namespace News { - - BuilderResourceManifest::BuilderResourceManifest( - std::function syncSuccessCallback, - std::function syncFailCallback, - std::function syncUpdateCallback) - : ResourceManifest(syncSuccessCallback, syncFailCallback, syncUpdateCallback) - , m_s3Connector(new S3Connector) - , m_uidGenerator(new UidGenerator) - , m_endpointManager(new EndpointManager) {} - - - Resource* BuilderResourceManifest::AddArticle() - { - auto pResource = new Resource( - QString("%1").arg(m_uidGenerator->GenerateUid()), - "article"); - QJsonObject json; - json["title"] = "New Article"; - json["body"] = "Enter article body here"; - json["imageId"] = "0"; - QJsonDocument doc(json); - QByteArray data = doc.toJson(QJsonDocument::Compact).toStdString().data(); - pResource->SetData(data); - m_toUpload.push(pResource); - AppendResource(pResource); - m_order.append(pResource->GetId()); - return pResource; - } - - Resource* BuilderResourceManifest::AddImage(const QString& filename) - { - auto pResource = new Resource( - QString("%1").arg(m_uidGenerator->GenerateUid()), - "image"); - ImageDescriptor descriptor(*pResource); - QString error; - if (!descriptor.Read(filename, error)) - { - m_syncUpdateCallback(error, LogError); - delete pResource; - return nullptr; - } - m_toUpload.push(pResource); - AppendResource(pResource); - return pResource; - } - - void BuilderResourceManifest::UpdateResource(Resource* pResource) - { - if (!m_toUpload.contains(pResource)) - { - pResource->SetVersion(pResource->GetVersion() + 1); - m_toUpload.push(pResource); - } - } - - void BuilderResourceManifest::UseResource(const QString& id) - { - auto pResource = FindById(id, m_resources); - if (!pResource) - { - return; - } - pResource->SetRefCount(pResource->GetRefCount() + 1); - UpdateResource(pResource); - } - - void BuilderResourceManifest::FreeResource(const QString& id) - { - auto pResource = FindById(id, m_resources); - if (!pResource) - { - return; - } - if (m_toDelete.contains(pResource)) - { - return; - } - pResource->SetRefCount(pResource->GetRefCount() - 1); - if (pResource->GetRefCount() <= 0) - { - m_toDelete.push(pResource); - RemoveResource(pResource); - m_toUpload.removeAll(pResource); - - if (pResource->GetType().compare("article") == 0) - { - m_order.removeAll(pResource->GetId()); - } - } - else - { - m_toUpload.push(pResource); - } - } - - bool BuilderResourceManifest::UpdateArticleOrder(const QString& id, bool direction, ErrorCode& error) - { - int index = m_order.indexOf(id); - if (index == -1) - { - m_syncUpdateCallback(QString("Couldn't find article: %1").arg(id), LogError); - error = ErrorCode::MissingArticle; - return false; - } - m_order.removeAll(id); - - index = index + (direction ? -1 : 1); - if (index < 0) - { - index = 0; - } - if (index > m_order.count()) - { - index = m_order.count(); - } - m_order.insert(index, id); - return true; - } - - EndpointManager* BuilderResourceManifest::GetEndpointManager() const - { - return m_endpointManager; - } - - void BuilderResourceManifest::Sync() - { - if (!m_endpointManager->GetSelectedEndpoint()) - { - FailSync(ErrorCode::NoEndpoint); - return; - } - if (!InitS3Connector()) - { - FailSync(ErrorCode::S3Fail); - return; - } - ResourceManifest::Sync(); - } - - void BuilderResourceManifest::Reset() - { - if (s_syncing) - { - m_syncUpdateCallback("Sync is already running", LogError); - return; - } - - m_toUpload.clear(); - - for (auto pResource : m_toDelete) - { - delete pResource; - } - m_toDelete.clear(); - - m_uidGenerator->Clear(); - - ResourceManifest::Reset(); - } - - void BuilderResourceManifest::PersistLocalResources() - { - // we are switching to another manifest here, while having the local data still present - // so we need to explicitly mark it for uploading so that it does not get deleted - for (auto pResource : m_resources) - { - if (!m_toUpload.contains(pResource)) - { - m_toUpload.push(pResource); - } - } - } - - void BuilderResourceManifest::SetSyncType(SyncType syncType) - { - m_syncType = syncType; - } - - bool BuilderResourceManifest::HasChanges() const - { - return m_toUpload.count() > 0 || m_toDelete.count() > 0; - } - - void BuilderResourceManifest::AppendResource(Resource* pResource) - { - m_uidGenerator->AddUid(pResource->GetId().toInt()); - ResourceManifest::AppendResource(pResource); - } - - void BuilderResourceManifest::RemoveResource(Resource* pResource) - { - m_uidGenerator->RemoveUid(pResource->GetId().toInt()); - ResourceManifest::RemoveResource(pResource); - } - - void BuilderResourceManifest::OnDownloadFail() - { - QMessageBox msgBox(QMessageBox::Critical, - "Sync failed", - QString("%1\n\n%2") - .arg(GetErrorMessage(ErrorCode::ManifestDownloadFail)) - .arg(QObject::tr("Overwrite resource manifest?")), - QMessageBox::Yes | QMessageBox::No); - if (msgBox.exec() == QMessageBox::Yes) - { - if (!UploadManifest()) - { - m_failed = true; - m_errorCode = ErrorCode::ManifestUploadFail; - } - } - ResourceManifest::OnDownloadFail(); - } - - //! This function overrides ResourceManifest Read and tries to do some minimal version checking - //! NOTE: version checking is not done yet, this needs a lot more work to version check properly - ErrorCode BuilderResourceManifest::Read(const QJsonObject& json) - { - int version = json["version"].toInt(); - if (version > m_version && m_syncType == SyncType::Verify) - { - return ErrorCode::OutOfSync; - } - - m_version = version; - QJsonArray resourceArray = json["resources"].toArray(); - - // initially mark ALL existing resource for deletion - QList toDelete = m_resources; - - for (auto resourceDoc : resourceArray) - { - auto pNewResource = new Resource(resourceDoc.toObject()); - // find local resource with the same id as new resource - auto pOldResource = FindById(pNewResource->GetId(), m_resources); - // if resource with the same id already exists then check its version - if (pOldResource) - { - // local resource is outdated, keep its in delete list, and download new one instead - if (pNewResource->GetVersion() > pOldResource->GetVersion()) - { - if (m_syncType == SyncType::Merge) - { - m_toDownload.push(pNewResource); - } - else if (m_syncType == SyncType::Overwrite) - { - m_toDelete.push(pNewResource); - } - } - // local resource is newer or same version, keep it (remove from toDelete list) - // and don't need to download new one - else - { - delete pNewResource; - toDelete.removeAll(pOldResource); - } - } - else - { - // if remote resource was NOT deleted locally then download it - if (!FindById(pNewResource->GetId(), m_toDelete)) - { - if (m_syncType == SyncType::Merge) - { - m_toDownload.push(pNewResource); - } - else if (m_syncType == SyncType::Overwrite) - { - m_toDelete.push(pNewResource); - } - } - // otherwise user deleted it... needs version check here - else - { - delete pNewResource; - } - } - } - - for (auto pResource : m_toUpload) - { - toDelete.removeAll(pResource); - } - - for (auto pResource : toDelete) - { - RemoveResource(pResource); - m_toDelete.removeAll(pResource); - delete pResource; - } - - //! Sync article display order - //! this is more complex to implement because articles may have been added or deleted - //! remotely by another developer while newsbuilder was running - //! for now just overwrite s3 version - QJsonArray orderArray = json["order"].toArray(); - for (auto idObject : orderArray) - { - QString id = idObject.toString(); - if (FindById(id, m_toDownload) && !m_order.contains(id)) - { - m_order.append(id); - } - } - return ErrorCode::None; - } - - //! Write resource manifest to JSON - void BuilderResourceManifest::Write(QJsonObject& json) const - { - QJsonArray resourceArray; - foreach(auto pResource, m_resources) - { - QJsonObject resourceObject; - pResource->Write(resourceObject); - resourceArray.append(resourceObject); - } - json["resources"] = resourceArray; - - QJsonArray orderArray; - foreach(auto id, m_order) - { - orderArray.append(id); - } - json["order"] = orderArray; - json["version"] = m_version; - } - - //! Figure out how many resources need to be synced - void BuilderResourceManifest::PrepareForSync() - { - // if resource is locally marked for deletion, then we don't need to upload/download it - for (auto pResource : m_toDelete) - { - m_toDownload.removeAll(pResource); - m_toUpload.removeAll(pResource); - } - - m_syncLeft = - m_toDownload.size() + - m_toUpload.size() + - m_toDelete.size(); - } - - void BuilderResourceManifest::SyncResources() - { - ResourceManifest::SyncResources(); - UploadResources(); - DeleteResources(); - } - - void BuilderResourceManifest::UploadResources() - { - QStack failures; - while (m_toUpload.count() > 0) - { - m_syncUpdateCallback( - QString("Uploading: %1 resources left").arg(m_toUpload.count()), - LogInfo); - - auto pResource = m_toUpload.pop(); - - auto uploadDescriptor = UploadDescriptor(*pResource); - uploadDescriptor.Upload(*m_s3Connector, - [&](QString url) - { - UpdateSync(); - }, - [&, pResource](QString error) - { - failures.push(pResource); - m_failed = true; - UpdateSync(); - m_syncUpdateCallback( - error, - LogError); - }); - } - while (failures.count() > 0) - { - m_toUpload.push(failures.pop()); - } - } - - void BuilderResourceManifest::DeleteResources() - { - while (m_toDelete.count() > 0) - { - m_syncUpdateCallback( - QString("Deleting: %1 resources left").arg(m_toDelete.count()), - LogInfo); - - auto pResource = m_toDelete.pop(); - - auto deleteDescriptor = DeleteDescriptor(*pResource); - deleteDescriptor.Delete(*m_s3Connector, - [&, pResource]() - { - delete pResource; - UpdateSync(); - }, - [&, pResource](QString error) - { - m_failed = true; - delete pResource; - UpdateSync(); - m_syncUpdateCallback( - QString("Failed to delete resource: %1").arg(error), - LogError); - }); - } - } - - void BuilderResourceManifest::FinishSync() - { - if (!m_failed) - { - QString error; - if (!UploadManifest()) - { - m_failed = true; - m_errorCode = ErrorCode::ManifestUploadFail; - } - } - ResourceManifest::FinishSync(); - } - - bool BuilderResourceManifest::UploadManifest() - { - m_syncUpdateCallback(QObject::tr("%1 to %2") - .arg("Uploading manifest") - .arg(m_endpointManager->GetSelectedEndpoint()->GetBucket()), - LogInfo); - m_version++; - Aws::String awsError; - QJsonObject manifestObject; - Write(manifestObject); - QJsonDocument doc(manifestObject); - auto ss = Aws::MakeShared( - S3Connector::ALLOCATION_TAG, - std::ios::in | std::ios::out | std::ios::binary); - *ss << QString(doc.toJson(QJsonDocument::Compact)).toStdString(); - Aws::String url; - if (!m_s3Connector->PutObject("resourceManifest", ss, url, awsError)) - { - m_syncUpdateCallback(QObject::tr(awsError.c_str()), LogError); - return false; - } - return true; - } - - bool BuilderResourceManifest::InitS3Connector() const - { - auto awsProfileName = - m_endpointManager->GetSelectedEndpoint()->GetAwsProfile(); - auto bucketName = - m_endpointManager->GetSelectedEndpoint()->GetBucket(); - Aws::String awsError; - if (!m_s3Connector->Init( - awsProfileName.toStdString().c_str(), - bucketName.toStdString().c_str(), - awsError)) - { - m_syncUpdateCallback(QObject::tr(awsError.c_str()), LogError); - return false; - } - return true; - } - -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.h b/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.h deleted file mode 100644 index b6c20df571..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/BuilderResourceManifest.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "NewsShared/ResourceManagement/ResourceManifest.h" - -#include - -class QJsonObject; - -namespace News -{ - class EndpointManager; - class ArticleDescriptor; - class UidGenerator; - class S3Connector; - class QtDownloadManager; - class Descriptor; - class DownloadDescriptor; - class Resource; - - //! Type of sync behavior - enum class SyncType - { - Merge, // merge resources from both endpoints, i.e. replacing outdated and appending missing (also normal sync behavior) - Overwrite, // overwrite resources on new endpoint with old endpoint - Verify // attempt to publish changes but abort if out of sync - }; - - //! Adds news-builder functionality layer to resource manager - class BuilderResourceManifest - : public ResourceManifest - { - public: - explicit BuilderResourceManifest( - std::function syncSuccessCallback, - std::function syncFailCallback, - std::function syncUpdateCallback); - - //! Create new article resource - /*! - Create new article with default parameters, - Add it to resource collection, - Mark it for upload. - - \retval Resource * - a pointer to an article Resource - */ - Resource* AddArticle(); - - //! Create new image resource - /*! - Create new image from file, - add it to resource collection, - mark it for upload. - - \param filename - path to an image on hard drive - \retval Resource * - a pointer to an image Resource - */ - Resource* AddImage(const QString& filename); - - //! If resource was modified, add it to upload list and increment its version - void UpdateResource(Resource* resource); - - //! When resource is used by several other resources, this function is called - //! to increment its ref count - void UseResource(const QString& id); - - //! When resource is no longer used by another resource - //! decrement refCount, - //! if nothing else is using it, then mark for delete - void FreeResource(const QString& id); - - //! Move article either up or down in order queue - bool UpdateArticleOrder(const QString& id, bool direction, ErrorCode& error); - - EndpointManager* GetEndpointManager() const; - - void Sync() override; - - void Reset() override; - - //! When switching endpoints Merge allows to persist resources to another endpoint, - //! thus copying news from one location to another upon next Sync - void PersistLocalResources(); - - void SetSyncType(SyncType syncType); - - //! Are there local changes - bool HasChanges() const; - - protected: - void AppendResource(Resource* pResource) override; - void RemoveResource(Resource* pResource) override; - void OnDownloadFail() override; - void FinishSync() override; - - private: - S3Connector* m_s3Connector = nullptr; - UidGenerator* m_uidGenerator = nullptr; - EndpointManager* m_endpointManager = nullptr; - SyncType m_syncType = SyncType::Merge; - - QStack m_toUpload; - QStack m_toDelete; - - ErrorCode Read(const QJsonObject& json) override; - void Write(QJsonObject& json) const; - - void PrepareForSync() override; - void SyncResources() override; - - void UploadResources(); - void DeleteResources(); - - bool UploadManifest(); - - //! Initializes S3 connector with selected endpoint - bool InitS3Connector() const; - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.cpp b/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.cpp deleted file mode 100644 index 63cdb46218..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "DeleteDescriptor.h" -#include "NewsBuilder/S3Connector.h" -#include "NewsShared/ResourceManagement/Resource.h" - -#include - -namespace News -{ - - DeleteDescriptor::DeleteDescriptor(Resource& resource) - : Descriptor(resource) {} - - void DeleteDescriptor::Delete(S3Connector& s3Connector, - std::function deleteSuccessCallback, - std::function deleteFailCallback) const - { - Aws::String error; - if (!s3Connector.DeleteObject( - m_resource.GetId().toStdString().c_str(), - error)) - { - deleteFailCallback(QString("Error deleting resource %1: %2") - .arg(m_resource.GetId()) - .arg(error.c_str())); - } - else - { - deleteSuccessCallback(); - } - } - -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.h b/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.h deleted file mode 100644 index 8928e9e19d..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/DeleteDescriptor.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "NewsShared/ResourceManagement/Descriptor.h" - -#include -#include - -namespace News -{ - class S3Connector; - - class DeleteDescriptor - : public Descriptor - { - public: - explicit DeleteDescriptor(Resource& resource); - - void Delete(S3Connector& s3Connector, - std::function deleteSuccessCallback, - std::function deleteFailCallback) const; - }; -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.cpp b/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.cpp deleted file mode 100644 index a16ec48851..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ImageDescriptor.h" -#include "NewsShared/ResourceManagement/Resource.h" - -#include -#include -#include -#include -#include - -namespace News -{ - - ImageDescriptor::ImageDescriptor( - Resource& resource) - : Descriptor(resource) - { - } - - bool ImageDescriptor::Read(const QString& filename, QString& error) const - { - QImageReader reader(filename); - if (!reader.canRead()) - { - error = reader.errorString(); - return false; - } - QImage image = reader.read(); - - QPixmap pixmap(filename); - QByteArray data; - QBuffer buffer(&data); - buffer.open(QIODevice::WriteOnly); - QFile test("test.png"); - if (pixmap.save(&buffer, "PNG")) - { - m_resource.SetData(data); - return true; - } - error = QString("failed to save image %1").arg(filename); - return false; - } - -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.h b/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.h deleted file mode 100644 index ba4533b0c0..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/ImageDescriptor.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -class QString; - -namespace News -{ - class ImageDescriptor - : public Descriptor - { - public: - explicit ImageDescriptor(Resource& resource); - - bool Read(const QString& filename, QString& error) const; - }; -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.cpp b/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.cpp deleted file mode 100644 index 699959ed85..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "NewsBuilder/S3Connector.h" -#include "UploadDescriptor.h" -#include "NewsShared/ResourceManagement/Resource.h" - -#include -#include -#include - -#include - -namespace News -{ - - UploadDescriptor::UploadDescriptor(Resource& resource) - : Descriptor(resource) {} - - void UploadDescriptor::Upload(S3Connector& s3Connector, - std::function uploadSuccessCallback, - std::function uploadFailCallback) const - { - Aws::String error; - - auto ss = - Aws::MakeShared(S3Connector::ALLOCATION_TAG, - std::ios::in | std::ios::out | std::ios::binary); - auto* pbuf = ss->rdbuf(); - pbuf->sputn(m_resource.GetData().data(), m_resource.GetData().size()); - Aws::String awsUrl; - - if (!s3Connector.PutObject( - m_resource.GetId().toStdString().c_str(), - ss, - m_resource.GetData().size(), - awsUrl, - error)) - { - uploadFailCallback(QObject::tr("Error uploading resource %1: %2") - .arg(m_resource.GetId()) - .arg(error.c_str())); - } - else - { - uploadSuccessCallback(QString(awsUrl.c_str())); - } - } - -} diff --git a/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.h b/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.h deleted file mode 100644 index 71a7732c1e..0000000000 --- a/Code/Tools/News/NewsBuilder/ResourceManagement/UploadDescriptor.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "NewsShared/ResourceManagement/Descriptor.h" - -#include -#include - -namespace News -{ - class S3Connector; - - class UploadDescriptor - : public Descriptor - { - public: - explicit UploadDescriptor(Resource& resource); - - void Upload(S3Connector& s3Connector, - std::function uploadSuccessCallback, - std::function uploadFailCallback) const; - }; -} diff --git a/Code/Tools/News/NewsBuilder/Resources/NewsBuilder.qss b/Code/Tools/News/NewsBuilder/Resources/NewsBuilder.qss deleted file mode 100644 index 01ca308585..0000000000 --- a/Code/Tools/News/NewsBuilder/Resources/NewsBuilder.qss +++ /dev/null @@ -1,44 +0,0 @@ -QLabel -{ - font-size: 12px; - color: #FFFFFF; - line-height: 20px; - background-color: transparent; - margin: 0; -} - -QLabel#titleLabel -{ - font-size: 22px; - line-height: 32px; -} - -QLabel#bodyLabel -{ - font-size: 14px; - line-height: 20px; -} - -QFrame#viewContainer[articleStyle="pinned"] -{ - background: rgba(180,139,255,5%); - border: 1px solid #B48BFF; - box-shadow: 0 0 4px 0 rgba(0,0,0,50%); -} - -QWidget#articleViewContainerRoot -{ - background: #222222; -} - -QScrollArea#previewArea, -QWidget#articleViewContents, -QFrame#imageFrame -{ - background-color: transparent; -} - -News--ArticleView.SelectedArticle > QWidget -{ - background: #333333; -} diff --git a/Code/Tools/News/NewsBuilder/Resources/missing-image.png b/Code/Tools/News/NewsBuilder/Resources/missing-image.png deleted file mode 100644 index 889493e628..0000000000 --- a/Code/Tools/News/NewsBuilder/Resources/missing-image.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4255a25636d77a54809592bc98bef47fa9044be03cd65d73daa821711489e00f -size 7379 diff --git a/Code/Tools/News/NewsBuilder/S3Connector.cpp b/Code/Tools/News/NewsBuilder/S3Connector.cpp deleted file mode 100644 index a54b6fa8f8..0000000000 --- a/Code/Tools/News/NewsBuilder/S3Connector.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "S3Connector.h" - -#include -#include -#include - - -AZ_PUSH_DISABLE_WARNING(4251 4819, "-Wunknown-warning-option") // Invalid character not in default code page -#include -#include -#include -#include -#include -#include -#include -#include -AZ_POP_DISABLE_WARNING - -namespace News -{ - const char* S3Connector::ALLOCATION_TAG = "NewsBuilder"; - - S3Connector::S3Connector() - : m_s3Client(nullptr) - , m_limiter(nullptr) - , m_valid(false) - { - } - - S3Connector::~S3Connector() {} - - bool S3Connector::Init(const char* awsProfileName, const char* bucket, Aws::String& error) - { - Aws::SDKOptions options; - options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace; - Aws::InitAPI(options); - - Aws::Client::ClientConfiguration config; - config.enableTcpKeepAlive = AZ_TRAIT_AZFRAMEWORK_AWS_ENABLE_TCP_KEEP_ALIVE_SUPPORTED; - config.scheme = Aws::Http::Scheme::HTTPS; - config.connectTimeoutMs = 30000; - config.requestTimeoutMs = 30000; - config.readRateLimiter = m_limiter; - config.writeRateLimiter = m_limiter; - - auto provider = - Aws::MakeShared( - ALLOCATION_TAG, - awsProfileName); - - auto accessKeyId = provider->GetAWSCredentials().GetAWSAccessKeyId(); - - //! verify that credential file exists - if (accessKeyId.empty()) - { - error = "LY_NEWS_DEVELOPER AWS credentials not found. Add credentials in LY Editor AWS->ClientManager"; - m_valid = false; - return false; - } - - m_bucket = Aws::String(bucket); - m_s3Client = Aws::MakeShared( - ALLOCATION_TAG, - provider, - config); - - m_valid = true; - return true; - } - - bool S3Connector::GetObject(const char* key, - Aws::String& data, - Aws::String& url, - Aws::String& error) const - { - if (!m_valid) - { - error = "Client not initialized"; - return false; - } - - Aws::S3::Model::GetObjectRequest getObjectRequest; - getObjectRequest.SetBucket(m_bucket); - getObjectRequest.SetKey(key); - auto outcome = m_s3Client->GetObject(getObjectRequest); - if (!outcome.IsSuccess()) - { - error = outcome.GetError().GetMessage(); - return false; - } - url = m_s3Client->GeneratePresignedUrl(m_bucket, key, Aws::Http::HttpMethod::HTTP_GET); - Aws::StringStream ss; - ss << outcome.GetResult().GetBody().rdbuf(); - data = ss.str(); - return true; - } - - bool S3Connector::PutObject(const char* key, - STREAM_PTR stream, - Aws::String& url, - Aws::String& error) const - { - return PutObject(key, stream, GetStreamLength(stream), url, error); - } - - bool S3Connector::PutObject(const char* key, - STREAM_PTR stream, - int length, - Aws::String& url, - Aws::String& error) const - { - if (!m_valid) - { - error = "Client not initialized"; - return false; - } - - Aws::S3::Model::PutObjectRequest putObjectRequest; - putObjectRequest.SetBucket(m_bucket); - putObjectRequest.SetBody(stream); - putObjectRequest.SetContentLength(length); - putObjectRequest.SetContentMD5( - Aws::Utils::HashingUtils::Base64Encode( - Aws::Utils::HashingUtils::CalculateMD5(*putObjectRequest.GetBody()))); - putObjectRequest.SetContentType(Aws::String("binary/octet-stream")); - putObjectRequest.SetKey(key); - putObjectRequest.SetACL(Aws::S3::Model::ObjectCannedACL::public_read); - auto outcome = m_s3Client->PutObject(putObjectRequest); - if (!outcome.IsSuccess()) - { - error = outcome.GetError().GetMessage(); - return false; - } - url = m_s3Client->GeneratePresignedUrl(m_bucket, key, Aws::Http::HttpMethod::HTTP_GET); - return true; - } - - bool S3Connector::DeleteObject(const char* key, Aws::String& error) const - { - if (!m_valid) - { - error = "Client not initialized"; - return false; - } - - Aws::S3::Model::DeleteObjectRequest deleteObjectRequest; - deleteObjectRequest.SetBucket(m_bucket); - deleteObjectRequest.SetKey(key); - auto outcome = m_s3Client->DeleteObject(deleteObjectRequest); - if (!outcome.IsSuccess()) - { - error = outcome.GetError().GetMessage(); - return false; - } - return true; - } - - int S3Connector::GetStreamLength(STREAM_PTR stream) - { - stream->seekg(0, std::ios::end); - auto length = stream->tellg(); - stream->seekg(0, std::ios::beg); - return static_cast(length); - } - -} diff --git a/Code/Tools/News/NewsBuilder/S3Connector.h b/Code/Tools/News/NewsBuilder/S3Connector.h deleted file mode 100644 index d0404bfddb..0000000000 --- a/Code/Tools/News/NewsBuilder/S3Connector.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include -AZ_PUSH_DISABLE_WARNING(4251 4355 4996, "-Wunknown-warning-option") // includes ppltasks.h which throws a C4355 warning: 'this' used in base member initializer list -#include -AZ_POP_DISABLE_WARNING - -typedef std::shared_ptr STREAM_PTR; - -namespace News -{ - //! A light wrapper around AWS SDK - class S3Connector - { - public: - static const char* ALLOCATION_TAG; - - S3Connector(); - ~S3Connector(); - - //! Make s3 client using credentials stored in [user]/.aws/credentials file - /*! - \param awsProfileName - name of AWS credentials - \param bucket - name of s3 bucket to use for AWS operations - \param error - error string - \retval bool - true if success else false - */ - bool Init(const char* awsProfileName, const char* bucket, Aws::String& error); - - bool GetObject(const char* key, - Aws::String& data, - Aws::String& url, - Aws::String& error) const; - - bool PutObject(const char* key, - STREAM_PTR stream, - Aws::String& url, - Aws::String& error) const; - - bool PutObject(const char* key, - STREAM_PTR stream, - int length, - Aws::String& url, - Aws::String& error) const; - - bool DeleteObject(const char* key, - Aws::String& error) const; - - private: - Aws::String m_bucket; - std::shared_ptr m_s3Client; - std::shared_ptr m_limiter; - bool m_valid; - - static int GetStreamLength(STREAM_PTR stream); - }; -} // namespace News diff --git a/Code/Tools/News/NewsBuilder/UidGenerator.cpp b/Code/Tools/News/NewsBuilder/UidGenerator.cpp deleted file mode 100644 index 060f593996..0000000000 --- a/Code/Tools/News/NewsBuilder/UidGenerator.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "UidGenerator.h" - -#include - -namespace News -{ - - UidGenerator::UidGenerator() - { - srand(static_cast(time(nullptr))); - } - - int UidGenerator::GenerateUid() - { - int uid; - do - { - uid = rand(); - } - while (std::find(m_uids.begin(), m_uids.end(), uid) != m_uids.end()); - m_uids.push_back(uid); - return uid; - } - - int UidGenerator::AddUid(int uid) - { - if (std::find(m_uids.begin(), m_uids.end(), uid) == m_uids.end()) - { - m_uids.push_back(uid); - } - return uid; - } - - void UidGenerator::RemoveUid(int uid) - { - auto it = std::find(m_uids.begin(), m_uids.end(), uid); - if (it != m_uids.end()) - { - m_uids.erase(it); - } - } - - void UidGenerator::Clear() - { - m_uids.clear(); - } - -} diff --git a/Code/Tools/News/NewsBuilder/UidGenerator.h b/Code/Tools/News/NewsBuilder/UidGenerator.h deleted file mode 100644 index 825df9e340..0000000000 --- a/Code/Tools/News/NewsBuilder/UidGenerator.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -namespace News -{ - //! A simple unique id generator. - class UidGenerator - { - public: - UidGenerator(); - int GenerateUid(); - int AddUid(int uid); - void RemoveUid(int uid); - void Clear(); - - private: - std::vector m_uids; - }; -} diff --git a/Code/Tools/News/NewsBuilder/main.cpp b/Code/Tools/News/NewsBuilder/main.cpp deleted file mode 100644 index 6a43c681b1..0000000000 --- a/Code/Tools/News/NewsBuilder/main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include - -#include "Qt/NewsBuilder.h" -#include -#include -#include -#include - - -int main(int argc, char *argv[]) -{ - // Must be set before QApplication is initialized, so that we support HighDpi monitors, like the Retina displays - // on Windows 10 - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); - - QApplication a(argc, argv); - AZ::IO::FixedMaxPath engineRootPath; - { - AZ::ComponentApplication componentApplication; - auto settingsRegistry = AZ::SettingsRegistry::Get(); - settingsRegistry->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder); - } - News::NewsBuilder w(nullptr, engineRootPath); - w.show(); - return a.exec(); -} diff --git a/Code/Tools/News/NewsBuilder/news_builder.qrc b/Code/Tools/News/NewsBuilder/news_builder.qrc deleted file mode 100644 index 010ac598f1..0000000000 --- a/Code/Tools/News/NewsBuilder/news_builder.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - Resources/NewsBuilder.qss - - diff --git a/Code/Tools/News/NewsBuilder/news_builder_files.cmake b/Code/Tools/News/NewsBuilder/news_builder_files.cmake deleted file mode 100644 index c46e66a357..0000000000 --- a/Code/Tools/News/NewsBuilder/news_builder_files.cmake +++ /dev/null @@ -1,64 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - main.cpp - S3Connector.cpp - S3Connector.h - UidGenerator.cpp - UidGenerator.h - EndpointManager.cpp - EndpointManager.h - Qt/ArticleDetails.cpp - Qt/ArticleDetails.h - Qt/ArticleDetails.ui - Qt/ArticleDetailsContainer.cpp - Qt/ArticleDetailsContainer.h - Qt/ArticleDetailsContainer.ui - Qt/AwsDialog.ui - Qt/BuilderArticleViewContainer.cpp - Qt/BuilderArticleViewContainer.h - Qt/BuilderArticleViewContainer.ui - Qt/EndpointEntryView.cpp - Qt/EndpointEntryView.h - Qt/EndpointEntryView.ui - Qt/EndpointManagerView.cpp - Qt/EndpointManagerView.h - Qt/EndpointManagerView.ui - Qt/ImageItem.cpp - Qt/ImageItem.h - Qt/ImageItem.ui - Qt/LogContainer.cpp - Qt/LogContainer.h - Qt/LogContainer.ui - Qt/NewsBuilder.cpp - Qt/NewsBuilder.h - Qt/Newsbuilder.qrc - Qt/Newsbuilder.ui - Qt/QCustomMessageBox.cpp - Qt/QCustomMessageBox.h - Qt/QCustomMessageBox.ui - Qt/SelectImage.cpp - Qt/SelectImage.h - Qt/SelectImage.ui - ResourceManagement/BuilderResourceManifest.cpp - ResourceManagement/BuilderResourceManifest.h - ResourceManagement/DeleteDescriptor.cpp - ResourceManagement/DeleteDescriptor.h - ResourceManagement/ImageDescriptor.cpp - ResourceManagement/ImageDescriptor.h - ResourceManagement/UploadDescriptor.cpp - ResourceManagement/UploadDescriptor.h -) - -set(SKIP_UNITY_BUILD_INCLUSION_FILES - # Fix for unity causing the 'News::BuilderResourceManifest::UpdateResourceA' symbol to be unresolved - Qt/ArticleDetails.cpp - # Fix for unity causing the ' Aws::S3::S3Client::GetObjectA' symbol to be unresolved - S3Connector.cpp - -) diff --git a/Code/Tools/News/NewsShared/ErrorCodes.h b/Code/Tools/News/NewsShared/ErrorCodes.h deleted file mode 100644 index 444e0c6f67..0000000000 --- a/Code/Tools/News/NewsShared/ErrorCodes.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -namespace News -{ - enum class ErrorCode : int - { - None, - OutOfSync, - ManifestDownloadFail, - FailedToSync, - AlreadySyncing, - FailedToParseManifest, - MissingArticle, - NoEndpoint, - ManifestUploadFail, - S3Fail - }; - - inline extern const char* GetErrorMessage(ErrorCode errorCode) - { - static const char* errors[] - { - "", - "Your manifest is out of sync. Reopen the same endpoint and sync to resolve the conflict and try again.", - "Failed to download resource manifest", - "Failed to sync resources", - "Sync is already running", - "Failed to parse resource manifest", - "Could not find article, try syncing again", - "Missing or incorrect endpoint selected", - "Failed to upload resource manifest", - "Failed to init S3 connection" - }; - int errorCount = sizeof errors / sizeof errors[0]; - int typeIndex = static_cast(errorCode); - if (typeIndex < 0 || typeIndex >= errorCount) - { - return "Invalid error code"; - } - return errors[typeIndex]; - } -} // namespace News diff --git a/Code/Tools/News/NewsShared/LogType.h b/Code/Tools/News/NewsShared/LogType.h deleted file mode 100644 index 92834adc58..0000000000 --- a/Code/Tools/News/NewsShared/LogType.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace News { - enum LogType - { - LogOk, - LogInfo, - LogError, - LogWarning - }; -} // namespace News diff --git a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.cpp b/Code/Tools/News/NewsShared/Qt/ArticleErrorView.cpp deleted file mode 100644 index 6f2a7e3c9c..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleErrorView.h" -#include "NewsShared/Qt/ui_ArticleErrorView.h" - -using namespace News; - -ArticleErrorView::ArticleErrorView( - QWidget* parent) - : QWidget(parent) - , m_ui(new Ui::ArticleErrorViewWidget()) -{ - m_ui->setupUi(this); -} - -ArticleErrorView::~ArticleErrorView(){} - -#include "NewsShared/Qt/moc_ArticleErrorView.cpp" diff --git a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.h b/Code/Tools/News/NewsShared/Qt/ArticleErrorView.h deleted file mode 100644 index 3130690dc1..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class ArticleErrorViewWidget; -} - -namespace AzQtComponents -{ - class ExtendedLabel; -} - -namespace News -{ - class ArticleErrorView - : public QWidget - { - Q_OBJECT - public: - ArticleErrorView(QWidget* parent); - ~ArticleErrorView(); - - private: - QScopedPointer m_ui; - }; -} diff --git a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.ui b/Code/Tools/News/NewsShared/Qt/ArticleErrorView.ui deleted file mode 100644 index c94c636720..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleErrorView.ui +++ /dev/null @@ -1,239 +0,0 @@ - - - ArticleErrorViewWidget - - - - 0 - 0 - 192 - 228 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - ArticleView - - - background-color: none; text-align: left; - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - border: none; - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 14 - - - - - - - - 0 - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 14 - 20 - - - - - - - - 0 - - - - - - 160 - 90 - - - - - - - :/images/Resources/ErrorImage.jpg - - - - 160 - 90 - - - - - - - - Qt::Vertical - - - - 20 - 20 - - - - - - - - - 0 - 0 - - - - - Open Sans - 8 - 50 - false - - - - a { text-decoration: underline; color: red } - - - We couldn’t connect to the network or access our news database. To see the latest Open 3D Engine news, blogs, tutorials, and more, please visit the <a href="http://aws.amazon.com/lumberyard/">Lumberyard website</a>. - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - true - - - Qt::LinksAccessibleByMouse - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 14 - 20 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - - - -
diff --git a/Code/Tools/News/NewsShared/Qt/ArticleView.cpp b/Code/Tools/News/NewsShared/Qt/ArticleView.cpp deleted file mode 100644 index 082a29d38a..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleView.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleView.h" - -#include - -AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: '...' needs to have dll-interface to be used by clients of class '...' -#include "NewsShared/ResourceManagement/ArticleDescriptor.h" -#include "NewsShared/Qt/ui_ArticleView.h" -#include "NewsShared/Qt/ui_PinnedArticleView.h" -#include "NewsShared/ResourceManagement/ResourceManifest.h" -#include "NewsShared/ResourceManagement/Resource.h" - - -#include -#include -AZ_POP_DISABLE_WARNING - -using namespace News; - -ArticleView::ArticleView( - QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest) - : QWidget(parent) - , m_pArticle(new ArticleDescriptor(article)) - , m_manifest(manifest) - , m_icon(nullptr) -{ - -} - -void ArticleView::Update() -{ - Q_ASSERT(m_widgetImageFrame && m_widgetTitle && m_widgetBody); - - auto pResource = m_manifest.FindById(m_pArticle->GetResource().GetId()); - m_pArticle.reset(); - if (pResource) - { - m_pArticle = QSharedPointer(new ArticleDescriptor(*pResource)); - m_widgetTitle->setText(m_pArticle->GetTitle()); - m_widgetBody->setText(m_pArticle->GetBody()); - auto pImageResource = m_manifest.FindById(m_pArticle->GetImageId()); - if (pImageResource) - { - QPixmap pixmap; - if (pixmap.loadFromData(pImageResource->GetData())) - { - if (!m_icon) - { - m_icon = new AzQtComponents::ExtendedLabel(this); - m_icon->setStyleSheet("border: none;"); - m_icon->setAlignment(Qt::AlignCenter); - static_cast( - m_widgetImageFrame->layout())->insertWidget(0, m_icon); - connect(m_icon, &AzQtComponents::ExtendedLabel::clicked, this, &ArticleView::articleSelectedSlot); - } - m_icon->setPixmap(pixmap.scaled(m_widgetImageFrame->minimumWidth(), - m_widgetImageFrame->minimumHeight(), - Qt::KeepAspectRatioByExpanding)); - } - else - { - RemoveIcon(); - } - } - else - { - RemoveIcon(); - } - } -} - -void ArticleView::mousePressEvent([[maybe_unused]] QMouseEvent* event) -{ - articleSelectedSlot(); -} - -void ArticleView::RemoveIcon() -{ - if (m_icon) - { - delete m_icon; - m_icon = nullptr; - } -} - -void ArticleView::linkActivatedSlot(const QString& link) -{ - QDesktopServices::openUrl(QUrl(link)); - Q_EMIT linkActivatedSignal(link); -} - -void ArticleView::articleSelectedSlot() -{ - Q_EMIT articleSelectedSignal(m_pArticle->GetResource().GetId()); -} - -QSharedPointer ArticleView::GetArticle() const -{ - return m_pArticle; -} - -void ArticleView::SetupViewWidget(QFrame* widgetImageFrame, AzQtComponents::ExtendedLabel* widgetTitle, AzQtComponents::ExtendedLabel* widgetBody) -{ - Q_ASSERT(m_widgetImageFrame == nullptr && m_widgetTitle == nullptr && m_widgetBody == nullptr); - - m_widgetImageFrame = widgetImageFrame; - m_widgetTitle = widgetTitle; - m_widgetBody = widgetBody; - - connect(m_widgetTitle, &QLabel::linkActivated, this, &ArticleView::linkActivatedSlot); - connect(m_widgetBody, &QLabel::linkActivated, this, &ArticleView::linkActivatedSlot); - connect(m_widgetTitle, &AzQtComponents::ExtendedLabel::clicked, this, &ArticleView::articleSelectedSlot); - connect(m_widgetBody, &AzQtComponents::ExtendedLabel::clicked, this, &ArticleView::articleSelectedSlot); - - Q_ASSERT(m_widgetImageFrame && m_widgetTitle && m_widgetBody); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ArticleViewDefaultWidget -//////////////////////////////////////////////////////////////////////////////////////////////////// -ArticleViewDefaultWidget::ArticleViewDefaultWidget(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest) - : ArticleView(parent, article, manifest) - , m_ui(new Ui::ArticleViewWidget()) -{ - m_ui->setupUi(this); - SetupViewWidget(m_ui->imageFrame, m_ui->titleLabel, m_ui->bodyLabel); - Update(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ArticleViewPinnedWidget -//////////////////////////////////////////////////////////////////////////////////////////////////// -ArticleViewPinnedWidget::ArticleViewPinnedWidget(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest) - : ArticleView(parent, article, manifest) - , m_ui(new Ui::PinnedArticleViewWidget()) -{ - m_ui->setupUi(this); - SetupViewWidget(m_ui->imageFrame, m_ui->titleLabel, m_ui->bodyLabel); - Update(); -} - -#include "NewsShared/Qt/moc_ArticleView.cpp" diff --git a/Code/Tools/News/NewsShared/Qt/ArticleView.h b/Code/Tools/News/NewsShared/Qt/ArticleView.h deleted file mode 100644 index 16a29732f0..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleView.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class ArticleViewWidget; - class PinnedArticleViewWidget; -} - -namespace AzQtComponents -{ - class ExtendedLabel; -} - -class QFrame; - -namespace News -{ - class ArticleDescriptor; - class ResourceManifest; - - class ArticleView - : public QWidget - { - Q_OBJECT - public: - ArticleView(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest); - ~ArticleView() = default; - - void Update(); - QSharedPointer GetArticle() const; - - Q_SIGNALS: - void articleSelectedSignal(QString resourceId); - void linkActivatedSignal(const QString& link); - - protected: - void SetupViewWidget(QFrame* widgetImageFrame, AzQtComponents::ExtendedLabel* widgetTitle, AzQtComponents::ExtendedLabel* widgetBody); - void mousePressEvent(QMouseEvent* event); - - private: - - QFrame* m_widgetImageFrame = nullptr; - AzQtComponents::ExtendedLabel* m_widgetTitle = nullptr; - AzQtComponents::ExtendedLabel* m_widgetBody = nullptr; - AzQtComponents::ExtendedLabel* m_icon = nullptr; - - QSharedPointer m_pArticle; - const ResourceManifest& m_manifest; - - void RemoveIcon(); - - private Q_SLOTS: - void linkActivatedSlot(const QString& link); - void articleSelectedSlot(); - }; - - class ArticleViewDefaultWidget : public ArticleView - { - public: - ArticleViewDefaultWidget(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest); - ~ArticleViewDefaultWidget() = default; - - private: - Ui::ArticleViewWidget* m_ui = nullptr; - }; - - class ArticleViewPinnedWidget : public ArticleView - { - public: - ArticleViewPinnedWidget(QWidget* parent, - const ArticleDescriptor& article, - const ResourceManifest& manifest); - ~ArticleViewPinnedWidget() = default; - - private: - Ui::PinnedArticleViewWidget* m_ui = nullptr; - }; -} diff --git a/Code/Tools/News/NewsShared/Qt/ArticleView.ui b/Code/Tools/News/NewsShared/Qt/ArticleView.ui deleted file mode 100644 index 67d1d8857b..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleView.ui +++ /dev/null @@ -1,244 +0,0 @@ - - - ArticleViewWidget - - - - 0 - 0 - 430 - 376 - - - - - 0 - 0 - - - - - 430 - 0 - - - - - 430 - 16777215 - - - - ArticleView - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - default - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 430 - 184 - - - - - 430 - 184 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 20 - - - - - - - - - 0 - 0 - - - - - Open Sans - 14 - 50 - false - - - - Title: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 12 - - - - - - - - - 0 - 0 - - - - - Open Sans - 8 - 50 - false - - - - Body - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - 0 - - - 0 - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 24 - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - -
diff --git a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.cpp b/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.cpp deleted file mode 100644 index 1d718d1bb8..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleViewContainer.h" -#include "ArticleView.h" -#include "NewsShared/ResourceManagement/ResourceManifest.h" -#include "NewsShared/ResourceManagement/ArticleDescriptor.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "NewsShared/Qt/ArticleErrorView.h" -#include "NewsShared/Qt/KeepInTouchView.h" -#include "NewsShared/Qt/ui_ArticleViewContainer.h" - -#include -#include - -namespace News -{ - - ArticleViewContainer::ArticleViewContainer(QWidget* parent, ResourceManifest& manifest) - : QWidget(parent) - , m_ui(new Ui::ArticleViewContainerWidget) - , m_manifest(manifest) - , m_loadingLabel(nullptr) - , m_errorMessage(nullptr) - { - m_ui->setupUi(this); - AddLoadingMessage(); - - m_keepInTouchViewWidget = new KeepInTouchView(this); - m_keepInTouchViewWidget->setVisible(false); - connect(m_keepInTouchViewWidget, &KeepInTouchView::linkActivatedSignal, - this, &ArticleViewContainer::linkActivatedSignal); - } - - ArticleViewContainer::~ArticleViewContainer() {} - - void ArticleViewContainer::PopulateArticles() - { - Clear(); - - bool articlesFound = false; - for (auto id : m_manifest.GetOrder()) - { - auto pResource = m_manifest.FindById(id); - if (pResource && pResource->GetType().compare("article") == 0) - { - AddArticleView(ArticleDescriptor(*pResource)); - articlesFound = true; - } - } - - if (!articlesFound) - { - AddErrorMessage(); - } - else - { - auto layout = static_cast(m_ui->articleViewContents->layout()); - layout->insertWidget(layout->count() - 1, m_keepInTouchViewWidget); - m_keepInTouchViewWidget->setVisible(true); - } - - qApp->processEvents(); - } - - ArticleView* ArticleViewContainer::FindById(const QString& id) - { - auto it = std::find_if( - m_articles.begin(), - m_articles.end(), - [id](ArticleView* articleView) -> bool - { - if (!articleView) - { - return false; - } - return articleView->GetArticle()->GetResource().GetId().compare(id) == 0; - }); - if (it == m_articles.end()) - { - return nullptr; - } - return *it; - } - - void ArticleViewContainer::AddArticleView(const ArticleDescriptor& articleDesc, int articlePosition) - { - ClearError(); - - ArticleView* view = CreateArticleView(articleDesc); - if (view == nullptr) - { - return; - } - - m_articles.append(view); - - connect(view, &ArticleView::articleSelectedSignal, - this, &ArticleViewContainer::articleSelectedSlot); - connect(view, &ArticleView::linkActivatedSignal, - this, &ArticleViewContainer::linkActivatedSignal); - - auto layout = static_cast(m_ui->articleViewContents->layout()); - if (articlePosition == -1) - { - articlePosition = layout->count() - 1; - } - - layout->insertWidget(articlePosition, view); - qApp->processEvents(); - } - - void ArticleViewContainer::DeleteArticleView(ArticleView* view) - { - m_articles.removeAll(view); - m_ui->articleViewContents->layout()->removeWidget(view); - delete view; - } - - void ArticleViewContainer::ForceRefreshArticleView(ArticleView* articleView) - { - if (articleView == nullptr) - { - return; - } - - QSharedPointer articleDesc = articleView->GetArticle(); - auto layout = static_cast(m_ui->articleViewContents->layout()); - const int viewIndex = layout->indexOf(articleView); - - DeleteArticleView(articleView); - AddArticleView(*articleDesc, viewIndex); - } - - void ArticleViewContainer::ScrollToView(ArticleView* view) const - { - m_ui->previewArea->ensureWidgetVisible(view); - } - - void ArticleViewContainer::ClearError() - { - //delete loading label - if (m_loadingLabel) - { - delete m_loadingLabel; - m_loadingLabel = nullptr; - } - - //delete error message - if (m_errorMessage) - { - delete m_errorMessage; - m_errorMessage = nullptr; - } - } - - void ArticleViewContainer::articleSelectedSlot(QString id) - { - emit articleSelectedSignal(id); - } - - void ArticleViewContainer::UpdateArticleOrder(ArticleView* view, bool direction) const - { - QVBoxLayout* layout = qobject_cast(m_ui->articleViewContents->layout()); - - const int index = layout->indexOf(view); - - if (direction && index == 0) - { - return; - } - - if (!direction && index == layout->count() - 2) - { - return; - } - - const int newIndex = direction ? index - 1 : index + 1; - layout->removeWidget(view); - layout->insertWidget(newIndex, view); - } - - void ArticleViewContainer::AddLoadingMessage() - { - if (m_errorMessage) - { - delete m_errorMessage; - m_errorMessage = nullptr; - } - - if (!m_loadingLabel) - { - m_loadingLabel = new QLabel(this); - m_loadingLabel->setText("Retrieving news..."); - auto layout = static_cast(m_ui->articleViewContents->layout()); - layout->insertWidget(0, m_loadingLabel); - } - } - - void ArticleViewContainer::AddErrorMessage() - { - if (m_loadingLabel) - { - delete m_loadingLabel; - m_loadingLabel = nullptr; - } - - if (!m_errorMessage) - { - m_errorMessage = new ArticleErrorView(this); - auto layout = static_cast(m_ui->articleViewContents->layout()); - layout->insertWidget(0, m_errorMessage); - } - } - - void ArticleViewContainer::Clear() - { - ClearError(); - - for (auto articleView : m_articles) - { - delete articleView; - } - - m_articles.clear(); - } - - ArticleViewContainer::ArticleStyle ArticleViewContainer::GetArticleStyleEnumFromString(const QString& articleStyleStr) const - { - static const QMap articleStyleStringEnumMap = { - { "default", ArticleStyle::Default }, - { "pinned", ArticleStyle::Pinned } - }; - - if (articleStyleStringEnumMap.contains(articleStyleStr) == false) - { - Q_ASSERT(false); - return ArticleStyle::Default; - } - - return articleStyleStringEnumMap.value(articleStyleStr); - } - - ArticleView* ArticleViewContainer::CreateArticleView(const ArticleDescriptor& articleDesc) - { - ArticleStyle articleStyle = GetArticleStyleEnumFromString(articleDesc.GetArticleStyle()); - - switch(articleStyle) - { - case ArticleStyle::Default: - return new ArticleViewDefaultWidget(this, articleDesc, m_manifest); - case ArticleStyle::Pinned: - return new ArticleViewPinnedWidget(this, articleDesc, m_manifest); - default: - Q_ASSERT(false); - return nullptr; - } - } - -} - -#include "NewsShared/Qt/moc_ArticleViewContainer.cpp" diff --git a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.h b/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.h deleted file mode 100644 index c0ae3b2701..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include "NewsShared/LogType.h" - -#include -#include -#endif - -class QLabel; - -namespace Ui -{ - class ArticleViewContainerWidget; -} - -namespace News -{ - class Resource; - class ArticleView; - class ArticleDescriptor; - class ResourceManifest; - class ArticleErrorView; - class KeepInTouchView; - - class ArticleViewContainer - : public QWidget - { - Q_OBJECT - - enum ArticleStyle - { - Default, - Pinned - }; - - public: - explicit ArticleViewContainer(QWidget* parent, ResourceManifest& manifest); - ~ArticleViewContainer(); - - virtual void PopulateArticles(); - ArticleView* FindById(const QString& id); - void AddArticleView(const ArticleDescriptor& articleDesc, int articlePosition = -1); - void DeleteArticleView(ArticleView* view); - void ForceRefreshArticleView(ArticleView* articleView); - void ScrollToView(ArticleView* view) const; - void UpdateArticleOrder(ArticleView* view, bool direction) const; - void AddLoadingMessage(); - void AddErrorMessage(); - void Clear(); - - Q_SIGNALS: - void articleSelectedSignal(QString resourceId); - void addArticle(Resource* article); - void logSignal(QString text, LogType logType = LogInfo); - void scrolled(); - void linkActivatedSignal(const QString& link); - - private: - QScopedPointer m_ui; - QList m_articles; - ResourceManifest& m_manifest; - QLabel* m_loadingLabel; - ArticleErrorView* m_errorMessage; - KeepInTouchView* m_keepInTouchViewWidget = nullptr; - - void ClearError(); - ArticleStyle GetArticleStyleEnumFromString(const QString& articleStyleStr) const; - ArticleView* CreateArticleView(const ArticleDescriptor& articleDesc); - - private Q_SLOTS: - virtual void articleSelectedSlot(QString id); - }; -} diff --git a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.ui b/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.ui deleted file mode 100644 index dfb71ea31f..0000000000 --- a/Code/Tools/News/NewsShared/Qt/ArticleViewContainer.ui +++ /dev/null @@ -1,104 +0,0 @@ - - - ArticleViewContainerWidget - - - - 0 - 0 - 606 - 753 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOff - - - true - - - Qt::AlignHCenter|Qt::AlignTop - - - - - 0 - 0 - 589 - 753 - - - - - 16 - - - 15 - - - 15 - - - 15 - - - 15 - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - - - - - - diff --git a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.cpp b/Code/Tools/News/NewsShared/Qt/KeepInTouchView.cpp deleted file mode 100644 index 43c32c43fc..0000000000 --- a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "KeepInTouchView.h" -#include "NewsShared/Qt/ui_KeepInTouchView.h" - -#include -#include -#include -#include - -namespace News -{ - KeepInTouchView::KeepInTouchView(QWidget* parent) - : QWidget(parent) - , m_ui(new Ui::KeepInTouchViewWidget()) - { - m_ui->setupUi(this); - - m_ui->twich_container->setCursor(Qt::PointingHandCursor); - m_ui->twitter_container->setCursor(Qt::PointingHandCursor); - m_ui->youtube_container->setCursor(Qt::PointingHandCursor); - m_ui->facebook_container->setCursor(Qt::PointingHandCursor); - - m_ui->twich_container->installEventFilter(this); - m_ui->twitter_container->installEventFilter(this); - m_ui->youtube_container->installEventFilter(this); - m_ui->facebook_container->installEventFilter(this); - } - - bool KeepInTouchView::eventFilter(QObject *watched, QEvent *event) - { - if (event->type() == QEvent::MouseButtonRelease) - { - if (watched == m_ui->twich_container) - { - return LaunchSocialMediaUrl(SocialMediaType::Twitch); - } - else if (watched == m_ui->twitter_container) - { - return LaunchSocialMediaUrl(SocialMediaType::Twitter); - } - else if (watched == m_ui->youtube_container) - { - return LaunchSocialMediaUrl(SocialMediaType::YouTube); - } - else if (watched == m_ui->facebook_container) - { - return LaunchSocialMediaUrl(SocialMediaType::Facebook); - } - } - - return QWidget::eventFilter(watched, event); - } - - bool KeepInTouchView::LaunchSocialMediaUrl(SocialMediaType type) - { - static const QMap socialMediaTypeToUrlMap = - { - { SocialMediaType::Twitch, m_twitchUrl }, - { SocialMediaType::Twitter, m_twitterUrl }, - { SocialMediaType::YouTube, m_youtubeUrl }, - { SocialMediaType::Facebook, m_facebookUrl } - }; - - if (socialMediaTypeToUrlMap.contains(type) == false) - { - return false; - } - - QString link = socialMediaTypeToUrlMap[type]; - Q_EMIT linkActivatedSignal(link); - - return QDesktopServices::openUrl(QUrl(link)); - } -} - -#include "NewsShared/Qt/moc_KeepInTouchView.cpp" diff --git a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.h b/Code/Tools/News/NewsShared/Qt/KeepInTouchView.h deleted file mode 100644 index 5d5c6a9e36..0000000000 --- a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#endif - -namespace Ui -{ - class KeepInTouchViewWidget; -} - -namespace News -{ - class KeepInTouchView - : public QWidget - { - Q_OBJECT - - enum class SocialMediaType - { - Twitch, - Twitter, - YouTube, - Facebook - }; - - public: - KeepInTouchView(QWidget* parent); - ~KeepInTouchView() = default; - - bool eventFilter(QObject *watched, QEvent *event); - - Q_SIGNALS: - void linkActivatedSignal(const QString& link); - - private: - bool LaunchSocialMediaUrl(SocialMediaType type); - - Ui::KeepInTouchViewWidget* m_ui = nullptr; - - const char* m_twitchUrl = "https://docs.aws.amazon.com/console/lumberyard/twitch"; - const char* m_twitterUrl = "https://docs.aws.amazon.com/console/lumberyard/twitter"; - const char* m_youtubeUrl = "https://docs.aws.amazon.com/console/lumberyard/youtube"; - const char* m_facebookUrl = "https://docs.aws.amazon.com/console/lumberyard/facebook"; - }; -} diff --git a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.ui b/Code/Tools/News/NewsShared/Qt/KeepInTouchView.ui deleted file mode 100644 index 076059f49d..0000000000 --- a/Code/Tools/News/NewsShared/Qt/KeepInTouchView.ui +++ /dev/null @@ -1,423 +0,0 @@ - - - KeepInTouchViewWidget - - - - 0 - 0 - 430 - 336 - - - - - 0 - 0 - - - - - 430 - 0 - - - - - 430 - 16777215 - - - - ArticleView - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 430 - 184 - - - - - 430 - 184 - - - - - - - :/images/Resources/KeepInTouchBanner.jpg - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 20 - - - - - - - - - 0 - 0 - - - - - Open Sans - 14 - 50 - false - - - - Keep in touch! - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 12 - - - - - - - - - 0 - 0 - - - - - Open Sans - 8 - 50 - false - - - - Want to know the latest news at AmazonGameDev? Sign up for our newsletter and use the following links to find us! - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - 0 - - - 0 - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 16 - - - - - - - - background: transparent; - - - - 20 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 8 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - :/images/Resources/icon_twitch.png - - - - - - - Twitch - - - - - - - - - - - 0 - 0 - - - - - 8 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - :/images/Resources/icon_twitter.png - - - - - - - Twitter - - - - - - - - - - - 0 - 0 - - - - - 8 - - - 0 - - - 0 - - - 0 - - - - - - - - :/images/Resources/icon_youtube.png - - - - - - - Youtube - - - - - - - - - - - 8 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - :/images/Resources/icon_facebook.png - - - - - - - Facebook - - - - - - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - - - -
diff --git a/Code/Tools/News/NewsShared/Qt/NewsShared.qrc b/Code/Tools/News/NewsShared/Qt/NewsShared.qrc deleted file mode 100644 index 8d5b84494b..0000000000 --- a/Code/Tools/News/NewsShared/Qt/NewsShared.qrc +++ /dev/null @@ -1,10 +0,0 @@ - - - ../Resources/ErrorImage.jpg - ../Resources/KeepInTouchBanner.jpg - ../Resources/icon_facebook.png - ../Resources/icon_twitch.png - ../Resources/icon_twitter.png - ../Resources/icon_youtube.png - - diff --git a/Code/Tools/News/NewsShared/Qt/PinnedArticleView.ui b/Code/Tools/News/NewsShared/Qt/PinnedArticleView.ui deleted file mode 100644 index 928046a064..0000000000 --- a/Code/Tools/News/NewsShared/Qt/PinnedArticleView.ui +++ /dev/null @@ -1,260 +0,0 @@ - - - PinnedArticleViewWidget - - - - 0 - 0 - 430 - 376 - - - - - 0 - 0 - - - - - 430 - 0 - - - - - 430 - 16777215 - - - - ArticleView - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - pinned - - - - 12 - - - 16 - - - 16 - - - 16 - - - 16 - - - - - - 128 - 0 - - - - - 128 - 16777215 - - - - background-color: transparent; - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 128 - 96 - - - - - 128 - 96 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - background-color: transparent; - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - Open Sans - 14 - 50 - false - - - - Title: - - - true - - - false - - - Qt::LinksAccessibleByMouse - - - sectionTitle - - - - - - - - 0 - 0 - - - - - Open Sans - 8 - 50 - false - - - - Body - - - true - - - false - - - Qt::LinksAccessibleByMouse - - - - - - - - - - - - - - AzQtComponents::ExtendedLabel - QLabel -
AzQtComponents/Components/ExtendedLabel.h
-
-
- - -
diff --git a/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.cpp b/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.cpp deleted file mode 100644 index c26d2357d7..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ArticleDescriptor.h" -#include "Resource.h" - -#include -#include - -using namespace News; - -ArticleDescriptor::ArticleDescriptor( - Resource& resource) - : JsonDescriptor(resource) - , m_imageId(m_json["image"].toString()) - , m_title(m_json["title"].toString()) - , m_body(m_json["body"].toString()) - , m_order(m_json["order"].toInt()) -{ - if (m_json.contains("articleStyle") == true) - { - m_articleStyle = m_json["articleStyle"].toString(); - } -} - -void ArticleDescriptor::Update() const -{ - QJsonObject json; - json["image"] = m_imageId; - json["title"] = m_title; - json["body"] = m_body; - json["order"] = m_order; - json["articleStyle"] = m_articleStyle; - QJsonDocument doc(json); - QByteArray data = doc.toJson(QJsonDocument::Compact).toStdString().data(); - m_resource.SetData(data); -} - -const QString& ArticleDescriptor::GetArticleStyle() const -{ - return m_articleStyle; -} - -void ArticleDescriptor::SetArticleStyle(const QString& style) -{ - m_articleStyle = style; -} - -const QString& ArticleDescriptor::GetImageId() const -{ - return m_imageId; -} - -void ArticleDescriptor::SetImageId(const QString& imageId) -{ - m_imageId = imageId; -} - -const QString& ArticleDescriptor::GetTitle() const -{ - return m_title; -} - -void ArticleDescriptor::SetTitle(const QString& title) -{ - m_title = title; -} - -const QString& ArticleDescriptor::GetBody() const -{ - return m_body; -} - -void ArticleDescriptor::SetBody(const QString& body) -{ - m_body = body; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.h b/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.h deleted file mode 100644 index c0ca459cf4..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/ArticleDescriptor.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "JsonDescriptor.h" - -#include - -namespace News -{ - class Resource; - - //! ArticleDescriptor represents Resource as an article - class ArticleDescriptor - : public JsonDescriptor - { - public: - explicit ArticleDescriptor(Resource& resource); - - //! If article was modified, call this to update resource data - void Update() const; - - const QString& GetArticleStyle() const; - - void SetArticleStyle(const QString& style); - - const QString& GetImageId() const; - - void SetImageId(const QString& imageId); - - const QString& GetTitle() const; - - void SetTitle(const QString& title); - - const QString& GetBody() const; - - void SetBody(const QString& body); - - private: - QString m_articleStyle = "default"; - QString m_imageId; - QString m_title; - QString m_body; - int m_order; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.cpp b/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.cpp deleted file mode 100644 index 0d21a18c05..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "Descriptor.h" - -using namespace News; - -Descriptor::Descriptor(Resource& resource) - : m_resource(resource) {} - -Descriptor::~Descriptor() {} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.h b/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.h deleted file mode 100644 index 3d56037543..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/Descriptor.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace News -{ - class Resource; - - //! Descriptor is a simple solution to add additional functionality to a Resource - /*! - Some descriptors can only work with certain resource types, like AerticleDescriptor - */ - class Descriptor - { - public: - explicit Descriptor(Resource& resource); - virtual ~Descriptor(); - - Resource& GetResource() const - { - return m_resource; - } - - protected: - Resource& m_resource; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.cpp b/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.cpp deleted file mode 100644 index 5e71c8f10b..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "JsonDescriptor.h" -#include "Resource.h" - -#include - -using namespace News; - -JsonDescriptor::JsonDescriptor(Resource& resource) - : Descriptor(resource) - , m_doc(QJsonDocument::fromJson(m_resource.GetData())) - , m_json(m_doc.object()) -{ -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.h b/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.h deleted file mode 100644 index 286e66c4ac..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/JsonDescriptor.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include "Descriptor.h" - -#include -#include - -namespace News -{ - //! JsonDescriptor assumes Resource is a JSON file - class JsonDescriptor - : public Descriptor - { - public: - explicit JsonDescriptor(Resource& resource); - - protected: - QJsonDocument m_doc; - QJsonObject m_json; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.cpp b/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.cpp deleted file mode 100644 index e70285fd31..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "QtDownloadManager.h" -#include "QtDownloader.h" - -namespace News -{ - -QtDownloadManager::QtDownloadManager() - : QObject() - , m_worker(new QtDownloader) // this will start the thread which does downloads -{ - // make sure the response handlers are queued connections as the worker runs in a different thread - connect(m_worker, &QtDownloader::failed, this, &QtDownloadManager::failedReply, Qt::QueuedConnection); - connect(m_worker, &QtDownloader::successfullyFinished, this, &QtDownloadManager::successfulReply, Qt::QueuedConnection); -} - -QtDownloadManager::~QtDownloadManager() -{ - // NOTE: we don't delete the QtDownloader; it deletes itself. - // We just tell it to stop - m_worker->Finish(); -} - -void QtDownloadManager::Download(const QString& url, - std::function downloadSuccessCallback, - std::function downloadFailCallback) -{ - int downloadId = m_worker->Download(url); - m_downloads[downloadId] = { downloadSuccessCallback, downloadFailCallback }; -} - -void QtDownloadManager::Abort() -{ - m_worker->Abort(); - m_downloads.clear(); -} - -void QtDownloadManager::successfulReply(int downloadId, QByteArray data) -{ - m_downloads[downloadId].downloadSuccessCallback(data); - m_downloads.remove(downloadId); -} - -void QtDownloadManager::failedReply(int downloadId) -{ - m_downloads[downloadId].downloadFailCallback(); - m_downloads.remove(downloadId); -} - -} // namespace News - -#include "NewsShared/ResourceManagement/moc_QtDownloadManager.cpp" diff --git a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.h b/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.h deleted file mode 100644 index 6a7c93a51f..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloadManager.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include - -#include -#include -#endif - -namespace News -{ - class QtDownloader; - - //! QtDownloadManager handles multiple asynchronous downloads - class QtDownloadManager - : public QObject - { - Q_OBJECT - public: - QtDownloadManager(); - ~QtDownloadManager(); - - //! Asynchronously download a file from the input url and return it as QByteArray via the success callback - /*! - \param url - file url to download - \param downloadSuccessCallback - if download is successful pass file's data as QByteArray - \param downloadFailCallback - if download failed, pass error message - */ - void Download(const QString& url, - std::function downloadSuccessCallback, - std::function downloadFailCallback); - - //! Aborts all currently active downloads. Success/failure callbacks will not be called. - void Abort(); - - private: - void successfulReply(int downloadId, QByteArray data); - void failedReply(int downloadId); - - QtDownloader* m_worker = nullptr; - - struct DownloadResponses - { - std::function downloadSuccessCallback; - std::function downloadFailCallback; - }; - QMap m_downloads; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.cpp b/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.cpp deleted file mode 100644 index 0139ec5344..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "QtDownloader.h" - -#include -#include -#include -#include - - -namespace News -{ - QtDownloader::QtDownloader() - : m_thread(new QThread()) - { - // make sure that everything that QObject::connects to us knows we're running in a different thread - moveToThread(m_thread); - - // handle clean up of both ourselves and of our thread. - // We manage thread clean up so that it can keep running and be cleaned up later, regardless of what - // the thing that created the QtDownloader does - connect(m_thread, &QThread::finished, m_thread, [this] { - m_thread->deleteLater(); - deleteLater(); - }); - - auto abortDownloadsHandler = [this] { - auto replies = m_downloads.keys(); - for (QNetworkReply* reply : replies) - { - reply->abort(); - } - - m_downloads.clear(); - }; - - auto queueDownloadHandler = [this](int downloadId, QString url) { - if (m_networkManager) - { - QNetworkReply* reply = m_networkManager->get(QNetworkRequest(QUrl(url))); - m_downloads.insert(reply, downloadId); - } - }; - - auto createNetworkManagerHandler = [this] { - m_networkManager = new QNetworkAccessManager; - connect(m_networkManager, &QNetworkAccessManager::finished, this, &QtDownloader::downloadFinished); - }; - - auto deleteNetworkManagerHandler = [this] { - delete m_networkManager; - m_networkManager = nullptr; - }; - - auto quitHandler = [this] { - // call quit via this callback, so that it executes in the running thread. - // QThread::quit() is actually blocking and waits until everything finishes, so - // we don't want to call it in the main thread - m_thread->quit(); - }; - - // make sure the response handlers are queued connections as the worker runs in one thread, but these triggers - // will be emitted from the main thread - connect(this, &QtDownloader::triggerAbortAll, this, abortDownloadsHandler, Qt::QueuedConnection); - connect(this, &QtDownloader::triggerDownload, this, queueDownloadHandler, Qt::QueuedConnection); - connect(this, &QtDownloader::triggerQuit, this, quitHandler, Qt::QueuedConnection); - - // create/delete the QNetworkAccessManager in our thread, to ensure that any slowdowns caused by - // having to create network connectors / load drivers are done in our non-ui thread. - // make sure that these connections are direct so that network requests can't predate the network engine itself - connect(m_thread, &QThread::started, this, createNetworkManagerHandler, Qt::DirectConnection); - connect(m_thread, &QThread::finished, this, deleteNetworkManagerHandler, Qt::DirectConnection); - - m_thread->start(); - } - - QtDownloader::~QtDownloader() - { - } - - int QtDownloader::Download(const QString& url) - { - // create a unique id for this download - int downloadId = m_lastId++; - - // trigger a download running in our worker thread - Q_EMIT triggerDownload(downloadId, url); - - return downloadId; - } - - void QtDownloader::Abort() - { - // trigger an abort in our worker thread - Q_EMIT triggerAbortAll(); - } - - void QtDownloader::Finish() - { - // trigger a quit in our worker thread - Q_EMIT triggerQuit(); - } - - void QtDownloader::downloadFinished(QNetworkReply* reply) - { - // Note: this will run in our worker thread - int downloadId = m_downloads[reply]; - - // emit the signal back to the main thread indicating that we're finished, either - // successfully or unsuccessfully - if (reply->error() == QNetworkReply::NoError) - { - Q_EMIT successfullyFinished(downloadId, reply->readAll()); - } - else - { - Q_EMIT failed(downloadId); - } - - // clean up the reply; have to do this later, according to the Qt docs - reply->deleteLater(); - - // make sure to remove our reference to this reply from our list of active downloads - m_downloads.remove(reply); - } - - #include "NewsShared/ResourceManagement/moc_QtDownloader.cpp" -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.h b/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.h deleted file mode 100644 index 0dcc86e951..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/QtDownloader.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#endif - -class QNetworkAccessManager; -class QNetworkReply; -class QThread; - -namespace News -{ - //! QtDownloader is a wrapper around Qt's file download functions - /*! - The QtDownloader spins up another thread and does all downloads in that thread. - The public slot methods (Finish, Download and Abort) can all be called from any thread. - The response signals (successfullyFinished and failed) should be QObject::connect to with - Qt::QueuedConnection, as they will be emitted from the worker thread. - */ - class QtDownloader - : public QObject - { - Q_OBJECT - - public: - QtDownloader(); - ~QtDownloader(); - - public Q_SLOTS: - void Finish(); - - int Download(const QString& url); - void Abort(); - - Q_SIGNALS: - void successfullyFinished(int downloadId, QByteArray data); - void failed(int downloadId); - - // *********************************************** - // private - DO NOT CONNECT TO outside of the class! - // (qt signals can't be made private) - void triggerAbortAll(); - void triggerDownload(int downloadId, QString url); - void triggerQuit(); - // *********************************************** - - private: - void downloadFinished(QNetworkReply* reply); - - int m_lastId = 0; - - QMap m_downloads; - QNetworkAccessManager* m_networkManager = nullptr; - QThread* m_thread; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/Resource.cpp b/Code/Tools/News/NewsShared/ResourceManagement/Resource.cpp deleted file mode 100644 index d40b66d6d7..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/Resource.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "Resource.h" - -#include - -using namespace News; - -Resource::Resource(const QJsonObject& json) - : Resource( - json["id"].toString(), - QByteArray(), - json["url"].toString(), - json["type"].toString(), - json["refCount"].toInt(), - json["version"].toInt()) {} - -Resource::Resource(const QString& id, const QString& type) - : Resource( - id, - QByteArray(), - "", - type, - 1, - 0) {} - -Resource::Resource(const QString& id, - const QByteArray& data, - [[maybe_unused]] const QString& url, - const QString& type, - int refCount, - int version) - : m_id(id) - , m_data(data) - , m_type(type) - , m_refCount(refCount) - , m_version(version) {} - -Resource::~Resource() {} - -void Resource::Write(QJsonObject& json) const -{ - json["id"] = m_id; - json["type"] = m_type; - json["refCount"] = m_refCount; - json["version"] = m_version; -} - -QString Resource::GetId() const -{ - return m_id; -} - -void Resource::SetId(const QString& id) -{ - m_id = id; -} - -QByteArray Resource::GetData() const -{ - return m_data; -} - -void Resource::SetData(QByteArray data) -{ - m_data = data; -} - -QString Resource::GetType() const -{ - return m_type; -} - -int Resource::GetRefCount() const -{ - return m_refCount; -} - -void Resource::SetRefCount(int refCount) -{ - m_refCount = refCount; -} - -int Resource::GetVersion() const -{ - return m_version; -} - -void Resource::SetVersion(int version) -{ - m_version = version; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/Resource.h b/Code/Tools/News/NewsShared/ResourceManagement/Resource.h deleted file mode 100644 index 1174fea788..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/Resource.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -class QJsonObject; - -namespace News -{ - class Descriptor; - - //! Resource is a central element of in-editor messages - //! It represents articles, images, and anything else that is part of news feed - class Resource - { - public: - //! resources are stored as json objects in \ref News::ResourceManifest - //! this creates resource with empty data array, that can be downloaded later - //! by calling News::ResourceManifest::Sync - explicit Resource(const QJsonObject& json); - - explicit Resource(const QString& id, - const QString& type); - - Resource(const QString& id, - const QByteArray& data, - const QString& url, - const QString& type, - int refCount, - int version); - - ~Resource(); - - //! Saves resource's description to a json file - void Write(QJsonObject& json) const; - - QString GetId() const; - - void SetId(const QString& id); - - QByteArray GetData() const; - - void SetData(QByteArray data); - - QString GetType() const; - - int GetRefCount() const; - - void SetRefCount(int refCount); - - int GetVersion() const; - - void SetVersion(int version); - - private: - QString m_id; - QByteArray m_data; - QString m_type; - int m_refCount; - int m_version; - }; -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.cpp b/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.cpp deleted file mode 100644 index 969c4ec8f1..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "ResourceManifest.h" -#include "NewsShared/ResourceManagement/QtDownloadManager.h" -#include "NewsShared/ResourceManagement/Resource.h" -#include "NewsShared/ResourceManagement/ArticleDescriptor.h" - -#include -#include -#include -#include -#include - -namespace News -{ - - const QString ResourceManifest::MANIFEST_NAME = "resourceManifest"; - bool ResourceManifest::s_syncing = false; - - ResourceManifest::ResourceManifest( - std::function syncSuccessCallback, - std::function syncFailCallback, - std::function syncUpdateCallback) - : m_downloader(new QtDownloadManager) - , m_syncSuccessCallback(syncSuccessCallback) - , m_syncFailCallback(syncFailCallback) - , m_syncUpdateCallback(syncUpdateCallback) - { - } - - ResourceManifest::~ResourceManifest() - { - // clean everything up - DeleteResources(); - - delete m_downloader; - } - - Resource* ResourceManifest::FindById(const QString& id) const - { - return FindById(id, m_resources); - } - - Resource* ResourceManifest::FindById(const QString& id, const QList& resources) - { - auto it = std::find_if( - resources.begin(), - resources.end(), - [id](Resource* resource) -> bool - { - return resource->GetId().compare(id) == 0; - }); - if (it == resources.end()) - { - return nullptr; - } - return *it; - } - - Resource* ResourceManifest::FindById(const QString& id, - const QStack& resources) - { - auto it = std::find_if( - resources.begin(), - resources.end(), - [id](Resource* resource) -> bool - { - return resource->GetId().compare(id) == 0; - }); - if (it == resources.end()) - { - return nullptr; - } - return *it; - } - - void ResourceManifest::Sync() - { - if (s_syncing) - { - FailSync(ErrorCode::AlreadySyncing); - return; - } - s_syncing = true; - m_failed = false; - - m_syncUpdateCallback("Starting sync", LogInfo); - - ReadConfig(); - - // first download the manifest json - m_syncUpdateCallback("Downloading manifest", LogInfo); - m_downloader->Download(QString(m_url).append(MANIFEST_NAME), - std::bind(&ResourceManifest::OnDownloadSuccess, this, std::placeholders::_1), - std::bind(&ResourceManifest::OnDownloadFail, this)); - } - - void ResourceManifest::Abort() - { - m_aborted = true; - m_downloader->Abort(); - } - - void ResourceManifest::Reset() - { - if (s_syncing) - { - m_syncUpdateCallback("Sync is already running", LogError); - return; - } - - m_aborted = false; - m_failed = false; - m_version = -1; - - DeleteResources(); - - m_order.clear(); - } - - QList::const_iterator ResourceManifest::begin() const - { - return m_resources.constBegin(); - } - - QList::const_iterator ResourceManifest::end() const - { - return m_resources.constEnd(); - } - - QList ResourceManifest::GetOrder() const - { - return m_order; - } - - void ResourceManifest::OnDownloadSuccess(QByteArray data) - { - QJsonDocument doc(QJsonDocument::fromJson(data)); - if (doc.isNull()) - { - FailSync(ErrorCode::FailedToParseManifest); - return; - } - - ErrorCode error = Read(doc.object()); - if (error != ErrorCode::None) - { - FailSync(error); - return; - } - - // check how many resources to sync - PrepareForSync(); - // if there is anything to sync, do that - if (m_syncLeft > 0) - { - m_syncUpdateCallback("Syncing resources", LogInfo); - SyncResources(); - } - // otherwise just finish sync - else - { - m_syncUpdateCallback("No new resources to sync", LogInfo); - FinishSync(); - } - } - - void ResourceManifest::OnDownloadFail() - { - FailSync(ErrorCode::ManifestDownloadFail); - } - - ErrorCode ResourceManifest::Read(const QJsonObject& json) - { - m_version = json["version"].toInt(); - QJsonArray resourceArray = json["resources"].toArray(); - // initially mark ALL existing resource for deletion - QList toDelete = m_resources; - - for (auto resourceDoc : resourceArray) - { - auto pNewResource = new Resource(resourceDoc.toObject()); - // find local resource with the same id as new resource - auto pOldResource = FindById(pNewResource->GetId(), m_resources); - // if resource with the same id already exists then check its version - if (pOldResource) - { - // local resource is outdated, keep it in delete list, and download new one instead - if (pNewResource->GetVersion() > pOldResource->GetVersion()) - { - m_toDownload.push(pNewResource); - } - // local resource is newer or same version, keep it (remove from toDelete list) - // and don't need to download new one - else - { - delete pNewResource; - toDelete.removeAll(pOldResource); - } - } - // resource with same id not found - else - { - m_toDownload.push(pNewResource); - } - } - - // delete everything that's not in s3 - for (auto pResource : toDelete) - { - RemoveResource(pResource); - delete pResource; - } - - // parse order of articles - m_order.clear(); - QJsonArray orderArray = json["order"].toArray(); - for (auto idObject : orderArray) - { - m_order.append(idObject.toString()); - } - return ErrorCode::None; - } - - void ResourceManifest::PrepareForSync() - { - if (m_aborted) - { - m_syncLeft = 0; - } - - m_syncLeft = m_toDownload.count(); - } - - void ResourceManifest::SyncResources() - { - DownloadResources(); - } - - void ResourceManifest::DownloadResources() - { - while (m_toDownload.count() > 0) - { - m_syncUpdateCallback( - QString("Downloading: %1 resources left").arg(m_toDownload.count()), - LogInfo); - - auto pResource = m_toDownload.pop(); - - m_downloader->Download(QString(m_url).append(pResource->GetId()), - //download success - [&, pResource](QByteArray data) - { - pResource->SetData(data); - AppendResource(pResource); - UpdateSync(); - }, - //download fail - [&, pResource]() - { - m_failed = true; - delete pResource; - m_syncUpdateCallback("Failed to download resource", LogError); - UpdateSync(); - }); - } - } - - void ResourceManifest::ReadConfig() - { - QFile file(QCoreApplication::applicationDirPath() + "/newsConfig.txt"); - if (file.exists()) - { - if (file.open(QIODevice::ReadOnly)) - { - QTextStream in(&file); - m_url = in.readAll().trimmed(); - file.close(); - } - } - } - - void ResourceManifest::DeleteResources() - { - for (auto pResource : m_toDownload) - { - delete pResource; - } - m_toDownload.clear(); - - for (auto pResource : m_resources) - { - delete pResource; - } - m_resources.clear(); - } - - void ResourceManifest::UpdateSync() - { - m_syncLeft--; - if (m_syncLeft == 0) - { - if (!m_failed) - { - FinishSync(); - } - else - { - FailSync(ErrorCode::FailedToSync); - } - } - } - - void ResourceManifest::FinishSync() - { - if (!m_failed) - { - m_syncSuccessCallback(); - } - else - { - m_syncFailCallback(m_errorCode); - } - s_syncing = false; - } - - void ResourceManifest::FailSync(ErrorCode error) - { - m_failed = true; - m_errorCode = error; - FinishSync(); - } - - void ResourceManifest::AppendResource(Resource* pResource) - { - m_resources.append(pResource); - } - - void ResourceManifest::RemoveResource(Resource* pResource) - { - m_resources.removeAll(pResource); - } - -} diff --git a/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.h b/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.h deleted file mode 100644 index 3a0f31de8f..0000000000 --- a/Code/Tools/News/NewsShared/ResourceManagement/ResourceManifest.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include -#include - -#include "NewsShared/LogType.h" -#include "NewsShared/ErrorCodes.h" - -class QJsonObject; - -namespace News -{ - class ArticleDescriptor; - class UidGenerator; - class S3Connector; - class QtDownloadManager; - class Descriptor; - class DownloadDescriptor; - class Resource; - - //! ResourceManifest manages resources. - /*! - Manifest contains information on resources, it handles syncing resources with s3 - */ - class ResourceManifest - { - public: - //! ResourceManifest ctor - /*! - \param syncSuccessCallback - called once when everything is synced - \param syncFailCallback - called once when sync failed - \param syncUpdateCallback - called multiple times to update information on sync process - */ - explicit ResourceManifest( - std::function syncSuccessCallback, - std::function syncFailCallback, - std::function syncUpdateCallback); - virtual ~ResourceManifest(); - - //! Find a resource that matches id - /*! - \retval Resource * - a pointer to a Resource with matching id, if none found return nullptr - */ - Resource* FindById(const QString& id) const; - static Resource* FindById(const QString& id, const QList& resources); - static Resource* FindById(const QString& id, const QStack& resources); - - //! Sync resources with s3 - /* - 1) First download resource manifest file - 2) Parse manifest - 3) Determine which resources need to be downloaded, updated, or deleted - 4) Download missing resources or resource that are out of date - 5) Call m_syncSuccessCallback - */ - virtual void Sync(); - - //! Gracegully stop sync process - /*! - Aborting works differently depending at what point during sync porocess it is called - If called before resources started to download, then skip download altogether - Otherwise gracefully abort all downloads and call m_syncFailCallback - */ - void Abort(); - - //! Called when switching endpoints to reset resource manifest to a clean state - virtual void Reset(); - - QList::const_iterator begin() const; - QList::const_iterator end() const; - - //! Get order of article resources, so they can be displayed properly in ArticleViewContainer - QList GetOrder() const; - - protected: - //! The root location of cloudfront resources - QString m_url = "https://lumberyard-data.amazon.com/"; - //! Name of resourceManifest file that links all other resources - static const QString MANIFEST_NAME; - //! Identifies whether syncing is in progress - static bool s_syncing; - //! Manifest Version - int m_version = -1; - //! Number of resources left to sync - int m_syncLeft = 0; - //! Identifies whether sync process was aborted - bool m_aborted = false; - //! Indentifies whether sync process has failed - bool m_failed = false; - ErrorCode m_errorCode = ErrorCode::None; - - QtDownloadManager* m_downloader = nullptr; - - QList m_resources; - QList m_order; - QStack m_toDownload; - - std::function m_syncSuccessCallback; - std::function m_syncFailCallback; - std::function m_syncUpdateCallback; - - //! Parse resource manifest json, and figure out which resources need to be downloaded - virtual ErrorCode Read(const QJsonObject& json); - - //! Executed before sync to figure out how many resources need to be synced - virtual void PrepareForSync(); - //! Actual sync function - virtual void SyncResources(); - //! Check whether everything is synced, if so call ResourceManifest::FinishSync - void UpdateSync(); - //! Notify that everything is synced - virtual void FinishSync(); - void FailSync(ErrorCode error); - - virtual void AppendResource(Resource* pResource); - virtual void RemoveResource(Resource* pResource); - - virtual void OnDownloadSuccess(QByteArray data); - virtual void OnDownloadFail(); - virtual void DownloadResources(); - - private: - void ReadConfig(); - void DeleteResources(); - }; -} // namespace News diff --git a/Code/Tools/News/NewsShared/Resources/ErrorImage.jpg b/Code/Tools/News/NewsShared/Resources/ErrorImage.jpg deleted file mode 100644 index 216fe14bd5..0000000000 --- a/Code/Tools/News/NewsShared/Resources/ErrorImage.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0a7430d63820b3b00e03b4a8ec73b5e8e3946659031e3aeeb355b632acca4122 -size 8857 diff --git a/Code/Tools/News/NewsShared/Resources/KeepInTouchBanner.jpg b/Code/Tools/News/NewsShared/Resources/KeepInTouchBanner.jpg deleted file mode 100644 index b47040b717..0000000000 --- a/Code/Tools/News/NewsShared/Resources/KeepInTouchBanner.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:09c1733f116c11b56c54f7c3b6b4462884116db06605ca3cdfa23c45a3695385 -size 68024 diff --git a/Code/Tools/News/NewsShared/Resources/icon_facebook.png b/Code/Tools/News/NewsShared/Resources/icon_facebook.png deleted file mode 100644 index 0fb823969b..0000000000 --- a/Code/Tools/News/NewsShared/Resources/icon_facebook.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f8b5493c81354b6757a21bea6baedd5665b8cb9ca19a6ff4fbd40afef534f35f -size 1257 diff --git a/Code/Tools/News/NewsShared/Resources/icon_twitch.png b/Code/Tools/News/NewsShared/Resources/icon_twitch.png deleted file mode 100644 index 50d7436b0d..0000000000 --- a/Code/Tools/News/NewsShared/Resources/icon_twitch.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2882aad73e2ecf310934ec3eacd0c1fa0a6ff012a4c3c9cf4ca96a72cef2fb8c -size 514 diff --git a/Code/Tools/News/NewsShared/Resources/icon_twitter.png b/Code/Tools/News/NewsShared/Resources/icon_twitter.png deleted file mode 100644 index d1cf7eb3dd..0000000000 --- a/Code/Tools/News/NewsShared/Resources/icon_twitter.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:046e14f1d90f77bb6ea0fe700bb10049748b46bb84c8ac3620642d4bca9df533 -size 954 diff --git a/Code/Tools/News/NewsShared/Resources/icon_youtube.png b/Code/Tools/News/NewsShared/Resources/icon_youtube.png deleted file mode 100644 index d3e7869387..0000000000 --- a/Code/Tools/News/NewsShared/Resources/icon_youtube.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3abaf8b178763441ac6812ae518c2f8cbea9b228aa1f84052a65836b33dc980c -size 976 diff --git a/Code/Tools/News/news_shared_files.cmake b/Code/Tools/News/news_shared_files.cmake deleted file mode 100644 index 2f20029068..0000000000 --- a/Code/Tools/News/news_shared_files.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -set(FILES - NewsShared/LogType.h - NewsShared/ErrorCodes.h - NewsShared/Qt/ArticleErrorView.cpp - NewsShared/Qt/ArticleErrorView.h - NewsShared/Qt/ArticleErrorView.ui - NewsShared/Qt/ArticleView.cpp - NewsShared/Qt/ArticleView.h - NewsShared/Qt/ArticleView.ui - NewsShared/Qt/PinnedArticleView.ui - NewsShared/Qt/ArticleViewContainer.cpp - NewsShared/Qt/ArticleViewContainer.h - NewsShared/Qt/ArticleViewContainer.ui - NewsShared/Qt/KeepInTouchView.cpp - NewsShared/Qt/KeepInTouchView.h - NewsShared/Qt/KeepInTouchView.ui - NewsShared/Qt/NewsShared.qrc - NewsShared/ResourceManagement/ArticleDescriptor.cpp - NewsShared/ResourceManagement/ArticleDescriptor.h - NewsShared/ResourceManagement/Descriptor.cpp - NewsShared/ResourceManagement/Descriptor.h - NewsShared/ResourceManagement/JsonDescriptor.cpp - NewsShared/ResourceManagement/JsonDescriptor.h - NewsShared/ResourceManagement/QtDownloader.cpp - NewsShared/ResourceManagement/QtDownloader.h - NewsShared/ResourceManagement/QtDownloadManager.cpp - NewsShared/ResourceManagement/QtDownloadManager.h - NewsShared/ResourceManagement/Resource.cpp - NewsShared/ResourceManagement/Resource.h - NewsShared/ResourceManagement/ResourceManifest.cpp - NewsShared/ResourceManagement/ResourceManifest.h - NewsShared/Resources/ErrorImage.jpg - NewsShared/Resources/KeepInTouchBanner.jpg - NewsShared/Resources/icon_facebook.png - NewsShared/Resources/icon_twitch.png - NewsShared/Resources/icon_twitter.png - NewsShared/Resources/icon_youtube.png -) From 45b024bed1e10a1f4d4698e5ebff6f519a30804d Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 8 Jul 2021 16:12:45 -0700 Subject: [PATCH 08/37] Remove dead backend code Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Asset/EditorAssetSystemComponent.cpp | 16 -------- .../Code/Asset/EditorAssetSystemComponent.h | 19 +--------- .../Builder/ScriptCanvasBuilderComponent.cpp | 15 -------- .../Builder/ScriptCanvasBuilderComponent.h | 17 --------- .../Code/Include/ScriptCanvas/Core/Node.cpp | 2 - .../Include/ScriptCanvas/Core/Nodeable.cpp | 2 - .../ScriptCanvas/Core/NodeableNode.cpp | 2 - .../Core/NodeableNodeOverloaded.cpp | 2 - .../Grammar/AbstractCodeModel.cpp | 1 - .../Grammar/ExecutionTraversalListeners.cpp | 1 - .../ScriptCanvas/Grammar/GrammarContext.cpp | 25 ------------ .../ScriptCanvas/Grammar/GrammarContext.h | 37 ------------------ .../ScriptCanvas/Grammar/GrammarContextBus.h | 35 ----------------- .../ScriptCanvas/Translation/GraphToLua.cpp | 10 ++--- .../ScriptCanvas/Translation/GraphToLua.h | 3 +- .../Translation/TranslationContext.h | 1 - .../Translation/TranslationContextBus.h | 38 ------------------- .../Code/scriptcanvasgem_common_files.cmake | 4 -- .../Framework/ScriptCanvasTestNodes.cpp | 2 - .../Tests/ScriptCanvas_RuntimeInterpreted.cpp | 2 - .../Code/Tests/ScriptCanvas_VM.cpp | 2 - 21 files changed, 6 insertions(+), 230 deletions(-) delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h diff --git a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp index e698fcc298..2bc3a91a96 100644 --- a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp @@ -58,16 +58,6 @@ namespace ScriptCanvasEditor required.push_back(AZ_CRC("ScriptCanvasService", 0x41fd58f3)); } - ScriptCanvas::Grammar::Context* EditorAssetSystemComponent::GetGrammarContext() - { - return &m_grammarContext; - } - - ScriptCanvas::Translation::Context* EditorAssetSystemComponent::GetTranslationContext() - { - return &m_translationContext; - } - void EditorAssetSystemComponent::Init() { } @@ -79,16 +69,10 @@ namespace ScriptCanvasEditor AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect(); EditorAssetConversionBus::Handler::BusConnect(); - - ScriptCanvas::Translation::RequestBus::Handler::BusConnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusConnect(); } void EditorAssetSystemComponent::Deactivate() { - ScriptCanvas::Translation::RequestBus::Handler::BusDisconnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect(); - EditorAssetConversionBus::Handler::BusDisconnect(); AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect(); m_editorAssetRegistry.Unregister(); diff --git a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h index 4a55a35908..84b10ff17c 100644 --- a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h +++ b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h @@ -12,11 +12,6 @@ #include "EditorAssetConversionBus.h" #include #include - -#include -#include -#include -#include #include namespace ScriptCanvasEditor @@ -26,8 +21,6 @@ namespace ScriptCanvasEditor class EditorAssetSystemComponent : public AZ::Component , public EditorAssetConversionBus::Handler - , public ScriptCanvas::Grammar::RequestBus::Handler - , public ScriptCanvas::Translation::RequestBus::Handler , private AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler { public: @@ -60,20 +53,10 @@ namespace ScriptCanvasEditor AZ::Outcome CreateLuaAsset(const AZ::Data::Asset& editAsset, AZStd::string_view graphPathForRawLuaFile) override; ////////////////////////////////////////////////////////////////////////// - // ScriptCanvas::Grammar::RequestBus::Handler... - ScriptCanvas::Grammar::Context* GetGrammarContext() override; - - // ScriptCanvas::Translation::RequestBus::Handler... - ScriptCanvas::Translation::Context* GetTranslationContext() override; - - ScriptCanvas::AssetRegistry& GetAssetRegistry(); private: - ScriptCanvas::AssetRegistry m_editorAssetRegistry; - ScriptCanvas::Translation::Context m_translationContext; - ScriptCanvas::Grammar::Context m_grammarContext; - + ScriptCanvas::AssetRegistry m_editorAssetRegistry; EditorAssetSystemComponent(const EditorAssetSystemComponent&) = delete; }; } diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp index 2f30106707..b37d5c1da4 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp @@ -104,9 +104,6 @@ namespace ScriptCanvasBuilder m_sharedHandlers = HandleAssetTypes(); AssetHandlers workerHandlers(m_sharedHandlers); m_scriptCanvasBuilder.Activate(workerHandlers); - - ScriptCanvas::Translation::RequestBus::Handler::BusConnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusConnect(); } void PluginComponent::Deactivate() @@ -116,18 +113,6 @@ namespace ScriptCanvasBuilder AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::UnregisterSourceAssetType, azrtti_typeid()); m_scriptCanvasBuilder.BusDisconnect(); m_sharedHandlers.DeleteOwnedHandlers(); - ScriptCanvas::Translation::RequestBus::Handler::BusDisconnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect(); - } - - ScriptCanvas::Grammar::Context* PluginComponent::GetGrammarContext() - { - return &m_grammarContext; - } - - ScriptCanvas::Translation::Context* PluginComponent::GetTranslationContext() - { - return &m_translationContext; } void PluginComponent::Reflect(AZ::ReflectContext* context) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h index 5d57863ec3..ff904d195a 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h @@ -12,18 +12,11 @@ #include #include "ScriptCanvasBuilderWorker.h" -#include -#include -#include -#include - namespace ScriptCanvasBuilder { //! ScriptCanvasBuilder is responsible for turning editor ScriptCanvas Assets into runtime script canvas assets class PluginComponent : public AZ::Component - , public ScriptCanvas::Grammar::RequestBus::Handler - , public ScriptCanvas::Translation::RequestBus::Handler { public: AZ_COMPONENT(PluginComponent, "{F8286B21-E751-4745-8BC4-512F190215FF}") @@ -42,19 +35,9 @@ namespace ScriptCanvasBuilder void Deactivate() override; ////////////////////////////////////////////////////////////////////////// - // ScriptCanvas::Grammar::RequestBus::Handler - ScriptCanvas::Grammar::Context* GetGrammarContext() override; - - // ScriptCanvas::Translation::RequestBus::Handler - ScriptCanvas::Translation::Context* GetTranslationContext() override; - private: PluginComponent(const PluginComponent&) = delete; - SharedHandlers m_sharedHandlers; - Worker m_scriptCanvasBuilder; - ScriptCanvas::Translation::Context m_translationContext; - ScriptCanvas::Grammar::Context m_grammarContext; }; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index c6c9330e51..3f9c5cc8a4 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include // Version Conversion includes diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp index f3d6070ac6..01b754506c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp @@ -9,8 +9,6 @@ #include #include -#include -#include namespace NodeableOutCpp { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp index 5ec40d8e5f..db0cf8e589 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp index c9e2e3acc6..882804de36 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 80d2977c6d..4ccb462a5d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -32,7 +32,6 @@ #include "AbstractCodeModel.h" #include "ExecutionTraversalListeners.h" -#include "GrammarContextBus.h" #include "ParsingUtilities.h" #include "Primitives.h" diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp index 1ac9303082..6ac80de542 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp @@ -27,7 +27,6 @@ #include #include "ExecutionTraversalListeners.h" -#include "GrammarContextBus.h" #include "ParsingUtilities.h" #include "Primitives.h" diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp deleted file mode 100644 index b8eb5f5ad5..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "GrammarContext.h" - -namespace ScriptCanvas -{ - namespace Grammar - { - const SubgraphInterfaceSystem& Context::GetExecutionMapSystem() const - { - return m_executionMapSystem; - } - - SubgraphInterfaceSystem& Context::ModExecutionMapSystem() - { - return m_executionMapSystem; - } - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h deleted file mode 100644 index 7a9d2eaec9..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -#include - -namespace ScriptCanvas -{ - namespace Grammar - { - class Context - { - public: - AZ_CLASS_ALLOCATOR(Context, AZ::SystemAllocator, 0); - - Context() = default; - ~Context() = default; - - const SubgraphInterfaceSystem& GetExecutionMapSystem() const; - SubgraphInterfaceSystem& ModExecutionMapSystem(); - - private: - SubgraphInterfaceSystem m_executionMapSystem; - - // put grammatical state globals in here, things that can be useful across several parses of graphs - }; - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h deleted file mode 100644 index 1630d0b99e..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace ScriptCanvas -{ - namespace Grammar - { - class Context; - - struct RequestTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - virtual Context* GetGrammarContext() = 0; - }; - - using RequestBus = AZ::EBus; - - struct EventTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - // add stuff here to speed up parsing across separate graphs - }; - - using EventBus = AZ::EBus; - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp index f945110674..085a0928bc 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp @@ -24,8 +24,6 @@ #include #include "GraphToLuaUtility.h" -#include "TranslationContext.h" -#include "TranslationContextBus.h" namespace GraphToLuaCpp { @@ -92,9 +90,7 @@ namespace ScriptCanvas { SystemRequestBus::BroadcastResult(m_systemConfiguration, &SystemRequests::GetSystemComponentConfiguration); MarkTranslationStart(); - RequestBus::BroadcastResult(m_context, &RequestTraits::GetTranslationContext); - AZ_Assert(m_context, "Nothing is possible without the context"); - + m_tableName = GraphToLuaCpp::FileNameToTableName(m_model.GetSource().m_name); m_tableName += m_configuration.m_suffix; @@ -138,12 +134,12 @@ namespace ScriptCanvas const AZStd::string& GraphToLua::FindAbbreviation(AZStd::string_view dependency) const { - return m_context->FindAbbreviation(dependency); + return m_context.FindAbbreviation(dependency); } const AZStd::string& GraphToLua::FindLibrary(AZStd::string_view dependency) const { - return m_context->FindLibrary(dependency); + return m_context.FindLibrary(dependency); } AZStd::string_view GraphToLua::GetOperatorString(Grammar::ExecutionTreeConstPtr execution) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h index ba46b21c65..347cb764e9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h @@ -16,6 +16,7 @@ #include #include "GraphToX.h" +#include "TranslationContext.h" #include "TranslationResult.h" #include "TranslationUtilities.h" @@ -60,7 +61,7 @@ namespace ScriptCanvas RuntimeInputs m_runtimeInputs; BuildConfiguration m_executionConfig = BuildConfiguration::Release; FunctionBlockConfig m_functionBlockConfig = FunctionBlockConfig::Ignored; - const Context* m_context = nullptr; + Context m_context; AZStd::string m_tableName; Writer m_dotLua; SystemComponentConfiguration m_systemConfiguration; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h index ea49f90bde..40f04f2f47 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h @@ -10,7 +10,6 @@ #include #include #include "Translation.h" -#include "TranslationContextBus.h" namespace ScriptCanvas { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h deleted file mode 100644 index 0edac2afe3..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -#include "Translation.h" - -namespace ScriptCanvas -{ - namespace Translation - { - class Context; - - struct RequestTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - virtual Context* GetTranslationContext() = 0; - }; - - using RequestBus = AZ::EBus; - - struct EventTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - }; - - using EventBus = AZ::EBus; - - } - -} diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 40b5786303..17273b7ae0 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -101,7 +101,6 @@ set(FILES Include/ScriptCanvas/Translation/Translation.cpp Include/ScriptCanvas/Translation/TranslationContext.h Include/ScriptCanvas/Translation/TranslationContext.cpp - Include/ScriptCanvas/Translation/TranslationContextBus.h Include/ScriptCanvas/Translation/TranslationResult.h Include/ScriptCanvas/Translation/TranslationResult.cpp Include/ScriptCanvas/Translation/TranslationUtilities.h @@ -196,9 +195,6 @@ set(FILES Include/ScriptCanvas/Grammar/DebugMap.cpp Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.h Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp - Include/ScriptCanvas/Grammar/GrammarContext.h - Include/ScriptCanvas/Grammar/GrammarContext.cpp - Include/ScriptCanvas/Grammar/GrammarContextBus.h Include/ScriptCanvas/Grammar/ParsingMetaData.h Include/ScriptCanvas/Grammar/ParsingMetaData.cpp Include/ScriptCanvas/Grammar/ParsingUtilities.h diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp index 727f73be39..e54c83c5d3 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index 3946057780..fedb1fc4d1 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp index 0733101743..8c4983da0f 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include From c8e932652628c302ea6b2ec8524fbf6855d27642 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 8 Jul 2021 16:16:25 -0700 Subject: [PATCH 09/37] add deliberately failing check again Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index fedb1fc4d1..db3d2223d6 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -83,6 +83,11 @@ public: } }; +TEST_F(ScriptCanvasTestFixture, ProveError) +{ + EXPECT_TRUE(false); +} + TEST_F(ScriptCanvasTestFixture, ParseErrorOnKnownNull) { ExpectParseError("LY_SC_UnitTest_ParseErrorOnKnownNull"); From d7c8c0192ffe008b4a3960de943997cf05ec6130 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Thu, 8 Jul 2021 17:20:20 -0700 Subject: [PATCH 10/37] SPEC-7503 Mac nightly run asset profile failed to process "Translation/scriptcanvas_en_us.ts" (#1742) * copy frameworks to output for loose file case Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * patching lrelease Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Fix for python in loose files and bundles Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * found what the problem is, setting a version just in case Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * fixup_bundle working with Python.framework and codesigning on AssetProcessor.app Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Trying to ignore other files to solve Jenkins Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Fix some qt stuff for mac Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * removal of cstemp files to prevent signature failures Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Updating Qt with fixes to solve some qt framework issues with include paths Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../CMakeLists.txt | 1 + .../Outliner/OutlinerDisplayOptionsMenu.cpp | 2 + .../Plugins/FFMPEGPlugin/CMakeLists.txt | 1 + .../FFMPEGPlugin/FFMPEGPlugin_precompiled.h | 11 - .../Plugins/PerforcePlugin/CMakeLists.txt | 2 + .../Code/Platform/Mac/lrelease_mac.cmake | 9 + .../Platform/Mac/BuiltInPackages_mac.cmake | 2 +- .../Common/RuntimeDependencies_common.cmake | 3 +- .../runtime_dependencies_common.cmake.in | 1 + .../Mac/runtime_dependencies_mac.cmake.in | 201 ++++++++++++------ 10 files changed, 157 insertions(+), 76 deletions(-) diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt b/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt index 4744b4e174..5aab2a2056 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt @@ -27,6 +27,7 @@ ly_add_target( BUILD_DEPENDENCIES PRIVATE 3rdParty::Qt::Core + 3rdParty::Qt::Widgets AZ::AzCore AZ::AzToolsFramework Legacy::CryCommon diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp index c1af8d76d7..a6c1ed6598 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp @@ -66,3 +66,5 @@ namespace EntityOutliner emit OnOptionToggled(DisplayOption::AutoExpand, checked); } } + +#include diff --git a/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt b/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt index 342151f24a..909ec193f3 100644 --- a/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt +++ b/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt @@ -23,6 +23,7 @@ ly_add_target( . BUILD_DEPENDENCIES PRIVATE + 3rdParty::Qt::Core AZ::AzCore Legacy::CryCommon Legacy::EditorLib diff --git a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h index 3b015dd9a5..33ca3390f1 100644 --- a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h +++ b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h @@ -17,19 +17,8 @@ ///////////////////////////////////////////////////////////////////////////// #include - -///////////////////////////////////////////////////////////////////////////// -// STL -///////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include - ///////////////////////////////////////////////////////////////////////////// // CRY Stuff //////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// #include -#include "Util/EditorUtils.h" #include "EditorCoreAPI.h" diff --git a/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt b/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt index 15a1147166..bd4661fa0f 100644 --- a/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt +++ b/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt @@ -31,6 +31,8 @@ ly_add_target( . BUILD_DEPENDENCIES PRIVATE + 3rdParty::Qt::Core + 3rdParty::Qt::Widgets AZ::AzCore Legacy::CryCommon Legacy::EditorLib diff --git a/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake b/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake index af355b0a51..34f67ccedd 100644 --- a/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake +++ b/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake @@ -5,6 +5,15 @@ # # +add_custom_command(TARGET LmbrCentral.Editor POST_BUILD + COMMAND "${CMAKE_COMMAND}" -P "${LY_ROOT_FOLDER}/cmake/Platform/Mac/RPathChange.cmake" + "$/lrelease" + @executable_path/../Frameworks + @executable_path + COMMENT "Patching lrelease..." + VERBATIM +) + set(lrelease_files ${QT_LRELEASE_EXECUTABLE} ) diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake index 59da804e82..b261f18035 100644 --- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake +++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake @@ -42,5 +42,5 @@ ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-mac ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-mac TARGETS googletest PACKAGE_HASH cbf020d5ef976c5db8b6e894c6c63151ade85ed98e7c502729dd20172acae5a8) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-mac TARGETS GoogleBenchmark PACKAGE_HASH ad25de0146769c91e179953d845de2bec8ed4a691f973f47e3eb37639381f665) ly_associate_package(PACKAGE_NAME OpenSSL-1.1.1b-rev1-mac TARGETS OpenSSL PACKAGE_HASH 28adc1c0616ac0482b2a9d7b4a3a3635a1020e87b163f8aba687c501cf35f96c) -ly_associate_package(PACKAGE_NAME qt-5.15.2-rev4-mac TARGETS Qt PACKAGE_HASH 08790d03a0e6ad808ad64cf25c3d75abd69a343f3d224fc39927e5c6e8738b98) +ly_associate_package(PACKAGE_NAME qt-5.15.2-rev5-mac TARGETS Qt PACKAGE_HASH 9d25918351898b308ded3e9e571fff6f26311b2071aeafd00dd5b249fdf53f7e) ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-mac TARGETS libsamplerate PACKAGE_HASH b912af40c0ac197af9c43d85004395ba92a6a859a24b7eacd920fed5854a97fe) diff --git a/cmake/Platform/Common/RuntimeDependencies_common.cmake b/cmake/Platform/Common/RuntimeDependencies_common.cmake index 734dd94203..31c8191a57 100644 --- a/cmake/Platform/Common/RuntimeDependencies_common.cmake +++ b/cmake/Platform/Common/RuntimeDependencies_common.cmake @@ -254,7 +254,8 @@ function(ly_delayed_generate_runtime_dependencies) # Generate the output file set(target_file_dir "$") - file(READ ${LY_RUNTIME_DEPENDENCIES_TEMPLATE} template_file) + set(target_file "$") + ly_file_read(${LY_RUNTIME_DEPENDENCIES_TEMPLATE} template_file) string(CONFIGURE "${LY_COPY_COMMANDS}" LY_COPY_COMMANDS @ONLY) string(CONFIGURE "${template_file}" configured_template_file @ONLY) file(GENERATE diff --git a/cmake/Platform/Common/runtime_dependencies_common.cmake.in b/cmake/Platform/Common/runtime_dependencies_common.cmake.in index e2a85374b8..9d23a73a26 100644 --- a/cmake/Platform/Common/runtime_dependencies_common.cmake.in +++ b/cmake/Platform/Common/runtime_dependencies_common.cmake.in @@ -13,6 +13,7 @@ function(ly_copy source_file target_directory) if(NOT ${same_location}) file(LOCK ${target_directory}/${target_filename}.lock GUARD FUNCTION TIMEOUT 300) if("${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") + message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) endif() endif() diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index 92ad3514d4..9f9006c4c0 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -19,56 +19,96 @@ endfunction() include(BundleUtilities) cmake_policy(SET CMP0012 NEW) # new policy for the if that evaluates a boolean out of the LY_BUILD_FIXUP_BUNDLE expansion +cmake_policy(SET CMP0009 NEW) # do not traverse symlinks on GLOB_RECURSE set(anything_new FALSE) set(plugin_libs) set(plugin_dirs) +set(depends_on_python FALSE) + +find_program(LY_INSTALL_NAME_TOOL install_name_tool) +if (NOT LY_INSTALL_NAME_TOOL) + message(FATAL_ERROR "Unable to locate 'install_name_tool'") +endif() function(ly_copy source_file target_directory) get_filename_component(target_filename "${source_file}" NAME) - # If source_file is a Framework and target_directory is a bundle - if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") + # If target_directory is a bundle + if("${target_directory}" MATCHES "\\.app/Contents/MacOS") - if(NOT @LY_BUILD_FIXUP_BUNDLE@) - return() - endif() + set(target_is_bundle TRUE) + if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]") - # fixup origin to copy the whole Framework folder and change destination to Contents/Frameworks - string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}") - get_filename_component(source_file_folder "${source_file}" DIRECTORY) + if(NOT @LY_BUILD_FIXUP_BUNDLE@) + return() + endif() + + # fixup origin to copy the whole Framework folder and change destination to Contents/Frameworks + string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}") + get_filename_component(source_file_folder "${source_file}" DIRECTORY) + + # Python.framework produces a bug in BundleUtilities so it needs manual handling + # https://gitlab.kitware.com/cmake/cmake/-/issues/20165 + if("${source_file}" MATCHES "Python.framework") + # fixup the destination so it ends up in Contents/Frameworks + string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/Frameworks" target_directory "${target_directory}") + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}/Python.framework") + set(target_filename Python.framework) + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + set(depends_on_python TRUE PARENT_SCOPE) + else() + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${source_file_folder}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + return() + endif() + + elseif("${source_file}" MATCHES "qt/plugins") + + if(NOT @LY_BUILD_FIXUP_BUNDLE@) + return() + endif() + + # fixup the destination so it ends up in Contents/Plugins + string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/plugins" target_directory "${target_directory}") + + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + set(local_plugin_libs ${plugin_libs}) + list(APPEND local_plugin_libs "${target_directory}/${target_filename}") + set(plugin_libs ${local_plugin_libs} PARENT_SCOPE) + + elseif("${source_file}" MATCHES "qt/translations") + + return() # skip, is this used? - set(local_plugin_dirs ${plugin_dirs}) - list(APPEND local_plugin_dirs "${source_file_folder}") - set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) - return() + elseif("${source_file}" MATCHES ".dylib") + + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) - elseif("${source_file}" MATCHES "qt/plugins" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") - - if(NOT @LY_BUILD_FIXUP_BUNDLE@) - return() endif() - - # fixup the destination so it ends up in Contents/Plugins - string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/plugins" target_directory "${target_directory}") - - set(local_plugin_dirs ${plugin_dirs}) - list(APPEND local_plugin_dirs "${target_directory}") - set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) - set(local_plugin_libs ${plugin_libs}) - list(APPEND local_plugin_libs "${target_directory}/${target_filename}") - set(plugin_libs ${local_plugin_libs} PARENT_SCOPE) - - elseif("${source_file}" MATCHES "qt/translations" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") - - return() # skip, is this used? - elseif("${source_file}" MATCHES ".dylib") + else() - set(local_plugin_dirs ${plugin_dirs}) - list(APPEND local_plugin_dirs "${target_directory}") - set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + # target is not a bundle + set(target_is_bundle FALSE) + if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]") + + # fixup origin to copy the whole Framework folder + string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}") + get_filename_component(target_filename "${source_file}" NAME) + + if("${source_file}" MATCHES "Python.framework") + set(depends_on_python TRUE PARENT_SCOPE) + endif() + + endif() endif() @@ -79,6 +119,11 @@ function(ly_copy source_file target_directory) endif() if(NOT EXISTS "${target_directory}/${target_filename}" OR "${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") + if(NOT target_is_bundle) + # if it is a bundle, there is no contention about the files in the destination, each bundle target will copy everything + # we dont want these files to invalidate the bundle and cause a new signature + file(LOCK ${target_directory}/${target_filename}.lock GUARD FUNCTION TIMEOUT 300) + endif() file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) file(TOUCH ${target_directory}/${target_filename}) set(anything_new TRUE PARENT_SCOPE) @@ -93,6 +138,7 @@ if(NOT @LY_BUILD_FIXUP_BUNDLE@) endif() if(@target_file_dir@ MATCHES ".app/Contents/MacOS") + string(REGEX REPLACE "(.*\\.app)/Contents/MacOS.*" "\\1" bundle_path "@target_file_dir@") set(fixup_timestamp_file "${bundle_path}.fixup.stamp") if(NOT anything_new) @@ -106,31 +152,44 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) list(APPEND fixup_bundle_ignore dxc-3.7) endif() - # Python.framework being copied by fixup_bundle - #if(EXISTS ${bundle_path}/Contents/Frameworks/Python.framework) - # # LYN-4502: Patch python bundle, it contains some windows executables, some files that fixup_bundle doesnt like and has - # # duplicated binaries between Versions/3.7 and Versions/Current. - # file(GLOB exe_files - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/distutils/command/*.exe - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip/_vendor/distlib/*.exe - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/setuptools/*.exe - # ) - # foreach(exe_file ${exe_files}) - # file(REMOVE ${exe_file}) - # endforeach() - # file(REMOVE_RECURSE - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Resources - # ${bundle_path}/Contents/Frameworks/Python.framework/Python - # ${bundle_path}/Contents/Frameworks/Python.framework/Resources/Python.app - # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Python - # ) - # file(REMOVE_RECURSE ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current) - # execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current - # WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/ - # ) - #endif() + # LYN-4502: Patch python bundle, it contains some windows executables, some files that fixup_bundle doesnt like and has + # other issues that produce signature problems + if(depends_on_python) + message(STATUS "Fixing ${bundle_path}/Contents/Frameworks/Python.framework...") + list(APPEND fixup_bundle_ignore Python python3.7m python3.7) + file(REMOVE_RECURSE + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Headers + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/Python + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests + ${bundle_path}/Contents/Frameworks/Python.framework/Python + ${bundle_path}/Contents/Frameworks/Python.framework/Resources + ${bundle_path}/Contents/Frameworks/Python.framework/Headers + ) + file(GLOB_RECURSE exe_file_list "${bundle_path}/Contents/Frameworks/Python.framework/**/*.exe") + if(exe_file_list) + file(REMOVE_RECURSE ${exe_file_list}) + endif() + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink include/python3.7m Headers + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7 + ) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/ + ) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Python Python + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + ) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers Headers + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + ) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Resources Resources + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework + ) + file(CHMOD ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current/Python + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + endif() list(REMOVE_DUPLICATES plugin_libs) list(REMOVE_DUPLICATES plugin_dirs) fixup_bundle("${bundle_path}" "${plugin_libs}" "${plugin_dirs}" IGNORE_ITEM ${fixup_bundle_ignore}) @@ -139,11 +198,27 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") # fixup bundle ends up removing the rpath of dxc (despite we exclude it) if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) - find_program(LY_INSTALL_NAME_TOOL install_name_tool) - if (NOT LY_INSTALL_NAME_TOOL) - message(FATAL_ERROR "Unable to locate 'install_name_tool'") - endif() execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -add_rpath @executable_path/../lib ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) endif() + + # misplaced .DS_Store files can cause signing to fail + # Interrupted signatures can leave cstemp files behind that fail next signature + file(GLOB_RECURSE remove_file_list + "${bundle_path}/**/.DS_Store" + "${bundle_path/}**/*.cstemp" + ) + if(remove_file_list) + file(REMOVE_RECURSE ${remove_file_list}) + endif() + + endif() + +else() # Non-bundle case + + if(depends_on_python) + # RPATH fix python + execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -change @rpath/Python @rpath/Python.framework/Versions/Current/Python @target_file@) + endif() + endif() From 92ff99c6a0766e72df7b969c86273a20af4035ee Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Thu, 8 Jul 2021 18:11:08 -0700 Subject: [PATCH 11/37] Remove NewsShared includes in the WelcomeDialog class Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp | 4 ---- Code/Editor/WelcomeScreen/WelcomeScreenDialog.h | 2 -- 2 files changed, 6 deletions(-) diff --git a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp index f9560aef55..49d9c58159 100644 --- a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp +++ b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp @@ -40,10 +40,6 @@ #include "CryEdit.h" #include "LevelFileDialog.h" -// NewsShared -#include // for News::ResourceManifest -#include // for News::ArticleViewContainer - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING #include AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING diff --git a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h index 4338a8250f..0a96836eb4 100644 --- a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h +++ b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h @@ -8,8 +8,6 @@ #if !defined(Q_MOC_RUN) #include -#include "NewsShared/LogType.h" -#include "NewsShared/ErrorCodes.h" #endif namespace News { From 2cc909570211e885748b2d525876dcea76f8faac Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Thu, 8 Jul 2021 21:35:17 -0700 Subject: [PATCH 12/37] Remove unused functions referencing the News ErrorCode class Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- Code/Editor/WelcomeScreen/WelcomeScreenDialog.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h index 0a96836eb4..39c0ad6316 100644 --- a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h +++ b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h @@ -60,9 +60,6 @@ private: void OnRecentLevelTableItemClicked(const QModelIndex& index); void OnCloseBtnClicked(bool checked); - void SyncFail(News::ErrorCode error); - void SyncSuccess(); - private Q_SLOTS: void previewAreaScrolled(); }; From 097dc25424cbca90243ba86df06e522340c1a2e5 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 9 Jul 2021 00:41:25 -0500 Subject: [PATCH 13/37] Fixed the discovery of the dependencies of gem variant aliases which (#2013) alias INTERFACE LIBRARY targets. This was causing the dependent Atom_AtomBridge sub gems from not being found when generating the cmake_dependencies.*.setreg file containing the list of gem modules to load Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- AutomatedTesting/Gem/Code/enabled_gems.cmake | 2 +- cmake/SettingsRegistry.cmake | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/AutomatedTesting/Gem/Code/enabled_gems.cmake b/AutomatedTesting/Gem/Code/enabled_gems.cmake index 0d4d4b116f..dd68e379dd 100644 --- a/AutomatedTesting/Gem/Code/enabled_gems.cmake +++ b/AutomatedTesting/Gem/Code/enabled_gems.cmake @@ -47,7 +47,7 @@ set(ENABLED_GEMS LmbrCentral LyShine HttpRequestor - Atom_AtomBridge + Atom AWSCore AWSClientAuth AWSMetrics diff --git a/cmake/SettingsRegistry.cmake b/cmake/SettingsRegistry.cmake index 0eae244c4f..934bae4e30 100644 --- a/cmake/SettingsRegistry.cmake +++ b/cmake/SettingsRegistry.cmake @@ -160,12 +160,6 @@ function(ly_delayed_generate_settings_registry) get_property(has_manually_added_dependencies TARGET ${gem_target} PROPERTY MANUALLY_ADDED_DEPENDENCIES SET) get_target_property(target_type ${gem_target} TYPE) - if (target_type STREQUAL "INTERFACE_LIBRARY" AND has_manually_added_dependencies) - # don't use interface libraries here, we only want ones which produce actual binaries unless the target - # is empty. We have still already recursed into their dependencies - they'll show up later. - # When the target has no dependencies however we want to add the gem root path to the generated setreg - continue() - endif() ly_get_gem_module_root(gem_module_root ${gem_target}) From 9794182842213ae2131d9ef0a096927cc53cace6 Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Fri, 9 Jul 2021 01:36:58 -0700 Subject: [PATCH 14/37] Notified the MeshFeatureProcessor when a ReflectionProbe is baked. Signed-off-by: dmcdiar --- .../ReflectionProbe/ReflectionProbeFeatureProcessor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp index 39c0d0592e..ac7b4b94b9 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp @@ -256,6 +256,10 @@ namespace AZ { AZ_Assert(probe.get(), "SetProbeCubeMap called with an invalid handle"); probe->SetCubeMapImage(cubeMapImage, relativePath); + + // notify the MeshFeatureProcessor that the reflection probe changed + MeshFeatureProcessor* meshFeatureProcessor = GetParentScene()->GetFeatureProcessor(); + meshFeatureProcessor->UpdateMeshReflectionProbes(); } void ReflectionProbeFeatureProcessor::SetProbeTransform(const ReflectionProbeHandle& probe, const AZ::Transform& transform) From 2555c88fe73628c3f2e02bb6ad620f5bf0d3942c Mon Sep 17 00:00:00 2001 From: jromnoa Date: Fri, 9 Jul 2021 07:42:57 -0700 Subject: [PATCH 15/37] this test needs to be disabled in main, it was supposed to be merged to development before break but got merged to stabilization and then main Signed-off-by: jromnoa --- .../Gem/PythonTests/smoke/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt index af9fc142e2..9951b448d8 100644 --- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt @@ -51,4 +51,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) AutomatedTesting.GameLauncher AutomatedTesting.Assets ) + +# ly_add_pytest( +# NAME AutomatedTesting::GameLauncherWithGPU +# TEST_REQUIRES gpu +# PATH ${CMAKE_CURRENT_LIST_DIR}/test_GameLauncher_EnterExitGameMode_Works.py +# TIMEOUT 100 +# RUNTIME_DEPENDENCIES +# AZ::AssetProcessor +# AZ::PythonBindingsExample +# Legacy::Editor +# AutomatedTesting.GameLauncher +# AutomatedTesting.Assets +# ) endif() From 5b44ea9b9ab99b5f285158afe88fca35219c33c5 Mon Sep 17 00:00:00 2001 From: AMZN-nggieber <52797929+AMZN-nggieber@users.noreply.github.com> Date: Fri, 9 Jul 2021 08:15:34 -0700 Subject: [PATCH 16/37] Project Manager: Added Per Project Template Previews and Icon Overlays (#1994) * Project Manager: Added Per Project Template Previews and Icon Overlays Signed-off-by: nggieber * Remove template icon overlays and bake them into template preview Signed-off-by: nggieber * Remove unused variables and headers Signed-off-by: nggieber --- .../ProjectManager/Source/NewProjectSettingsScreen.cpp | 3 ++- Code/Tools/ProjectManager/Source/ProjectManagerDefs.h | 1 + Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp | 6 +++--- Code/Tools/ProjectManager/Source/TemplateButtonWidget.h | 4 ---- Templates/DefaultProject/preview.png | 3 +++ Templates/MinimalProject/preview.png | 3 +++ 6 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 Templates/DefaultProject/preview.png create mode 100644 Templates/MinimalProject/preview.png diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp index c0c96d8281..508b7256d1 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -117,7 +118,7 @@ namespace O3DE::ProjectManager for (int index = 0; index < m_templates.size(); ++index) { ProjectTemplateInfo projectTemplate = m_templates.at(index); - QString projectPreviewPath = projectTemplate.m_path + "/Template/preview.png"; + QString projectPreviewPath = QDir(projectTemplate.m_path).filePath(ProjectPreviewImagePath); QFileInfo doesPreviewExist(projectPreviewPath); if (!doesPreviewExist.exists() || !doesPreviewExist.isFile()) { diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h b/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h index f74233db51..79ad04c43a 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h +++ b/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h @@ -12,6 +12,7 @@ namespace O3DE::ProjectManager { inline constexpr static int ProjectPreviewImageWidth = 210; inline constexpr static int ProjectPreviewImageHeight = 280; + inline constexpr static int ProjectTemplateImageWidth = 92; static const QString ProjectBuildPathPostfix = "build/windows_vs2019"; static const QString ProjectBuildPathCmakeFiles = "CMakeFiles"; diff --git a/Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp b/Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp index d20b91ac8e..638b821e5d 100644 --- a/Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp +++ b/Code/Tools/ProjectManager/Source/TemplateButtonWidget.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -16,7 +17,6 @@ namespace O3DE::ProjectManager { - TemplateButton::TemplateButton(const QString& imagePath, const QString& labelText, QWidget* parent) : QPushButton(parent) { @@ -31,8 +31,8 @@ namespace O3DE::ProjectManager QLabel* image = new QLabel(this); image->setObjectName("templateImage"); - image->setPixmap( - QPixmap(imagePath).scaled(QSize(s_templateImageWidth,s_templateImageHeight) , Qt::KeepAspectRatio, Qt::SmoothTransformation)); + image->setPixmap(QPixmap(imagePath).scaled( + QSize(ProjectTemplateImageWidth, ProjectTemplateImageWidth), Qt::KeepAspectRatio, Qt::SmoothTransformation)); vLayout->addWidget(image); QLabel* label = new QLabel(labelText, this); diff --git a/Code/Tools/ProjectManager/Source/TemplateButtonWidget.h b/Code/Tools/ProjectManager/Source/TemplateButtonWidget.h index 2b2b3474c2..0607b8fbfe 100644 --- a/Code/Tools/ProjectManager/Source/TemplateButtonWidget.h +++ b/Code/Tools/ProjectManager/Source/TemplateButtonWidget.h @@ -24,9 +24,5 @@ namespace O3DE::ProjectManager protected slots: void onToggled(); - - private: - inline constexpr static int s_templateImageWidth = 92; - inline constexpr static int s_templateImageHeight = 122; }; } // namespace O3DE::ProjectManager diff --git a/Templates/DefaultProject/preview.png b/Templates/DefaultProject/preview.png new file mode 100644 index 0000000000..78a2a735d2 --- /dev/null +++ b/Templates/DefaultProject/preview.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ae503ec99c8358991dc3c6e50737844d3602b81a49abbbed7d697d7238547c0 +size 28026 diff --git a/Templates/MinimalProject/preview.png b/Templates/MinimalProject/preview.png new file mode 100644 index 0000000000..b94e84a348 --- /dev/null +++ b/Templates/MinimalProject/preview.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c14254e4c822fb50bfec42691c49f1089ab020a873c366f71168390d3705c6e +size 17522 From 595ac3fb0881cdc397f729fe5211ffa35cfb9791 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Fri, 9 Jul 2021 08:18:35 -0700 Subject: [PATCH 17/37] Project Manager: Feature tag filtering for header of the gem catalog (#1956) * [LYN-4440] Added new feature tag remove icon Signed-off-by: Benjamin Jillich * [LYN-4440] Added new gem filter tag widget Signed-off-by: Benjamin Jillich * [LYN-4440] Added feature tag widget used for showing the filtered tags in the gem catalog header Signed-off-by: Benjamin Jillich * [LYN-4440] Added filter tag widget container to the gem catalog header and connected it to the gem model Signed-off-by: Benjamin Jillich * [LYN-4440] Syncing the feature tag filters on the left panel with the tag widgets in the header and styling the item delegates Signed-off-by: Benjamin Jillich --- .../Resources/FeatureTagClose.svg | 4 + .../Resources/ProjectManager.qrc | 1 + .../Resources/ProjectManager.qss | 7 ++ .../Source/GemCatalog/GemFilterTagWidget.cpp | 96 +++++++++++++++++++ .../Source/GemCatalog/GemFilterTagWidget.h | 57 +++++++++++ .../Source/GemCatalog/GemFilterWidget.cpp | 11 +++ .../Source/GemCatalog/GemItemDelegate.cpp | 6 +- .../Source/GemCatalog/GemListHeaderWidget.cpp | 34 ++++++- .../Source/GemCatalog/GemListHeaderWidget.h | 3 +- .../project_manager_files.cmake | 2 + 10 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 Code/Tools/ProjectManager/Resources/FeatureTagClose.svg create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.h diff --git a/Code/Tools/ProjectManager/Resources/FeatureTagClose.svg b/Code/Tools/ProjectManager/Resources/FeatureTagClose.svg new file mode 100644 index 0000000000..9ab30acd65 --- /dev/null +++ b/Code/Tools/ProjectManager/Resources/FeatureTagClose.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc index cfe4b37fbc..2e93e9eca9 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc @@ -34,5 +34,6 @@ Warning.svg Backgrounds/DefaultBackground.jpg Backgrounds/FtueBackground.jpg + FeatureTagClose.svg diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qss b/Code/Tools/ProjectManager/Resources/ProjectManager.qss index d6a2476e83..0684ec1310 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qss +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qss @@ -478,6 +478,13 @@ QProgressBar::chunk { background-color: #333333; } +/************** Filter tag widget **************/ + +#FilterTagWidgetTextLabel { + color: #94D2FF; + font-size: 10px; +} + /************** Gem Catalog (Inspector) **************/ #GemCatalogInspector { diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp new file mode 100644 index 0000000000..c4612debc8 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include +#include + +namespace O3DE::ProjectManager +{ + FilterTagWidget::FilterTagWidget(const QString& text, QWidget* parent) + : QFrame(parent) + { + setFrameShape(QFrame::NoFrame); + + auto* layout = new QHBoxLayout(); + layout->setContentsMargins(6, 5, 4, 4); + layout->setSpacing(2); + setLayout(layout); + + setStyleSheet("background-color: #555555;"); + + m_textLabel = new QLabel(); + m_textLabel->setObjectName("FilterTagWidgetTextLabel"); + m_textLabel->setText(text); + layout->addWidget(m_textLabel); + + m_closeButton = new QPushButton(); + m_closeButton->setFlat(true); + m_closeButton->setIcon(QIcon(":/FeatureTagClose.svg")); + m_closeButton->setIconSize(QSize(12, 12)); + m_closeButton->setStyleSheet("QPushButton { background-color: transparent; border: 0px }"); + layout->addWidget(m_closeButton); + connect(m_closeButton, &QPushButton::clicked, this, [=]{ emit RemoveClicked(); }); + } + + QString FilterTagWidget::text() const + { + return m_textLabel->text(); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + FilterTagWidgetContainer::FilterTagWidgetContainer(QWidget* parent) + : QWidget(parent) + { + m_layout = new QHBoxLayout(); + m_layout->setMargin(0); + m_layout->setSpacing(0); + setLayout(m_layout); + } + + void FilterTagWidgetContainer::Reinit(const QVector& tags) + { + if (m_widget) + { + // Hide the old widget and request deletion. + m_widget->hide(); + m_widget->deleteLater(); + } + + m_widget = new QWidget(this); + + QHBoxLayout* hLayout = new QHBoxLayout(); + hLayout->setAlignment(Qt::AlignLeft); + hLayout->setMargin(0); + hLayout->setSpacing(8); + + const int numTags = tags.count(); + for (int i = 0; i < numTags; ++i) + { + FilterTagWidget* tagWidget = new FilterTagWidget(tags[i]); + + // Add the tag widget to the current row. + hLayout->addWidget(tagWidget); + + // Connect the clicked event of the close button of the tag widget to the remove tag function in the container. + connect(tagWidget, &FilterTagWidget::RemoveClicked, this, [this, tagWidget]{ emit TagRemoved(tagWidget->text()); }); + } + + QWidget* spacerWidget = new QWidget(); + spacerWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + hLayout->addWidget(spacerWidget); + + m_widget->setLayout(hLayout); + m_layout->addWidget(m_widget); + + setFixedHeight(30); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.h new file mode 100644 index 0000000000..0994618d4e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QHBoxLayout) +QT_FORWARD_DECLARE_CLASS(QLabel) +QT_FORWARD_DECLARE_CLASS(QPushButton) +QT_FORWARD_DECLARE_CLASS(QWidget) + +namespace O3DE::ProjectManager +{ + class FilterTagWidget + : public QFrame + { + Q_OBJECT + + public: + FilterTagWidget(const QString& text, QWidget* parent = nullptr); + QString text() const; + + signals: + void RemoveClicked(); + + private: + QLabel* m_textLabel = nullptr; + QPushButton* m_closeButton = nullptr; + }; + + // Horizontally expanding filter tag container widget + class FilterTagWidgetContainer + : public QWidget + { + Q_OBJECT + + public: + FilterTagWidgetContainer(QWidget* parent = nullptr); + void Reinit(const QVector& tags); + + signals: + void TagRemoved(QString tagName); + + private: + QWidget* m_widget = nullptr; + QHBoxLayout* m_layout = nullptr; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp index 753371ba52..268e793ee8 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace O3DE::ProjectManager { @@ -485,6 +486,7 @@ namespace O3DE::ProjectManager const QString& feature = elementNames[i]; QAbstractButton* button = buttons[i]; + // Adjust the proxy model and enable or disable the clicked feature used for filtering. connect(button, &QAbstractButton::toggled, this, [=](bool checked) { QSet features = m_filterProxyModel->GetFeatures(); @@ -498,6 +500,15 @@ namespace O3DE::ProjectManager } m_filterProxyModel->SetFeatures(features); }); + + // Sync the UI state with the proxy model filtering. + connect(m_filterProxyModel, &GemSortFilterProxyModel::OnInvalidated, this, [=] + { + const QSet& filteredFeatureTags = m_filterProxyModel->GetFeatures(); + const bool isChecked = filteredFeatureTags.contains(button->text()); + QSignalBlocker signalsBlocker(button); + button->setChecked(isChecked); + }); } } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp index b9dc3e9fcc..f5bedb79eb 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp @@ -102,9 +102,11 @@ namespace O3DE::ProjectManager // In case there are feature tags displayed at the bottom, decrease the size of the summary text field. const QStringList featureTags = GemModel::GetFeatures(modelIndex); - const int summaryHeight = contentRect.height() - (!featureTags.empty() * 30); + const int featureTagAreaHeight = 30; + const int summaryHeight = contentRect.height() - (!featureTags.empty() * featureTagAreaHeight); - const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - s_itemMargins.right() * 3, + const int additionalSummarySpacing = s_itemMargins.right() * 3; + const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - additionalSummarySpacing, summaryHeight); const QRect summaryRect = QRect(/*topLeft=*/QPoint(contentRect.left() + s_summaryStartX, contentRect.top()), summarySize); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.cpp index 5e2f93c2fc..3d6fd1947c 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.cpp @@ -7,10 +7,13 @@ #include #include -#include +#include +#include +#include #include -#include #include +#include +#include namespace O3DE::ProjectManager { @@ -23,11 +26,34 @@ namespace O3DE::ProjectManager setStyleSheet("background-color: #333333;"); - vLayout->addSpacing(20); + vLayout->addSpacing(13); // Top section QHBoxLayout* topLayout = new QHBoxLayout(); + topLayout->addSpacing(16); topLayout->setMargin(0); + + auto* tagWidget = new FilterTagWidgetContainer(); + + // Adjust the proxy model and disable the given feature used for filtering. + connect(tagWidget, &FilterTagWidgetContainer::TagRemoved, this, [=](QString tagName) + { + QSet filteredFeatureTags = proxyModel->GetFeatures(); + filteredFeatureTags.remove(tagName); + proxyModel->SetFeatures(filteredFeatureTags); + }); + + // Reinitialize the tag widget in case the filter in the proxy model got invalided. + connect(proxyModel, &GemSortFilterProxyModel::OnInvalidated, this, [=] + { + const QSet& tagSet = proxyModel->GetFeatures(); + QVector sortedTags(tagSet.begin(), tagSet.end()); + std::sort(sortedTags.begin(), sortedTags.end()); + tagWidget->Reinit(sortedTags); + }); + + topLayout->addWidget(tagWidget); + topLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); QLabel* showCountLabel = new QLabel(); @@ -43,7 +69,7 @@ namespace O3DE::ProjectManager vLayout->addLayout(topLayout); - vLayout->addSpacing(20); + vLayout->addSpacing(13); // Separating line QFrame* hLine = new QFrame(); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.h index a9b3b3aa36..fcad58a321 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemListHeaderWidget.h @@ -8,9 +8,8 @@ #pragma once #if !defined(Q_MOC_RUN) +#include #include -#include -#include #include #endif diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index a5632f082c..07c649624e 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -71,6 +71,8 @@ set(FILES Source/GemCatalog/GemCatalogHeaderWidget.cpp Source/GemCatalog/GemCatalogScreen.h Source/GemCatalog/GemCatalogScreen.cpp + Source/GemCatalog/GemFilterTagWidget.h + Source/GemCatalog/GemFilterTagWidget.cpp Source/GemCatalog/GemFilterWidget.h Source/GemCatalog/GemFilterWidget.cpp Source/GemCatalog/GemInfo.h From e3be8b4c467ded8670c338479af9715287f8c5f8 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 9 Jul 2021 09:01:35 -0700 Subject: [PATCH 18/37] Enable AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER for Mac/Linux (#2017) Validated it opens the project manager in Mac Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../Platform/Linux/AzFramework/AzFramework_Traits_Linux.h | 2 +- .../Platform/Mac/AzFramework/AzFramework_Traits_Mac.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h b/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h index 98893e2d01..2cf5b3f87e 100644 --- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h +++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h @@ -12,5 +12,5 @@ #define AZ_TRAIT_AZFRAMEWORK_USE_ERRNO_T_TYPEDEF 1 #define AZ_TRAIT_AZFRAMEWORK_USE_POSIX_LOCALTIME_R 0 #define AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL "python.sh" -#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 0 +#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 1 #define AZ_TRAIT_AZFRAMEWORK_PROCESSLAUNCH_DEFAULT 0 diff --git a/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h b/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h index 6af4294a5c..73f6d212d4 100644 --- a/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h +++ b/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h @@ -12,5 +12,5 @@ #define AZ_TRAIT_AZFRAMEWORK_USE_ERRNO_T_TYPEDEF 0 #define AZ_TRAIT_AZFRAMEWORK_USE_POSIX_LOCALTIME_R 1 #define AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL "python.sh" -#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 0 +#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 1 #define AZ_TRAIT_AZFRAMEWORK_PROCESSLAUNCH_DEFAULT 0 From 76cef6e91fb90f406674eefaf81ac24d55b8ab9b Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Fri, 9 Jul 2021 09:38:11 -0700 Subject: [PATCH 19/37] Project Manager: Showing a progress bar when copying projects (#2025) Signed-off-by: Benjamin Jillich --- .../Resources/ProjectManager.qss | 2 - .../ProjectManager/Source/ProjectUtils.cpp | 167 ++++++++++++++++-- .../ProjectManager/Source/ProjectUtils.h | 2 +- 3 files changed, 152 insertions(+), 19 deletions(-) diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qss b/Code/Tools/ProjectManager/Resources/ProjectManager.qss index 0684ec1310..74acc1c7ef 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qss +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qss @@ -435,8 +435,6 @@ QProgressBar { border: none; background-color: transparent; padding: 0px; - min-height: 14px; - font-size: 2px; } QProgressBar::chunk { diff --git a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp index f7a90f5e0c..82944aa41a 100644 --- a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp @@ -10,11 +10,13 @@ #include #include +#include #include #include #include #include #include +#include namespace O3DE::ProjectManager { @@ -55,7 +57,42 @@ namespace O3DE::ProjectManager return false; } - static bool CopyDirectory(const QString& origPath, const QString& newPath) + typedef AZStd::function StatusFunction; + static void RecursiveGetAllFiles(const QDir& directory, QStringList& outFileList, qint64& outTotalSizeInBytes, StatusFunction statusCallback) + { + const QStringList entries = directory.entryList(QDir::Dirs | QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot); + for (const QString& entryPath : entries) + { + const QString filePath = QDir::toNativeSeparators(QString("%1/%2").arg(directory.path()).arg(entryPath)); + QFileInfo fileInfo(filePath); + + if (fileInfo.isDir()) + { + QDir subDirectory(filePath); + RecursiveGetAllFiles(subDirectory, outFileList, outTotalSizeInBytes, statusCallback); + } + else + { + outFileList.push_back(filePath); + outTotalSizeInBytes += fileInfo.size(); + + const int updateStatusEvery = 64; + if (outFileList.size() % updateStatusEvery == 0) + { + statusCallback(outFileList.size(), outTotalSizeInBytes); + } + } + } + } + + static bool CopyDirectory(QProgressDialog* progressDialog, + const QString& origPath, + const QString& newPath, + QStringList& filesToCopy, + int& outNumCopiedFiles, + qint64 totalSizeToCopy, + qint64& outCopiedFileSize, + bool& showIgnoreFileDialog) { QDir original(origPath); if (!original.exists()) @@ -65,19 +102,91 @@ namespace O3DE::ProjectManager for (QString directory : original.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + if (progressDialog->wasCanceled()) + { + return false; + } + QString newDirectoryPath = newPath + QDir::separator() + directory; original.mkpath(newDirectoryPath); - if (!CopyDirectory(origPath + QDir::separator() + directory, newDirectoryPath)) + if (!CopyDirectory(progressDialog, origPath + QDir::separator() + directory, + newDirectoryPath, filesToCopy, outNumCopiedFiles, totalSizeToCopy, outCopiedFileSize, showIgnoreFileDialog)) { return false; } } + QLocale locale; + const float progressDialogRangeHalf = qFabs(progressDialog->maximum() - progressDialog->minimum()) * 0.5f; for (QString file : original.entryList(QDir::Files)) { - if (!QFile::copy(origPath + QDir::separator() + file, newPath + QDir::separator() + file)) + if (progressDialog->wasCanceled()) + { return false; + } + + // Progress window update + { + // Weight in the number of already copied files as well as the copied bytes to get a better progress indication + // for cases combining many small files and some really large files. + const float normalizedNumFiles = static_cast(outNumCopiedFiles) / filesToCopy.count(); + const float normalizedFileSize = static_cast(outCopiedFileSize) / totalSizeToCopy; + const int progress = normalizedNumFiles * progressDialogRangeHalf + normalizedFileSize * progressDialogRangeHalf; + progressDialog->setValue(progress); + + const QString copiedFileSizeString = locale.formattedDataSize(outCopiedFileSize); + const QString totalFileSizeString = locale.formattedDataSize(totalSizeToCopy); + progressDialog->setLabelText(QString("Coping file %1 of %2 (%3 of %4) ...").arg(QString::number(outNumCopiedFiles), + QString::number(filesToCopy.count()), + copiedFileSizeString, + totalFileSizeString)); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + } + + const QString toBeCopiedFilePath = origPath + QDir::separator() + file; + const QString copyToFilePath = newPath + QDir::separator() + file; + if (!QFile::copy(toBeCopiedFilePath, copyToFilePath)) + { + // Let the user decide to ignore files that failed to copy or cancel the whole operation. + if (showIgnoreFileDialog) + { + QMessageBox ignoreFileMessageBox; + const QString text = QString("Cannot copy %1.

" + "Source: %2
" + "Destination: %3

" + "Press Yes to ignore the file, YesToAll to ignore all upcoming non-copyable files or " + "Cancel to abort duplicating the project.").arg(file, toBeCopiedFilePath, copyToFilePath); + + ignoreFileMessageBox.setModal(true); + ignoreFileMessageBox.setWindowTitle("Cannot copy file"); + ignoreFileMessageBox.setText(text); + ignoreFileMessageBox.setIcon(QMessageBox::Question); + ignoreFileMessageBox.setStandardButtons(QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::Cancel); + + int ignoreFile = ignoreFileMessageBox.exec(); + if (ignoreFile == QMessageBox::YesToAll) + { + showIgnoreFileDialog = false; + continue; + } + else if (ignoreFile == QMessageBox::Yes) + { + continue; + } + else + { + return false; + } + } + } + else + { + outNumCopiedFiles++; + + QFileInfo fileInfo(toBeCopiedFilePath); + outCopiedFileSize += fileInfo.size(); + } } return true; @@ -119,16 +228,13 @@ namespace O3DE::ProjectManager return false; } - QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - copyResult = CopyProject(origPath, newPath); - QGuiApplication::restoreOverrideCursor(); - + copyResult = CopyProject(origPath, newPath, parent); } return copyResult; } - bool CopyProject(const QString& origPath, const QString& newPath) + bool CopyProject(const QString& origPath, const QString& newPath, QWidget* parent) { // Disallow copying from or into subdirectory if (IsDirectoryDescedent(origPath, newPath) || IsDirectoryDescedent(newPath, origPath)) @@ -136,19 +242,49 @@ namespace O3DE::ProjectManager return false; } - if (!CopyDirectory(origPath, newPath)) + QStringList filesToCopy; + qint64 totalSizeInBytes = 0; + + QProgressDialog* progressDialog = new QProgressDialog(parent); + progressDialog->setAutoClose(true); + progressDialog->setValue(0); + progressDialog->setRange(0, 1000); + progressDialog->setModal(true); + progressDialog->setWindowTitle("Copying project ..."); + progressDialog->show(); + + QLocale locale; + RecursiveGetAllFiles(origPath, filesToCopy, totalSizeInBytes, [=](int fileCount, int sizeInBytes) + { + // Create a human-readable version of the file size. + const QString fileSizeString = locale.formattedDataSize(sizeInBytes); + + progressDialog->setLabelText(QString("Indexing files ... %1 files found, %2 to copy.").arg(fileCount).arg(fileSizeString)); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + }); + + int numFilesCopied = 0; + qint64 copiedFileSize = 0; + + // Phase 1: Copy files + bool showIgnoreFileDialog = true; + bool success = CopyDirectory(progressDialog, origPath, newPath, filesToCopy, numFilesCopied, totalSizeInBytes, copiedFileSize, showIgnoreFileDialog); + if (success) { - // Cleanup whatever mess was made - DeleteProjectFiles(newPath, true); - return false; + // Phase 2: Register project + success = RegisterProject(newPath); } - if (!RegisterProject(newPath)) + if (!success) { + progressDialog->setLabelText("Duplicating project failed/cancelled, removing already copied files ..."); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + DeleteProjectFiles(newPath, true); } - return true; + progressDialog->deleteLater(); + return success; } bool DeleteProjectFiles(const QString& path, bool force) @@ -184,7 +320,7 @@ namespace O3DE::ProjectManager if (!newDirectory.rename(origPath, newPath)) { // Likely failed because trying to move to another partition, try copying - if (!CopyProject(origPath, newPath)) + if (!CopyProject(origPath, newPath, parent)) { return false; } @@ -272,7 +408,6 @@ namespace O3DE::ProjectManager bool IsVS2019Installed() { static bool vs2019Installed = IsVS2019Installed_internal(); - return vs2019Installed; } diff --git a/Code/Tools/ProjectManager/Source/ProjectUtils.h b/Code/Tools/ProjectManager/Source/ProjectUtils.h index 786ff34b88..2829a45180 100644 --- a/Code/Tools/ProjectManager/Source/ProjectUtils.h +++ b/Code/Tools/ProjectManager/Source/ProjectUtils.h @@ -17,7 +17,7 @@ namespace O3DE::ProjectManager bool RegisterProject(const QString& path); bool UnregisterProject(const QString& path); bool CopyProjectDialog(const QString& origPath, QWidget* parent = nullptr); - bool CopyProject(const QString& origPath, const QString& newPath); + bool CopyProject(const QString& origPath, const QString& newPath, QWidget* parent); bool DeleteProjectFiles(const QString& path, bool force = false); bool MoveProject(QString origPath, QString newPath, QWidget* parent = nullptr, bool ignoreRegister = false); From 1b530195fc0bd6e34272a5258230b6ad725acb56 Mon Sep 17 00:00:00 2001 From: jjjoness <82226755+jjjoness@users.noreply.github.com> Date: Fri, 9 Jul 2021 18:03:20 +0100 Subject: [PATCH 20/37] Clarify ImGui activation in Editor viewport (#1765) * Clarify ImGui activation in Editor viewport Signed-off-by: John Jones-Steele * All working following changes from comments in PR Signed-off-by: John Jones-Steele * One more change Signed-off-by: John Jones-Steele * fixes from comments in PR. Signed-off-by: John Jones-Steele * Fixed git merge error Signed-off-by: John Jones-Steele * Added header to ImGuiBus.h Signed-off-by: John Jones-Steele * Fix for Jenkins error Signed-off-by: John Jones-Steele * Minor typo fix Signed-off-by: John Jones-Steele --- Code/Editor/MainWindow.cpp | 13 ++++++ Code/Editor/MainWindow.h | 1 + .../UI/Outliner/OutlinerWidget.cpp | 19 +++++++-- .../UI/Outliner/OutlinerWidget.hxx | 6 +++ Code/Editor/QtViewPaneManager.cpp | 14 +++++++ Code/Editor/QtViewPaneManager.h | 9 +++- .../API/EditorWindowRequestBus.h | 41 ++++++++++++++++++- .../UI/Outliner/EntityOutlinerWidget.cpp | 19 +++++++-- .../UI/Outliner/EntityOutlinerWidget.hxx | 6 +++ .../PropertyEditor/EntityPropertyEditor.cpp | 23 +++++++++++ .../PropertyEditor/EntityPropertyEditor.hxx | 5 +++ Gems/ImGui/Code/Include/ImGuiBus.h | 32 ++++++++++++--- Gems/ImGui/Code/Source/ImGuiManager.cpp | 7 ++++ Gems/ImGui/Code/Source/ImGuiManager.h | 1 + .../LYCommonMenu/ImGuiLYAssetExplorer.cpp | 2 +- .../Source/LYCommonMenu/ImGuiLYCommonMenu.cpp | 19 +++++++++ .../LYCommonMenu/ImGuiLYEntityOutliner.cpp | 2 +- 17 files changed, 201 insertions(+), 18 deletions(-) diff --git a/Code/Editor/MainWindow.cpp b/Code/Editor/MainWindow.cpp index 10dfddbf8c..b2cb2fc8b6 100644 --- a/Code/Editor/MainWindow.cpp +++ b/Code/Editor/MainWindow.cpp @@ -41,6 +41,7 @@ AZ_POP_DISABLE_WARNING // AzToolsFramework #include +#include #include #include #include @@ -93,6 +94,8 @@ AZ_POP_DISABLE_WARNING #include "AssetEditor/AssetEditorWindow.h" #include "ActionManager.h" +#include + using namespace AZ; using namespace AzQtComponents; using namespace AzToolsFramework; @@ -489,6 +492,16 @@ void MainWindow::Initialize() ActionOverrideRequestBus::Event( GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, this); + if (auto imGuiManager = AZ::Interface::Get()) + { + auto handleImGuiStateChangeFn = [](bool enabled) + { + EditorWindowUIRequestBus::Broadcast(&EditorWindowUIRequests::SetEditorUiEnabled, enabled); + }; + m_handleImGuiStateChangeHandler = ImGui::IImGuiManager::ImGuiSetEnabledEvent::Handler(handleImGuiStateChangeFn); + imGuiManager->ConnectImGuiSetEnabledChangedHandler(m_handleImGuiStateChangeHandler); + } + AzToolsFramework::EditorEventsBus::Broadcast(&AzToolsFramework::EditorEvents::NotifyMainWindowInitialized, this); } diff --git a/Code/Editor/MainWindow.h b/Code/Editor/MainWindow.h index 34b121537d..99af2ea326 100644 --- a/Code/Editor/MainWindow.h +++ b/Code/Editor/MainWindow.h @@ -249,6 +249,7 @@ private: QPointer m_toolbarCustomizationDialog; QScopedPointer m_sourceControlNotifHandler; + AZ::Event::Handler m_handleImGuiStateChangeHandler; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING static MainWindow* m_instance; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp index d69480b169..02dabb8b20 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp @@ -269,10 +269,12 @@ OutlinerWidget::OutlinerWidget(QWidget* pParent, Qt::WindowFlags flags) AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect( AzToolsFramework::GetEntityContextId()); AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusConnect(); + AzToolsFramework::EditorWindowUIRequestBus::Handler::BusConnect(); } OutlinerWidget::~OutlinerWidget() { + AzToolsFramework::EditorWindowUIRequestBus::Handler::BusDisconnect(); AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorPickModeNotificationBus::Handler::BusDisconnect(); @@ -1321,16 +1323,25 @@ static void SetEntityOutlinerState(Ui::OutlinerWidgetUI* entityOutlinerUi, const AzQtComponents::SetWidgetInteractEnabled(entityOutlinerUi->m_searchWidget, on); } +void OutlinerWidget::EnableUi(bool enable) +{ + SetEntityOutlinerState(m_gui, enable); + setEnabled(enable); +} + +void OutlinerWidget::SetEditorUiEnabled(bool enable) +{ + EnableUi(enable); +} + void OutlinerWidget::EnteredComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - SetEntityOutlinerState(m_gui, false); - setEnabled(false); + EnableUi(false); } void OutlinerWidget::LeftComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - setEnabled(true); - SetEntityOutlinerState(m_gui, true); + EnableUi(true); } void OutlinerWidget::OnSliceInstantiated(const AZ::Data::AssetId& /*sliceAssetId*/, AZ::SliceComponent::SliceInstanceAddress& sliceAddress, const AzFramework::SliceInstantiationTicket& /*ticket*/) diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx index 75991424bb..aff305e0fe 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -57,6 +58,7 @@ class OutlinerWidget , private AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler , private AzToolsFramework::EditorEntityInfoNotificationBus::Handler , private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler + , private AzToolsFramework::EditorWindowUIRequestBus::Handler { Q_OBJECT; public: @@ -106,6 +108,9 @@ private: void EnteredComponentMode(const AZStd::vector& componentModeTypes) override; void LeftComponentMode(const AZStd::vector& componentModeTypes) override; + // EditorWindowUIRequestBus overrides + void SetEditorUiEnabled(bool enable) override; + // Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored. template QItemSelection BuildSelectionFromEntities(const EntityIdCollection& entityIds); @@ -171,6 +176,7 @@ private: AZ::EntityId GetEntityIdFromIndex(const QModelIndex& index) const; QModelIndex GetIndexFromEntityId(const AZ::EntityId& entityId) const; void ExtractEntityIdsFromSelection(const QItemSelection& selection, AzToolsFramework::EntityIdList& entityIdList) const; + void EnableUi(bool enable); // AzToolsFramework::OutlinerModelNotificationBus::Handler // Receive notification from the outliner model that we should scroll diff --git a/Code/Editor/QtViewPaneManager.cpp b/Code/Editor/QtViewPaneManager.cpp index 35b2160a1f..9f2b9f9cf8 100644 --- a/Code/Editor/QtViewPaneManager.cpp +++ b/Code/Editor/QtViewPaneManager.cpp @@ -525,6 +525,7 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent) // view pane manager is interested when we enter/exit ComponentMode m_componentModeNotifications.BusConnect(AzToolsFramework::GetEntityContextId()); + m_windowRequest.BusConnect(); m_componentModeNotifications.SetEnteredComponentModeFunc( [this](const AZStd::vector& /*componentModeTypes*/) @@ -545,10 +546,23 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent) AzQtComponents::SetWidgetInteractEnabled(widget, on); }); }); + + m_windowRequest.SetEnableEditorUiFunc( + [this](bool enable) + { + // gray out panels when entering ImGui mode + SetDefaultActionsEnabled( + enable, m_registeredPanes, + [](QWidget* widget, bool on) + { + AzQtComponents::SetWidgetInteractEnabled(widget, on); + }); + }); } QtViewPaneManager::~QtViewPaneManager() { + m_windowRequest.BusDisconnect(); m_componentModeNotifications.BusDisconnect(); } diff --git a/Code/Editor/QtViewPaneManager.h b/Code/Editor/QtViewPaneManager.h index aa382c41c0..2b3412aad6 100644 --- a/Code/Editor/QtViewPaneManager.h +++ b/Code/Editor/QtViewPaneManager.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -249,8 +250,12 @@ private: QPointer m_advancedDockManager; using EditorComponentModeNotificationBusImpl = AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBusImpl; - EditorComponentModeNotificationBusImpl m_componentModeNotifications; /**< Helper for EditorComponentModeNotificationBus so - * QtViewPaneManager does not need to inherit directly from it. */ + EditorComponentModeNotificationBusImpl m_componentModeNotifications; //!< Helper for EditorComponentModeNotificationBus so + //!< QtViewPaneManager does not need to inherit directly from it. */ + + using EditorWindowRequestBusImpl = AzToolsFramework::EditorWindowRequestBusImpl; + EditorWindowRequestBusImpl m_windowRequest; //!< Helper for EditorWindowRequestBus so + //!< QtViewPaneManager does not need to inherit directly from it. */ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h index 03bb76b03a..ef4d2deb5e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h @@ -36,8 +36,47 @@ namespace AzToolsFramework /// Retrieve the main application window. virtual QWidget* GetAppMainWindow() { return nullptr; } }; - using EditorWindowRequestBus = AZ::EBus; + + class EditorWindowUIRequests : public AZ::EBusTraits + { + public: + using Bus = AZ::EBus; + + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + ////////////////////////////////////////////////////////////////////////// + + /// Enable/Disable the Editor UI. + virtual void SetEditorUiEnabled([[maybe_unused]] bool enable) {} + }; + using EditorWindowUIRequestBus = AZ::EBus; + + using EnableUiFunction = AZStd::function; + + /// Helper for EditorWindowRequests to be used as a + /// member instead of inheriting from EBus directly. + class EditorWindowRequestBusImpl + : public EditorWindowUIRequestBus::Handler + { + public: + /// Set the function to be called when entering ImGui Mode. + void SetEnableEditorUiFunc(const EnableUiFunction enableEditorUiFunc) + { + m_enableEditorUiFunc = AZStd::move(enableEditorUiFunc); + } + + private: + // EditorWindowRequestBus + void SetEditorUiEnabled( [[maybe_unused]] bool enable) override + { + m_enableEditorUiFunc(enable); + } + + EnableUiFunction m_enableEditorUiFunc; ///< Function to call when entering ImGui Mode. + }; + } // namespace AzToolsFramework #endif // AZTOOLSFRAMEWORK_EDITORWINDOWREQUESTBUS_H diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.cpp index 96479bb54c..03784343f5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.cpp @@ -291,10 +291,12 @@ namespace AzToolsFramework GetEntityContextId()); EditorEntityInfoNotificationBus::Handler::BusConnect(); Prefab::PrefabPublicNotificationBus::Handler::BusConnect(); + EditorWindowUIRequestBus::Handler::BusConnect(); } EntityOutlinerWidget::~EntityOutlinerWidget() { + EditorWindowUIRequestBus::Handler::BusDisconnect(); Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect(); ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect(); EditorEntityInfoNotificationBus::Handler::BusDisconnect(); @@ -1106,16 +1108,25 @@ namespace AzToolsFramework AzQtComponents::SetWidgetInteractEnabled(entityOutlinerUi->m_searchWidget, on); } + void EntityOutlinerWidget::EnableUi(bool enable) + { + SetEntityOutlinerState(m_gui, enable); + setEnabled(enable); + } + + void EntityOutlinerWidget::SetEditorUiEnabled(bool enable) + { + EnableUi(enable); + } + void EntityOutlinerWidget::EnteredComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - SetEntityOutlinerState(m_gui, false); - setEnabled(false); + EnableUi(false); } void EntityOutlinerWidget::LeftComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { - setEnabled(true); - SetEntityOutlinerState(m_gui, true); + EnableUi(true); } void EntityOutlinerWidget::OnPrefabInstancePropagationBegin() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.hxx index 68f538c3ff..e3f9ad2135 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.hxx +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerWidget.hxx @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -58,6 +59,7 @@ namespace AzToolsFramework , private EditorEntityInfoNotificationBus::Handler , private ComponentModeFramework::EditorComponentModeNotificationBus::Handler , private Prefab::PrefabPublicNotificationBus::Handler + , private EditorWindowUIRequestBus::Handler { Q_OBJECT; public: @@ -105,6 +107,9 @@ namespace AzToolsFramework void OnPrefabInstancePropagationBegin() override; void OnPrefabInstancePropagationEnd() override; + // EditorWindowUIRequestBus overrides + void SetEditorUiEnabled(bool enable) override; + // Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored. template QItemSelection BuildSelectionFromEntities(const EntityIdCollection& entityIds); @@ -155,6 +160,7 @@ namespace AzToolsFramework AZ::EntityId GetEntityIdFromIndex(const QModelIndex& index) const; QModelIndex GetIndexFromEntityId(const AZ::EntityId& entityId) const; void ExtractEntityIdsFromSelection(const QItemSelection& selection, EntityIdList& entityIdList) const; + void EnableUi(bool enable); // OutlinerModelNotificationBus::Handler // Receive notification from the outliner model that we should scroll diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp index 6a399ad816..5d1ec93fda 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp @@ -376,6 +376,7 @@ namespace AzToolsFramework ToolsApplicationEvents::Bus::Handler::BusConnect(); AZ::EntitySystemBus::Handler::BusConnect(); EntityPropertyEditorRequestBus::Handler::BusConnect(); + EditorWindowUIRequestBus::Handler::BusConnect(); m_spacer = nullptr; m_emptyIcon = QIcon(); @@ -421,6 +422,7 @@ namespace AzToolsFramework { qApp->removeEventFilter(this); + EditorWindowUIRequestBus::Handler::BusDisconnect(); EntityPropertyEditorRequestBus::Handler::BusDisconnect(); ToolsApplicationEvents::Bus::Handler::BusDisconnect(); AZ::EntitySystemBus::Handler::BusDisconnect(); @@ -4961,6 +4963,27 @@ namespace AzToolsFramework EnableDisableComponentActions(widget, actions, false); } + void EntityPropertyEditor::SetEditorUiEnabled(bool enable) + { + if (enable) + { + EnableComponentActions(this, m_entityComponentActions); + } + else + { + DisableComponentActions(this, m_entityComponentActions); + } + m_disabled = !enable; + SetPropertyEditorState(m_gui, enable); + + for (auto componentEditor : m_componentEditors) + { + AzQtComponents::SetWidgetInteractEnabled(componentEditor, enable); + } + // record the selected state after entering/leaving component mode + SaveComponentEditorState(); + } + void EntityPropertyEditor::EnteredComponentMode(const AZStd::vector& componentModeTypes) { DisableComponentActions(this, m_entityComponentActions); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx index b15e27e41a..f2ff4eb927 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,7 @@ namespace AzToolsFramework , public EditorInspectorComponentNotificationBus::MultiHandler , private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler , public AZ::EntitySystemBus::Handler + , private EditorWindowUIRequestBus::Handler { Q_OBJECT; public: @@ -208,6 +210,9 @@ namespace AzToolsFramework void GetSelectedEntities(EntityIdList& selectedEntityIds) override; void SetNewComponentId(AZ::ComponentId componentId) override; + // EditorWindowRequestBus overrides + void SetEditorUiEnabled(bool enable) override; + bool IsEntitySelected(const AZ::EntityId& id) const; bool IsSingleEntitySelected(const AZ::EntityId& id) const; diff --git a/Gems/ImGui/Code/Include/ImGuiBus.h b/Gems/ImGui/Code/Include/ImGuiBus.h index ea7fe1631e..06a3b472da 100644 --- a/Gems/ImGui/Code/Include/ImGuiBus.h +++ b/Gems/ImGui/Code/Include/ImGuiBus.h @@ -8,6 +8,7 @@ #pragma once #include +#include // Forward Declares struct ImVec2; @@ -86,9 +87,19 @@ namespace ImGui virtual void SetImGuiRenderResolution(const ImVec2& res) = 0; virtual void OverrideRenderWindowSize(uint32_t width, uint32_t height) = 0; virtual void RestoreRenderWindowSizeToDefault() = 0; + virtual void ToggleThroughImGuiVisibleState() = 0; virtual void SetDpiScalingFactor(float dpiScalingFactor) = 0; virtual float GetDpiScalingFactor() const = 0; virtual void Render() = 0; + + using ImGuiSetEnabledEvent = AZ::Event; + ImGuiSetEnabledEvent m_setEnabledEvent; + + // interface + void ConnectImGuiSetEnabledChangedHandler(ImGuiSetEnabledEvent::Handler& handler) + { + handler.Connect(m_setEnabledEvent); + } }; class IImGuiManagerRequests @@ -101,19 +112,30 @@ namespace ImGui }; using ImGuiManagerBus = AZ::EBus; - // Bus for getting notifications from the IMGUI Entity Outliner - class IImGuiEntityOutlinerNotifcations : public AZ::EBusTraits + class IImGuiManagerNotifications : public AZ::EBusTraits { public: - static const char* GetUniqueName() { return "IImGuiEntityOutlinerNotifcations"; } static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - using Bus = AZ::EBus; + using Bus = AZ::EBus; + + virtual void ImGuiSetEnabled( [[maybe_unused]] bool enabled) {} + }; + using ImGuiManagerNotificationBus = AZ::EBus; + + // Bus for getting notifications from the IMGUI Entity Outliner + class IImGuiEntityOutlinerNotifications : public AZ::EBusTraits + { + public: + static const char* GetUniqueName() { return "IImGuiEntityOutlinerNotifications"; } + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + using Bus = AZ::EBus; // Callback for game code to handle targetting an IMGUI entity virtual void OnImGuiEntityOutlinerTarget(AZ::EntityId target) { (void)target; } }; - typedef AZ::EBus ImGuiEntityOutlinerNotifcationBus; + typedef AZ::EBus ImGuiEntityOutlinerNotificationBus; // a pair of an entity id, and a typeid, used to represent component rtti type info typedef AZStd::pair ImGuiEntComponentId; diff --git a/Gems/ImGui/Code/Source/ImGuiManager.cpp b/Gems/ImGui/Code/Source/ImGuiManager.cpp index 42c8d3929c..7b2506fbcb 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.cpp +++ b/Gems/ImGui/Code/Source/ImGuiManager.cpp @@ -738,8 +738,15 @@ void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex) } m_menuBarStatusChanged = true; + m_setEnabledEvent.Signal(m_clientMenuBarState == DisplayState::Hidden); } +void ImGuiManager::ToggleThroughImGuiVisibleState() +{ + ToggleThroughImGuiVisibleState(-1); +} + + void ImGuiManager::RenderImGuiBuffers(const ImVec2& scaleRects) { ImGui::ImGuiContextScope contextScope(m_imguiContext); diff --git a/Gems/ImGui/Code/Source/ImGuiManager.h b/Gems/ImGui/Code/Source/ImGuiManager.h index 1509f27c57..02af3d0c09 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.h +++ b/Gems/ImGui/Code/Source/ImGuiManager.h @@ -60,6 +60,7 @@ namespace ImGui void SetDpiScalingFactor(float dpiScalingFactor) override; float GetDpiScalingFactor() const override; void Render() override; + void ToggleThroughImGuiVisibleState() override; // -- ImGuiManagerBus Interface ------------------------------------------------------------------- // -- AzFramework::InputChannelEventListener and AzFramework::InputTextEventListener Interface ------------ diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp index 2f996f5768..d9d81c24f2 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp @@ -465,7 +465,7 @@ namespace ImGui ImGui::BeginGroup(); if (ImGui::SmallButton(AZStd::string::format("-View #%03d-##%s", ++instanceCount, meshInstance.first.ToString().c_str()).c_str())) { - ImGuiEntityOutlinerNotifcationBus::Broadcast(&IImGuiEntityOutlinerNotifcations::OnImGuiEntityOutlinerTarget, meshInstance.first); + ImGuiEntityOutlinerNotificationBus::Broadcast(&IImGuiEntityOutlinerNotifications::OnImGuiEntityOutlinerTarget, meshInstance.first); } // Build the Label String. ImGui::SameLine(); diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYCommonMenu.cpp b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYCommonMenu.cpp index 9994851faa..eb918041f7 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYCommonMenu.cpp +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYCommonMenu.cpp @@ -571,7 +571,26 @@ namespace ImGui // End LY Common Tools menu ImGui::EndMenu(); } + const int labelSize{ 100 }; + const int buttonSize{ 40 }; ImGuiUpdateListenerBus::Broadcast(&IImGuiUpdateListener::OnImGuiMainMenuUpdate); + ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - labelSize); + float backgroundHeight = ImGui::GetTextLineHeight() + 3; + ImVec2 cursorPos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled( + cursorPos, ImVec2(cursorPos.x + labelSize, cursorPos.y + backgroundHeight), IM_COL32(0, 115, 187, 255)); + ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - labelSize); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 1); + ImGui::Text("ImGui:ON"); + ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - buttonSize); + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 0, 0, 255)); + ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(255, 255, 255, 255)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(128, 128, 128, 255)); + if (ImGui::SmallButton("home")) + { + ImGuiManagerBus::Broadcast(&IImGuiManager::ToggleThroughImGuiVisibleState); + } + ImGui::PopStyleColor(3); ImGui::EndMainMenuBar(); } diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp index aca52af238..57502296ae 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp @@ -590,7 +590,7 @@ namespace ImGui if (ImGui::SmallButton(targetLabel.c_str())) { // Send EBUS event out to Target an Entity. Up to game code to implement. - ImGuiEntityOutlinerNotifcationBus::Broadcast(&IImGuiEntityOutlinerNotifcations::OnImGuiEntityOutlinerTarget, node->m_entityId); + ImGuiEntityOutlinerNotificationBus::Broadcast(&IImGuiEntityOutlinerNotifications::OnImGuiEntityOutlinerTarget, node->m_entityId); } } From e06ec2caa903260f9ce2de90e0be9bfba90ed747 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:19:42 -0500 Subject: [PATCH 21/37] Fixed cmake configuring when using an External Gem (#2020) The ly_get_absolute_pal_filename method has been refactored to no longer use regular expressions to determine how to split a PAL directory, but instead Path operations are used Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- Templates/DefaultGem/Template/CMakeLists.txt | 8 +- cmake/PAL.cmake | 154 ++++++++++--------- 2 files changed, 80 insertions(+), 82 deletions(-) diff --git a/Templates/DefaultGem/Template/CMakeLists.txt b/Templates/DefaultGem/Template/CMakeLists.txt index d00a5f0128..5ea435a790 100644 --- a/Templates/DefaultGem/Template/CMakeLists.txt +++ b/Templates/DefaultGem/Template/CMakeLists.txt @@ -10,13 +10,7 @@ set(o3de_gem_json ${o3de_gem_path}/gem.json) o3de_read_json_key(o3de_gem_name ${o3de_gem_json} "gem_name") o3de_restricted_path(${o3de_gem_json} o3de_gem_restricted_path) -# Currently we are in the DefaultProjectSource folder: ${CMAKE_CURRENT_LIST_DIR} -# Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} -# Note: ly_get_list_relative_pal_filename will take care of the details for us, as this may be a restricted platform -# in which case it will see if that platform is present here or in the restricted folder. -# i.e. It could here: DefaultProjectSource/Platform/ or -# //DefaultProjectSource -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_gem_restricted_path} ${o3de_gem_path} ${o3de_gem_name}) +ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${o3de_gem_restricted_path}" ${o3de_gem_path} ${o3de_gem_name}) # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the # project cmake for this platform. diff --git a/cmake/PAL.cmake b/cmake/PAL.cmake index 11541d395a..c51b39482f 100644 --- a/cmake/PAL.cmake +++ b/cmake/PAL.cmake @@ -29,7 +29,8 @@ function(o3de_restricted_id o3de_json_file restricted) ly_file_read(${o3de_json_file} json_data) string(JSON restricted_entry ERROR_VARIABLE json_error GET ${json_data} "restricted_name") if(json_error) - message(WARNING "Unable to read restricted from '${o3de_json_file}', error: ${json_error}") + # Restricted fields can never be a requirement so no warning is issued + return() endif() if(restricted_entry) set(${restricted} ${restricted_entry} PARENT_SCOPE) @@ -148,86 +149,89 @@ function(ly_get_absolute_pal_filename out_name in_name) set(full_name ${in_name}) if(${ARGC} GREATER 4) - # The user has supplied an object restricted path, the object path and the object name for consideration - set(object_restricted_path ${ARGV2}) - set(object_path ${ARGV3}) + # The object name is used to resolve ambiguities when a PAL directory is requested from + # two different external subdirectory root paths + # Such as if a PAL directory for two root object paths with same relative structure was requested to be Palified + # i.e /Platform//IO and /Platform//IO + # Normally the restricted PAL path for both gems would be "//IO". + # The object name can be used to make this path unique + # "///IO" for gem 1 and + # "///IO" for gem 2 set(object_name ${ARGV4}) - - # if the file is not in the object path then we cannot determine a PAL file for it - file(RELATIVE_PATH relative_path ${object_path} ${full_name}) - if (NOT (IS_ABSOLUTE relative_path OR relative_path MATCHES [[^(\.\./)+(.*)]])) - if (NOT EXISTS ${full_name}) - string(REGEX MATCH "${object_path}/(.*)/Platform/([^/]*)/?(.*)$" match ${full_name}) - if(NOT CMAKE_MATCH_1) - string(REGEX MATCH "${object_path}/Platform/([^/]*)/?(.*)$" match ${full_name}) - set(full_name ${object_restricted_path}/${CMAKE_MATCH_1}/${object_name}) - if(CMAKE_MATCH_2) - string(APPEND full_name "/" ${CMAKE_MATCH_2}) - endif() - elseif("${CMAKE_MATCH_2}" IN_LIST PAL_RESTRICTED_PLATFORMS) - set(full_name ${object_restricted_path}/${CMAKE_MATCH_2}/${object_name}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_3) - string(APPEND full_name "/" ${CMAKE_MATCH_3}) - endif() - endif() - endif() - endif() - set(${out_name} ${full_name} PARENT_SCOPE) - - elseif(${ARGC} GREATER 3) - # The user has supplied an object restricted path, the object path for consideration - set(object_restricted_path ${ARGV2}) - set(object_path ${ARGV3}) - - # if the file is not in the object path then we cannot determine a PAL file for it - file(RELATIVE_PATH relative_path ${object_path} ${full_name}) - if (NOT (IS_ABSOLUTE relative_path OR relative_path MATCHES [[^(\.\./)+(.*)]])) - if (NOT EXISTS ${full_name}) - string(REGEX MATCH "${object_path}/(.*)/Platform/([^/]*)/?(.*)$" match ${full_name}) - if(NOT CMAKE_MATCH_1) - string(REGEX MATCH "${object_path}/Platform/([^/]*)/?(.*)$" match ${full_name}) - set(full_name ${object_restricted_path}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_2) - string(APPEND full_name "/" ${CMAKE_MATCH_2}) - endif() - elseif("${CMAKE_MATCH_2}" IN_LIST PAL_RESTRICTED_PLATFORMS) - set(full_name ${object_restricted_path}/${CMAKE_MATCH_2}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_3) - string(APPEND full_name "/" ${CMAKE_MATCH_3}) - endif() - endif() - endif() - endif() - set(${out_name} ${full_name} PARENT_SCOPE) - - else() - # The user has not supplied any path so we must assume it is the o3de engine restricted and o3de engine path - # if the file is not in the o3de engine path then we cannot determine a PAL file for it - file(RELATIVE_PATH relative_path ${LY_ROOT_FOLDER} ${full_name}) - if (NOT (IS_ABSOLUTE relative_path OR relative_path MATCHES [[^(\.\./)+(.*)]])) - if (NOT EXISTS ${full_name}) - string(REGEX MATCH "${LY_ROOT_FOLDER}/(.*)/Platform/([^/]*)/?(.*)$" match ${full_name}) - if(NOT CMAKE_MATCH_1) - string(REGEX MATCH "${LY_ROOT_FOLDER}/Platform/([^/]*)/?(.*)$" match ${full_name}) - set(full_name ${O3DE_ENGINE_RESTRICTED_PATH}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_2) - string(APPEND full_name "/" ${CMAKE_MATCH_2}) - endif() - elseif("${CMAKE_MATCH_2}" IN_LIST PAL_RESTRICTED_PLATFORMS) - set(full_name ${O3DE_ENGINE_RESTRICTED_PATH}/${CMAKE_MATCH_2}/${CMAKE_MATCH_1}) - if(CMAKE_MATCH_3) - string(APPEND full_name "/" ${CMAKE_MATCH_3}) - endif() - endif() - endif() - endif() - set(${out_name} ${full_name} PARENT_SCOPE) endif() + + # The Default object path for path is the LY_ROOT_FOLDER + cmake_path(SET object_path NORMALIZE "${LY_ROOT_FOLDER}") + if(${ARGC} GREATER 3) + # The user has supplied an object restricted path, the object path for consideration + cmake_path(SET object_path NORMALIZE ${ARGV3}) + endif() + + # The Default restricted object path is the result of the read_engine_restricted_path function + cmake_path(SET object_restricted_path NORMALIZE "${O3DE_ENGINE_RESTRICTED_PATH}") + if(${ARGC} GREATER 2) + # The user has supplied an object restricted path + cmake_path(SET object_restricted_path NORMALIZE ${ARGV2}) + endif() + + # The input path must exist in order to form a PAL path + if (NOT EXISTS ${full_name}) + # if the file is not in the object path then we cannot determine a PAL file for it + cmake_path(IS_PREFIX object_path ${full_name} is_input_path_in_root) + if(is_input_path_in_root) + cmake_path(RELATIVE_PATH full_name BASE_DIRECTORY ${object_path} OUTPUT_VARIABLE relative_object_path) + cmake_path(SET current_object_path ${relative_object_path}) + + # Remove one path segment from the end of the current_object_path and prepend it to the list path_segments + cmake_path(GET current_object_path PARENT_PATH parent_path) + cmake_path(GET current_object_path FILENAME path_segment) + list(PREPEND path_segments_visited path_segment) + cmake_path(COMPARE current_object_path NOT_EQUAL parent_path is_prev_path_segment) + cmake_path(SET current_object_path "${parent_path}") + + while(is_prev_path_segment) + # The Path is in a PAL structure + # Decompose the path into sections before "Platform" and after "Platform" + if(path_segment STREQUAL "Platform") + # The first path segment after the "/Platform/" + # is a potential platform name. Store it off for later checks + list(GET path_segments_visited 0 candidate_platform_name) + + # Store off all the path segments iterated from the end in the post-"Platform" path + cmake_path(APPEND post_platform_paths ${path_segments_visited}) + # The parent path is just the pre-"Platform" section of the path + cmake_path(SET pre_platform_paths "${parent_path}") + break() + endif() + + # Remove one path segment from the end of the current_object_path and prepend it to the list path_segments + cmake_path(GET current_object_path PARENT_PATH parent_path) + cmake_path(GET current_object_path FILENAME path_segment) + list(PREPEND path_segments_visited path_segment) + cmake_path(COMPARE current_object_path NOT_EQUAL parent_path is_prev_path_segment) + cmake_path(SET current_object_path "${parent_path}") + endwhile() + + # Compose a candidate restricted path and examine if it exists + cmake_path(APPEND object_restricted_path ${pre_platform_paths} "Platform" ${post_platform_paths} + OUTPUT_VARIABLE candidate_PAL_path) + if(NOT EXISTS ${candidate_PAL_path}) + if("${candidate_platform_name}" IN_LIST PAL_RESTRICTED_PLATFORMS) + cmake_path(APPEND object_restricted_path ${candidate_platform_name} ${object_name} + ${pre_platform_paths} ${post_platform_paths} OUTPUT_VARIABLE candidate_PAL_path) + endif() + endif() + if(EXISTS ${candidate_PAL_path}) + cmake_path(SET full_name ${candidate_PAL_path}) + endif() + endif() + endif() + set(${out_name} ${full_name} PARENT_SCOPE) endfunction() function(ly_get_list_relative_pal_filename out_name in_name) ly_get_absolute_pal_filename(abs_name ${in_name} ${ARGN}) - file(RELATIVE_PATH relative_name ${CMAKE_CURRENT_LIST_DIR} ${abs_name}) + cmake_path(RELATIVE_PATH abs_name BASE_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} OUTPUT_VARIABLE relative_name) set(${out_name} ${relative_name} PARENT_SCOPE) endfunction() From a40c979baa570a07e705e006eba4bda6638d01b1 Mon Sep 17 00:00:00 2001 From: jromnoa Date: Fri, 9 Jul 2021 10:24:07 -0700 Subject: [PATCH 22/37] move test to sandbox instead of disabling it Signed-off-by: jromnoa --- .../Gem/PythonTests/smoke/CMakeLists.txt | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt index 9951b448d8..73af69b93a 100644 --- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt @@ -52,16 +52,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) AutomatedTesting.Assets ) -# ly_add_pytest( -# NAME AutomatedTesting::GameLauncherWithGPU -# TEST_REQUIRES gpu -# PATH ${CMAKE_CURRENT_LIST_DIR}/test_GameLauncher_EnterExitGameMode_Works.py -# TIMEOUT 100 -# RUNTIME_DEPENDENCIES -# AZ::AssetProcessor -# AZ::PythonBindingsExample -# Legacy::Editor -# AutomatedTesting.GameLauncher -# AutomatedTesting.Assets -# ) + ly_add_pytest( + NAME AutomatedTesting::GameLauncherWithGPU + TEST_SUITE sandbox + TEST_REQUIRES gpu + PATH ${CMAKE_CURRENT_LIST_DIR}/test_GameLauncher_EnterExitGameMode_Works.py + TIMEOUT 100 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + AZ::PythonBindingsExample + Legacy::Editor + AutomatedTesting.GameLauncher + AutomatedTesting.Assets + ) endif() From 8a76ec713efeaa5196fec21e60c473993f132f42 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:41:43 -0500 Subject: [PATCH 23/37] Updated the SettingsRegistry Specialization tag name max size to 64 (#2016) The tag name max size should match the maximum size of a project name, since the project name is automatically added as a specialization tag in the settings registry when loading .setreg files from within the /Registry directory Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../AzCore/AzCore/Settings/SettingsRegistry.cpp | 9 +++++++++ Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp index efbc0eaa1f..5a709f9324 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp @@ -32,6 +32,15 @@ namespace AZ { if (m_hashes.size() < m_hashes.max_size()) { + constexpr size_t MaxTagSize = TagName{}.max_size(); + if (specialization.size() > MaxTagSize) + { + AZ_Error("Settings Registry", false, R"(Cannot append Specialization tag of "%.*s.")" + " It is longer than the MaxTagNameSize of %zu", AZ_STRING_ARG(specialization), + MaxTagSize); + return false; + } + m_names.push_back(TagName{ specialization }); TagName& tag = m_names.back(); AZStd::to_lower(tag.begin(), tag.end()); diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h index baeca89636..f0077db2ca 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h @@ -49,7 +49,7 @@ namespace AZ class Specializations { public: - static constexpr size_t MaxTagNameSize = 32; + static constexpr size_t MaxTagNameSize = 64; static constexpr size_t MaxCount = 15; static constexpr size_t NotFound = static_cast(-1); using TagName = AZStd::fixed_string; From 6ebf3a93d19cf78117a61edf52cb6db9f1b848b4 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:56:29 -0500 Subject: [PATCH 24/37] Added protection in the register python script queries of the default folders against a non-existent key causing a KeyError in python (#1946) Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../ProjectManager/Source/PythonBindings.cpp | 17 +++++++---- scripts/o3de/o3de/register.py | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 167cf6d10e..f8e90b0a59 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -394,13 +394,20 @@ namespace O3DE::ProjectManager if (pybind11::isinstance(o3deData)) { engineInfo.m_path = Py_To_String(enginePath); - engineInfo.m_defaultGemsFolder = Py_To_String(o3deData["default_gems_folder"]); - engineInfo.m_defaultProjectsFolder = Py_To_String(o3deData["default_projects_folder"]); - engineInfo.m_defaultRestrictedFolder = Py_To_String(o3deData["default_restricted_folder"]); - engineInfo.m_defaultTemplatesFolder = Py_To_String(o3deData["default_templates_folder"]); + auto defaultGemsFolder = m_manifest.attr("get_o3de_gems_folder")(); + engineInfo.m_defaultGemsFolder = Py_To_String_Optional(o3deData, "default_gems_folder", Py_To_String(defaultGemsFolder)); + + auto defaultProjectsFolder = m_manifest.attr("get_o3de_projects_folder")(); + engineInfo.m_defaultProjectsFolder = Py_To_String_Optional(o3deData, "default_projects_folder", Py_To_String(defaultProjectsFolder)); + + auto defaultRestrictedFolder = m_manifest.attr("get_o3de_restricted_folder")(); + engineInfo.m_defaultRestrictedFolder = Py_To_String_Optional(o3deData, "default_restricted_folder", Py_To_String(defaultRestrictedFolder)); + + auto defaultTemplatesFolder = m_manifest.attr("get_o3de_templates_folder")(); + engineInfo.m_defaultTemplatesFolder = Py_To_String_Optional(o3deData, "default_templates_folder", Py_To_String(defaultTemplatesFolder)); auto defaultThirdPartyFolder = m_manifest.attr("get_o3de_third_party_folder")(); - engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData,"default_third_party_folder", Py_To_String(defaultThirdPartyFolder)); + engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData, "default_third_party_folder", Py_To_String(defaultThirdPartyFolder)); } auto engineData = m_manifest.attr("get_engine_json_data")(pybind11::none(), enginePath); diff --git a/scripts/o3de/o3de/register.py b/scripts/o3de/o3de/register.py index ff4ccdc0a6..9d1d6e3122 100644 --- a/scripts/o3de/o3de/register.py +++ b/scripts/o3de/o3de/register.py @@ -253,7 +253,8 @@ def add_engine_name_to_path(json_data: dict, engine_path: pathlib.Path, force: b logger.error( f'Attempting to register existing engine "{engine_name}" with a new path of {engine_path.as_posix()}.' f' The current path is {pathlib.Path(engines_path_json[engine_name]).as_posix()}.' - f' To force registration of a new engine path, specify the -f/--force option.') + f' To force registration of a new engine path, specify the -f/--force option.' + f'\nAlternatively the engine can be registered with a different name by changing the "engine_name" field in the engine.json.') return 1 engines_path_json[engine_name] = engine_path.as_posix() return 0 @@ -665,7 +666,7 @@ def remove_invalid_o3de_projects(manifest_path: pathlib.Path = None) -> int: result = 0 - for project in json_data['projects']: + for project in json_data.get('projects', []): if not validation.valid_o3de_project_json(pathlib.Path(project).resolve() / 'project.json'): logger.warn(f"Project path {project} is invalid.") # Attempt to unregister all invalid projects even if previous projects failed to unregister @@ -677,36 +678,36 @@ def remove_invalid_o3de_projects(manifest_path: pathlib.Path = None) -> int: def remove_invalid_o3de_objects() -> None: json_data = manifest.load_o3de_manifest() - for engine_object in json_data['engines']: - engine_path = engine_object['path'] + for engine_object in json_data.get('engines', []): + engine_path = engine_object.get('path', '') if not validation.valid_o3de_engine_json(pathlib.Path(engine_path).resolve() / 'engine.json'): logger.warn(f"Engine path {engine_path} is invalid.") register(engine_path=engine_path, remove=True) remove_invalid_o3de_projects() - for gem in json_data['gems']: + for gem in json_data.get('gems', []): if not validation.valid_o3de_gem_json(pathlib.Path(gem).resolve() / 'gem.json'): logger.warn(f"Gem path {gem} is invalid.") register(gem_path=gem, remove=True) - for external in json_data['external_subdirectories']: + for external in json_data.get('external_subdirectories', []): external = pathlib.Path(external).resolve() if not external.is_dir(): logger.warn(f"External subdirectory {external} is invalid.") register(engine_path=engine_path, external_subdir_path=external, remove=True) - for template in json_data['templates']: + for template in json_data.get('templates', []): if not validation.valid_o3de_template_json(pathlib.Path(template).resolve() / 'template.json'): logger.warn(f"Template path {template} is invalid.") register(template_path=template, remove=True) - for restricted in json_data['restricted']: + for restricted in json_data.get('restricted', []): if not validation.valid_o3de_restricted_json(pathlib.Path(restricted).resolve() / 'restricted.json'): logger.warn(f"Restricted path {restricted} is invalid.") register(restricted_path=restricted, remove=True) - default_engines_folder = pathlib.Path(json_data['default_engines_folder']).resolve() + default_engines_folder = pathlib.Path(json_data.get('default_engines_folder', manifest.get_o3de_engines_folder())).resolve() if not default_engines_folder.is_dir(): new_default_engines_folder = manifest.get_o3de_folder() / 'Engines' new_default_engines_folder.mkdir(parents=True, exist_ok=True) @@ -714,7 +715,7 @@ def remove_invalid_o3de_objects() -> None: f"Default engines folder {default_engines_folder} is invalid. Set default {new_default_engines_folder}") register(default_engines_folder=new_default_engines_folder.as_posix()) - default_projects_folder = pathlib.Path(json_data['default_projects_folder']).resolve() + default_projects_folder = pathlib.Path(json_data.get('default_projects_folder', manifest.get_o3de_projects_folder())).resolve() if not default_projects_folder.is_dir(): new_default_projects_folder = manifest.get_o3de_folder() / 'Projects' new_default_projects_folder.mkdir(parents=True, exist_ok=True) @@ -722,7 +723,7 @@ def remove_invalid_o3de_objects() -> None: f"Default projects folder {default_projects_folder} is invalid. Set default {new_default_projects_folder}") register(default_projects_folder=new_default_projects_folder.as_posix()) - default_gems_folder = pathlib.Path(json_data['default_gems_folder']).resolve() + default_gems_folder = pathlib.Path(json_data.get('default_gems_folder', manifest.get_o3de_gems_folder())).resolve() if not default_gems_folder.is_dir(): new_default_gems_folder = manifest.get_o3de_folder() / 'Gems' new_default_gems_folder.mkdir(parents=True, exist_ok=True) @@ -730,7 +731,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {new_default_gems_folder}") register(default_gems_folder=new_default_gems_folder.as_posix()) - default_templates_folder = pathlib.Path(json_data['default_templates_folder']).resolve() + default_templates_folder = pathlib.Path(json_data.get('default_templates_folder', manifest.get_o3de_templates_folder())).resolve() if not default_templates_folder.is_dir(): new_default_templates_folder = manifest.get_o3de_folder() / 'Templates' new_default_templates_folder.mkdir(parents=True, exist_ok=True) @@ -739,7 +740,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {new_default_templates_folder}") register(default_templates_folder=new_default_templates_folder.as_posix()) - default_restricted_folder = pathlib.Path(json_data['default_restricted_folder']).resolve() + default_restricted_folder = pathlib.Path(json_data.get('default_restricted_folder', manifest.get_o3de_restricted_folder())).resolve() if not default_restricted_folder.is_dir(): default_restricted_folder = manifest.get_o3de_folder() / 'Restricted' default_restricted_folder.mkdir(parents=True, exist_ok=True) @@ -748,7 +749,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {default_restricted_folder}") register(default_restricted_folder=default_restricted_folder.as_posix()) - default_third_party_folder = pathlib.Path(json_data['default_third_party_folder']).resolve() + default_third_party_folder = pathlib.Path(json_data.get('default_third_party_folder', manifest.get_o3de_third_party_folder())).resolve() if not default_third_party_folder.is_dir(): default_third_party_folder = manifest.get_o3de_folder() / '3rdParty' default_third_party_folder.mkdir(parents=True, exist_ok=True) From 7ce6eec39e77035aac2ac7b4ada41ae478c70a82 Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Fri, 9 Jul 2021 13:36:33 -0500 Subject: [PATCH 25/37] {SPEC-7645} Disabling FileWatcherUnitTests for Linux (#2012) * Disabling FileWatcherUnitTests for Linux Signed-off-by: jackalbe <23512001+jackalbe@users.noreply.github.com> * added comments to explain the update Signed-off-by: jackalbe <23512001+jackalbe@users.noreply.github.com> --- .../native/unittests/FileWatcherUnitTests.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Code/Tools/AssetProcessor/native/unittests/FileWatcherUnitTests.cpp b/Code/Tools/AssetProcessor/native/unittests/FileWatcherUnitTests.cpp index 2ffe6a7996..dd39283b22 100644 --- a/Code/Tools/AssetProcessor/native/unittests/FileWatcherUnitTests.cpp +++ b/Code/Tools/AssetProcessor/native/unittests/FileWatcherUnitTests.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -277,7 +277,7 @@ void FileWatcherUnitTestRunner::StartTest() UNIT_TEST_EXPECT_TRUE(QDir::toNativeSeparators(fileAddName).toLower() == QDir::toNativeSeparators(newName3).toLower()); #if !defined(AZ_PLATFORM_LINUX) - // final test... make sure that renaming a DIRECTORY works too. + // final test... make sure that renaming a DIRECTORY works too. // Note that linux does not get any callbacks if just the directory is renamed (from inotify) QDir renamer; fileAddCalled = false; @@ -312,6 +312,9 @@ void FileWatcherUnitTestRunner::StartTest() Q_EMIT UnitTestPassed(); } -#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS +// File operations on Linux behave differently on Linux than Windows. +// The system under test doesn't yet handle Linux's file operations, which surfaced as this test arbitrarily passing and failing. +// This test is disabled on Linux until the system under test can handle Linux file system behavior correctly. +#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS && !defined(AZ_PLATFORM_LINUX) REGISTER_UNIT_TEST(FileWatcherUnitTestRunner) #endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS From 4475528df236fe0340431c16b2af4d8ac955e6d1 Mon Sep 17 00:00:00 2001 From: moraaar Date: Fri, 9 Jul 2021 19:48:04 +0100 Subject: [PATCH 26/37] Fixed Event Hander's copy constructor and copy assignments It was missing to save the event before connecting to it. (#2026) Signed-off-by: moraaar --- Code/Framework/AzCore/AzCore/EBus/Event.inl | 23 ++++++++--- Code/Framework/AzCore/Tests/EventTests.cpp | 42 +++++++++++++++++++++ 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/EBus/Event.inl b/Code/Framework/AzCore/AzCore/EBus/Event.inl index 006ff81e34..493dea4a3f 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Event.inl +++ b/Code/Framework/AzCore/AzCore/EBus/Event.inl @@ -27,11 +27,17 @@ namespace AZ template EventHandler::EventHandler(const EventHandler& rhs) : m_callback(rhs.m_callback) + , m_event(rhs.m_event) { - // Copy the callback function, then perform a Connect with the new event - if (rhs.m_event) + // Copy the callback and event, then perform a Connect to the event + if (m_callback && m_event) { - rhs.m_event->Connect(*this); + m_event->Connect(*this); + } + else + { + // It was not possible to connect to the event, set it to nullptr + m_event = nullptr; } } @@ -65,9 +71,16 @@ namespace AZ { Disconnect(); m_callback = rhs.m_callback; - if (rhs.m_event) + m_event = rhs.m_event; + // Copy the callback and event, then perform a Connect to the event + if (m_callback && m_event) { - rhs.m_event->Connect(*this); + m_event->Connect(*this); + } + else + { + // It was not possible to connect to the event, set it to nullptr + m_event = nullptr; } } diff --git a/Code/Framework/AzCore/Tests/EventTests.cpp b/Code/Framework/AzCore/Tests/EventTests.cpp index 7640201e0d..571bdd5345 100644 --- a/Code/Framework/AzCore/Tests/EventTests.cpp +++ b/Code/Framework/AzCore/Tests/EventTests.cpp @@ -257,6 +257,48 @@ namespace UnitTest EXPECT_FALSE(testEvent1.HasHandlerConnected()); EXPECT_TRUE(testEvent2.HasHandlerConnected()); } + + TEST_F(EventTests, TestHandlerCopyConstructorOperator) + { + int32_t invokedCounter = 0; + + AZ::Event<> testEvent; + AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; }); + + testHandler.Connect(testEvent); + + AZ::Event<>::Handler testHandler2(testHandler); + + EXPECT_TRUE(testHandler.IsConnected()); + EXPECT_TRUE(testHandler2.IsConnected()); + + EXPECT_TRUE(invokedCounter == 0); + testEvent.Signal(); + EXPECT_TRUE(invokedCounter == 2); + } + + TEST_F(EventTests, TestHandlerCopyAssignmentOperator) + { + int32_t invokedCounter = 0; + + AZ::Event<> testEvent; + AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; }); + + testHandler.Connect(testEvent); + + AZ::Event<>::Handler testHandler2; + + EXPECT_TRUE(testHandler.IsConnected()); + EXPECT_FALSE(testHandler2.IsConnected()); + + testHandler2 = testHandler; + + EXPECT_TRUE(testHandler2.IsConnected()); + + EXPECT_TRUE(invokedCounter == 0); + testEvent.Signal(); + EXPECT_TRUE(invokedCounter == 2); + } } #if defined(HAVE_BENCHMARK) From 3e7f99812adc48d920e1e240bdd24298ceb2555e Mon Sep 17 00:00:00 2001 From: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> Date: Fri, 9 Jul 2021 11:57:51 -0700 Subject: [PATCH 27/37] [installer/2106-desktop-shortcuts] update desktop shortcuts created by the installer Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> --- cmake/Platform/Windows/Packaging/Shortcuts.wxs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Windows/Packaging/Shortcuts.wxs b/cmake/Platform/Windows/Packaging/Shortcuts.wxs index 283a3c08ea..fefd15294a 100644 --- a/cmake/Platform/Windows/Packaging/Shortcuts.wxs +++ b/cmake/Platform/Windows/Packaging/Shortcuts.wxs @@ -26,10 +26,15 @@ - + + + Name="$(var.CPACK_PACKAGE_NAME) Project Manager" /> From b187407e65e0f48f65837c4e208b00ad9657b717 Mon Sep 17 00:00:00 2001 From: mrieggeramzn <61609885+mrieggeramzn@users.noreply.github.com> Date: Fri, 9 Jul 2021 13:56:13 -0700 Subject: [PATCH 28/37] fix for lightculling / pdo artifacts (#2033) Signed-off-by: mrieggeramzn --- .../Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2c2f956f8f..c979cff128 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ParallaxMapping.azsli @@ -427,7 +427,7 @@ PixelDepthOffset CalcPixelDepthOffset( float depthFactor, float4 clipOffsetPosition = mul(viewProjectionMatrix, float4(worldOffsetPosition, 1.0)); PixelDepthOffset pdo; - pdo.m_depthCS = clipOffsetPosition.z; + pdo.m_depthCS = clipOffsetPosition.w; pdo.m_depthNDC = clipOffsetPosition.z / clipOffsetPosition.w; pdo.m_worldPosition = worldOffsetPosition; return pdo; From ed33b429aa0370f45637e4e128bcb3c4737fbfc8 Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Fri, 9 Jul 2021 15:56:46 -0500 Subject: [PATCH 29/37] =?UTF-8?q?Updating=20some=20labels=20in=20the=20dir?= =?UTF-8?q?ectional=20light=20and=20light=20components=E2=80=A6=20(#1996)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updating some labels in the directional light and light components to make them more readable and consistent with standards. Removed hard caps on directional light intensity. Signed-off-by: Ken Pruiksma --- .../DirectionalLightComponentConfig.cpp | 13 +-- .../CoreLights/EditorAreaLightComponent.cpp | 10 +-- .../EditorDirectionalLightComponent.cpp | 90 +++++++++---------- 3 files changed, 54 insertions(+), 59 deletions(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentConfig.cpp index 3923136bcc..5325ba911d 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentConfig.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DirectionalLightComponentConfig.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace AZ { @@ -55,21 +56,15 @@ namespace AZ case PhotometricUnit::Lux: return 0.0f; case PhotometricUnit::Ev100Illuminance: - return -10.0f; + return AZStd::numeric_limits::lowest(); } return 0.0f; } float DirectionalLightComponentConfig::GetIntensityMax() const { - switch (m_intensityMode) - { - case PhotometricUnit::Lux: - return 1'000'000.0f; - case PhotometricUnit::Ev100Illuminance: - return 20.0f; - } - return 0.0f; + // While there is no hard-max, a max must be included when there is a hard min. + return AZStd::numeric_limits::max(); } float DirectionalLightComponentConfig::GetIntensitySoftMin() const diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp index 81e87f3cb5..c27faa2241 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp @@ -154,19 +154,19 @@ namespace AZ ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsPcfBoundarySearchDisabled) ->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_predictionSampleCount, "Prediction sample count", - "Sample Count for prediction of whether the pixel is on the boundary. Specific to PCF and ESM+PCF.") + "Sample count for prediction of whether the pixel is on the boundary. Specific to PCF and ESM+PCF.") ->Attribute(Edit::Attributes::Min, 4) ->Attribute(Edit::Attributes::Max, 16) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsPcfBoundarySearchDisabled) ->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_filteringSampleCount, "Filtering sample count", - "It is used only when the pixel is predicted to be on the boundary. Specific to PCF and ESM+PCF.") + "This is only used when the pixel is predicted to be on the boundary. Specific to PCF and ESM+PCF.") ->Attribute(Edit::Attributes::Min, 4) ->Attribute(Edit::Attributes::Max, 64) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled) ->DataElement( - Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_pcfMethod, "Pcf method", + Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_pcfMethod, "PCF method", "Type of PCF to use.\n" " Bicubic: a smooth, fixed-size kernel \n" " Boundary search: do several taps to first determine if we are on a shadow boundary\n") @@ -176,8 +176,8 @@ namespace AZ ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled) ->DataElement( - Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_esmExponent, "Esm Exponent", - "Exponent used by Esm shadows. " + Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_esmExponent, "ESM exponent", + "Exponent used by ESM shadows. " "Larger values increase the sharpness of the border between lit and unlit areas.") ->Attribute(Edit::Attributes::Min, 50.0f) ->Attribute(Edit::Attributes::Max, 5000.0f) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp index 8163dcfe20..4d43c23e25 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorDirectionalLightComponent.cpp @@ -57,74 +57,74 @@ namespace AZ editContext->Class("DirectionalLightComponentConfig", "") ->ClassElement(Edit::ClassElements::EditorData, "") ->DataElement(Edit::UIHandlers::Color, &DirectionalLightComponentConfig::m_color, "Color", "Color of the light") - ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig()) - ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_intensityMode, "Intensity Mode", "Allows specifying light values in lux or Ev100") - ->EnumAttribute(PhotometricUnit::Lux, "Lux") - ->EnumAttribute(PhotometricUnit::Ev100Illuminance, "Ev100") - ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues) + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) + ->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig()) + ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying light values in lux or Ev100") + ->EnumAttribute(PhotometricUnit::Lux, "Lux") + ->EnumAttribute(PhotometricUnit::Ev100Illuminance, "Ev100") + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues) ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_intensity, "Intensity", "Intensity of the light in the set photometric unit.") - ->Attribute(Edit::Attributes::Min, &DirectionalLightComponentConfig::GetIntensityMin) - ->Attribute(Edit::Attributes::Max, &DirectionalLightComponentConfig::GetIntensityMax) - ->Attribute(Edit::Attributes::SoftMin, &DirectionalLightComponentConfig::GetIntensitySoftMin) - ->Attribute(Edit::Attributes::SoftMax, &DirectionalLightComponentConfig::GetIntensitySoftMax) - ->Attribute(Edit::Attributes::Suffix, &DirectionalLightComponentConfig::GetIntensitySuffix) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_angularDiameter, "Angular Diameter", "Angular Diameter of the directional light in degrees. The sun is about 0.5.") - ->Attribute(Edit::Attributes::Min, 0.0f) - ->Attribute(Edit::Attributes::Max, 5.0f) - ->Attribute(Edit::Attributes::SoftMax, 1.0f) - ->Attribute(Edit::Attributes::Suffix, " deg") + ->Attribute(Edit::Attributes::Min, &DirectionalLightComponentConfig::GetIntensityMin) + ->Attribute(Edit::Attributes::Max, &DirectionalLightComponentConfig::GetIntensityMax) + ->Attribute(Edit::Attributes::SoftMin, &DirectionalLightComponentConfig::GetIntensitySoftMin) + ->Attribute(Edit::Attributes::SoftMax, &DirectionalLightComponentConfig::GetIntensitySoftMax) + ->Attribute(Edit::Attributes::Suffix, &DirectionalLightComponentConfig::GetIntensitySuffix) + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_angularDiameter, "Angular diameter", "Angular diameter of the directional light in degrees. The sun is about 0.5.") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 5.0f) + ->Attribute(Edit::Attributes::SoftMax, 1.0f) + ->Attribute(Edit::Attributes::Suffix, " deg") ->ClassElement(AZ::Edit::ClassElements::Group, "Shadow") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(Edit::UIHandlers::EntityId, &DirectionalLightComponentConfig::m_cameraEntityId, "Camera", "Entity of the camera for cascaded shadowmap view frustum.") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_shadowFarClipDistance, "Shadow Far Clip", "Shadow sepcific far clip distance.") + ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_shadowFarClipDistance, "Shadow far clip", "Shadow specific far clip distance.") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_shadowmapSize, "Shadowmap Size", "Width/Height of shadowmap") + ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_shadowmapSize, "Shadowmap size", "Width/Height of shadowmap") ->EnumAttribute(ShadowmapSize::Size256, " 256") ->EnumAttribute(ShadowmapSize::Size512, " 512") ->EnumAttribute(ShadowmapSize::Size1024, "1024") ->EnumAttribute(ShadowmapSize::Size2048, "2048") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_cascadeCount, "Cascade Count", "Number of cascades") + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_cascadeCount, "Cascade count", "Number of cascades") ->Attribute(Edit::Attributes::Min, 1) ->Attribute(Edit::Attributes::Max, Shadow::MaxNumberOfCascades) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_isShadowmapFrustumSplitAutomatic, "Split Automatic", + ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_isShadowmapFrustumSplitAutomatic, "Automatic splitting", "Switch splitting of shadowmap frustum to cascades automatically or not.") - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_shadowmapFrustumSplitSchemeRatio, "Split Ratio", + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_shadowmapFrustumSplitSchemeRatio, "Split ratio", "Ratio to lerp between the two types of frustum splitting scheme.\n" - "0 = Uniform scheme which will split the Frustum evenly across all cascades.\n" + "0 = Uniform scheme which will split the frustum evenly across all cascades.\n" "1 = Logarithmic scheme which is designed to split the frustum in a logarithmic fashion " "in order to enable us to produce a more optimal perspective aliasing across the frustum.") ->Attribute(Edit::Attributes::Min, 0.f) ->Attribute(Edit::Attributes::Max, 1.f) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsSplitManual) - ->DataElement(Edit::UIHandlers::Vector4, &DirectionalLightComponentConfig::m_cascadeFarDepths, "Far Depth Cascade", - "Far Depth of each cascade. The value of the index greater than or equal to cascade count is ignored.") + ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsSplitManual) + ->DataElement(Edit::UIHandlers::Vector4, &DirectionalLightComponentConfig::m_cascadeFarDepths, "Far depth cascade", + "Far depth of each cascade. The value of the index greater than or equal to cascade count is ignored.") ->Attribute(Edit::Attributes::Min, 0.01f) ->Attribute(Edit::Attributes::Max, &DirectionalLightComponentConfig::m_shadowFarClipDistance) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsSplitAutomatic) - ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_groundHeight, "Ground Height", + ->DataElement(Edit::UIHandlers::Default, &DirectionalLightComponentConfig::m_groundHeight, "Ground height", "Height of the ground. Used to correct position of cascades.") ->Attribute(Edit::Attributes::Suffix, " m") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsCascadeCorrectionDisabled) + ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsCascadeCorrectionDisabled) ->DataElement(Edit::UIHandlers::CheckBox, - &DirectionalLightComponentConfig::m_isCascadeCorrectionEnabled, "Enable Cascade Correction?", + &DirectionalLightComponentConfig::m_isCascadeCorrectionEnabled, "Cascade correction", "Enable position correction of cascades to optimize the appearance for certain camera positions.") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->DataElement(Edit::UIHandlers::CheckBox, - &DirectionalLightComponentConfig::m_isDebugColoringEnabled, "Enable Debug Coloring?", + &DirectionalLightComponentConfig::m_isDebugColoringEnabled, "Debug coloring", "Enable coloring to see how cascades places 0:red, 1:green, 2:blue, 3:yellow.") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_shadowFilterMethod, "Shadow Filter Method", + ->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_shadowFilterMethod, "Shadow filter method", "Filtering method of edge-softening of shadows.\n" - " None: no filtering\n" - " PCF: Percentage-Closer Filtering\n" - " ESM: Exponential Shadow Maps\n" + " None: No filtering\n" + " PCF: Percentage-closer filtering\n" + " ESM: Exponential shadow maps\n" " ESM+PCF: ESM with a PCF fallback\n" "For BehaviorContext (or TrackView), None=0, PCF=1, ESM=2, ESM+PCF=3") ->EnumAttribute(ShadowFilterMethod::None, "None") @@ -132,7 +132,7 @@ namespace AZ ->EnumAttribute(ShadowFilterMethod::Esm, "ESM") ->EnumAttribute(ShadowFilterMethod::EsmPcf, "ESM+PCF") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_boundaryWidth, "Softening Boundary Width", + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_boundaryWidth, "Softening boundary width", "Width of the boundary between shadowed area and lit one. " "Units are in meters. " "If this is 0, softening edge is disabled.") @@ -141,29 +141,29 @@ namespace AZ ->Attribute(Edit::Attributes::Suffix, " m") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsPcfBoundarySearchDisabled) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_predictionSampleCount, "Prediction Sample Count", - "Sample Count for prediction of whether the pixel is on the boundary. " + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_predictionSampleCount, "Prediction sample count", + "Sample count for prediction of whether the pixel is on the boundary. " "Specific to PCF and ESM+PCF.") ->Attribute(Edit::Attributes::Min, 4) ->Attribute(Edit::Attributes::Max, 16) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsPcfBoundarySearchDisabled) - ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering Sample Count", - "It is used only when the pixel is predicted as on the boundary. " + ->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering sample count", + "This is used only when the pixel is predicted as on the boundary. " "Specific to PCF and ESM+PCF.") ->Attribute(Edit::Attributes::Min, 4) ->Attribute(Edit::Attributes::Max, 64) ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled) ->DataElement( - Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_pcfMethod, "Pcf Method", - "Type of Pcf to use.\n" + Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_pcfMethod, "Pcf method", + "Type of PCF to use.\n" " Bicubic: a smooth, fixed-size kernel \n" " Boundary search: do several taps to first determine if we are on a shadow boundary\n") - ->EnumAttribute(PcfMethod::Bicubic, "Bicubic") - ->EnumAttribute(PcfMethod::BoundarySearch, "Boundary Search") - ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) - ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled); + ->EnumAttribute(PcfMethod::Bicubic, "Bicubic") + ->EnumAttribute(PcfMethod::BoundarySearch, "Boundary search") + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) + ->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled); ; } From 4f628cfb77f5d36dd2dc5b918773672f6f81ca5b Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 9 Jul 2021 14:25:23 -0700 Subject: [PATCH 30/37] Fix for alias not understood in generation expressions that query properties (#2034) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- cmake/LYWrappers.cmake | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/LYWrappers.cmake b/cmake/LYWrappers.cmake index b6daf8b6d7..40bf6ef541 100644 --- a/cmake/LYWrappers.cmake +++ b/cmake/LYWrappers.cmake @@ -380,12 +380,14 @@ function(ly_delayed_target_link_libraries) cmake_parse_arguments(ly_delayed_target_link_libraries "" "" "${visibilities}" ${delayed_link}) foreach(visibility ${visibilities}) - foreach(item ${ly_delayed_target_link_libraries_${visibility}}) + foreach(alias_item ${ly_delayed_target_link_libraries_${visibility}}) - if(TARGET ${item}) - get_target_property(item_type ${item} TYPE) + if(TARGET ${alias_item}) + get_target_property(item_type ${alias_item} TYPE) + ly_de_alias_target(${alias_item} item) else() unset(item_type) + set(item ${alias_item}) endif() if(item_type STREQUAL MODULE_LIBRARY) From 9b72b71aa08c87d0fc6ff5b3d7c272a8c4da8a2f Mon Sep 17 00:00:00 2001 From: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> Date: Fri, 9 Jul 2021 14:58:32 -0700 Subject: [PATCH 31/37] [installer/2106-latest-upload] also upload a copy of the boostrapper to the 'latest' folder for tagged builds Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> --- .../Platform/Windows/PackagingPostBuild.cmake | 109 +++++++++++++----- 1 file changed, 82 insertions(+), 27 deletions(-) diff --git a/cmake/Platform/Windows/PackagingPostBuild.cmake b/cmake/Platform/Windows/PackagingPostBuild.cmake index 2d003d6062..70f8834207 100644 --- a/cmake/Platform/Windows/PackagingPostBuild.cmake +++ b/cmake/Platform/Windows/PackagingPostBuild.cmake @@ -105,39 +105,94 @@ file(TO_NATIVE_PATH "${_root_path}/python/python.cmd" _python_cmd) file(TO_NATIVE_PATH "${_root_path}/scripts/build/tools/upload_to_s3.py" _upload_script) file(TO_NATIVE_PATH "${_cpack_wix_out_dir}" _cpack_wix_out_dir) -# strip the scheme and extract the bucket/key prefix from the URL -string(REPLACE "s3://" "" _stripped_url ${CPACK_UPLOAD_URL}) -string(REPLACE "/" ";" _tokens ${_stripped_url}) +function(upload_to_s3 in_url in_local_path in_file_regex) -list(POP_FRONT _tokens _bucket) -string(JOIN "/" _prefix ${_tokens}) + # strip the scheme and extract the bucket/key prefix from the URL + string(REPLACE "s3://" "" _stripped_url ${in_url}) + string(REPLACE "/" ";" _tokens ${_stripped_url}) -set(_file_regex ".*(cab|exe|msi)$") -set(_extra_args [[{"ACL":"bucket-owner-full-control"}]]) + list(POP_FRONT _tokens _bucket) + string(JOIN "/" _prefix ${_tokens}) -set(_upload_command - ${_python_cmd} -s - -u ${_upload_script} - --base_dir ${_cpack_wix_out_dir} - --file_regex="${_file_regex}" - --bucket ${_bucket} - --key_prefix ${_prefix} - --extra_args ${_extra_args} -) + set(_extra_args [[{"ACL":"bucket-owner-full-control"}]]) -if(CPACK_AWS_PROFILE) - list(APPEND _upload_command --profile ${CPACK_AWS_PROFILE}) -endif() + set(_upload_command + ${_python_cmd} -s + -u ${_upload_script} + --base_dir ${in_local_path} + --file_regex="${in_file_regex}" + --bucket ${_bucket} + --key_prefix ${_prefix} + --extra_args ${_extra_args} + ) + + if(CPACK_AWS_PROFILE) + list(APPEND _upload_command --profile ${CPACK_AWS_PROFILE}) + endif() + + execute_process( + COMMAND ${_upload_command} + RESULT_VARIABLE _upload_result + OUTPUT_VARIABLE _upload_output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (NOT ${_upload_result} EQUAL 0) + message(FATAL_ERROR "An error occurred uploading to s3.\nOutput:\n${_upload_output}") + endif() +endfunction() message(STATUS "Uploading artifacts to ${CPACK_UPLOAD_URL}") -execute_process( - COMMAND ${_upload_command} - RESULT_VARIABLE _upload_result - ERROR_VARIABLE _upload_errors +upload_to_s3( + ${CPACK_UPLOAD_URL} + ${_cpack_wix_out_dir} + ".*(cab|exe|msi)$" ) +message(STATUS "Artifact uploading complete!") -if (${_upload_result} EQUAL 0) - message(STATUS "Artifact uploading complete!") -else() - message(FATAL_ERROR "An error occurred uploading artifacts. ${_upload_errors}") +# for auto tagged builds, we will also upload a second copy of just the boostrapper +# to a special "Latest" folder under the branch in place of the commit date/hash +if(CPACK_AUTO_GEN_TAG) + message(STATUS "Updating latest tagged build") + + # make sure we can extra the commit info from the URL first + string(REGEX MATCH "([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9a-zA-Z]+)" + _commit_info ${CPACK_UPLOAD_URL} + ) + if(NOT _commit_info) + message(FATAL_ERROR "Failed to extract the build tag") + endif() + + set(_temp_dir ${_cpack_wix_out_dir}/temp) + if(NOT EXISTS ${_temp_dir}) + file(MAKE_DIRECTORY ${_temp_dir}) + endif() + + # strip the version number form the exe name in the one uploaded to latest + string(TOLOWER "${CPACK_PACKAGE_NAME}_installer.exe" _non_versioned_exe) + set(_temp_exe_copy ${_temp_dir}/${_non_versioned_exe}) + + file(COPY ${_bootstrap_output_file} DESTINATION ${_temp_dir}) + file(RENAME "${_temp_dir}/${_bootstrap_filename}" ${_temp_exe_copy}) + + # include the commit info in a text file that will live next to the exe + set(_temp_info_file ${_temp_dir}/build_tag.txt) + file(WRITE ${_temp_info_file} ${_commit_info}) + + # update the URL and upload + string(REPLACE + ${_commit_info} "Latest" + _latest_upload_url ${CPACK_UPLOAD_URL} + ) + + upload_to_s3( + ${_latest_upload_url} + ${_temp_dir} + "(${_non_versioned_exe}|build_tag.txt)$" + ) + + # cleanup the temp files + file(REMOVE_RECURSE ${_temp_dir}) + + message(STATUS "Latest build update complete!") endif() From 0d82c1e670b15faaaa2c738eb628db7dc159225b Mon Sep 17 00:00:00 2001 From: Tommy Walton <82672795+amzn-tommy@users.noreply.github.com> Date: Fri, 9 Jul 2021 15:54:46 -0700 Subject: [PATCH 32/37] Use float buffer for skinning (#2009) * Switching to Buffer instead of Buffer in the skinning shader because metal doesn't support float3 buffers Signed-off-by: amzn-tommy * Adding a comment to LinearSkinningPassSRG pointing out that positions, normals, and bitangents are using float buffers to work on Metal Signed-off-by: amzn-tommy --- .../Shaders/SkinnedMesh/LinearSkinningCS.azsl | 17 +++++++++--- .../SkinnedMesh/LinearSkinningPassSRG.azsli | 8 +++--- .../SkinnedMesh/SkinnedMeshInputBuffers.cpp | 26 +++++++++++++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningCS.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningCS.azsl index fc5684fe7f..99d38463c7 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningCS.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningCS.azsl @@ -14,6 +14,15 @@ option enum class SkinningMethod { LinearSkinning, DualQuaternion } o_skinningMe option bool o_applyMorphTargets = false; option bool o_applyColorMorphTargets = false; +float3 ReadFloat3FromFloatBuffer(Buffer buffer, uint index) +{ + float3 result; + result.x = buffer[index * 3]; + result.y = buffer[index * 3 + 1]; + result.z = buffer[index * 3 + 2]; + return result; +} + // Apply a morph target delta with three components void ApplyMorphTargetDelta(uint streamOffset, uint vertexIndex, inout float3 modifiedValue) { @@ -162,10 +171,10 @@ void MainCS(uint3 thread_id: SV_DispatchThreadID) return; } - float3 position = InstanceSrg::m_sourcePositions[i]; - float3 normal = InstanceSrg::m_sourceNormals[i]; - float4 tangent = InstanceSrg::m_sourceTangents[i]; - float3 bitangent = InstanceSrg::m_sourceBiTangents[i]; + float3 position = ReadFloat3FromFloatBuffer(InstanceSrg::m_sourcePositions, i); + float3 normal = ReadFloat3FromFloatBuffer(InstanceSrg::m_sourceNormals, i); + float4 tangent = InstanceSrg::m_sourceTangents[i]; + float3 bitangent = ReadFloat3FromFloatBuffer(InstanceSrg::m_sourceBiTangents, i); // Four indices, 16-bits each, stored in 2 32-bit uints uint2 rawIndices = InstanceSrg::m_sourceBlendIndices.Load2(i * 8); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli b/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli index 95802ddbb7..066cefdc37 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli +++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli @@ -20,10 +20,12 @@ ShaderResourceGroup InstanceSrg : SRG_PerDraw uint m_totalNumberOfThreadsX; // Per-model input - Buffer m_sourcePositions; // POSITION 0 - Buffer m_sourceNormals; // NORMAL 0 + // Positions, normals, and bitangents are all 3-component per-vertex buffers, + // but Metal doesn't support float3 buffers so Buffer is used instead + Buffer m_sourcePositions; // POSITION 0 + Buffer m_sourceNormals; // NORMAL 0 Buffer m_sourceTangents; // TANGENT 0 - Buffer m_sourceBiTangents; // BITANGENT 0 + Buffer m_sourceBiTangents; // BITANGENT 0 ByteAddressBuffer m_sourceBlendIndices; // BLENDINDICES 0 Buffer m_sourceBlendWeights; // BLENDWEIGHTS 0 diff --git a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp index 75d079c937..8ef82dfac4 100644 --- a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp @@ -118,7 +118,29 @@ namespace AZ } m_inputBufferAssets[static_cast(inputStream)] = bufferAsset; - m_inputBuffers[static_cast(inputStream)] = RPI::Buffer::FindOrCreate(bufferAsset); + Data::Instance buffer = RPI::Buffer::FindOrCreate(bufferAsset); + m_inputBuffers[static_cast(inputStream)] = buffer; + + // Create a buffer view to use as input to the skinning shader + AZ::RHI::Ptr bufferView = RHI::Factory::Get().CreateBufferView(); + bufferView->SetName(Name{ AZStd::string(buffer->GetBufferView()->GetName().GetStringView()) + "_SkinningInputBufferView" }); + RHI::BufferViewDescriptor bufferViewDescriptor = bufferAsset->GetBufferViewDescriptor(); + + // 3-component float buffers are not supported on metal for non-input assembly buffer views, so use a float view instead + if (bufferViewDescriptor.m_elementFormat == RHI::Format::R32G32B32_FLOAT) + { + // Use one float per element, with 3x as many elements + bufferViewDescriptor = RHI::BufferViewDescriptor::CreateTyped( + bufferViewDescriptor.m_elementOffset * 3, bufferViewDescriptor.m_elementCount * 3, RHI::Format::R32_FLOAT); + } + + [[maybe_unused]] RHI::ResultCode resultCode = + bufferView->Init(*buffer->GetRHIBuffer(), bufferViewDescriptor); + AZ_Error( + "SkinnedMeshInputBuffers", resultCode == RHI::ResultCode::Success, + "Failed to initialize buffer view for skinned mesh input."); + + m_bufferViews[static_cast(inputStream)] = bufferView; } void SkinnedMeshInputLod::SetStaticBufferAsset(const Data::Asset bufferAsset, SkinnedMeshStaticVertexStreams staticStream) @@ -315,7 +337,7 @@ namespace AZ [[maybe_unused]] bool success = false; if (m_lods[lodIndex].m_inputBuffers[inputStream]) { - success = perInstanceSRG->SetBufferView(srgIndex, m_lods[lodIndex].m_inputBuffers[inputStream]->GetBufferView()); + success = perInstanceSRG->SetBufferView(srgIndex, m_lods[lodIndex].m_bufferViews[inputStream].get()); } AZ_Error("SkinnedMeshInputBuffers", success, "Failed to bind buffer view for %s", streamInfo.m_bufferName.GetCStr()); From 8eb8088a3606ba190e6778eb53707e5d19049155 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Fri, 9 Jul 2021 16:25:13 -0700 Subject: [PATCH 33/37] Remove Cry -> Atom camera sync. (#2047) Signed-off-by: nvsickle --- Code/Editor/EditorViewportWidget.cpp | 44 ++++++++++------------------ Code/Editor/EditorViewportWidget.h | 1 - 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index fca698e88a..0f911878c3 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -463,25 +463,7 @@ void EditorViewportWidget::Update() SetFOV(cameraState.m_fovOrZoom); m_Camera.SetZRange(cameraState.m_nearClip, cameraState.m_farClip); } - else if (!ed_useNewCameraSystem) - { - m_renderViewport->GetViewportContext()->SetCameraTransform(LYTransformToAZTransform(m_Camera.GetMatrix())); - } - // Don't override the game mode FOV - if (!GetIEditor()->IsInGameMode()) - { - AZ::Matrix4x4 clipMatrix; - AZ::MakePerspectiveFovMatrixRH( - clipMatrix, - GetFOV(), - aznumeric_cast(width()) / aznumeric_cast(height()), - m_Camera.GetNearPlane(), - m_Camera.GetFarPlane(), - true - ); - m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix); - } // Reset the camera update flag now that we're finished updating our viewport context m_updateCameraPositionNextTick = false; @@ -637,7 +619,6 @@ void EditorViewportWidget::SetViewEntity(const AZ::EntityId& viewEntityId, bool void EditorViewportWidget::ResetToViewSourceType(const ViewSourceType& viewSourceType) { LockCameraMovement(true); - m_pCameraFOVVariable = nullptr; m_viewEntityId.SetInvalid(); m_cameraObjectId = GUID_NULL; m_viewSourceType = viewSourceType; @@ -2416,13 +2397,26 @@ void EditorViewportWidget::CenterOnSliceInstance() ////////////////////////////////////////////////////////////////////////// void EditorViewportWidget::SetFOV(float fov) { - if (m_pCameraFOVVariable) + if (m_viewEntityId.IsValid()) { - m_pCameraFOVVariable->Set(fov); + Camera::CameraRequestBus::Event(m_viewEntityId, &Camera::CameraComponentRequests::SetFov, AZ::RadToDeg(fov)); } else { m_camFOV = fov; + // Set the active camera's FOV + { + AZ::Matrix4x4 clipMatrix; + AZ::MakePerspectiveFovMatrixRH( + clipMatrix, + GetFOV(), + aznumeric_cast(width()) / aznumeric_cast(height()), + m_Camera.GetNearPlane(), + m_Camera.GetFarPlane(), + true + ); + m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix); + } } if (m_viewPane) @@ -2449,13 +2443,7 @@ float EditorViewportWidget::GetFOV() const } } - if (m_pCameraFOVVariable) - { - float fov; - m_pCameraFOVVariable->Get(fov); - return fov; - } - else if (m_viewEntityId.IsValid()) + if (m_viewEntityId.IsValid()) { float fov = AZ::RadToDeg(m_camFOV); Camera::CameraRequestBus::EventResult(fov, m_viewEntityId, &Camera::CameraComponentRequests::GetFov); diff --git a/Code/Editor/EditorViewportWidget.h b/Code/Editor/EditorViewportWidget.h index 682d37199c..e99c963b5a 100644 --- a/Code/Editor/EditorViewportWidget.h +++ b/Code/Editor/EditorViewportWidget.h @@ -505,7 +505,6 @@ protected: CPredefinedAspectRatios m_predefinedAspectRatios; - IVariable* m_pCameraFOVVariable = nullptr; bool m_bCursorHidden = false; void OnMenuResolutionCustom(); From 372ac2707fea95b31d34953a9be6e34cde28e089 Mon Sep 17 00:00:00 2001 From: Alex Montgomery Date: Fri, 9 Jul 2021 19:37:57 -0700 Subject: [PATCH 34/37] fix outliner sorting using incorrect types for comparisons (#2052) * fix outliner sorting using incorrect types for comparisons, fixes for [LY-122258] and [LYN-3666] Signed-off-by: Alex Montgomery * fix annoying but necessary Qt type cast Signed-off-by: Alex Montgomery --- .../Outliner/OutlinerSortFilterProxyModel.cpp | 19 ++++++++++++++++++- .../EntityOutlinerSortFilterProxyModel.cpp | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp index 660ea137cf..89cd361fb6 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp @@ -32,7 +32,24 @@ bool OutlinerSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelI bool OutlinerSortFilterProxyModel::lessThan(const QModelIndex& leftIndex, const QModelIndex& rightIndex) const { - return sourceModel()->data(leftIndex).toString() < sourceModel()->data(rightIndex).toString(); + if (leftIndex.isValid() && rightIndex.isValid()) + { + QVariant leftData = sourceModel()->data(leftIndex); + QVariant rightData = sourceModel()->data(rightIndex); + + // make sure to compare the correct data types for sorting the current column + AZ_Assert(leftData.type() == rightData.type(), "OutlinerSortFilterProxyModel::lessThan types do not agree!"); + if (static_cast(leftData.type()) == QMetaType::QString) + { + return leftData.toString() < rightData.toString(); + } + else if (static_cast(leftData.type()) == QMetaType::ULongLong) + { + return leftData.toULongLong() < rightData.toULongLong(); + } + AZ_Error("Editor", false, "Error! Unhandled type \"%s\" in OutlinerSortFilterProxyModel::lessThan", leftData.typeName()); + } + return false; } void OutlinerSortFilterProxyModel::sort(int /*column*/, Qt::SortOrder /*order*/) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.cpp index 73139b5a67..90274bc734 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.cpp @@ -34,7 +34,24 @@ namespace AzToolsFramework bool EntityOutlinerSortFilterProxyModel::lessThan(const QModelIndex& leftIndex, const QModelIndex& rightIndex) const { - return sourceModel()->data(leftIndex).toString() < sourceModel()->data(rightIndex).toString(); + if (leftIndex.isValid() && rightIndex.isValid()) + { + QVariant leftData = sourceModel()->data(leftIndex); + QVariant rightData = sourceModel()->data(rightIndex); + + // make sure to compare the correct data types for sorting the current column + AZ_Assert(leftData.type() == rightData.type(), "EntityOutlinerSortFilterProxyModel::lessThan types do not agree!"); + if (static_cast(leftData.type()) == QMetaType::QString) + { + return leftData.toString() < rightData.toString(); + } + else if (static_cast(leftData.type()) == QMetaType::ULongLong) + { + return leftData.toULongLong() < rightData.toULongLong(); + } + AZ_Error("Editor", false, "Error! Unhandled type \"%s\" in EntityOutlinerSortFilterProxyModel::lessThan", leftData.typeName()); + } + return false; } void EntityOutlinerSortFilterProxyModel::sort(int /*column*/, Qt::SortOrder /*order*/) From 2727f36621ed501fb725dd998e01c334b1844738 Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Sun, 11 Jul 2021 17:31:51 -0700 Subject: [PATCH 35/37] Set DiffuseProbeGrids to visible when baking textures. Added an initialization delay before starting the DiffuseProbeGrid texture readbacks, to allow the textures to settle. Signed-off-by: dmcdiar --- .../DiffuseProbeGrid.cpp | 6 ++++++ .../DiffuseProbeGridTextureReadback.cpp | 17 ++++++++++++++++- .../DiffuseProbeGridTextureReadback.h | 7 +++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp index 888d7c57d8..baf71ca7f1 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGrid.cpp @@ -259,6 +259,12 @@ namespace AZ return true; } + // if a bake is in progress we need to make this DiffuseProbeGrid visible + if (!m_textureReadback.IsIdle()) + { + return true; + } + return m_cullable.m_isVisible; } diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.cpp index 3e808a99c1..8931a4feb1 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.cpp @@ -22,7 +22,9 @@ namespace AZ AZ_Assert(m_readbackState == DiffuseProbeGridReadbackState::Idle, "DiffuseProbeGridTextureReadback is already processing a readback request"); m_callback = callback; - m_readbackState = DiffuseProbeGridReadbackState::Irradiance; + + m_remainingInitializationFrames = DefaultNumInitializationFrames; + m_readbackState = DiffuseProbeGridReadbackState::Initializing; } void DiffuseProbeGridTextureReadback::Update(const AZ::Name& passName) @@ -32,6 +34,19 @@ namespace AZ return; } + if (m_readbackState == DiffuseProbeGridReadbackState::Initializing) + { + if (m_remainingInitializationFrames > 0) + { + // still in the initialization state to allow the irradiance textures to settle, decrement the frame count + m_remainingInitializationFrames--; + return; + } + + // settling complete, move to the irradiance readback state to begin the readback process + m_readbackState = DiffuseProbeGridReadbackState::Irradiance; + } + if (m_attachmentReadback.get() && m_attachmentReadback->GetReadbackState() > RPI::AttachmentReadback::ReadbackState::Idle) { // still processing previous request diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.h b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.h index c399fac534..b0d35069a7 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.h +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseGlobalIllumination/DiffuseProbeGridTextureReadback.h @@ -20,6 +20,7 @@ namespace AZ enum class DiffuseProbeGridReadbackState { Idle, + Initializing, Irradiance, Distance, Relocation, @@ -39,6 +40,8 @@ namespace AZ void Update(const AZ::Name& passName); void FrameBegin(AZ::RPI::Pass::FramePrepareParams& params); + bool IsIdle() const { return m_readbackState == DiffuseProbeGridReadbackState::Idle; } + private: DiffuseProbeGrid* m_diffuseProbeGrid = nullptr; @@ -50,6 +53,10 @@ namespace AZ AZ::RPI::AttachmentReadback::ReadbackResult m_distanceReadbackResult; AZ::RPI::AttachmentReadback::ReadbackResult m_relocationReadbackResult; AZ::RPI::AttachmentReadback::ReadbackResult m_classificationReadbackResult; + + // number of frames to delay before starting the texture readbacks, this allows the textures to settle + static constexpr int32_t DefaultNumInitializationFrames = 50; + int32_t m_remainingInitializationFrames = DefaultNumInitializationFrames; }; } // namespace Render } // namespace AZ From c9ff634080f5364d64fda7c1e8ff799cdd37b6ea Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Sun, 11 Jul 2021 23:30:07 -0700 Subject: [PATCH 36/37] Aftermath for PR-1956 and PR-2025 (#2035) Signed-off-by: Benjamin Jillich --- .../Source/GemCatalog/GemFilterTagWidget.cpp | 6 ++---- Code/Tools/ProjectManager/Source/ProjectUtils.cpp | 11 ++++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp index c4612debc8..c7925a2d6e 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterTagWidget.cpp @@ -10,7 +10,6 @@ #include #include #include -#include namespace O3DE::ProjectManager { @@ -72,10 +71,9 @@ namespace O3DE::ProjectManager hLayout->setMargin(0); hLayout->setSpacing(8); - const int numTags = tags.count(); - for (int i = 0; i < numTags; ++i) + for(const QString& tag : tags) { - FilterTagWidget* tagWidget = new FilterTagWidget(tags[i]); + FilterTagWidget* tagWidget = new FilterTagWidget(tag); // Add the tag widget to the current row. hLayout->addWidget(tagWidget); diff --git a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp index 82944aa41a..83e7546670 100644 --- a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp @@ -250,7 +250,7 @@ namespace O3DE::ProjectManager progressDialog->setValue(0); progressDialog->setRange(0, 1000); progressDialog->setModal(true); - progressDialog->setWindowTitle("Copying project ..."); + progressDialog->setWindowTitle(QObject::tr("Copying project ...")); progressDialog->show(); QLocale locale; @@ -259,7 +259,12 @@ namespace O3DE::ProjectManager // Create a human-readable version of the file size. const QString fileSizeString = locale.formattedDataSize(sizeInBytes); - progressDialog->setLabelText(QString("Indexing files ... %1 files found, %2 to copy.").arg(fileCount).arg(fileSizeString)); + progressDialog->setLabelText(QString("%1 ... %2 %3, %4 %5.") + .arg(QObject::tr("Indexing files")) + .arg(QString::number(fileCount)) + .arg(QObject::tr("files found")) + .arg(fileSizeString) + .arg(QObject::tr("to copy"))); qApp->processEvents(QEventLoop::ExcludeUserInputEvents); }); @@ -277,7 +282,7 @@ namespace O3DE::ProjectManager if (!success) { - progressDialog->setLabelText("Duplicating project failed/cancelled, removing already copied files ..."); + progressDialog->setLabelText(QObject::tr("Duplicating project failed/cancelled, removing already copied files ...")); qApp->processEvents(QEventLoop::ExcludeUserInputEvents); DeleteProjectFiles(newPath, true); From 7cfde884d9aa1a19e70793e563fb138b92d06ee2 Mon Sep 17 00:00:00 2001 From: moraaar Date: Mon, 12 Jul 2021 13:10:20 +0100 Subject: [PATCH 37/37] Fix unused variable warning in release configuration: DebugComponent::DrawInstanceDebug (#2085) Signed-off-by: moraaar --- Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp index 5fa2d6fd88..2f3c8d08be 100644 --- a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp @@ -185,7 +185,7 @@ void DebugComponent::DisplayEntityViewport(const AzFramework::ViewportInfo& view } } -void DebugComponent::DrawInstanceDebug(AzFramework::DebugDisplayRequests& debugDisplay) +void DebugComponent::DrawInstanceDebug([[maybe_unused]] AzFramework::DebugDisplayRequests& debugDisplay) { #if defined(VEG_PROFILE_ENABLED) AZStd::unordered_map areaDebugDisplayDataMap;