// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using FlaxEngine;
using Object = FlaxEngine.Object;
namespace FlaxEditor.Actions
{
///
/// Implementation of used to break/restore connection for the collection of and objects.
///
///
/// This action assumes that all objects in the given actor hierarchy are using the same prefab asset.
///
///
[Serializable]
sealed class BreakPrefabLinkAction : IUndoAction
{
[Serialize]
private readonly bool _isBreak;
[Serialize]
private Guid _actorId;
[Serialize]
private Guid _prefabId;
[Serialize]
private Dictionary _prefabObjectIds;
private BreakPrefabLinkAction(bool isBreak, Guid actorId, Guid prefabId)
{
_isBreak = isBreak;
_actorId = actorId;
_prefabId = prefabId;
}
private BreakPrefabLinkAction(bool isBreak, Actor actor)
{
_isBreak = isBreak;
_actorId = actor.ID;
_prefabId = actor.PrefabID;
_prefabObjectIds = new Dictionary(1024);
CollectIds(actor);
}
///
/// Creates a new undo action that in state for breaking prefab connection.
///
/// The target actor.
/// The action.
public static BreakPrefabLinkAction Break(Actor actor)
{
if (actor == null)
throw new ArgumentNullException(nameof(actor));
return new BreakPrefabLinkAction(true, actor.ID, Guid.Empty);
}
///
/// Creates a new undo action that in state for linked prefab connection. Action on perform will undo that.
///
/// The target actor.
/// The action.
public static BreakPrefabLinkAction Linked(Actor actor)
{
if (actor == null)
throw new ArgumentNullException(nameof(actor));
if (!actor.HasPrefabLink)
throw new Exception("Cannot register missing prefab link.");
return new BreakPrefabLinkAction(false, actor);
}
///
public string ActionString => _isBreak ? "Break prefab link" : "Link prefab";
///
public void Do()
{
if (_isBreak)
DoBreak();
else
DoLink();
}
///
public void Undo()
{
if (_isBreak)
DoLink();
else
DoBreak();
}
///
public void Dispose()
{
_prefabObjectIds.Clear();
}
private void DoLink()
{
if (_prefabObjectIds == null)
throw new Exception("Cannot link prefab. Missing objects Ids mapping.");
var actor = Object.Find(ref _actorId);
if (actor == null)
throw new Exception("Cannot link prefab. Missing actor.");
// Restore cached links
foreach (var e in _prefabObjectIds)
{
var objId = e.Key;
var prefabObjId = e.Value;
var obj = Object.Find