//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
//**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************//
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using bs;
namespace bs.Editor
{
/** @addtogroup Utility-Editor
* @{
*/
///
/// Provides functionality to undo or redo recently performed operations in the editor. All commands executed from this
/// class are undoable/redoable.
///
/// The class provides static methods that access the global undo/redo stack, but can also be instantiated to provide
/// local undo/redo stacks.
///
public class UndoRedo : ScriptObject
{
private static UndoRedo global;
///
/// Constructor for internal runtime use.
///
/// Dummy parameter to distinguish from public constructor.
private UndoRedo(bool dummy)
{ }
///
/// Creates a new undo/redo stack.
///
public UndoRedo()
{
Internal_CreateInstance(this);
}
///
/// Returns the global undo/redo stack.
///
public static UndoRedo Global
{
get { return global; }
}
///
/// Returns the unique identifier of the command currently at the top of the undo stack.
///
public int TopCommandId
{
get { return Internal_GetTopCommandId(mCachedPtr); }
}
///
/// Executes the last command on the undo stack, undoing its operations.
///
public void Undo()
{
Internal_Undo(mCachedPtr);
}
///
/// Executes the last command on the redo stack (last command we called undo on), re-applying its operation.
///
public void Redo()
{
Internal_Redo(mCachedPtr);
}
///
/// Registers a new undo command.
///
/// Command to register
public void RegisterCommand(UndoableCommand command)
{
if (command == null)
return;
Internal_RegisterCommand(mCachedPtr, command.GetCachedPtr());
}
///
/// Creates a new undo/redo group. All new commands will be registered to this group. You may remove the group and
/// all of its commands by calling .
///
/// Unique name of the group.
public void PushGroup(string name)
{
Internal_PushGroup(mCachedPtr, name);
}
///
/// Removes all the command registered to the current undo/redo group.
///
/// Unique name of the group.
public void PopGroup(string name)
{
Internal_PopGroup(mCachedPtr, name);
}
///
/// Removes a command with the specified identifier from undo/redo stack without executing it.
///
/// Identifier of the command as returned by
public void PopCommand(int id)
{
Internal_PopCommand(mCachedPtr, id);
}
///
/// Clears all undo/redo commands from the stack.
///
public void Clear()
{
Internal_Clear(mCachedPtr);
}
///
/// Creates new scene object(s) by cloning existing objects. Undo operation recorded in global undo/redo stack.
///
/// Scene object(s) to clone.
/// Optional description of what exactly the command does.
/// Cloned scene objects.
public static SceneObject[] CloneSO(SceneObject[] so, string description = "")
{
if (so != null)
{
List soPtrs = new List();
for (int i = 0; i < so.Length; i++)
{
if(so[i] != null)
soPtrs.Add(so[i].GetCachedPtr());
}
return Internal_CloneSOMulti(soPtrs.ToArray(), description);
}
return new SceneObject[0];
}
///
/// Creates new a scene object by cloning an existing object. Undo operation recorded in global undo/redo stack.
///
/// Scene object to clone.
/// Optional description of what exactly the command does.
/// Cloned scene object.
public static SceneObject CloneSO(SceneObject so, string description = "")
{
if (so != null)
return Internal_CloneSO(so.GetCachedPtr(), description);
return null;
}
///
/// Instantiates scene object(s) from a prefab. Undo operation recorded in global undo/redo stack.
///
/// Prefab to instantiate.
/// Optional description of what exactly the command does.
/// Instantiated scene object.
public static SceneObject Instantiate(Prefab prefab, string description = "")
{
if (prefab != null)
return Internal_Instantiate(prefab.GetCachedPtr(), description);
return null;
}
///
/// Creates a new scene object. Undo operation recorded in global undo/redo stack.
///
/// Name of the scene object.
/// Optional description of what exactly the command does.
/// Newly created scene object.
public static SceneObject CreateSO(string name, string description = "")
{
return Internal_CreateSO(name, description);
}
///
/// Deletes a scene object. Undo operation recorded in global undo/redo stack.
///
/// Scene object to delete.
/// Optional description of what exactly the command does.
public static void DeleteSO(SceneObject so, string description = "")
{
if (so != null)
Internal_DeleteSO(so.GetCachedPtr(), description);
}
///
/// Changes the parent of the scene object. Undo operation recorded in global undo/redo stack.
///
/// Scene object to change the parent of.
/// New parent.
/// Optional description of what exactly the command does.
public static void ReparentSO(SceneObject so, SceneObject parent, string description = "")
{
if (so != null)
{
IntPtr parentPtr = IntPtr.Zero;
if (parent != null)
parentPtr = parent.GetCachedPtr();
Internal_ReparentSO(so.GetCachedPtr(), parentPtr, description);
}
}
///
/// Changes the parent of a set of scene objects. Undo operation recorded in global undo/redo stack.
///
/// Scene objects to change the parent of.
/// New parent.
/// Optional description of what exactly the command does.
public static void ReparentSO(SceneObject[] so, SceneObject parent, string description = "")
{
if (so != null)
{
List soPtrs = new List();
for (int i = 0; i < so.Length; i++)
{
if (so[i] != null)
soPtrs.Add(so[i].GetCachedPtr());
}
if (soPtrs.Count > 0)
{
IntPtr parentPtr = IntPtr.Zero;
if (parent != null)
parentPtr = parent.GetCachedPtr();
Internal_ReparentSOMulti(soPtrs.ToArray(), parentPtr, description);
}
}
}
///
/// Breaks the prefab link on the provided scene object and makes the operation undo-able. Undo operation recorded
/// in global undo/redo stack.
/// See .
///
/// Scene object whose prefab link to break.
/// Optional description of what exactly the command does.
public static void BreakPrefab(SceneObject so, string description = "")
{
if (so != null)
Internal_BreakPrefab(so.GetCachedPtr(), description);
}
///
/// Used by the runtime to set the global undo/redo stack.
///
/// Instance of the global undo/redo stack.
private static void Internal_SetGlobal(UndoRedo global)
{
// We can't set this directly through the field because there is an issue with Mono and static fields
UndoRedo.global = global;
}
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_CreateInstance(UndoRedo instance);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_Undo(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_Redo(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_RegisterCommand(IntPtr thisPtr, IntPtr commandPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_PushGroup(IntPtr thisPtr, string name);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_PopGroup(IntPtr thisPtr, string name);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_Clear(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_PopCommand(IntPtr thisPtr, int id);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern int Internal_GetTopCommandId(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern SceneObject Internal_CloneSO(IntPtr soPtr, string description);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern SceneObject[] Internal_CloneSOMulti(IntPtr[] soPtr, string description);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern SceneObject Internal_Instantiate(IntPtr prefabPtr, string description);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern SceneObject Internal_CreateSO(string name, string description);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_DeleteSO(IntPtr soPtr, string description);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_ReparentSO(IntPtr soPtr, IntPtr parentSOPtr, string description);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_ReparentSOMulti(IntPtr[] soPtr, IntPtr parentSOPtr, string description);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Internal_BreakPrefab(IntPtr soPtr, string description);
}
/** @} */
}