Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- Switched from ISerializationCallbackReceiver to ondemand serialization
- Added support for Collection serialization for variables stored in anonymous functions (TODO: Fix warning about serialization loop that has been created instead)
- Other Bugfixes in serialization system
- Reworked UndoProTestWindow to easily visualize if anything has gone wrong with tracking (use this to verify suspicions, if anything breaks, bold UndoPro records will get a normal font, split up and shift: 'Normal / Pro')
- Added Begin-/EndRecordStack to be able to group singular UndoPro records together as a group
  • Loading branch information
Seneral committed Jun 30, 2019
1 parent bec9874 commit 8605034
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 163 deletions.
17 changes: 1 addition & 16 deletions .gitignore
@@ -1,16 +1 @@
workspace.xml
junitvmwatcher*.properties
build.properties

# generated java classes and java source files
# manually add any custom artifacts that can't be generated from the models
# http://confluence.jetbrains.com/display/MPSD25/HowTo+--+MPS+and+Git
classes_gen
source_gen
source_gen.caches

# generated test code and test results
test_gen
test_gen.caches
TEST-*.xml
junit*.properties
**/*.meta
79 changes: 32 additions & 47 deletions Editor/UndoProTestWindow.cs
Expand Up @@ -83,60 +83,45 @@ public void OnGUI ()

maxRecordCount = EditorGUILayout.IntSlider ("Max shown records", maxRecordCount, 0, 20);

EditorGUILayout.Space ();

GUILayout.BeginHorizontal ();
// Undo's
GUILayout.BeginVertical ();
GUILayout.Label ("UNDO:");
for (int cnt = 0; cnt < Math.Min (state.undoRecords.Count, maxRecordCount); cnt++)
{
int index = state.undoRecords.Count-1-cnt;
GUILayout.Label ("Undo " + index + ": " + state.undoRecords[index]);
}
GUILayout.EndVertical ();
// Redo's
GUILayout.BeginVertical ();
GUILayout.Label ("REDO:");
for (int cnt = 0; cnt < Math.Min (state.redoRecords.Count, maxRecordCount); cnt++)
{
int index = state.redoRecords.Count-1-cnt;
GUILayout.Label ("Redo " + index + ": " + state.redoRecords[index]);
}
GUILayout.EndVertical ();
GUILayout.EndHorizontal ();


EditorGUILayout.Space ();
EditorGUILayout.Space ();
EditorGUILayout.Space();

GUILayout.BeginHorizontal();

GUILayout.Label ("--- PRO RECORDS:");

GUILayout.BeginHorizontal ();
// Undo's
GUILayout.BeginVertical ();
GUILayout.Label ("UNDO:");
List<UndoProRecord> undoStack = records.proUndoStack;
for (int cnt = 0; cnt < Math.Min (undoStack.Count, maxRecordCount); cnt++)
GUILayout.BeginVertical(GUILayout.Width(EditorGUIUtility.currentViewWidth/2));
GUILayout.Label("UNDO:");
for (int cnt = 0; cnt < Math.Min(state.undoRecords.Count, maxRecordCount); cnt++)
{
UndoProRecord rec = undoStack[undoStack.Count-1-cnt];
GUILayout.Label ("Undo " + (state.undoRecords.Count-1+rec.relativeStackPos) + "(" + rec.relativeStackPos + "): " + rec.label);
int index = state.undoRecords.Count - 1 - cnt;
string rec = state.undoRecords[index];
List<UndoProRecord> proRecords = records.proUndoStack.FindAll(r => r.relativeStackPos == -cnt);
int matchInd = proRecords.FindIndex(r => r.label == rec);
string proRec = "";
for (int i = 0; i < proRecords.Count; i++)
if (i != matchInd) proRec += " / " + proRecords[i].label;
GUILayout.Label("Undo " + index + ": " + rec + proRec,
matchInd == -1? EditorStyles.label : EditorStyles.boldLabel,
GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth / 2));
}
GUILayout.EndVertical ();
// Redo's
GUILayout.BeginVertical ();
GUILayout.Label ("REDO:");
List<UndoProRecord> redoStack = records.proRedoStack;
for (int cnt = 0; cnt < Math.Min (redoStack.Count, maxRecordCount); cnt++)
GUILayout.EndVertical();

GUILayout.BeginVertical();
GUILayout.Label("REDO:");
for (int cnt = 0; cnt < Math.Min(state.redoRecords.Count, maxRecordCount); cnt++)
{
UndoProRecord rec = redoStack[redoStack.Count-1-cnt];
GUILayout.Label ("Redo " + (state.redoRecords.Count-rec.relativeStackPos) + "(" + rec.relativeStackPos + "): " + rec.label);
int index = state.redoRecords.Count - 1 - cnt;
string rec = state.redoRecords[index];
List<UndoProRecord> proRecords = records.proRedoStack.FindAll(r => r.relativeStackPos == cnt+1);
int matchInd = proRecords.FindIndex(r => r.label == rec);
string proRec = "";
for (int i = 0; i < proRecords.Count; i++)
if (i != matchInd) proRec += " / " + proRecords[i].label;
GUILayout.Label("Redo " + index + ": " + rec + proRec, matchInd == -1 ? EditorStyles.label : EditorStyles.boldLabel);
}
GUILayout.EndVertical ();
GUILayout.EndHorizontal ();
GUILayout.EndVertical();

EditorGUILayout.Space ();
GUILayout.EndHorizontal();

EditorGUILayout.Space();

GUILayout.Label ("Current Group " + Undo.GetCurrentGroupName () + " : " + Undo.GetCurrentGroup () + " ---");
}
Expand Down
52 changes: 31 additions & 21 deletions UndoPro/SerializableAction/SerializableMethodInfo.cs
Expand Up @@ -12,9 +12,18 @@
/// Stores declaringType, methodName, parameters and flags only and supports generic types (one level for class, two levels for method).
/// </summary>
[Serializable]
public class SerializableMethodInfo : ISerializationCallbackReceiver
public class SerializableMethodInfo
{
public MethodInfo methodInfo;
private MethodInfo _methodInfo;
public MethodInfo methodInfo
{
get
{
if (_methodInfo == null)
Deserialize();
return _methodInfo;
}
}

[SerializeField]
private SerializableType declaringType;
Expand All @@ -33,47 +42,48 @@ public class SerializableMethodInfo : ISerializationCallbackReceiver

public SerializableMethodInfo (MethodInfo MethodInfo)
{
methodInfo = MethodInfo;
_methodInfo = MethodInfo;
Serialize();
}

#region Serialization

public void OnBeforeSerialize()
public void Serialize()
{
if (methodInfo == null)
if (_methodInfo == null)
return;

declaringType = new SerializableType (methodInfo.DeclaringType);
methodName = methodInfo.Name;
declaringType = new SerializableType (_methodInfo.DeclaringType);
methodName = _methodInfo.Name;

// Flags
if (methodInfo.IsPrivate)
if (_methodInfo.IsPrivate)
flags |= (int)BindingFlags.NonPublic;
else
flags |= (int)BindingFlags.Public;
if (methodInfo.IsStatic)
if (_methodInfo.IsStatic)
flags |= (int)BindingFlags.Static;
else
flags |= (int)BindingFlags.Instance;

// Parameter
ParameterInfo[] param = methodInfo.GetParameters ();
ParameterInfo[] param = _methodInfo.GetParameters ();
if (param != null && param.Length > 0)
parameters = param.Select ((ParameterInfo p) => new SerializableType (p.ParameterType)).ToList ();
else
parameters = null;

// Generic types
if (methodInfo.IsGenericMethod)
if (_methodInfo.IsGenericMethod)
{
methodName = methodInfo.GetGenericMethodDefinition ().Name;
genericTypes = methodInfo.GetGenericArguments ().Select ((Type genArgT) => new SerializableType (genArgT)).ToList ();
methodName = _methodInfo.GetGenericMethodDefinition ().Name;
genericTypes = _methodInfo.GetGenericArguments ().Select ((Type genArgT) => new SerializableType (genArgT)).ToList ();
}
else
genericTypes = null;
}

public void OnAfterDeserialize()
public void Deserialize()
{
if (declaringType == null || declaringType.type == null || string.IsNullOrEmpty (methodName))
return;
Expand All @@ -85,21 +95,21 @@ public void OnAfterDeserialize()
else
param = new Type[0];

methodInfo = declaringType.type.GetMethod (methodName, (BindingFlags)flags, null, param, null);
if (methodInfo == null)
_methodInfo = declaringType.type.GetMethod (methodName, (BindingFlags)flags, null, param, null);
if (_methodInfo == null)
{ // Retry with private flags, because in some compiler generated methods flags will be uncertain (?) which then return public but are private
methodInfo = declaringType.type.GetMethod (methodName, (BindingFlags)flags | BindingFlags.NonPublic, null, param, null);
if (methodInfo == null)
_methodInfo = declaringType.type.GetMethod (methodName, (BindingFlags)flags | BindingFlags.NonPublic, null, param, null);
if (_methodInfo == null)
throw new Exception ("Could not deserialize '" + SignatureName + "' in declaring type '" + declaringType.type.FullName + "'!");
}

if (methodInfo.IsGenericMethodDefinition && genericTypes != null && genericTypes.Count > 0)
if (_methodInfo.IsGenericMethodDefinition && genericTypes != null && genericTypes.Count > 0)
{ // Generic Method
Type[] genArgs = genericTypes.Select ((SerializableType t) => t.type).ToArray ();

MethodInfo genMethod = methodInfo.MakeGenericMethod (genArgs);
MethodInfo genMethod = _methodInfo.MakeGenericMethod (genArgs);
if (genMethod != null)
methodInfo = genMethod;
_methodInfo = genMethod;
else
Debug.LogError ("Could not make generic-method definition '" + methodName + "' generic!");
}
Expand Down

0 comments on commit 8605034

Please sign in to comment.