// 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);
}
}
}
}