using System.Reflection; namespace Pilz.Collections.SimpleHistory; public class ObjectAction : ObjectBase { public object? Object { get; set; } = null; public List ParametersUndo { get; } = []; public List ParametersRedo { get; } = []; public MethodInfo? MethodUndo { get; set; } = null; public MethodInfo? MethodRedo { get; set; } = null; public bool AutogenerateObject { get; set; } = true; /// /// Creates a new Instance of Object Action. /// public ObjectAction() { } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The name of the methode to call on Undo. /// The name of the methode to call on Redo. public ObjectAction(object obj, string methodNameUndo, string methodNameRedo) : this(obj, methodNameUndo, methodNameRedo, [], [], BindingFlags.Default, BindingFlags.Default) { } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The name of the methode to call on Undo. /// The name of the methode to call on Redo. /// The parameters for calling the methode on Undo. /// The parameters for calling the methode on Redo. public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodNameUndo, methodNameRedo, paramsUndo, paramsRedo, BindingFlags.Default, BindingFlags.Default) { } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The name of the methode to call on Undo. /// The name of the methode to call on Redo. /// The parameters for calling the methode on Undo. /// The parameters for calling the methode on Redo. /// The Binding Flags of Methode on Undo. /// The Binding Flags of Methode on Redo. public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, object[] paramsUndo, object[] paramsRedo, BindingFlags methodFlagsUndo, BindingFlags methodFlagsRedo) { Object = obj; ParametersUndo.AddRange(paramsUndo); ParametersRedo.AddRange(paramsRedo); MethodUndo = GetMethodInfo(obj, methodNameUndo, GetFlags(methodFlagsUndo)); MethodRedo = GetMethodInfo(obj, methodNameRedo, GetFlags(methodFlagsRedo)); } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The name of the methode to call on Undo. /// The name of the methode to call on Redo. /// The Binding Flags of Methode on Undo. /// The Binding Flags of Methode on Redo. public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, BindingFlags methodFlagsUndo, BindingFlags methodFlagsRedo) : this(obj, methodNameUndo, methodNameRedo, [], [], methodFlagsUndo, methodFlagsRedo) { } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The MethodInfo of the methode to call on Undo. /// The MethodInfo of the methode to call on Redo. public ObjectAction(object obj, MethodInfo methodUndo, MethodInfo methodRedo) { Object = obj; MethodUndo = methodUndo; MethodRedo = methodRedo; } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The MethodInfo of the methode to call on Undo. /// The MethodInfo of the methode to call on Redo. /// The parameters for calling the methode on Undo. /// The parameters for calling the methode on Redo. public ObjectAction(object obj, MethodInfo methodUndo, MethodInfo methodRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodUndo, methodRedo) { ParametersUndo.AddRange(paramsUndo); ParametersRedo.AddRange(paramsRedo); } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The Delegate of the methode to call on Undo. /// The Delegate of the methode to call on Redo. public ObjectAction(object obj, Delegate methodUndo, Delegate methodRedo) { Object = obj; MethodUndo = methodUndo.Method; MethodRedo = methodRedo.Method; } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The Delegate of the methode to call on Undo. /// The Delegate of the methode to call on Redo. /// The parameters for calling the methode on Undo. /// The parameters for calling the methode on Redo. public ObjectAction(object obj, Delegate methodUndo, Delegate methodRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodUndo, methodRedo) { ParametersUndo.AddRange(paramsUndo); ParametersRedo.AddRange(paramsRedo); } /// /// Creates a new Instance of Object Action. /// /// The Objects that contains the methodes to call. /// The Action of the methode to call on Undo. /// The Action of the methode to call on Redo. public ObjectAction(object obj, Action methodUndo, Action methodRedo) { Object = obj; MethodUndo = methodUndo.Method; MethodRedo = methodRedo.Method; } private static BindingFlags GetFlags(BindingFlags flags) { if (flags == BindingFlags.Default) flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; return flags; } private static MethodInfo? GetMethodInfo(object obj, string name, BindingFlags flags) { return obj.GetType().GetMethod(name, flags); } internal void Undo() { CheckIfObjIsNothing(MethodUndo); MethodUndo?.Invoke(Object, ParametersUndo.ToArray()); } internal void Redo() { CheckIfObjIsNothing(MethodRedo); MethodRedo?.Invoke(Object, ParametersRedo.ToArray()); } private void CheckIfObjIsNothing(MethodInfo? mi) { if (mi is not null && !mi.IsStatic && AutogenerateObject) { if ((Object is null || Object.GetType() != mi.ReflectedType) && !mi.IsStatic) { var constructor = mi.ReflectedType?.GetConstructor(Type.EmptyTypes); var classObject = constructor?.Invoke([]); Object = classObject; } } } }