// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; using FlaxEditor.History; using FlaxEditor.Options; using FlaxEngine; namespace FlaxEditor { /// /// Implementation of customized for the . /// /// public class EditorUndo : Undo { private readonly Editor _editor; internal EditorUndo(Editor editor) : base(500) { _editor = editor; editor.Options.OptionsChanged += OnOptionsChanged; } private void OnOptionsChanged(EditorOptions options) { Capacity = options.General.UndoActionsCapacity; } /// public override bool Enabled { get => _editor.StateMachine.CurrentState.CanUseUndoRedo; set => throw new AccessViolationException("Cannot change enabled state of the editor main undo."); } /// protected override void OnAction(IUndoAction action) { CheckSceneEdited(action); base.OnAction(action); } /// protected override void OnUndo(IUndoAction action) { CheckSceneEdited(action); base.OnUndo(action); } /// protected override void OnRedo(IUndoAction action) { CheckSceneEdited(action); base.OnRedo(action); } /// /// Checks if the any scene has been edited after performing the given action. /// /// The action. private void CheckSceneEdited(IUndoAction action) { // Note: this is automatic tracking system to check if undo action modifies scene objects // Skip if all scenes are already modified if (Editor.Instance.Scene.IsEverySceneEdited()) return; // ReSharper disable once SuspiciousTypeConversion.Global if (action is ISceneEditAction sceneEditAction) { sceneEditAction.MarkSceneEdited(Editor.Instance.Scene); } else if (action is UndoActionObject undoActionObject) { var data = undoActionObject.PrepareData(); if (data.TargetInstance is SceneGraph.SceneGraphNode node) { Editor.Instance.Scene.MarkSceneEdited(node.ParentScene); } else if (data.TargetInstance is Actor actor) { Editor.Instance.Scene.MarkSceneEdited(actor.Scene); } else if (data.TargetInstance is Script script && script.Actor != null) { Editor.Instance.Scene.MarkSceneEdited(script.Actor.Scene); } } else if (action is MultiUndoAction multiUndoAction) { // Process child actions for (int i = 0; i < multiUndoAction.Actions.Length; i++) { CheckSceneEdited(multiUndoAction.Actions[i]); } } } } }