using System.Collections.Generic;
using System.Linq;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace VelNet
{
public class UndoGroup : MonoBehaviour
{
///
/// This cannot be changed at runtime.
///
public List objects;
private readonly List undoBuffer = new List();
public int maxUndoSteps = 50;
///
/// Reset to the last UndoState. This only takes ownership if the IPackState component is also a NetworkComponent
///
public void Undo()
{
byte[][] lastStates = undoBuffer.LastOrDefault();
if (lastStates != null)
{
for (int i = 0; i < objects.Count; i++)
{
objects[i].networkObject.TakeOwnership();
objects[i].UnpackState(lastStates[i]);
}
}
}
public void SaveUndoState()
{
byte[][] states = new byte[objects.Count][];
for (int i = 0; i < objects.Count; i++)
{
states[i] = objects[i].PackState();
}
undoBuffer.Add(states);
while (undoBuffer.Count > maxUndoSteps)
{
undoBuffer.RemoveAt(0);
}
}
public int UndoHistoryLength()
{
return undoBuffer.Count;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(UndoGroup))]
public class UndoGroupEditor : Editor
{
public override void OnInspectorGUI()
{
UndoGroup t = target as UndoGroup;
EditorGUILayout.Space();
if (t == null) return;
EditorGUILayout.HelpBox("Undo Group. Use SaveUndoState() to make checkpoints.", MessageType.Info);
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.TextField("Undo Length: ", t.UndoHistoryLength().ToString("N0"));
EditorGUI.EndDisabledGroup();
EditorGUILayout.Space();
if (EditorApplication.isPlaying && GUILayout.Button("Save undo checkpoint now."))
{
t.SaveUndoState();
}
if (GUILayout.Button("Find all undoable components in children."))
{
SyncState[] components = t.GetComponentsInChildren();
SerializedObject so = new SerializedObject(t);
SerializedProperty prop = so.FindProperty("objects");
prop.ClearArray();
foreach (SyncState comp in components)
{
prop.InsertArrayElementAtIndex(0);
prop.GetArrayElementAtIndex(0).objectReferenceValue = comp;
}
so.ApplyModifiedProperties();
}
EditorGUILayout.Space();
DrawDefaultInspector();
}
}
#endif
}