191 lines
5.7 KiB
C#
191 lines
5.7 KiB
C#
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
|
|
|
using System;
|
|
using FlaxEditor.Scripting;
|
|
using FlaxEngine;
|
|
using FlaxEngine.Utilities;
|
|
using Object = FlaxEngine.Object;
|
|
|
|
namespace FlaxEditor.Actions
|
|
{
|
|
/// <summary>
|
|
/// Implementation of <see cref="IUndoAction"/> used to add/remove <see cref="Script"/> from the <see cref="Actor"/>.
|
|
/// </summary>
|
|
/// <seealso cref="IUndoAction" />
|
|
[Serializable]
|
|
sealed class AddRemoveScript : IUndoAction
|
|
{
|
|
[Serialize]
|
|
private bool _isAdd;
|
|
|
|
[Serialize]
|
|
private Guid _scriptId;
|
|
|
|
[Serialize]
|
|
private Guid _prefabId;
|
|
|
|
[Serialize]
|
|
private Guid _prefabObjectId;
|
|
|
|
[Serialize]
|
|
private string _scriptTypeName;
|
|
|
|
[Serialize]
|
|
private string _scriptData;
|
|
|
|
[Serialize]
|
|
private Guid _parentId;
|
|
|
|
[Serialize]
|
|
private int _orderInParent;
|
|
|
|
[Serialize]
|
|
private bool _enabled;
|
|
|
|
internal AddRemoveScript(bool isAdd, Script script)
|
|
{
|
|
_isAdd = isAdd;
|
|
_scriptId = script.ID;
|
|
_scriptTypeName = script.TypeName;
|
|
_prefabId = script.PrefabID;
|
|
_prefabObjectId = script.PrefabObjectID;
|
|
try
|
|
{
|
|
_scriptData = FlaxEngine.Json.JsonSerializer.Serialize(script);
|
|
}
|
|
catch
|
|
{
|
|
_scriptData = null;
|
|
}
|
|
_parentId = script.Actor.ID;
|
|
_orderInParent = script.OrderInParent;
|
|
_enabled = script.Enabled;
|
|
}
|
|
|
|
internal AddRemoveScript(bool isAdd, Actor parentActor, ScriptType scriptType)
|
|
{
|
|
_isAdd = isAdd;
|
|
_scriptId = Guid.NewGuid();
|
|
_scriptTypeName = scriptType.TypeName;
|
|
_scriptData = null;
|
|
_parentId = parentActor.ID;
|
|
_orderInParent = -1;
|
|
_enabled = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new added script undo action.
|
|
/// </summary>
|
|
/// <param name="script">The new script.</param>
|
|
/// <returns>The action.</returns>
|
|
public static AddRemoveScript Added(Script script)
|
|
{
|
|
if (script == null)
|
|
throw new ArgumentNullException(nameof(script));
|
|
return new AddRemoveScript(true, script);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new add script undo action.
|
|
/// </summary>
|
|
/// <param name="parentActor">The parent actor.</param>
|
|
/// <param name="scriptType">The script type.</param>
|
|
/// <returns>The action.</returns>
|
|
public static AddRemoveScript Add(Actor parentActor, ScriptType scriptType)
|
|
{
|
|
if (parentActor == null)
|
|
throw new ArgumentNullException(nameof(parentActor));
|
|
if (!scriptType)
|
|
throw new ArgumentNullException(nameof(scriptType));
|
|
return new AddRemoveScript(true, parentActor, scriptType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new remove script undo action.
|
|
/// </summary>
|
|
/// <param name="script">The script.</param>
|
|
/// <returns>The action.</returns>
|
|
public static AddRemoveScript Remove(Script script)
|
|
{
|
|
if (script == null)
|
|
throw new ArgumentNullException(nameof(script));
|
|
return new AddRemoveScript(false, script);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public string ActionString => _isAdd ? "Add script" : "Remove script";
|
|
|
|
/// <inheritdoc />
|
|
public void Do()
|
|
{
|
|
if (_isAdd)
|
|
DoAdd();
|
|
else
|
|
DoRemove();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void Undo()
|
|
{
|
|
if (_isAdd)
|
|
DoRemove();
|
|
else
|
|
DoAdd();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void Dispose()
|
|
{
|
|
_scriptTypeName = null;
|
|
_scriptData = null;
|
|
}
|
|
|
|
private void DoRemove()
|
|
{
|
|
// Remove script (it could be removed by sth else, just check it)
|
|
var script = Object.Find<Script>(ref _scriptId);
|
|
if (!script)
|
|
{
|
|
Editor.LogWarning("Missing script.");
|
|
return;
|
|
}
|
|
if (script.Actor)
|
|
Editor.Instance.Scene.MarkSceneEdited(script.Scene);
|
|
Object.Destroy(ref script);
|
|
}
|
|
|
|
private void DoAdd()
|
|
{
|
|
// Restore script
|
|
var parentActor = Object.Find<Actor>(ref _parentId);
|
|
if (parentActor == null)
|
|
{
|
|
Editor.LogWarning("Missing parent actor.");
|
|
return;
|
|
}
|
|
var type = TypeUtils.GetType(_scriptTypeName);
|
|
if (!type)
|
|
{
|
|
Editor.LogWarning("Cannot find script type " + _scriptTypeName);
|
|
return;
|
|
}
|
|
var script = type.CreateInstance() as Script;
|
|
if (script == null)
|
|
{
|
|
Editor.LogWarning("Cannot create script of type " + _scriptTypeName);
|
|
return;
|
|
}
|
|
Object.Internal_ChangeID(Object.GetUnmanagedPtr(script), ref _scriptId);
|
|
if (_scriptData != null)
|
|
FlaxEngine.Json.JsonSerializer.Deserialize(script, _scriptData);
|
|
script.Enabled = _enabled;
|
|
script.Parent = parentActor;
|
|
if (_orderInParent != -1)
|
|
script.OrderInParent = _orderInParent;
|
|
if (_prefabObjectId != Guid.Empty)
|
|
SceneObject.Internal_LinkPrefab(Object.GetUnmanagedPtr(script), ref _prefabId, ref _prefabObjectId);
|
|
Editor.Instance.Scene.MarkSceneEdited(parentActor.Scene);
|
|
}
|
|
}
|
|
}
|