// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; using FlaxEditor.SceneGraph; using FlaxEngine; namespace FlaxEditor.Actions { /// /// Implementation of used to delete a selection of . /// /// [Serializable] class DeleteActorsAction : IUndoAction { [Serialize] private byte[] _data; [Serialize] private Guid[] _prefabIds; [Serialize] private Guid[] _prefabObjectIds; [Serialize] private bool _isInverted; /// /// The node parents. /// [Serialize] protected List _nodeParents; /// /// Initializes a new instance of the class. /// /// The objects. /// If set to true action will be inverted - instead of delete it will be create actors. internal DeleteActorsAction(List objects, bool isInverted = false) { _isInverted = isInverted; _nodeParents = new List(objects.Count); var actorNodes = new List(objects.Count); var actors = new List(objects.Count); for (int i = 0; i < objects.Count; i++) { if (objects[i] is ActorNode node) { actorNodes.Add(node); actors.Add(node.Actor); } } actorNodes.BuildNodesParents(_nodeParents); _data = Actor.ToBytes(actors.ToArray()); _prefabIds = new Guid[actors.Count]; _prefabObjectIds = new Guid[actors.Count]; for (int i = 0; i < actors.Count; i++) { _prefabIds[i] = actors[i].PrefabID; _prefabObjectIds[i] = actors[i].PrefabObjectID; } } /// public string ActionString => _isInverted ? "Create actors" : "Delete actors"; /// public void Do() { if (_isInverted) Create(); else Delete(); } /// public void Undo() { if (_isInverted) Delete(); else Create(); } /// public void Dispose() { _data = null; _prefabIds = null; _prefabObjectIds = null; } /// /// Deletes the objects. /// protected virtual void Delete() { // Remove objects for (int i = 0; i < _nodeParents.Count; i++) { var node = _nodeParents[i]; Editor.Instance.Scene.MarkSceneEdited(node.ParentScene); node.Delete(); } _nodeParents.Clear(); } /// /// Gets the node. /// /// The actor id. /// The scene graph node. protected virtual SceneGraphNode GetNode(Guid id) { return SceneGraphFactory.FindNode(id); } /// /// Creates the removed objects (from data). /// protected virtual void Create() { // Restore objects var actors = Actor.FromBytes(_data); if (actors == null) return; for (int i = 0; i < actors.Length; i++) { Guid prefabId = _prefabIds[i]; if (prefabId != Guid.Empty) { Actor.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(actors[i]), ref prefabId, ref _prefabObjectIds[i]); } } var actorNodes = new List(actors.Length); for (int i = 0; i < actors.Length; i++) { var foundNode = GetNode(actors[i].ID); if (foundNode is ActorNode node) { actorNodes.Add(node); } } actorNodes.BuildNodesParents(_nodeParents); for (int i = 0; i < _nodeParents.Count; i++) { Editor.Instance.Scene.MarkSceneEdited(_nodeParents[i].ParentScene); } } } }