From 7018f16088c36377b88f86f79c6de3d03cb81beb Mon Sep 17 00:00:00 2001 From: Mikhail Naumov <82239319+AMZN-mnaumov@users.noreply.github.com> Date: Fri, 1 Oct 2021 15:16:45 -0500 Subject: [PATCH] Fixing undo/redo not updating transform pivot point (#4375) * Fixing undo/redo not updating transform pivot point Signed-off-by: Mikhail Naumov * PR feedback Signed-off-by: Mikhail Naumov * PR feedback Signed-off-by: Mikhail Naumov * fixing non-redo operations to still use batching (fixes some tests) Signed-off-by: Mikhail Naumov --- .../Prefab/Instance/InstanceToTemplateInterface.h | 3 ++- .../Instance/InstanceToTemplatePropagator.cpp | 4 ++-- .../Instance/InstanceToTemplatePropagator.h | 2 +- .../Prefab/Instance/InstanceUpdateExecutor.cpp | 7 ++++++- .../Prefab/Instance/InstanceUpdateExecutor.h | 2 +- .../Instance/InstanceUpdateExecutorInterface.h | 2 +- .../Prefab/PrefabPublicHandler.cpp | 2 +- .../Prefab/PrefabSystemComponent.cpp | 8 ++++---- .../Prefab/PrefabSystemComponent.h | 7 +++++-- .../Prefab/PrefabSystemComponentInterface.h | 2 +- .../AzToolsFramework/Prefab/PrefabUndo.cpp | 15 ++++++++++----- .../AzToolsFramework/Prefab/PrefabUndo.h | 1 + .../AzToolsFramework/Prefab/PrefabUndoHelpers.cpp | 2 +- 13 files changed, 36 insertions(+), 21 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h index b944ef159a..a8c717d6b0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h @@ -46,10 +46,11 @@ namespace AzToolsFramework //! Updates the template links (updating instances) for the given template and triggers propagation on its instances. //! @param providedPatch The patch to apply to the template. //! @param templateId The id of the template to update. + //! @param immediate An optional flag whether to apply the patch immediately (needed for Undo/Redos) or wait until next system tick. //! @param instanceToExclude An optional reference to an instance of the template being updated that should not be refreshes as part of propagation. //! Defaults to nullopt, which means that all instances will be refreshed. //! @return True if the template was patched correctly, false if the operation failed. - virtual bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0; + virtual bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, bool immediate = false, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0; virtual void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp index 6b281bcbae..73acb9b8a4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp @@ -156,7 +156,7 @@ namespace AzToolsFramework } } - bool InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, InstanceOptionalReference instanceToExclude) + bool InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, bool immediate, InstanceOptionalReference instanceToExclude) { PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId); @@ -178,7 +178,7 @@ namespace AzToolsFramework (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip), "Some of the patches were not successfully applied."); m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true); - m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude); + m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, immediate, instanceToExclude); return true; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h index 75acb410c9..80fe7de8d5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.h @@ -33,7 +33,7 @@ namespace AzToolsFramework InstanceOptionalReference GetTopMostInstanceInHierarchy(AZ::EntityId entityId) override; - bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override; + bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, bool immediate = false, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override; void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp index 9ef74167a6..feea3ce25b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp @@ -52,7 +52,7 @@ namespace AzToolsFramework AZ::Interface::Unregister(this); } - void InstanceUpdateExecutor::AddTemplateInstancesToQueue(TemplateId instanceTemplateId, InstanceOptionalReference instanceToExclude) + void InstanceUpdateExecutor::AddTemplateInstancesToQueue(TemplateId instanceTemplateId, bool immediate, InstanceOptionalReference instanceToExclude) { auto findInstancesResult = m_templateInstanceMapperInterface->FindInstancesOwnedByTemplate(instanceTemplateId); @@ -79,6 +79,11 @@ namespace AzToolsFramework m_instancesUpdateQueue.emplace_back(instance); } } + + if (immediate) + { + UpdateTemplateInstancesInQueue(); + } } void InstanceUpdateExecutor::RemoveTemplateInstanceFromQueue(const Instance* instance) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.h index ee461eae88..de2b483c4d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.h @@ -31,7 +31,7 @@ namespace AzToolsFramework explicit InstanceUpdateExecutor(int instanceCountToUpdateInBatch = 0); - void AddTemplateInstancesToQueue(TemplateId instanceTemplateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override; + void AddTemplateInstancesToQueue(TemplateId instanceTemplateId, bool immediate = false, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override; bool UpdateTemplateInstancesInQueue() override; virtual void RemoveTemplateInstanceFromQueue(const Instance* instance) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutorInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutorInterface.h index 8ad032e1d0..3b894efd21 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutorInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutorInterface.h @@ -23,7 +23,7 @@ namespace AzToolsFramework virtual ~InstanceUpdateExecutorInterface() = default; // Add all Instances of Template with given Id into a queue for updating them later. - virtual void AddTemplateInstancesToQueue(TemplateId instanceTemplateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0; + virtual void AddTemplateInstancesToQueue(TemplateId instanceTemplateId, bool immediate = false, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0; // Update Instances in the waiting queue. virtual bool UpdateTemplateInstancesInQueue() = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 41538d54e8..038f36eac9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -1041,7 +1041,7 @@ namespace AzToolsFramework PrefabUndoInstance* command = aznew PrefabUndoInstance("Entity/Instance duplication"); command->SetParent(undoBatch.GetUndoBatch()); command->Capture(instanceDomBefore, instanceDomAfter, commonOwningInstance->get().GetTemplateId()); - command->Redo(); + command->RedoBatched(); DuplicateNestedInstancesInInstance(commonOwningInstance->get(), instances, instanceDomAfter, duplicatedEntityAndInstanceIds, newInstanceAliasToOldInstanceMap); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index 29bad78b1c..0ecde973c2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -146,9 +146,9 @@ namespace AzToolsFramework } } - void PrefabSystemComponent::PropagateTemplateChanges(TemplateId templateId, InstanceOptionalReference instanceToExclude) + void PrefabSystemComponent::PropagateTemplateChanges(TemplateId templateId, bool immediate, InstanceOptionalReference instanceToExclude) { - UpdatePrefabInstances(templateId, instanceToExclude); + UpdatePrefabInstances(templateId, immediate, instanceToExclude); auto templateIdToLinkIdsIterator = m_templateToLinkIdsMap.find(templateId); if (templateIdToLinkIdsIterator != m_templateToLinkIdsMap.end()) @@ -177,9 +177,9 @@ namespace AzToolsFramework } } - void PrefabSystemComponent::UpdatePrefabInstances(TemplateId templateId, InstanceOptionalReference instanceToExclude) + void PrefabSystemComponent::UpdatePrefabInstances(TemplateId templateId, bool immediate, InstanceOptionalReference instanceToExclude) { - m_instanceUpdateExecutor.AddTemplateInstancesToQueue(templateId, instanceToExclude); + m_instanceUpdateExecutor.AddTemplateInstancesToQueue(templateId, immediate, instanceToExclude); } void PrefabSystemComponent::UpdateLinkedInstances(AZStd::queue& linkIdsQueue) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h index 19c7aeb8a9..f640eb2f1b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h @@ -230,14 +230,17 @@ namespace AzToolsFramework */ void UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom) override; - void PropagateTemplateChanges(TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override; + void PropagateTemplateChanges(TemplateId templateId, bool immediate = false, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override; /** * Updates all Instances owned by a Template. * * @param templateId The id of the Template owning Instances to update. + * @param immediate An optional flag whether to apply the patch immediately (needed for Undo/Redos) or wait until next system tick. + * @param instanceToExclude An optional reference to an instance of the template being updated that should not be refreshes as part of propagation. + * Defaults to nullopt, which means that all instances will be refreshed. */ - void UpdatePrefabInstances(TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt); + void UpdatePrefabInstances(TemplateId templateId, bool immediate = false, InstanceOptionalReference instanceToExclude = AZStd::nullopt); private: AZ_DISABLE_COPY_MOVE(PrefabSystemComponent); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h index 3baaf9ae12..54ca951841 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h @@ -67,7 +67,7 @@ namespace AzToolsFramework virtual PrefabDom& FindTemplateDom(TemplateId templateId) = 0; virtual void UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom) = 0; - virtual void PropagateTemplateChanges(TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0; + virtual void PropagateTemplateChanges(TemplateId templateId, bool immediate = false, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0; virtual AZStd::unique_ptr InstantiatePrefab( AZ::IO::PathView filePath, InstanceOptionalReference parent = AZStd::nullopt) = 0; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp index 385e9b149b..b298304e3b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp @@ -43,10 +43,15 @@ namespace AzToolsFramework void PrefabUndoInstance::Undo() { - m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId); + m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId, true); } void PrefabUndoInstance::Redo() + { + m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, true); + } + + void PrefabUndoInstance::RedoBatched() { m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId); } @@ -91,7 +96,7 @@ namespace AzToolsFramework void PrefabUndoEntityUpdate::Undo() { [[maybe_unused]] bool isPatchApplicationSuccessful = - m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId); + m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId, true); AZ_Error( "Prefab", isPatchApplicationSuccessful, @@ -102,7 +107,7 @@ namespace AzToolsFramework void PrefabUndoEntityUpdate::Redo() { [[maybe_unused]] bool isPatchApplicationSuccessful = - m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId); + m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, true); AZ_Error( "Prefab", isPatchApplicationSuccessful, @@ -113,7 +118,7 @@ namespace AzToolsFramework void PrefabUndoEntityUpdate::Redo(InstanceOptionalReference instanceToExclude) { [[maybe_unused]] bool isPatchApplicationSuccessful = - m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, instanceToExclude); + m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, false, instanceToExclude); AZ_Error( "Prefab", isPatchApplicationSuccessful, @@ -329,7 +334,7 @@ namespace AzToolsFramework //propagate the link changes link->get().UpdateTarget(); - m_prefabSystemComponentInterface->PropagateTemplateChanges(link->get().GetTargetTemplateId(), instanceToExclude); + m_prefabSystemComponentInterface->PropagateTemplateChanges(link->get().GetTargetTemplateId(), false, instanceToExclude); //mark as dirty m_prefabSystemComponentInterface->SetTemplateDirtyFlag(link->get().GetTargetTemplateId(), true); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.h index 0af94f86cc..8669024df7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.h @@ -53,6 +53,7 @@ namespace AzToolsFramework void Undo() override; void Redo() override; + void RedoBatched(); }; //! handles entity updates, such as when the values on an entity change diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp index 9c44fc7ffd..9803b55324 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoHelpers.cpp @@ -26,7 +26,7 @@ namespace AzToolsFramework PrefabUndoInstance* state = aznew Prefab::PrefabUndoInstance(undoMessage); state->Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, instance.GetTemplateId()); state->SetParent(undoBatch); - state->Redo(); + state->RedoBatched(); } LinkId CreateLink(